1 /*
2 * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <errno.h>
8 #include <string.h>
9
10 #include <common/debug.h>
11 #include <drivers/st/stpmic1.h>
12
13 #define I2C_TIMEOUT_MS 25
14
15 struct regul_struct {
16 const char *dt_node_name;
17 const uint16_t *voltage_table;
18 uint8_t voltage_table_size;
19 uint8_t control_reg;
20 uint8_t enable_mask;
21 uint8_t low_power_reg;
22 uint8_t pull_down_reg;
23 uint8_t pull_down;
24 uint8_t mask_reset_reg;
25 uint8_t mask_reset;
26 uint8_t icc_reg;
27 uint8_t icc_mask;
28 };
29
30 static struct i2c_handle_s *pmic_i2c_handle;
31 static uint16_t pmic_i2c_addr;
32 /*
33 * Special mode corresponds to LDO3 in sink source mode or in bypass mode.
34 * LDO3 doesn't switch back from special to normal mode.
35 */
36 static bool ldo3_special_mode;
37
38 /* Voltage tables in mV */
39 static const uint16_t buck1_voltage_table[] = {
40 725,
41 725,
42 725,
43 725,
44 725,
45 725,
46 750,
47 775,
48 800,
49 825,
50 850,
51 875,
52 900,
53 925,
54 950,
55 975,
56 1000,
57 1025,
58 1050,
59 1075,
60 1100,
61 1125,
62 1150,
63 1175,
64 1200,
65 1225,
66 1250,
67 1275,
68 1300,
69 1325,
70 1350,
71 1375,
72 1400,
73 1425,
74 1450,
75 1475,
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 1500,
100 1500,
101 1500,
102 1500,
103 1500,
104 };
105
106 static const uint16_t buck2_voltage_table[] = {
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 1000,
121 1000,
122 1000,
123 1000,
124 1000,
125 1050,
126 1050,
127 1100,
128 1100,
129 1150,
130 1150,
131 1200,
132 1200,
133 1250,
134 1250,
135 1300,
136 1300,
137 1350,
138 1350,
139 1400,
140 1400,
141 1450,
142 1450,
143 1500,
144 };
145
146 static const uint16_t buck3_voltage_table[] = {
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 1000,
163 1000,
164 1000,
165 1000,
166 1000,
167 1100,
168 1100,
169 1100,
170 1100,
171 1200,
172 1200,
173 1200,
174 1200,
175 1300,
176 1300,
177 1300,
178 1300,
179 1400,
180 1400,
181 1400,
182 1400,
183 1500,
184 1600,
185 1700,
186 1800,
187 1900,
188 2000,
189 2100,
190 2200,
191 2300,
192 2400,
193 2500,
194 2600,
195 2700,
196 2800,
197 2900,
198 3000,
199 3100,
200 3200,
201 3300,
202 3400,
203 };
204
205 static const uint16_t buck4_voltage_table[] = {
206 600,
207 625,
208 650,
209 675,
210 700,
211 725,
212 750,
213 775,
214 800,
215 825,
216 850,
217 875,
218 900,
219 925,
220 950,
221 975,
222 1000,
223 1025,
224 1050,
225 1075,
226 1100,
227 1125,
228 1150,
229 1175,
230 1200,
231 1225,
232 1250,
233 1275,
234 1300,
235 1300,
236 1350,
237 1350,
238 1400,
239 1400,
240 1450,
241 1450,
242 1500,
243 1600,
244 1700,
245 1800,
246 1900,
247 2000,
248 2100,
249 2200,
250 2300,
251 2400,
252 2500,
253 2600,
254 2700,
255 2800,
256 2900,
257 3000,
258 3100,
259 3200,
260 3300,
261 3400,
262 3500,
263 3600,
264 3700,
265 3800,
266 3900,
267 };
268
269 static const uint16_t ldo1_voltage_table[] = {
270 1700,
271 1700,
272 1700,
273 1700,
274 1700,
275 1700,
276 1700,
277 1700,
278 1700,
279 1800,
280 1900,
281 2000,
282 2100,
283 2200,
284 2300,
285 2400,
286 2500,
287 2600,
288 2700,
289 2800,
290 2900,
291 3000,
292 3100,
293 3200,
294 3300,
295 };
296
297 static const uint16_t ldo2_voltage_table[] = {
298 1700,
299 1700,
300 1700,
301 1700,
302 1700,
303 1700,
304 1700,
305 1700,
306 1700,
307 1800,
308 1900,
309 2000,
310 2100,
311 2200,
312 2300,
313 2400,
314 2500,
315 2600,
316 2700,
317 2800,
318 2900,
319 3000,
320 3100,
321 3200,
322 3300,
323 };
324
325 static const uint16_t ldo3_voltage_table[] = {
326 1700,
327 1700,
328 1700,
329 1700,
330 1700,
331 1700,
332 1700,
333 1700,
334 1700,
335 1800,
336 1900,
337 2000,
338 2100,
339 2200,
340 2300,
341 2400,
342 2500,
343 2600,
344 2700,
345 2800,
346 2900,
347 3000,
348 3100,
349 3200,
350 3300,
351 3300,
352 3300,
353 3300,
354 3300,
355 3300,
356 3300,
357 };
358
359 /* Special mode table is used for sink source OR bypass mode */
360 static const uint16_t ldo3_special_mode_table[] = {
361 0,
362 };
363
364 static const uint16_t ldo5_voltage_table[] = {
365 1700,
366 1700,
367 1700,
368 1700,
369 1700,
370 1700,
371 1700,
372 1700,
373 1700,
374 1800,
375 1900,
376 2000,
377 2100,
378 2200,
379 2300,
380 2400,
381 2500,
382 2600,
383 2700,
384 2800,
385 2900,
386 3000,
387 3100,
388 3200,
389 3300,
390 3400,
391 3500,
392 3600,
393 3700,
394 3800,
395 3900,
396 };
397
398 static const uint16_t ldo6_voltage_table[] = {
399 900,
400 1000,
401 1100,
402 1200,
403 1300,
404 1400,
405 1500,
406 1600,
407 1700,
408 1800,
409 1900,
410 2000,
411 2100,
412 2200,
413 2300,
414 2400,
415 2500,
416 2600,
417 2700,
418 2800,
419 2900,
420 3000,
421 3100,
422 3200,
423 3300,
424 };
425
426 static const uint16_t ldo4_voltage_table[] = {
427 3300,
428 };
429
430 static const uint16_t vref_ddr_voltage_table[] = {
431 3300,
432 };
433
434 static const uint16_t fixed_5v_voltage_table[] = {
435 5000,
436 };
437
438 /* Table of Regulators in PMIC SoC */
439 static const struct regul_struct regulators_table[] = {
440 {
441 .dt_node_name = "buck1",
442 .voltage_table = buck1_voltage_table,
443 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
444 .control_reg = BUCK1_CONTROL_REG,
445 .enable_mask = LDO_BUCK_ENABLE_MASK,
446 .low_power_reg = BUCK1_PWRCTRL_REG,
447 .pull_down_reg = BUCK_PULL_DOWN_REG,
448 .pull_down = BUCK1_PULL_DOWN_SHIFT,
449 .mask_reset_reg = MASK_RESET_BUCK_REG,
450 .mask_reset = BUCK1_MASK_RESET,
451 .icc_reg = BUCK_ICC_TURNOFF_REG,
452 .icc_mask = BUCK1_ICC_SHIFT,
453 },
454 {
455 .dt_node_name = "buck2",
456 .voltage_table = buck2_voltage_table,
457 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
458 .control_reg = BUCK2_CONTROL_REG,
459 .enable_mask = LDO_BUCK_ENABLE_MASK,
460 .low_power_reg = BUCK2_PWRCTRL_REG,
461 .pull_down_reg = BUCK_PULL_DOWN_REG,
462 .pull_down = BUCK2_PULL_DOWN_SHIFT,
463 .mask_reset_reg = MASK_RESET_BUCK_REG,
464 .mask_reset = BUCK2_MASK_RESET,
465 .icc_reg = BUCK_ICC_TURNOFF_REG,
466 .icc_mask = BUCK2_ICC_SHIFT,
467 },
468 {
469 .dt_node_name = "buck3",
470 .voltage_table = buck3_voltage_table,
471 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
472 .control_reg = BUCK3_CONTROL_REG,
473 .enable_mask = LDO_BUCK_ENABLE_MASK,
474 .low_power_reg = BUCK3_PWRCTRL_REG,
475 .pull_down_reg = BUCK_PULL_DOWN_REG,
476 .pull_down = BUCK3_PULL_DOWN_SHIFT,
477 .mask_reset_reg = MASK_RESET_BUCK_REG,
478 .mask_reset = BUCK3_MASK_RESET,
479 .icc_reg = BUCK_ICC_TURNOFF_REG,
480 .icc_mask = BUCK3_ICC_SHIFT,
481 },
482 {
483 .dt_node_name = "buck4",
484 .voltage_table = buck4_voltage_table,
485 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
486 .control_reg = BUCK4_CONTROL_REG,
487 .enable_mask = LDO_BUCK_ENABLE_MASK,
488 .low_power_reg = BUCK4_PWRCTRL_REG,
489 .pull_down_reg = BUCK_PULL_DOWN_REG,
490 .pull_down = BUCK4_PULL_DOWN_SHIFT,
491 .mask_reset_reg = MASK_RESET_BUCK_REG,
492 .mask_reset = BUCK4_MASK_RESET,
493 .icc_reg = BUCK_ICC_TURNOFF_REG,
494 .icc_mask = BUCK4_ICC_SHIFT,
495 },
496 {
497 .dt_node_name = "ldo1",
498 .voltage_table = ldo1_voltage_table,
499 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
500 .control_reg = LDO1_CONTROL_REG,
501 .enable_mask = LDO_BUCK_ENABLE_MASK,
502 .low_power_reg = LDO1_PWRCTRL_REG,
503 .mask_reset_reg = MASK_RESET_LDO_REG,
504 .mask_reset = LDO1_MASK_RESET,
505 .icc_reg = LDO_ICC_TURNOFF_REG,
506 .icc_mask = LDO1_ICC_SHIFT,
507 },
508 {
509 .dt_node_name = "ldo2",
510 .voltage_table = ldo2_voltage_table,
511 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
512 .control_reg = LDO2_CONTROL_REG,
513 .enable_mask = LDO_BUCK_ENABLE_MASK,
514 .low_power_reg = LDO2_PWRCTRL_REG,
515 .mask_reset_reg = MASK_RESET_LDO_REG,
516 .mask_reset = LDO2_MASK_RESET,
517 .icc_reg = LDO_ICC_TURNOFF_REG,
518 .icc_mask = LDO2_ICC_SHIFT,
519 },
520 {
521 .dt_node_name = "ldo3",
522 .voltage_table = ldo3_voltage_table,
523 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
524 .control_reg = LDO3_CONTROL_REG,
525 .enable_mask = LDO_BUCK_ENABLE_MASK,
526 .low_power_reg = LDO3_PWRCTRL_REG,
527 .mask_reset_reg = MASK_RESET_LDO_REG,
528 .mask_reset = LDO3_MASK_RESET,
529 .icc_reg = LDO_ICC_TURNOFF_REG,
530 .icc_mask = LDO3_ICC_SHIFT,
531 },
532 {
533 .dt_node_name = "ldo4",
534 .voltage_table = ldo4_voltage_table,
535 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
536 .control_reg = LDO4_CONTROL_REG,
537 .enable_mask = LDO_BUCK_ENABLE_MASK,
538 .low_power_reg = LDO4_PWRCTRL_REG,
539 .mask_reset_reg = MASK_RESET_LDO_REG,
540 .mask_reset = LDO4_MASK_RESET,
541 .icc_reg = LDO_ICC_TURNOFF_REG,
542 .icc_mask = LDO4_ICC_SHIFT,
543 },
544 {
545 .dt_node_name = "ldo5",
546 .voltage_table = ldo5_voltage_table,
547 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
548 .control_reg = LDO5_CONTROL_REG,
549 .enable_mask = LDO_BUCK_ENABLE_MASK,
550 .low_power_reg = LDO5_PWRCTRL_REG,
551 .mask_reset_reg = MASK_RESET_LDO_REG,
552 .mask_reset = LDO5_MASK_RESET,
553 .icc_reg = LDO_ICC_TURNOFF_REG,
554 .icc_mask = LDO5_ICC_SHIFT,
555 },
556 {
557 .dt_node_name = "ldo6",
558 .voltage_table = ldo6_voltage_table,
559 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
560 .control_reg = LDO6_CONTROL_REG,
561 .enable_mask = LDO_BUCK_ENABLE_MASK,
562 .low_power_reg = LDO6_PWRCTRL_REG,
563 .mask_reset_reg = MASK_RESET_LDO_REG,
564 .mask_reset = LDO6_MASK_RESET,
565 .icc_reg = LDO_ICC_TURNOFF_REG,
566 .icc_mask = LDO6_ICC_SHIFT,
567 },
568 {
569 .dt_node_name = "vref_ddr",
570 .voltage_table = vref_ddr_voltage_table,
571 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
572 .control_reg = VREF_DDR_CONTROL_REG,
573 .enable_mask = LDO_BUCK_ENABLE_MASK,
574 .low_power_reg = VREF_DDR_PWRCTRL_REG,
575 .mask_reset_reg = MASK_RESET_LDO_REG,
576 .mask_reset = VREF_DDR_MASK_RESET,
577 },
578 {
579 .dt_node_name = "boost",
580 .voltage_table = fixed_5v_voltage_table,
581 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
582 .control_reg = USB_CONTROL_REG,
583 .enable_mask = BOOST_ENABLED,
584 .icc_reg = BUCK_ICC_TURNOFF_REG,
585 .icc_mask = BOOST_ICC_SHIFT,
586 },
587 {
588 .dt_node_name = "pwr_sw1",
589 .voltage_table = fixed_5v_voltage_table,
590 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
591 .control_reg = USB_CONTROL_REG,
592 .enable_mask = USBSW_OTG_SWITCH_ENABLED,
593 .icc_reg = BUCK_ICC_TURNOFF_REG,
594 .icc_mask = PWR_SW1_ICC_SHIFT,
595 },
596 {
597 .dt_node_name = "pwr_sw2",
598 .voltage_table = fixed_5v_voltage_table,
599 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
600 .control_reg = USB_CONTROL_REG,
601 .enable_mask = SWIN_SWOUT_ENABLED,
602 .icc_reg = BUCK_ICC_TURNOFF_REG,
603 .icc_mask = PWR_SW2_ICC_SHIFT,
604 },
605 };
606
607 #define MAX_REGUL ARRAY_SIZE(regulators_table)
608
get_regulator_data(const char * name)609 static const struct regul_struct *get_regulator_data(const char *name)
610 {
611 uint8_t i;
612
613 for (i = 0 ; i < MAX_REGUL ; i++) {
614 if (strncmp(name, regulators_table[i].dt_node_name,
615 strlen(regulators_table[i].dt_node_name)) == 0) {
616 return ®ulators_table[i];
617 }
618 }
619
620 /* Regulator not found */
621 panic();
622 return NULL;
623 }
624
voltage_to_index(const char * name,uint16_t millivolts)625 static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
626 {
627 const struct regul_struct *regul = get_regulator_data(name);
628 uint8_t i;
629
630 for (i = 0 ; i < regul->voltage_table_size ; i++) {
631 if (regul->voltage_table[i] == millivolts) {
632 return i;
633 }
634 }
635
636 /* Voltage not found */
637 panic();
638
639 return 0;
640 }
641
stpmic1_powerctrl_on(void)642 int stpmic1_powerctrl_on(void)
643 {
644 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
645 PWRCTRL_PIN_VALID);
646 }
647
stpmic1_switch_off(void)648 int stpmic1_switch_off(void)
649 {
650 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
651 SOFTWARE_SWITCH_OFF_ENABLED);
652 }
653
stpmic1_regulator_enable(const char * name)654 int stpmic1_regulator_enable(const char *name)
655 {
656 const struct regul_struct *regul = get_regulator_data(name);
657
658 return stpmic1_register_update(regul->control_reg, regul->enable_mask,
659 regul->enable_mask);
660 }
661
stpmic1_regulator_disable(const char * name)662 int stpmic1_regulator_disable(const char *name)
663 {
664 const struct regul_struct *regul = get_regulator_data(name);
665
666 return stpmic1_register_update(regul->control_reg, 0,
667 regul->enable_mask);
668 }
669
stpmic1_is_regulator_enabled(const char * name)670 bool stpmic1_is_regulator_enabled(const char *name)
671 {
672 uint8_t val;
673 const struct regul_struct *regul = get_regulator_data(name);
674
675 if (stpmic1_register_read(regul->control_reg, &val) != 0) {
676 panic();
677 }
678
679 return (val & regul->enable_mask) == regul->enable_mask;
680 }
681
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)682 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
683 {
684 uint8_t voltage_index = voltage_to_index(name, millivolts);
685 const struct regul_struct *regul = get_regulator_data(name);
686 uint8_t mask;
687
688 if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
689 /*
690 * when the LDO3 is in special mode, we do not change voltage,
691 * because by setting voltage, the LDO would leaves sink-source
692 * mode. There is obviously no reason to leave sink-source mode
693 * at runtime.
694 */
695 return 0;
696 }
697
698 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
699 if (strncmp(name, "buck", 4) == 0) {
700 mask = BUCK_VOLTAGE_MASK;
701 } else if ((strncmp(name, "ldo", 3) == 0) &&
702 (strncmp(name, "ldo4", 5) != 0)) {
703 mask = LDO_VOLTAGE_MASK;
704 } else {
705 return 0;
706 }
707
708 return stpmic1_register_update(regul->control_reg,
709 voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
710 mask);
711 }
712
stpmic1_regulator_pull_down_set(const char * name)713 int stpmic1_regulator_pull_down_set(const char *name)
714 {
715 const struct regul_struct *regul = get_regulator_data(name);
716
717 if (regul->pull_down_reg != 0) {
718 return stpmic1_register_update(regul->pull_down_reg,
719 BIT(regul->pull_down),
720 LDO_BUCK_PULL_DOWN_MASK <<
721 regul->pull_down);
722 }
723
724 return 0;
725 }
726
stpmic1_regulator_mask_reset_set(const char * name)727 int stpmic1_regulator_mask_reset_set(const char *name)
728 {
729 const struct regul_struct *regul = get_regulator_data(name);
730
731 if (regul->mask_reset_reg == 0U) {
732 return -EPERM;
733 }
734
735 return stpmic1_register_update(regul->mask_reset_reg,
736 BIT(regul->mask_reset),
737 LDO_BUCK_RESET_MASK <<
738 regul->mask_reset);
739 }
740
stpmic1_regulator_icc_set(const char * name)741 int stpmic1_regulator_icc_set(const char *name)
742 {
743 const struct regul_struct *regul = get_regulator_data(name);
744
745 if (regul->mask_reset_reg == 0U) {
746 return -EPERM;
747 }
748
749 return stpmic1_register_update(regul->icc_reg,
750 BIT(regul->icc_mask),
751 BIT(regul->icc_mask));
752 }
753
stpmic1_regulator_sink_mode_set(const char * name)754 int stpmic1_regulator_sink_mode_set(const char *name)
755 {
756 if (strncmp(name, "ldo3", 5) != 0) {
757 return -EPERM;
758 }
759
760 ldo3_special_mode = true;
761
762 /* disable bypass mode, enable sink mode */
763 return stpmic1_register_update(LDO3_CONTROL_REG,
764 LDO3_DDR_SEL << LDO_BUCK_VOLTAGE_SHIFT,
765 LDO3_BYPASS | LDO_VOLTAGE_MASK);
766 }
767
stpmic1_regulator_bypass_mode_set(const char * name)768 int stpmic1_regulator_bypass_mode_set(const char *name)
769 {
770 if (strncmp(name, "ldo3", 5) != 0) {
771 return -EPERM;
772 }
773
774 ldo3_special_mode = true;
775
776 /* enable bypass mode, disable sink mode */
777 return stpmic1_register_update(LDO3_CONTROL_REG,
778 LDO3_BYPASS,
779 LDO3_BYPASS | LDO_VOLTAGE_MASK);
780 }
781
stpmic1_active_discharge_mode_set(const char * name)782 int stpmic1_active_discharge_mode_set(const char *name)
783 {
784 if (strncmp(name, "pwr_sw1", 8) == 0) {
785 return stpmic1_register_update(USB_CONTROL_REG,
786 VBUS_OTG_DISCHARGE,
787 VBUS_OTG_DISCHARGE);
788 }
789
790 if (strncmp(name, "pwr_sw2", 8) == 0) {
791 return stpmic1_register_update(USB_CONTROL_REG,
792 SW_OUT_DISCHARGE,
793 SW_OUT_DISCHARGE);
794 }
795
796 return -EPERM;
797 }
798
stpmic1_regulator_levels_mv(const char * name,const uint16_t ** levels,size_t * levels_count)799 int stpmic1_regulator_levels_mv(const char *name, const uint16_t **levels,
800 size_t *levels_count)
801 {
802 const struct regul_struct *regul = get_regulator_data(name);
803
804 if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
805 *levels_count = ARRAY_SIZE(ldo3_special_mode_table);
806 *levels = ldo3_special_mode_table;
807 } else {
808 *levels_count = regul->voltage_table_size;
809 *levels = regul->voltage_table;
810 }
811
812 return 0;
813 }
814
stpmic1_regulator_voltage_get(const char * name)815 int stpmic1_regulator_voltage_get(const char *name)
816 {
817 const struct regul_struct *regul = get_regulator_data(name);
818 uint8_t value;
819 uint8_t mask;
820 int status;
821
822 if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
823 return 0;
824 }
825
826 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
827 if (strncmp(name, "buck", 4) == 0) {
828 mask = BUCK_VOLTAGE_MASK;
829 } else if ((strncmp(name, "ldo", 3) == 0) &&
830 (strncmp(name, "ldo4", 5) != 0)) {
831 mask = LDO_VOLTAGE_MASK;
832 } else {
833 return 0;
834 }
835
836 status = stpmic1_register_read(regul->control_reg, &value);
837 if (status < 0) {
838 return status;
839 }
840
841 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
842
843 if (value > regul->voltage_table_size) {
844 return -ERANGE;
845 }
846
847 return (int)regul->voltage_table[value];
848 }
849
stpmic1_register_read(uint8_t register_id,uint8_t * value)850 int stpmic1_register_read(uint8_t register_id, uint8_t *value)
851 {
852 return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
853 (uint16_t)register_id,
854 I2C_MEMADD_SIZE_8BIT, value,
855 1, I2C_TIMEOUT_MS);
856 }
857
stpmic1_register_write(uint8_t register_id,uint8_t value)858 int stpmic1_register_write(uint8_t register_id, uint8_t value)
859 {
860 int status;
861
862 status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
863 (uint16_t)register_id,
864 I2C_MEMADD_SIZE_8BIT, &value,
865 1, I2C_TIMEOUT_MS);
866
867 #if ENABLE_ASSERTIONS
868 if (status != 0) {
869 return status;
870 }
871
872 if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
873 uint8_t readval;
874
875 status = stpmic1_register_read(register_id, &readval);
876 if (status != 0) {
877 return status;
878 }
879
880 if (readval != value) {
881 return -EIO;
882 }
883 }
884 #endif
885
886 return status;
887 }
888
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)889 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
890 {
891 int status;
892 uint8_t val;
893
894 status = stpmic1_register_read(register_id, &val);
895 if (status != 0) {
896 return status;
897 }
898
899 val = (val & ~mask) | (value & mask);
900
901 return stpmic1_register_write(register_id, val);
902 }
903
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)904 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
905 {
906 pmic_i2c_handle = i2c_handle;
907 pmic_i2c_addr = i2c_addr;
908 }
909
stpmic1_dump_regulators(void)910 void stpmic1_dump_regulators(void)
911 {
912 uint32_t i;
913
914 for (i = 0U; i < MAX_REGUL; i++) {
915 const char *name __unused = regulators_table[i].dt_node_name;
916
917 VERBOSE("PMIC regul %s: %sable, %dmV",
918 name,
919 stpmic1_is_regulator_enabled(name) ? "en" : "dis",
920 stpmic1_regulator_voltage_get(name));
921 }
922 }
923
stpmic1_get_version(unsigned long * version)924 int stpmic1_get_version(unsigned long *version)
925 {
926 uint8_t read_val;
927 int status;
928
929 status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
930 if (status < 0) {
931 return status;
932 }
933
934 *version = (unsigned long)read_val;
935
936 return 0;
937 }
938