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