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