From 453c5a927cddf19344a73f8d850ed6a317da54d2 Mon Sep 17 00:00:00 2001 From: Jacob Chen Date: Tue, 2 May 2017 14:54:52 +0800 Subject: power: rk808: rename to rk8xx Since this driver can be used for rk8xx series pmic, let's rename rk808 to rk8xx, to make it clear. Configs parts are done by sed -i "s/RK808/RK8XX/g" `grep RK808 -lr ./` Signed-off-by: Jacob Chen --- drivers/power/pmic/Kconfig | 6 +- drivers/power/pmic/Makefile | 2 +- drivers/power/pmic/rk808.c | 118 ------------- drivers/power/pmic/rk8xx.c | 118 +++++++++++++ drivers/power/regulator/Kconfig | 8 +- drivers/power/regulator/Makefile | 2 +- drivers/power/regulator/rk808.c | 353 --------------------------------------- drivers/power/regulator/rk8xx.c | 353 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 480 insertions(+), 480 deletions(-) delete mode 100644 drivers/power/pmic/rk808.c create mode 100644 drivers/power/pmic/rk8xx.c delete mode 100644 drivers/power/regulator/rk808.c create mode 100644 drivers/power/regulator/rk8xx.c (limited to 'drivers/power') diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 4891b1704e..3f50c12157 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -28,7 +28,7 @@ config SPL_PMIC_CHILDREN This allows PMICs to support child devices (such as regulators) in SPL. This adds quite a bit of code so if you are not using this feature you can turn it off. In this case you may need a 'back door' - to call your regulator code (e.g. see rk808.c for direct functions + to call your regulator code (e.g. see rk8xx.c for direct functions for use in SPL). config PMIC_ACT8846 @@ -100,8 +100,8 @@ config PMIC_PM8916 Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt -config PMIC_RK808 - bool "Enable support for Rockchip PMIC RK808" +config PMIC_RK8XX + bool "Enable support for Rockchip PMIC RK8XX" depends on DM_PMIC ---help--- The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs, diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 5f1bef33cd..f409e3a0b3 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o obj-$(CONFIG_PMIC_AS3722) += as3722.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o obj-$(CONFIG_PMIC_PM8916) += pm8916.o -obj-$(CONFIG_PMIC_RK808) += rk808.o +obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o obj-$(CONFIG_PMIC_RN5T567) += rn5t567.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 deleted file mode 100644 index 582e456d7f..0000000000 --- a/drivers/power/pmic/rk808.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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) -{ - int ret; - - ret = dm_i2c_write(dev, reg, buff, len); - if (ret) { - debug("write error to device: %p register: %#x!", dev, reg); - return ret; - } - - return 0; -} - -static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len) -{ - int ret; - - ret = dm_i2c_read(dev, reg, buff, len); - if (ret) { - debug("read error from device: %p register: %#x!", dev, reg); - return ret; - } - - 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(dev), - "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 int rk808_probe(struct udevice *dev) -{ - struct rk808_priv *priv = dev_get_priv(dev); - uint8_t msb, lsb; - - /* read Chip variant */ - rk808_read(dev, ID_MSB, &msb, 1); - rk808_read(dev, ID_LSB, &lsb, 1); - - priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; - - return 0; -} - -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" }, - { .compatible = "rockchip,rk818" }, - { } -}; - -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 - .probe = rk808_probe, - .ops = &rk808_ops, -}; diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c new file mode 100644 index 0000000000..394e2ff9db --- /dev/null +++ b/drivers/power/pmic/rk8xx.c @@ -0,0 +1,118 @@ +/* + * 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 = "rk8xx_buck"}, + { .prefix = "LDO_REG", .driver = "rk8xx_ldo"}, + { .prefix = "SWITCH_REG", .driver = "rk8xx_switch"}, + { }, +}; + +static int rk8xx_reg_count(struct udevice *dev) +{ + return RK808_NUM_OF_REGS; +} + +static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buff, len); + if (ret) { + debug("write error to device: %p register: %#x!", dev, reg); + return ret; + } + + return 0; +} + +static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buff, len); + if (ret) { + debug("read error from device: %p register: %#x!", dev, reg); + return ret; + } + + return 0; +} + +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) +static int rk8xx_bind(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int regulators_node; + int children; + + regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev), + "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 int rk8xx_probe(struct udevice *dev) +{ + struct rk8xx_priv *priv = dev_get_priv(dev); + uint8_t msb, lsb; + + /* read Chip variant */ + rk8xx_read(dev, ID_MSB, &msb, 1); + rk8xx_read(dev, ID_LSB, &lsb, 1); + + priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; + + return 0; +} + +static struct dm_pmic_ops rk8xx_ops = { + .reg_count = rk8xx_reg_count, + .read = rk8xx_read, + .write = rk8xx_write, +}; + +static const struct udevice_id rk8xx_ids[] = { + { .compatible = "rockchip,rk808" }, + { .compatible = "rockchip,rk818" }, + { } +}; + +U_BOOT_DRIVER(pmic_rk8xx) = { + .name = "rk8xx pmic", + .id = UCLASS_PMIC, + .of_match = rk8xx_ids, +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) + .bind = rk8xx_bind, +#endif + .probe = rk8xx_probe, + .ops = &rk8xx_ops, +}; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index f870e8bcc9..ef057e0e2f 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -76,11 +76,11 @@ config DM_REGULATOR_GPIO features for gpio regulators. The driver implements get/set for voltage value. -config REGULATOR_RK808 - bool "Enable driver for RK808 regulators" - depends on DM_REGULATOR && PMIC_RK808 +config REGULATOR_RK8XX + bool "Enable driver for RK8XX regulators" + depends on DM_REGULATOR && PMIC_RK8XX ---help--- - Enable support for the regulator functions of the RK808 PMIC. The + Enable support for the regulator functions of the RK8XX PMIC. The driver implements get/set api for the various BUCKS and LDOs supported by the PMIC device. This driver is controlled by a device tree node which includes voltage limits. diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 6002c88a6c..3e01021b76 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o -obj-$(CONFIG_REGULATOR_RK808) += rk808.o +obj-$(CONFIG_REGULATOR_RK8XX) += rk8xx.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o diff --git a/drivers/power/regulator/rk808.c b/drivers/power/regulator/rk808.c deleted file mode 100644 index 1ffe9dc3e4..0000000000 --- a/drivers/power/regulator/rk808.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2015 Google, Inc - * Written by Simon Glass - * - * Based on Rockchip's drivers/power/pmic/pmic_rk808.c: - * Copyright (C) 2012 rockchips - * zyw - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SPL_BUILD -#define ENABLE_DRIVER -#endif - -/* Field Definitions */ -#define RK808_BUCK_VSEL_MASK 0x3f -#define RK808_BUCK4_VSEL_MASK 0xf -#define RK808_LDO_VSEL_MASK 0x1f - -#define RK818_BUCK_VSEL_MASK 0x3f -#define RK818_BUCK4_VSEL_MASK 0x1f -#define RK818_LDO_VSEL_MASK 0x1f -#define RK818_LDO3_ON_VSEL_MASK 0xf -#define RK818_BOOST_ON_VSEL_MASK 0xe0 - -struct rk808_reg_info { - uint min_uv; - uint step_uv; - s8 vsel_reg; - u8 vsel_mask; -}; - -static const struct rk808_reg_info rk808_buck[] = { - { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, }, - { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, }, - { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, }, - { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, -}; - -static const struct rk808_reg_info rk808_ldo[] = { - { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, - { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, }, -}; - -static const struct rk808_reg_info rk818_buck[] = { - { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, }, - { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, }, - { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, }, - { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, }, -}; - -static const struct rk808_reg_info rk818_ldo[] = { - { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, }, - { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, }, - { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, }, -}; - -static const struct rk808_reg_info *get_buck_reg(struct udevice *pmic, - int num) -{ - struct rk808_priv *rk808 = dev_get_priv(pmic); - switch (rk808->variant) { - case RK818_ID: - return &rk818_buck[num]; - default: - return &rk808_buck[num]; - } -} - -static const struct rk808_reg_info *get_ldo_reg(struct udevice *pmic, - int num) -{ - struct rk808_priv *rk808 = dev_get_priv(pmic); - switch (rk808->variant) { - case RK818_ID: - return &rk818_ldo[num - 1]; - default: - return &rk808_ldo[num - 1]; - } -} - -static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) -{ - const struct rk808_reg_info *info = get_buck_reg(pmic, buck - 1); - int mask = info->vsel_mask; - int val; - - if (info->vsel_reg == -1) - return -ENOSYS; - val = (uvolt - info->min_uv) / info->step_uv; - debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, - val); - - return pmic_clrsetbits(pmic, info->vsel_reg, mask, val); -} - -static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) -{ - uint mask; - int ret; - - buck--; - mask = 1 << buck; - if (enable) { - ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2)); - if (ret) - return ret; - ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0); - if (ret) - return ret; - } - - return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0); -} - -#ifdef ENABLE_DRIVER -static int buck_get_value(struct udevice *dev) -{ - int buck = dev->driver_data - 1; - const struct rk808_reg_info *info = get_buck_reg(dev->parent, buck); - int mask = info->vsel_mask; - int ret, val; - - if (info->vsel_reg == -1) - return -ENOSYS; - ret = pmic_reg_read(dev->parent, info->vsel_reg); - if (ret < 0) - return ret; - val = ret & mask; - - return info->min_uv + val * info->step_uv; -} - -static int buck_set_value(struct udevice *dev, int uvolt) -{ - int buck = dev->driver_data; - - return _buck_set_value(dev->parent, buck, uvolt); -} - -static int buck_set_enable(struct udevice *dev, bool enable) -{ - int buck = dev->driver_data; - - return _buck_set_enable(dev->parent, buck, enable); -} - -static bool buck_get_enable(struct udevice *dev) -{ - int buck = dev->driver_data - 1; - int ret; - uint mask; - - mask = 1 << buck; - - ret = pmic_reg_read(dev->parent, REG_DCDC_EN); - if (ret < 0) - return ret; - - return ret & mask ? true : false; -} - -static int ldo_get_value(struct udevice *dev) -{ - int ldo = dev->driver_data - 1; - const struct rk808_reg_info *info = get_ldo_reg(dev->parent, ldo); - int mask = info->vsel_mask; - int ret, val; - - if (info->vsel_reg == -1) - return -ENOSYS; - ret = pmic_reg_read(dev->parent, info->vsel_reg); - if (ret < 0) - return ret; - val = ret & mask; - - return info->min_uv + val * info->step_uv; -} - -static int ldo_set_value(struct udevice *dev, int uvolt) -{ - int ldo = dev->driver_data - 1; - const struct rk808_reg_info *info = get_ldo_reg(dev->parent, ldo); - int mask = info->vsel_mask; - int val; - - if (info->vsel_reg == -1) - return -ENOSYS; - val = (uvolt - info->min_uv) / info->step_uv; - debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, - val); - - return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val); -} - -static int ldo_set_enable(struct udevice *dev, bool enable) -{ - int ldo = dev->driver_data - 1; - uint mask; - - mask = 1 << ldo; - - return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask, - enable ? mask : 0); -} - -static bool ldo_get_enable(struct udevice *dev) -{ - int ldo = dev->driver_data - 1; - int ret; - uint mask; - - mask = 1 << ldo; - - ret = pmic_reg_read(dev->parent, REG_LDO_EN); - if (ret < 0) - return ret; - - return ret & mask ? true : false; -} - -static int switch_set_enable(struct udevice *dev, bool enable) -{ - int sw = dev->driver_data - 1; - uint mask; - - mask = 1 << (sw + 5); - - return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask, - enable ? mask : 0); -} - -static bool switch_get_enable(struct udevice *dev) -{ - int sw = dev->driver_data - 1; - int ret; - uint mask; - - mask = 1 << (sw + 5); - - ret = pmic_reg_read(dev->parent, REG_DCDC_EN); - if (ret < 0) - return ret; - - return ret & mask ? true : false; -} - -static int rk808_buck_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_BUCK; - uc_pdata->mode_count = 0; - - return 0; -} - -static int rk808_ldo_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_LDO; - uc_pdata->mode_count = 0; - - return 0; -} - -static int rk808_switch_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_FIXED; - uc_pdata->mode_count = 0; - - return 0; -} - -static const struct dm_regulator_ops rk808_buck_ops = { - .get_value = buck_get_value, - .set_value = buck_set_value, - .get_enable = buck_get_enable, - .set_enable = buck_set_enable, -}; - -static const struct dm_regulator_ops rk808_ldo_ops = { - .get_value = ldo_get_value, - .set_value = ldo_set_value, - .get_enable = ldo_get_enable, - .set_enable = ldo_set_enable, -}; - -static const struct dm_regulator_ops rk808_switch_ops = { - .get_enable = switch_get_enable, - .set_enable = switch_set_enable, -}; - -U_BOOT_DRIVER(rk808_buck) = { - .name = "rk808_buck", - .id = UCLASS_REGULATOR, - .ops = &rk808_buck_ops, - .probe = rk808_buck_probe, -}; - -U_BOOT_DRIVER(rk808_ldo) = { - .name = "rk808_ldo", - .id = UCLASS_REGULATOR, - .ops = &rk808_ldo_ops, - .probe = rk808_ldo_probe, -}; - -U_BOOT_DRIVER(rk808_switch) = { - .name = "rk808_switch", - .id = UCLASS_REGULATOR, - .ops = &rk808_switch_ops, - .probe = rk808_switch_probe, -}; -#endif - -int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt) -{ - int ret; - - ret = _buck_set_value(pmic, buck, uvolt); - if (ret) - return ret; - - return _buck_set_enable(pmic, buck, true); -} diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c new file mode 100644 index 0000000000..e655c2d91f --- /dev/null +++ b/drivers/power/regulator/rk8xx.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2015 Google, Inc + * Written by Simon Glass + * + * Based on Rockchip's drivers/power/pmic/pmic_rk808.c: + * Copyright (C) 2012 rockchips + * zyw + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SPL_BUILD +#define ENABLE_DRIVER +#endif + +/* Field Definitions */ +#define RK808_BUCK_VSEL_MASK 0x3f +#define RK808_BUCK4_VSEL_MASK 0xf +#define RK808_LDO_VSEL_MASK 0x1f + +#define RK818_BUCK_VSEL_MASK 0x3f +#define RK818_BUCK4_VSEL_MASK 0x1f +#define RK818_LDO_VSEL_MASK 0x1f +#define RK818_LDO3_ON_VSEL_MASK 0xf +#define RK818_BOOST_ON_VSEL_MASK 0xe0 + +struct rk8xx_reg_info { + uint min_uv; + uint step_uv; + s8 vsel_reg; + u8 vsel_mask; +}; + +static const struct rk8xx_reg_info rk808_buck[] = { + { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, }, + { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, }, + { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, }, + { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, +}; + +static const struct rk8xx_reg_info rk808_ldo[] = { + { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, + { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, }, +}; + +static const struct rk8xx_reg_info rk818_buck[] = { + { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, }, + { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, }, + { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, }, + { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, }, +}; + +static const struct rk8xx_reg_info rk818_ldo[] = { + { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, }, + { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, }, + { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, }, +}; + +static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic, + int num) +{ + struct rk8xx_priv *priv = dev_get_priv(pmic); + switch (priv->variant) { + case RK818_ID: + return &rk818_buck[num]; + default: + return &rk808_buck[num]; + } +} + +static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic, + int num) +{ + struct rk8xx_priv *priv = dev_get_priv(pmic); + switch (priv->variant) { + case RK818_ID: + return &rk818_ldo[num - 1]; + default: + return &rk808_ldo[num - 1]; + } +} + +static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) +{ + const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1); + int mask = info->vsel_mask; + int val; + + if (info->vsel_reg == -1) + return -ENOSYS; + val = (uvolt - info->min_uv) / info->step_uv; + debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, + val); + + return pmic_clrsetbits(pmic, info->vsel_reg, mask, val); +} + +static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) +{ + uint mask; + int ret; + + buck--; + mask = 1 << buck; + if (enable) { + ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2)); + if (ret) + return ret; + ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0); + if (ret) + return ret; + } + + return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0); +} + +#ifdef ENABLE_DRIVER +static int buck_get_value(struct udevice *dev) +{ + int buck = dev->driver_data - 1; + const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck); + int mask = info->vsel_mask; + int ret, val; + + if (info->vsel_reg == -1) + return -ENOSYS; + ret = pmic_reg_read(dev->parent, info->vsel_reg); + if (ret < 0) + return ret; + val = ret & mask; + + return info->min_uv + val * info->step_uv; +} + +static int buck_set_value(struct udevice *dev, int uvolt) +{ + int buck = dev->driver_data; + + return _buck_set_value(dev->parent, buck, uvolt); +} + +static int buck_set_enable(struct udevice *dev, bool enable) +{ + int buck = dev->driver_data; + + return _buck_set_enable(dev->parent, buck, enable); +} + +static bool buck_get_enable(struct udevice *dev) +{ + int buck = dev->driver_data - 1; + int ret; + uint mask; + + mask = 1 << buck; + + ret = pmic_reg_read(dev->parent, REG_DCDC_EN); + if (ret < 0) + return ret; + + return ret & mask ? true : false; +} + +static int ldo_get_value(struct udevice *dev) +{ + int ldo = dev->driver_data - 1; + const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo); + int mask = info->vsel_mask; + int ret, val; + + if (info->vsel_reg == -1) + return -ENOSYS; + ret = pmic_reg_read(dev->parent, info->vsel_reg); + if (ret < 0) + return ret; + val = ret & mask; + + return info->min_uv + val * info->step_uv; +} + +static int ldo_set_value(struct udevice *dev, int uvolt) +{ + int ldo = dev->driver_data - 1; + const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo); + int mask = info->vsel_mask; + int val; + + if (info->vsel_reg == -1) + return -ENOSYS; + val = (uvolt - info->min_uv) / info->step_uv; + debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, + val); + + return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val); +} + +static int ldo_set_enable(struct udevice *dev, bool enable) +{ + int ldo = dev->driver_data - 1; + uint mask; + + mask = 1 << ldo; + + return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask, + enable ? mask : 0); +} + +static bool ldo_get_enable(struct udevice *dev) +{ + int ldo = dev->driver_data - 1; + int ret; + uint mask; + + mask = 1 << ldo; + + ret = pmic_reg_read(dev->parent, REG_LDO_EN); + if (ret < 0) + return ret; + + return ret & mask ? true : false; +} + +static int switch_set_enable(struct udevice *dev, bool enable) +{ + int sw = dev->driver_data - 1; + uint mask; + + mask = 1 << (sw + 5); + + return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask, + enable ? mask : 0); +} + +static bool switch_get_enable(struct udevice *dev) +{ + int sw = dev->driver_data - 1; + int ret; + uint mask; + + mask = 1 << (sw + 5); + + ret = pmic_reg_read(dev->parent, REG_DCDC_EN); + if (ret < 0) + return ret; + + return ret & mask ? true : false; +} + +static int rk8xx_buck_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + uc_pdata->mode_count = 0; + + return 0; +} + +static int rk8xx_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->mode_count = 0; + + return 0; +} + +static int rk8xx_switch_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_FIXED; + uc_pdata->mode_count = 0; + + return 0; +} + +static const struct dm_regulator_ops rk8xx_buck_ops = { + .get_value = buck_get_value, + .set_value = buck_set_value, + .get_enable = buck_get_enable, + .set_enable = buck_set_enable, +}; + +static const struct dm_regulator_ops rk8xx_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = ldo_get_enable, + .set_enable = ldo_set_enable, +}; + +static const struct dm_regulator_ops rk8xx_switch_ops = { + .get_enable = switch_get_enable, + .set_enable = switch_set_enable, +}; + +U_BOOT_DRIVER(rk8xx_buck) = { + .name = "rk8xx_buck", + .id = UCLASS_REGULATOR, + .ops = &rk8xx_buck_ops, + .probe = rk8xx_buck_probe, +}; + +U_BOOT_DRIVER(rk8xx_ldo) = { + .name = "rk8xx_ldo", + .id = UCLASS_REGULATOR, + .ops = &rk8xx_ldo_ops, + .probe = rk8xx_ldo_probe, +}; + +U_BOOT_DRIVER(rk8xx_switch) = { + .name = "rk8xx_switch", + .id = UCLASS_REGULATOR, + .ops = &rk8xx_switch_ops, + .probe = rk8xx_switch_probe, +}; +#endif + +int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt) +{ + int ret; + + ret = _buck_set_value(pmic, buck, uvolt); + if (ret) + return ret; + + return _buck_set_enable(pmic, buck, true); +} -- cgit