summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-03-14 11:37:11 -0400
committerTom Rini <trini@konsulko.com>2019-03-14 11:37:11 -0400
commit9659eb46af6249b6e4b3712e60a1eb2e87fc48a1 (patch)
tree2d7e7149804ddbf6d0bc5e6cb3dd20706be45809 /drivers/power
parent7f295ffed6f3c62bf15a48bb12b5757f4716f789 (diff)
parent1411298cbca83a8527d2c1b5c4d299871fc34cf1 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-samsung
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/regulator/regulator-uclass.c47
-rw-r--r--drivers/power/regulator/s2mps11_regulator.c15
2 files changed, 59 insertions, 3 deletions
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 6f355b969a..9118b8eb39 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -35,10 +35,22 @@ int regulator_get_value(struct udevice *dev)
return ops->get_value(dev);
}
+static void regulator_set_value_ramp_delay(struct udevice *dev, int old_uV,
+ int new_uV, unsigned int ramp_delay)
+{
+ int delay = DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay);
+
+ debug("regulator %s: delay %u us (%d uV -> %d uV)\n", dev->name, delay,
+ old_uV, new_uV);
+
+ udelay(delay);
+}
+
int regulator_set_value(struct udevice *dev, int uV)
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
struct dm_regulator_uclass_platdata *uc_pdata;
+ int ret, old_uV = uV, is_enabled = 0;
uc_pdata = dev_get_uclass_platdata(dev);
if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
@@ -49,7 +61,20 @@ int regulator_set_value(struct udevice *dev, int uV)
if (!ops || !ops->set_value)
return -ENOSYS;
- return ops->set_value(dev, uV);
+ if (uc_pdata->ramp_delay) {
+ is_enabled = regulator_get_enable(dev);
+ old_uV = regulator_get_value(dev);
+ }
+
+ ret = ops->set_value(dev, uV);
+
+ if (!ret) {
+ if (uc_pdata->ramp_delay && old_uV > 0 && is_enabled)
+ regulator_set_value_ramp_delay(dev, old_uV, uV,
+ uc_pdata->ramp_delay);
+ }
+
+ return ret;
}
/*
@@ -107,6 +132,7 @@ int regulator_set_enable(struct udevice *dev, bool enable)
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
struct dm_regulator_uclass_platdata *uc_pdata;
+ int ret, old_enable = 0;
if (!ops || !ops->set_enable)
return -ENOSYS;
@@ -115,7 +141,22 @@ int regulator_set_enable(struct udevice *dev, bool enable)
if (!enable && uc_pdata->always_on)
return -EACCES;
- return ops->set_enable(dev, enable);
+ if (uc_pdata->ramp_delay)
+ old_enable = regulator_get_enable(dev);
+
+ ret = ops->set_enable(dev, enable);
+ if (!ret) {
+ if (uc_pdata->ramp_delay && !old_enable && enable) {
+ int uV = regulator_get_value(dev);
+
+ if (uV > 0) {
+ regulator_set_value_ramp_delay(dev, 0, uV,
+ uc_pdata->ramp_delay);
+ }
+ }
+ }
+
+ return ret;
}
int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
@@ -335,6 +376,8 @@ static int regulator_pre_probe(struct udevice *dev)
-ENODATA);
uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
+ uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
+ 0);
/* Those values are optional (-ENODATA if unset) */
if ((uc_pdata->min_uV != -ENODATA) &&
diff --git a/drivers/power/regulator/s2mps11_regulator.c b/drivers/power/regulator/s2mps11_regulator.c
index ced504eb14..67d1f9689d 100644
--- a/drivers/power/regulator/s2mps11_regulator.c
+++ b/drivers/power/regulator/s2mps11_regulator.c
@@ -346,6 +346,8 @@ static int s2mps11_ldo_hex2volt(int ldo, int hex)
case 11:
case 22:
case 23:
+ case 27:
+ case 35:
uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
break;
default:
@@ -366,6 +368,8 @@ static int s2mps11_ldo_volt2hex(int ldo, int uV)
case 11:
case 22:
case 23:
+ case 27:
+ case 35:
hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
break;
default:
@@ -547,7 +551,16 @@ static int ldo_get_enable(struct udevice *dev)
static int ldo_set_enable(struct udevice *dev, bool enable)
{
- return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
+ int ret;
+
+ ret = s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
+ if (ret)
+ return ret;
+
+ /* Wait the "enable delay" for voltage to start to rise */
+ udelay(15);
+
+ return 0;
}
static int ldo_get_mode(struct udevice *dev)