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