• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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