[U-Boot] [PATCH 0/3] power: s2mps11: Support the DM regulator

S2MPS11 has the 10-bucks and 38-ldos regulators. To control the each power, add the s2mps11 regulator driver. Tested with Odroid-xu3 board (Exynos5422)
ODROID-XU3 # regulator list | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66
ODROID-XU3 # regulator status Name Enabled uV mA Mode vdd_ldo1 enabled 1000000 - ON vddq_mmc0 enabled 1800000 - ON vdd_adc enabled 1800000 - ON vdd_ldo5 enabled 1800000 - ON vdd_ldo6 enabled 1000000 - ON vdd_ldo7 enabled 1800000 - ON vdd_ldo8 enabled 1800000 - ON vdd_ldo9 enabled 3300000 - ON vdd_ldo10 enabled 1800000 - ON vdd_ldo11 enabled 1000000 - ON vdd_ldo12 enabled 1800000 - ON vddq_mmc2 enabled 3300000 - ON vdd_ldo15 enabled 3300000 - ON vdd_ldo16 disabled 2200000 - OFF vdd_ldo17 enabled 3300000 - ON vdd_emmc_1V8 disabled 1800000 - OFF vdd_sd enabled 3300000 - ON tsp_io disabled 2800000 - OFF vdd_ldo26 enabled 3000000 - ON vdd_mif enabled 1100000 - ON vdd_arm enabled 1000000 - ON vdd_int enabled 1000000 - ON vdd_g3d enabled 1000000 - ON vdd_mem enabled 1200000 - ON vdd_kfc enabled 1025000 - ON vdd_1.0v_ldo enabled 1350000 - ON vdd_1.8v_ldo enabled 2000000 - ON vdd_2.8v_ldo enabled 2200000 - ON vdd_vmem disabled 2850000 - OFF
Jaehoon Chung (3): power: regulator: s2mps11: add a regulator driver for s2mps11 power: pmic: s2mps11: probe the regulator driver configs: odroid-xu3: enable the configs relevant to regulator
configs/odroid-xu3_defconfig | 2 + drivers/power/pmic/s2mps11.c | 28 ++ drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 6 files changed, 691 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c

