X-Git-Url: https://repo.jachan.dev/J-u-boot.git/blobdiff_plain/c8ffd1356d42223cbb8c86280a083cc3c93e6426..6f52feee2867f138af3d81a90a02a2b222e3366d:/drivers/power/regulator/regulator-uclass.c diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 66fd531da04..decd0802c84 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -55,14 +55,16 @@ int regulator_set_value(struct udevice *dev, int uV) 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); @@ -85,14 +87,16 @@ int regulator_set_suspend_value(struct udevice *dev, int uV) 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); } @@ -101,7 +105,7 @@ int regulator_get_suspend_value(struct udevice *dev) { 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); @@ -136,14 +140,16 @@ int regulator_set_current(struct udevice *dev, int uA) 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); } @@ -210,7 +216,7 @@ int regulator_set_suspend_enable(struct udevice *dev, bool enable) { 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); @@ -220,7 +226,7 @@ int regulator_get_suspend_enable(struct udevice *dev) { 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); @@ -299,7 +305,7 @@ int regulator_autoset(struct udevice *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; @@ -308,6 +314,11 @@ int regulator_autoset(struct udevice *dev) 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; @@ -334,17 +345,6 @@ 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; @@ -433,6 +433,8 @@ static int regulator_post_bind(struct udevice *dev) 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); @@ -444,13 +446,21 @@ static int regulator_post_bind(struct udevice *dev) 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) @@ -473,8 +483,6 @@ 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"); @@ -504,56 +512,18 @@ static int regulator_pre_probe(struct udevice *dev) 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) = { @@ -561,5 +531,6 @@ 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), };