xref: /openbsd/sys/arch/landisk/stand/boot/getsecs.c (revision 09467b48)
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