Index: sys/arm64/rockchip/rk805.c =================================================================== --- sys/arm64/rockchip/rk805.c +++ sys/arm64/rockchip/rk805.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include +#include "clock_if.h" #include "regdev_if.h" MALLOC_DEFINE(M_RK805_REG, "RK805 regulator", "RK805 power regulator"); @@ -233,9 +235,9 @@ } static int -rk805_write(device_t dev, uint8_t reg, uint8_t data) +rk805_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) { - return (iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT)); + return (iicdev_writeto(dev, reg, data, size, IIC_INTRWAIT)); } static int @@ -260,7 +262,7 @@ val |= sc->def->enable_mask; else val &= ~sc->def->enable_mask; - rk805_write(sc->base_dev, sc->def->enable_reg, val); + rk805_write(sc->base_dev, sc->def->enable_reg, &val, 1); *udelay = 0; @@ -320,7 +322,7 @@ if (rk805_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0) return (ERANGE); - rk805_write(sc->base_dev, sc->def->voltage_reg, val); + rk805_write(sc->base_dev, sc->def->voltage_reg, &val, 1); rk805_read(sc->base_dev, sc->def->voltage_reg, &val, 1); @@ -447,9 +449,77 @@ device_printf(dev, "Chip Version: %x\n", data[1] & 0xf); } + /* Register this as a 1Hz clock */ + clock_register(dev, 1000000); + config_intrhook_disestablish(&sc->intr_hook); } +static int +rk805_gettime(device_t dev, struct timespec *ts) +{ + struct bcd_clocktime bct; + uint8_t data[7]; + int error; + + /* This works as long as RK805_RTC_SECS = 0 */ + error = rk805_read(dev, RK805_RTC_SECS, data, 7); + if (error != 0) + return (error); + + memset(&bct, 0, sizeof(bct)); + bct.year = data[RK805_RTC_YEARS]; + bct.mon = data[RK805_RTC_MONTHS] & RK805_RTC_MONTHS_MASK; + bct.day = data[RK805_RTC_DAYS] & RK805_RTC_DAYS_MASK; + bct.hour = data[RK805_RTC_HOURS] & RK805_RTC_HOURS_MASK; + bct.min = data[RK805_RTC_MINUTES] & RK805_RTC_MINUTES_MASK; + bct.sec = data[RK805_RTC_SECS] & RK805_RTC_SECS_MASK; + bct.dow = data[RK805_RTC_WEEKS] & RK805_RTC_WEEKS_MASK; + /* The day of week is reported as 1-7 with 1 = Monday */ + if (bct.dow == 7) + bct.dow = 0; + bct.ispm = (data[RK805_RTC_HOURS] & RK805_RTC_HOURS_PM) != 0; + + return (clock_bcd_to_ts(&bct, ts, true)); +} + +static int +rk805_settime(device_t dev, struct timespec *ts) +{ + struct bcd_clocktime bct; + uint8_t data[7]; + int error; + uint8_t ctrl; + + clock_ts_to_bcd(ts, &bct, true); + + data[RK805_RTC_YEARS] = bct.year; + data[RK805_RTC_MONTHS] = bct.mon; + data[RK805_RTC_DAYS] = bct.day; + data[RK805_RTC_HOURS] = bct.hour | (bct.ispm ? RK805_RTC_HOURS_PM : 0); + data[RK805_RTC_MINUTES] = bct.min; + data[RK805_RTC_SECS] = bct.sec; + data[RK805_RTC_WEEKS] = bct.dow; + /* The day of week is reported as 1-7 with 1 = Monday */ + if (data[RK805_RTC_WEEKS] == 0) + data[RK805_RTC_WEEKS] = 7; + + error = rk805_read(dev, RK805_RTC_CTRL, &ctrl, 1); + if (error != 0) + return (error); + + ctrl |= RK805_RTC_CTRL_STOP; + error = rk805_write(dev, RK805_RTC_CTRL, &ctrl, 1); + if (error != 0) + return (error); + + error = rk805_write(dev, RRK805_RTC_SECS, data, 7); + ctrl &= ~RK805_RTC_CTRL_STOP; + rk805_write(dev, RK805_RTC_CTRL, &ctrl, 1); + + return (error); +} + static int rk805_attach(device_t dev) { @@ -543,6 +613,11 @@ /* regdev interface */ DEVMETHOD(regdev_map, rk805_map), + + /* Clock interface */ + DEVMETHOD(clock_gettime, rk805_gettime), + DEVMETHOD(clock_settime, rk805_settime), + DEVMETHOD_END }; Index: sys/arm64/rockchip/rk805reg.h =================================================================== --- sys/arm64/rockchip/rk805reg.h +++ sys/arm64/rockchip/rk805reg.h @@ -31,6 +31,24 @@ #ifndef _RK805REG_H_ #define _RK805REG_H_ +#define RK805_RTC_SECS 0x00 +#define RK805_RTC_SECS_MASK 0x7f +#define RK805_RTC_MINUTES 0x01 +#define RK805_RTC_MINUTES_MASK 0x7f +#define RK805_RTC_HOURS 0x02 +#define RK805_RTC_HOURS_MASK 0x3f +#define RK805_RTC_HOURS_PM 0x80 +#define RK805_RTC_DAYS 0x03 +#define RK805_RTC_DAYS_MASK 0x3f +#define RK805_RTC_MONTHS 0x04 +#define RK805_RTC_MONTHS_MASK 0x1f +#define RK805_RTC_YEARS 0x05 +#define RK805_RTC_WEEKS 0x06 /* day of week */ +#define RK805_RTC_WEEKS_MASK 0x07 + +#define RK805_RTC_CTRL 0x10 +#define RK805_RTC_CTRL_STOP (1 << 0) + #define RK805_CHIP_NAME 0x17 #define RK805_CHIP_VER 0x18 #define RK805_OTP_VER 0x19