exynos5422 has the s2mps11 PMIC. s2mps11 pmic has the 10-BUCK and 38-LDO regulators. Each IP and devices in exynos5422 can be controlled by each regulators. This patch is support for s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 4 files changed, 661 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 26fb9368ea..5b4ac10462 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -101,6 +101,14 @@ config REGULATOR_RK8XX by the PMIC device. This driver is controlled by a device tree node which includes voltage limits.
+config DM_REGULATOR_S2MPS11 + bool "Enable driver for S2MPS11 regulator" + depends on DM_REGULATOR && PMIC_S2MPS11 + ---help--- + This enables implementation of driver-model regulator uclass + features for REGULATOR S2MPS11. + The driver implements get/set api for: value and enable. + config REGULATOR_S5M8767 bool "Enable support for S5M8767 regulator" depends on DM_REGULATOR && PMIC_S5M8767 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 7a2e76dc82..728e8144de 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -14,6 +14,7 @@ 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_RK8XX) += rk8xx.o +obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.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/s2mps11_regulator.c b/drivers/power/regulator/s2mps11_regulator.c new file mode 100644 index 0000000000..3af20e60dd --- /dev/null +++ b/drivers/power/regulator/s2mps11_regulator.c @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2018 Samsung Electronics + * Jaehoon Chung jh80.chung@samsung.com + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/s2mps11.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MODE(_id, _val, _name) { \ + .id = _id, \ + .register_value = _val, \ + .name = _name, \ +} + +/* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */ +static struct dm_regulator_mode s2mps11_buck_modes[] = { + MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"), + MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"), + MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"), +}; + +static struct dm_regulator_mode s2mps11_ldo_modes[] = { + MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"), + MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"), + MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"), + MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"), +}; + +static const char s2mps11_buck_ctrl[] = { + 0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b +}; + +static const char s2mps11_buck_out[] = { + 0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c +}; + +static int s2mps11_buck_hex2volt(int buck, int hex) +{ + unsigned int uV = 0; + + if (hex < 0) + goto bad; + + switch (buck) { + case 7: + case 8: + case 10: + if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX) + goto bad; + + uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN; + break; + case 9: + if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX) + goto bad; + uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN; + break; + default: + if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX) + goto bad; + else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX) + goto bad; + + uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN; + break; + } + + return uV; +bad: + pr_err("Value: %#x is wrong for BUCK%d", hex, buck); + return -EINVAL; +} + +static int s2mps11_buck_volt2hex(int buck, int uV) +{ + int hex; + + switch (buck) { + case 7: + case 8: + case 10: + hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP; + if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX) + goto bad; + + break; + case 9: + hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP; + if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX) + goto bad; + break; + default: + hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP; + if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX) + goto bad; + else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX) + goto bad; + break; + }; + + if (hex >= 0) + return hex; + +bad: + pr_err("Value: %d uV is wrong for BUCK%d", uV, buck); + return -EINVAL; +} + +static int s2mps11_buck_val(struct udevice *dev, int op, int *uV) +{ + int hex, buck, ret; + u32 mask, addr; + u8 val; + + buck = dev->driver_data; + if (buck < 1 || buck > S2MPS11_BUCK_NUM) { + pr_err("Wrong buck number: %d\n", buck); + return -EINVAL; + } + + if (op == PMIC_OP_GET) + *uV = 0; + + addr = s2mps11_buck_out[buck]; + + switch (buck) { + case 9: + mask = S2MPS11_BUCK9_VOLT_MASK; + break; + default: + mask = S2MPS11_BUCK_VOLT_MASK; + break; + } + + ret = pmic_read(dev->parent, addr, &val, 1); + if (ret) + return ret; + + if (op == PMIC_OP_GET) { + val &= mask; + ret = s2mps11_buck_hex2volt(buck, val); + if (ret < 0) + return ret; + *uV = ret; + return 0; + } + + hex = s2mps11_buck_volt2hex(buck, *uV); + if (hex < 0) + return hex; + + val &= ~mask; + val |= hex; + ret = pmic_write(dev->parent, addr, &val, 1); + + return ret; +} + +static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode) +{ + unsigned int addr, mode; + unsigned char val; + int buck, ret; + + buck = dev->driver_data; + if (buck < 1 || buck > S2MPS11_BUCK_NUM) { + pr_err("Wrong buck number: %d\n", buck); + return -EINVAL; + } + + addr = s2mps11_buck_ctrl[buck]; + + ret = pmic_read(dev->parent, addr, &val, 1); + if (ret) + return ret; + + if (op == PMIC_OP_GET) { + val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT); + switch (val) { + case S2MPS11_BUCK_MODE_OFF: + *opmode = OP_OFF; + break; + case S2MPS11_BUCK_MODE_STANDBY: + *opmode = OP_STANDBY; + break; + case S2MPS11_BUCK_MODE_ON: + *opmode = OP_ON; + break; + default: + return -EINVAL; + } + return 0; + } + + switch (*opmode) { + case OP_OFF: + mode = S2MPS11_BUCK_MODE_OFF; + break; + case OP_STANDBY: + mode = S2MPS11_BUCK_MODE_STANDBY; + break; + case OP_ON: + mode = S2MPS11_BUCK_MODE_ON; + break; + default: + pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck); + return -EINVAL; + } + + val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT); + val |= mode; + ret = pmic_write(dev->parent, addr, &val, 1); + + return ret; +} + +static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable) +{ + int ret, on_off; + + if (op == PMIC_OP_GET) { + ret = s2mps11_buck_mode(dev, op, &on_off); + if (ret) + return ret; + switch (on_off) { + case OP_OFF: + *enable = false; + break; + case OP_ON: + *enable = true; + break; + default: + return -EINVAL; + } + } else if (op == PMIC_OP_SET) { + if (*enable) + on_off = OP_ON; + else + on_off = OP_OFF; + + ret = s2mps11_buck_mode(dev, op, &on_off); + if (ret) + return ret; + } + + return 0; +} + +static int buck_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + return uV; +} + +static int buck_set_value(struct udevice *dev, int uV) +{ + return s2mps11_buck_val(dev, PMIC_OP_SET, &uV); +} + +static int buck_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + return enable; +} + +static int buck_set_enable(struct udevice *dev, bool enable) +{ + return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable); +} + +static int buck_get_mode(struct udevice *dev) +{ + int mode; + int ret; + + ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode); + if (ret) + return ret; + + return mode; +} + +static int buck_set_mode(struct udevice *dev, int mode) +{ + return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode); +} + +static int s2mps11_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 = s2mps11_buck_modes; + uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes); + + return 0; +} + +static const struct dm_regulator_ops s2mps11_buck_ops = { + .get_value = buck_get_value, + .set_value = buck_set_value, + .get_enable = buck_get_enable, + .set_enable = buck_set_enable, + .get_mode = buck_get_mode, + .set_mode = buck_set_mode, +}; + +U_BOOT_DRIVER(s2mps11_buck) = { + .name = S2MPS11_BUCK_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &s2mps11_buck_ops, + .probe = s2mps11_buck_probe, +}; + +static int s2mps11_ldo_hex2volt(int ldo, int hex) +{ + unsigned int uV = 0; + + if (hex > S2MPS11_LDO_VOLT_MAX_HEX) { + pr_err("Value: %#x is wrong for LDO%d", hex, ldo); + return -EINVAL; + } + + switch (ldo) { + case 1: + case 6: + case 11: + case 22: + case 23: + uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN; + break; + default: + uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN; + break; + } + + return uV; +} + +static int s2mps11_ldo_volt2hex(int ldo, int uV) +{ + int hex = 0; + + switch (ldo) { + case 1: + case 6: + case 11: + case 22: + case 23: + hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP; + break; + default: + hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2); + break; + } + + if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX) + return hex; + + pr_err("Value: %d uV is wrong for LDO%d", uV, ldo); + return -EINVAL; + + return 0; +} + +static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV) +{ + unsigned int addr; + unsigned char val; + int hex, ldo, ret; + + ldo = dev->driver_data; + if (ldo < 1 || ldo > S2MPS11_LDO_NUM) { + pr_err("Wrong ldo number: %d\n", ldo); + return -EINVAL; + } + + addr = S2MPS11_REG_L1CTRL + ldo - 1; + + ret = pmic_read(dev->parent, addr, &val, 1); + if (ret) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + val &= S2MPS11_LDO_VOLT_MASK; + ret = s2mps11_ldo_hex2volt(ldo, val); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + hex = s2mps11_ldo_volt2hex(ldo, *uV); + if (hex < 0) + return hex; + + val &= ~S2MPS11_LDO_VOLT_MASK; + val |= hex; + ret = pmic_write(dev->parent, addr, &val, 1); + + return ret; +} + +static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode) +{ + unsigned int addr, mode; + unsigned char val; + int ldo, ret; + + ldo = dev->driver_data; + if (ldo < 1 || ldo > S2MPS11_LDO_NUM) { + pr_err("Wrong ldo number: %d\n", ldo); + return -EINVAL; + } + addr = S2MPS11_REG_L1CTRL + ldo - 1; + + ret = pmic_read(dev->parent, addr, &val, 1); + if (ret) + return ret; + + if (op == PMIC_OP_GET) { + val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT); + switch (val) { + case S2MPS11_LDO_MODE_OFF: + *opmode = OP_OFF; + break; + case S2MPS11_LDO_MODE_STANDBY: + *opmode = OP_STANDBY; + break; + case S2MPS11_LDO_MODE_STANDBY_LPM: + *opmode = OP_STANDBY_LPM; + break; + case S2MPS11_LDO_MODE_ON: + *opmode = OP_ON; + break; + default: + return -EINVAL; + } + return 0; + } + + switch (*opmode) { + case OP_OFF: + mode = S2MPS11_LDO_MODE_OFF; + break; + case OP_STANDBY: + mode = S2MPS11_LDO_MODE_STANDBY; + break; + case OP_STANDBY_LPM: + mode = S2MPS11_LDO_MODE_STANDBY_LPM; + break; + case OP_ON: + mode = S2MPS11_LDO_MODE_ON; + break; + default: + pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo); + return -EINVAL; + } + + val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT); + val |= mode; + ret = pmic_write(dev->parent, addr, &val, 1); + + return ret; +} + +static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable) +{ + int ret, on_off; + + if (op == PMIC_OP_GET) { + ret = s2mps11_ldo_mode(dev, op, &on_off); + if (ret) + return ret; + switch (on_off) { + case OP_OFF: + *enable = false; + break; + case OP_ON: + *enable = true; + break; + default: + return -EINVAL; + } + } else if (op == PMIC_OP_SET) { + if (*enable) + on_off = OP_ON; + else + on_off = OP_OFF; + + ret = s2mps11_ldo_mode(dev, op, &on_off); + if (ret) + return ret; + } + + return 0; +} + +static int ldo_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int ldo_set_value(struct udevice *dev, int uV) +{ + return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV); +} + +static int ldo_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + return enable; +} + +static int ldo_set_enable(struct udevice *dev, bool enable) +{ + return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable); +} + +static int ldo_get_mode(struct udevice *dev) +{ + int mode, ret; + + ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode); + if (ret) + return ret; + return mode; +} + +static int ldo_set_mode(struct udevice *dev, int mode) +{ + return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode); +} + +static int s2mps11_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 = s2mps11_ldo_modes; + uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes); + + return 0; +} + +static const struct dm_regulator_ops s2mps11_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = ldo_get_enable, + .set_enable = ldo_set_enable, + .get_mode = ldo_get_mode, + .set_mode = ldo_set_mode, +}; + +U_BOOT_DRIVER(s2mps11_ldo) = { + .name = S2MPS11_LDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &s2mps11_ldo_ops, + .probe = s2mps11_ldo_probe, +}; diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h index 5da47198a4..22b38fff70 100644 --- a/include/power/s2mps11.h +++ b/include/power/s2mps11.h @@ -106,4 +106,59 @@ enum s2mps11_reg {
#define S2MPS11_LDO26_ENABLE 0xec
+#define S2MPS11_LDO_NUM 26 +#define S2MPS11_BUCK_NUM 10 + +/* Driver name */ +#define S2MPS11_BUCK_DRIVER "s2mps11_buck" +#define S2MPS11_OF_BUCK_PREFIX "BUCK" +#define S2MPS11_LDO_DRIVER "s2mps11_ldo" +#define S2MPS11_OF_LDO_PREFIX "LDO" + +/* BUCK */ +#define S2MPS11_BUCK_VOLT_MASK 0xff +#define S2MPS11_BUCK9_VOLT_MASK 0x1f + +#define S2MPS11_BUCK_LSTEP 6250 +#define S2MPS11_BUCK_HSTEP 12500 +#define S2MPS11_BUCK9_STEP 25000 + +#define S2MPS11_BUCK_UV_MIN 600000 +#define S2MPS11_BUCK_UV_HMIN 750000 +#define S2MPS11_BUCK9_UV_MIN 1400000 + +#define S2MPS11_BUCK_VOLT_MAX_HEX 0xA0 +#define S2MPS11_BUCK5_VOLT_MAX_HEX 0xDF +#define S2MPS11_BUCK7_8_10_VOLT_MAX_HEX 0xDC +#define S2MPS11_BUCK9_VOLT_MAX_HEX 0x5F + +#define S2MPS11_BUCK_MODE_SHIFT 6 +#define S2MPS11_BUCK_MODE_MASK (0x3) +#define S2MPS11_BUCK_MODE_OFF (0x0 << 6) +#define S2MPS11_BUCK_MODE_STANDBY (0x1 << 6) +#define S2MPS11_BUCK_MODE_ON (0x3 << 6) + +/* LDO */ +#define S2MPS11_LDO_VOLT_MASK 0x3F +#define S2MPS11_LDO_VOLT_MAX_HEX 0x3F + +#define S2MPS11_LDO_STEP 25000 +#define S2MPS11_LDO_UV_MIN 800000 + +#define S2MPS11_LDO_MODE_MASK 0x3 +#define S2MPS11_LDO_MODE_SHIFT 6 + +#define S2MPS11_LDO_MODE_OFF (0x0 << 6) +#define S2MPS11_LDO_MODE_STANDBY (0x1 << 6) +#define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6) +#define S2MPS11_LDO_MODE_ON (0x3 << 6) + +enum { + OP_OFF = 0, + OP_LPM, + OP_STANDBY, + OP_STANDBY_LPM, + OP_ON, +}; + #endif

