1 /* $NetBSD: getsecs.c,v 1.3 2009/01/12 11:32:44 tsutsui Exp $ */ 2 3 #include <sys/param.h> 4 #include <sys/types.h> 5 6 #include <netinet/in.h> 7 #include <netinet/in_systm.h> 8 9 #include <lib/libsa/stand.h> 10 #include <lib/libsa/net.h> 11 #include <lib/libsa/netif.h> 12 #include <lib/libkern/libkern.h> 13 14 #include <sh3/devreg.h> 15 #include <sh3/scireg.h> 16 17 #include <dev/ic/rs5c313reg.h> 18 19 /** 20 * RICOH RS5C313 21 * 22 * Web page: http://www.ricoh.co.jp/LSI/product_rtc/3wire/5c313/ 23 * 24 * How to control RS5C313 on LANDISK 25 * see http://www.mizore.jp/wiki/index.php?LANDISK/rtc 26 */ 27 28 uint8_t rtc_read(uint32_t addr); 29 void rtc_write(uint32_t addr, uint8_t data); 30 31 static void 32 rtc_init(void) 33 { 34 35 SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT 36 | SCSPTR_SPB0IO | SCSPTR_SPB0DT; 37 } 38 39 /* control RTC chip enable */ 40 static void 41 rtc_ce(int onoff) 42 { 43 44 if (onoff) { 45 _reg_write_1(0xb0000003, (1 << 1)); 46 } else { 47 _reg_write_1(0xb0000003, (0 << 1)); 48 } 49 } 50 51 static inline void 52 rtc_clk(int onoff) 53 { 54 55 if (onoff) { 56 SHREG_SCSPTR |= SCSPTR_SPB0DT; 57 } else { 58 SHREG_SCSPTR &= ~SCSPTR_SPB0DT; 59 } 60 } 61 62 static void 63 rtc_dir(int output) 64 { 65 66 if (output) { 67 SHREG_SCSPTR |= SCSPTR_SPB1IO; 68 } else { 69 SHREG_SCSPTR &= ~SCSPTR_SPB1IO; 70 } 71 } 72 73 /* data-out */ 74 static void 75 rtc_do(int onoff) 76 { 77 78 if (onoff) { 79 SHREG_SCSPTR |= SCSPTR_SPB1DT; 80 } else { 81 SHREG_SCSPTR &= ~SCSPTR_SPB1DT; 82 } 83 84 rtc_clk(0); 85 rtc_clk(1); 86 } 87 88 /* data-in */ 89 static int 90 rtc_di(void) 91 { 92 int d; 93 94 d = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0; 95 96 rtc_clk(0); 97 rtc_clk(1); 98 99 return d; 100 } 101 102 uint8_t 103 rtc_read(uint32_t addr) 104 { 105 uint8_t data; 106 107 rtc_init(); 108 rtc_ce(1); 109 110 rtc_dir(1); 111 rtc_do(1); /* Don't care */ 112 rtc_do(1); /* R/#W = 1(READ) */ 113 rtc_do(1); /* AD = 1 */ 114 rtc_do(0); /* DT = 0 */ 115 rtc_do(addr & 0x8); /* A3 */ 116 rtc_do(addr & 0x4); /* A2 */ 117 rtc_do(addr & 0x2); /* A1 */ 118 rtc_do(addr & 0x1); /* A0 */ 119 120 rtc_dir(0); 121 (void)rtc_di(); 122 (void)rtc_di(); 123 (void)rtc_di(); 124 (void)rtc_di(); 125 data = rtc_di(); /* D3 */ 126 data <<= 1; 127 data |= rtc_di(); /* D2 */ 128 data <<= 1; 129 data |= rtc_di(); /* D1 */ 130 data <<= 1; 131 data |= rtc_di(); /* D0 */ 132 133 rtc_ce(0); 134 135 return data & 0xf; 136 } 137 138 void 139 rtc_write(uint32_t addr, uint8_t data) 140 { 141 142 rtc_init(); 143 rtc_ce(1); 144 145 rtc_dir(1); 146 rtc_do(1); /* Don't care */ 147 rtc_do(0); /* R/#W = 0(WRITE) */ 148 rtc_do(1); /* AD = 1 */ 149 rtc_do(0); /* DT = 0 */ 150 rtc_do(addr & 0x8); /* A3 */ 151 rtc_do(addr & 0x4); /* A2 */ 152 rtc_do(addr & 0x2); /* A1 */ 153 rtc_do(addr & 0x1); /* A0 */ 154 155 rtc_do(1); /* Don't care */ 156 rtc_do(0); /* R/#W = 0(WRITE) */ 157 rtc_do(0); /* AD = 0 */ 158 rtc_do(1); /* DT = 1 */ 159 rtc_do(data & 0x8); /* D3 */ 160 rtc_do(data & 0x4); /* D2 */ 161 rtc_do(data & 0x2); /* D1 */ 162 rtc_do(data & 0x1); /* D0 */ 163 164 rtc_ce(0); 165 } 166 167 satime_t 168 getsecs(void) 169 { 170 uint32_t sec, min, hour, day; 171 #if 0 172 uint32_t mon, year; 173 #endif 174 satime_t secs; 175 176 sec = rtc_read(RS5C313_SEC1); 177 sec += rtc_read(RS5C313_SEC10) * 10; 178 min = rtc_read(RS5C313_MIN1); 179 min += rtc_read(RS5C313_MIN10) * 10; 180 hour = rtc_read(RS5C313_HOUR1); 181 hour += rtc_read(RS5C313_HOUR10) * 10; 182 day = rtc_read(RS5C313_DAY1); 183 day += rtc_read(RS5C313_DAY10) * 10; 184 #if 0 185 mon = rtc_read(RS5C313_MON1); 186 mon += rtc_read(RS5C313_MON10) * 10; 187 year = rtc_read(RS5C313_YEAR1); 188 year += rtc_read(RS5C313_YEAR10) * 10; 189 #endif 190 191 secs = sec; 192 secs += min * 60; 193 secs += hour * 60 * 60; 194 secs += day * 60 * 60 * 24; 195 #if 0 196 /* XXX mon, year */ 197 #endif 198 199 #if defined(DEBUG) 200 printf("getsecs: secs = %d\n", (uint32_t)secs); 201 #endif 202 203 return secs; 204 } 205