xref: /netbsd-src/sys/arch/landisk/stand/boot/getsecs.c (revision 45cd6b0b7f9ca171bc736b6565174df876dc17e2)
1 /*	$NetBSD: getsecs.c,v 1.4 2022/08/24 14:22:35 nonaka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2005 NONAKA Kimihiro
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/types.h>
31 
32 #include <netinet/in.h>
33 #include <netinet/in_systm.h>
34 
35 #include <lib/libsa/stand.h>
36 #include <lib/libsa/net.h>
37 #include <lib/libsa/netif.h>
38 #include <lib/libkern/libkern.h>
39 
40 #include <sh3/devreg.h>
41 #include <sh3/scireg.h>
42 
43 #include <dev/ic/rs5c313reg.h>
44 
45 /**
46  * RICOH RS5C313
47  *
48  * Web page: http://www.ricoh.co.jp/LSI/product_rtc/3wire/5c313/
49  *
50  * How to control RS5C313 on LANDISK
51  *   see http://www.mizore.jp/wiki/index.php?LANDISK/rtc
52  */
53 
54 uint8_t rtc_read(uint32_t addr);
55 void rtc_write(uint32_t addr, uint8_t data);
56 
57 static void
rtc_init(void)58 rtc_init(void)
59 {
60 
61 	SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT
62 		       | SCSPTR_SPB0IO | SCSPTR_SPB0DT;
63 }
64 
65 /* control RTC chip enable */
66 static void
rtc_ce(int onoff)67 rtc_ce(int onoff)
68 {
69 
70 	if (onoff) {
71 		_reg_write_1(0xb0000003, (1 << 1));
72 	} else {
73 		_reg_write_1(0xb0000003, (0 << 1));
74 	}
75 }
76 
77 static inline void
rtc_clk(int onoff)78 rtc_clk(int onoff)
79 {
80 
81 	if (onoff) {
82 		SHREG_SCSPTR |= SCSPTR_SPB0DT;
83 	} else {
84 		SHREG_SCSPTR &= ~SCSPTR_SPB0DT;
85 	}
86 }
87 
88 static void
rtc_dir(int output)89 rtc_dir(int output)
90 {
91 
92 	if (output) {
93 		SHREG_SCSPTR |= SCSPTR_SPB1IO;
94 	} else {
95 		SHREG_SCSPTR &= ~SCSPTR_SPB1IO;
96 	}
97 }
98 
99 /* data-out */
100 static void
rtc_do(int onoff)101 rtc_do(int onoff)
102 {
103 
104 	if (onoff) {
105 		SHREG_SCSPTR |= SCSPTR_SPB1DT;
106 	} else {
107 		SHREG_SCSPTR &= ~SCSPTR_SPB1DT;
108 	}
109 
110 	rtc_clk(0);
111 	rtc_clk(1);
112 }
113 
114 /* data-in */
115 static int
rtc_di(void)116 rtc_di(void)
117 {
118 	int d;
119 
120 	d = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0;
121 
122 	rtc_clk(0);
123 	rtc_clk(1);
124 
125 	return d;
126 }
127 
128 uint8_t
rtc_read(uint32_t addr)129 rtc_read(uint32_t addr)
130 {
131 	uint8_t data;
132 
133 	rtc_init();
134 	rtc_ce(1);
135 
136 	rtc_dir(1);
137 	rtc_do(1);		/* Don't care */
138 	rtc_do(1);		/* R/#W = 1(READ) */
139 	rtc_do(1);		/* AD = 1 */
140 	rtc_do(0);		/* DT = 0 */
141 	rtc_do(addr & 0x8);	/* A3 */
142 	rtc_do(addr & 0x4);	/* A2 */
143 	rtc_do(addr & 0x2);	/* A1 */
144 	rtc_do(addr & 0x1);	/* A0 */
145 
146 	rtc_dir(0);
147 	(void)rtc_di();
148 	(void)rtc_di();
149 	(void)rtc_di();
150 	(void)rtc_di();
151 	data = rtc_di();	/* D3 */
152 	data <<= 1;
153 	data |= rtc_di();	/* D2 */
154 	data <<= 1;
155 	data |= rtc_di();	/* D1 */
156 	data <<= 1;
157 	data |= rtc_di();	/* D0 */
158 
159 	rtc_ce(0);
160 
161 	return data & 0xf;
162 }
163 
164 void
rtc_write(uint32_t addr,uint8_t data)165 rtc_write(uint32_t addr, uint8_t data)
166 {
167 
168 	rtc_init();
169 	rtc_ce(1);
170 
171 	rtc_dir(1);
172 	rtc_do(1);		/* Don't care */
173 	rtc_do(0);		/* R/#W = 0(WRITE) */
174 	rtc_do(1);		/* AD = 1 */
175 	rtc_do(0);		/* DT = 0 */
176 	rtc_do(addr & 0x8);	/* A3 */
177 	rtc_do(addr & 0x4);	/* A2 */
178 	rtc_do(addr & 0x2);	/* A1 */
179 	rtc_do(addr & 0x1);	/* A0 */
180 
181 	rtc_do(1);		/* Don't care */
182 	rtc_do(0);		/* R/#W = 0(WRITE) */
183 	rtc_do(0);		/* AD = 0 */
184 	rtc_do(1);		/* DT = 1 */
185 	rtc_do(data & 0x8);	/* D3 */
186 	rtc_do(data & 0x4);	/* D2 */
187 	rtc_do(data & 0x2);	/* D1 */
188 	rtc_do(data & 0x1);	/* D0 */
189 
190 	rtc_ce(0);
191 }
192 
193 satime_t
getsecs(void)194 getsecs(void)
195 {
196 	uint32_t sec, min, hour, day;
197 #if 0
198 	uint32_t mon, year;
199 #endif
200 	satime_t secs;
201 
202 	sec = rtc_read(RS5C313_SEC1);
203 	sec += rtc_read(RS5C313_SEC10) * 10;
204 	min = rtc_read(RS5C313_MIN1);
205 	min += rtc_read(RS5C313_MIN10) * 10;
206 	hour = rtc_read(RS5C313_HOUR1);
207 	hour += rtc_read(RS5C313_HOUR10) * 10;
208 	day = rtc_read(RS5C313_DAY1);
209 	day += rtc_read(RS5C313_DAY10) * 10;
210 #if 0
211 	mon = rtc_read(RS5C313_MON1);
212 	mon += rtc_read(RS5C313_MON10) * 10;
213 	year = rtc_read(RS5C313_YEAR1);
214 	year += rtc_read(RS5C313_YEAR10) * 10;
215 #endif
216 
217 	secs = sec;
218 	secs += min * 60;
219 	secs += hour * 60 * 60;
220 	secs += day * 60 * 60 * 24;
221 #if 0
222 	/* XXX mon, year */
223 #endif
224 
225 #if defined(DEBUG)
226 	printf("getsecs: secs = %d\n", (uint32_t)secs);
227 #endif
228 
229 	return secs;
230 }
231