Index: sys/arm64/rockchip/rk817.c =================================================================== --- sys/arm64/rockchip/rk817.c +++ sys/arm64/rockchip/rk817.c @@ -0,0 +1,739 @@ +/*- + * Copyright (c) 2021 Soren Schmidt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$Id$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include "regdev_if.h" +#include "clock_if.h" + +MALLOC_DEFINE(M_RK817_REG, "RK817 regulator", "RK817 power regulator"); + +#if 0 +#define dprintf(sc, format, arg...) \ + device_printf(sc->base_dev, "%s: " format, __func__, arg) +#else +#define dprintf(sc, format, arg...) +#endif + +enum rk817_type { + RK817 = 1, +}; + +static struct ofw_compat_data compat_data[] = { + {"rockchip,rk817", RK817}, + {NULL, 0} +}; + +struct rk817_regdef { + intptr_t id; + char *name; + uint8_t enable_reg; + uint8_t enable_mask; + uint8_t voltage_reg; + uint8_t voltage_mask; + int voltage_min1; + int voltage_max1; + int voltage_step1; + int voltage_min2; + int voltage_max2; + int voltage_step2; + int voltage_steps; +}; + +struct rk817_reg_sc { + struct regnode *regnode; + device_t base_dev; + struct rk817_regdef *def; + phandle_t xref; + struct regnode_std_param *param; +}; + +struct reg_list { + TAILQ_ENTRY(reg_list) next; + struct rk817_reg_sc *reg; +}; + +struct rk817_softc { + device_t dev; + struct mtx mtx; + struct resource * res[1]; + void * intrcookie; + struct intr_config_hook intr_hook; + enum rk817_type type; + TAILQ_HEAD(, reg_list) regs; + int nregs; +}; + +static struct rk817_regdef rk817_regdefs[] = { + { + .id = RK817_DCDC1, + .name = "DCDC_REG1", + .enable_reg = RK817_DCDC_EN, + .enable_mask = 0x11, + .voltage_reg = RK817_DCDC1_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 500000, + .voltage_max1 = 1487500, + .voltage_min2 = 1500000, + .voltage_max2 = 2400000, + .voltage_step1 = 12500, + .voltage_step2 = 100000, + .voltage_steps = 177, + }, + { + .id = RK817_DCDC2, + .name = "DCDC_REG2", + .enable_reg = RK817_DCDC_EN, + .enable_mask = 0x22, + .voltage_reg = RK817_DCDC2_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 500000, + .voltage_max1 = 1487500, + .voltage_min2 = 1500000, + .voltage_max2 = 2400000, + .voltage_step1 = 12500, + .voltage_step2 = 100000, + .voltage_steps = 177, + }, + { + .id = RK817_DCDC3, + .name = "DCDC_REG3", + .enable_reg = RK817_DCDC_EN, + .enable_mask = 0x44, + .voltage_reg = RK817_DCDC3_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 500000, + .voltage_max1 = 1487500, + .voltage_min2 = 1500000, + .voltage_max2 = 2400000, + .voltage_step1 = 12500, + .voltage_step2 = 100000, + .voltage_steps = 177, + }, + { + .id = RK817_DCDC4, + .name = "DCDC_REG4", + .enable_reg = RK817_DCDC_EN, + .enable_mask = 0x88, + .voltage_reg = RK817_DCDC4_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 500000, + .voltage_max1 = 1487500, + .voltage_min2 = 1500000, + .voltage_max2 = 3400000, + .voltage_step1 = 12500, + .voltage_step2 = 100000, + .voltage_steps = 195, + }, + { + .id = RK817_LDO1, + .name = "LDO_REG1", + .enable_reg = RK817_LDO_EN1, + .enable_mask = 0x11, + .voltage_reg = RK817_LDO1_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO2, + .name = "LDO_REG2", + .enable_reg = RK817_LDO_EN1, + .enable_mask = 0x22, + .voltage_reg = RK817_LDO2_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO3, + .name = "LDO_REG3", + .enable_reg = RK817_LDO_EN1, + .enable_mask = 0x44, + .voltage_reg = RK817_LDO3_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO4, + .name = "LDO_REG4", + .enable_reg = RK817_LDO_EN1, + .enable_mask = 0x88, + .voltage_reg = RK817_LDO4_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO5, + .name = "LDO_REG5", + .enable_reg = RK817_LDO_EN2, + .enable_mask = 0x11, + .voltage_reg = RK817_LDO5_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO6, + .name = "LDO_REG6", + .enable_reg = RK817_LDO_EN2, + .enable_mask = 0x22, + .voltage_reg = RK817_LDO6_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO7, + .name = "LDO_REG7", + .enable_reg = RK817_LDO_EN2, + .enable_mask = 0x44, + .voltage_reg = RK817_LDO7_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO8, + .name = "LDO_REG8", + .enable_reg = RK817_LDO_EN2, + .enable_mask = 0x88, + .voltage_reg = RK817_LDO8_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_LDO9, + .name = "LDO_REG9", + .enable_reg = RK817_LDO_EN3, + .enable_mask = 0x11, + .voltage_reg = RK817_LDO9_ON_VSEL, + .voltage_mask = 0x7f, + .voltage_min1 = 600000, + .voltage_max1 = 3400000, + .voltage_step1 = 25000, + .voltage_steps = 112, + }, + { + .id = RK817_BOOST, + .name = "BOOST", + .enable_reg = RK817_LDO_EN3, + .enable_mask = 0x22, + .voltage_reg = RK817_BOOST_ON_VSEL, + .voltage_mask = 0x07, + .voltage_min1 = 4700000, + .voltage_max1 = 5400000, + .voltage_step1 = 100000, + .voltage_steps = 8, + }, +}; + +static int +rk817_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) +{ + return iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT); +} + +static int +rk817_write(device_t dev, uint8_t reg, uint8_t data) +{ + return iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT); +} + +static void +rk817_regnode_reg_to_voltage(struct rk817_reg_sc *sc, uint8_t steps, int *uv) +{ + if (sc->def->voltage_step2) { + int change; + + change = ((sc->def->voltage_min2 - sc->def->voltage_min1) / sc->def->voltage_step1); + if (steps > change) { + if (steps < sc->def->voltage_steps) + *uv = sc->def->voltage_min2 + (steps - change) * sc->def->voltage_step2; + else + *uv = sc->def->voltage_max2; + return; + } + } + if (steps < sc->def->voltage_steps) + *uv = sc->def->voltage_min1 + steps * sc->def->voltage_step1; + else + *uv = sc->def->voltage_max1; +} + +static int +rk817_regnode_voltage_to_reg(struct rk817_reg_sc *sc, int min_uvolt, int max_uvolt, uint8_t *steps) +{ + uint8_t count; + int uvolt; + + uvolt = sc->def->voltage_min1; + for (count = 0; count < sc->def->voltage_steps && uvolt < min_uvolt; count++) { + if (uvolt < sc->def->voltage_min2) + uvolt += sc->def->voltage_step1; + else + uvolt += sc->def->voltage_step2; + } + if (uvolt > max_uvolt) + return EINVAL; + *steps = count; + return 0; +} + +static int +rk817_regnode_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt, int *udelay) +{ + struct rk817_reg_sc *sc = regnode_get_softc(regnode); + uint8_t val; + int uvolt; + + if (!sc->def->voltage_step1 && + (sc->def->voltage_min1 != sc->def->voltage_max1)) + return ENXIO; + + dprintf(sc, "Setting %s to %d<->%d uvolts\n", + sc->def->name, min_uvolt, max_uvolt); + + rk817_read(sc->base_dev, sc->def->voltage_reg, &val, 1); + if (rk817_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0) + return ERANGE; + + rk817_write(sc->base_dev, sc->def->voltage_reg, val); + rk817_read(sc->base_dev, sc->def->voltage_reg, &val, 1); + + *udelay = 0; + + rk817_regnode_reg_to_voltage(sc, val, &uvolt); + + dprintf(sc, "Regulator %s set to %d uvolt\n", sc->def->name, uvolt); + + return 0; +} + +static int +rk817_regnode_get_voltage(struct regnode *regnode, int *uvolt) +{ + struct rk817_reg_sc *sc = regnode_get_softc(regnode); + uint8_t val; + + if (sc->def->voltage_min1 == sc->def->voltage_max1) { + *uvolt = sc->def->voltage_min1; + return 0; + } + + if (!sc->def->voltage_step1) + return ENXIO; + + rk817_read(sc->base_dev, sc->def->voltage_reg, &val, 1); + rk817_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt); + + dprintf(sc, "Regulator %s is at %d uvolt\n", sc->def->name, *uvolt); + + return (0); +} + +static int +rk817_regnode_status(struct regnode *regnode, int *status) +{ + struct rk817_reg_sc *sc = regnode_get_softc(regnode); + uint8_t val; + + *status = 0; + rk817_read(sc->base_dev, sc->def->enable_reg, &val, 1); + if (val & sc->def->enable_mask) + *status = REGULATOR_STATUS_ENABLED; + + return 0; +} + +static int +rk817_regnode_init(struct regnode *regnode) +{ + struct regnode_std_param *param = regnode_get_stdparam(regnode); + int retval, uvolt, udelay, status; + + if (!param->min_uvolt) + return 0; + + /* Check that the regulator is preset to the correct voltage */ + if ((retval = rk817_regnode_get_voltage(regnode, &uvolt))) + return retval; + if (uvolt >= param->min_uvolt && uvolt <= param->max_uvolt) + return 0; + + /* if the regulator is enabled dont touch it */ + retval = rk817_regnode_status(regnode, &status); + if (retval || status == REGULATOR_STATUS_ENABLED) + return retval; + + /* + * Set regulator at the correct voltage if it is not enabled. + * Do not enable it, this is will be done either by a + * consumer or by regnode_set_constraint if boot_on is true + */ + retval = rk817_regnode_set_voltage(regnode, param->min_uvolt, + param->max_uvolt, &udelay); + if (udelay) + DELAY(udelay); + + return retval; +} + +static int +rk817_regnode_enable(struct regnode *regnode, bool enable, int *udelay) +{ + struct rk817_reg_sc *sc = regnode_get_softc(regnode); + uint8_t val; + + dprintf(sc, "%sabling regulator %s\n", + enable ? "En" : "Dis", sc->def->name); + rk817_read(sc->base_dev, sc->def->enable_reg, &val, 1); + if (enable) + val |= sc->def->enable_mask; + else + val &= ~sc->def->enable_mask; + rk817_write(sc->base_dev, sc->def->enable_reg, val); + + *udelay = 0; + + return 0; +} + +static regnode_method_t rk817_regnode_methods[] = { + /* Regulator interface */ + REGNODEMETHOD(regnode_init, rk817_regnode_init), + REGNODEMETHOD(regnode_enable, rk817_regnode_enable), + REGNODEMETHOD(regnode_status, rk817_regnode_status), + REGNODEMETHOD(regnode_set_voltage, rk817_regnode_set_voltage), + REGNODEMETHOD(regnode_get_voltage, rk817_regnode_get_voltage), + REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage), + REGNODEMETHOD_END +}; +DEFINE_CLASS_1(rk817_regnode, rk817_regnode_class, rk817_regnode_methods, + sizeof(struct rk817_reg_sc), regnode_class); + +static struct rk817_reg_sc * +rk817_reg_attach(device_t dev, phandle_t node, struct rk817_regdef *def) +{ + struct rk817_reg_sc *reg_sc; + struct regnode_init_def initdef; + struct regnode *regnode; + + memset(&initdef, 0, sizeof(initdef)); + if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) { + device_printf(dev, "cannot create regulator\n"); + return (NULL); + } + if (initdef.std_param.min_uvolt == 0) + initdef.std_param.min_uvolt = def->voltage_min1; + if (initdef.std_param.max_uvolt == 0) + initdef.std_param.max_uvolt = def->voltage_max1; + initdef.id = def->id; + initdef.ofw_node = node; + + regnode = regnode_create(dev, &rk817_regnode_class, &initdef); + if (regnode == NULL) { + device_printf(dev, "cannot create regulator\n"); + return (NULL); + } + + reg_sc = regnode_get_softc(regnode); + reg_sc->regnode = regnode; + reg_sc->base_dev = dev; + reg_sc->def = def; + reg_sc->xref = OF_xref_from_node(node); + reg_sc->param = regnode_get_stdparam(regnode); + regnode_register(regnode); + return (reg_sc); +} + +static void +rk817_shutdown(void *devp, int howto) +{ + device_t dev = (device_t)devp; + + if (howto & RB_POWEROFF) { + if (bootverbose) + device_printf(dev, "Shutdown RK817 PMIC\n"); + rk817_write(dev, RK817_SYS_CFG3, 0x01); + return; + } + if (howto & RB_POWERCYCLE) { + if (bootverbose) + device_printf(dev, "Powercycle RK817 PMIC\n"); + rk817_write(dev, RK817_SYS_CFG3, 0x04); + return; + } + if (bootverbose) + device_printf(dev, "Shutdown called howto=0x%x unhandled\n", + howto); +} + +static int +rk817_rtc_gettime(device_t dev, struct timespec *ts) +{ + struct bcd_clocktime ct; + uint8_t reg, val; + + /* read ctrl reg, set 24h and read from shadow regs mode */ + reg = RK817_RTC_CTRL_REG; + rk817_read(dev, reg, &val, 1); + val &= ~((1<<3) | (1<<6)); + val |= (1<<7); + rk817_write(dev, reg, val); + + /* latch clock regs to shadow regs */ + rk817_write(dev, reg, val | (1<<6)); + + /* wait one 32khz cycle for clock shadow registers to latch */ + DELAY(1000000 / 32000); + + /* release latch */ + rk817_write(dev, reg, val); + + /* read registers */ + rk817_read(dev, RK817_SECONDS_REG, &ct.sec, 1); + rk817_read(dev, RK817_MINUTES_REG, &ct.min, 1); + rk817_read(dev, RK817_HOURS_REG, &ct.hour, 1); + rk817_read(dev, RK817_DAYS_REG, &ct.day, 1); + rk817_read(dev, RK817_MONTHS_REG, &ct.mon, 1); + rk817_read(dev, RK817_WEEKS_REG, &ct.dow, 1); + rk817_read(dev, RK817_YEARS_REG, &val, 1); + + ct.year = val + 0x2000; /* valid for 2000-2099 only */ + if (ct.dow == 7) /* our sunday is 0 not 7 */ + ct.dow = 0; + ct.nsec = 0; /* RTC resolution is 1 sec */ + + if (bootverbose) + device_printf(dev, "gettime %04x-%02x-%02x %02x:%02x:%02x\n", + ct.year, ct.mon, ct.day, ct.hour, ct.min, ct.sec); + + return (clock_bcd_to_ts(&ct, ts, false)); +} + +static int +rk817_rtc_settime(device_t dev, struct timespec *ts) +{ + struct bcd_clocktime ct; + uint8_t reg, val; + + reg = RK817_RTC_CTRL_REG; + clock_ts_to_bcd(ts, &ct, false); + + if (bootverbose) + device_printf(dev, "settime %04x-%02x-%02x %02x:%02x:%02x\n", + ct.year, ct.mon, ct.day, ct.hour, ct.min, ct.sec); + + /* valid for 2000-2099 only */ + if ((ct.year & 0xff00) != 0x2000) { + device_printf(dev, "year out of range\n"); + return EINVAL; + } + ct.year &= 0x00ff; + + /* read ctrl reg and set 24h mode as default */ + rk817_read(dev, reg, &val, 1); + val &= ~(1<<3); + + /* stop RTC clock */ + rk817_write(dev, reg, val | (1<<0)); + + /* update registers */ + rk817_write(dev, RK817_SECONDS_REG, ct.sec); + rk817_write(dev, RK817_MINUTES_REG, ct.min); + rk817_write(dev, RK817_HOURS_REG, ct.hour); + rk817_write(dev, RK817_DAYS_REG, ct.day); + rk817_write(dev, RK817_MONTHS_REG, ct.mon); + rk817_write(dev, RK817_WEEKS_REG, (ct.dow == 0) ? 7 : ct.dow); + rk817_write(dev, RK817_YEARS_REG, ct.year); + + /* start RTC clock */ + rk817_write(dev, reg, val & ~(1<<0)); + + return 0; +} + +static int +rk817_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + case RK817: + device_set_desc(dev, "RockChip RK817 PMIC"); + break; + default: + return (ENXIO); + } + + return (BUS_PROBE_DEFAULT); +} + +static int +rk817_attach(device_t dev) +{ + struct rk817_softc *sc = device_get_softc(dev); + struct rk817_reg_sc *reg; + struct rk817_regdef *regdefs; + struct reg_list *regp; + phandle_t rnode, child; + int i; + + sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + switch (sc->type) { + case RK817: + regdefs = rk817_regdefs; + sc->nregs = nitems(rk817_regdefs); + break; + default: + device_printf(dev, "Unknown type %d\n", sc->type); + return (ENXIO); + } + + TAILQ_INIT(&sc->regs); + rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators"); + if (rnode > 0) { + for (i = 0; i < sc->nregs; i++) { + if (!(child=ofw_bus_find_child(rnode, regdefs[i].name))) + continue; + if (OF_hasprop(child, "regulator-name") != 1) + continue; + if (!(reg = rk817_reg_attach(dev, child, ®defs[i]))) + device_printf(dev, + "cannot attach regulator %s\n", + regdefs[i].name); + regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK|M_ZERO); + regp->reg = reg; + TAILQ_INSERT_TAIL(&sc->regs, regp, next); + if (bootverbose) + device_printf(dev, "Regulator %s attached\n", + regdefs[i].name); + } + } + + /* Register this as a 1Hz clock */ + clock_register(dev, 1000000); + + /* Register shutdown method */ + EVENTHANDLER_REGISTER(shutdown_final, rk817_shutdown, dev, + SHUTDOWN_PRI_LAST - 100); + + return 0; +} + +static int +rk817_detach(device_t dev) +{ + /* We cannot detach regulators */ + return EBUSY; +} + +static int +rk817_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells, intptr_t *id) +{ + struct rk817_softc *sc = device_get_softc(dev);; + struct reg_list *regp; + + TAILQ_FOREACH(regp, &sc->regs, next) { + if (regp->reg->xref == xref) { + *id = regp->reg->def->id; + return 0; + } + } + return ERANGE; +} + +static device_method_t rk817_methods[] = { + DEVMETHOD(device_probe, rk817_probe), + DEVMETHOD(device_attach, rk817_attach), + DEVMETHOD(device_detach, rk817_detach), + + /* regdev interface */ + DEVMETHOD(regdev_map, rk817_map), + + /* Clock interface */ + DEVMETHOD(clock_gettime, rk817_rtc_gettime), + DEVMETHOD(clock_settime, rk817_rtc_settime), + + DEVMETHOD_END +}; + +static driver_t rk817_driver = { + "rk817_pmic", + rk817_methods, + sizeof(struct rk817_softc), +}; + +static devclass_t rk817_devclass; + +EARLY_DRIVER_MODULE(rk817, iicbus, rk817_driver, rk817_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST); +MODULE_DEPEND(rk817, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); +MODULE_VERSION(rk817, 1); Index: sys/arm64/rockchip/rk817reg.h =================================================================== --- sys/arm64/rockchip/rk817reg.h +++ sys/arm64/rockchip/rk817reg.h @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2021 Soren Schmidt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + + +#ifndef _RK8XXREG_H_ +#define _RK8XXREG_H_ + +#define RK817_SECONDS_REG 0x00 +#define RK817_MINUTES_REG 0x01 +#define RK817_HOURS_REG 0x02 +#define RK817_DAYS_REG 0x03 +#define RK817_MONTHS_REG 0x04 +#define RK817_YEARS_REG 0x05 +#define RK817_WEEKS_REG 0x06 +#define RK817_RTC_CTRL_REG 0x0d +#define RK817_RTC_STATUS_REG 0x0e +#define RK817_RTC_INT_REG 0x0f +#define RK817_RTC_COMP_LSB_REG 0x10 +#define RK817_RTC_COMP_MSB_REG 0x11 + +#define RK817_DCDC_EN 0xb1 +#define RK817_LDO_EN1 0xb2 +#define RK817_LDO_EN2 0xb3 +#define RK817_LDO_EN3 0xb4 +#define RK817_DCDC1_ON_VSEL 0xbb +#define RK817_DCDC2_ON_VSEL 0xbe +#define RK817_DCDC3_ON_VSEL 0xc1 +#define RK817_DCDC4_ON_VSEL 0xc4 +#define RK817_LDO1_ON_VSEL 0xcc +#define RK817_LDO2_ON_VSEL 0xce +#define RK817_LDO3_ON_VSEL 0xd0 +#define RK817_LDO4_ON_VSEL 0xd2 +#define RK817_LDO5_ON_VSEL 0xd4 +#define RK817_LDO6_ON_VSEL 0xd6 +#define RK817_LDO7_ON_VSEL 0xd8 +#define RK817_LDO8_ON_VSEL 0xda +#define RK817_LDO9_ON_VSEL 0xdc +#define RK817_BOOST_ON_VSEL 0xde +#define RK817_SYS_CFG3 0xf4 + +enum rk817_regulator { + RK817_DCDC1 = 0, + RK817_DCDC2, + RK817_DCDC3, + RK817_DCDC4, + RK817_LDO1, + RK817_LDO2, + RK817_LDO3, + RK817_LDO4, + RK817_LDO5, + RK817_LDO6, + RK817_LDO7, + RK817_LDO8, + RK817_LDO9, + RK817_BOOST, + RK817_OTG_SWITCH, +}; + +#endif /* _RK8XXREG_H_ */