Home | History | Annotate | Download | only in regulator
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2014-2015 Samsung Electronics
      4  * Przemyslaw Marczak <p.marczak (at) samsung.com>
      5  */
      6 
      7 #include <common.h>
      8 #include <errno.h>
      9 #include <dm.h>
     10 #include <dm/uclass-internal.h>
     11 #include <power/pmic.h>
     12 #include <power/regulator.h>
     13 
     14 int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
     15 {
     16 	struct dm_regulator_uclass_platdata *uc_pdata;
     17 
     18 	*modep = NULL;
     19 
     20 	uc_pdata = dev_get_uclass_platdata(dev);
     21 	if (!uc_pdata)
     22 		return -ENXIO;
     23 
     24 	*modep = uc_pdata->mode;
     25 	return uc_pdata->mode_count;
     26 }
     27 
     28 int regulator_get_value(struct udevice *dev)
     29 {
     30 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     31 
     32 	if (!ops || !ops->get_value)
     33 		return -ENOSYS;
     34 
     35 	return ops->get_value(dev);
     36 }
     37 
     38 int regulator_set_value(struct udevice *dev, int uV)
     39 {
     40 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     41 	struct dm_regulator_uclass_platdata *uc_pdata;
     42 
     43 	uc_pdata = dev_get_uclass_platdata(dev);
     44 	if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
     45 		return -EINVAL;
     46 	if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
     47 		return -EINVAL;
     48 
     49 	if (!ops || !ops->set_value)
     50 		return -ENOSYS;
     51 
     52 	return ops->set_value(dev, uV);
     53 }
     54 
     55 /*
     56  * To be called with at most caution as there is no check
     57  * before setting the actual voltage value.
     58  */
     59 int regulator_set_value_force(struct udevice *dev, int uV)
     60 {
     61 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     62 
     63 	if (!ops || !ops->set_value)
     64 		return -ENOSYS;
     65 
     66 	return ops->set_value(dev, uV);
     67 }
     68 
     69 int regulator_get_current(struct udevice *dev)
     70 {
     71 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     72 
     73 	if (!ops || !ops->get_current)
     74 		return -ENOSYS;
     75 
     76 	return ops->get_current(dev);
     77 }
     78 
     79 int regulator_set_current(struct udevice *dev, int uA)
     80 {
     81 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     82 	struct dm_regulator_uclass_platdata *uc_pdata;
     83 
     84 	uc_pdata = dev_get_uclass_platdata(dev);
     85 	if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
     86 		return -EINVAL;
     87 	if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
     88 		return -EINVAL;
     89 
     90 	if (!ops || !ops->set_current)
     91 		return -ENOSYS;
     92 
     93 	return ops->set_current(dev, uA);
     94 }
     95 
     96 int regulator_get_enable(struct udevice *dev)
     97 {
     98 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
     99 
    100 	if (!ops || !ops->get_enable)
    101 		return -ENOSYS;
    102 
    103 	return ops->get_enable(dev);
    104 }
    105 
    106 int regulator_set_enable(struct udevice *dev, bool enable)
    107 {
    108 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
    109 
    110 	if (!ops || !ops->set_enable)
    111 		return -ENOSYS;
    112 
    113 	return ops->set_enable(dev, enable);
    114 }
    115 
    116 int regulator_get_mode(struct udevice *dev)
    117 {
    118 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
    119 
    120 	if (!ops || !ops->get_mode)
    121 		return -ENOSYS;
    122 
    123 	return ops->get_mode(dev);
    124 }
    125 
    126 int regulator_set_mode(struct udevice *dev, int mode)
    127 {
    128 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
    129 
    130 	if (!ops || !ops->set_mode)
    131 		return -ENOSYS;
    132 
    133 	return ops->set_mode(dev, mode);
    134 }
    135 
    136 int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
    137 {
    138 	struct dm_regulator_uclass_platdata *uc_pdata;
    139 	struct udevice *dev;
    140 	int ret;
    141 
    142 	*devp = NULL;
    143 
    144 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
    145 	     ret = uclass_find_next_device(&dev)) {
    146 		if (ret) {
    147 			debug("regulator %s, ret=%d\n", dev->name, ret);
    148 			continue;
    149 		}
    150 
    151 		uc_pdata = dev_get_uclass_platdata(dev);
    152 		if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
    153 			continue;
    154 
    155 		return uclass_get_device_tail(dev, 0, devp);
    156 	}
    157 
    158 	debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
    159 
    160 	return -ENODEV;
    161 }
    162 
    163 int regulator_get_by_devname(const char *devname, struct udevice **devp)
    164 {
    165 	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
    166 }
    167 
    168 int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
    169 				struct udevice **devp)
    170 {
    171 	return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
    172 					    supply_name, devp);
    173 }
    174 
    175 int regulator_autoset(struct udevice *dev)
    176 {
    177 	struct dm_regulator_uclass_platdata *uc_pdata;
    178 	int ret = 0;
    179 
    180 	uc_pdata = dev_get_uclass_platdata(dev);
    181 	if (!uc_pdata->always_on && !uc_pdata->boot_on)
    182 		return -EMEDIUMTYPE;
    183 
    184 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
    185 		ret = regulator_set_value(dev, uc_pdata->min_uV);
    186 	if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
    187 		ret = regulator_set_current(dev, uc_pdata->min_uA);
    188 
    189 	if (!ret)
    190 		ret = regulator_set_enable(dev, true);
    191 
    192 	return ret;
    193 }
    194 
    195 static void regulator_show(struct udevice *dev, int ret)
    196 {
    197 	struct dm_regulator_uclass_platdata *uc_pdata;
    198 
    199 	uc_pdata = dev_get_uclass_platdata(dev);
    200 
    201 	printf("%s@%s: ", dev->name, uc_pdata->name);
    202 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
    203 		printf("set %d uV", uc_pdata->min_uV);
    204 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
    205 		printf("; set %d uA", uc_pdata->min_uA);
    206 	printf("; enabling");
    207 	if (ret)
    208 		printf(" (ret: %d)", ret);
    209 	printf("\n");
    210 }
    211 
    212 int regulator_autoset_by_name(const char *platname, struct udevice **devp)
    213 {
    214 	struct udevice *dev;
    215 	int ret;
    216 
    217 	ret = regulator_get_by_platname(platname, &dev);
    218 	if (devp)
    219 		*devp = dev;
    220 	if (ret) {
    221 		debug("Can get the regulator: %s (err=%d)\n", platname, ret);
    222 		return ret;
    223 	}
    224 
    225 	return regulator_autoset(dev);
    226 }
    227 
    228 int regulator_list_autoset(const char *list_platname[],
    229 			   struct udevice *list_devp[],
    230 			   bool verbose)
    231 {
    232 	struct udevice *dev;
    233 	int error = 0, i = 0, ret;
    234 
    235 	while (list_platname[i]) {
    236 		ret = regulator_autoset_by_name(list_platname[i], &dev);
    237 		if (ret != -EMEDIUMTYPE && verbose)
    238 			regulator_show(dev, ret);
    239 		if (ret & !error)
    240 			error = ret;
    241 
    242 		if (list_devp)
    243 			list_devp[i] = dev;
    244 
    245 		i++;
    246 	}
    247 
    248 	return error;
    249 }
    250 
    251 static bool regulator_name_is_unique(struct udevice *check_dev,
    252 				     const char *check_name)
    253 {
    254 	struct dm_regulator_uclass_platdata *uc_pdata;
    255 	struct udevice *dev;
    256 	int check_len = strlen(check_name);
    257 	int ret;
    258 	int len;
    259 
    260 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
    261 	     ret = uclass_find_next_device(&dev)) {
    262 		if (ret || dev == check_dev)
    263 			continue;
    264 
    265 		uc_pdata = dev_get_uclass_platdata(dev);
    266 		len = strlen(uc_pdata->name);
    267 		if (len != check_len)
    268 			continue;
    269 
    270 		if (!strcmp(uc_pdata->name, check_name))
    271 			return false;
    272 	}
    273 
    274 	return true;
    275 }
    276 
    277 static int regulator_post_bind(struct udevice *dev)
    278 {
    279 	struct dm_regulator_uclass_platdata *uc_pdata;
    280 	const char *property = "regulator-name";
    281 
    282 	uc_pdata = dev_get_uclass_platdata(dev);
    283 
    284 	/* Regulator's mandatory constraint */
    285 	uc_pdata->name = dev_read_string(dev, property);
    286 	if (!uc_pdata->name) {
    287 		debug("%s: dev '%s' has no property '%s'\n",
    288 		      __func__, dev->name, property);
    289 		uc_pdata->name = dev_read_name(dev);
    290 		if (!uc_pdata->name)
    291 			return -EINVAL;
    292 	}
    293 
    294 	if (regulator_name_is_unique(dev, uc_pdata->name))
    295 		return 0;
    296 
    297 	debug("'%s' of dev: '%s', has nonunique value: '%s\n",
    298 	      property, dev->name, uc_pdata->name);
    299 
    300 	return -EINVAL;
    301 }
    302 
    303 static int regulator_pre_probe(struct udevice *dev)
    304 {
    305 	struct dm_regulator_uclass_platdata *uc_pdata;
    306 
    307 	uc_pdata = dev_get_uclass_platdata(dev);
    308 	if (!uc_pdata)
    309 		return -ENXIO;
    310 
    311 	/* Regulator's optional constraints */
    312 	uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
    313 						-ENODATA);
    314 	uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
    315 						-ENODATA);
    316 	uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
    317 						-ENODATA);
    318 	uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
    319 						-ENODATA);
    320 	uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
    321 	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
    322 
    323 	/* Those values are optional (-ENODATA if unset) */
    324 	if ((uc_pdata->min_uV != -ENODATA) &&
    325 	    (uc_pdata->max_uV != -ENODATA) &&
    326 	    (uc_pdata->min_uV == uc_pdata->max_uV))
    327 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
    328 
    329 	/* Those values are optional (-ENODATA if unset) */
    330 	if ((uc_pdata->min_uA != -ENODATA) &&
    331 	    (uc_pdata->max_uA != -ENODATA) &&
    332 	    (uc_pdata->min_uA == uc_pdata->max_uA))
    333 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
    334 
    335 	return 0;
    336 }
    337 
    338 int regulators_enable_boot_on(bool verbose)
    339 {
    340 	struct udevice *dev;
    341 	struct uclass *uc;
    342 	int ret;
    343 
    344 	ret = uclass_get(UCLASS_REGULATOR, &uc);
    345 	if (ret)
    346 		return ret;
    347 	for (uclass_first_device(UCLASS_REGULATOR, &dev);
    348 	     dev;
    349 	     uclass_next_device(&dev)) {
    350 		ret = regulator_autoset(dev);
    351 		if (ret == -EMEDIUMTYPE) {
    352 			ret = 0;
    353 			continue;
    354 		}
    355 		if (verbose)
    356 			regulator_show(dev, ret);
    357 		if (ret == -ENOSYS)
    358 			ret = 0;
    359 	}
    360 
    361 	return ret;
    362 }
    363 
    364 UCLASS_DRIVER(regulator) = {
    365 	.id		= UCLASS_REGULATOR,
    366 	.name		= "regulator",
    367 	.post_bind	= regulator_post_bind,
    368 	.pre_probe	= regulator_pre_probe,
    369 	.per_device_platdata_auto_alloc_size =
    370 				sizeof(struct dm_regulator_uclass_platdata),
    371 };
    372