1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014-2015 Samsung Electronics
4  * Przemyslaw Marczak <p.marczak@samsung.com>
5  */
6 
7 #define LOG_CATEGORY UCLASS_REGULATOR
8 
9 #include <common.h>
10 #include <errno.h>
11 #include <dm.h>
12 #include <log.h>
13 #include <dm/uclass-internal.h>
14 #include <linux/delay.h>
15 #include <power/pmic.h>
16 #include <power/regulator.h>
17 
regulator_mode(struct udevice * dev,struct dm_regulator_mode ** modep)18 int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
19 {
20 	struct dm_regulator_uclass_plat *uc_pdata;
21 
22 	*modep = NULL;
23 
24 	uc_pdata = dev_get_uclass_plat(dev);
25 	if (!uc_pdata)
26 		return -ENXIO;
27 
28 	*modep = uc_pdata->mode;
29 	return uc_pdata->mode_count;
30 }
31 
regulator_get_value(struct udevice * dev)32 int regulator_get_value(struct udevice *dev)
33 {
34 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
35 
36 	if (!ops || !ops->get_value)
37 		return -ENOSYS;
38 
39 	return ops->get_value(dev);
40 }
41 
regulator_set_value_ramp_delay(struct udevice * dev,int old_uV,int new_uV,unsigned int ramp_delay)42 static void regulator_set_value_ramp_delay(struct udevice *dev, int old_uV,
43 					   int new_uV, unsigned int ramp_delay)
44 {
45 	int delay = DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay);
46 
47 	debug("regulator %s: delay %u us (%d uV -> %d uV)\n", dev->name, delay,
48 	      old_uV, new_uV);
49 
50 	udelay(delay);
51 }
52 
regulator_set_value(struct udevice * dev,int uV)53 int regulator_set_value(struct udevice *dev, int uV)
54 {
55 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
56 	struct dm_regulator_uclass_plat *uc_pdata;
57 	int ret, old_uV = uV, is_enabled = 0;
58 
59 	uc_pdata = dev_get_uclass_plat(dev);
60 	if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
61 		return -EINVAL;
62 	if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
63 		return -EINVAL;
64 
65 	if (!ops || !ops->set_value)
66 		return -ENOSYS;
67 
68 	if (uc_pdata->ramp_delay) {
69 		is_enabled = regulator_get_enable(dev);
70 		old_uV = regulator_get_value(dev);
71 	}
72 
73 	ret = ops->set_value(dev, uV);
74 
75 	if (!ret) {
76 		if (uc_pdata->ramp_delay && old_uV > 0 && is_enabled)
77 			regulator_set_value_ramp_delay(dev, old_uV, uV,
78 						       uc_pdata->ramp_delay);
79 	}
80 
81 	return ret;
82 }
83 
regulator_set_suspend_value(struct udevice * dev,int uV)84 int regulator_set_suspend_value(struct udevice *dev, int uV)
85 {
86 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
87 	struct dm_regulator_uclass_plat *uc_pdata;
88 
89 	uc_pdata = dev_get_uclass_plat(dev);
90 	if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
91 		return -EINVAL;
92 	if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
93 		return -EINVAL;
94 
95 	if (!ops->set_suspend_value)
96 		return -ENOSYS;
97 
98 	return ops->set_suspend_value(dev, uV);
99 }
100 
regulator_get_suspend_value(struct udevice * dev)101 int regulator_get_suspend_value(struct udevice *dev)
102 {
103 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
104 
105 	if (!ops->get_suspend_value)
106 		return -ENOSYS;
107 
108 	return ops->get_suspend_value(dev);
109 }
110 
111 /*
112  * To be called with at most caution as there is no check
113  * before setting the actual voltage value.
114  */
regulator_set_value_force(struct udevice * dev,int uV)115 int regulator_set_value_force(struct udevice *dev, int uV)
116 {
117 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
118 
119 	if (!ops || !ops->set_value)
120 		return -ENOSYS;
121 
122 	return ops->set_value(dev, uV);
123 }
124 
regulator_get_current(struct udevice * dev)125 int regulator_get_current(struct udevice *dev)
126 {
127 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
128 
129 	if (!ops || !ops->get_current)
130 		return -ENOSYS;
131 
132 	return ops->get_current(dev);
133 }
134 
regulator_set_current(struct udevice * dev,int uA)135 int regulator_set_current(struct udevice *dev, int uA)
136 {
137 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
138 	struct dm_regulator_uclass_plat *uc_pdata;
139 
140 	uc_pdata = dev_get_uclass_plat(dev);
141 	if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
142 		return -EINVAL;
143 	if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
144 		return -EINVAL;
145 
146 	if (!ops || !ops->set_current)
147 		return -ENOSYS;
148 
149 	return ops->set_current(dev, uA);
150 }
151 
regulator_get_enable(struct udevice * dev)152 int regulator_get_enable(struct udevice *dev)
153 {
154 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
155 
156 	if (!ops || !ops->get_enable)
157 		return -ENOSYS;
158 
159 	return ops->get_enable(dev);
160 }
161 
regulator_set_enable(struct udevice * dev,bool enable)162 int regulator_set_enable(struct udevice *dev, bool enable)
163 {
164 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
165 	struct dm_regulator_uclass_plat *uc_pdata;
166 	int ret, old_enable = 0;
167 
168 	if (!ops || !ops->set_enable)
169 		return -ENOSYS;
170 
171 	uc_pdata = dev_get_uclass_plat(dev);
172 	if (!enable && uc_pdata->always_on)
173 		return -EACCES;
174 
175 	if (uc_pdata->ramp_delay)
176 		old_enable = regulator_get_enable(dev);
177 
178 	ret = ops->set_enable(dev, enable);
179 	if (!ret) {
180 		if (uc_pdata->ramp_delay && !old_enable && enable) {
181 			int uV = regulator_get_value(dev);
182 
183 			if (uV > 0) {
184 				regulator_set_value_ramp_delay(dev, 0, uV,
185 							       uc_pdata->ramp_delay);
186 			}
187 		}
188 	}
189 
190 	return ret;
191 }
192 
regulator_set_enable_if_allowed(struct udevice * dev,bool enable)193 int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
194 {
195 	int ret;
196 
197 	ret = regulator_set_enable(dev, enable);
198 	if (ret == -ENOSYS || ret == -EACCES)
199 		return 0;
200 
201 	return ret;
202 }
203 
regulator_set_suspend_enable(struct udevice * dev,bool enable)204 int regulator_set_suspend_enable(struct udevice *dev, bool enable)
205 {
206 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
207 
208 	if (!ops->set_suspend_enable)
209 		return -ENOSYS;
210 
211 	return ops->set_suspend_enable(dev, enable);
212 }
213 
regulator_get_suspend_enable(struct udevice * dev)214 int regulator_get_suspend_enable(struct udevice *dev)
215 {
216 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
217 
218 	if (!ops->get_suspend_enable)
219 		return -ENOSYS;
220 
221 	return ops->get_suspend_enable(dev);
222 }
223 
regulator_get_mode(struct udevice * dev)224 int regulator_get_mode(struct udevice *dev)
225 {
226 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
227 
228 	if (!ops || !ops->get_mode)
229 		return -ENOSYS;
230 
231 	return ops->get_mode(dev);
232 }
233 
regulator_set_mode(struct udevice * dev,int mode)234 int regulator_set_mode(struct udevice *dev, int mode)
235 {
236 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
237 
238 	if (!ops || !ops->set_mode)
239 		return -ENOSYS;
240 
241 	return ops->set_mode(dev, mode);
242 }
243 
regulator_get_by_platname(const char * plat_name,struct udevice ** devp)244 int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
245 {
246 	struct dm_regulator_uclass_plat *uc_pdata;
247 	struct udevice *dev;
248 	int ret;
249 
250 	*devp = NULL;
251 
252 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
253 	     ret = uclass_find_next_device(&dev)) {
254 		if (ret) {
255 			debug("regulator %s, ret=%d\n", dev->name, ret);
256 			continue;
257 		}
258 
259 		uc_pdata = dev_get_uclass_plat(dev);
260 		if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
261 			continue;
262 
263 		return uclass_get_device_tail(dev, 0, devp);
264 	}
265 
266 	debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
267 
268 	return -ENODEV;
269 }
270 
regulator_get_by_devname(const char * devname,struct udevice ** devp)271 int regulator_get_by_devname(const char *devname, struct udevice **devp)
272 {
273 	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
274 }
275 
device_get_supply_regulator(struct udevice * dev,const char * supply_name,struct udevice ** devp)276 int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
277 				struct udevice **devp)
278 {
279 	return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
280 					    supply_name, devp);
281 }
282 
regulator_autoset(struct udevice * dev)283 int regulator_autoset(struct udevice *dev)
284 {
285 	struct dm_regulator_uclass_plat *uc_pdata;
286 	int ret = 0;
287 
288 	uc_pdata = dev_get_uclass_plat(dev);
289 
290 	ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
291 	if (ret == -ENOSYS)
292 		ret = 0;
293 
294 	if (!ret && uc_pdata->suspend_on) {
295 		ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
296 		if (ret == -ENOSYS)
297 			ret = 0;
298 
299 		if (ret)
300 			return ret;
301 	}
302 
303 	if (!uc_pdata->always_on && !uc_pdata->boot_on)
304 		return -EMEDIUMTYPE;
305 
306 	if (uc_pdata->type == REGULATOR_TYPE_FIXED)
307 		return regulator_set_enable(dev, true);
308 
309 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
310 		ret = regulator_set_value(dev, uc_pdata->min_uV);
311 	if (uc_pdata->init_uV > 0)
312 		ret = regulator_set_value(dev, uc_pdata->init_uV);
313 	if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
314 		ret = regulator_set_current(dev, uc_pdata->min_uA);
315 
316 	if (!ret)
317 		ret = regulator_set_enable(dev, true);
318 
319 	return ret;
320 }
321 
regulator_unset(struct udevice * dev)322 int regulator_unset(struct udevice *dev)
323 {
324 	struct dm_regulator_uclass_plat *uc_pdata;
325 
326 	uc_pdata = dev_get_uclass_plat(dev);
327 	if (uc_pdata && uc_pdata->force_off)
328 		return regulator_set_enable(dev, false);
329 
330 	return -EMEDIUMTYPE;
331 }
332 
regulator_show(struct udevice * dev,int ret)333 static void regulator_show(struct udevice *dev, int ret)
334 {
335 	struct dm_regulator_uclass_plat *uc_pdata;
336 
337 	uc_pdata = dev_get_uclass_plat(dev);
338 
339 	printf("%s@%s: ", dev->name, uc_pdata->name);
340 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
341 		printf("set %d uV", uc_pdata->min_uV);
342 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
343 		printf("; set %d uA", uc_pdata->min_uA);
344 	printf("; enabling");
345 	if (ret)
346 		printf(" (ret: %d)", ret);
347 	printf("\n");
348 }
349 
regulator_autoset_by_name(const char * platname,struct udevice ** devp)350 int regulator_autoset_by_name(const char *platname, struct udevice **devp)
351 {
352 	struct udevice *dev;
353 	int ret;
354 
355 	ret = regulator_get_by_platname(platname, &dev);
356 	if (devp)
357 		*devp = dev;
358 	if (ret) {
359 		debug("Can get the regulator: %s (err=%d)\n", platname, ret);
360 		return ret;
361 	}
362 
363 	return regulator_autoset(dev);
364 }
365 
regulator_list_autoset(const char * list_platname[],struct udevice * list_devp[],bool verbose)366 int regulator_list_autoset(const char *list_platname[],
367 			   struct udevice *list_devp[],
368 			   bool verbose)
369 {
370 	struct udevice *dev;
371 	int error = 0, i = 0, ret;
372 
373 	while (list_platname[i]) {
374 		ret = regulator_autoset_by_name(list_platname[i], &dev);
375 		if (ret != -EMEDIUMTYPE && verbose)
376 			regulator_show(dev, ret);
377 		if (ret & !error)
378 			error = ret;
379 
380 		if (list_devp)
381 			list_devp[i] = dev;
382 
383 		i++;
384 	}
385 
386 	return error;
387 }
388 
regulator_name_is_unique(struct udevice * check_dev,const char * check_name)389 static bool regulator_name_is_unique(struct udevice *check_dev,
390 				     const char *check_name)
391 {
392 	struct dm_regulator_uclass_plat *uc_pdata;
393 	struct udevice *dev;
394 	int check_len = strlen(check_name);
395 	int ret;
396 	int len;
397 
398 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
399 	     ret = uclass_find_next_device(&dev)) {
400 		if (ret || dev == check_dev)
401 			continue;
402 
403 		uc_pdata = dev_get_uclass_plat(dev);
404 		len = strlen(uc_pdata->name);
405 		if (len != check_len)
406 			continue;
407 
408 		if (!strcmp(uc_pdata->name, check_name))
409 			return false;
410 	}
411 
412 	return true;
413 }
414 
regulator_post_bind(struct udevice * dev)415 static int regulator_post_bind(struct udevice *dev)
416 {
417 	struct dm_regulator_uclass_plat *uc_pdata;
418 	const char *property = "regulator-name";
419 
420 	uc_pdata = dev_get_uclass_plat(dev);
421 
422 	/* Regulator's mandatory constraint */
423 	uc_pdata->name = dev_read_string(dev, property);
424 	if (!uc_pdata->name) {
425 		debug("%s: dev '%s' has no property '%s'\n",
426 		      __func__, dev->name, property);
427 		uc_pdata->name = dev_read_name(dev);
428 		if (!uc_pdata->name)
429 			return -EINVAL;
430 	}
431 
432 	if (regulator_name_is_unique(dev, uc_pdata->name))
433 		return 0;
434 
435 	debug("'%s' of dev: '%s', has nonunique value: '%s\n",
436 	      property, dev->name, uc_pdata->name);
437 
438 	return -EINVAL;
439 }
440 
regulator_pre_probe(struct udevice * dev)441 static int regulator_pre_probe(struct udevice *dev)
442 {
443 	struct dm_regulator_uclass_plat *uc_pdata;
444 	ofnode node;
445 
446 	uc_pdata = dev_get_uclass_plat(dev);
447 	if (!uc_pdata)
448 		return -ENXIO;
449 
450 	/* Regulator's optional constraints */
451 	uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
452 						-ENODATA);
453 	uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
454 						-ENODATA);
455 	uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
456 						 -ENODATA);
457 	uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
458 						-ENODATA);
459 	uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
460 						-ENODATA);
461 	uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
462 	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
463 	uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
464 						    0);
465 	uc_pdata->force_off = dev_read_bool(dev, "regulator-force-boot-off");
466 
467 	node = dev_read_subnode(dev, "regulator-state-mem");
468 	if (ofnode_valid(node)) {
469 		uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
470 		if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
471 			uc_pdata->suspend_uV = uc_pdata->max_uV;
472 	} else {
473 		uc_pdata->suspend_on = true;
474 		uc_pdata->suspend_uV = uc_pdata->max_uV;
475 	}
476 
477 	/* Those values are optional (-ENODATA if unset) */
478 	if ((uc_pdata->min_uV != -ENODATA) &&
479 	    (uc_pdata->max_uV != -ENODATA) &&
480 	    (uc_pdata->min_uV == uc_pdata->max_uV))
481 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
482 
483 	/* Those values are optional (-ENODATA if unset) */
484 	if ((uc_pdata->min_uA != -ENODATA) &&
485 	    (uc_pdata->max_uA != -ENODATA) &&
486 	    (uc_pdata->min_uA == uc_pdata->max_uA))
487 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
488 
489 	return 0;
490 }
491 
regulators_enable_boot_on(bool verbose)492 int regulators_enable_boot_on(bool verbose)
493 {
494 	struct udevice *dev;
495 	struct uclass *uc;
496 	int ret;
497 
498 	ret = uclass_get(UCLASS_REGULATOR, &uc);
499 	if (ret)
500 		return ret;
501 	for (uclass_first_device(UCLASS_REGULATOR, &dev);
502 	     dev;
503 	     uclass_next_device(&dev)) {
504 		ret = regulator_autoset(dev);
505 		if (ret == -EMEDIUMTYPE) {
506 			ret = 0;
507 			continue;
508 		}
509 		if (verbose)
510 			regulator_show(dev, ret);
511 		if (ret == -ENOSYS)
512 			ret = 0;
513 	}
514 
515 	return ret;
516 }
517 
regulators_enable_boot_off(bool verbose)518 int regulators_enable_boot_off(bool verbose)
519 {
520 	struct udevice *dev;
521 	struct uclass *uc;
522 	int ret;
523 
524 	ret = uclass_get(UCLASS_REGULATOR, &uc);
525 	if (ret)
526 		return ret;
527 	for (uclass_first_device(UCLASS_REGULATOR, &dev);
528 	     dev;
529 	     uclass_next_device(&dev)) {
530 		ret = regulator_unset(dev);
531 		if (ret == -EMEDIUMTYPE) {
532 			ret = 0;
533 			continue;
534 		}
535 		if (verbose)
536 			regulator_show(dev, ret);
537 		if (ret == -ENOSYS)
538 			ret = 0;
539 	}
540 
541 	return ret;
542 }
543 
544 UCLASS_DRIVER(regulator) = {
545 	.id		= UCLASS_REGULATOR,
546 	.name		= "regulator",
547 	.post_bind	= regulator_post_bind,
548 	.pre_probe	= regulator_pre_probe,
549 	.per_device_plat_auto	= sizeof(struct dm_regulator_uclass_plat),
550 };
551