2 * Copyright (c) 2003-2012 Broadcom Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
37 #include <sys/clock.h>
39 #include <sys/resource.h>
42 #include <dev/iicbus/iiconf.h>
43 #include <dev/iicbus/iicbus.h>
45 #include "iicbus_if.h"
48 #define DS1374_RTC_COUNTER 0 /* counter (bytes 0-3) */
56 ds1374_probe(device_t dev)
58 device_set_desc(dev, "DS1374 RTC");
63 ds1374_attach(device_t dev)
65 struct ds1374_softc *sc = device_get_softc(dev);
68 printf("ds1374_attach device_get_softc failed\n");
72 sc->sc_addr = iicbus_get_addr(dev);
74 clock_register(dev, 1000);
79 ds1374_settime(device_t dev, struct timespec *ts)
81 /* NB: register pointer precedes actual data */
82 uint8_t data[5] = { DS1374_RTC_COUNTER };
83 struct ds1374_softc *sc = device_get_softc(dev);
84 struct iic_msg msgs[1] = {
85 { sc->sc_addr, IIC_M_WR, 5, data },
88 data[1] = (ts->tv_sec >> 0) & 0xff;
89 data[2] = (ts->tv_sec >> 8) & 0xff;
90 data[3] = (ts->tv_sec >> 16) & 0xff;
91 data[4] = (ts->tv_sec >> 24) & 0xff;
93 return iicbus_transfer(dev, msgs, 1);
97 ds1374_gettime(device_t dev, struct timespec *ts)
99 struct ds1374_softc *sc = device_get_softc(dev);
100 uint8_t addr[1] = { DS1374_RTC_COUNTER };
102 struct iic_msg msgs[2] = {
103 { sc->sc_addr, IIC_M_WR, 1, addr },
104 { sc->sc_addr, IIC_M_RD, 4, secs },
108 error = iicbus_transfer(dev, msgs, 2);
110 /* counter has seconds since epoch */
111 ts->tv_sec = (secs[3] << 24) | (secs[2] << 16)
112 | (secs[1] << 8) | (secs[0] << 0);
118 static device_method_t ds1374_methods[] = {
119 DEVMETHOD(device_probe, ds1374_probe),
120 DEVMETHOD(device_attach, ds1374_attach),
122 DEVMETHOD(clock_gettime, ds1374_gettime),
123 DEVMETHOD(clock_settime, ds1374_settime),
128 static driver_t ds1374_driver = {
131 sizeof(struct ds1374_softc),
133 static devclass_t ds1374_devclass;
135 DRIVER_MODULE(ds1374, iicbus, ds1374_driver, ds1374_devclass, 0, 0);
136 MODULE_VERSION(ds1374, 1);
137 MODULE_DEPEND(ds1374, iicbus, 1, 1, 1);