struct dm_regulator_uclass_plat *uc_pdata;
int ret, old_uV = uV, is_enabled = 0;
+ if (!ops || !ops->set_value)
+ return -ENOSYS;
+
uc_pdata = dev_get_uclass_plat(dev);
if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
return -EINVAL;
if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
return -EINVAL;
-
- if (!ops || !ops->set_value)
- return -ENOSYS;
+ if (uV == -ENODATA)
+ return -EINVAL;
if (uc_pdata->ramp_delay) {
is_enabled = regulator_get_enable(dev);
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
struct dm_regulator_uclass_plat *uc_pdata;
+ if (!ops || !ops->set_suspend_value)
+ return -ENOSYS;
+
uc_pdata = dev_get_uclass_plat(dev);
if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
return -EINVAL;
if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
return -EINVAL;
-
- if (!ops->set_suspend_value)
- return -ENOSYS;
+ if (uV == -ENODATA)
+ return -EINVAL;
return ops->set_suspend_value(dev, uV);
}
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_value)
+ if (!ops || !ops->get_suspend_value)
return -ENOSYS;
return ops->get_suspend_value(dev);
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
struct dm_regulator_uclass_plat *uc_pdata;
+ if (!ops || !ops->set_current)
+ return -ENOSYS;
+
uc_pdata = dev_get_uclass_plat(dev);
if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
return -EINVAL;
if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
return -EINVAL;
-
- if (!ops || !ops->set_current)
- return -ENOSYS;
+ if (uA == -ENODATA)
+ return -EINVAL;
return ops->set_current(dev, uA);
}
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->set_suspend_enable)
+ if (!ops || !ops->set_suspend_enable)
return -ENOSYS;
return ops->set_suspend_enable(dev, enable);
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_enable)
+ if (!ops || !ops->get_suspend_enable)
return -ENOSYS;
return ops->get_suspend_enable(dev);
if (ret == -ENOSYS)
ret = 0;
- if (!ret && uc_pdata->suspend_on) {
+ if (!ret && uc_pdata->suspend_on && uc_pdata->suspend_uV != -ENODATA) {
ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
if (ret == -ENOSYS)
ret = 0;
return ret;
}
+ if (uc_pdata->force_off) {
+ ret = regulator_set_enable(dev, false);
+ goto out;
+ }
+
if (!uc_pdata->always_on && !uc_pdata->boot_on) {
ret = -EMEDIUMTYPE;
goto out;
return ret;
}
-int regulator_unset(struct udevice *dev)
-{
- struct dm_regulator_uclass_plat *uc_pdata;
-
- uc_pdata = dev_get_uclass_plat(dev);
- if (uc_pdata && uc_pdata->force_off)
- return regulator_set_enable(dev, false);
-
- return -EMEDIUMTYPE;
-}
-
static void regulator_show(struct udevice *dev, int ret)
{
struct dm_regulator_uclass_plat *uc_pdata;
const char *property = "regulator-name";
uc_pdata = dev_get_uclass_plat(dev);
+ uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
+ uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
/* Regulator's mandatory constraint */
uc_pdata->name = dev_read_string(dev, property);
return -EINVAL;
}
- if (regulator_name_is_unique(dev, uc_pdata->name))
- return 0;
+ if (!regulator_name_is_unique(dev, uc_pdata->name)) {
+ debug("'%s' of dev: '%s', has nonunique value: '%s\n",
+ property, dev->name, uc_pdata->name);
+ return -EINVAL;
+ }
- debug("'%s' of dev: '%s', has nonunique value: '%s\n",
- property, dev->name, uc_pdata->name);
+ /*
+ * In case the regulator has regulator-always-on or
+ * regulator-boot-on DT property, trigger probe() to
+ * configure its default state during startup.
+ */
+ if (uc_pdata->always_on || uc_pdata->boot_on)
+ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
- return -EINVAL;
+ return 0;
}
static int regulator_pre_probe(struct udevice *dev)
-ENODATA);
uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
-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);
uc_pdata->force_off = dev_read_bool(dev, "regulator-force-boot-off");
return 0;
}
-int regulators_enable_boot_on(bool verbose)
+static int regulator_post_probe(struct udevice *dev)
{
- struct udevice *dev;
- struct uclass *uc;
int ret;
- ret = uclass_get(UCLASS_REGULATOR, &uc);
- if (ret)
+ ret = regulator_autoset(dev);
+ if (ret && ret != -EMEDIUMTYPE && ret != -EALREADY && ret != ENOSYS)
return ret;
- for (uclass_first_device(UCLASS_REGULATOR, &dev);
- dev;
- uclass_next_device(&dev)) {
- ret = regulator_autoset(dev);
- if (ret == -EMEDIUMTYPE) {
- ret = 0;
- continue;
- }
- if (verbose)
- regulator_show(dev, ret);
- if (ret == -ENOSYS)
- ret = 0;
- }
-
- return ret;
-}
-
-int regulators_enable_boot_off(bool verbose)
-{
- struct udevice *dev;
- struct uclass *uc;
- int ret;
- ret = uclass_get(UCLASS_REGULATOR, &uc);
- if (ret)
- return ret;
- for (uclass_first_device(UCLASS_REGULATOR, &dev);
- dev;
- uclass_next_device(&dev)) {
- ret = regulator_unset(dev);
- if (ret == -EMEDIUMTYPE) {
- ret = 0;
- continue;
- }
- if (verbose)
- regulator_show(dev, ret);
- if (ret == -ENOSYS)
- ret = 0;
- }
+ if (_DEBUG)
+ regulator_show(dev, ret);
- return ret;
+ return 0;
}
UCLASS_DRIVER(regulator) = {
.name = "regulator",
.post_bind = regulator_post_bind,
.pre_probe = regulator_pre_probe,
+ .post_probe = regulator_post_probe,
.per_device_plat_auto = sizeof(struct dm_regulator_uclass_plat),
};