xref: /rk3399_ARM-atf/drivers/st/pmic/stm32mp_pmic2.c (revision 314aa18a7918375ab019beefeee15a661376a4d8)
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 = &regul->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