No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / evbppc / walnut / dev / ds1743.c
blobf5eda675a7e19734ec909588e8713a778321af09
1 /* $NetBSD: ds1743.c,v 1.6 2005/12/11 12:17:13 christos Exp $ */
3 /*
4 * Copyright (c) 2001-2002 Wasabi Sysetms, Inc.
5 * Copyright (c) 1998 Mark Brinicombe.
6 * Copyright (c) 1998 Causality Limited.
7 * All rights reserved.
9 * Written by Mark Brinicombe, Causality Limited
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Mark Brinicombe
22 * for the NetBSD Project.
23 * 4. The name of the company nor the name of the author may be used to
24 * endorse or promote products derived from this software without specific
25 * prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY CAUASLITY LIMITED ``AS IS'' AND ANY EXPRESS
28 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: ds1743.c,v 1.6 2005/12/11 12:17:13 christos Exp $");
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46 #include <dev/clock_subr.h>
48 #include <machine/rtc.h>
49 #include <machine/bus.h>
51 #include <evbppc/walnut/dev/ds1743reg.h>
52 #include <evbppc/walnut/dev/pbusvar.h>
54 struct dsrtc_softc {
55 struct device sc_dev;
56 bus_space_tag_t sc_iot;
57 bus_space_handle_t sc_ioh;
58 struct todr_chip_handle sc_todr;
61 static void dsrtcattach(struct device *, struct device *, void *);
62 static int dsrtcmatch(struct device *, struct cfdata *, void *);
63 #if 0 /* Nothing uses these yet */
64 static int ds1743_ram_read(struct dsrtc_softc *, int);
65 static void ds1743_ram_write(struct dsrtc_softc *, int, int);
66 #endif
68 static int dsrtc_read(todr_chip_handle_t, struct clock_ymdhms *);
69 static int dsrtc_write(todr_chip_handle_t, struct clock_ymdhms *);
70 static inline u_char ds1743_read(struct dsrtc_softc *, int);
71 static inline void ds1743_write(struct dsrtc_softc *, int, u_char);
72 static u_char ds1743_lock(struct dsrtc_softc *, u_char);
73 static void ds1743_unlock(struct dsrtc_softc *, u_char);
75 /* device and attach structures */
76 CFATTACH_DECL(ds1743rtc, sizeof(struct dsrtc_softc),
77 dsrtcmatch, dsrtcattach, NULL, NULL);
80 * dsrtcmatch()
82 * Validate the IIC address to make sure its an RTC we understand
84 int ds1743found = 0;
86 #define DS_SCRATCH_ADDR 0x1FF7
88 static int
89 dsrtcmatch(struct device *parent, struct cfdata *cf, void *aux)
91 struct pbus_attach_args *paa = aux;
92 int retval = !ds1743found;
93 bus_space_handle_t h;
94 u_int8_t x;
96 /* match only RTC devices */
97 if (strcmp(paa->pb_name, cf->cf_name) != 0)
98 return 0;
100 if (bus_space_map(paa->pb_bt, paa->pb_addr, DS_SIZE, 0, &h)) {
101 printf("%s: can't map i/o space\n", paa->pb_name);
102 return 0;
105 /* Read one byte of what's supposed to be NVRAM */
106 x = bus_space_read_1(paa->pb_bt, h, DS_SCRATCH_ADDR);
107 bus_space_write_1(paa->pb_bt, h, DS_SCRATCH_ADDR, 0xAA);
108 if (bus_space_read_1(paa->pb_bt, h, DS_SCRATCH_ADDR) != 0xAA) {
109 retval = 0;
110 goto done;
113 bus_space_write_1(paa->pb_bt, h, DS_SCRATCH_ADDR, 0x55);
114 if (bus_space_read_1(paa->pb_bt, h, DS_SCRATCH_ADDR) != 0x55) {
115 retval = 0;
116 goto done;
119 /* Restore scratch byte value */
120 bus_space_write_1(paa->pb_bt, h, DS_SCRATCH_ADDR, x);
121 done:
122 bus_space_unmap(paa->pb_bt, h, DS_SIZE);
124 return retval;
128 * dsrtcattach()
130 * Attach the rtc device
133 static void
134 dsrtcattach(struct device *parent, struct device *self, void *aux)
136 struct dsrtc_softc *sc = (struct dsrtc_softc *)self;
137 struct pbus_attach_args *paa = aux;
139 ds1743found = 1;
141 sc->sc_iot = paa->pb_bt;
142 if (bus_space_map(sc->sc_iot, paa->pb_addr, DS_SIZE, 0, &sc->sc_ioh)) {
143 printf(": can't map i/o space\n");
144 return;
147 ds1743_unlock(sc, 0); /* Make sure the clock is running */
148 if ((ds1743_read(sc, DS_DAY) & DS_CTL_BF) == 0)
149 printf(": lithium cell is dead, RTC unreliable");
150 printf("\n");
152 #ifdef DEBUG
154 rtc_t rtc;
155 dsrtc_read(sc, &rtc);
156 printf("RTC: %d/%d/%02d%02d %d:%02d:%02d\n",
157 rtc.rtc_mon, rtc.rtc_day, rtc.rtc_cen, rtc.rtc_year,
158 rtc.rtc_hour, rtc.rtc_min, rtc.rtc_sec);
160 #endif
162 sc->sc_todr.todr_gettime_ymdhms = dsrtc_read;
163 sc->sc_todr.todr_settime_ymdhms = dsrtc_write;
164 sc->sc_todr.cookie = sc;
165 todr_attach(&sc->sc_todr);
168 static inline u_char
169 ds1743_read(struct dsrtc_softc *sc, int addr)
172 return(bus_space_read_1(sc->sc_iot, sc->sc_ioh, addr));
175 static inline void
176 ds1743_write(struct dsrtc_softc *sc, int addr, u_char data)
179 bus_space_write_1(sc->sc_iot, sc->sc_ioh, addr, data);
183 #if 0 /* Nothing uses these yet */
184 static u_char
185 ds1743_ram_read(struct dsrtc_softc *sc, int addr)
188 if (addr >= DS_RAM_SIZE)
189 return(-1);
190 return(ds1743_read(sc, addr));
193 static void
194 ds1743_ram_write(struct dsrtc_softc *sc, int addr, u_char val)
197 if (addr >= DS_RAM_SIZE)
198 return (-1);
199 ds1743_write(sc, addr, val);
201 #endif
203 #define BCD(x) ((((x) / 10) << 4) | (x % 10))
204 #define unBCD(v, x) v = x; v = ((v >> 4) & 0xf) * 10 + (v & 0xf)
206 static u_char
207 ds1743_lock(struct dsrtc_softc *sc, u_char mode)
209 u_char octl, ctl;
211 octl = ds1743_read(sc, DS_CENTURY);
212 ctl = octl | (mode & DS_CTL_RW);
213 ds1743_write(sc, DS_CENTURY, ctl); /* Lock RTC for both reading and writing */
214 return octl;
217 static void
218 ds1743_unlock(struct dsrtc_softc *sc, u_char key)
220 int ctl;
222 ctl = ds1743_read(sc, DS_CENTURY);
223 ctl = (ctl & 0x3f) | (key & DS_CTL_RW);
224 ds1743_write(sc, DS_CENTURY, ctl); /* Enable updates */
227 static int
228 dsrtc_write(todr_chip_handle_t tch, struct clock_ymdhms *dt)
230 struct dsrtc_softc *sc = tch->cookie;
231 u_char key;
233 key = ds1743_lock(sc, DS_CTL_W);
235 ds1743_write(sc, DS_SECONDS, TOBCD(dt->dt_sec) & 0x7f);
236 ds1743_write(sc, DS_MINUTES, TOBCD(dt->dt_min) & 0x7f);
237 ds1743_write(sc, DS_HOURS, TOBCD(dt->dt_hour) & 0x3f);
238 ds1743_write(sc, DS_DATE, TOBCD(dt->dt_day) & 0x3f);
239 ds1743_write(sc, DS_MONTH, TOBCD(dt->dt_mon) & 0x1f);
240 ds1743_write(sc, DS_YEAR, TOBCD(dt->dt_year % 100));
241 ds1743_write(sc, DS_CENTURY, ((ds1743_read(sc, DS_CENTURY) & DS_CTL_RW)
242 | TOBCD(dt->dt_year / 100)));
244 ds1743_unlock(sc, key);
245 return(0);
248 static int
249 dsrtc_read(todr_chip_handle_t tch, struct clock_ymdhms *dt)
251 struct dsrtc_softc *sc = tch->cookie;
252 u_char key;
254 key = ds1743_lock(sc, DS_CTL_R);
255 dt->dt_sec = FROMBCD(ds1743_read(sc, DS_SECONDS) & 0x7f);
256 dt->dt_min = FROMBCD(ds1743_read(sc, DS_MINUTES) & 0x7f);
257 dt->dt_hour = FROMBCD(ds1743_read(sc, DS_HOURS) & 0x3f);
258 dt->dt_day = FROMBCD(ds1743_read(sc, DS_DATE) & 0x3f);
259 dt->dt_mon = FROMBCD(ds1743_read(sc, DS_MONTH) & 0x1f);
260 dt->dt_year =
261 FROMBCD(ds1743_read(sc, DS_YEAR)) +
262 FROMBCD(ds1743_read(sc, DS_CENTURY) & ~DS_CTL_RW) * 100;
264 ds1743_unlock(sc, key);
265 return(0);