xref: /optee_os/core/drivers/stpmic1.c (revision 6a63363ba8fe959537b53590c61879168ca59696)
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 static size_t voltage_to_index(const char *name, uint16_t millivolts)
586 {
587 	const struct regul_struct *regul = get_regulator_data(name);
588 	unsigned int i = 0;
589 
590 	assert(regul->voltage_table);
591 	for (i = 0; i < regul->voltage_table_size; i++)
592 		if (regul->voltage_table[i] == millivolts)
593 			return i;
594 
595 	return VOLTAGE_INDEX_INVALID;
596 }
597 
598 int stpmic1_powerctrl_on(void)
599 {
600 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
601 				       PWRCTRL_PIN_VALID);
602 }
603 
604 int stpmic1_switch_off(void)
605 {
606 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
607 				       SOFTWARE_SWITCH_OFF_ENABLED);
608 }
609 
610 int stpmic1_regulator_enable(const char *name)
611 {
612 	const struct regul_struct *regul = get_regulator_data(name);
613 
614 	return stpmic1_register_update(regul->control_reg,
615 				       BIT(regul->enable_pos),
616 				       BIT(regul->enable_pos));
617 }
618 
619 int stpmic1_regulator_disable(const char *name)
620 {
621 	const struct regul_struct *regul = get_regulator_data(name);
622 
623 	return stpmic1_register_update(regul->control_reg, 0,
624 				       BIT(regul->enable_pos));
625 }
626 
627 bool stpmic1_is_regulator_enabled(const char *name)
628 {
629 	const struct regul_struct *regul = get_regulator_data(name);
630 	uint8_t val = 0;
631 
632 	if (stpmic1_register_read(regul->control_reg, &val))
633 		panic();
634 
635 	return val & BIT(regul->enable_pos);
636 }
637 
638 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
639 static uint8_t find_plat_mask(const char *name)
640 {
641 	if (!strncmp(name, "buck", 4))
642 		return BUCK_VOLTAGE_MASK;
643 
644 	if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
645 		return LDO_VOLTAGE_MASK;
646 
647 	return 0;
648 }
649 
650 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
651 {
652 	size_t voltage_index = voltage_to_index(name, millivolts);
653 	const struct regul_struct *regul = get_regulator_data(name);
654 	uint8_t mask = 0;
655 
656 	if (voltage_index == VOLTAGE_INDEX_INVALID)
657 		return -1;
658 
659 	mask = find_plat_mask(name);
660 	if (!mask)
661 		return 0;
662 
663 	return stpmic1_register_update(regul->control_reg,
664 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
665 				       mask);
666 }
667 
668 int stpmic1_regulator_mask_reset_set(const char *name)
669 {
670 	const struct regul_struct *regul = get_regulator_data(name);
671 
672 	if (regul->control_reg == USB_CONTROL_REG) {
673 		DMSG("No reset for USB control");
674 		return -1;
675 	}
676 
677 	return stpmic1_register_update(regul->mask_reset_reg,
678 				       BIT(regul->mask_reset_pos),
679 				       LDO_BUCK_RESET_MASK <<
680 				       regul->mask_reset_pos);
681 }
682 
683 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
684 {
685 	const struct regul_struct *regul = get_regulator_data(name);
686 
687 	cfg->ctrl_reg = regul->control_reg;
688 	cfg->enable_pos = regul->enable_pos;
689 
690 	return 0;
691 }
692 
693 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
694 {
695 	return stpmic1_register_update(cfg->ctrl_reg,
696 				       BIT(cfg->enable_pos),
697 				       BIT(cfg->enable_pos));
698 }
699 
700 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
701 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
702 			   struct stpmic1_bo_cfg *cfg)
703 {
704 	size_t min_index = voltage_to_index(name, min_millivolt);
705 	const struct regul_struct *regul = get_regulator_data(name);
706 	uint8_t mask = 0;
707 
708 	if (min_index == VOLTAGE_INDEX_INVALID)
709 		panic();
710 
711 	mask = find_plat_mask(name);
712 	if (!mask)
713 		return 1;
714 
715 	cfg->ctrl_reg = regul->control_reg;
716 	cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
717 	cfg->mask = mask;
718 
719 	return 0;
720 }
721 
722 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
723 {
724 	uint8_t value = 0;
725 
726 	assert(cfg->ctrl_reg);
727 
728 	if (stpmic1_register_read(cfg->ctrl_reg, &value))
729 		return -1;
730 
731 	if ((value & cfg->mask) >= cfg->min_value)
732 		return 0;
733 
734 	return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
735 				       cfg->mask);
736 }
737 
738 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
739 {
740 	const struct regul_struct *regul = get_regulator_data(name);
741 
742 	if (!regul->pull_down_reg) {
743 		DMSG("No pull down for regu %s", name);
744 		panic();
745 	}
746 
747 	cfg->pd_reg = regul->pull_down_reg;
748 	cfg->pd_value = BIT(regul->pull_down_pos);
749 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
750 
751 	return 0;
752 }
753 
754 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
755 {
756 	assert(cfg->pd_reg);
757 
758 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
759 				       cfg->pd_mask);
760 }
761 
762 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
763 {
764 	const struct regul_struct *regul = get_regulator_data(name);
765 
766 	if (!regul->mask_reset_reg) {
767 		DMSG("No reset mask for regu %s", name);
768 		panic();
769 	}
770 
771 	cfg->mrst_reg = regul->mask_reset_reg;
772 	cfg->mrst_value = BIT(regul->mask_reset_pos);
773 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
774 
775 	return 0;
776 }
777 
778 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
779 {
780 	assert(cfg->mrst_reg);
781 
782 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
783 				       cfg->mrst_mask);
784 }
785 
786 int stpmic1_regulator_voltage_get(const char *name)
787 {
788 	const struct regul_struct *regul = get_regulator_data(name);
789 	uint8_t value = 0;
790 	uint8_t mask = 0;
791 
792 	mask = find_plat_mask(name);
793 	if (!mask)
794 		return 0;
795 
796 	if (stpmic1_register_read(regul->control_reg, &value))
797 		return -1;
798 
799 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
800 
801 	if (value > regul->voltage_table_size)
802 		return -1;
803 
804 	return regul->voltage_table[value];
805 }
806 
807 int stpmic1_lp_copy_reg(const char *name)
808 {
809 	const struct regul_struct *regul = get_regulator_data(name);
810 	uint8_t val = 0;
811 	int status = 0;
812 
813 	if (!regul->low_power_reg)
814 		return -1;
815 
816 	status = stpmic1_register_read(regul->control_reg, &val);
817 	if (status)
818 		return status;
819 
820 	return stpmic1_register_write(regul->low_power_reg, val);
821 }
822 
823 bool stpmic1_regu_has_lp_cfg(const char *name)
824 {
825 	return get_regulator_data(name)->low_power_reg;
826 }
827 
828 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
829 {
830 	const struct regul_struct *regul = get_regulator_data(name);
831 
832 	if (!regul->low_power_reg)
833 		return -1;
834 
835 	cfg->ctrl_reg = regul->control_reg;
836 	cfg->lp_reg = regul->low_power_reg;
837 
838 	return 0;
839 }
840 
841 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
842 {
843 	uint8_t val = 0;
844 	int status = 0;
845 
846 	assert(cfg->lp_reg);
847 
848 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
849 	if (!status)
850 		status = stpmic1_register_write(cfg->lp_reg, val);
851 
852 	return status;
853 }
854 
855 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
856 {
857 	const struct regul_struct *regul = get_regulator_data(name);
858 
859 	if (!regul->low_power_reg)
860 		return -1;
861 
862 	return stpmic1_register_update(regul->low_power_reg, enable,
863 				       LDO_BUCK_ENABLE_MASK);
864 }
865 
866 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
867 {
868 	assert(cfg->lp_reg && (enable == 0 || enable == 1));
869 
870 	return stpmic1_register_update(cfg->lp_reg, enable,
871 				       LDO_BUCK_ENABLE_MASK);
872 }
873 
874 int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
875 {
876 	const struct regul_struct *regul = get_regulator_data(name);
877 
878 	assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
879 
880 	return stpmic1_register_update(regul->low_power_reg,
881 				       hplp << LDO_BUCK_HPLP_POS,
882 				       BIT(LDO_BUCK_HPLP_POS));
883 }
884 
885 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
886 {
887 	assert(cfg->lp_reg && (mode == 0 || mode == 1));
888 	return stpmic1_register_update(cfg->lp_reg,
889 				       mode << LDO_BUCK_HPLP_POS,
890 				       BIT(LDO_BUCK_HPLP_POS));
891 }
892 
893 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
894 {
895 	size_t voltage_index = voltage_to_index(name, millivolts);
896 	const struct regul_struct *regul = get_regulator_data(name);
897 	uint8_t mask = 0;
898 
899 	assert(voltage_index != VOLTAGE_INDEX_INVALID);
900 
901 	mask = find_plat_mask(name);
902 	if (!mask)
903 		return 0;
904 
905 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
906 				       mask);
907 }
908 
909 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
910 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
911 			   struct stpmic1_lp_cfg *cfg)
912 
913 {
914 	size_t voltage_index = voltage_to_index(name, millivolts);
915 	uint8_t mask = 0;
916 
917 	mask = find_plat_mask(name);
918 	if (!mask)
919 		return 1;
920 
921 	assert(voltage_index != VOLTAGE_INDEX_INVALID &&
922 	       cfg->lp_reg == get_regulator_data(name)->low_power_reg);
923 
924 	cfg->value = voltage_index << 2;
925 	cfg->mask = mask;
926 
927 	return 0;
928 }
929 
930 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
931 {
932 	assert(cfg->lp_reg);
933 
934 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
935 }
936 
937 int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
938 {
939 	struct i2c_handle_s *i2c = pmic_i2c_handle;
940 
941 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
942 					    register_id, value,
943 					    false /* !write */);
944 }
945 
946 int stpmic1_register_write(uint8_t register_id, uint8_t value)
947 {
948 	struct i2c_handle_s *i2c = pmic_i2c_handle;
949 	uint8_t val = value;
950 
951 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
952 					    register_id, &val,
953 					    true /* write */);
954 }
955 
956 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
957 {
958 	int status = 0;
959 	uint8_t val = 0;
960 
961 	status = stpmic1_register_read(register_id, &val);
962 	if (status)
963 		return status;
964 
965 	val = (val & ~mask) | (value & mask);
966 
967 	return stpmic1_register_write(register_id, val);
968 }
969 
970 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
971 {
972 	pmic_i2c_handle = i2c_handle;
973 	pmic_i2c_addr = i2c_addr;
974 }
975 
976 void stpmic1_dump_regulators(void)
977 {
978 	size_t i = 0;
979 	char __maybe_unused const *name = NULL;
980 
981 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
982 		if (!regulators_table[i].control_reg)
983 			continue;
984 
985 		name = regulators_table[i].dt_node_name;
986 		DMSG("PMIC regul %s: %sable, %dmV",
987 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
988 		     stpmic1_regulator_voltage_get(name));
989 	}
990 }
991 
992 int stpmic1_get_version(unsigned long *version)
993 {
994 	uint8_t read_val = 0;
995 
996 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
997 		return -1;
998 
999 	*version = read_val;
1000 	return 0;
1001 }
1002