1af41e8dbSPrzemyslaw Marczak /* 2af41e8dbSPrzemyslaw Marczak * Copyright (C) 2014-2015 Samsung Electronics 3af41e8dbSPrzemyslaw Marczak * Przemyslaw Marczak <p.marczak@samsung.com> 4af41e8dbSPrzemyslaw Marczak * 5af41e8dbSPrzemyslaw Marczak * SPDX-License-Identifier: GPL-2.0+ 6af41e8dbSPrzemyslaw Marczak */ 7f15cd4f1SSimon Glass 8af41e8dbSPrzemyslaw Marczak #include <common.h> 9af41e8dbSPrzemyslaw Marczak #include <errno.h> 10af41e8dbSPrzemyslaw Marczak #include <dm.h> 11af41e8dbSPrzemyslaw Marczak #include <dm/uclass-internal.h> 12af41e8dbSPrzemyslaw Marczak #include <power/pmic.h> 13af41e8dbSPrzemyslaw Marczak #include <power/regulator.h> 14af41e8dbSPrzemyslaw Marczak 15af41e8dbSPrzemyslaw Marczak DECLARE_GLOBAL_DATA_PTR; 16af41e8dbSPrzemyslaw Marczak 17af41e8dbSPrzemyslaw Marczak int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep) 18af41e8dbSPrzemyslaw Marczak { 19af41e8dbSPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 20af41e8dbSPrzemyslaw Marczak 21af41e8dbSPrzemyslaw Marczak *modep = NULL; 22af41e8dbSPrzemyslaw Marczak 23af41e8dbSPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 24af41e8dbSPrzemyslaw Marczak if (!uc_pdata) 25af41e8dbSPrzemyslaw Marczak return -ENXIO; 26af41e8dbSPrzemyslaw Marczak 27af41e8dbSPrzemyslaw Marczak *modep = uc_pdata->mode; 28af41e8dbSPrzemyslaw Marczak return uc_pdata->mode_count; 29af41e8dbSPrzemyslaw Marczak } 30af41e8dbSPrzemyslaw Marczak 31af41e8dbSPrzemyslaw Marczak int regulator_get_value(struct udevice *dev) 32af41e8dbSPrzemyslaw Marczak { 33af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 34af41e8dbSPrzemyslaw Marczak 35af41e8dbSPrzemyslaw Marczak if (!ops || !ops->get_value) 36af41e8dbSPrzemyslaw Marczak return -ENOSYS; 37af41e8dbSPrzemyslaw Marczak 38af41e8dbSPrzemyslaw Marczak return ops->get_value(dev); 39af41e8dbSPrzemyslaw Marczak } 40af41e8dbSPrzemyslaw Marczak 41af41e8dbSPrzemyslaw Marczak int regulator_set_value(struct udevice *dev, int uV) 42af41e8dbSPrzemyslaw Marczak { 43af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 44eaadcf38SKeerthy struct dm_regulator_uclass_platdata *uc_pdata; 45eaadcf38SKeerthy 46eaadcf38SKeerthy uc_pdata = dev_get_uclass_platdata(dev); 47eaadcf38SKeerthy if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV) 48eaadcf38SKeerthy return -EINVAL; 49eaadcf38SKeerthy if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV) 50eaadcf38SKeerthy return -EINVAL; 51af41e8dbSPrzemyslaw Marczak 52af41e8dbSPrzemyslaw Marczak if (!ops || !ops->set_value) 53af41e8dbSPrzemyslaw Marczak return -ENOSYS; 54af41e8dbSPrzemyslaw Marczak 55af41e8dbSPrzemyslaw Marczak return ops->set_value(dev, uV); 56af41e8dbSPrzemyslaw Marczak } 57af41e8dbSPrzemyslaw Marczak 58*fbc6dab9SJoseph Chen int regulator_set_suspend_value(struct udevice *dev, int uV) 59*fbc6dab9SJoseph Chen { 60*fbc6dab9SJoseph Chen const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 61*fbc6dab9SJoseph Chen struct dm_regulator_uclass_platdata *uc_pdata; 62*fbc6dab9SJoseph Chen 63*fbc6dab9SJoseph Chen uc_pdata = dev_get_uclass_platdata(dev); 64*fbc6dab9SJoseph Chen if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV) 65*fbc6dab9SJoseph Chen return -EINVAL; 66*fbc6dab9SJoseph Chen if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV) 67*fbc6dab9SJoseph Chen return -EINVAL; 68*fbc6dab9SJoseph Chen 69*fbc6dab9SJoseph Chen if (!ops || !ops->set_suspend_value) 70*fbc6dab9SJoseph Chen return -ENOSYS; 71*fbc6dab9SJoseph Chen 72*fbc6dab9SJoseph Chen return ops->set_suspend_value(dev, uV); 73*fbc6dab9SJoseph Chen } 74*fbc6dab9SJoseph Chen 752f5d532fSKeerthy /* 762f5d532fSKeerthy * To be called with at most caution as there is no check 772f5d532fSKeerthy * before setting the actual voltage value. 782f5d532fSKeerthy */ 792f5d532fSKeerthy int regulator_set_value_force(struct udevice *dev, int uV) 802f5d532fSKeerthy { 812f5d532fSKeerthy const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 822f5d532fSKeerthy 832f5d532fSKeerthy if (!ops || !ops->set_value) 842f5d532fSKeerthy return -ENOSYS; 852f5d532fSKeerthy 862f5d532fSKeerthy return ops->set_value(dev, uV); 872f5d532fSKeerthy } 882f5d532fSKeerthy 89af41e8dbSPrzemyslaw Marczak int regulator_get_current(struct udevice *dev) 90af41e8dbSPrzemyslaw Marczak { 91af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 92af41e8dbSPrzemyslaw Marczak 93af41e8dbSPrzemyslaw Marczak if (!ops || !ops->get_current) 94af41e8dbSPrzemyslaw Marczak return -ENOSYS; 95af41e8dbSPrzemyslaw Marczak 96af41e8dbSPrzemyslaw Marczak return ops->get_current(dev); 97af41e8dbSPrzemyslaw Marczak } 98af41e8dbSPrzemyslaw Marczak 99af41e8dbSPrzemyslaw Marczak int regulator_set_current(struct udevice *dev, int uA) 100af41e8dbSPrzemyslaw Marczak { 101af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 1025483456eSKeerthy struct dm_regulator_uclass_platdata *uc_pdata; 1035483456eSKeerthy 1045483456eSKeerthy uc_pdata = dev_get_uclass_platdata(dev); 1055483456eSKeerthy if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA) 1065483456eSKeerthy return -EINVAL; 1075483456eSKeerthy if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA) 1085483456eSKeerthy return -EINVAL; 109af41e8dbSPrzemyslaw Marczak 110af41e8dbSPrzemyslaw Marczak if (!ops || !ops->set_current) 111af41e8dbSPrzemyslaw Marczak return -ENOSYS; 112af41e8dbSPrzemyslaw Marczak 113af41e8dbSPrzemyslaw Marczak return ops->set_current(dev, uA); 114af41e8dbSPrzemyslaw Marczak } 115af41e8dbSPrzemyslaw Marczak 11606bdf600SKeerthy int regulator_get_enable(struct udevice *dev) 117af41e8dbSPrzemyslaw Marczak { 118af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 119af41e8dbSPrzemyslaw Marczak 120af41e8dbSPrzemyslaw Marczak if (!ops || !ops->get_enable) 121af41e8dbSPrzemyslaw Marczak return -ENOSYS; 122af41e8dbSPrzemyslaw Marczak 123af41e8dbSPrzemyslaw Marczak return ops->get_enable(dev); 124af41e8dbSPrzemyslaw Marczak } 125af41e8dbSPrzemyslaw Marczak 126af41e8dbSPrzemyslaw Marczak int regulator_set_enable(struct udevice *dev, bool enable) 127af41e8dbSPrzemyslaw Marczak { 128af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 129af41e8dbSPrzemyslaw Marczak 130af41e8dbSPrzemyslaw Marczak if (!ops || !ops->set_enable) 131af41e8dbSPrzemyslaw Marczak return -ENOSYS; 132af41e8dbSPrzemyslaw Marczak 133af41e8dbSPrzemyslaw Marczak return ops->set_enable(dev, enable); 134af41e8dbSPrzemyslaw Marczak } 135af41e8dbSPrzemyslaw Marczak 136*fbc6dab9SJoseph Chen int regulator_set_suspend_enable(struct udevice *dev, bool enable) 137*fbc6dab9SJoseph Chen { 138*fbc6dab9SJoseph Chen const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 139*fbc6dab9SJoseph Chen 140*fbc6dab9SJoseph Chen if (!ops || !ops->set_suspend_enable) 141*fbc6dab9SJoseph Chen return -ENOSYS; 142*fbc6dab9SJoseph Chen 143*fbc6dab9SJoseph Chen return ops->set_suspend_enable(dev, enable); 144*fbc6dab9SJoseph Chen } 145*fbc6dab9SJoseph Chen 146af41e8dbSPrzemyslaw Marczak int regulator_get_mode(struct udevice *dev) 147af41e8dbSPrzemyslaw Marczak { 148af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 149af41e8dbSPrzemyslaw Marczak 150af41e8dbSPrzemyslaw Marczak if (!ops || !ops->get_mode) 151af41e8dbSPrzemyslaw Marczak return -ENOSYS; 152af41e8dbSPrzemyslaw Marczak 153af41e8dbSPrzemyslaw Marczak return ops->get_mode(dev); 154af41e8dbSPrzemyslaw Marczak } 155af41e8dbSPrzemyslaw Marczak 156af41e8dbSPrzemyslaw Marczak int regulator_set_mode(struct udevice *dev, int mode) 157af41e8dbSPrzemyslaw Marczak { 158af41e8dbSPrzemyslaw Marczak const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); 159af41e8dbSPrzemyslaw Marczak 160af41e8dbSPrzemyslaw Marczak if (!ops || !ops->set_mode) 161af41e8dbSPrzemyslaw Marczak return -ENOSYS; 162af41e8dbSPrzemyslaw Marczak 163af41e8dbSPrzemyslaw Marczak return ops->set_mode(dev, mode); 164af41e8dbSPrzemyslaw Marczak } 165af41e8dbSPrzemyslaw Marczak 1663b880757SPrzemyslaw Marczak int regulator_get_by_platname(const char *plat_name, struct udevice **devp) 167af41e8dbSPrzemyslaw Marczak { 168af41e8dbSPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 169af41e8dbSPrzemyslaw Marczak struct udevice *dev; 1703b880757SPrzemyslaw Marczak int ret; 171af41e8dbSPrzemyslaw Marczak 172af41e8dbSPrzemyslaw Marczak *devp = NULL; 173af41e8dbSPrzemyslaw Marczak 1743b880757SPrzemyslaw Marczak for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev; 1753b880757SPrzemyslaw Marczak ret = uclass_find_next_device(&dev)) { 176422f04b6SSimon Glass if (ret) { 177422f04b6SSimon Glass debug("regulator %s, ret=%d\n", dev->name, ret); 1783b880757SPrzemyslaw Marczak continue; 179422f04b6SSimon Glass } 1803b880757SPrzemyslaw Marczak 181af41e8dbSPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 182af41e8dbSPrzemyslaw Marczak if (!uc_pdata || strcmp(plat_name, uc_pdata->name)) 183af41e8dbSPrzemyslaw Marczak continue; 184af41e8dbSPrzemyslaw Marczak 185af41e8dbSPrzemyslaw Marczak return uclass_get_device_tail(dev, 0, devp); 186af41e8dbSPrzemyslaw Marczak } 187af41e8dbSPrzemyslaw Marczak 188422f04b6SSimon Glass debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret); 189af41e8dbSPrzemyslaw Marczak 190af41e8dbSPrzemyslaw Marczak return -ENODEV; 191af41e8dbSPrzemyslaw Marczak } 192af41e8dbSPrzemyslaw Marczak 1933b880757SPrzemyslaw Marczak int regulator_get_by_devname(const char *devname, struct udevice **devp) 194af41e8dbSPrzemyslaw Marczak { 195af41e8dbSPrzemyslaw Marczak return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp); 196af41e8dbSPrzemyslaw Marczak } 197af41e8dbSPrzemyslaw Marczak 1987c816e24SPrzemyslaw Marczak int device_get_supply_regulator(struct udevice *dev, const char *supply_name, 1997c816e24SPrzemyslaw Marczak struct udevice **devp) 2007c816e24SPrzemyslaw Marczak { 2017c816e24SPrzemyslaw Marczak return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 2027c816e24SPrzemyslaw Marczak supply_name, devp); 2037c816e24SPrzemyslaw Marczak } 2047c816e24SPrzemyslaw Marczak 2053b55d30fSSimon Glass int regulator_autoset(struct udevice *dev) 206af41e8dbSPrzemyslaw Marczak { 2073b55d30fSSimon Glass struct dm_regulator_uclass_platdata *uc_pdata; 2083b55d30fSSimon Glass int ret = 0; 209af41e8dbSPrzemyslaw Marczak 2103b55d30fSSimon Glass uc_pdata = dev_get_uclass_platdata(dev); 211*fbc6dab9SJoseph Chen 212*fbc6dab9SJoseph Chen ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on); 213*fbc6dab9SJoseph Chen if (!ret && uc_pdata->suspend_on) 214*fbc6dab9SJoseph Chen ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV); 215*fbc6dab9SJoseph Chen 2163b55d30fSSimon Glass if (!uc_pdata->always_on && !uc_pdata->boot_on) 2173b55d30fSSimon Glass return -EMEDIUMTYPE; 218af41e8dbSPrzemyslaw Marczak 2193b55d30fSSimon Glass if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) 2203b55d30fSSimon Glass ret = regulator_set_value(dev, uc_pdata->min_uV); 2213b55d30fSSimon Glass if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)) 2223b55d30fSSimon Glass ret = regulator_set_current(dev, uc_pdata->min_uA); 223af41e8dbSPrzemyslaw Marczak 224af41e8dbSPrzemyslaw Marczak if (!ret) 2253b55d30fSSimon Glass ret = regulator_set_enable(dev, true); 226af41e8dbSPrzemyslaw Marczak 227af41e8dbSPrzemyslaw Marczak return ret; 228af41e8dbSPrzemyslaw Marczak } 229af41e8dbSPrzemyslaw Marczak 2303b55d30fSSimon Glass static void regulator_show(struct udevice *dev, int ret) 231af41e8dbSPrzemyslaw Marczak { 232af41e8dbSPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 2333b55d30fSSimon Glass 2343b55d30fSSimon Glass uc_pdata = dev_get_uclass_platdata(dev); 2353b55d30fSSimon Glass 2363b55d30fSSimon Glass printf("%s@%s: ", dev->name, uc_pdata->name); 2373b55d30fSSimon Glass if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) 2383b55d30fSSimon Glass printf("set %d uV", uc_pdata->min_uV); 2393b55d30fSSimon Glass if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA) 2403b55d30fSSimon Glass printf("; set %d uA", uc_pdata->min_uA); 2413b55d30fSSimon Glass printf("; enabling"); 2423b55d30fSSimon Glass if (ret) 2437d577999SSimon Glass printf(" (ret: %d)", ret); 2443b55d30fSSimon Glass printf("\n"); 2453b55d30fSSimon Glass } 2463b55d30fSSimon Glass 2473b55d30fSSimon Glass int regulator_autoset_by_name(const char *platname, struct udevice **devp) 2483b55d30fSSimon Glass { 249af41e8dbSPrzemyslaw Marczak struct udevice *dev; 250af41e8dbSPrzemyslaw Marczak int ret; 251af41e8dbSPrzemyslaw Marczak 2523b880757SPrzemyslaw Marczak ret = regulator_get_by_platname(platname, &dev); 253af41e8dbSPrzemyslaw Marczak if (devp) 254af41e8dbSPrzemyslaw Marczak *devp = dev; 2553b55d30fSSimon Glass if (ret) { 256422f04b6SSimon Glass debug("Can get the regulator: %s (err=%d)\n", platname, ret); 257af41e8dbSPrzemyslaw Marczak return ret; 258af41e8dbSPrzemyslaw Marczak } 259af41e8dbSPrzemyslaw Marczak 2603b55d30fSSimon Glass return regulator_autoset(dev); 2613b55d30fSSimon Glass } 2623b55d30fSSimon Glass 2633b880757SPrzemyslaw Marczak int regulator_list_autoset(const char *list_platname[], 264af41e8dbSPrzemyslaw Marczak struct udevice *list_devp[], 265af41e8dbSPrzemyslaw Marczak bool verbose) 266af41e8dbSPrzemyslaw Marczak { 267af41e8dbSPrzemyslaw Marczak struct udevice *dev; 2683b880757SPrzemyslaw Marczak int error = 0, i = 0, ret; 269af41e8dbSPrzemyslaw Marczak 2703b880757SPrzemyslaw Marczak while (list_platname[i]) { 2713b55d30fSSimon Glass ret = regulator_autoset_by_name(list_platname[i], &dev); 2723b55d30fSSimon Glass if (ret != -EMEDIUMTYPE && verbose) 2733b55d30fSSimon Glass regulator_show(dev, ret); 2743b880757SPrzemyslaw Marczak if (ret & !error) 2753b880757SPrzemyslaw Marczak error = ret; 276af41e8dbSPrzemyslaw Marczak 2773b880757SPrzemyslaw Marczak if (list_devp) 278af41e8dbSPrzemyslaw Marczak list_devp[i] = dev; 2793b880757SPrzemyslaw Marczak 2803b880757SPrzemyslaw Marczak i++; 281af41e8dbSPrzemyslaw Marczak } 282af41e8dbSPrzemyslaw Marczak 2833b880757SPrzemyslaw Marczak return error; 2843b880757SPrzemyslaw Marczak } 2853b880757SPrzemyslaw Marczak 2863b880757SPrzemyslaw Marczak static bool regulator_name_is_unique(struct udevice *check_dev, 2873b880757SPrzemyslaw Marczak const char *check_name) 2883b880757SPrzemyslaw Marczak { 2893b880757SPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 2903b880757SPrzemyslaw Marczak struct udevice *dev; 2913b880757SPrzemyslaw Marczak int check_len = strlen(check_name); 2923b880757SPrzemyslaw Marczak int ret; 2933b880757SPrzemyslaw Marczak int len; 2943b880757SPrzemyslaw Marczak 2953b880757SPrzemyslaw Marczak for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev; 2963b880757SPrzemyslaw Marczak ret = uclass_find_next_device(&dev)) { 2973b880757SPrzemyslaw Marczak if (ret || dev == check_dev) 2983b880757SPrzemyslaw Marczak continue; 2993b880757SPrzemyslaw Marczak 3003b880757SPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 3013b880757SPrzemyslaw Marczak len = strlen(uc_pdata->name); 3023b880757SPrzemyslaw Marczak if (len != check_len) 3033b880757SPrzemyslaw Marczak continue; 3043b880757SPrzemyslaw Marczak 3053b880757SPrzemyslaw Marczak if (!strcmp(uc_pdata->name, check_name)) 3063b880757SPrzemyslaw Marczak return false; 3073b880757SPrzemyslaw Marczak } 3083b880757SPrzemyslaw Marczak 3093b880757SPrzemyslaw Marczak return true; 310af41e8dbSPrzemyslaw Marczak } 311af41e8dbSPrzemyslaw Marczak 312af41e8dbSPrzemyslaw Marczak static int regulator_post_bind(struct udevice *dev) 313af41e8dbSPrzemyslaw Marczak { 314af41e8dbSPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 3153b880757SPrzemyslaw Marczak const char *property = "regulator-name"; 316af41e8dbSPrzemyslaw Marczak 317af41e8dbSPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 318af41e8dbSPrzemyslaw Marczak 319af41e8dbSPrzemyslaw Marczak /* Regulator's mandatory constraint */ 320f15cd4f1SSimon Glass uc_pdata->name = dev_read_string(dev, property); 321af41e8dbSPrzemyslaw Marczak if (!uc_pdata->name) { 322f15cd4f1SSimon Glass debug("%s: dev '%s' has no property '%s'\n", 323f15cd4f1SSimon Glass __func__, dev->name, property); 324f15cd4f1SSimon Glass uc_pdata->name = dev_read_name(dev); 325cf260011SPeng Fan if (!uc_pdata->name) 3263b880757SPrzemyslaw Marczak return -EINVAL; 327af41e8dbSPrzemyslaw Marczak } 328af41e8dbSPrzemyslaw Marczak 3293b880757SPrzemyslaw Marczak if (regulator_name_is_unique(dev, uc_pdata->name)) 330af41e8dbSPrzemyslaw Marczak return 0; 3313b880757SPrzemyslaw Marczak 332f15cd4f1SSimon Glass debug("'%s' of dev: '%s', has nonunique value: '%s\n", 3333b880757SPrzemyslaw Marczak property, dev->name, uc_pdata->name); 3343b880757SPrzemyslaw Marczak 3353b880757SPrzemyslaw Marczak return -EINVAL; 336af41e8dbSPrzemyslaw Marczak } 337af41e8dbSPrzemyslaw Marczak 338af41e8dbSPrzemyslaw Marczak static int regulator_pre_probe(struct udevice *dev) 339af41e8dbSPrzemyslaw Marczak { 340af41e8dbSPrzemyslaw Marczak struct dm_regulator_uclass_platdata *uc_pdata; 341*fbc6dab9SJoseph Chen ofnode node; 342af41e8dbSPrzemyslaw Marczak 343af41e8dbSPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 344af41e8dbSPrzemyslaw Marczak if (!uc_pdata) 345af41e8dbSPrzemyslaw Marczak return -ENXIO; 346af41e8dbSPrzemyslaw Marczak 347af41e8dbSPrzemyslaw Marczak /* Regulator's optional constraints */ 348f15cd4f1SSimon Glass uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt", 349f15cd4f1SSimon Glass -ENODATA); 350f15cd4f1SSimon Glass uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt", 351f15cd4f1SSimon Glass -ENODATA); 352f15cd4f1SSimon Glass uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp", 353f15cd4f1SSimon Glass -ENODATA); 354f15cd4f1SSimon Glass uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp", 355f15cd4f1SSimon Glass -ENODATA); 356f15cd4f1SSimon Glass uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on"); 357f15cd4f1SSimon Glass uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on"); 358af41e8dbSPrzemyslaw Marczak 359*fbc6dab9SJoseph Chen node = dev_read_subnode(dev, "regulator-state-mem"); 360*fbc6dab9SJoseph Chen if (ofnode_valid(node)) { 361*fbc6dab9SJoseph Chen uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend"); 362*fbc6dab9SJoseph Chen if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV)) 363*fbc6dab9SJoseph Chen uc_pdata->suspend_uV = uc_pdata->max_uA; 364*fbc6dab9SJoseph Chen } else { 365*fbc6dab9SJoseph Chen uc_pdata->suspend_on = true; 366*fbc6dab9SJoseph Chen uc_pdata->suspend_uV = uc_pdata->max_uA; 367*fbc6dab9SJoseph Chen } 368*fbc6dab9SJoseph Chen 3697837ceabSSimon Glass /* Those values are optional (-ENODATA if unset) */ 3707837ceabSSimon Glass if ((uc_pdata->min_uV != -ENODATA) && 3717837ceabSSimon Glass (uc_pdata->max_uV != -ENODATA) && 3727837ceabSSimon Glass (uc_pdata->min_uV == uc_pdata->max_uV)) 3737837ceabSSimon Glass uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV; 3747837ceabSSimon Glass 3757837ceabSSimon Glass /* Those values are optional (-ENODATA if unset) */ 3767837ceabSSimon Glass if ((uc_pdata->min_uA != -ENODATA) && 3777837ceabSSimon Glass (uc_pdata->max_uA != -ENODATA) && 3787837ceabSSimon Glass (uc_pdata->min_uA == uc_pdata->max_uA)) 3797837ceabSSimon Glass uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA; 3807837ceabSSimon Glass 381af41e8dbSPrzemyslaw Marczak return 0; 382af41e8dbSPrzemyslaw Marczak } 383af41e8dbSPrzemyslaw Marczak 384083fc83aSSimon Glass int regulators_enable_boot_on(bool verbose) 385083fc83aSSimon Glass { 386083fc83aSSimon Glass struct udevice *dev; 387083fc83aSSimon Glass struct uclass *uc; 388083fc83aSSimon Glass int ret; 389083fc83aSSimon Glass 390083fc83aSSimon Glass ret = uclass_get(UCLASS_REGULATOR, &uc); 391083fc83aSSimon Glass if (ret) 392083fc83aSSimon Glass return ret; 393083fc83aSSimon Glass for (uclass_first_device(UCLASS_REGULATOR, &dev); 3943f603cbbSSimon Glass dev; 395083fc83aSSimon Glass uclass_next_device(&dev)) { 396083fc83aSSimon Glass ret = regulator_autoset(dev); 397d08504d1SSimon Glass if (ret == -EMEDIUMTYPE) { 398d08504d1SSimon Glass ret = 0; 399083fc83aSSimon Glass continue; 400d08504d1SSimon Glass } 401083fc83aSSimon Glass if (verbose) 402083fc83aSSimon Glass regulator_show(dev, ret); 403364809deSSimon Glass if (ret == -ENOSYS) 404364809deSSimon Glass ret = 0; 405083fc83aSSimon Glass } 406083fc83aSSimon Glass 407083fc83aSSimon Glass return ret; 408083fc83aSSimon Glass } 409083fc83aSSimon Glass 410af41e8dbSPrzemyslaw Marczak UCLASS_DRIVER(regulator) = { 411af41e8dbSPrzemyslaw Marczak .id = UCLASS_REGULATOR, 412af41e8dbSPrzemyslaw Marczak .name = "regulator", 413af41e8dbSPrzemyslaw Marczak .post_bind = regulator_post_bind, 414af41e8dbSPrzemyslaw Marczak .pre_probe = regulator_pre_probe, 415af41e8dbSPrzemyslaw Marczak .per_device_platdata_auto_alloc_size = 416af41e8dbSPrzemyslaw Marczak sizeof(struct dm_regulator_uclass_platdata), 417af41e8dbSPrzemyslaw Marczak }; 418