diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index fb29843a5a..8be3c071ca 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -33,6 +33,15 @@ config DM_PMIC_MAX77686 This config enables implementation of driver-model pmic uclass features for PMIC MAX77686. The driver implements read/write operations. +config PMIC_RK808 + bool "Enable support for Rockchip PMIC RK808" + depends on DM_PMIC + ---help--- + The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs, + an RTC and two low Rds (resistance (drain to source)) switches. It is + accessed via an I2C interface. The device is used with Rockchip SoCs. + This driver implements register read/write operations. + config PMIC_S2MPS11 bool "Enable Driver Model for PMIC Samsung S2MPS11" depends on DM_PMIC diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 91e78f8149..c6e8d0c610 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_ACT8846) += act8846.o +obj-$(CONFIG_PMIC_RK808) += rk808.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o diff --git a/drivers/power/pmic/rk808.c b/drivers/power/pmic/rk808.c new file mode 100644 index 0000000000..11d5f07767 --- /dev/null +++ b/drivers/power/pmic/rk808.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "DCDC_REG", .driver = "rk808_buck"}, + { .prefix = "LDO_REG", .driver = "rk808_ldo"}, + { .prefix = "SWITCH_REG", .driver = "rk808_switch"}, + { }, +}; + +static int rk808_reg_count(struct udevice *dev) +{ + return RK808_NUM_OF_REGS; +} + +static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + debug("write error to device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + debug("read error from device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) +static int rk808_bind(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int regulators_node; + int children; + + regulators_node = fdt_subnode_offset(blob, dev->of_offset, + "regulators"); + if (regulators_node <= 0) { + debug("%s: %s regulators subnode not found!", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} +#endif + +static struct dm_pmic_ops rk808_ops = { + .reg_count = rk808_reg_count, + .read = rk808_read, + .write = rk808_write, +}; + +static const struct udevice_id rk808_ids[] = { + { .compatible = "rockchip,rk808" }, + { } +}; + +U_BOOT_DRIVER(pmic_rk808) = { + .name = "rk808 pmic", + .id = UCLASS_PMIC, + .of_match = rk808_ids, +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) + .bind = rk808_bind, +#endif + .ops = &rk808_ops, +}; diff --git a/include/power/rk808_pmic.h b/include/power/rk808_pmic.h new file mode 100644 index 0000000000..fb0800b9cb --- /dev/null +++ b/include/power/rk808_pmic.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _PMIC_RK808_H_ +#define _PMIC_RK808_H_ + +enum { + REG_DCDC_EN = 0x23, + REG_LDO_EN, + REG_SLEEP_SET_OFF1, + REG_SLEEP_SET_OFF2, + REG_DCDC_UV_STS, + + REG_DCDC_UV_ACT, + REG_LDO_UV_STS, + REG_LDO_UV_ACT, + REG_DCDC_PG, + REG_LDO_PG, + REG_VOUT_MON_TDB, + REG_BUCK1_CONFIG, + REG_BUCK1_ON_VSEL, + + REG_BUCK1_SLP_VSEL, + REG_BUCK1_DVS_VSEL, + REG_BUCK2_CONFIG, + REG_BUCK2_ON_VSEL, + REG_BUCK2_SLP_VSEL, + REG_BUCK2_DVS_VSEL, + REG_BUCK3_CONFIG, + REG_BUCK4_CONFIG, + + REG_BUCK4_ON_VSEL, + REG_BUCK4_SLP_VSEL, + LDO1_ON_VSEL = 0x3b, + LDO1_SLP_VSEL, + LDO2_ON_VSEL, + LDO2_SLP_VSEL, + LDO3_ON_VSEL, + + LDO3_SLP_VSEL, + LDO4_ON_VSEL, + LDO4_SLP_VSEL, + LDO5_ON_VSEL, + LDO5_SLP_VSEL, + LDO6_ON_VSEL, + LDO6_SLP_VSEL, + LDO7_ON_VSEL, + + LDO7_SLP_VSEL, + LDO8_ON_VSEL, + LDO8_SLP_VSEL, + DEVCTRL, + INT_STS1, + INT_STS_MSK1, + INT_STS2, + INT_STS_MSK2, + IO_POL, + + /* Not sure what this does */ + DCDC_ILMAX = 0x90, + + RK808_NUM_OF_REGS, +}; + +struct rk808_reg_table { + char *name; + u8 reg_ctl; + u8 reg_vol; +}; + +int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt); + +#endif