Home | History | Annotate | Line # | Download | only in boot
getsecs.c revision 1.2
      1 /*	$NetBSD: getsecs.c,v 1.2 2006/09/11 13:48:57 nonaka 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 time_t
    168 getsecs(void)
    169 {
    170 	uint32_t sec, min, hour, day;
    171 #if 0
    172 	uint32_t mon, year;
    173 #endif
    174 	time_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