xref: /netbsd-src/sys/arch/mipsco/obio/mkclock.c (revision b59f66e17c500a0d8ac8904c4c2fe7f387334983)
1*b59f66e1Schristos /*	$NetBSD: mkclock.c,v 1.12 2014/11/20 16:34:25 christos Exp $	*/
23f55a7b9Swdk 
33f55a7b9Swdk /*-
43f55a7b9Swdk  * Copyright (c) 2000 The NetBSD Foundation, Inc.
53f55a7b9Swdk  * All rights reserved.
63f55a7b9Swdk  *
73f55a7b9Swdk  * This code is derived from software contributed to The NetBSD Foundation
83f55a7b9Swdk  * by Wayne Knowles
93f55a7b9Swdk  *
103f55a7b9Swdk  * Redistribution and use in source and binary forms, with or without
113f55a7b9Swdk  * modification, are permitted provided that the following conditions
123f55a7b9Swdk  * are met:
133f55a7b9Swdk  * 1. Redistributions of source code must retain the above copyright
143f55a7b9Swdk  *    notice, this list of conditions and the following disclaimer.
153f55a7b9Swdk  * 2. Redistributions in binary form must reproduce the above copyright
163f55a7b9Swdk  *    notice, this list of conditions and the following disclaimer in the
173f55a7b9Swdk  *    documentation and/or other materials provided with the distribution.
183f55a7b9Swdk  *
193f55a7b9Swdk  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
203f55a7b9Swdk  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
213f55a7b9Swdk  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223f55a7b9Swdk  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
233f55a7b9Swdk  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
243f55a7b9Swdk  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
253f55a7b9Swdk  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
263f55a7b9Swdk  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
273f55a7b9Swdk  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
283f55a7b9Swdk  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
293f55a7b9Swdk  * POSSIBILITY OF SUCH DAMAGE.
303f55a7b9Swdk  */
313f55a7b9Swdk 
324b2744bfSlukem #include <sys/cdefs.h>
33*b59f66e1Schristos __KERNEL_RCSID(0, "$NetBSD: mkclock.c,v 1.12 2014/11/20 16:34:25 christos Exp $");
344b2744bfSlukem 
353f55a7b9Swdk #include <sys/param.h>
363f55a7b9Swdk #include <sys/kernel.h>
373f55a7b9Swdk #include <sys/device.h>
383f55a7b9Swdk #include <sys/systm.h>
393f55a7b9Swdk 
403f55a7b9Swdk #include <dev/clock_subr.h>
413f55a7b9Swdk 
423f55a7b9Swdk #include <machine/cpu.h>
433f55a7b9Swdk #include <machine/mainboard.h>
443f55a7b9Swdk #include <machine/autoconf.h>
453f55a7b9Swdk #include <machine/sysconf.h>
463f55a7b9Swdk #include <machine/bus.h>
473f55a7b9Swdk 
483f55a7b9Swdk #include <mipsco/obio/clockreg.h>
493f55a7b9Swdk 
503f55a7b9Swdk struct	mkclock_softc {
513f55a7b9Swdk 	bus_space_tag_t	sc_bst;
523f55a7b9Swdk 	bus_space_handle_t sc_bsh;
5312fed6d0Sgdamore 	struct todr_chip_handle sc_todr;
543f55a7b9Swdk };
553f55a7b9Swdk 
56cbab9cadSchs static int mkclock_match (device_t, cfdata_t, void *);
57cbab9cadSchs static void mkclock_attach (device_t, device_t, void *);
583f55a7b9Swdk 
59cbab9cadSchs CFATTACH_DECL_NEW(mkclock, sizeof(struct mkclock_softc),
60c5e91d44Sthorpej     mkclock_match, mkclock_attach, NULL, NULL);
613f55a7b9Swdk 
6212fed6d0Sgdamore int mkclock_read (todr_chip_handle_t, struct clock_ymdhms *);
6312fed6d0Sgdamore int mkclock_write (todr_chip_handle_t, struct clock_ymdhms *);
64bd338a51Smatt 
65bd338a51Smatt static int mk_read (struct mkclock_softc *, int);
66bd338a51Smatt static void mk_write (struct mkclock_softc *, int, int);
673f55a7b9Swdk 
683f55a7b9Swdk int
mkclock_match(device_t parent,cfdata_t cf,void * aux)69cbab9cadSchs mkclock_match(device_t parent, cfdata_t cf, void *aux)
703f55a7b9Swdk {
713f55a7b9Swdk 	return 1;
723f55a7b9Swdk }
733f55a7b9Swdk 
743f55a7b9Swdk void
mkclock_attach(device_t parent,device_t self,void * aux)75cbab9cadSchs mkclock_attach(device_t parent, device_t self, void *aux)
763f55a7b9Swdk {
77cbab9cadSchs         struct mkclock_softc *sc = device_private(self);
783f55a7b9Swdk 	struct confargs *ca = aux;
793f55a7b9Swdk 
803f55a7b9Swdk 	sc->sc_bst = ca->ca_bustag;
813f55a7b9Swdk 	if (bus_space_map(ca->ca_bustag, ca->ca_addr,
823f55a7b9Swdk 			  0x10000,
833f55a7b9Swdk 			  BUS_SPACE_MAP_LINEAR,
843f55a7b9Swdk 			  &sc->sc_bsh) != 0) {
853f55a7b9Swdk 		printf(": cannot map registers\n");
863f55a7b9Swdk 		return;
873f55a7b9Swdk 	}
883f55a7b9Swdk 
8912fed6d0Sgdamore 	sc->sc_todr.todr_settime_ymdhms = mkclock_write;
9012fed6d0Sgdamore 	sc->sc_todr.todr_gettime_ymdhms = mkclock_read;
9112fed6d0Sgdamore 	sc->sc_todr.cookie = sc;
9212fed6d0Sgdamore 	todr_attach(&sc->sc_todr);
9312fed6d0Sgdamore 
943f55a7b9Swdk 	printf("\n");
953f55a7b9Swdk }
963f55a7b9Swdk 
973f55a7b9Swdk static int
mk_read(struct mkclock_softc * sc,int reg)98454af1c0Sdsl mk_read(struct mkclock_softc *sc, int reg)
993f55a7b9Swdk {
1003f55a7b9Swdk 	u_int8_t val;
1013f55a7b9Swdk 
1023f55a7b9Swdk 	val = bus_space_read_1(sc->sc_bst, sc->sc_bsh, DATA_PORT + reg*4);
103*b59f66e1Schristos 	return bcdtobin(val);
1043f55a7b9Swdk }
1053f55a7b9Swdk 
1063f55a7b9Swdk static void
mk_write(struct mkclock_softc * sc,int reg,int val)10782357f6dSdsl mk_write(struct mkclock_softc *sc, int reg, int val)
1083f55a7b9Swdk {
1093f55a7b9Swdk 	bus_space_write_1(sc->sc_bst, sc->sc_bsh,
110*b59f66e1Schristos 			  DATA_PORT + reg*4, bintobcd(val));
1113f55a7b9Swdk }
1123f55a7b9Swdk 
11312fed6d0Sgdamore int
mkclock_read(todr_chip_handle_t tch,struct clock_ymdhms * dt)11412fed6d0Sgdamore mkclock_read(todr_chip_handle_t tch, struct clock_ymdhms *dt)
1153f55a7b9Swdk {
11612fed6d0Sgdamore 	struct mkclock_softc *sc = tch->cookie;
1173f55a7b9Swdk 	int s = splclock();
1183f55a7b9Swdk 
1193f55a7b9Swdk 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, READ_CLOCK);
1203f55a7b9Swdk 	dt->dt_sec  = mk_read(sc, 0);
1213f55a7b9Swdk 	dt->dt_min  = mk_read(sc, 1);
1223f55a7b9Swdk 	dt->dt_hour = mk_read(sc, 2);
1233f55a7b9Swdk 	dt->dt_wday = mk_read(sc, 3);
1243f55a7b9Swdk 	dt->dt_day  = mk_read(sc, 4);
1253f55a7b9Swdk 	dt->dt_mon  = mk_read(sc, 5);
1263f55a7b9Swdk 	dt->dt_year = mk_read(sc, 6);
1273f55a7b9Swdk 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, 0);
1283f55a7b9Swdk 	splx(s);
1293f55a7b9Swdk 
1303f55a7b9Swdk 	dt->dt_year = dt->dt_year + (dt->dt_year >= 70 ? 1900 : 2000);
13112fed6d0Sgdamore 	return 0;
1323f55a7b9Swdk }
1333f55a7b9Swdk 
13412fed6d0Sgdamore int
mkclock_write(todr_chip_handle_t tch,struct clock_ymdhms * dt)13512fed6d0Sgdamore mkclock_write(todr_chip_handle_t tch, struct clock_ymdhms *dt)
1363f55a7b9Swdk {
13712fed6d0Sgdamore 	struct mkclock_softc *sc = tch->cookie;
1383f55a7b9Swdk 	int year, s;
1393f55a7b9Swdk 
1403f55a7b9Swdk 	year = dt->dt_year % 100;
1413f55a7b9Swdk 
1423f55a7b9Swdk 	s = splclock();
1433f55a7b9Swdk 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, SET_CLOCK);
1443f55a7b9Swdk 	mk_write(sc, 0, dt->dt_sec);
1453f55a7b9Swdk 	mk_write(sc, 1, dt->dt_min);
1463f55a7b9Swdk 	mk_write(sc, 2, dt->dt_hour);
1473f55a7b9Swdk 	/* week day not set */
1483f55a7b9Swdk 	mk_write(sc, 4, dt->dt_day);
1493f55a7b9Swdk 	mk_write(sc, 5, dt->dt_mon);
1503f55a7b9Swdk 	mk_write(sc, 6, year);
1513f55a7b9Swdk 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, 0);
1523f55a7b9Swdk 	splx(s);
15312fed6d0Sgdamore 	return 0;
1543f55a7b9Swdk }
155