xref: /optee_os/core/drivers/stpmic1.c (revision 9fc2442cc66c279cb962c90c4375746fc9b28bb9)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <assert.h>
7 #include <drivers/stpmic1.h>
8 #include <kernel/panic.h>
9 #include <platform_config.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <trace.h>
13 #include <util.h>
14 
15 #define VOLTAGE_INDEX_INVALID		((unsigned int)~0)
16 
17 struct regul_struct {
18 	const char *dt_node_name;
19 	const uint16_t *voltage_table;
20 	uint8_t voltage_table_size;
21 	uint8_t control_reg;
22 	uint8_t low_power_reg;
23 	uint8_t enable_pos;
24 	uint8_t pull_down_reg;
25 	uint8_t pull_down_pos;
26 	uint8_t mask_reset_reg;
27 	uint8_t mask_reset_pos;
28 };
29 
30 static struct i2c_handle_s *pmic_i2c_handle;
31 static uint16_t pmic_i2c_addr;
32 
33 /* Voltage tables in mV */
34 static const uint16_t buck1_voltage_table[] = {
35 	725,
36 	725,
37 	725,
38 	725,
39 	725,
40 	725,
41 	750,
42 	775,
43 	800,
44 	825,
45 	850,
46 	875,
47 	900,
48 	925,
49 	950,
50 	975,
51 	1000,
52 	1025,
53 	1050,
54 	1075,
55 	1100,
56 	1125,
57 	1150,
58 	1175,
59 	1200,
60 	1225,
61 	1250,
62 	1275,
63 	1300,
64 	1325,
65 	1350,
66 	1375,
67 	1400,
68 	1425,
69 	1450,
70 	1475,
71 	1500,
72 	1500,
73 	1500,
74 	1500,
75 	1500,
76 	1500,
77 	1500,
78 	1500,
79 	1500,
80 	1500,
81 	1500,
82 	1500,
83 	1500,
84 	1500,
85 	1500,
86 	1500,
87 	1500,
88 	1500,
89 	1500,
90 	1500,
91 	1500,
92 	1500,
93 	1500,
94 	1500,
95 	1500,
96 	1500,
97 	1500,
98 	1500,
99 };
100 
101 static const uint16_t buck2_voltage_table[] = {
102 	1000,
103 	1000,
104 	1000,
105 	1000,
106 	1000,
107 	1000,
108 	1000,
109 	1000,
110 	1000,
111 	1000,
112 	1000,
113 	1000,
114 	1000,
115 	1000,
116 	1000,
117 	1000,
118 	1000,
119 	1000,
120 	1050,
121 	1050,
122 	1100,
123 	1100,
124 	1150,
125 	1150,
126 	1200,
127 	1200,
128 	1250,
129 	1250,
130 	1300,
131 	1300,
132 	1350,
133 	1350,
134 	1400,
135 	1400,
136 	1450,
137 	1450,
138 	1500,
139 };
140 
141 static const uint16_t buck3_voltage_table[] = {
142 	1000,
143 	1000,
144 	1000,
145 	1000,
146 	1000,
147 	1000,
148 	1000,
149 	1000,
150 	1000,
151 	1000,
152 	1000,
153 	1000,
154 	1000,
155 	1000,
156 	1000,
157 	1000,
158 	1000,
159 	1000,
160 	1000,
161 	1000,
162 	1100,
163 	1100,
164 	1100,
165 	1100,
166 	1200,
167 	1200,
168 	1200,
169 	1200,
170 	1300,
171 	1300,
172 	1300,
173 	1300,
174 	1400,
175 	1400,
176 	1400,
177 	1400,
178 	1500,
179 	1600,
180 	1700,
181 	1800,
182 	1900,
183 	2000,
184 	2100,
185 	2200,
186 	2300,
187 	2400,
188 	2500,
189 	2600,
190 	2700,
191 	2800,
192 	2900,
193 	3000,
194 	3100,
195 	3200,
196 	3300,
197 	3400,
198 };
199 
200 static const uint16_t buck4_voltage_table[] = {
201 	600,
202 	625,
203 	650,
204 	675,
205 	700,
206 	725,
207 	750,
208 	775,
209 	800,
210 	825,
211 	850,
212 	875,
213 	900,
214 	925,
215 	950,
216 	975,
217 	1000,
218 	1025,
219 	1050,
220 	1075,
221 	1100,
222 	1125,
223 	1150,
224 	1175,
225 	1200,
226 	1225,
227 	1250,
228 	1275,
229 	1300,
230 	1300,
231 	1350,
232 	1350,
233 	1400,
234 	1400,
235 	1450,
236 	1450,
237 	1500,
238 	1600,
239 	1700,
240 	1800,
241 	1900,
242 	2000,
243 	2100,
244 	2200,
245 	2300,
246 	2400,
247 	2500,
248 	2600,
249 	2700,
250 	2800,
251 	2900,
252 	3000,
253 	3100,
254 	3200,
255 	3300,
256 	3400,
257 	3500,
258 	3600,
259 	3700,
260 	3800,
261 	3900,
262 };
263 
264 static const uint16_t ldo1_voltage_table[] = {
265 	1700,
266 	1700,
267 	1700,
268 	1700,
269 	1700,
270 	1700,
271 	1700,
272 	1700,
273 	1700,
274 	1800,
275 	1900,
276 	2000,
277 	2100,
278 	2200,
279 	2300,
280 	2400,
281 	2500,
282 	2600,
283 	2700,
284 	2800,
285 	2900,
286 	3000,
287 	3100,
288 	3200,
289 	3300,
290 };
291 
292 static const uint16_t ldo2_voltage_table[] = {
293 	1700,
294 	1700,
295 	1700,
296 	1700,
297 	1700,
298 	1700,
299 	1700,
300 	1700,
301 	1700,
302 	1800,
303 	1900,
304 	2000,
305 	2100,
306 	2200,
307 	2300,
308 	2400,
309 	2500,
310 	2600,
311 	2700,
312 	2800,
313 	2900,
314 	3000,
315 	3100,
316 	3200,
317 	3300,
318 };
319 
320 static const uint16_t ldo3_voltage_table[] = {
321 	1700,
322 	1700,
323 	1700,
324 	1700,
325 	1700,
326 	1700,
327 	1700,
328 	1700,
329 	1700,
330 	1800,
331 	1900,
332 	2000,
333 	2100,
334 	2200,
335 	2300,
336 	2400,
337 	2500,
338 	2600,
339 	2700,
340 	2800,
341 	2900,
342 	3000,
343 	3100,
344 	3200,
345 	3300,
346 	3300,
347 	3300,
348 	3300,
349 	3300,
350 	3300,
351 	3300,
352 	500,	/* VOUT2/2 (Sink/source mode) */
353 	0xFFFF, /* VREFDDR */
354 };
355 
356 static const uint16_t ldo5_voltage_table[] = {
357 	1700,
358 	1700,
359 	1700,
360 	1700,
361 	1700,
362 	1700,
363 	1700,
364 	1700,
365 	1700,
366 	1800,
367 	1900,
368 	2000,
369 	2100,
370 	2200,
371 	2300,
372 	2400,
373 	2500,
374 	2600,
375 	2700,
376 	2800,
377 	2900,
378 	3000,
379 	3100,
380 	3200,
381 	3300,
382 	3400,
383 	3500,
384 	3600,
385 	3700,
386 	3800,
387 	3900,
388 };
389 
390 static const uint16_t ldo6_voltage_table[] = {
391 	900,
392 	1000,
393 	1100,
394 	1200,
395 	1300,
396 	1400,
397 	1500,
398 	1600,
399 	1700,
400 	1800,
401 	1900,
402 	2000,
403 	2100,
404 	2200,
405 	2300,
406 	2400,
407 	2500,
408 	2600,
409 	2700,
410 	2800,
411 	2900,
412 	3000,
413 	3100,
414 	3200,
415 	3300,
416 };
417 
418 static const uint16_t ldo4_voltage_table[] = {
419 	3300,
420 };
421 
422 static const uint16_t vref_ddr_voltage_table[] = {
423 	3300,
424 };
425 
426 static const uint16_t fixed_5v_voltage_table[] = {
427 	5000,
428 };
429 
430 /* Table of Regulators in PMIC SoC */
431 static const struct regul_struct regulators_table[] = {
432 	{
433 		.dt_node_name	= "buck1",
434 		.voltage_table	= buck1_voltage_table,
435 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
436 		.control_reg	= BUCK1_CONTROL_REG,
437 		.low_power_reg	= BUCK1_PWRCTRL_REG,
438 		.enable_pos	= LDO_BUCK_ENABLE_POS,
439 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
440 		.pull_down_pos	= BUCK1_PULL_DOWN_SHIFT,
441 		.mask_reset_reg = MASK_RESET_BUCK_REG,
442 		.mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
443 	},
444 	{
445 		.dt_node_name	= "buck2",
446 		.voltage_table	= buck2_voltage_table,
447 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
448 		.control_reg	= BUCK2_CONTROL_REG,
449 		.low_power_reg	= BUCK2_PWRCTRL_REG,
450 		.enable_pos	= LDO_BUCK_ENABLE_POS,
451 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
452 		.pull_down_pos	= BUCK2_PULL_DOWN_SHIFT,
453 		.mask_reset_reg = MASK_RESET_BUCK_REG,
454 		.mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
455 	},
456 	{
457 		.dt_node_name	= "buck3",
458 		.voltage_table	= buck3_voltage_table,
459 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
460 		.control_reg	= BUCK3_CONTROL_REG,
461 		.low_power_reg	= BUCK3_PWRCTRL_REG,
462 		.enable_pos	= LDO_BUCK_ENABLE_POS,
463 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
464 		.pull_down_pos	= BUCK3_PULL_DOWN_SHIFT,
465 		.mask_reset_reg = MASK_RESET_BUCK_REG,
466 		.mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
467 	},
468 	{
469 		.dt_node_name	= "buck4",
470 		.voltage_table	= buck4_voltage_table,
471 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
472 		.control_reg	= BUCK4_CONTROL_REG,
473 		.low_power_reg	= BUCK4_PWRCTRL_REG,
474 		.enable_pos	= LDO_BUCK_ENABLE_POS,
475 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
476 		.pull_down_pos	= BUCK4_PULL_DOWN_SHIFT,
477 		.mask_reset_reg = MASK_RESET_BUCK_REG,
478 		.mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
479 	},
480 	{
481 		.dt_node_name	= "ldo1",
482 		.voltage_table	= ldo1_voltage_table,
483 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
484 		.control_reg	= LDO1_CONTROL_REG,
485 		.low_power_reg	= LDO1_PWRCTRL_REG,
486 		.enable_pos	= LDO_BUCK_ENABLE_POS,
487 		.mask_reset_reg = MASK_RESET_LDO_REG,
488 		.mask_reset_pos = LDO1_MASK_RESET_SHIFT,
489 	},
490 	{
491 		.dt_node_name	= "ldo2",
492 		.voltage_table	= ldo2_voltage_table,
493 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
494 		.control_reg	= LDO2_CONTROL_REG,
495 		.low_power_reg	= LDO2_PWRCTRL_REG,
496 		.enable_pos	= LDO_BUCK_ENABLE_POS,
497 		.mask_reset_reg = MASK_RESET_LDO_REG,
498 		.mask_reset_pos = LDO2_MASK_RESET_SHIFT,
499 	},
500 	{
501 		.dt_node_name	= "ldo3",
502 		.voltage_table	= ldo3_voltage_table,
503 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
504 		.control_reg	= LDO3_CONTROL_REG,
505 		.low_power_reg	= LDO3_PWRCTRL_REG,
506 		.enable_pos	= LDO_BUCK_ENABLE_POS,
507 		.mask_reset_reg = MASK_RESET_LDO_REG,
508 		.mask_reset_pos = LDO3_MASK_RESET_SHIFT,
509 	},
510 	{
511 		.dt_node_name	= "ldo4",
512 		.voltage_table	= ldo4_voltage_table,
513 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
514 		.control_reg	= LDO4_CONTROL_REG,
515 		.low_power_reg	= LDO4_PWRCTRL_REG,
516 		.enable_pos	= LDO_BUCK_ENABLE_POS,
517 		.mask_reset_reg = MASK_RESET_LDO_REG,
518 		.mask_reset_pos = LDO4_MASK_RESET_SHIFT,
519 	},
520 	{
521 		.dt_node_name	= "ldo5",
522 		.voltage_table	= ldo5_voltage_table,
523 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
524 		.control_reg	= LDO5_CONTROL_REG,
525 		.low_power_reg	= LDO5_PWRCTRL_REG,
526 		.enable_pos	= LDO_BUCK_ENABLE_POS,
527 		.mask_reset_reg = MASK_RESET_LDO_REG,
528 		.mask_reset_pos = LDO5_MASK_RESET_SHIFT,
529 	},
530 	{
531 		.dt_node_name	= "ldo6",
532 		.voltage_table	= ldo6_voltage_table,
533 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
534 		.control_reg	= LDO6_CONTROL_REG,
535 		.low_power_reg	= LDO6_PWRCTRL_REG,
536 		.enable_pos	= LDO_BUCK_ENABLE_POS,
537 		.mask_reset_reg = MASK_RESET_LDO_REG,
538 		.mask_reset_pos = LDO6_MASK_RESET_SHIFT,
539 	},
540 	{
541 		.dt_node_name	= "vref_ddr",
542 		.voltage_table	= vref_ddr_voltage_table,
543 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
544 		.control_reg	= VREF_DDR_CONTROL_REG,
545 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
546 		.enable_pos	= LDO_BUCK_ENABLE_POS,
547 		.mask_reset_reg = MASK_RESET_LDO_REG,
548 		.mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
549 	},
550 	{
551 		.dt_node_name = "boost",
552 		.voltage_table	= fixed_5v_voltage_table,
553 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
554 		.control_reg	= USB_CONTROL_REG,
555 		.enable_pos	= BOOST_ENABLED_POS,
556 	},
557 	{
558 		.dt_node_name	= "pwr_sw1",
559 		.voltage_table	= fixed_5v_voltage_table,
560 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
561 		.control_reg	= USB_CONTROL_REG,
562 		.enable_pos	= USBSW_OTG_SWITCH_ENABLED_POS,
563 	},
564 	{
565 		.dt_node_name	= "pwr_sw2",
566 		.voltage_table	= fixed_5v_voltage_table,
567 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
568 		.control_reg	= USB_CONTROL_REG,
569 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
570 	},
571 };
572 
573 static const struct regul_struct *get_regulator_data(const char *name)
574 {
575 	unsigned int i = 0;
576 
577 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
578 		if (strcmp(name, regulators_table[i].dt_node_name) == 0)
579 			return &regulators_table[i];
580 
581 	DMSG("Regulator %s not found", name);
582 	return NULL;
583 }
584 
585 bool stpmic1_regulator_is_valid(const char *name)
586 {
587 	return get_regulator_data(name);
588 }
589 
590 TEE_Result stpmic1_regulator_levels_mv(const char *name,
591 				       const uint16_t **levels,
592 				       size_t *levels_count)
593 {
594 	const struct regul_struct *regul = get_regulator_data(name);
595 
596 	if (!regul)
597 		return TEE_ERROR_BAD_PARAMETERS;
598 
599 	if (levels_count)
600 		*levels_count = regul->voltage_table_size;
601 
602 	if (levels)
603 		*levels = regul->voltage_table;
604 
605 	return TEE_SUCCESS;
606 }
607 
608 static size_t voltage_to_index(const char *name, uint16_t millivolts)
609 {
610 	const struct regul_struct *regul = get_regulator_data(name);
611 	unsigned int i = 0;
612 
613 	assert(regul->voltage_table);
614 	for (i = 0; i < regul->voltage_table_size; i++)
615 		if (regul->voltage_table[i] == millivolts)
616 			return i;
617 
618 	return VOLTAGE_INDEX_INVALID;
619 }
620 
621 int stpmic1_powerctrl_on(void)
622 {
623 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
624 				       PWRCTRL_PIN_VALID);
625 }
626 
627 int stpmic1_switch_off(void)
628 {
629 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
630 				       SOFTWARE_SWITCH_OFF_ENABLED);
631 }
632 
633 int stpmic1_regulator_enable(const char *name)
634 {
635 	const struct regul_struct *regul = get_regulator_data(name);
636 
637 	return stpmic1_register_update(regul->control_reg,
638 				       BIT(regul->enable_pos),
639 				       BIT(regul->enable_pos));
640 }
641 
642 int stpmic1_regulator_disable(const char *name)
643 {
644 	const struct regul_struct *regul = get_regulator_data(name);
645 
646 	return stpmic1_register_update(regul->control_reg, 0,
647 				       BIT(regul->enable_pos));
648 }
649 
650 bool stpmic1_is_regulator_enabled(const char *name)
651 {
652 	const struct regul_struct *regul = get_regulator_data(name);
653 	uint8_t val = 0;
654 
655 	if (stpmic1_register_read(regul->control_reg, &val))
656 		panic();
657 
658 	return val & BIT(regul->enable_pos);
659 }
660 
661 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
662 static uint8_t find_plat_mask(const char *name)
663 {
664 	if (!strncmp(name, "buck", 4))
665 		return BUCK_VOLTAGE_MASK;
666 
667 	if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
668 		return LDO_VOLTAGE_MASK;
669 
670 	return 0;
671 }
672 
673 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
674 {
675 	size_t voltage_index = voltage_to_index(name, millivolts);
676 	const struct regul_struct *regul = get_regulator_data(name);
677 	uint8_t mask = 0;
678 
679 	if (voltage_index == VOLTAGE_INDEX_INVALID)
680 		return -1;
681 
682 	mask = find_plat_mask(name);
683 	if (!mask)
684 		return 0;
685 
686 	return stpmic1_register_update(regul->control_reg,
687 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
688 				       mask);
689 }
690 
691 int stpmic1_regulator_mask_reset_set(const char *name)
692 {
693 	const struct regul_struct *regul = get_regulator_data(name);
694 
695 	if (regul->control_reg == USB_CONTROL_REG) {
696 		DMSG("No reset for USB control");
697 		return -1;
698 	}
699 
700 	return stpmic1_register_update(regul->mask_reset_reg,
701 				       BIT(regul->mask_reset_pos),
702 				       LDO_BUCK_RESET_MASK <<
703 				       regul->mask_reset_pos);
704 }
705 
706 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
707 {
708 	const struct regul_struct *regul = get_regulator_data(name);
709 
710 	cfg->ctrl_reg = regul->control_reg;
711 	cfg->enable_pos = regul->enable_pos;
712 
713 	return 0;
714 }
715 
716 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
717 {
718 	return stpmic1_register_update(cfg->ctrl_reg,
719 				       BIT(cfg->enable_pos),
720 				       BIT(cfg->enable_pos));
721 }
722 
723 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
724 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
725 			   struct stpmic1_bo_cfg *cfg)
726 {
727 	size_t min_index = voltage_to_index(name, min_millivolt);
728 	const struct regul_struct *regul = get_regulator_data(name);
729 	uint8_t mask = 0;
730 
731 	if (min_index == VOLTAGE_INDEX_INVALID)
732 		panic();
733 
734 	mask = find_plat_mask(name);
735 	if (!mask)
736 		return 1;
737 
738 	cfg->ctrl_reg = regul->control_reg;
739 	cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
740 	cfg->mask = mask;
741 
742 	return 0;
743 }
744 
745 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
746 {
747 	uint8_t value = 0;
748 
749 	assert(cfg->ctrl_reg);
750 
751 	if (stpmic1_register_read(cfg->ctrl_reg, &value))
752 		return -1;
753 
754 	if ((value & cfg->mask) >= cfg->min_value)
755 		return 0;
756 
757 	return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
758 				       cfg->mask);
759 }
760 
761 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
762 {
763 	const struct regul_struct *regul = get_regulator_data(name);
764 
765 	if (!regul->pull_down_reg) {
766 		DMSG("No pull down for regu %s", name);
767 		panic();
768 	}
769 
770 	cfg->pd_reg = regul->pull_down_reg;
771 	cfg->pd_value = BIT(regul->pull_down_pos);
772 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
773 
774 	return 0;
775 }
776 
777 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
778 {
779 	assert(cfg->pd_reg);
780 
781 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
782 				       cfg->pd_mask);
783 }
784 
785 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
786 {
787 	const struct regul_struct *regul = get_regulator_data(name);
788 
789 	if (!regul->mask_reset_reg) {
790 		DMSG("No reset mask for regu %s", name);
791 		panic();
792 	}
793 
794 	cfg->mrst_reg = regul->mask_reset_reg;
795 	cfg->mrst_value = BIT(regul->mask_reset_pos);
796 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
797 
798 	return 0;
799 }
800 
801 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
802 {
803 	assert(cfg->mrst_reg);
804 
805 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
806 				       cfg->mrst_mask);
807 }
808 
809 int stpmic1_regulator_voltage_get(const char *name)
810 {
811 	const struct regul_struct *regul = get_regulator_data(name);
812 	uint8_t value = 0;
813 	uint8_t mask = 0;
814 
815 	mask = find_plat_mask(name);
816 	if (!mask)
817 		return 0;
818 
819 	if (stpmic1_register_read(regul->control_reg, &value))
820 		return -1;
821 
822 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
823 
824 	if (value > regul->voltage_table_size)
825 		return -1;
826 
827 	return regul->voltage_table[value];
828 }
829 
830 int stpmic1_lp_copy_reg(const char *name)
831 {
832 	const struct regul_struct *regul = get_regulator_data(name);
833 	uint8_t val = 0;
834 	int status = 0;
835 
836 	if (!regul->low_power_reg)
837 		return -1;
838 
839 	status = stpmic1_register_read(regul->control_reg, &val);
840 	if (status)
841 		return status;
842 
843 	return stpmic1_register_write(regul->low_power_reg, val);
844 }
845 
846 bool stpmic1_regu_has_lp_cfg(const char *name)
847 {
848 	return get_regulator_data(name)->low_power_reg;
849 }
850 
851 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
852 {
853 	const struct regul_struct *regul = get_regulator_data(name);
854 
855 	if (!regul->low_power_reg)
856 		return -1;
857 
858 	cfg->ctrl_reg = regul->control_reg;
859 	cfg->lp_reg = regul->low_power_reg;
860 
861 	return 0;
862 }
863 
864 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
865 {
866 	uint8_t val = 0;
867 	int status = 0;
868 
869 	assert(cfg->lp_reg);
870 
871 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
872 	if (!status)
873 		status = stpmic1_register_write(cfg->lp_reg, val);
874 
875 	return status;
876 }
877 
878 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
879 {
880 	const struct regul_struct *regul = get_regulator_data(name);
881 
882 	if (!regul->low_power_reg)
883 		return -1;
884 
885 	return stpmic1_register_update(regul->low_power_reg, enable,
886 				       LDO_BUCK_ENABLE_MASK);
887 }
888 
889 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
890 {
891 	assert(cfg->lp_reg && (enable == 0 || enable == 1));
892 
893 	return stpmic1_register_update(cfg->lp_reg, enable,
894 				       LDO_BUCK_ENABLE_MASK);
895 }
896 
897 int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
898 {
899 	const struct regul_struct *regul = get_regulator_data(name);
900 
901 	assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
902 
903 	return stpmic1_register_update(regul->low_power_reg,
904 				       hplp << LDO_BUCK_HPLP_POS,
905 				       BIT(LDO_BUCK_HPLP_POS));
906 }
907 
908 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
909 {
910 	assert(cfg->lp_reg && (mode == 0 || mode == 1));
911 	return stpmic1_register_update(cfg->lp_reg,
912 				       mode << LDO_BUCK_HPLP_POS,
913 				       BIT(LDO_BUCK_HPLP_POS));
914 }
915 
916 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
917 {
918 	size_t voltage_index = voltage_to_index(name, millivolts);
919 	const struct regul_struct *regul = get_regulator_data(name);
920 	uint8_t mask = 0;
921 
922 	assert(voltage_index != VOLTAGE_INDEX_INVALID);
923 
924 	mask = find_plat_mask(name);
925 	if (!mask)
926 		return 0;
927 
928 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
929 				       mask);
930 }
931 
932 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
933 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
934 			   struct stpmic1_lp_cfg *cfg)
935 
936 {
937 	size_t voltage_index = voltage_to_index(name, millivolts);
938 	uint8_t mask = 0;
939 
940 	mask = find_plat_mask(name);
941 	if (!mask)
942 		return 1;
943 
944 	assert(voltage_index != VOLTAGE_INDEX_INVALID &&
945 	       cfg->lp_reg == get_regulator_data(name)->low_power_reg);
946 
947 	cfg->value = voltage_index << 2;
948 	cfg->mask = mask;
949 
950 	return 0;
951 }
952 
953 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
954 {
955 	assert(cfg->lp_reg);
956 
957 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
958 }
959 
960 int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
961 {
962 	struct i2c_handle_s *i2c = pmic_i2c_handle;
963 
964 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
965 					    register_id, value,
966 					    false /* !write */);
967 }
968 
969 int stpmic1_register_write(uint8_t register_id, uint8_t value)
970 {
971 	struct i2c_handle_s *i2c = pmic_i2c_handle;
972 	uint8_t val = value;
973 
974 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
975 					    register_id, &val,
976 					    true /* write */);
977 }
978 
979 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
980 {
981 	int status = 0;
982 	uint8_t val = 0;
983 
984 	status = stpmic1_register_read(register_id, &val);
985 	if (status)
986 		return status;
987 
988 	val = (val & ~mask) | (value & mask);
989 
990 	return stpmic1_register_write(register_id, val);
991 }
992 
993 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
994 {
995 	pmic_i2c_handle = i2c_handle;
996 	pmic_i2c_addr = i2c_addr;
997 }
998 
999 void stpmic1_dump_regulators(void)
1000 {
1001 	size_t i = 0;
1002 	char __maybe_unused const *name = NULL;
1003 
1004 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1005 		if (!regulators_table[i].control_reg)
1006 			continue;
1007 
1008 		name = regulators_table[i].dt_node_name;
1009 		DMSG("PMIC regul %s: %sable, %dmV",
1010 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1011 		     stpmic1_regulator_voltage_get(name));
1012 	}
1013 }
1014 
1015 int stpmic1_get_version(unsigned long *version)
1016 {
1017 	uint8_t read_val = 0;
1018 
1019 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1020 		return -1;
1021 
1022 	*version = read_val;
1023 	return 0;
1024 }
1025