xref: /netbsd-src/sys/arch/evbarm/tsarm/tsrtc.c (revision b59f66e17c500a0d8ac8904c4c2fe7f387334983)
1*b59f66e1Schristos /*	$NetBSD: tsrtc.c,v 1.8 2014/11/20 16:34:25 christos Exp $	*/
2cff4f008Sjoff 
3cff4f008Sjoff /*
4cff4f008Sjoff  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5cff4f008Sjoff  * All rights reserved.
6cff4f008Sjoff  *
7cff4f008Sjoff  * Author: Chris G. Demetriou
8cff4f008Sjoff  *
9cff4f008Sjoff  * Permission to use, copy, modify and distribute this software and
10cff4f008Sjoff  * its documentation is hereby granted, provided that both the copyright
11cff4f008Sjoff  * notice and this permission notice appear in all copies of the
12cff4f008Sjoff  * software, derivative works or modified versions, and any portions
13cff4f008Sjoff  * thereof, and that both notices appear in supporting documentation.
14cff4f008Sjoff  *
15cff4f008Sjoff  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16cff4f008Sjoff  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17cff4f008Sjoff  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18cff4f008Sjoff  *
19cff4f008Sjoff  * Carnegie Mellon requests users of this software to return to
20cff4f008Sjoff  *
21cff4f008Sjoff  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22cff4f008Sjoff  *  School of Computer Science
23cff4f008Sjoff  *  Carnegie Mellon University
24cff4f008Sjoff  *  Pittsburgh PA 15213-3890
25cff4f008Sjoff  *
26cff4f008Sjoff  * any improvements or extensions that they make and grant Carnegie the
27cff4f008Sjoff  * rights to redistribute these changes.
28cff4f008Sjoff  */
29cff4f008Sjoff 
30cff4f008Sjoff #include <sys/cdefs.h>
31*b59f66e1Schristos __KERNEL_RCSID(0, "$NetBSD: tsrtc.c,v 1.8 2014/11/20 16:34:25 christos Exp $");
32cff4f008Sjoff 
33cff4f008Sjoff #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
34cff4f008Sjoff 
35cff4f008Sjoff #include <sys/param.h>
36cff4f008Sjoff #include <sys/kernel.h>
37cff4f008Sjoff #include <sys/systm.h>
38cff4f008Sjoff #include <sys/device.h>
39cff4f008Sjoff 
40cf10107dSdyoung #include <sys/bus.h>
41cff4f008Sjoff 
42cff4f008Sjoff #include <dev/clock_subr.h>
43cff4f008Sjoff #include <dev/ic/mc146818reg.h>
44cff4f008Sjoff #include <dev/ic/mc146818var.h>
45cff4f008Sjoff 
46cff4f008Sjoff #include <evbarm/tsarm/tspldvar.h>
47cff4f008Sjoff #include <evbarm/tsarm/tsarmreg.h>
48cff4f008Sjoff 
49048fb884Stsutsui int	tsrtc_match(device_t, cfdata_t, void *);
50048fb884Stsutsui void	tsrtc_attach(device_t, device_t, void *);
51cff4f008Sjoff 
52cff4f008Sjoff struct tsrtc_softc {
53cff4f008Sjoff 	struct mc146818_softc	sc_mc;
54cff4f008Sjoff 	bus_space_tag_t		sc_iot;
55cff4f008Sjoff 	bus_space_handle_t	sc_dath;
56cff4f008Sjoff 	bus_space_handle_t	sc_idxh;
57cff4f008Sjoff };
58cff4f008Sjoff 
59048fb884Stsutsui CFATTACH_DECL_NEW(tsrtc, sizeof (struct tsrtc_softc),
60cff4f008Sjoff     tsrtc_match, tsrtc_attach, NULL, NULL);
61cff4f008Sjoff 
62048fb884Stsutsui void	tsrtc_write(struct mc146818_softc *, u_int, u_int);
63048fb884Stsutsui u_int	tsrtc_read(struct mc146818_softc *, u_int);
64cff4f008Sjoff 
65cff4f008Sjoff 
66cff4f008Sjoff int
tsrtc_match(device_t parent,cfdata_t cf,void * aux)67048fb884Stsutsui tsrtc_match(device_t parent, cfdata_t cf, void *aux)
68cff4f008Sjoff {
69cff4f008Sjoff 	struct tspld_attach_args *aa = aux;
70703736dfStsutsui 	struct tsrtc_softc tsrtc, *tsc;
71703736dfStsutsui 	struct mc146818_softc *sc;
72cff4f008Sjoff 	unsigned int t1, t2;
73cff4f008Sjoff 	static int found = -1;
74cff4f008Sjoff 
75048fb884Stsutsui 	if (found != -1)
76048fb884Stsutsui 		return found;
77cff4f008Sjoff 
78703736dfStsutsui 	tsc = &tsrtc;
79703736dfStsutsui 	sc = &tsc->sc_mc;
80703736dfStsutsui 	tsc->sc_iot = aa->ta_iot;
81703736dfStsutsui 	if (bus_space_map(tsc->sc_iot, TS7XXX_IO8_HWBASE + TS7XXX_RTCIDX, 1, 0,
82703736dfStsutsui 		 &tsc->sc_idxh))
83cff4f008Sjoff 		return (0);
84703736dfStsutsui 	if (bus_space_map(tsc->sc_iot, TS7XXX_IO8_HWBASE + TS7XXX_RTCDAT, 1, 0,
85703736dfStsutsui 		 &tsc->sc_dath))
86cff4f008Sjoff 		return (0);
87cff4f008Sjoff 
88cff4f008Sjoff 	/* Read from the seconds counter. */
89*b59f66e1Schristos 	t1 = bcdtobin(tsrtc_read(sc, MC_SEC));
90cff4f008Sjoff 	if (t1 > 59)
91cff4f008Sjoff 		goto unmap;
92cff4f008Sjoff 
93cff4f008Sjoff 	/* Wait, then look again. */
94cff4f008Sjoff 	DELAY(1100000);
95*b59f66e1Schristos 	t2 = bcdtobin(tsrtc_read(sc, MC_SEC));
96cff4f008Sjoff 	if (t2 > 59)
97cff4f008Sjoff 		goto unmap;
98cff4f008Sjoff 
99cff4f008Sjoff         /* If [1,2) seconds have passed since, call it a clock. */
100cff4f008Sjoff 	if ((t1 + 1) % 60 == t2 || (t1 + 2) % 60 == t2)
101cff4f008Sjoff 		found = 1;
102cff4f008Sjoff 
103cff4f008Sjoff  unmap:
104703736dfStsutsui 	bus_space_unmap(tsc->sc_iot, tsc->sc_idxh, 1);
105703736dfStsutsui 	bus_space_unmap(tsc->sc_iot, tsc->sc_dath, 1);
106cff4f008Sjoff 
107cff4f008Sjoff 	return (found);
108cff4f008Sjoff }
109cff4f008Sjoff 
110cff4f008Sjoff void
tsrtc_attach(device_t parent,device_t self,void * aux)111048fb884Stsutsui tsrtc_attach(device_t parent, device_t self, void *aux)
112cff4f008Sjoff {
113703736dfStsutsui 	struct tsrtc_softc *tsc = device_private(self);
114703736dfStsutsui 	struct mc146818_softc *sc = &tsc->sc_mc;
115cff4f008Sjoff 	struct tspld_attach_args *aa = aux;
116cff4f008Sjoff 
1174090172bStsutsui 	sc->sc_dev = self;
118703736dfStsutsui 	tsc->sc_iot = aa->ta_iot;
119703736dfStsutsui 	if (bus_space_map(tsc->sc_iot, TS7XXX_IO8_HWBASE + TS7XXX_RTCIDX,
120703736dfStsutsui 	    1, 0, &tsc->sc_idxh))
121cff4f008Sjoff 		panic("tsrtc_attach: couldn't map clock I/O space");
122703736dfStsutsui 	if (bus_space_map(tsc->sc_iot, TS7XXX_IO8_HWBASE + TS7XXX_RTCDAT,
123703736dfStsutsui 	    1, 0, &tsc->sc_dath))
124cff4f008Sjoff 		panic("tsrtc_attach: couldn't map clock I/O space");
125cff4f008Sjoff 
126703736dfStsutsui 	sc->sc_year0 = 2000;
127703736dfStsutsui 	sc->sc_mcread = tsrtc_read;
128703736dfStsutsui 	sc->sc_mcwrite = tsrtc_write;
129703736dfStsutsui 	sc->sc_flag = MC146818_BCD;
130703736dfStsutsui 	mc146818_attach(sc);
131cff4f008Sjoff 
132703736dfStsutsui 	aprint_normal("\n");
133cff4f008Sjoff 
134703736dfStsutsui 	(*sc->sc_mcwrite)(sc, MC_REGB, MC_REGB_24HR);
135cff4f008Sjoff }
136cff4f008Sjoff 
137cff4f008Sjoff void
tsrtc_write(struct mc146818_softc * mc_sc,u_int reg,u_int datum)138048fb884Stsutsui tsrtc_write(struct mc146818_softc *mc_sc, u_int reg, u_int datum)
139cff4f008Sjoff {
140cff4f008Sjoff 	struct tsrtc_softc *sc = (struct tsrtc_softc *)mc_sc;
141cff4f008Sjoff 
142cff4f008Sjoff 	bus_space_write_1(sc->sc_iot, sc->sc_idxh, 0, reg);
143cff4f008Sjoff 	bus_space_write_1(sc->sc_iot, sc->sc_dath, 0, datum);
144cff4f008Sjoff }
145cff4f008Sjoff 
146cff4f008Sjoff u_int
tsrtc_read(struct mc146818_softc * mc_sc,u_int reg)147048fb884Stsutsui tsrtc_read(struct mc146818_softc *mc_sc, u_int reg)
148cff4f008Sjoff {
149cff4f008Sjoff 	struct tsrtc_softc *sc = (struct tsrtc_softc *)mc_sc;
150cff4f008Sjoff 	u_int datum;
151cff4f008Sjoff 
152cff4f008Sjoff 	bus_space_write_1(sc->sc_iot, sc->sc_idxh, 0, reg);
153cff4f008Sjoff 	datum = bus_space_read_1(sc->sc_iot, sc->sc_dath, 0);
154cff4f008Sjoff 
155cff4f008Sjoff 	return (datum);
156cff4f008Sjoff }
157