On 15 January 2018 at 22:33, Jaehoon Chung jh80.chung@samsung.com wrote:
exynos5422 has the s2mps11 PMIC. s2mps11 pmic has the 10-BUCK and 38-LDO regulators. Each IP and devices in exynos5422 can be controlled by each regulators. This patch is support for s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 4 files changed, 661 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c
Reviewed-by: Simon Glass sjg@chromium.org

Hi JaeHoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
exynos5422 has the s2mps11 PMIC. s2mps11 pmic has the 10-BUCK and 38-LDO regulators. Each IP and devices in exynos5422 can be controlled by each regulators. This patch is support for s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 4 files changed, 661 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 26fb9368ea..5b4ac10462 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -101,6 +101,14 @@ config REGULATOR_RK8XX by the PMIC device. This driver is controlled by a device tree node which includes voltage limits.
+config DM_REGULATOR_S2MPS11
bool "Enable driver for S2MPS11 regulator"
depends on DM_REGULATOR && PMIC_S2MPS11
---help---
This enables implementation of driver-model regulator uclass
features for REGULATOR S2MPS11.
The driver implements get/set api for: value and enable.
config REGULATOR_S5M8767 bool "Enable support for S5M8767 regulator" depends on DM_REGULATOR && PMIC_S5M8767 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 7a2e76dc82..728e8144de 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -14,6 +14,7 @@ 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_RK8XX) += rk8xx.o +obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.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/s2mps11_regulator.c b/drivers/power/regulator/s2mps11_regulator.c new file mode 100644 index 0000000000..3af20e60dd --- /dev/null +++ b/drivers/power/regulator/s2mps11_regulator.c @@ -0,0 +1,597 @@ +/*
- Copyright (C) 2018 Samsung Electronics
- Jaehoon Chung jh80.chung@samsung.com
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/s2mps11.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define MODE(_id, _val, _name) { \
.id = _id, \
.register_value = _val, \
.name = _name, \
+}
+/* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */ +static struct dm_regulator_mode s2mps11_buck_modes[] = {
MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"),
MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"),
MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"),
+};
+static struct dm_regulator_mode s2mps11_ldo_modes[] = {
MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"),
MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"),
MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"),
MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
+};
+static const char s2mps11_buck_ctrl[] = {
0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
+};
+static const char s2mps11_buck_out[] = {
0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
+};
+static int s2mps11_buck_hex2volt(int buck, int hex) +{
unsigned int uV = 0;
if (hex < 0)
goto bad;
switch (buck) {
case 7:
case 8:
case 10:
if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
goto bad;
uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN;
break;
case 9:
if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
goto bad;
uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN;
break;
default:
if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
goto bad;
else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
goto bad;
uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN;
break;
}
return uV;
+bad:
pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
return -EINVAL;
+}
+static int s2mps11_buck_volt2hex(int buck, int uV) +{
int hex;
switch (buck) {
case 7:
case 8:
case 10:
hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP;
if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
goto bad;
break;
case 9:
hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP;
if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
goto bad;
break;
default:
hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP;
if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
goto bad;
else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
goto bad;
break;
};
if (hex >= 0)
return hex;
+bad:
pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
return -EINVAL;
+}
+static int s2mps11_buck_val(struct udevice *dev, int op, int *uV) +{
int hex, buck, ret;
u32 mask, addr;
u8 val;
buck = dev->driver_data;
if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
pr_err("Wrong buck number: %d\n", buck);
return -EINVAL;
}
if (op == PMIC_OP_GET)
*uV = 0;
addr = s2mps11_buck_out[buck];
switch (buck) {
case 9:
mask = S2MPS11_BUCK9_VOLT_MASK;
break;
default:
mask = S2MPS11_BUCK_VOLT_MASK;
break;
}
ret = pmic_read(dev->parent, addr, &val, 1);
if (ret)
return ret;
if (op == PMIC_OP_GET) {
val &= mask;
ret = s2mps11_buck_hex2volt(buck, val);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = s2mps11_buck_volt2hex(buck, *uV);
if (hex < 0)
return hex;
val &= ~mask;
val |= hex;
ret = pmic_write(dev->parent, addr, &val, 1);
return ret;
+}
+static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode) +{
unsigned int addr, mode;
unsigned char val;
int buck, ret;
buck = dev->driver_data;
if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
pr_err("Wrong buck number: %d\n", buck);
return -EINVAL;
}
addr = s2mps11_buck_ctrl[buck];
ret = pmic_read(dev->parent, addr, &val, 1);
if (ret)
return ret;
if (op == PMIC_OP_GET) {
val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
switch (val) {
case S2MPS11_BUCK_MODE_OFF:
*opmode = OP_OFF;
break;
case S2MPS11_BUCK_MODE_STANDBY:
*opmode = OP_STANDBY;
break;
case S2MPS11_BUCK_MODE_ON:
*opmode = OP_ON;
break;
default:
return -EINVAL;
}
return 0;
}
switch (*opmode) {
case OP_OFF:
mode = S2MPS11_BUCK_MODE_OFF;
break;
case OP_STANDBY:
mode = S2MPS11_BUCK_MODE_STANDBY;
break;
case OP_ON:
mode = S2MPS11_BUCK_MODE_ON;
break;
default:
pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
return -EINVAL;
}
val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
val |= mode;
ret = pmic_write(dev->parent, addr, &val, 1);
return ret;
+}
+static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable) +{
int ret, on_off;
if (op == PMIC_OP_GET) {
ret = s2mps11_buck_mode(dev, op, &on_off);
if (ret)
return ret;
switch (on_off) {
case OP_OFF:
*enable = false;
break;
case OP_ON:
*enable = true;
break;
default:
return -EINVAL;
}
} else if (op == PMIC_OP_SET) {
if (*enable)
on_off = OP_ON;
else
on_off = OP_OFF;
ret = s2mps11_buck_mode(dev, op, &on_off);
if (ret)
return ret;
}
return 0;
+}
+static int buck_get_value(struct udevice *dev) +{
int uV;
int ret;
ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
+}
+static int buck_set_value(struct udevice *dev, int uV) +{
return s2mps11_buck_val(dev, PMIC_OP_SET, &uV);
+}
+static int buck_get_enable(struct udevice *dev) +{
bool enable = false;
int ret;
ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
+}
+static int buck_set_enable(struct udevice *dev, bool enable) +{
return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable);
+}
+static int buck_get_mode(struct udevice *dev) +{
int mode;
int ret;
ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode);
if (ret)
return ret;
return mode;
+}
+static int buck_set_mode(struct udevice *dev, int mode) +{
return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode);
+}
+static int s2mps11_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 = s2mps11_buck_modes;
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
return 0;
+}
+static const struct dm_regulator_ops s2mps11_buck_ops = {
.get_value = buck_get_value,
.set_value = buck_set_value,
.get_enable = buck_get_enable,
.set_enable = buck_set_enable,
.get_mode = buck_get_mode,
.set_mode = buck_set_mode,
+};
+U_BOOT_DRIVER(s2mps11_buck) = {
.name = S2MPS11_BUCK_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &s2mps11_buck_ops,
.probe = s2mps11_buck_probe,
+};
+static int s2mps11_ldo_hex2volt(int ldo, int hex) +{
unsigned int uV = 0;
if (hex > S2MPS11_LDO_VOLT_MAX_HEX) {
pr_err("Value: %#x is wrong for LDO%d", hex, ldo);
return -EINVAL;
}
switch (ldo) {
case 1:
case 6:
case 11:
case 22:
case 23:
uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
break;
default:
uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
break;
}
return uV;
+}
+static int s2mps11_ldo_volt2hex(int ldo, int uV) +{
int hex = 0;
switch (ldo) {
case 1:
case 6:
case 11:
case 22:
case 23:
hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
break;
default:
hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
break;
}
if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
return hex;
pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
return -EINVAL;
return 0;
+}
+static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV) +{
unsigned int addr;
unsigned char val;
int hex, ldo, ret;
ldo = dev->driver_data;
if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
pr_err("Wrong ldo number: %d\n", ldo);
return -EINVAL;
}
addr = S2MPS11_REG_L1CTRL + ldo - 1;
ret = pmic_read(dev->parent, addr, &val, 1);
if (ret)
return ret;
if (op == PMIC_OP_GET) {
*uV = 0;
val &= S2MPS11_LDO_VOLT_MASK;
ret = s2mps11_ldo_hex2volt(ldo, val);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = s2mps11_ldo_volt2hex(ldo, *uV);
if (hex < 0)
return hex;
val &= ~S2MPS11_LDO_VOLT_MASK;
val |= hex;
ret = pmic_write(dev->parent, addr, &val, 1);
return ret;
+}
+static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode) +{
unsigned int addr, mode;
unsigned char val;
int ldo, ret;
ldo = dev->driver_data;
if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
pr_err("Wrong ldo number: %d\n", ldo);
return -EINVAL;
}
addr = S2MPS11_REG_L1CTRL + ldo - 1;
ret = pmic_read(dev->parent, addr, &val, 1);
if (ret)
return ret;
if (op == PMIC_OP_GET) {
val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
switch (val) {
case S2MPS11_LDO_MODE_OFF:
*opmode = OP_OFF;
break;
case S2MPS11_LDO_MODE_STANDBY:
*opmode = OP_STANDBY;
break;
case S2MPS11_LDO_MODE_STANDBY_LPM:
*opmode = OP_STANDBY_LPM;
break;
case S2MPS11_LDO_MODE_ON:
*opmode = OP_ON;
break;
default:
return -EINVAL;
}
return 0;
}
switch (*opmode) {
case OP_OFF:
mode = S2MPS11_LDO_MODE_OFF;
break;
case OP_STANDBY:
mode = S2MPS11_LDO_MODE_STANDBY;
break;
case OP_STANDBY_LPM:
mode = S2MPS11_LDO_MODE_STANDBY_LPM;
break;
case OP_ON:
mode = S2MPS11_LDO_MODE_ON;
break;
default:
pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
return -EINVAL;
}
val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
val |= mode;
ret = pmic_write(dev->parent, addr, &val, 1);
return ret;
+}
+static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable) +{
int ret, on_off;
if (op == PMIC_OP_GET) {
ret = s2mps11_ldo_mode(dev, op, &on_off);
if (ret)
return ret;
switch (on_off) {
case OP_OFF:
*enable = false;
break;
case OP_ON:
*enable = true;
break;
default:
return -EINVAL;
}
} else if (op == PMIC_OP_SET) {
if (*enable)
on_off = OP_ON;
else
on_off = OP_OFF;
ret = s2mps11_ldo_mode(dev, op, &on_off);
if (ret)
return ret;
}
return 0;
+}
+static int ldo_get_value(struct udevice *dev) +{
int uV;
int ret;
ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
+}
+static int ldo_set_value(struct udevice *dev, int uV) +{
return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV);
+}
+static int ldo_get_enable(struct udevice *dev) +{
bool enable = false;
int ret;
ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
+}
+static int ldo_set_enable(struct udevice *dev, bool enable) +{
return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
+}
+static int ldo_get_mode(struct udevice *dev) +{
int mode, ret;
ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode);
if (ret)
return ret;
return mode;
+}
+static int ldo_set_mode(struct udevice *dev, int mode) +{
return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode);
+}
+static int s2mps11_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 = s2mps11_ldo_modes;
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
return 0;
+}
+static const struct dm_regulator_ops s2mps11_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
.get_enable = ldo_get_enable,
.set_enable = ldo_set_enable,
.get_mode = ldo_get_mode,
.set_mode = ldo_set_mode,
+};
+U_BOOT_DRIVER(s2mps11_ldo) = {
.name = S2MPS11_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &s2mps11_ldo_ops,
.probe = s2mps11_ldo_probe,
+}; diff --git a/include/power/s2mps11.h b/include/power/s2mps11.h index 5da47198a4..22b38fff70 100644 --- a/include/power/s2mps11.h +++ b/include/power/s2mps11.h @@ -106,4 +106,59 @@ enum s2mps11_reg {
#define S2MPS11_LDO26_ENABLE 0xec
+#define S2MPS11_LDO_NUM 26 +#define S2MPS11_BUCK_NUM 10
+/* Driver name */ +#define S2MPS11_BUCK_DRIVER "s2mps11_buck" +#define S2MPS11_OF_BUCK_PREFIX "BUCK" +#define S2MPS11_LDO_DRIVER "s2mps11_ldo" +#define S2MPS11_OF_LDO_PREFIX "LDO"
+/* BUCK */ +#define S2MPS11_BUCK_VOLT_MASK 0xff +#define S2MPS11_BUCK9_VOLT_MASK 0x1f
+#define S2MPS11_BUCK_LSTEP 6250 +#define S2MPS11_BUCK_HSTEP 12500 +#define S2MPS11_BUCK9_STEP 25000
+#define S2MPS11_BUCK_UV_MIN 600000 +#define S2MPS11_BUCK_UV_HMIN 750000 +#define S2MPS11_BUCK9_UV_MIN 1400000
+#define S2MPS11_BUCK_VOLT_MAX_HEX 0xA0 +#define S2MPS11_BUCK5_VOLT_MAX_HEX 0xDF +#define S2MPS11_BUCK7_8_10_VOLT_MAX_HEX 0xDC +#define S2MPS11_BUCK9_VOLT_MAX_HEX 0x5F
+#define S2MPS11_BUCK_MODE_SHIFT 6 +#define S2MPS11_BUCK_MODE_MASK (0x3) +#define S2MPS11_BUCK_MODE_OFF (0x0 << 6) +#define S2MPS11_BUCK_MODE_STANDBY (0x1 << 6) +#define S2MPS11_BUCK_MODE_ON (0x3 << 6)
+/* LDO */ +#define S2MPS11_LDO_VOLT_MASK 0x3F +#define S2MPS11_LDO_VOLT_MAX_HEX 0x3F
+#define S2MPS11_LDO_STEP 25000 +#define S2MPS11_LDO_UV_MIN 800000
+#define S2MPS11_LDO_MODE_MASK 0x3 +#define S2MPS11_LDO_MODE_SHIFT 6
+#define S2MPS11_LDO_MODE_OFF (0x0 << 6) +#define S2MPS11_LDO_MODE_STANDBY (0x1 << 6) +#define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6) +#define S2MPS11_LDO_MODE_ON (0x3 << 6)
+enum {
OP_OFF = 0,
OP_LPM,
OP_STANDBY,
OP_STANDBY_LPM,
OP_ON,
+};
#endif
2.15.1
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Best Regards -Anand

On 01/24/2018 01:01 AM, Anand Moon wrote:
Hi JaeHoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
exynos5422 has the s2mps11 PMIC. s2mps11 pmic has the 10-BUCK and 38-LDO regulators. Each IP and devices in exynos5422 can be controlled by each regulators. This patch is support for s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 4 files changed, 661 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c
[..snip..]
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Applied to u-boot-mmc.
Best Regards, Jaehoon Chung
Best Regards -Anand

Add the probe function to support the s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- drivers/power/pmic/s2mps11.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/power/pmic/s2mps11.c b/drivers/power/pmic/s2mps11.c index 522105e5ff..3f9525b67d 100644 --- a/drivers/power/pmic/s2mps11.c +++ b/drivers/power/pmic/s2mps11.c @@ -15,6 +15,12 @@
DECLARE_GLOBAL_DATA_PTR;
+static const struct pmic_child_info pmic_children_info[] = { + { .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER }, + { .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER }, + { }, +}; + static int s2mps11_reg_count(struct udevice *dev) { return S2MPS11_REG_COUNT; @@ -43,6 +49,27 @@ static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return ret; }
+static int s2mps11_probe(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "voltage-regulators"); + if (!ofnode_valid(regulators_node)) { + 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); + + return 0; +} + static struct dm_pmic_ops s2mps11_ops = { .reg_count = s2mps11_reg_count, .read = s2mps11_read, @@ -59,4 +86,5 @@ U_BOOT_DRIVER(pmic_s2mps11) = { .id = UCLASS_PMIC, .of_match = s2mps11_ids, .ops = &s2mps11_ops, + .probe = s2mps11_probe, };

On 15 January 2018 at 22:33, Jaehoon Chung jh80.chung@samsung.com wrote:
Add the probe function to support the s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/pmic/s2mps11.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Hi JaeHoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
Add the probe function to support the s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/pmic/s2mps11.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/power/pmic/s2mps11.c b/drivers/power/pmic/s2mps11.c index 522105e5ff..3f9525b67d 100644 --- a/drivers/power/pmic/s2mps11.c +++ b/drivers/power/pmic/s2mps11.c @@ -15,6 +15,12 @@
DECLARE_GLOBAL_DATA_PTR;
+static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
{ .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
{ },
+};
static int s2mps11_reg_count(struct udevice *dev) { return S2MPS11_REG_COUNT; @@ -43,6 +49,27 @@ static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return ret; }
+static int s2mps11_probe(struct udevice *dev) +{
ofnode regulators_node;
int children;
regulators_node = dev_read_subnode(dev, "voltage-regulators");
if (!ofnode_valid(regulators_node)) {
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);
return 0;
+}
static struct dm_pmic_ops s2mps11_ops = { .reg_count = s2mps11_reg_count, .read = s2mps11_read, @@ -59,4 +86,5 @@ U_BOOT_DRIVER(pmic_s2mps11) = { .id = UCLASS_PMIC, .of_match = s2mps11_ids, .ops = &s2mps11_ops,
.probe = s2mps11_probe,
};
2.15.1
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Best Regards -Anand

On 01/24/2018 01:02 AM, Anand Moon wrote:
Hi JaeHoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
Add the probe function to support the s2mps11 regulator driver.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/power/pmic/s2mps11.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/power/pmic/s2mps11.c b/drivers/power/pmic/s2mps11.c index 522105e5ff..3f9525b67d 100644 --- a/drivers/power/pmic/s2mps11.c +++ b/drivers/power/pmic/s2mps11.c @@ -15,6 +15,12 @@
DECLARE_GLOBAL_DATA_PTR;
+static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
{ .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
{ },
+};
static int s2mps11_reg_count(struct udevice *dev) { return S2MPS11_REG_COUNT; @@ -43,6 +49,27 @@ static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return ret; }
+static int s2mps11_probe(struct udevice *dev) +{
ofnode regulators_node;
int children;
regulators_node = dev_read_subnode(dev, "voltage-regulators");
if (!ofnode_valid(regulators_node)) {
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);
return 0;
+}
static struct dm_pmic_ops s2mps11_ops = { .reg_count = s2mps11_reg_count, .read = s2mps11_read, @@ -59,4 +86,5 @@ U_BOOT_DRIVER(pmic_s2mps11) = { .id = UCLASS_PMIC, .of_match = s2mps11_ids, .ops = &s2mps11_ops,
.probe = s2mps11_probe,
};
2.15.1
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Applied to u-boot-mmc.
Best Regards, Jaehoon Chung
Best Regards -Anand

Enable the CONFIG_CMD_REGULATOR and CONFIG_DM_REGULATOR_S2MPS11.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- configs/odroid-xu3_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig index 976c06a29d..11b1c8bf11 100644 --- a/configs/odroid-xu3_defconfig +++ b/configs/odroid-xu3_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y CONFIG_CMD_PMIC=y CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_REGULATOR=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ADC=y CONFIG_ADC_EXYNOS=y @@ -35,6 +36,7 @@ CONFIG_SMC911X_BASE=0x5000000 CONFIG_DM_PMIC=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_S2MPS11=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y

On 15 January 2018 at 22:33, Jaehoon Chung jh80.chung@samsung.com wrote:
Enable the CONFIG_CMD_REGULATOR and CONFIG_DM_REGULATOR_S2MPS11.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
configs/odroid-xu3_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Jaehoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
Enable the CONFIG_CMD_REGULATOR and CONFIG_DM_REGULATOR_S2MPS11.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
configs/odroid-xu3_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig index 976c06a29d..11b1c8bf11 100644 --- a/configs/odroid-xu3_defconfig +++ b/configs/odroid-xu3_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y CONFIG_CMD_PMIC=y CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_REGULATOR=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ADC=y CONFIG_ADC_EXYNOS=y @@ -35,6 +36,7 @@ CONFIG_SMC911X_BASE=0x5000000 CONFIG_DM_PMIC=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_S2MPS11=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y -- 2.15.1
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Best Regards -Anand

On 01/24/2018 01:04 AM, Anand Moon wrote:
Hi Jaehoon Chung,
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
Enable the CONFIG_CMD_REGULATOR and CONFIG_DM_REGULATOR_S2MPS11.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
configs/odroid-xu3_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig index 976c06a29d..11b1c8bf11 100644 --- a/configs/odroid-xu3_defconfig +++ b/configs/odroid-xu3_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y CONFIG_CMD_PMIC=y CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_REGULATOR=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ADC=y CONFIG_ADC_EXYNOS=y @@ -35,6 +36,7 @@ CONFIG_SMC911X_BASE=0x5000000 CONFIG_DM_PMIC=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_S2MPS11=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y -- 2.15.1
Please add my. Tested-by: Anand Moon linux.amoon@gmail.com
Applied to u-boot-mmc.
Best Regards, Jaehoon Chung
Best Regards -Anand

Hi Jaehoon
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
S2MPS11 has the 10-bucks and 38-ldos regulators. To control the each power, add the s2mps11 regulator driver. Tested with Odroid-xu3 board (Exynos5422)
ODROID-XU3 # regulator list | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66
ODROID-XU3 # regulator status Name Enabled uV mA Mode vdd_ldo1 enabled 1000000 - ON vddq_mmc0 enabled 1800000 - ON vdd_adc enabled 1800000 - ON vdd_ldo5 enabled 1800000 - ON vdd_ldo6 enabled 1000000 - ON vdd_ldo7 enabled 1800000 - ON vdd_ldo8 enabled 1800000 - ON vdd_ldo9 enabled 3300000 - ON vdd_ldo10 enabled 1800000 - ON vdd_ldo11 enabled 1000000 - ON vdd_ldo12 enabled 1800000 - ON vddq_mmc2 enabled 3300000 - ON vdd_ldo15 enabled 3300000 - ON vdd_ldo16 disabled 2200000 - OFF vdd_ldo17 enabled 3300000 - ON vdd_emmc_1V8 disabled 1800000 - OFF vdd_sd enabled 3300000 - ON tsp_io disabled 2800000 - OFF vdd_ldo26 enabled 3000000 - ON vdd_mif enabled 1100000 - ON vdd_arm enabled 1000000 - ON vdd_int enabled 1000000 - ON vdd_g3d enabled 1000000 - ON vdd_mem enabled 1200000 - ON vdd_kfc enabled 1025000 - ON vdd_1.0v_ldo enabled 1350000 - ON vdd_1.8v_ldo enabled 2000000 - ON vdd_2.8v_ldo enabled 2200000 - ON vdd_vmem disabled 2850000 - OFF
Jaehoon Chung (3): power: regulator: s2mps11: add a regulator driver for s2mps11 power: pmic: s2mps11: probe the regulator driver configs: odroid-xu3: enable the configs relevant to regulator
configs/odroid-xu3_defconfig | 2 + drivers/power/pmic/s2mps11.c | 28 ++ drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/s2mps11_regulator.c | 597 ++++++++++++++++++++++++++++ include/power/s2mps11.h | 55 +++ 6 files changed, 691 insertions(+) create mode 100644 drivers/power/regulator/s2mps11_regulator.c
-- 2.15.1
Thanks for you patches it seem to initialize the s2mps11 pmic and regulator.
After applying you patches on latest u-boot It fails to boot up on my Odroid-XU3 and Odroid-XU4. I have verified twice with two different sdcard.
It looks like mmc failed to initialize
Here is the boot log at my end, ---------------------------------------------------- ODROID-XU3 # reset resetting ...
U-Boot 2018.01-00333-gfdb6c32-dirty (Jan 16 2018 - 15:50:26 +0000) for ODROID-XU3/XU4/HC1
CPU: Exynos5422 @ 800 MHz Model: Odroid XU3 based on EXYNOS5422 Board: Odroid XU3 based on EXYNOS5422 Type: xu4 DRAM: 2 GiB MMC: EXYNOS DWMMC: 0, EXYNOS DWMMC: 1 mmc_init: -110, time 82 *** Warning - MMC init failed, using default environment
In: serial Out: serial Err: serial Net: No ethernet found. Hit any key to stop autoboot: 0 mmc_init: -110, time 83 mmc_init: -110, time 80 starting USB... USB0: USB EHCI 1.00 USB1: Register 2000140 NbrPorts 2 Starting the controller USB XHCI 1.00 USB2: Register 2000140 NbrPorts 2 Starting the controller USB XHCI 1.00 scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 3 USB Device(s) found scanning bus 2 for devices... 2 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found scanning usb for ethernet devices... 1 Ethernet Device(s) found Waiting for Ethernet connection... done. BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 DHCP client bound to address 10.0.0.144 (25642 ms) *** Warning: no boot file name; using '0A000090.img' Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename '0A000090.img'. Load address: 0x43e00000 Loading: * TFTP error: 'File not found' (1) Not retrying... missing environment variable: pxeuuid missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A000090 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A00009 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A0000 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A000 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A00 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A0 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default-arm-exynos *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default-arm *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default *** ERROR: `serverip' not set Config file not found BOOTP broadcast 1 DHCP client bound to address 10.0.0.144 (645 ms) Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename 'boot.scr.uimg'. Load address: 0x50000000 Loading: * TFTP error: 'File not found' (1) Not retrying... BOOTP broadcast 1 DHCP client bound to address 10.0.0.144 (644 ms) Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename 'boot.scr.uimg'. Load address: 0x42000000 Loading: * TFTP error: 'File not found' (1) Not retrying... ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # pmic dev s2mps11_pmic@66 dev: 0 @ s2mps11_pmic@66 ODROID-XU3 # regulator list | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66 ODROID-XU3 # | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66 ODROID-XU3 # regulator status Name Enabled uV mA Mode vdd_ldo1 enabled 1000000 - ON vddq_mmc0 enabled 1800000 - ON vdd_adc enabled 1800000 - ON vdd_ldo5 enabled 1800000 - ON vdd_ldo6 enabled 1000000 - ON vdd_ldo7 enabled 1800000 - ON vdd_ldo8 enabled 1800000 - ON vdd_ldo9 enabled 3300000 - ON vdd_ldo10 enabled 1800000 - ON vdd_ldo11 enabled 1000000 - ON vdd_ldo12 enabled 1800000 - ON vddq_mmc2 enabled 3300000 - ON vdd_ldo15 enabled 3300000 - ON vdd_ldo16 disabled 2200000 - OFF vdd_ldo17 enabled 3300000 - ON vdd_emmc_1V8 disabled 1800000 - OFF vdd_sd enabled 3300000 - ON tsp_io disabled 2800000 - OFF vdd_ldo26 disabled 3000000 - OFF vdd_mif enabled 1100000 - ON vdd_arm enabled 1000000 - ON vdd_int enabled 1000000 - ON vdd_g3d enabled 1000000 - ON vdd_mem enabled 1200000 - ON vdd_kfc enabled 1025000 - ON vdd_1.0v_ldo enabled 1350000 - ON vdd_1.8v_ldo enabled 2000000 - ON vdd_2.8v_ldo enabled 2200000 - ON vdd_vmem disabled 2850000 - OFF ODROID-XU3 # pmic dump Dump pmic: s2mps11_pmic@66 registers
0x00: 83 10 11 00 00 ff ff 1a 00 00 04 01 10 00 00 57 0x10: 5f 55 ff ff ff ff ff 00 00 00 00 00 00 00 00 00 0x20: 00 50 12 ca dc d8 50 f8 40 f9 40 f8 40 fe 3f 60 0x30: 78 90 c0 d8 44 d8 30 d8 64 d8 50 18 a8 c8 d4 d4 0x40: d4 d4 c8 d4 d4 f2 d4 c8 d4 f2 2c f2 1c f2 14 f2 0x50: 14 14 10 cc 28 14 2c c8 32 14 14 14 14 14 2c 10 0x60: 14 14 28 ODROID-XU3 # ODROID-XU3 # mmc info mmc_init: -110, time 81
Best Regards -Anand

Hi Anand,
On 01/17/2018 02:18 AM, Anand Moon wrote:
Hi Jaehoon
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
S2MPS11 has the 10-bucks and 38-ldos regulators. To control the each power, add the s2mps11 regulator driver. Tested with Odroid-xu3 board (Exynos5422)
[..snip..]
Thanks for you patches it seem to initialize the s2mps11 pmic and regulator.
After applying you patches on latest u-boot It fails to boot up on my Odroid-XU3 and Odroid-XU4. I have verified twice with two different sdcard.
It looks like mmc failed to initialize
This patch-set is based on u-boot-samsung. so I didn't found your issue. Yep, When i applied the patches on latest u-boot-mmc, SD-card is failed.
I will fix it. Thanks for reporting it!
Best Regards, Jaehoon Chung
Here is the boot log at my end,
ODROID-XU3 # reset resetting ...
U-Boot 2018.01-00333-gfdb6c32-dirty (Jan 16 2018 - 15:50:26 +0000) for ODROID-XU3/XU4/HC1
CPU: Exynos5422 @ 800 MHz Model: Odroid XU3 based on EXYNOS5422 Board: Odroid XU3 based on EXYNOS5422 Type: xu4 DRAM: 2 GiB MMC: EXYNOS DWMMC: 0, EXYNOS DWMMC: 1 mmc_init: -110, time 82 *** Warning - MMC init failed, using default environment
In: serial Out: serial Err: serial Net: No ethernet found. Hit any key to stop autoboot: 0 mmc_init: -110, time 83 mmc_init: -110, time 80 starting USB... USB0: USB EHCI 1.00 USB1: Register 2000140 NbrPorts 2 Starting the controller USB XHCI 1.00 USB2: Register 2000140 NbrPorts 2 Starting the controller USB XHCI 1.00 scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 3 USB Device(s) found scanning bus 2 for devices... 2 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found scanning usb for ethernet devices... 1 Ethernet Device(s) found Waiting for Ethernet connection... done. BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 DHCP client bound to address 10.0.0.144 (25642 ms) *** Warning: no boot file name; using '0A000090.img' Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename '0A000090.img'. Load address: 0x43e00000 Loading: * TFTP error: 'File not found' (1) Not retrying... missing environment variable: pxeuuid missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A000090 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A00009 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A0000 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A000 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A00 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A0 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0A *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/0 *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default-arm-exynos *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default-arm *** ERROR: `serverip' not set missing environment variable: bootfile Retrieving file: pxelinux.cfg/default *** ERROR: `serverip' not set Config file not found BOOTP broadcast 1 DHCP client bound to address 10.0.0.144 (645 ms) Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename 'boot.scr.uimg'. Load address: 0x50000000 Loading: * TFTP error: 'File not found' (1) Not retrying... BOOTP broadcast 1 DHCP client bound to address 10.0.0.144 (644 ms) Using r8152#0 device TFTP from server 0.0.0.0; our IP address is 10.0.0.144; sending through gateway 10.0.0.1 Filename 'boot.scr.uimg'. Load address: 0x42000000 Loading: * TFTP error: 'File not found' (1) Not retrying... ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # ODROID-XU3 # pmic dev s2mps11_pmic@66 dev: 0 @ s2mps11_pmic@66 ODROID-XU3 # regulator list | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66 ODROID-XU3 # | Device | regulator-name | Parent | LDO1 | vdd_ldo1 | s2mps11_pmic@66 | LDO3 | vddq_mmc0 | s2mps11_pmic@66 | LDO4 | vdd_adc | s2mps11_pmic@66 | LDO5 | vdd_ldo5 | s2mps11_pmic@66 | LDO6 | vdd_ldo6 | s2mps11_pmic@66 | LDO7 | vdd_ldo7 | s2mps11_pmic@66 | LDO8 | vdd_ldo8 | s2mps11_pmic@66 | LDO9 | vdd_ldo9 | s2mps11_pmic@66 | LDO10 | vdd_ldo10 | s2mps11_pmic@66 | LDO11 | vdd_ldo11 | s2mps11_pmic@66 | LDO12 | vdd_ldo12 | s2mps11_pmic@66 | LDO13 | vddq_mmc2 | s2mps11_pmic@66 | LDO15 | vdd_ldo15 | s2mps11_pmic@66 | LDO16 | vdd_ldo16 | s2mps11_pmic@66 | LDO17 | vdd_ldo17 | s2mps11_pmic@66 | LDO18 | vdd_emmc_1V8 | s2mps11_pmic@66 | LDO19 | vdd_sd | s2mps11_pmic@66 | LDO24 | tsp_io | s2mps11_pmic@66 | LDO26 | vdd_ldo26 | s2mps11_pmic@66 | BUCK1 | vdd_mif | s2mps11_pmic@66 | BUCK2 | vdd_arm | s2mps11_pmic@66 | BUCK3 | vdd_int | s2mps11_pmic@66 | BUCK4 | vdd_g3d | s2mps11_pmic@66 | BUCK5 | vdd_mem | s2mps11_pmic@66 | BUCK6 | vdd_kfc | s2mps11_pmic@66 | BUCK7 | vdd_1.0v_ldo | s2mps11_pmic@66 | BUCK8 | vdd_1.8v_ldo | s2mps11_pmic@66 | BUCK9 | vdd_2.8v_ldo | s2mps11_pmic@66 | BUCK10 | vdd_vmem | s2mps11_pmic@66 ODROID-XU3 # regulator status Name Enabled uV mA Mode vdd_ldo1 enabled 1000000 - ON vddq_mmc0 enabled 1800000 - ON vdd_adc enabled 1800000 - ON vdd_ldo5 enabled 1800000 - ON vdd_ldo6 enabled 1000000 - ON vdd_ldo7 enabled 1800000 - ON vdd_ldo8 enabled 1800000 - ON vdd_ldo9 enabled 3300000 - ON vdd_ldo10 enabled 1800000 - ON vdd_ldo11 enabled 1000000 - ON vdd_ldo12 enabled 1800000 - ON vddq_mmc2 enabled 3300000 - ON vdd_ldo15 enabled 3300000 - ON vdd_ldo16 disabled 2200000 - OFF vdd_ldo17 enabled 3300000 - ON vdd_emmc_1V8 disabled 1800000 - OFF vdd_sd enabled 3300000 - ON tsp_io disabled 2800000 - OFF vdd_ldo26 disabled 3000000 - OFF vdd_mif enabled 1100000 - ON vdd_arm enabled 1000000 - ON vdd_int enabled 1000000 - ON vdd_g3d enabled 1000000 - ON vdd_mem enabled 1200000 - ON vdd_kfc enabled 1025000 - ON vdd_1.0v_ldo enabled 1350000 - ON vdd_1.8v_ldo enabled 2000000 - ON vdd_2.8v_ldo enabled 2200000 - ON vdd_vmem disabled 2850000 - OFF ODROID-XU3 # pmic dump Dump pmic: s2mps11_pmic@66 registers
0x00: 83 10 11 00 00 ff ff 1a 00 00 04 01 10 00 00 57 0x10: 5f 55 ff ff ff ff ff 00 00 00 00 00 00 00 00 00 0x20: 00 50 12 ca dc d8 50 f8 40 f9 40 f8 40 fe 3f 60 0x30: 78 90 c0 d8 44 d8 30 d8 64 d8 50 18 a8 c8 d4 d4 0x40: d4 d4 c8 d4 d4 f2 d4 c8 d4 f2 2c f2 1c f2 14 f2 0x50: 14 14 10 cc 28 14 2c c8 32 14 14 14 14 14 2c 10 0x60: 14 14 28 ODROID-XU3 # ODROID-XU3 # mmc info mmc_init: -110, time 81
Best Regards -Anand

On 01/17/2018 12:54 PM, Jaehoon Chung wrote:
Hi Anand,
On 01/17/2018 02:18 AM, Anand Moon wrote:
Hi Jaehoon
On 16 January 2018 at 12:03, Jaehoon Chung jh80.chung@samsung.com wrote:
S2MPS11 has the 10-bucks and 38-ldos regulators. To control the each power, add the s2mps11 regulator driver. Tested with Odroid-xu3 board (Exynos5422)
[..snip..]
Thanks for you patches it seem to initialize the s2mps11 pmic and regulator.
After applying you patches on latest u-boot It fails to boot up on my Odroid-XU3 and Odroid-XU4. I have verified twice with two different sdcard.
It looks like mmc failed to initialize
This patch-set is based on u-boot-samsung. so I didn't found your issue. Yep, When i applied the patches on latest u-boot-mmc, SD-card is failed.
I will fix it. Thanks for reporting it!
First, i found that this patch didn't initialize the values from device-tree. It is called power_board_init -> exynos_power_init() In exnyos_power_init(), there is no code relevant to "s2mps11_pmic".
pmic_get("s2mps11_pmic", &dev);
and need to implement the others..
Second, it seems that there is a bug on mmc side about "mmc_init: -110, time 80".
Will send the patch about all things.
Best Regards, Jaehoon Chung
Best Regards, Jaehoon Chung
[..snip..]
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
participants (3)
-
Anand Moon
-
Jaehoon Chung
-
Simon Glass