1*817f42f0SPascal Paillet /*
2*817f42f0SPascal Paillet * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
3*817f42f0SPascal Paillet *
4*817f42f0SPascal Paillet * SPDX-License-Identifier: BSD-3-Clause
5*817f42f0SPascal Paillet */
6*817f42f0SPascal Paillet
7*817f42f0SPascal Paillet #include <assert.h>
8*817f42f0SPascal Paillet #include <errno.h>
9*817f42f0SPascal Paillet
10*817f42f0SPascal Paillet #include <common/debug.h>
11*817f42f0SPascal Paillet #include <drivers/delay_timer.h>
12*817f42f0SPascal Paillet #include <drivers/st/regulator.h>
13*817f42f0SPascal Paillet #include <drivers/st/stm32_i2c.h>
14*817f42f0SPascal Paillet #include <drivers/st/stm32mp_pmic2.h>
15*817f42f0SPascal Paillet #include <drivers/st/stpmic2.h>
16*817f42f0SPascal Paillet #include <lib/mmio.h>
17*817f42f0SPascal Paillet #include <lib/spinlock.h>
18*817f42f0SPascal Paillet #include <lib/utils_def.h>
19*817f42f0SPascal Paillet #include <libfdt.h>
20*817f42f0SPascal Paillet
21*817f42f0SPascal Paillet #include <platform_def.h>
22*817f42f0SPascal Paillet
23*817f42f0SPascal Paillet #define PMIC_NODE_NOT_FOUND 1
24*817f42f0SPascal Paillet
25*817f42f0SPascal Paillet struct regul_handle_s {
26*817f42f0SPascal Paillet const uint32_t id;
27*817f42f0SPascal Paillet uint16_t bypass_mv;
28*817f42f0SPascal Paillet };
29*817f42f0SPascal Paillet
30*817f42f0SPascal Paillet static struct pmic_handle_s pmic2_handle;
31*817f42f0SPascal Paillet static struct i2c_handle_s i2c_handle;
32*817f42f0SPascal Paillet
33*817f42f0SPascal Paillet /* This driver is monoinstance */
34*817f42f0SPascal Paillet static struct pmic_handle_s *pmic2;
35*817f42f0SPascal Paillet
dt_get_pmic_node(void * fdt)36*817f42f0SPascal Paillet static int dt_get_pmic_node(void *fdt)
37*817f42f0SPascal Paillet {
38*817f42f0SPascal Paillet static int node = -FDT_ERR_BADOFFSET;
39*817f42f0SPascal Paillet
40*817f42f0SPascal Paillet if (node == -FDT_ERR_BADOFFSET) {
41*817f42f0SPascal Paillet node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic2");
42*817f42f0SPascal Paillet }
43*817f42f0SPascal Paillet
44*817f42f0SPascal Paillet return node;
45*817f42f0SPascal Paillet }
46*817f42f0SPascal Paillet
dt_pmic_status(void)47*817f42f0SPascal Paillet int dt_pmic_status(void)
48*817f42f0SPascal Paillet {
49*817f42f0SPascal Paillet static int status = -FDT_ERR_BADVALUE;
50*817f42f0SPascal Paillet int node;
51*817f42f0SPascal Paillet void *fdt;
52*817f42f0SPascal Paillet
53*817f42f0SPascal Paillet if (status != -FDT_ERR_BADVALUE) {
54*817f42f0SPascal Paillet return status;
55*817f42f0SPascal Paillet }
56*817f42f0SPascal Paillet
57*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) {
58*817f42f0SPascal Paillet return -ENOENT;
59*817f42f0SPascal Paillet }
60*817f42f0SPascal Paillet
61*817f42f0SPascal Paillet node = dt_get_pmic_node(fdt);
62*817f42f0SPascal Paillet if (node <= 0) {
63*817f42f0SPascal Paillet status = -FDT_ERR_NOTFOUND;
64*817f42f0SPascal Paillet
65*817f42f0SPascal Paillet return status;
66*817f42f0SPascal Paillet }
67*817f42f0SPascal Paillet
68*817f42f0SPascal Paillet status = DT_SECURE;
69*817f42f0SPascal Paillet
70*817f42f0SPascal Paillet return status;
71*817f42f0SPascal Paillet }
72*817f42f0SPascal Paillet
73*817f42f0SPascal Paillet /*
74*817f42f0SPascal Paillet * Get PMIC and its I2C bus configuration from the device tree.
75*817f42f0SPascal Paillet * Return 0 on success, negative on error, 1 if no PMIC node is defined.
76*817f42f0SPascal Paillet */
dt_pmic2_i2c_config(struct dt_node_info * i2c_info,struct stm32_i2c_init_s * init,uint32_t * i2c_addr)77*817f42f0SPascal Paillet static int dt_pmic2_i2c_config(struct dt_node_info *i2c_info,
78*817f42f0SPascal Paillet struct stm32_i2c_init_s *init,
79*817f42f0SPascal Paillet uint32_t *i2c_addr)
80*817f42f0SPascal Paillet {
81*817f42f0SPascal Paillet static int i2c_node = -FDT_ERR_NOTFOUND;
82*817f42f0SPascal Paillet void *fdt;
83*817f42f0SPascal Paillet
84*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) {
85*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND;
86*817f42f0SPascal Paillet }
87*817f42f0SPascal Paillet
88*817f42f0SPascal Paillet if (i2c_node == -FDT_ERR_NOTFOUND) {
89*817f42f0SPascal Paillet int pmic_node;
90*817f42f0SPascal Paillet const fdt32_t *cuint;
91*817f42f0SPascal Paillet
92*817f42f0SPascal Paillet pmic_node = dt_get_pmic_node(fdt);
93*817f42f0SPascal Paillet if (pmic_node < 0) {
94*817f42f0SPascal Paillet return PMIC_NODE_NOT_FOUND;
95*817f42f0SPascal Paillet }
96*817f42f0SPascal Paillet
97*817f42f0SPascal Paillet cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
98*817f42f0SPascal Paillet if (cuint == NULL) {
99*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND;
100*817f42f0SPascal Paillet }
101*817f42f0SPascal Paillet
102*817f42f0SPascal Paillet *i2c_addr = fdt32_to_cpu(*cuint) << 1;
103*817f42f0SPascal Paillet if (*i2c_addr > UINT16_MAX) {
104*817f42f0SPascal Paillet return -FDT_ERR_BADVALUE;
105*817f42f0SPascal Paillet }
106*817f42f0SPascal Paillet
107*817f42f0SPascal Paillet i2c_node = fdt_parent_offset(fdt, pmic_node);
108*817f42f0SPascal Paillet if (i2c_node < 0) {
109*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND;
110*817f42f0SPascal Paillet }
111*817f42f0SPascal Paillet }
112*817f42f0SPascal Paillet
113*817f42f0SPascal Paillet dt_fill_device_info(i2c_info, i2c_node);
114*817f42f0SPascal Paillet if (i2c_info->base == 0U) {
115*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND;
116*817f42f0SPascal Paillet }
117*817f42f0SPascal Paillet
118*817f42f0SPascal Paillet i2c_info->status = DT_SECURE;
119*817f42f0SPascal Paillet
120*817f42f0SPascal Paillet return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init);
121*817f42f0SPascal Paillet }
122*817f42f0SPascal Paillet
initialize_pmic_i2c(void)123*817f42f0SPascal Paillet bool initialize_pmic_i2c(void)
124*817f42f0SPascal Paillet {
125*817f42f0SPascal Paillet int ret;
126*817f42f0SPascal Paillet struct dt_node_info i2c_info;
127*817f42f0SPascal Paillet struct i2c_handle_s *i2c = &i2c_handle;
128*817f42f0SPascal Paillet uint32_t i2c_addr = 0U;
129*817f42f0SPascal Paillet struct stm32_i2c_init_s i2c_init;
130*817f42f0SPascal Paillet
131*817f42f0SPascal Paillet ret = dt_pmic2_i2c_config(&i2c_info, &i2c_init, &i2c_addr);
132*817f42f0SPascal Paillet if (ret < 0) {
133*817f42f0SPascal Paillet ERROR("I2C configuration failed %d\n", ret);
134*817f42f0SPascal Paillet panic();
135*817f42f0SPascal Paillet }
136*817f42f0SPascal Paillet
137*817f42f0SPascal Paillet if (ret != 0) {
138*817f42f0SPascal Paillet return false;
139*817f42f0SPascal Paillet }
140*817f42f0SPascal Paillet
141*817f42f0SPascal Paillet /* Initialize PMIC I2C */
142*817f42f0SPascal Paillet i2c->i2c_base_addr = i2c_info.base;
143*817f42f0SPascal Paillet i2c->dt_status = i2c_info.status;
144*817f42f0SPascal Paillet i2c->clock = i2c_info.clock;
145*817f42f0SPascal Paillet i2c->i2c_state = I2C_STATE_RESET;
146*817f42f0SPascal Paillet i2c_init.own_address1 = i2c_addr;
147*817f42f0SPascal Paillet i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT;
148*817f42f0SPascal Paillet i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE;
149*817f42f0SPascal Paillet i2c_init.own_address2 = 0;
150*817f42f0SPascal Paillet i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK;
151*817f42f0SPascal Paillet i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE;
152*817f42f0SPascal Paillet i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE;
153*817f42f0SPascal Paillet i2c_init.analog_filter = 1;
154*817f42f0SPascal Paillet i2c_init.digital_filter_coef = 0;
155*817f42f0SPascal Paillet
156*817f42f0SPascal Paillet ret = stm32_i2c_init(i2c, &i2c_init);
157*817f42f0SPascal Paillet if (ret != 0) {
158*817f42f0SPascal Paillet ERROR("Cannot initialize I2C %x (%d)\n",
159*817f42f0SPascal Paillet i2c->i2c_base_addr, ret);
160*817f42f0SPascal Paillet panic();
161*817f42f0SPascal Paillet }
162*817f42f0SPascal Paillet
163*817f42f0SPascal Paillet if (!stm32_i2c_is_device_ready(i2c, i2c_addr, 1,
164*817f42f0SPascal Paillet I2C_TIMEOUT_BUSY_MS)) {
165*817f42f0SPascal Paillet ERROR("I2C device not ready\n");
166*817f42f0SPascal Paillet panic();
167*817f42f0SPascal Paillet }
168*817f42f0SPascal Paillet
169*817f42f0SPascal Paillet pmic2 = &pmic2_handle;
170*817f42f0SPascal Paillet pmic2->i2c_handle = &i2c_handle;
171*817f42f0SPascal Paillet pmic2->i2c_addr = i2c_addr;
172*817f42f0SPascal Paillet
173*817f42f0SPascal Paillet return true;
174*817f42f0SPascal Paillet }
175*817f42f0SPascal Paillet
pmic2_set_state(const struct regul_description * desc,bool enable)176*817f42f0SPascal Paillet static int pmic2_set_state(const struct regul_description *desc, bool enable)
177*817f42f0SPascal Paillet {
178*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
179*817f42f0SPascal Paillet
180*817f42f0SPascal Paillet VERBOSE("%s: set state to %d\n", desc->node_name, enable);
181*817f42f0SPascal Paillet
182*817f42f0SPascal Paillet return stpmic2_regulator_set_state(pmic2, regul->id, enable);
183*817f42f0SPascal Paillet }
184*817f42f0SPascal Paillet
pmic2_get_state(const struct regul_description * desc)185*817f42f0SPascal Paillet static int pmic2_get_state(const struct regul_description *desc)
186*817f42f0SPascal Paillet {
187*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
188*817f42f0SPascal Paillet bool enabled;
189*817f42f0SPascal Paillet
190*817f42f0SPascal Paillet VERBOSE("%s: get state\n", desc->node_name);
191*817f42f0SPascal Paillet
192*817f42f0SPascal Paillet if (stpmic2_regulator_get_state(pmic2, regul->id, &enabled) < 0) {
193*817f42f0SPascal Paillet panic();
194*817f42f0SPascal Paillet }
195*817f42f0SPascal Paillet
196*817f42f0SPascal Paillet return enabled;
197*817f42f0SPascal Paillet }
198*817f42f0SPascal Paillet
pmic2_get_voltage(const struct regul_description * desc)199*817f42f0SPascal Paillet static int pmic2_get_voltage(const struct regul_description *desc)
200*817f42f0SPascal Paillet {
201*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
202*817f42f0SPascal Paillet uint16_t mv;
203*817f42f0SPascal Paillet
204*817f42f0SPascal Paillet VERBOSE("%s: get volt\n", desc->node_name);
205*817f42f0SPascal Paillet
206*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) {
207*817f42f0SPascal Paillet int ret;
208*817f42f0SPascal Paillet
209*817f42f0SPascal Paillet /* If the regul is in bypass mode, return bypass value */
210*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
211*817f42f0SPascal Paillet if (ret < 0) {
212*817f42f0SPascal Paillet return ret;
213*817f42f0SPascal Paillet }
214*817f42f0SPascal Paillet
215*817f42f0SPascal Paillet if (ret == 1) {
216*817f42f0SPascal Paillet return regul->bypass_mv;
217*817f42f0SPascal Paillet }
218*817f42f0SPascal Paillet };
219*817f42f0SPascal Paillet
220*817f42f0SPascal Paillet if (stpmic2_regulator_get_voltage(pmic2, regul->id, &mv) < 0) {
221*817f42f0SPascal Paillet panic();
222*817f42f0SPascal Paillet }
223*817f42f0SPascal Paillet
224*817f42f0SPascal Paillet return mv;
225*817f42f0SPascal Paillet }
226*817f42f0SPascal Paillet
pmic2_set_voltage(const struct regul_description * desc,uint16_t mv)227*817f42f0SPascal Paillet static int pmic2_set_voltage(const struct regul_description *desc, uint16_t mv)
228*817f42f0SPascal Paillet {
229*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
230*817f42f0SPascal Paillet
231*817f42f0SPascal Paillet VERBOSE("%s: set volt\n", desc->node_name);
232*817f42f0SPascal Paillet
233*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) {
234*817f42f0SPascal Paillet int ret;
235*817f42f0SPascal Paillet
236*817f42f0SPascal Paillet /* If the regul is in bypass mode, authorize bypass mV */
237*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
238*817f42f0SPascal Paillet if (ret < 0) {
239*817f42f0SPascal Paillet return ret;
240*817f42f0SPascal Paillet }
241*817f42f0SPascal Paillet
242*817f42f0SPascal Paillet if ((ret == 1) && (mv != regul->bypass_mv)) {
243*817f42f0SPascal Paillet return -EPERM;
244*817f42f0SPascal Paillet }
245*817f42f0SPascal Paillet };
246*817f42f0SPascal Paillet
247*817f42f0SPascal Paillet return stpmic2_regulator_set_voltage(pmic2, regul->id, mv);
248*817f42f0SPascal Paillet }
249*817f42f0SPascal Paillet
pmic2_list_voltages(const struct regul_description * desc,const uint16_t ** levels,size_t * count)250*817f42f0SPascal Paillet static int pmic2_list_voltages(const struct regul_description *desc,
251*817f42f0SPascal Paillet const uint16_t **levels, size_t *count)
252*817f42f0SPascal Paillet {
253*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
254*817f42f0SPascal Paillet
255*817f42f0SPascal Paillet VERBOSE("%s: list volt\n", desc->node_name);
256*817f42f0SPascal Paillet
257*817f42f0SPascal Paillet if (regul->bypass_mv != 0U) {
258*817f42f0SPascal Paillet int ret;
259*817f42f0SPascal Paillet
260*817f42f0SPascal Paillet ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
261*817f42f0SPascal Paillet if (ret < 0) {
262*817f42f0SPascal Paillet return ret;
263*817f42f0SPascal Paillet }
264*817f42f0SPascal Paillet
265*817f42f0SPascal Paillet /* bypass is enabled, return a list with only bypass mV */
266*817f42f0SPascal Paillet if (ret == 1) {
267*817f42f0SPascal Paillet if (count != NULL) {
268*817f42f0SPascal Paillet *count = 1U;
269*817f42f0SPascal Paillet }
270*817f42f0SPascal Paillet if (levels != NULL) {
271*817f42f0SPascal Paillet *levels = ®ul->bypass_mv;
272*817f42f0SPascal Paillet }
273*817f42f0SPascal Paillet return 0;
274*817f42f0SPascal Paillet }
275*817f42f0SPascal Paillet };
276*817f42f0SPascal Paillet
277*817f42f0SPascal Paillet return stpmic2_regulator_levels_mv(pmic2, regul->id, levels, count);
278*817f42f0SPascal Paillet }
279*817f42f0SPascal Paillet
pmic2_set_flag(const struct regul_description * desc,uint16_t flag)280*817f42f0SPascal Paillet static int pmic2_set_flag(const struct regul_description *desc, uint16_t flag)
281*817f42f0SPascal Paillet {
282*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
283*817f42f0SPascal Paillet uint32_t id = regul->id;
284*817f42f0SPascal Paillet int ret = -EPERM;
285*817f42f0SPascal Paillet
286*817f42f0SPascal Paillet VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag);
287*817f42f0SPascal Paillet
288*817f42f0SPascal Paillet switch (flag) {
289*817f42f0SPascal Paillet case REGUL_PULL_DOWN:
290*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_PULL_DOWN, 1U);
291*817f42f0SPascal Paillet break;
292*817f42f0SPascal Paillet case REGUL_OCP:
293*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_OCP, 1U);
294*817f42f0SPascal Paillet break;
295*817f42f0SPascal Paillet case REGUL_SINK_SOURCE:
296*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_SINK_SOURCE, 1U);
297*817f42f0SPascal Paillet break;
298*817f42f0SPascal Paillet case REGUL_ENABLE_BYPASS:
299*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_BYPASS, 1U);
300*817f42f0SPascal Paillet break;
301*817f42f0SPascal Paillet case REGUL_MASK_RESET:
302*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_MASK_RESET, 1U);
303*817f42f0SPascal Paillet break;
304*817f42f0SPascal Paillet default:
305*817f42f0SPascal Paillet ERROR("Invalid flag %u", flag);
306*817f42f0SPascal Paillet panic();
307*817f42f0SPascal Paillet }
308*817f42f0SPascal Paillet
309*817f42f0SPascal Paillet if (ret != 0) {
310*817f42f0SPascal Paillet return -EPERM;
311*817f42f0SPascal Paillet }
312*817f42f0SPascal Paillet
313*817f42f0SPascal Paillet return 0;
314*817f42f0SPascal Paillet }
315*817f42f0SPascal Paillet
stpmic2_set_prop(const struct regul_description * desc,uint16_t prop,uint32_t value)316*817f42f0SPascal Paillet int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value)
317*817f42f0SPascal Paillet {
318*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
319*817f42f0SPascal Paillet int ret;
320*817f42f0SPascal Paillet
321*817f42f0SPascal Paillet VERBOSE("%s: set_prop 0x%x val=%u\n", desc->node_name, prop, value);
322*817f42f0SPascal Paillet
323*817f42f0SPascal Paillet ret = stpmic2_regulator_set_prop(pmic2, regul->id, prop, value);
324*817f42f0SPascal Paillet if (ret != 0)
325*817f42f0SPascal Paillet return -EPERM;
326*817f42f0SPascal Paillet
327*817f42f0SPascal Paillet return 0;
328*817f42f0SPascal Paillet }
329*817f42f0SPascal Paillet
330*817f42f0SPascal Paillet static struct regul_ops pmic2_ops = {
331*817f42f0SPascal Paillet .set_state = pmic2_set_state,
332*817f42f0SPascal Paillet .get_state = pmic2_get_state,
333*817f42f0SPascal Paillet .set_voltage = pmic2_set_voltage,
334*817f42f0SPascal Paillet .get_voltage = pmic2_get_voltage,
335*817f42f0SPascal Paillet .list_voltages = pmic2_list_voltages,
336*817f42f0SPascal Paillet .set_flag = pmic2_set_flag,
337*817f42f0SPascal Paillet };
338*817f42f0SPascal Paillet
339*817f42f0SPascal Paillet #define DEFINE_PMIC_REGUL_HANDLE(rid) \
340*817f42f0SPascal Paillet [(rid)] = { \
341*817f42f0SPascal Paillet .id = (rid), \
342*817f42f0SPascal Paillet }
343*817f42f0SPascal Paillet
344*817f42f0SPascal Paillet static struct regul_handle_s pmic2_regul_handles[STPMIC2_NB_REG] = {
345*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK1),
346*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK2),
347*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK3),
348*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK4),
349*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK5),
350*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK6),
351*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK7),
352*817f42f0SPascal Paillet
353*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO1),
354*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO2),
355*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO3),
356*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO4),
357*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO5),
358*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO6),
359*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO7),
360*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO8),
361*817f42f0SPascal Paillet
362*817f42f0SPascal Paillet DEFINE_PMIC_REGUL_HANDLE(STPMIC2_REFDDR),
363*817f42f0SPascal Paillet };
364*817f42f0SPascal Paillet
365*817f42f0SPascal Paillet #define DEFINE_REGUL(rid, name) \
366*817f42f0SPascal Paillet [rid] = { \
367*817f42f0SPascal Paillet .node_name = name, \
368*817f42f0SPascal Paillet .ops = &pmic2_ops, \
369*817f42f0SPascal Paillet .driver_data = &pmic2_regul_handles[rid], \
370*817f42f0SPascal Paillet }
371*817f42f0SPascal Paillet
372*817f42f0SPascal Paillet static const struct regul_description pmic2_descs[STPMIC2_NB_REG] = {
373*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK1, "buck1"),
374*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK2, "buck2"),
375*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK3, "buck3"),
376*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK4, "buck4"),
377*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK5, "buck5"),
378*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK6, "buck6"),
379*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_BUCK7, "buck7"),
380*817f42f0SPascal Paillet
381*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO1, "ldo1"),
382*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO2, "ldo2"),
383*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO3, "ldo3"),
384*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO4, "ldo4"),
385*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO5, "ldo5"),
386*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO6, "ldo6"),
387*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO7, "ldo7"),
388*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_LDO8, "ldo8"),
389*817f42f0SPascal Paillet
390*817f42f0SPascal Paillet DEFINE_REGUL(STPMIC2_REFDDR, "refddr"),
391*817f42f0SPascal Paillet };
392*817f42f0SPascal Paillet
register_pmic2(void)393*817f42f0SPascal Paillet static int register_pmic2(void)
394*817f42f0SPascal Paillet {
395*817f42f0SPascal Paillet void *fdt;
396*817f42f0SPascal Paillet int pmic_node, regulators_node, subnode;
397*817f42f0SPascal Paillet
398*817f42f0SPascal Paillet VERBOSE("Register pmic2\n");
399*817f42f0SPascal Paillet
400*817f42f0SPascal Paillet if (fdt_get_address(&fdt) == 0) {
401*817f42f0SPascal Paillet return -FDT_ERR_NOTFOUND;
402*817f42f0SPascal Paillet }
403*817f42f0SPascal Paillet
404*817f42f0SPascal Paillet pmic_node = dt_get_pmic_node(fdt);
405*817f42f0SPascal Paillet if (pmic_node < 0) {
406*817f42f0SPascal Paillet return pmic_node;
407*817f42f0SPascal Paillet }
408*817f42f0SPascal Paillet
409*817f42f0SPascal Paillet regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
410*817f42f0SPascal Paillet if (regulators_node < 0) {
411*817f42f0SPascal Paillet return -ENOENT;
412*817f42f0SPascal Paillet }
413*817f42f0SPascal Paillet
414*817f42f0SPascal Paillet fdt_for_each_subnode(subnode, fdt, regulators_node) {
415*817f42f0SPascal Paillet const char *reg_name = fdt_get_name(fdt, subnode, NULL);
416*817f42f0SPascal Paillet const struct regul_description *desc;
417*817f42f0SPascal Paillet unsigned int i;
418*817f42f0SPascal Paillet int ret;
419*817f42f0SPascal Paillet const fdt32_t *cuint;
420*817f42f0SPascal Paillet
421*817f42f0SPascal Paillet for (i = 0; i < STPMIC2_NB_REG; i++) {
422*817f42f0SPascal Paillet desc = &pmic2_descs[i];
423*817f42f0SPascal Paillet if (strcmp(desc->node_name, reg_name) == 0) {
424*817f42f0SPascal Paillet break;
425*817f42f0SPascal Paillet }
426*817f42f0SPascal Paillet }
427*817f42f0SPascal Paillet assert(i < STPMIC2_NB_REG);
428*817f42f0SPascal Paillet
429*817f42f0SPascal Paillet ret = regulator_register(desc, subnode);
430*817f42f0SPascal Paillet if (ret != 0) {
431*817f42f0SPascal Paillet WARN("%s:%d failed to register %s\n", __func__,
432*817f42f0SPascal Paillet __LINE__, reg_name);
433*817f42f0SPascal Paillet return ret;
434*817f42f0SPascal Paillet }
435*817f42f0SPascal Paillet
436*817f42f0SPascal Paillet cuint = fdt_getprop(fdt, subnode, "st,regulator-bypass-microvolt", NULL);
437*817f42f0SPascal Paillet if (cuint != NULL) {
438*817f42f0SPascal Paillet struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
439*817f42f0SPascal Paillet
440*817f42f0SPascal Paillet regul->bypass_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
441*817f42f0SPascal Paillet VERBOSE("%s: bypass voltage=%umV\n", desc->node_name,
442*817f42f0SPascal Paillet regul->bypass_mv);
443*817f42f0SPascal Paillet }
444*817f42f0SPascal Paillet
445*817f42f0SPascal Paillet if (fdt_getprop(fdt, subnode, "st,mask-reset", NULL) != NULL) {
446*817f42f0SPascal Paillet VERBOSE("%s: set mask-reset\n", desc->node_name);
447*817f42f0SPascal Paillet ret = pmic2_set_flag(desc, REGUL_MASK_RESET);
448*817f42f0SPascal Paillet if (ret != 0) {
449*817f42f0SPascal Paillet ERROR("set mask-reset failed\n");
450*817f42f0SPascal Paillet return ret;
451*817f42f0SPascal Paillet }
452*817f42f0SPascal Paillet }
453*817f42f0SPascal Paillet
454*817f42f0SPascal Paillet if (fdt_getprop(fdt, subnode, "st,regulator-sink-source", NULL) != NULL) {
455*817f42f0SPascal Paillet VERBOSE("%s: set regulator-sink-source\n", desc->node_name);
456*817f42f0SPascal Paillet ret = pmic2_set_flag(desc, REGUL_SINK_SOURCE);
457*817f42f0SPascal Paillet if (ret != 0) {
458*817f42f0SPascal Paillet ERROR("set regulator-sink-source failed\n");
459*817f42f0SPascal Paillet return ret;
460*817f42f0SPascal Paillet }
461*817f42f0SPascal Paillet }
462*817f42f0SPascal Paillet }
463*817f42f0SPascal Paillet
464*817f42f0SPascal Paillet return 0;
465*817f42f0SPascal Paillet }
466*817f42f0SPascal Paillet
initialize_pmic(void)467*817f42f0SPascal Paillet void initialize_pmic(void)
468*817f42f0SPascal Paillet {
469*817f42f0SPascal Paillet int ret;
470*817f42f0SPascal Paillet uint8_t val;
471*817f42f0SPascal Paillet
472*817f42f0SPascal Paillet ret = initialize_pmic_i2c();
473*817f42f0SPascal Paillet if (!ret) {
474*817f42f0SPascal Paillet VERBOSE("No PMIC2\n");
475*817f42f0SPascal Paillet return;
476*817f42f0SPascal Paillet }
477*817f42f0SPascal Paillet
478*817f42f0SPascal Paillet if (stpmic2_get_version(pmic2, &val) != 0) {
479*817f42f0SPascal Paillet ERROR("Failed to access PMIC\n");
480*817f42f0SPascal Paillet panic();
481*817f42f0SPascal Paillet }
482*817f42f0SPascal Paillet INFO("PMIC2 version = 0x%02x\n", val);
483*817f42f0SPascal Paillet
484*817f42f0SPascal Paillet if (stpmic2_get_product_id(pmic2, &val) != 0) {
485*817f42f0SPascal Paillet ERROR("Failed to access PMIC\n");
486*817f42f0SPascal Paillet panic();
487*817f42f0SPascal Paillet }
488*817f42f0SPascal Paillet INFO("PMIC2 product ID = 0x%02x\n", val);
489*817f42f0SPascal Paillet
490*817f42f0SPascal Paillet ret = register_pmic2();
491*817f42f0SPascal Paillet if (ret < 0) {
492*817f42f0SPascal Paillet ERROR("Register pmic2 failed\n");
493*817f42f0SPascal Paillet panic();
494*817f42f0SPascal Paillet }
495*817f42f0SPascal Paillet
496*817f42f0SPascal Paillet stpmic2_dump_regulators(pmic2);
497*817f42f0SPascal Paillet }
498