123684d0eSYann Gautier /*
2ed6a8523SYann Gautier * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
323684d0eSYann Gautier *
423684d0eSYann Gautier * SPDX-License-Identifier: BSD-3-Clause
523684d0eSYann Gautier */
623684d0eSYann Gautier
7ed6a8523SYann Gautier #include <errno.h>
823684d0eSYann Gautier #include <string.h>
923684d0eSYann Gautier
1023684d0eSYann Gautier #include <common/debug.h>
1123684d0eSYann Gautier #include <drivers/st/stpmic1.h>
12d82d4ff0SYann Gautier
13d82d4ff0SYann Gautier #define I2C_TIMEOUT_MS 25
1423684d0eSYann Gautier
1523684d0eSYann Gautier struct regul_struct {
1623684d0eSYann Gautier const char *dt_node_name;
1723684d0eSYann Gautier const uint16_t *voltage_table;
1823684d0eSYann Gautier uint8_t voltage_table_size;
1923684d0eSYann Gautier uint8_t control_reg;
2001619911SPascal Paillet uint8_t enable_mask;
2123684d0eSYann Gautier uint8_t low_power_reg;
22077f6828SYann Gautier uint8_t pull_down_reg;
23077f6828SYann Gautier uint8_t pull_down;
24077f6828SYann Gautier uint8_t mask_reset_reg;
25077f6828SYann Gautier uint8_t mask_reset;
26*ea552bf5SPascal Paillet uint8_t icc_reg;
27*ea552bf5SPascal Paillet uint8_t icc_mask;
2823684d0eSYann Gautier };
2923684d0eSYann Gautier
3023684d0eSYann Gautier static struct i2c_handle_s *pmic_i2c_handle;
3123684d0eSYann Gautier static uint16_t pmic_i2c_addr;
32*ea552bf5SPascal Paillet /*
33*ea552bf5SPascal Paillet * Special mode corresponds to LDO3 in sink source mode or in bypass mode.
34*ea552bf5SPascal Paillet * LDO3 doesn't switch back from special to normal mode.
35*ea552bf5SPascal Paillet */
36*ea552bf5SPascal Paillet static bool ldo3_special_mode;
3723684d0eSYann Gautier
3823684d0eSYann Gautier /* Voltage tables in mV */
3923684d0eSYann Gautier static const uint16_t buck1_voltage_table[] = {
40077f6828SYann Gautier 725,
41077f6828SYann Gautier 725,
42077f6828SYann Gautier 725,
43077f6828SYann Gautier 725,
44077f6828SYann Gautier 725,
4523684d0eSYann Gautier 725,
4623684d0eSYann Gautier 750,
4723684d0eSYann Gautier 775,
4823684d0eSYann Gautier 800,
4923684d0eSYann Gautier 825,
5023684d0eSYann Gautier 850,
5123684d0eSYann Gautier 875,
5223684d0eSYann Gautier 900,
5323684d0eSYann Gautier 925,
5423684d0eSYann Gautier 950,
5523684d0eSYann Gautier 975,
5623684d0eSYann Gautier 1000,
5723684d0eSYann Gautier 1025,
5823684d0eSYann Gautier 1050,
5923684d0eSYann Gautier 1075,
6023684d0eSYann Gautier 1100,
6123684d0eSYann Gautier 1125,
6223684d0eSYann Gautier 1150,
6323684d0eSYann Gautier 1175,
6423684d0eSYann Gautier 1200,
6523684d0eSYann Gautier 1225,
6623684d0eSYann Gautier 1250,
6723684d0eSYann Gautier 1275,
6823684d0eSYann Gautier 1300,
6923684d0eSYann Gautier 1325,
7023684d0eSYann Gautier 1350,
71077f6828SYann Gautier 1375,
72077f6828SYann Gautier 1400,
73077f6828SYann Gautier 1425,
74077f6828SYann Gautier 1450,
75077f6828SYann Gautier 1475,
76077f6828SYann Gautier 1500,
77077f6828SYann Gautier 1500,
78077f6828SYann Gautier 1500,
79077f6828SYann Gautier 1500,
80077f6828SYann Gautier 1500,
81077f6828SYann Gautier 1500,
82077f6828SYann Gautier 1500,
83077f6828SYann Gautier 1500,
84077f6828SYann Gautier 1500,
85077f6828SYann Gautier 1500,
86077f6828SYann Gautier 1500,
87077f6828SYann Gautier 1500,
88077f6828SYann Gautier 1500,
89077f6828SYann Gautier 1500,
90077f6828SYann Gautier 1500,
91077f6828SYann Gautier 1500,
92077f6828SYann Gautier 1500,
93077f6828SYann Gautier 1500,
94077f6828SYann Gautier 1500,
95077f6828SYann Gautier 1500,
96077f6828SYann Gautier 1500,
97077f6828SYann Gautier 1500,
98077f6828SYann Gautier 1500,
99077f6828SYann Gautier 1500,
100077f6828SYann Gautier 1500,
101077f6828SYann Gautier 1500,
102077f6828SYann Gautier 1500,
103077f6828SYann Gautier 1500,
10423684d0eSYann Gautier };
10523684d0eSYann Gautier
10623684d0eSYann Gautier static const uint16_t buck2_voltage_table[] = {
10723684d0eSYann Gautier 1000,
10823684d0eSYann Gautier 1000,
10923684d0eSYann Gautier 1000,
11023684d0eSYann Gautier 1000,
11123684d0eSYann Gautier 1000,
11223684d0eSYann Gautier 1000,
11323684d0eSYann Gautier 1000,
11423684d0eSYann Gautier 1000,
11523684d0eSYann Gautier 1000,
11623684d0eSYann Gautier 1000,
11723684d0eSYann Gautier 1000,
11823684d0eSYann Gautier 1000,
11923684d0eSYann Gautier 1000,
12023684d0eSYann Gautier 1000,
12123684d0eSYann Gautier 1000,
12223684d0eSYann Gautier 1000,
12323684d0eSYann Gautier 1000,
12423684d0eSYann Gautier 1000,
12523684d0eSYann Gautier 1050,
12623684d0eSYann Gautier 1050,
12723684d0eSYann Gautier 1100,
12823684d0eSYann Gautier 1100,
12923684d0eSYann Gautier 1150,
13023684d0eSYann Gautier 1150,
13123684d0eSYann Gautier 1200,
13223684d0eSYann Gautier 1200,
13323684d0eSYann Gautier 1250,
13423684d0eSYann Gautier 1250,
13523684d0eSYann Gautier 1300,
13623684d0eSYann Gautier 1300,
13723684d0eSYann Gautier 1350,
13823684d0eSYann Gautier 1350,
13923684d0eSYann Gautier 1400,
14023684d0eSYann Gautier 1400,
14123684d0eSYann Gautier 1450,
14223684d0eSYann Gautier 1450,
14323684d0eSYann Gautier 1500,
14423684d0eSYann Gautier };
14523684d0eSYann Gautier
14623684d0eSYann Gautier static const uint16_t buck3_voltage_table[] = {
14723684d0eSYann Gautier 1000,
14823684d0eSYann Gautier 1000,
14923684d0eSYann Gautier 1000,
15023684d0eSYann Gautier 1000,
15123684d0eSYann Gautier 1000,
15223684d0eSYann Gautier 1000,
15323684d0eSYann Gautier 1000,
15423684d0eSYann Gautier 1000,
15523684d0eSYann Gautier 1000,
15623684d0eSYann Gautier 1000,
15723684d0eSYann Gautier 1000,
15823684d0eSYann Gautier 1000,
15923684d0eSYann Gautier 1000,
16023684d0eSYann Gautier 1000,
16123684d0eSYann Gautier 1000,
16223684d0eSYann Gautier 1000,
16323684d0eSYann Gautier 1000,
16423684d0eSYann Gautier 1000,
16523684d0eSYann Gautier 1000,
16623684d0eSYann Gautier 1000,
16723684d0eSYann Gautier 1100,
16823684d0eSYann Gautier 1100,
16923684d0eSYann Gautier 1100,
17023684d0eSYann Gautier 1100,
17123684d0eSYann Gautier 1200,
17223684d0eSYann Gautier 1200,
17323684d0eSYann Gautier 1200,
17423684d0eSYann Gautier 1200,
17523684d0eSYann Gautier 1300,
17623684d0eSYann Gautier 1300,
17723684d0eSYann Gautier 1300,
17823684d0eSYann Gautier 1300,
17923684d0eSYann Gautier 1400,
18023684d0eSYann Gautier 1400,
18123684d0eSYann Gautier 1400,
18223684d0eSYann Gautier 1400,
18323684d0eSYann Gautier 1500,
18423684d0eSYann Gautier 1600,
18523684d0eSYann Gautier 1700,
18623684d0eSYann Gautier 1800,
18723684d0eSYann Gautier 1900,
18823684d0eSYann Gautier 2000,
18923684d0eSYann Gautier 2100,
19023684d0eSYann Gautier 2200,
19123684d0eSYann Gautier 2300,
19223684d0eSYann Gautier 2400,
19323684d0eSYann Gautier 2500,
19423684d0eSYann Gautier 2600,
19523684d0eSYann Gautier 2700,
19623684d0eSYann Gautier 2800,
19723684d0eSYann Gautier 2900,
19823684d0eSYann Gautier 3000,
19923684d0eSYann Gautier 3100,
20023684d0eSYann Gautier 3200,
20123684d0eSYann Gautier 3300,
20223684d0eSYann Gautier 3400,
20323684d0eSYann Gautier };
20423684d0eSYann Gautier
20523684d0eSYann Gautier static const uint16_t buck4_voltage_table[] = {
20623684d0eSYann Gautier 600,
20723684d0eSYann Gautier 625,
20823684d0eSYann Gautier 650,
20923684d0eSYann Gautier 675,
21023684d0eSYann Gautier 700,
21123684d0eSYann Gautier 725,
21223684d0eSYann Gautier 750,
21323684d0eSYann Gautier 775,
21423684d0eSYann Gautier 800,
21523684d0eSYann Gautier 825,
21623684d0eSYann Gautier 850,
21723684d0eSYann Gautier 875,
21823684d0eSYann Gautier 900,
21923684d0eSYann Gautier 925,
22023684d0eSYann Gautier 950,
22123684d0eSYann Gautier 975,
22223684d0eSYann Gautier 1000,
22323684d0eSYann Gautier 1025,
22423684d0eSYann Gautier 1050,
22523684d0eSYann Gautier 1075,
22623684d0eSYann Gautier 1100,
22723684d0eSYann Gautier 1125,
22823684d0eSYann Gautier 1150,
22923684d0eSYann Gautier 1175,
23023684d0eSYann Gautier 1200,
23123684d0eSYann Gautier 1225,
23223684d0eSYann Gautier 1250,
23323684d0eSYann Gautier 1275,
23423684d0eSYann Gautier 1300,
23523684d0eSYann Gautier 1300,
23623684d0eSYann Gautier 1350,
23723684d0eSYann Gautier 1350,
23823684d0eSYann Gautier 1400,
23923684d0eSYann Gautier 1400,
24023684d0eSYann Gautier 1450,
24123684d0eSYann Gautier 1450,
24223684d0eSYann Gautier 1500,
24323684d0eSYann Gautier 1600,
24423684d0eSYann Gautier 1700,
24523684d0eSYann Gautier 1800,
24623684d0eSYann Gautier 1900,
24723684d0eSYann Gautier 2000,
24823684d0eSYann Gautier 2100,
24923684d0eSYann Gautier 2200,
25023684d0eSYann Gautier 2300,
25123684d0eSYann Gautier 2400,
25223684d0eSYann Gautier 2500,
25323684d0eSYann Gautier 2600,
25423684d0eSYann Gautier 2700,
25523684d0eSYann Gautier 2800,
25623684d0eSYann Gautier 2900,
25723684d0eSYann Gautier 3000,
25823684d0eSYann Gautier 3100,
25923684d0eSYann Gautier 3200,
26023684d0eSYann Gautier 3300,
26123684d0eSYann Gautier 3400,
26223684d0eSYann Gautier 3500,
26323684d0eSYann Gautier 3600,
26423684d0eSYann Gautier 3700,
26523684d0eSYann Gautier 3800,
26623684d0eSYann Gautier 3900,
26723684d0eSYann Gautier };
26823684d0eSYann Gautier
26923684d0eSYann Gautier static const uint16_t ldo1_voltage_table[] = {
27023684d0eSYann Gautier 1700,
27123684d0eSYann Gautier 1700,
27223684d0eSYann Gautier 1700,
27323684d0eSYann Gautier 1700,
27423684d0eSYann Gautier 1700,
27523684d0eSYann Gautier 1700,
27623684d0eSYann Gautier 1700,
27723684d0eSYann Gautier 1700,
27823684d0eSYann Gautier 1700,
27923684d0eSYann Gautier 1800,
28023684d0eSYann Gautier 1900,
28123684d0eSYann Gautier 2000,
28223684d0eSYann Gautier 2100,
28323684d0eSYann Gautier 2200,
28423684d0eSYann Gautier 2300,
28523684d0eSYann Gautier 2400,
28623684d0eSYann Gautier 2500,
28723684d0eSYann Gautier 2600,
28823684d0eSYann Gautier 2700,
28923684d0eSYann Gautier 2800,
29023684d0eSYann Gautier 2900,
29123684d0eSYann Gautier 3000,
29223684d0eSYann Gautier 3100,
29323684d0eSYann Gautier 3200,
29423684d0eSYann Gautier 3300,
29523684d0eSYann Gautier };
29623684d0eSYann Gautier
29723684d0eSYann Gautier static const uint16_t ldo2_voltage_table[] = {
29823684d0eSYann Gautier 1700,
29923684d0eSYann Gautier 1700,
30023684d0eSYann Gautier 1700,
30123684d0eSYann Gautier 1700,
30223684d0eSYann Gautier 1700,
30323684d0eSYann Gautier 1700,
30423684d0eSYann Gautier 1700,
30523684d0eSYann Gautier 1700,
30623684d0eSYann Gautier 1700,
30723684d0eSYann Gautier 1800,
30823684d0eSYann Gautier 1900,
30923684d0eSYann Gautier 2000,
31023684d0eSYann Gautier 2100,
31123684d0eSYann Gautier 2200,
31223684d0eSYann Gautier 2300,
31323684d0eSYann Gautier 2400,
31423684d0eSYann Gautier 2500,
31523684d0eSYann Gautier 2600,
31623684d0eSYann Gautier 2700,
31723684d0eSYann Gautier 2800,
31823684d0eSYann Gautier 2900,
31923684d0eSYann Gautier 3000,
32023684d0eSYann Gautier 3100,
32123684d0eSYann Gautier 3200,
32223684d0eSYann Gautier 3300,
32323684d0eSYann Gautier };
32423684d0eSYann Gautier
32523684d0eSYann Gautier static const uint16_t ldo3_voltage_table[] = {
32623684d0eSYann Gautier 1700,
32723684d0eSYann Gautier 1700,
32823684d0eSYann Gautier 1700,
32923684d0eSYann Gautier 1700,
33023684d0eSYann Gautier 1700,
33123684d0eSYann Gautier 1700,
33223684d0eSYann Gautier 1700,
33323684d0eSYann Gautier 1700,
33423684d0eSYann Gautier 1700,
33523684d0eSYann Gautier 1800,
33623684d0eSYann Gautier 1900,
33723684d0eSYann Gautier 2000,
33823684d0eSYann Gautier 2100,
33923684d0eSYann Gautier 2200,
34023684d0eSYann Gautier 2300,
34123684d0eSYann Gautier 2400,
34223684d0eSYann Gautier 2500,
34323684d0eSYann Gautier 2600,
34423684d0eSYann Gautier 2700,
34523684d0eSYann Gautier 2800,
34623684d0eSYann Gautier 2900,
34723684d0eSYann Gautier 3000,
34823684d0eSYann Gautier 3100,
34923684d0eSYann Gautier 3200,
35023684d0eSYann Gautier 3300,
35123684d0eSYann Gautier 3300,
35223684d0eSYann Gautier 3300,
35323684d0eSYann Gautier 3300,
35423684d0eSYann Gautier 3300,
35523684d0eSYann Gautier 3300,
35623684d0eSYann Gautier 3300,
357*ea552bf5SPascal Paillet };
358*ea552bf5SPascal Paillet
359*ea552bf5SPascal Paillet /* Special mode table is used for sink source OR bypass mode */
360*ea552bf5SPascal Paillet static const uint16_t ldo3_special_mode_table[] = {
361*ea552bf5SPascal Paillet 0,
36223684d0eSYann Gautier };
36323684d0eSYann Gautier
36423684d0eSYann Gautier static const uint16_t ldo5_voltage_table[] = {
36523684d0eSYann Gautier 1700,
36623684d0eSYann Gautier 1700,
36723684d0eSYann Gautier 1700,
36823684d0eSYann Gautier 1700,
36923684d0eSYann Gautier 1700,
37023684d0eSYann Gautier 1700,
37123684d0eSYann Gautier 1700,
37223684d0eSYann Gautier 1700,
37323684d0eSYann Gautier 1700,
37423684d0eSYann Gautier 1800,
37523684d0eSYann Gautier 1900,
37623684d0eSYann Gautier 2000,
37723684d0eSYann Gautier 2100,
37823684d0eSYann Gautier 2200,
37923684d0eSYann Gautier 2300,
38023684d0eSYann Gautier 2400,
38123684d0eSYann Gautier 2500,
38223684d0eSYann Gautier 2600,
38323684d0eSYann Gautier 2700,
38423684d0eSYann Gautier 2800,
38523684d0eSYann Gautier 2900,
38623684d0eSYann Gautier 3000,
38723684d0eSYann Gautier 3100,
38823684d0eSYann Gautier 3200,
38923684d0eSYann Gautier 3300,
39023684d0eSYann Gautier 3400,
39123684d0eSYann Gautier 3500,
39223684d0eSYann Gautier 3600,
39323684d0eSYann Gautier 3700,
39423684d0eSYann Gautier 3800,
39523684d0eSYann Gautier 3900,
39623684d0eSYann Gautier };
39723684d0eSYann Gautier
39823684d0eSYann Gautier static const uint16_t ldo6_voltage_table[] = {
39923684d0eSYann Gautier 900,
40023684d0eSYann Gautier 1000,
40123684d0eSYann Gautier 1100,
40223684d0eSYann Gautier 1200,
40323684d0eSYann Gautier 1300,
40423684d0eSYann Gautier 1400,
40523684d0eSYann Gautier 1500,
40623684d0eSYann Gautier 1600,
40723684d0eSYann Gautier 1700,
40823684d0eSYann Gautier 1800,
40923684d0eSYann Gautier 1900,
41023684d0eSYann Gautier 2000,
41123684d0eSYann Gautier 2100,
41223684d0eSYann Gautier 2200,
41323684d0eSYann Gautier 2300,
41423684d0eSYann Gautier 2400,
41523684d0eSYann Gautier 2500,
41623684d0eSYann Gautier 2600,
41723684d0eSYann Gautier 2700,
41823684d0eSYann Gautier 2800,
41923684d0eSYann Gautier 2900,
42023684d0eSYann Gautier 3000,
42123684d0eSYann Gautier 3100,
42223684d0eSYann Gautier 3200,
42323684d0eSYann Gautier 3300,
42423684d0eSYann Gautier };
42523684d0eSYann Gautier
42623684d0eSYann Gautier static const uint16_t ldo4_voltage_table[] = {
42723684d0eSYann Gautier 3300,
42823684d0eSYann Gautier };
42923684d0eSYann Gautier
43023684d0eSYann Gautier static const uint16_t vref_ddr_voltage_table[] = {
43123684d0eSYann Gautier 3300,
43223684d0eSYann Gautier };
43323684d0eSYann Gautier
43413fbfe04SEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = {
43513fbfe04SEtienne Carriere 5000,
43613fbfe04SEtienne Carriere };
43713fbfe04SEtienne Carriere
43823684d0eSYann Gautier /* Table of Regulators in PMIC SoC */
43923684d0eSYann Gautier static const struct regul_struct regulators_table[] = {
44023684d0eSYann Gautier {
44123684d0eSYann Gautier .dt_node_name = "buck1",
44223684d0eSYann Gautier .voltage_table = buck1_voltage_table,
44323684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
44423684d0eSYann Gautier .control_reg = BUCK1_CONTROL_REG,
44501619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
44623684d0eSYann Gautier .low_power_reg = BUCK1_PWRCTRL_REG,
447077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG,
448077f6828SYann Gautier .pull_down = BUCK1_PULL_DOWN_SHIFT,
449077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG,
450077f6828SYann Gautier .mask_reset = BUCK1_MASK_RESET,
451*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
452*ea552bf5SPascal Paillet .icc_mask = BUCK1_ICC_SHIFT,
45323684d0eSYann Gautier },
45423684d0eSYann Gautier {
45523684d0eSYann Gautier .dt_node_name = "buck2",
45623684d0eSYann Gautier .voltage_table = buck2_voltage_table,
45723684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
45823684d0eSYann Gautier .control_reg = BUCK2_CONTROL_REG,
45901619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
46023684d0eSYann Gautier .low_power_reg = BUCK2_PWRCTRL_REG,
461077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG,
462077f6828SYann Gautier .pull_down = BUCK2_PULL_DOWN_SHIFT,
463077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG,
464077f6828SYann Gautier .mask_reset = BUCK2_MASK_RESET,
465*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
466*ea552bf5SPascal Paillet .icc_mask = BUCK2_ICC_SHIFT,
46723684d0eSYann Gautier },
46823684d0eSYann Gautier {
46923684d0eSYann Gautier .dt_node_name = "buck3",
47023684d0eSYann Gautier .voltage_table = buck3_voltage_table,
47123684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
47223684d0eSYann Gautier .control_reg = BUCK3_CONTROL_REG,
47301619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
47423684d0eSYann Gautier .low_power_reg = BUCK3_PWRCTRL_REG,
475077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG,
476077f6828SYann Gautier .pull_down = BUCK3_PULL_DOWN_SHIFT,
477077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG,
478077f6828SYann Gautier .mask_reset = BUCK3_MASK_RESET,
479*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
480*ea552bf5SPascal Paillet .icc_mask = BUCK3_ICC_SHIFT,
48123684d0eSYann Gautier },
48223684d0eSYann Gautier {
48323684d0eSYann Gautier .dt_node_name = "buck4",
48423684d0eSYann Gautier .voltage_table = buck4_voltage_table,
48523684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
48623684d0eSYann Gautier .control_reg = BUCK4_CONTROL_REG,
48701619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
48823684d0eSYann Gautier .low_power_reg = BUCK4_PWRCTRL_REG,
489077f6828SYann Gautier .pull_down_reg = BUCK_PULL_DOWN_REG,
490077f6828SYann Gautier .pull_down = BUCK4_PULL_DOWN_SHIFT,
491077f6828SYann Gautier .mask_reset_reg = MASK_RESET_BUCK_REG,
492077f6828SYann Gautier .mask_reset = BUCK4_MASK_RESET,
493*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
494*ea552bf5SPascal Paillet .icc_mask = BUCK4_ICC_SHIFT,
49523684d0eSYann Gautier },
49623684d0eSYann Gautier {
49723684d0eSYann Gautier .dt_node_name = "ldo1",
49823684d0eSYann Gautier .voltage_table = ldo1_voltage_table,
49923684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
50023684d0eSYann Gautier .control_reg = LDO1_CONTROL_REG,
50101619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
50223684d0eSYann Gautier .low_power_reg = LDO1_PWRCTRL_REG,
503077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
504077f6828SYann Gautier .mask_reset = LDO1_MASK_RESET,
505*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
506*ea552bf5SPascal Paillet .icc_mask = LDO1_ICC_SHIFT,
50723684d0eSYann Gautier },
50823684d0eSYann Gautier {
50923684d0eSYann Gautier .dt_node_name = "ldo2",
51023684d0eSYann Gautier .voltage_table = ldo2_voltage_table,
51123684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
51223684d0eSYann Gautier .control_reg = LDO2_CONTROL_REG,
51301619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
51423684d0eSYann Gautier .low_power_reg = LDO2_PWRCTRL_REG,
515077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
516077f6828SYann Gautier .mask_reset = LDO2_MASK_RESET,
517*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
518*ea552bf5SPascal Paillet .icc_mask = LDO2_ICC_SHIFT,
51923684d0eSYann Gautier },
52023684d0eSYann Gautier {
52123684d0eSYann Gautier .dt_node_name = "ldo3",
52223684d0eSYann Gautier .voltage_table = ldo3_voltage_table,
52323684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
52423684d0eSYann Gautier .control_reg = LDO3_CONTROL_REG,
52501619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
52623684d0eSYann Gautier .low_power_reg = LDO3_PWRCTRL_REG,
527077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
528077f6828SYann Gautier .mask_reset = LDO3_MASK_RESET,
529*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
530*ea552bf5SPascal Paillet .icc_mask = LDO3_ICC_SHIFT,
53123684d0eSYann Gautier },
53223684d0eSYann Gautier {
53323684d0eSYann Gautier .dt_node_name = "ldo4",
53423684d0eSYann Gautier .voltage_table = ldo4_voltage_table,
53523684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
53623684d0eSYann Gautier .control_reg = LDO4_CONTROL_REG,
53701619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
53823684d0eSYann Gautier .low_power_reg = LDO4_PWRCTRL_REG,
539077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
540077f6828SYann Gautier .mask_reset = LDO4_MASK_RESET,
541*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
542*ea552bf5SPascal Paillet .icc_mask = LDO4_ICC_SHIFT,
54323684d0eSYann Gautier },
54423684d0eSYann Gautier {
54523684d0eSYann Gautier .dt_node_name = "ldo5",
54623684d0eSYann Gautier .voltage_table = ldo5_voltage_table,
54723684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
54823684d0eSYann Gautier .control_reg = LDO5_CONTROL_REG,
54901619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
55023684d0eSYann Gautier .low_power_reg = LDO5_PWRCTRL_REG,
551077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
552077f6828SYann Gautier .mask_reset = LDO5_MASK_RESET,
553*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
554*ea552bf5SPascal Paillet .icc_mask = LDO5_ICC_SHIFT,
55523684d0eSYann Gautier },
55623684d0eSYann Gautier {
55723684d0eSYann Gautier .dt_node_name = "ldo6",
55823684d0eSYann Gautier .voltage_table = ldo6_voltage_table,
55923684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
56023684d0eSYann Gautier .control_reg = LDO6_CONTROL_REG,
56101619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
56223684d0eSYann Gautier .low_power_reg = LDO6_PWRCTRL_REG,
563077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
564077f6828SYann Gautier .mask_reset = LDO6_MASK_RESET,
565*ea552bf5SPascal Paillet .icc_reg = LDO_ICC_TURNOFF_REG,
566*ea552bf5SPascal Paillet .icc_mask = LDO6_ICC_SHIFT,
56723684d0eSYann Gautier },
56823684d0eSYann Gautier {
56923684d0eSYann Gautier .dt_node_name = "vref_ddr",
57023684d0eSYann Gautier .voltage_table = vref_ddr_voltage_table,
57123684d0eSYann Gautier .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
57223684d0eSYann Gautier .control_reg = VREF_DDR_CONTROL_REG,
57301619911SPascal Paillet .enable_mask = LDO_BUCK_ENABLE_MASK,
57423684d0eSYann Gautier .low_power_reg = VREF_DDR_PWRCTRL_REG,
575077f6828SYann Gautier .mask_reset_reg = MASK_RESET_LDO_REG,
576077f6828SYann Gautier .mask_reset = VREF_DDR_MASK_RESET,
57723684d0eSYann Gautier },
57813fbfe04SEtienne Carriere {
57913fbfe04SEtienne Carriere .dt_node_name = "boost",
58013fbfe04SEtienne Carriere .voltage_table = fixed_5v_voltage_table,
58113fbfe04SEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
58213fbfe04SEtienne Carriere .control_reg = USB_CONTROL_REG,
58313fbfe04SEtienne Carriere .enable_mask = BOOST_ENABLED,
584*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
585*ea552bf5SPascal Paillet .icc_mask = BOOST_ICC_SHIFT,
58613fbfe04SEtienne Carriere },
58713fbfe04SEtienne Carriere {
58813fbfe04SEtienne Carriere .dt_node_name = "pwr_sw1",
58913fbfe04SEtienne Carriere .voltage_table = fixed_5v_voltage_table,
59013fbfe04SEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
59113fbfe04SEtienne Carriere .control_reg = USB_CONTROL_REG,
59213fbfe04SEtienne Carriere .enable_mask = USBSW_OTG_SWITCH_ENABLED,
593*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
594*ea552bf5SPascal Paillet .icc_mask = PWR_SW1_ICC_SHIFT,
59513fbfe04SEtienne Carriere },
59613fbfe04SEtienne Carriere {
59713fbfe04SEtienne Carriere .dt_node_name = "pwr_sw2",
59813fbfe04SEtienne Carriere .voltage_table = fixed_5v_voltage_table,
59913fbfe04SEtienne Carriere .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
60013fbfe04SEtienne Carriere .control_reg = USB_CONTROL_REG,
60113fbfe04SEtienne Carriere .enable_mask = SWIN_SWOUT_ENABLED,
602*ea552bf5SPascal Paillet .icc_reg = BUCK_ICC_TURNOFF_REG,
603*ea552bf5SPascal Paillet .icc_mask = PWR_SW2_ICC_SHIFT,
60413fbfe04SEtienne Carriere },
60523684d0eSYann Gautier };
60623684d0eSYann Gautier
60723684d0eSYann Gautier #define MAX_REGUL ARRAY_SIZE(regulators_table)
60823684d0eSYann Gautier
get_regulator_data(const char * name)60923684d0eSYann Gautier static const struct regul_struct *get_regulator_data(const char *name)
61023684d0eSYann Gautier {
61123684d0eSYann Gautier uint8_t i;
61223684d0eSYann Gautier
61323684d0eSYann Gautier for (i = 0 ; i < MAX_REGUL ; i++) {
61423684d0eSYann Gautier if (strncmp(name, regulators_table[i].dt_node_name,
61523684d0eSYann Gautier strlen(regulators_table[i].dt_node_name)) == 0) {
61623684d0eSYann Gautier return ®ulators_table[i];
61723684d0eSYann Gautier }
61823684d0eSYann Gautier }
61923684d0eSYann Gautier
62023684d0eSYann Gautier /* Regulator not found */
62123684d0eSYann Gautier panic();
62223684d0eSYann Gautier return NULL;
62323684d0eSYann Gautier }
62423684d0eSYann Gautier
voltage_to_index(const char * name,uint16_t millivolts)62523684d0eSYann Gautier static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
62623684d0eSYann Gautier {
62723684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name);
62823684d0eSYann Gautier uint8_t i;
62923684d0eSYann Gautier
63023684d0eSYann Gautier for (i = 0 ; i < regul->voltage_table_size ; i++) {
63123684d0eSYann Gautier if (regul->voltage_table[i] == millivolts) {
63223684d0eSYann Gautier return i;
63323684d0eSYann Gautier }
63423684d0eSYann Gautier }
63523684d0eSYann Gautier
63623684d0eSYann Gautier /* Voltage not found */
63723684d0eSYann Gautier panic();
63823684d0eSYann Gautier
63923684d0eSYann Gautier return 0;
64023684d0eSYann Gautier }
64123684d0eSYann Gautier
stpmic1_powerctrl_on(void)642077f6828SYann Gautier int stpmic1_powerctrl_on(void)
643077f6828SYann Gautier {
644077f6828SYann Gautier return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
645077f6828SYann Gautier PWRCTRL_PIN_VALID);
646077f6828SYann Gautier }
647077f6828SYann Gautier
stpmic1_switch_off(void)64823684d0eSYann Gautier int stpmic1_switch_off(void)
64923684d0eSYann Gautier {
65023684d0eSYann Gautier return stpmic1_register_update(MAIN_CONTROL_REG, 1,
65123684d0eSYann Gautier SOFTWARE_SWITCH_OFF_ENABLED);
65223684d0eSYann Gautier }
65323684d0eSYann Gautier
stpmic1_regulator_enable(const char * name)65423684d0eSYann Gautier int stpmic1_regulator_enable(const char *name)
65523684d0eSYann Gautier {
65623684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name);
65723684d0eSYann Gautier
65801619911SPascal Paillet return stpmic1_register_update(regul->control_reg, regul->enable_mask,
65901619911SPascal Paillet regul->enable_mask);
66023684d0eSYann Gautier }
66123684d0eSYann Gautier
stpmic1_regulator_disable(const char * name)66223684d0eSYann Gautier int stpmic1_regulator_disable(const char *name)
66323684d0eSYann Gautier {
66423684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name);
66523684d0eSYann Gautier
66601619911SPascal Paillet return stpmic1_register_update(regul->control_reg, 0,
66701619911SPascal Paillet regul->enable_mask);
66823684d0eSYann Gautier }
66923684d0eSYann Gautier
stpmic1_is_regulator_enabled(const char * name)67016e56a75SNicolas Le Bayon bool stpmic1_is_regulator_enabled(const char *name)
67123684d0eSYann Gautier {
67223684d0eSYann Gautier uint8_t val;
67323684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name);
67423684d0eSYann Gautier
67523684d0eSYann Gautier if (stpmic1_register_read(regul->control_reg, &val) != 0) {
67623684d0eSYann Gautier panic();
67723684d0eSYann Gautier }
67823684d0eSYann Gautier
67916e56a75SNicolas Le Bayon return (val & regul->enable_mask) == regul->enable_mask;
68023684d0eSYann Gautier }
68123684d0eSYann Gautier
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)68223684d0eSYann Gautier int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
68323684d0eSYann Gautier {
68423684d0eSYann Gautier uint8_t voltage_index = voltage_to_index(name, millivolts);
68523684d0eSYann Gautier const struct regul_struct *regul = get_regulator_data(name);
686077f6828SYann Gautier uint8_t mask;
68723684d0eSYann Gautier
688*ea552bf5SPascal Paillet if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
689*ea552bf5SPascal Paillet /*
690*ea552bf5SPascal Paillet * when the LDO3 is in special mode, we do not change voltage,
691*ea552bf5SPascal Paillet * because by setting voltage, the LDO would leaves sink-source
692*ea552bf5SPascal Paillet * mode. There is obviously no reason to leave sink-source mode
693*ea552bf5SPascal Paillet * at runtime.
694*ea552bf5SPascal Paillet */
695*ea552bf5SPascal Paillet return 0;
696*ea552bf5SPascal Paillet }
697*ea552bf5SPascal Paillet
698077f6828SYann Gautier /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
699077f6828SYann Gautier if (strncmp(name, "buck", 4) == 0) {
700077f6828SYann Gautier mask = BUCK_VOLTAGE_MASK;
701077f6828SYann Gautier } else if ((strncmp(name, "ldo", 3) == 0) &&
702*ea552bf5SPascal Paillet (strncmp(name, "ldo4", 5) != 0)) {
703077f6828SYann Gautier mask = LDO_VOLTAGE_MASK;
704077f6828SYann Gautier } else {
705077f6828SYann Gautier return 0;
706077f6828SYann Gautier }
707077f6828SYann Gautier
708077f6828SYann Gautier return stpmic1_register_update(regul->control_reg,
709077f6828SYann Gautier voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
710077f6828SYann Gautier mask);
711077f6828SYann Gautier }
712077f6828SYann Gautier
stpmic1_regulator_pull_down_set(const char * name)713077f6828SYann Gautier int stpmic1_regulator_pull_down_set(const char *name)
714077f6828SYann Gautier {
715077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name);
716077f6828SYann Gautier
717077f6828SYann Gautier if (regul->pull_down_reg != 0) {
718077f6828SYann Gautier return stpmic1_register_update(regul->pull_down_reg,
719077f6828SYann Gautier BIT(regul->pull_down),
720077f6828SYann Gautier LDO_BUCK_PULL_DOWN_MASK <<
721077f6828SYann Gautier regul->pull_down);
722077f6828SYann Gautier }
723077f6828SYann Gautier
724077f6828SYann Gautier return 0;
725077f6828SYann Gautier }
726077f6828SYann Gautier
stpmic1_regulator_mask_reset_set(const char * name)727077f6828SYann Gautier int stpmic1_regulator_mask_reset_set(const char *name)
728077f6828SYann Gautier {
729077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name);
730077f6828SYann Gautier
731*ea552bf5SPascal Paillet if (regul->mask_reset_reg == 0U) {
732*ea552bf5SPascal Paillet return -EPERM;
733*ea552bf5SPascal Paillet }
734*ea552bf5SPascal Paillet
735077f6828SYann Gautier return stpmic1_register_update(regul->mask_reset_reg,
736077f6828SYann Gautier BIT(regul->mask_reset),
737077f6828SYann Gautier LDO_BUCK_RESET_MASK <<
738077f6828SYann Gautier regul->mask_reset);
739077f6828SYann Gautier }
740077f6828SYann Gautier
stpmic1_regulator_icc_set(const char * name)741*ea552bf5SPascal Paillet int stpmic1_regulator_icc_set(const char *name)
742*ea552bf5SPascal Paillet {
743*ea552bf5SPascal Paillet const struct regul_struct *regul = get_regulator_data(name);
744*ea552bf5SPascal Paillet
745*ea552bf5SPascal Paillet if (regul->mask_reset_reg == 0U) {
746*ea552bf5SPascal Paillet return -EPERM;
747*ea552bf5SPascal Paillet }
748*ea552bf5SPascal Paillet
749*ea552bf5SPascal Paillet return stpmic1_register_update(regul->icc_reg,
750*ea552bf5SPascal Paillet BIT(regul->icc_mask),
751*ea552bf5SPascal Paillet BIT(regul->icc_mask));
752*ea552bf5SPascal Paillet }
753*ea552bf5SPascal Paillet
stpmic1_regulator_sink_mode_set(const char * name)754*ea552bf5SPascal Paillet int stpmic1_regulator_sink_mode_set(const char *name)
755*ea552bf5SPascal Paillet {
756*ea552bf5SPascal Paillet if (strncmp(name, "ldo3", 5) != 0) {
757*ea552bf5SPascal Paillet return -EPERM;
758*ea552bf5SPascal Paillet }
759*ea552bf5SPascal Paillet
760*ea552bf5SPascal Paillet ldo3_special_mode = true;
761*ea552bf5SPascal Paillet
762*ea552bf5SPascal Paillet /* disable bypass mode, enable sink mode */
763*ea552bf5SPascal Paillet return stpmic1_register_update(LDO3_CONTROL_REG,
764*ea552bf5SPascal Paillet LDO3_DDR_SEL << LDO_BUCK_VOLTAGE_SHIFT,
765*ea552bf5SPascal Paillet LDO3_BYPASS | LDO_VOLTAGE_MASK);
766*ea552bf5SPascal Paillet }
767*ea552bf5SPascal Paillet
stpmic1_regulator_bypass_mode_set(const char * name)768*ea552bf5SPascal Paillet int stpmic1_regulator_bypass_mode_set(const char *name)
769*ea552bf5SPascal Paillet {
770*ea552bf5SPascal Paillet if (strncmp(name, "ldo3", 5) != 0) {
771*ea552bf5SPascal Paillet return -EPERM;
772*ea552bf5SPascal Paillet }
773*ea552bf5SPascal Paillet
774*ea552bf5SPascal Paillet ldo3_special_mode = true;
775*ea552bf5SPascal Paillet
776*ea552bf5SPascal Paillet /* enable bypass mode, disable sink mode */
777*ea552bf5SPascal Paillet return stpmic1_register_update(LDO3_CONTROL_REG,
778*ea552bf5SPascal Paillet LDO3_BYPASS,
779*ea552bf5SPascal Paillet LDO3_BYPASS | LDO_VOLTAGE_MASK);
780*ea552bf5SPascal Paillet }
781*ea552bf5SPascal Paillet
stpmic1_active_discharge_mode_set(const char * name)782*ea552bf5SPascal Paillet int stpmic1_active_discharge_mode_set(const char *name)
783*ea552bf5SPascal Paillet {
784*ea552bf5SPascal Paillet if (strncmp(name, "pwr_sw1", 8) == 0) {
785*ea552bf5SPascal Paillet return stpmic1_register_update(USB_CONTROL_REG,
786*ea552bf5SPascal Paillet VBUS_OTG_DISCHARGE,
787*ea552bf5SPascal Paillet VBUS_OTG_DISCHARGE);
788*ea552bf5SPascal Paillet }
789*ea552bf5SPascal Paillet
790*ea552bf5SPascal Paillet if (strncmp(name, "pwr_sw2", 8) == 0) {
791*ea552bf5SPascal Paillet return stpmic1_register_update(USB_CONTROL_REG,
792*ea552bf5SPascal Paillet SW_OUT_DISCHARGE,
793*ea552bf5SPascal Paillet SW_OUT_DISCHARGE);
794*ea552bf5SPascal Paillet }
795*ea552bf5SPascal Paillet
796*ea552bf5SPascal Paillet return -EPERM;
797*ea552bf5SPascal Paillet }
798*ea552bf5SPascal Paillet
stpmic1_regulator_levels_mv(const char * name,const uint16_t ** levels,size_t * levels_count)799*ea552bf5SPascal Paillet int stpmic1_regulator_levels_mv(const char *name, const uint16_t **levels,
800*ea552bf5SPascal Paillet size_t *levels_count)
801*ea552bf5SPascal Paillet {
802*ea552bf5SPascal Paillet const struct regul_struct *regul = get_regulator_data(name);
803*ea552bf5SPascal Paillet
804*ea552bf5SPascal Paillet if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
805*ea552bf5SPascal Paillet *levels_count = ARRAY_SIZE(ldo3_special_mode_table);
806*ea552bf5SPascal Paillet *levels = ldo3_special_mode_table;
807*ea552bf5SPascal Paillet } else {
808*ea552bf5SPascal Paillet *levels_count = regul->voltage_table_size;
809*ea552bf5SPascal Paillet *levels = regul->voltage_table;
810*ea552bf5SPascal Paillet }
811*ea552bf5SPascal Paillet
812*ea552bf5SPascal Paillet return 0;
813*ea552bf5SPascal Paillet }
814*ea552bf5SPascal Paillet
stpmic1_regulator_voltage_get(const char * name)815077f6828SYann Gautier int stpmic1_regulator_voltage_get(const char *name)
816077f6828SYann Gautier {
817077f6828SYann Gautier const struct regul_struct *regul = get_regulator_data(name);
818077f6828SYann Gautier uint8_t value;
819077f6828SYann Gautier uint8_t mask;
820ed6a8523SYann Gautier int status;
821077f6828SYann Gautier
822*ea552bf5SPascal Paillet if ((strncmp(name, "ldo3", 5) == 0) && ldo3_special_mode) {
823*ea552bf5SPascal Paillet return 0;
824*ea552bf5SPascal Paillet }
825*ea552bf5SPascal Paillet
826077f6828SYann Gautier /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
827077f6828SYann Gautier if (strncmp(name, "buck", 4) == 0) {
828077f6828SYann Gautier mask = BUCK_VOLTAGE_MASK;
829077f6828SYann Gautier } else if ((strncmp(name, "ldo", 3) == 0) &&
830*ea552bf5SPascal Paillet (strncmp(name, "ldo4", 5) != 0)) {
831077f6828SYann Gautier mask = LDO_VOLTAGE_MASK;
832077f6828SYann Gautier } else {
833077f6828SYann Gautier return 0;
834077f6828SYann Gautier }
835077f6828SYann Gautier
836ed6a8523SYann Gautier status = stpmic1_register_read(regul->control_reg, &value);
837ed6a8523SYann Gautier if (status < 0) {
838ed6a8523SYann Gautier return status;
839ed6a8523SYann Gautier }
840077f6828SYann Gautier
841077f6828SYann Gautier value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
842077f6828SYann Gautier
843ed6a8523SYann Gautier if (value > regul->voltage_table_size) {
844ed6a8523SYann Gautier return -ERANGE;
845ed6a8523SYann Gautier }
846077f6828SYann Gautier
847077f6828SYann Gautier return (int)regul->voltage_table[value];
84823684d0eSYann Gautier }
84923684d0eSYann Gautier
stpmic1_register_read(uint8_t register_id,uint8_t * value)85023684d0eSYann Gautier int stpmic1_register_read(uint8_t register_id, uint8_t *value)
85123684d0eSYann Gautier {
85223684d0eSYann Gautier return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
853d82d4ff0SYann Gautier (uint16_t)register_id,
854d82d4ff0SYann Gautier I2C_MEMADD_SIZE_8BIT, value,
855d82d4ff0SYann Gautier 1, I2C_TIMEOUT_MS);
85623684d0eSYann Gautier }
85723684d0eSYann Gautier
stpmic1_register_write(uint8_t register_id,uint8_t value)85823684d0eSYann Gautier int stpmic1_register_write(uint8_t register_id, uint8_t value)
85923684d0eSYann Gautier {
86023684d0eSYann Gautier int status;
86123684d0eSYann Gautier
86223684d0eSYann Gautier status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
86323684d0eSYann Gautier (uint16_t)register_id,
864d82d4ff0SYann Gautier I2C_MEMADD_SIZE_8BIT, &value,
865d82d4ff0SYann Gautier 1, I2C_TIMEOUT_MS);
86623684d0eSYann Gautier
867077f6828SYann Gautier #if ENABLE_ASSERTIONS
86823684d0eSYann Gautier if (status != 0) {
86923684d0eSYann Gautier return status;
87023684d0eSYann Gautier }
87123684d0eSYann Gautier
87223684d0eSYann Gautier if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
87323684d0eSYann Gautier uint8_t readval;
87423684d0eSYann Gautier
87523684d0eSYann Gautier status = stpmic1_register_read(register_id, &readval);
87623684d0eSYann Gautier if (status != 0) {
87723684d0eSYann Gautier return status;
87823684d0eSYann Gautier }
87923684d0eSYann Gautier
88023684d0eSYann Gautier if (readval != value) {
881ed6a8523SYann Gautier return -EIO;
88223684d0eSYann Gautier }
88323684d0eSYann Gautier }
884077f6828SYann Gautier #endif
88523684d0eSYann Gautier
886077f6828SYann Gautier return status;
88723684d0eSYann Gautier }
88823684d0eSYann Gautier
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)88923684d0eSYann Gautier int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
89023684d0eSYann Gautier {
89123684d0eSYann Gautier int status;
89223684d0eSYann Gautier uint8_t val;
89323684d0eSYann Gautier
89423684d0eSYann Gautier status = stpmic1_register_read(register_id, &val);
89523684d0eSYann Gautier if (status != 0) {
89623684d0eSYann Gautier return status;
89723684d0eSYann Gautier }
89823684d0eSYann Gautier
899077f6828SYann Gautier val = (val & ~mask) | (value & mask);
90023684d0eSYann Gautier
90123684d0eSYann Gautier return stpmic1_register_write(register_id, val);
90223684d0eSYann Gautier }
90323684d0eSYann Gautier
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)90423684d0eSYann Gautier void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
90523684d0eSYann Gautier {
90623684d0eSYann Gautier pmic_i2c_handle = i2c_handle;
90723684d0eSYann Gautier pmic_i2c_addr = i2c_addr;
90823684d0eSYann Gautier }
909077f6828SYann Gautier
stpmic1_dump_regulators(void)910077f6828SYann Gautier void stpmic1_dump_regulators(void)
911077f6828SYann Gautier {
912077f6828SYann Gautier uint32_t i;
913077f6828SYann Gautier
914077f6828SYann Gautier for (i = 0U; i < MAX_REGUL; i++) {
915077f6828SYann Gautier const char *name __unused = regulators_table[i].dt_node_name;
916077f6828SYann Gautier
917077f6828SYann Gautier VERBOSE("PMIC regul %s: %sable, %dmV",
918077f6828SYann Gautier name,
919077f6828SYann Gautier stpmic1_is_regulator_enabled(name) ? "en" : "dis",
920077f6828SYann Gautier stpmic1_regulator_voltage_get(name));
921077f6828SYann Gautier }
922077f6828SYann Gautier }
923077f6828SYann Gautier
stpmic1_get_version(unsigned long * version)924077f6828SYann Gautier int stpmic1_get_version(unsigned long *version)
925077f6828SYann Gautier {
926077f6828SYann Gautier uint8_t read_val;
927ed6a8523SYann Gautier int status;
928077f6828SYann Gautier
929ed6a8523SYann Gautier status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
930ed6a8523SYann Gautier if (status < 0) {
931ed6a8523SYann Gautier return status;
932077f6828SYann Gautier }
933077f6828SYann Gautier
934077f6828SYann Gautier *version = (unsigned long)read_val;
935077f6828SYann Gautier
936077f6828SYann Gautier return 0;
937077f6828SYann Gautier }
938