41#include "opt_platform.h"
47#include <sys/kernel.h>
49#include <sys/module.h>
53#include <dev/ofw/ofw_bus.h>
54#include <dev/ofw/ofw_bus_subr.h>
69#define ISL12XX_SC_REG 0x00
71#define ISL12XX_SR_REG 0x07
72#define ISL12XX_SR_ARST (1u << 7)
73#define ISL12XX_SR_XTOSCB (1u << 5)
74#define ISL12XX_SR_WRTC (1u << 4)
75#define ISL12XX_SR_EVT (1u << 3)
76#define ISL12XX_SR_ALM (1u << 2)
77#define ISL12XX_SR_BAT (1u << 1)
78#define ISL12XX_SR_RTCF (1u << 0)
79#define ISL12XX_SR_W0C_BITS (ISL12XX_SR_BAT | ISL12XX_SR_ALM | ISL12XX_SR_EVT)
81#define ISL12XX_INT_REG 0x08
82#define ISL12XX_INT_IM (1u << 7)
83#define ISL12XX_INT_ALME (1u << 6)
84#define ISL12XX_INT_LPMODE (1u << 5)
85#define ISL12XX_INT_FOBATB (1u << 4)
86#define ISL12XX_INT_FO_SHIFT 0
87#define ISL12XX_INT_FO_MASK 0x0f
89#define ISL12XX_EV_REG 0x09
90#define ISL12XX_EV_EVIENB (1u << 7)
91#define ISL12XX_EV_EVBATB (1u << 6)
92#define ISL12XX_EV_RTCHLT (1u << 5)
93#define ISL12XX_EV_EVEN (1u << 4)
94#define ISL12XX_EV_EHYS_SHIFT 2
95#define ISL12XX_EV_EHYS_MASK 0x03
96#define ISL12XX_EV_ESMP_SHIFT 0
97#define ISL12XX_EV_ESMP_MASK 0x03
99#define ISL12XX_ATR_REG 0x0a
101#define ISL12XX_DTR_REG 0x0b
103#define ISL12XX_SCA_REG 0x0c
105#define ISL12XX_USR1_REG 0x12
107#define ISL12XX_USR2_REG 0x13
109#define ISL12XX_SCT_REG 0x14
111#define ISL12XX_24HR_FLAG (1u << 7)
112#define ISL12XX_PM_FLAG (1u << 5)
113#define ISL12xx_12HR_MASK 0x1f
114#define ISL12xx_24HR_MASK 0x3f
126 struct intr_config_hook
149#define WAITFLAGS (IIC_WAIT | IIC_RECURSIVE)
171 config_intrhook_disestablish(&sc->
init_hook);
179 device_printf(sc->
dev,
180 "RTC clock stopped; check battery\n");
186 clock_register_flags(sc->
dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
187 clock_schedule(sc->
dev, 1);
195 if (!ofw_bus_status_okay(
dev))
199 device_set_desc(
dev,
"Intersil ISL12xx RTC");
200 return (BUS_PROBE_DEFAULT);
220 if (config_intrhook_establish(&sc->
init_hook) != 0)
230 clock_unregister(
dev);
238 struct bcd_clocktime bct;
241 uint8_t hourmask, sreg;
271 bct.hour = tregs.
hour & hourmask;
273 bct.mon = tregs.
month;
274 bct.year = tregs.
year;
277 clock_dbgprint_bcd(sc->
dev, CLOCK_DBG_READ, &bct);
278 return (clock_bcd_to_ts(&bct, ts, sc->
use_ampm));
285 struct bcd_clocktime bct;
288 uint8_t ampmflags, sreg;
294 ts->tv_sec -= utc_offset();
296 clock_ts_to_bcd(ts, &bct, sc->
use_ampm);
297 clock_dbgprint_bcd(sc->
dev, CLOCK_DBG_WRITE, &bct);
307 tregs.
hour = bct.hour | ampmflags;
309 tregs.
month = bct.mon;
310 tregs.
year = bct.year % 100;
329 sreg &= ~ISL12XX_SR_WRTC;
static ds13_compat_data compat_data[]
int iicbus_request_bus(device_t bus, device_t dev, int how)
int iicbus_release_bus(device_t bus, device_t dev)
int iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer, uint16_t buflen, int waithow)
int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer, uint16_t buflen, int waithow)
#define ISL12XX_24HR_FLAG
#define ISL12xx_12HR_MASK
static int isl12xx_read1(struct isl12xx_softc *sc, uint8_t reg, uint8_t *data)
DRIVER_MODULE(isl12xx, iicbus, isl12xx_driver, isl12xx_devclass, NULL, NULL)
static driver_t isl12xx_driver
static int isl12xx_write1(struct isl12xx_softc *sc, uint8_t reg, uint8_t val)
#define ISL12XX_SR_W0C_BITS
static void isl12xx_init(void *arg)
static int isl12xx_attach(device_t dev)
static int isl12xx_gettime(device_t dev, struct timespec *ts)
static devclass_t isl12xx_devclass
MODULE_DEPEND(isl12xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
MODULE_VERSION(isl12xx, 1)
static int isl12xx_detach(device_t dev)
IICBUS_FDT_PNP_INFO(compat_data)
static int isl12xx_settime(device_t dev, struct timespec *ts)
static device_method_t isl12xx_methods[]
static int isl12xx_probe(device_t dev)
#define ISL12xx_24HR_MASK
struct intr_config_hook init_hook