xref: /netbsd-src/sys/arch/arm/footbridge/isa/dsrtc.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: dsrtc.c,v 1.8 2005/12/11 12:16:46 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1998 Mark Brinicombe.
5  * Copyright (c) 1998 Causality Limited.
6  * All rights reserved.
7  *
8  * Written by Mark Brinicombe, Causality Limited
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by Mark Brinicombe
21  *	for the NetBSD Project.
22  * 4. The name of the company nor the name of the author may be used to
23  *    endorse or promote products derived from this software without specific
24  *    prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY CAUASLITY LIMITED ``AS IS'' AND ANY EXPRESS
27  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29  * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38 
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: dsrtc.c,v 1.8 2005/12/11 12:16:46 christos Exp $");
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/conf.h>
46 #include <sys/device.h>
47 
48 #include <machine/rtc.h>
49 
50 #include <arm/footbridge/todclockvar.h>
51 #include <arm/footbridge/isa/ds1687reg.h>
52 
53 #include <dev/isa/isavar.h>
54 
55 #define NRTC_PORTS	2
56 
57 struct dsrtc_softc {
58 	struct device	sc_dev;
59 	bus_space_tag_t	sc_iot;
60 	bus_space_handle_t sc_ioh;
61 };
62 
63 void dsrtcattach __P((struct device *parent, struct device *self, void *aux));
64 int dsrtcmatch __P((struct device *parent, struct cfdata *cf, void *aux));
65 int ds1687_read __P((struct dsrtc_softc *sc, int addr));
66 void ds1687_write __P((struct dsrtc_softc *sc, int addr, int data));
67 int ds1687_ram_read __P((struct dsrtc_softc *sc, int addr));
68 void ds1687_ram_write __P((struct dsrtc_softc *sc, int addr, int data));
69 static void ds1687_bank_select __P((struct dsrtc_softc *, int));
70 static int dsrtc_write __P((void *, rtc_t *));
71 static int dsrtc_read __P((void *, rtc_t *));
72 
73 int
74 ds1687_read(sc, addr)
75 	struct dsrtc_softc *sc;
76 	int addr;
77 {
78 
79 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, RTC_ADDR_REG, addr);
80 	return(bus_space_read_1(sc->sc_iot, sc->sc_ioh, RTC_DATA_REG));
81 }
82 
83 void
84 ds1687_write(sc, addr, data)
85 	struct dsrtc_softc *sc;
86 	int addr;
87 	int data;
88 {
89 
90 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, RTC_ADDR_REG, addr);
91 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, RTC_DATA_REG, data);
92 }
93 
94 static void
95 ds1687_bank_select(sc, bank)
96 	struct dsrtc_softc *sc;
97 	int bank;
98 {
99 	int data;
100 
101 	data = ds1687_read(sc, RTC_REG_A);
102 	data &= ~RTC_REG_A_BANK_MASK;
103 	if (bank)
104 		data |= RTC_REG_A_BANK1;
105 	ds1687_write(sc, RTC_REG_A, data);
106 }
107 
108 #if 0
109 /* Nothing uses these yet */
110 int
111 ds1687_ram_read(sc, addr)
112 	struct dsrtc_softc *sc;
113 	int addr;
114 {
115 	if (addr < RTC_PC_RAM_SIZE)
116 		return(ds1687_read(sc, RTC_PC_RAM_START + addr));
117 
118 	addr -= RTC_PC_RAM_SIZE;
119 	if (addr < RTC_BANK0_RAM_SIZE)
120 		return(ds1687_read(sc, RTC_BANK0_RAM_START + addr));
121 
122 	addr -= RTC_BANK0_RAM_SIZE;
123 	if (addr < RTC_EXT_RAM_SIZE) {
124 		int data;
125 
126 		ds1687_bank_select(sc, 1);
127 		ds1687_write(sc, RTC_EXT_RAM_ADDRESS, addr);
128 		data = ds1687_read(sc, RTC_EXT_RAM_DATA);
129 		ds1687_bank_select(sc, 0);
130 		return(data);
131 	}
132 	return(-1);
133 }
134 
135 void
136 ds1687_ram_write(sc, addr, val)
137 	struct dsrtc_softc *sc;
138 	int addr;
139 	int val;
140 {
141 	if (addr < RTC_PC_RAM_SIZE)
142 		return(ds1687_write(sc, RTC_PC_RAM_START + addr, val));
143 
144 	addr -= RTC_PC_RAM_SIZE;
145 	if (addr < RTC_BANK0_RAM_SIZE)
146 		return(ds1687_write(sc, RTC_BANK0_RAM_START + addr, val));
147 
148 	addr -= RTC_BANK0_RAM_SIZE;
149 	if (addr < RTC_EXT_RAM_SIZE) {
150 		ds1687_bank_select(sc, 1);
151 		ds1687_write(sc, RTC_EXT_RAM_ADDRESS, addr);
152 		ds1687_write(sc, RTC_EXT_RAM_DATA, val);
153 		ds1687_bank_select(sc, 0);
154 	}
155 }
156 #endif
157 
158 static int
159 dsrtc_write(arg, rtc)
160 	void *arg;
161 	rtc_t *rtc;
162 {
163 	struct dsrtc_softc *sc = arg;
164 
165 	ds1687_write(sc, RTC_SECONDS, rtc->rtc_sec);
166 	ds1687_write(sc, RTC_MINUTES, rtc->rtc_min);
167 	ds1687_write(sc, RTC_HOURS, rtc->rtc_hour);
168 	ds1687_write(sc, RTC_DAYOFMONTH, rtc->rtc_day);
169 	ds1687_write(sc, RTC_MONTH, rtc->rtc_mon);
170 	ds1687_write(sc, RTC_YEAR, rtc->rtc_year);
171 	ds1687_bank_select(sc, 1);
172 	ds1687_write(sc, RTC_CENTURY, rtc->rtc_cen);
173 	ds1687_bank_select(sc, 0);
174 	return(1);
175 }
176 
177 static int
178 dsrtc_read(arg, rtc)
179 	void *arg;
180 	rtc_t *rtc;
181 {
182 	struct dsrtc_softc *sc = arg;
183 
184 	rtc->rtc_micro = 0;
185 	rtc->rtc_centi = 0;
186 	rtc->rtc_sec   = ds1687_read(sc, RTC_SECONDS);
187 	rtc->rtc_min   = ds1687_read(sc, RTC_MINUTES);
188 	rtc->rtc_hour  = ds1687_read(sc, RTC_HOURS);
189 	rtc->rtc_day   = ds1687_read(sc, RTC_DAYOFMONTH);
190 	rtc->rtc_mon   = ds1687_read(sc, RTC_MONTH);
191 	rtc->rtc_year  = ds1687_read(sc, RTC_YEAR);
192 	ds1687_bank_select(sc, 1);
193 	rtc->rtc_cen   = ds1687_read(sc, RTC_CENTURY);
194 	ds1687_bank_select(sc, 0);
195 
196 	return(1);
197 }
198 
199 /* device and attach structures */
200 CFATTACH_DECL(ds1687rtc, sizeof(struct dsrtc_softc),
201     dsrtcmatch, dsrtcattach, NULL, NULL);
202 
203 /*
204  * dsrtcmatch()
205  *
206  * Validate the IIC address to make sure its an RTC we understand
207  */
208 
209 int
210 dsrtcmatch(parent, cf, aux)
211 	struct device *parent;
212 	struct cfdata *cf;
213 	void *aux;
214 {
215 	struct isa_attach_args *ia = aux;
216 
217 	if (ia->ia_nio < 1 ||
218 	    ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
219 		return (0);
220 
221 	ia->ia_nio = 1;
222 	ia->ia_io[0].ir_size = NRTC_PORTS;
223 
224 	ia->ia_niomem = 0;
225 	ia->ia_nirq = 0;
226 	ia->ia_ndrq = 0;
227 
228 	return(1);
229 }
230 
231 /*
232  * dsrtcattach()
233  *
234  * Attach the rtc device
235  */
236 
237 void
238 dsrtcattach(parent, self, aux)
239 	struct device *parent;
240 	struct device *self;
241 	void *aux;
242 {
243 	struct dsrtc_softc *sc = (struct dsrtc_softc *)self;
244 	struct isa_attach_args *ia = aux;
245 	struct todclock_attach_args ta;
246 
247 	sc->sc_iot = ia->ia_iot;
248 	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr,
249 	    ia->ia_io[0].ir_size, 0, &sc->sc_ioh)) {
250 		printf(": cannot map I/O space\n");
251 		return;
252 	}
253 
254 	ds1687_write(sc, RTC_REG_A, RTC_REG_A_DV1);
255 	ds1687_write(sc, RTC_REG_B, RTC_REG_B_BINARY | RTC_REG_B_24_HOUR);
256 
257 	if (!(ds1687_read(sc, RTC_REG_D) & RTC_REG_D_VRT))
258 		printf(": lithium cell is dead, RTC unreliable");
259 	printf("\n");
260 
261 	ta.ta_name = "todclock";
262 	ta.ta_rtc_arg = sc;
263 	ta.ta_rtc_write = dsrtc_write;
264 	ta.ta_rtc_read = dsrtc_read;
265 	ta.ta_flags = 0;
266 	config_found(self, &ta, NULL);
267 }
268 
269 /* End of dsrtc.c */
270