]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - drivers/power/regulator/regulator-uclass.c
dm: pmic: Split output from function
[karo-tx-uboot.git] / drivers / power / regulator / regulator-uclass.c
index 07ce2869e6f4603f7c74b718ec667aaa84881f60..687d3b1e31b6574a8099a675b801113335c00671 100644 (file)
@@ -108,16 +108,19 @@ int regulator_set_mode(struct udevice *dev, int mode)
        return ops->set_mode(dev, mode);
 }
 
-int regulator_by_platname(const char *plat_name, struct udevice **devp)
+int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
 {
        struct dm_regulator_uclass_platdata *uc_pdata;
        struct udevice *dev;
+       int ret;
 
        *devp = NULL;
 
-       for (uclass_find_first_device(UCLASS_REGULATOR, &dev);
-            dev;
-            uclass_find_next_device(&dev)) {
+       for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
+            ret = uclass_find_next_device(&dev)) {
+               if (ret)
+                       continue;
+
                uc_pdata = dev_get_uclass_platdata(dev);
                if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
                        continue;
@@ -130,117 +133,111 @@ int regulator_by_platname(const char *plat_name, struct udevice **devp)
        return -ENODEV;
 }
 
-int regulator_by_devname(const char *devname, struct udevice **devp)
+int regulator_get_by_devname(const char *devname, struct udevice **devp)
 {
        return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
 }
 
-static int setting_failed(int ret, bool verbose, const char *fmt, ...)
+int regulator_autoset(struct udevice *dev)
 {
-       va_list args;
-       char buf[64];
-
-       if (verbose == false)
-               return ret;
+       struct dm_regulator_uclass_platdata *uc_pdata;
+       int ret = 0;
 
-       va_start(args, fmt);
-       vscnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
+       uc_pdata = dev_get_uclass_platdata(dev);
+       if (!uc_pdata->always_on && !uc_pdata->boot_on)
+               return -EMEDIUMTYPE;
 
-       printf(buf);
+       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+               ret = regulator_set_value(dev, uc_pdata->min_uV);
+       if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
+               ret = regulator_set_current(dev, uc_pdata->min_uA);
 
        if (!ret)
-               return 0;
-
-       printf(" (ret: %d)", ret);
+               ret = regulator_set_enable(dev, true);
 
        return ret;
 }
 
-int regulator_by_platname_autoset_and_enable(const char *platname,
-                                            struct udevice **devp,
-                                            bool verbose)
+static void regulator_show(struct udevice *dev, int ret)
 {
        struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       printf("%s@%s: ", dev->name, uc_pdata->name);
+       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+               printf("set %d uV", uc_pdata->min_uV);
+       if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
+               printf("; set %d uA", uc_pdata->min_uA);
+       printf("; enabling");
+       if (ret)
+               printf(" (ret: %d)\n", ret);
+       printf("\n");
+}
+
+int regulator_autoset_by_name(const char *platname, struct udevice **devp)
+{
        struct udevice *dev;
-       bool v = verbose;
        int ret;
 
+       ret = regulator_get_by_platname(platname, &dev);
        if (devp)
-               *devp = NULL;
-
-       ret = regulator_by_platname(platname, &dev);
+               *devp = dev;
        if (ret) {
-               error("Can get the regulator: %s!", platname);
+               debug("Can get the regulator: %s!", platname);
                return ret;
        }
 
-       uc_pdata = dev_get_uclass_platdata(dev);
-       if (!uc_pdata) {
-               error("Can get the regulator %s uclass platdata!", platname);
-               return -ENXIO;
-       }
-
-       if (v)
-               printf("%s@%s: ", dev->name, uc_pdata->name);
+       return regulator_autoset(dev);
+}
 
-       /* Those values are optional (-ENODATA if unset) */
-       if ((uc_pdata->min_uV != -ENODATA) &&
-           (uc_pdata->max_uV != -ENODATA) &&
-           (uc_pdata->min_uV == uc_pdata->max_uV)) {
-               ret = regulator_set_value(dev, uc_pdata->min_uV);
-               if (setting_failed(ret, v, "set %d uV", uc_pdata->min_uV))
-                       goto exit;
-       }
+int regulator_list_autoset(const char *list_platname[],
+                          struct udevice *list_devp[],
+                          bool verbose)
+{
+       struct udevice *dev;
+       int error = 0, i = 0, ret;
 
-       /* Those values are optional (-ENODATA if unset) */
-       if ((uc_pdata->min_uA != -ENODATA) &&
-           (uc_pdata->max_uA != -ENODATA) &&
-           (uc_pdata->min_uA == uc_pdata->max_uA)) {
-               ret = regulator_set_current(dev, uc_pdata->min_uA);
-               if (setting_failed(ret, v, "; set %d uA", uc_pdata->min_uA))
-                       goto exit;
-       }
+       while (list_platname[i]) {
+               ret = regulator_autoset_by_name(list_platname[i], &dev);
+               if (ret != -EMEDIUMTYPE && verbose)
+                       regulator_show(dev, ret);
+               if (ret & !error)
+                       error = ret;
 
-       if (!uc_pdata->always_on && !uc_pdata->boot_on)
-               goto retdev;
+               if (list_devp)
+                       list_devp[i] = dev;
 
-       ret = regulator_set_enable(dev, true);
-       if (setting_failed(ret, v, "; enabling", uc_pdata->min_uA))
-               goto exit;
+               i++;
+       }
 
-retdev:
-       if (devp)
-               *devp = dev;
-exit:
-       if (v)
-               printf("\n");
-       return ret;
+       return error;
 }
 
-int regulator_by_platname_list_autoset_and_enable(const char *list_platname[],
-                                                 int list_entries,
-                                                 struct udevice *list_devp[],
-                                                 bool verbose)
+static bool regulator_name_is_unique(struct udevice *check_dev,
+                                    const char *check_name)
 {
+       struct dm_regulator_uclass_platdata *uc_pdata;
        struct udevice *dev;
-       int i, ret, success = 0;
+       int check_len = strlen(check_name);
+       int ret;
+       int len;
 
-       for (i = 0; i < list_entries; i++) {
-               ret = regulator_autoset(list_platname[i], &dev, verbose);
-               if (!ret)
-                       success++;
+       for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
+            ret = uclass_find_next_device(&dev)) {
+               if (ret || dev == check_dev)
+                       continue;
 
-               if (!list_devp)
+               uc_pdata = dev_get_uclass_platdata(dev);
+               len = strlen(uc_pdata->name);
+               if (len != check_len)
                        continue;
 
-               if (ret)
-                       list_devp[i] = NULL;
-               else
-                       list_devp[i] = dev;
+               if (!strcmp(uc_pdata->name, check_name))
+                       return false;
        }
 
-       return (success != list_entries);
+       return true;
 }
 
 static int regulator_post_bind(struct udevice *dev)
@@ -248,20 +245,27 @@ static int regulator_post_bind(struct udevice *dev)
        struct dm_regulator_uclass_platdata *uc_pdata;
        int offset = dev->of_offset;
        const void *blob = gd->fdt_blob;
+       const char *property = "regulator-name";
 
        uc_pdata = dev_get_uclass_platdata(dev);
        if (!uc_pdata)
                return -ENXIO;
 
        /* Regulator's mandatory constraint */
-       uc_pdata->name = fdt_getprop(blob, offset, "regulator-name", NULL);
+       uc_pdata->name = fdt_getprop(blob, offset, property, NULL);
        if (!uc_pdata->name) {
                debug("%s: dev: %s has no property 'regulator-name'\n",
                      __func__, dev->name);
-               return -ENXIO;
+               return -EINVAL;
        }
 
-       return 0;
+       if (regulator_name_is_unique(dev, uc_pdata->name))
+               return 0;
+
+       error("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
+             property, dev->name, uc_pdata->name);
+
+       return -EINVAL;
 }
 
 static int regulator_pre_probe(struct udevice *dev)
@@ -287,6 +291,18 @@ static int regulator_pre_probe(struct udevice *dev)
        uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
                                            "regulator-boot-on");
 
+       /* Those values are optional (-ENODATA if unset) */
+       if ((uc_pdata->min_uV != -ENODATA) &&
+           (uc_pdata->max_uV != -ENODATA) &&
+           (uc_pdata->min_uV == uc_pdata->max_uV))
+               uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
+
+       /* Those values are optional (-ENODATA if unset) */
+       if ((uc_pdata->min_uA != -ENODATA) &&
+           (uc_pdata->max_uA != -ENODATA) &&
+           (uc_pdata->min_uA == uc_pdata->max_uA))
+               uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
+
        return 0;
 }