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