1 /*
2 * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <limits.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include <common/debug.h>
14 #include <drivers/delay_timer.h>
15 #include <drivers/st/regulator.h>
16 #include <libfdt.h>
17
18 #define MAX_PROPERTY_LEN 64
19
20 CASSERT(PLAT_NB_RDEVS >= 1U, plat_nb_rdevs_must_be_higher);
21
22 static struct rdev rdev_array[PLAT_NB_RDEVS];
23
24 #define for_each_rdev(rdev) \
25 for ((rdev) = rdev_array; (rdev) <= &rdev_array[PLAT_NB_RDEVS - 1U]; (rdev)++)
26
27 #define for_each_registered_rdev(rdev) \
28 for ((rdev) = rdev_array; \
29 ((rdev) <= &rdev_array[PLAT_NB_RDEVS - 1U]) && ((rdev)->desc != NULL); (rdev)++)
30
lock_driver(const struct rdev * rdev)31 static void lock_driver(const struct rdev *rdev)
32 {
33 if (rdev->desc->ops->lock != NULL) {
34 rdev->desc->ops->lock(rdev->desc);
35 }
36 }
37
unlock_driver(const struct rdev * rdev)38 static void unlock_driver(const struct rdev *rdev)
39 {
40 if (rdev->desc->ops->unlock != NULL) {
41 rdev->desc->ops->unlock(rdev->desc);
42 }
43 }
44
regulator_get_by_phandle(int32_t phandle)45 static struct rdev *regulator_get_by_phandle(int32_t phandle)
46 {
47 struct rdev *rdev;
48
49 for_each_registered_rdev(rdev) {
50 if (rdev->phandle == phandle) {
51 return rdev;
52 }
53 }
54
55 WARN("%s: phandle %d not found\n", __func__, phandle);
56 return NULL;
57 }
58
59 /*
60 * Get a regulator from its node name
61 *
62 * @fdt - pointer to device tree memory
63 * @node_name - name of the node "ldo1"
64 * Return pointer to rdev if succeed, NULL else.
65 */
regulator_get_by_name(const char * node_name)66 struct rdev *regulator_get_by_name(const char *node_name)
67 {
68 struct rdev *rdev;
69
70 assert(node_name != NULL);
71 VERBOSE("get %s\n", node_name);
72
73 for_each_registered_rdev(rdev) {
74 if (strcmp(rdev->desc->node_name, node_name) == 0) {
75 return rdev;
76 }
77 }
78
79 WARN("%s: %s not found\n", __func__, node_name);
80 return NULL;
81 }
82
get_supply_phandle(const void * fdt,int node,const char * name)83 static int32_t get_supply_phandle(const void *fdt, int node, const char *name)
84 {
85 const fdt32_t *cuint;
86 int len __unused;
87 int supply_phandle = -FDT_ERR_NOTFOUND;
88 char prop_name[MAX_PROPERTY_LEN];
89
90 len = snprintf(prop_name, MAX_PROPERTY_LEN - 1, "%s-supply", name);
91 assert((len >= 0) && (len < (MAX_PROPERTY_LEN - 1)));
92
93 cuint = fdt_getprop(fdt, node, prop_name, NULL);
94 if (cuint != NULL) {
95 supply_phandle = fdt32_to_cpu(*cuint);
96 VERBOSE("%s: supplied by %d\n", name, supply_phandle);
97 }
98
99 return supply_phandle;
100 }
101
102 /*
103 * Get a regulator from a supply name
104 *
105 * @fdt - pointer to device tree memory
106 * @node - offset of the node that contains the supply description
107 * @name - name of the supply "vdd" for "vdd-supply'
108 * Return pointer to rdev if succeed, NULL else.
109 */
regulator_get_by_supply_name(const void * fdt,int node,const char * name)110 struct rdev *regulator_get_by_supply_name(const void *fdt, int node, const char *name)
111 {
112 const int p = get_supply_phandle(fdt, node, name);
113
114 if (p < 0) {
115 return NULL;
116 }
117
118 return regulator_get_by_phandle(p);
119 }
120
__regulator_set_state(struct rdev * rdev,bool state)121 static int __regulator_set_state(struct rdev *rdev, bool state)
122 {
123 if (rdev->desc->ops->set_state == NULL) {
124 return -ENODEV;
125 }
126
127 return rdev->desc->ops->set_state(rdev->desc, state);
128 }
129
130 /*
131 * Enable regulator
132 *
133 * @rdev - pointer to rdev struct
134 * Return 0 if succeed, non 0 else.
135 */
regulator_enable(struct rdev * rdev)136 int regulator_enable(struct rdev *rdev)
137 {
138 int ret;
139
140 assert(rdev != NULL);
141
142 ret = __regulator_set_state(rdev, STATE_ENABLE);
143
144 udelay(rdev->enable_ramp_delay);
145
146 return ret;
147 }
148
149 /*
150 * Disable regulator
151 *
152 * @rdev - pointer to rdev struct
153 * Return 0 if succeed, non 0 else.
154 */
regulator_disable(struct rdev * rdev)155 int regulator_disable(struct rdev *rdev)
156 {
157 int ret;
158
159 assert(rdev != NULL);
160
161 if ((rdev->flags & REGUL_ALWAYS_ON) != 0U) {
162 return 0;
163 }
164
165 ret = __regulator_set_state(rdev, STATE_DISABLE);
166
167 udelay(rdev->enable_ramp_delay);
168
169 return ret;
170 }
171
172 /*
173 * Regulator enabled query
174 *
175 * @rdev - pointer to rdev struct
176 * Return 0 if disabled, 1 if enabled, <0 else.
177 */
regulator_is_enabled(const struct rdev * rdev)178 int regulator_is_enabled(const struct rdev *rdev)
179 {
180 int ret;
181
182 assert(rdev != NULL);
183
184 VERBOSE("%s: is en\n", rdev->desc->node_name);
185
186 if (rdev->desc->ops->get_state == NULL) {
187 return -ENODEV;
188 }
189
190 lock_driver(rdev);
191
192 ret = rdev->desc->ops->get_state(rdev->desc);
193 if (ret < 0) {
194 ERROR("regul %s get state failed: err:%d\n",
195 rdev->desc->node_name, ret);
196 }
197
198 unlock_driver(rdev);
199
200 return ret;
201 }
202
203 /*
204 * Set regulator voltage
205 *
206 * @rdev - pointer to rdev struct
207 * @mvolt - Target voltage level in millivolt
208 * Return 0 if succeed, non 0 else.
209 */
regulator_set_voltage(struct rdev * rdev,uint16_t mvolt)210 int regulator_set_voltage(struct rdev *rdev, uint16_t mvolt)
211 {
212 int ret;
213
214 assert(rdev != NULL);
215
216 VERBOSE("%s: set mvolt\n", rdev->desc->node_name);
217
218 if ((mvolt < rdev->min_mv) || (mvolt > rdev->max_mv)) {
219 return -EPERM;
220 }
221
222 if (regulator_get_voltage(rdev) == mvolt) {
223 return 0U;
224 }
225
226 if (rdev->desc->ops->set_voltage == NULL) {
227 return -ENODEV;
228 }
229
230 lock_driver(rdev);
231
232 ret = rdev->desc->ops->set_voltage(rdev->desc, mvolt);
233 if (ret < 0) {
234 ERROR("regul %s set volt failed: err:%d\n",
235 rdev->desc->node_name, ret);
236 }
237
238 unlock_driver(rdev);
239
240 return ret;
241 }
242
243 /*
244 * Set regulator min voltage
245 *
246 * @rdev - pointer to rdev struct
247 * Return 0 if succeed, non 0 else.
248 */
regulator_set_min_voltage(struct rdev * rdev)249 int regulator_set_min_voltage(struct rdev *rdev)
250 {
251 return regulator_set_voltage(rdev, rdev->min_mv);
252 }
253
254 /*
255 * Get regulator voltage
256 *
257 * @rdev - pointer to rdev struct
258 * Return milli volts if succeed, <0 else.
259 */
regulator_get_voltage(const struct rdev * rdev)260 int regulator_get_voltage(const struct rdev *rdev)
261 {
262 int ret;
263
264 assert(rdev != NULL);
265
266 VERBOSE("%s: get volt\n", rdev->desc->node_name);
267
268 if (rdev->desc->ops->get_voltage == NULL) {
269 return rdev->min_mv;
270 }
271
272 lock_driver(rdev);
273
274 ret = rdev->desc->ops->get_voltage(rdev->desc);
275 if (ret < 0) {
276 ERROR("regul %s get voltage failed: err:%d\n",
277 rdev->desc->node_name, ret);
278 }
279
280 unlock_driver(rdev);
281
282 return ret;
283 }
284
285 /*
286 * List regulator voltages
287 *
288 * @rdev - pointer to rdev struct
289 * @levels - out: array of supported millitvolt levels from min to max value
290 * @count - out: number of possible millivolt values
291 * Return 0 if succeed, non 0 else.
292 */
regulator_list_voltages(const struct rdev * rdev,const uint16_t ** levels,size_t * count)293 int regulator_list_voltages(const struct rdev *rdev, const uint16_t **levels, size_t *count)
294 {
295 int ret;
296 size_t n;
297
298 assert(rdev != NULL);
299 assert(levels != NULL);
300 assert(count != NULL);
301
302 VERBOSE("%s: list volt\n", rdev->desc->node_name);
303
304 if (rdev->desc->ops->list_voltages == NULL) {
305 return -ENODEV;
306 }
307
308 lock_driver(rdev);
309
310 ret = rdev->desc->ops->list_voltages(rdev->desc, levels, count);
311
312 unlock_driver(rdev);
313
314 if (ret < 0) {
315 ERROR("regul %s list_voltages failed: err: %d\n",
316 rdev->desc->node_name, ret);
317 return ret;
318 }
319
320 /*
321 * Reduce the possible values depending on min and max from device-tree
322 */
323 n = *count;
324 while ((n > 1U) && ((*levels)[n - 1U] > rdev->max_mv)) {
325 n--;
326 }
327
328 /* Verify that max val is a valid value */
329 if (rdev->max_mv != (*levels)[n - 1]) {
330 ERROR("regul %s: max value %u is invalid\n",
331 rdev->desc->node_name, rdev->max_mv);
332 return -EINVAL;
333 }
334
335 while ((n > 1U) && ((*levels[0U]) < rdev->min_mv)) {
336 (*levels)++;
337 n--;
338 }
339
340 /* Verify that min is not too high */
341 if (n == 0U) {
342 ERROR("regul %s set min voltage is too high\n",
343 rdev->desc->node_name);
344 return -EINVAL;
345 }
346
347 /* Verify that min val is a valid vlue */
348 if (rdev->min_mv != (*levels)[0U]) {
349 ERROR("regul %s: min value %u is invalid\n",
350 rdev->desc->node_name, rdev->min_mv);
351 return -EINVAL;
352 }
353
354 *count = n;
355
356 VERBOSE("rdev->min_mv=%u rdev->max_mv=%u\n", rdev->min_mv, rdev->max_mv);
357
358 return 0;
359 }
360
361 /*
362 * Get regulator voltages range
363 *
364 * @rdev - pointer to rdev struct
365 * @min_mv - out: min possible millivolt value
366 * @max_mv - out: max possible millivolt value
367 * Return 0 if succeed, non 0 else.
368 */
regulator_get_range(const struct rdev * rdev,uint16_t * min_mv,uint16_t * max_mv)369 void regulator_get_range(const struct rdev *rdev, uint16_t *min_mv, uint16_t *max_mv)
370 {
371 assert(rdev != NULL);
372
373 if (min_mv != NULL) {
374 *min_mv = rdev->min_mv;
375 }
376 if (max_mv != NULL) {
377 *max_mv = rdev->max_mv;
378 }
379 }
380
381 /*
382 * Set regulator flag
383 *
384 * @rdev - pointer to rdev struct
385 * @flag - flag value to set (eg: REGUL_OCP)
386 * Return 0 if succeed, non 0 else.
387 */
regulator_set_flag(struct rdev * rdev,uint16_t flag)388 int regulator_set_flag(struct rdev *rdev, uint16_t flag)
389 {
390 int ret;
391
392 /* check that only one bit is set on flag */
393 if (__builtin_popcount(flag) != 1) {
394 return -EINVAL;
395 }
396
397 /* REGUL_ALWAYS_ON and REGUL_BOOT_ON are internal properties of the core */
398 if ((flag == REGUL_ALWAYS_ON) || (flag == REGUL_BOOT_ON)) {
399 rdev->flags |= flag;
400 return 0;
401 }
402
403 if (rdev->desc->ops->set_flag == NULL) {
404 ERROR("%s can not set any flag\n", rdev->desc->node_name);
405 return -ENODEV;
406 }
407
408 lock_driver(rdev);
409
410 ret = rdev->desc->ops->set_flag(rdev->desc, flag);
411
412 unlock_driver(rdev);
413
414 if (ret != 0) {
415 ERROR("%s: could not set flag %d ret=%d\n",
416 rdev->desc->node_name, flag, ret);
417 return ret;
418 }
419
420 rdev->flags |= flag;
421
422 return 0;
423 }
424
parse_properties(const void * fdt,struct rdev * rdev,int node)425 static int parse_properties(const void *fdt, struct rdev *rdev, int node)
426 {
427 const fdt32_t *cuint;
428 int ret;
429
430 if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL) {
431 VERBOSE("%s: set regulator-always-on\n", rdev->desc->node_name);
432 ret = regulator_set_flag(rdev, REGUL_ALWAYS_ON);
433 if (ret != 0) {
434 return ret;
435 }
436 }
437
438 cuint = fdt_getprop(fdt, node, "regulator-enable-ramp-delay", NULL);
439 if (cuint != NULL) {
440 rdev->enable_ramp_delay = fdt32_to_cpu(*cuint);
441 VERBOSE("%s: enable_ramp_delay=%u\n", rdev->desc->node_name,
442 rdev->enable_ramp_delay);
443 }
444
445 return 0;
446 }
447
448 /*
449 * Parse the device-tree for a regulator
450 *
451 * Read min/max voltage from dt and check its validity
452 * Read the properties, and call the driver to set flags
453 * Read power supply phandle
454 * Read and store low power mode states
455 *
456 * @rdev - pointer to rdev struct
457 * @node - device-tree node offset of the regulator
458 * Return 0 if disabled, 1 if enabled, <0 else.
459 */
parse_dt(struct rdev * rdev,int node)460 static int parse_dt(struct rdev *rdev, int node)
461 {
462 void *fdt;
463 const fdt32_t *cuint;
464 const uint16_t *levels;
465 size_t size;
466 int ret;
467
468 VERBOSE("%s: parse dt\n", rdev->desc->node_name);
469
470 if (fdt_get_address(&fdt) == 0) {
471 return -ENOENT;
472 }
473
474 rdev->phandle = fdt_get_phandle(fdt, node);
475
476 cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
477 if (cuint != NULL) {
478 uint16_t min_mv;
479
480 min_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
481 VERBOSE("%s: min_mv=%d\n", rdev->desc->node_name, (int)min_mv);
482 if (min_mv <= rdev->max_mv) {
483 rdev->min_mv = min_mv;
484 } else {
485 ERROR("%s: min_mv=%d is too high\n",
486 rdev->desc->node_name, (int)min_mv);
487 return -EINVAL;
488 }
489 }
490
491 cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
492 if (cuint != NULL) {
493 uint16_t max_mv;
494
495 max_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
496 VERBOSE("%s: max_mv=%d\n", rdev->desc->node_name, (int)max_mv);
497 if (max_mv >= rdev->min_mv) {
498 rdev->max_mv = max_mv;
499 } else {
500 ERROR("%s: max_mv=%d is too low\n",
501 rdev->desc->node_name, (int)max_mv);
502 return -EINVAL;
503 }
504 }
505
506 /* validate that min and max values can be used */
507 ret = regulator_list_voltages(rdev, &levels, &size);
508 if ((ret != 0) && (ret != -ENODEV)) {
509 return ret;
510 }
511
512 ret = parse_properties(fdt, rdev, node);
513 if (ret != 0) {
514 return ret;
515 }
516
517 return 0;
518 }
519
520 /*
521 * Register a regulator driver in regulator framework.
522 * Initialize voltage range from driver description
523 *
524 * @desc - pointer to the regulator description
525 * @node - device-tree node offset of the regulator
526 * Return 0 if succeed, non 0 else.
527 */
regulator_register(const struct regul_description * desc,int node)528 int regulator_register(const struct regul_description *desc, int node)
529 {
530 struct rdev *rdev;
531
532 assert(desc != NULL);
533
534 VERBOSE("register %s\n", desc->node_name);
535
536 for_each_rdev(rdev) {
537 if (rdev->desc == NULL) {
538 break;
539 }
540 }
541
542 if (rdev > &rdev_array[PLAT_NB_RDEVS - 1U]) {
543 WARN("Not enough place for regulators, PLAT_NB_RDEVS should be increased.\n");
544 return -ENOMEM;
545 }
546
547 rdev->desc = desc;
548 rdev->enable_ramp_delay = rdev->desc->enable_ramp_delay;
549
550 if (rdev->desc->ops->list_voltages != NULL) {
551 int ret;
552 const uint16_t *levels;
553 size_t count;
554
555 lock_driver(rdev);
556
557 ret = rdev->desc->ops->list_voltages(rdev->desc, &levels, &count);
558
559 unlock_driver(rdev);
560
561 if (ret < 0) {
562 ERROR("regul %s set state failed: err:%d\n",
563 rdev->desc->node_name, ret);
564 return ret;
565 }
566
567 rdev->min_mv = levels[0];
568 rdev->max_mv = levels[count - 1U];
569 } else {
570 rdev->max_mv = UINT16_MAX;
571 }
572
573 return parse_dt(rdev, node);
574 }
575