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