xref: /optee_os/core/drivers/stpmic1.c (revision 6149e2d874c054814ca7e83e0a5834cd1c7fa47f)
1c7cf2933SEtienne Carriere // SPDX-License-Identifier: BSD-3-Clause
2c7cf2933SEtienne Carriere /*
368cfb83dSEtienne Carriere  * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
4c7cf2933SEtienne Carriere  */
5c7cf2933SEtienne Carriere 
6c7cf2933SEtienne Carriere #include <assert.h>
7c7cf2933SEtienne Carriere #include <drivers/stpmic1.h>
8c7cf2933SEtienne Carriere #include <kernel/panic.h>
9c7cf2933SEtienne Carriere #include <platform_config.h>
10c7cf2933SEtienne Carriere #include <stdint.h>
11c7cf2933SEtienne Carriere #include <string.h>
12c7cf2933SEtienne Carriere #include <trace.h>
1342032ea0SEtienne Carriere #include <util.h>
14c7cf2933SEtienne Carriere 
15c7cf2933SEtienne Carriere struct regul_struct {
16c7cf2933SEtienne Carriere 	const char *dt_node_name;
17c7cf2933SEtienne Carriere 	const uint16_t *voltage_table;
18c7cf2933SEtienne Carriere 	uint8_t voltage_table_size;
19c7cf2933SEtienne Carriere 	uint8_t control_reg;
20c7cf2933SEtienne Carriere 	uint8_t low_power_reg;
2168cfb83dSEtienne Carriere 	uint8_t enable_pos;
22c7cf2933SEtienne Carriere 	uint8_t pull_down_reg;
23c7cf2933SEtienne Carriere 	uint8_t pull_down_pos;
24c7cf2933SEtienne Carriere 	uint8_t mask_reset_reg;
25c7cf2933SEtienne Carriere 	uint8_t mask_reset_pos;
26c7cf2933SEtienne Carriere };
27c7cf2933SEtienne Carriere 
28c7cf2933SEtienne Carriere static struct i2c_handle_s *pmic_i2c_handle;
29c7cf2933SEtienne Carriere static uint16_t pmic_i2c_addr;
30c7cf2933SEtienne Carriere 
31c7cf2933SEtienne Carriere /* Voltage tables in mV */
32c7cf2933SEtienne Carriere static const uint16_t buck1_voltage_table[] = {
33c7cf2933SEtienne Carriere 	725,
34c7cf2933SEtienne Carriere 	725,
35c7cf2933SEtienne Carriere 	725,
36c7cf2933SEtienne Carriere 	725,
37c7cf2933SEtienne Carriere 	725,
38c7cf2933SEtienne Carriere 	725,
39c7cf2933SEtienne Carriere 	750,
40c7cf2933SEtienne Carriere 	775,
41c7cf2933SEtienne Carriere 	800,
42c7cf2933SEtienne Carriere 	825,
43c7cf2933SEtienne Carriere 	850,
44c7cf2933SEtienne Carriere 	875,
45c7cf2933SEtienne Carriere 	900,
46c7cf2933SEtienne Carriere 	925,
47c7cf2933SEtienne Carriere 	950,
48c7cf2933SEtienne Carriere 	975,
49c7cf2933SEtienne Carriere 	1000,
50c7cf2933SEtienne Carriere 	1025,
51c7cf2933SEtienne Carriere 	1050,
52c7cf2933SEtienne Carriere 	1075,
53c7cf2933SEtienne Carriere 	1100,
54c7cf2933SEtienne Carriere 	1125,
55c7cf2933SEtienne Carriere 	1150,
56c7cf2933SEtienne Carriere 	1175,
57c7cf2933SEtienne Carriere 	1200,
58c7cf2933SEtienne Carriere 	1225,
59c7cf2933SEtienne Carriere 	1250,
60c7cf2933SEtienne Carriere 	1275,
61c7cf2933SEtienne Carriere 	1300,
62c7cf2933SEtienne Carriere 	1325,
63c7cf2933SEtienne Carriere 	1350,
64c7cf2933SEtienne Carriere 	1375,
65c7cf2933SEtienne Carriere 	1400,
66c7cf2933SEtienne Carriere 	1425,
67c7cf2933SEtienne Carriere 	1450,
68c7cf2933SEtienne Carriere 	1475,
69c7cf2933SEtienne Carriere 	1500,
70c7cf2933SEtienne Carriere 	1500,
71c7cf2933SEtienne Carriere 	1500,
72c7cf2933SEtienne Carriere 	1500,
73c7cf2933SEtienne Carriere 	1500,
74c7cf2933SEtienne Carriere 	1500,
75c7cf2933SEtienne Carriere 	1500,
76c7cf2933SEtienne Carriere 	1500,
77c7cf2933SEtienne Carriere 	1500,
78c7cf2933SEtienne Carriere 	1500,
79c7cf2933SEtienne Carriere 	1500,
80c7cf2933SEtienne Carriere 	1500,
81c7cf2933SEtienne Carriere 	1500,
82c7cf2933SEtienne Carriere 	1500,
83c7cf2933SEtienne Carriere 	1500,
84c7cf2933SEtienne Carriere 	1500,
85c7cf2933SEtienne Carriere 	1500,
86c7cf2933SEtienne Carriere 	1500,
87c7cf2933SEtienne Carriere 	1500,
88c7cf2933SEtienne Carriere 	1500,
89c7cf2933SEtienne Carriere 	1500,
90c7cf2933SEtienne Carriere 	1500,
91c7cf2933SEtienne Carriere 	1500,
92c7cf2933SEtienne Carriere 	1500,
93c7cf2933SEtienne Carriere 	1500,
94c7cf2933SEtienne Carriere 	1500,
95c7cf2933SEtienne Carriere 	1500,
96c7cf2933SEtienne Carriere 	1500,
97c7cf2933SEtienne Carriere };
98c7cf2933SEtienne Carriere 
99c7cf2933SEtienne Carriere static const uint16_t buck2_voltage_table[] = {
100c7cf2933SEtienne Carriere 	1000,
101c7cf2933SEtienne Carriere 	1000,
102c7cf2933SEtienne Carriere 	1000,
103c7cf2933SEtienne Carriere 	1000,
104c7cf2933SEtienne Carriere 	1000,
105c7cf2933SEtienne Carriere 	1000,
106c7cf2933SEtienne Carriere 	1000,
107c7cf2933SEtienne Carriere 	1000,
108c7cf2933SEtienne Carriere 	1000,
109c7cf2933SEtienne Carriere 	1000,
110c7cf2933SEtienne Carriere 	1000,
111c7cf2933SEtienne Carriere 	1000,
112c7cf2933SEtienne Carriere 	1000,
113c7cf2933SEtienne Carriere 	1000,
114c7cf2933SEtienne Carriere 	1000,
115c7cf2933SEtienne Carriere 	1000,
116c7cf2933SEtienne Carriere 	1000,
117c7cf2933SEtienne Carriere 	1000,
118c7cf2933SEtienne Carriere 	1050,
119c7cf2933SEtienne Carriere 	1050,
120c7cf2933SEtienne Carriere 	1100,
121c7cf2933SEtienne Carriere 	1100,
122c7cf2933SEtienne Carriere 	1150,
123c7cf2933SEtienne Carriere 	1150,
124c7cf2933SEtienne Carriere 	1200,
125c7cf2933SEtienne Carriere 	1200,
126c7cf2933SEtienne Carriere 	1250,
127c7cf2933SEtienne Carriere 	1250,
128c7cf2933SEtienne Carriere 	1300,
129c7cf2933SEtienne Carriere 	1300,
130c7cf2933SEtienne Carriere 	1350,
131c7cf2933SEtienne Carriere 	1350,
132c7cf2933SEtienne Carriere 	1400,
133c7cf2933SEtienne Carriere 	1400,
134c7cf2933SEtienne Carriere 	1450,
135c7cf2933SEtienne Carriere 	1450,
136c7cf2933SEtienne Carriere 	1500,
137c7cf2933SEtienne Carriere };
138c7cf2933SEtienne Carriere 
139c7cf2933SEtienne Carriere static const uint16_t buck3_voltage_table[] = {
140c7cf2933SEtienne Carriere 	1000,
141c7cf2933SEtienne Carriere 	1000,
142c7cf2933SEtienne Carriere 	1000,
143c7cf2933SEtienne Carriere 	1000,
144c7cf2933SEtienne Carriere 	1000,
145c7cf2933SEtienne Carriere 	1000,
146c7cf2933SEtienne Carriere 	1000,
147c7cf2933SEtienne Carriere 	1000,
148c7cf2933SEtienne Carriere 	1000,
149c7cf2933SEtienne Carriere 	1000,
150c7cf2933SEtienne Carriere 	1000,
151c7cf2933SEtienne Carriere 	1000,
152c7cf2933SEtienne Carriere 	1000,
153c7cf2933SEtienne Carriere 	1000,
154c7cf2933SEtienne Carriere 	1000,
155c7cf2933SEtienne Carriere 	1000,
156c7cf2933SEtienne Carriere 	1000,
157c7cf2933SEtienne Carriere 	1000,
158c7cf2933SEtienne Carriere 	1000,
159c7cf2933SEtienne Carriere 	1000,
160c7cf2933SEtienne Carriere 	1100,
161c7cf2933SEtienne Carriere 	1100,
162c7cf2933SEtienne Carriere 	1100,
163c7cf2933SEtienne Carriere 	1100,
164c7cf2933SEtienne Carriere 	1200,
165c7cf2933SEtienne Carriere 	1200,
166c7cf2933SEtienne Carriere 	1200,
167c7cf2933SEtienne Carriere 	1200,
168c7cf2933SEtienne Carriere 	1300,
169c7cf2933SEtienne Carriere 	1300,
170c7cf2933SEtienne Carriere 	1300,
171c7cf2933SEtienne Carriere 	1300,
172c7cf2933SEtienne Carriere 	1400,
173c7cf2933SEtienne Carriere 	1400,
174c7cf2933SEtienne Carriere 	1400,
175c7cf2933SEtienne Carriere 	1400,
176c7cf2933SEtienne Carriere 	1500,
177c7cf2933SEtienne Carriere 	1600,
178c7cf2933SEtienne Carriere 	1700,
179c7cf2933SEtienne Carriere 	1800,
180c7cf2933SEtienne Carriere 	1900,
181c7cf2933SEtienne Carriere 	2000,
182c7cf2933SEtienne Carriere 	2100,
183c7cf2933SEtienne Carriere 	2200,
184c7cf2933SEtienne Carriere 	2300,
185c7cf2933SEtienne Carriere 	2400,
186c7cf2933SEtienne Carriere 	2500,
187c7cf2933SEtienne Carriere 	2600,
188c7cf2933SEtienne Carriere 	2700,
189c7cf2933SEtienne Carriere 	2800,
190c7cf2933SEtienne Carriere 	2900,
191c7cf2933SEtienne Carriere 	3000,
192c7cf2933SEtienne Carriere 	3100,
193c7cf2933SEtienne Carriere 	3200,
194c7cf2933SEtienne Carriere 	3300,
195c7cf2933SEtienne Carriere 	3400,
196c7cf2933SEtienne Carriere };
197c7cf2933SEtienne Carriere 
198c7cf2933SEtienne Carriere static const uint16_t buck4_voltage_table[] = {
199c7cf2933SEtienne Carriere 	600,
200c7cf2933SEtienne Carriere 	625,
201c7cf2933SEtienne Carriere 	650,
202c7cf2933SEtienne Carriere 	675,
203c7cf2933SEtienne Carriere 	700,
204c7cf2933SEtienne Carriere 	725,
205c7cf2933SEtienne Carriere 	750,
206c7cf2933SEtienne Carriere 	775,
207c7cf2933SEtienne Carriere 	800,
208c7cf2933SEtienne Carriere 	825,
209c7cf2933SEtienne Carriere 	850,
210c7cf2933SEtienne Carriere 	875,
211c7cf2933SEtienne Carriere 	900,
212c7cf2933SEtienne Carriere 	925,
213c7cf2933SEtienne Carriere 	950,
214c7cf2933SEtienne Carriere 	975,
215c7cf2933SEtienne Carriere 	1000,
216c7cf2933SEtienne Carriere 	1025,
217c7cf2933SEtienne Carriere 	1050,
218c7cf2933SEtienne Carriere 	1075,
219c7cf2933SEtienne Carriere 	1100,
220c7cf2933SEtienne Carriere 	1125,
221c7cf2933SEtienne Carriere 	1150,
222c7cf2933SEtienne Carriere 	1175,
223c7cf2933SEtienne Carriere 	1200,
224c7cf2933SEtienne Carriere 	1225,
225c7cf2933SEtienne Carriere 	1250,
226c7cf2933SEtienne Carriere 	1275,
227c7cf2933SEtienne Carriere 	1300,
228c7cf2933SEtienne Carriere 	1300,
229c7cf2933SEtienne Carriere 	1350,
230c7cf2933SEtienne Carriere 	1350,
231c7cf2933SEtienne Carriere 	1400,
232c7cf2933SEtienne Carriere 	1400,
233c7cf2933SEtienne Carriere 	1450,
234c7cf2933SEtienne Carriere 	1450,
235c7cf2933SEtienne Carriere 	1500,
236c7cf2933SEtienne Carriere 	1600,
237c7cf2933SEtienne Carriere 	1700,
238c7cf2933SEtienne Carriere 	1800,
239c7cf2933SEtienne Carriere 	1900,
240c7cf2933SEtienne Carriere 	2000,
241c7cf2933SEtienne Carriere 	2100,
242c7cf2933SEtienne Carriere 	2200,
243c7cf2933SEtienne Carriere 	2300,
244c7cf2933SEtienne Carriere 	2400,
245c7cf2933SEtienne Carriere 	2500,
246c7cf2933SEtienne Carriere 	2600,
247c7cf2933SEtienne Carriere 	2700,
248c7cf2933SEtienne Carriere 	2800,
249c7cf2933SEtienne Carriere 	2900,
250c7cf2933SEtienne Carriere 	3000,
251c7cf2933SEtienne Carriere 	3100,
252c7cf2933SEtienne Carriere 	3200,
253c7cf2933SEtienne Carriere 	3300,
254c7cf2933SEtienne Carriere 	3400,
255c7cf2933SEtienne Carriere 	3500,
256c7cf2933SEtienne Carriere 	3600,
257c7cf2933SEtienne Carriere 	3700,
258c7cf2933SEtienne Carriere 	3800,
259c7cf2933SEtienne Carriere 	3900,
260c7cf2933SEtienne Carriere };
261c7cf2933SEtienne Carriere 
262c7cf2933SEtienne Carriere static const uint16_t ldo1_voltage_table[] = {
263c7cf2933SEtienne Carriere 	1700,
264c7cf2933SEtienne Carriere 	1700,
265c7cf2933SEtienne Carriere 	1700,
266c7cf2933SEtienne Carriere 	1700,
267c7cf2933SEtienne Carriere 	1700,
268c7cf2933SEtienne Carriere 	1700,
269c7cf2933SEtienne Carriere 	1700,
270c7cf2933SEtienne Carriere 	1700,
271c7cf2933SEtienne Carriere 	1700,
272c7cf2933SEtienne Carriere 	1800,
273c7cf2933SEtienne Carriere 	1900,
274c7cf2933SEtienne Carriere 	2000,
275c7cf2933SEtienne Carriere 	2100,
276c7cf2933SEtienne Carriere 	2200,
277c7cf2933SEtienne Carriere 	2300,
278c7cf2933SEtienne Carriere 	2400,
279c7cf2933SEtienne Carriere 	2500,
280c7cf2933SEtienne Carriere 	2600,
281c7cf2933SEtienne Carriere 	2700,
282c7cf2933SEtienne Carriere 	2800,
283c7cf2933SEtienne Carriere 	2900,
284c7cf2933SEtienne Carriere 	3000,
285c7cf2933SEtienne Carriere 	3100,
286c7cf2933SEtienne Carriere 	3200,
287c7cf2933SEtienne Carriere 	3300,
288c7cf2933SEtienne Carriere };
289c7cf2933SEtienne Carriere 
290c7cf2933SEtienne Carriere static const uint16_t ldo2_voltage_table[] = {
291c7cf2933SEtienne Carriere 	1700,
292c7cf2933SEtienne Carriere 	1700,
293c7cf2933SEtienne Carriere 	1700,
294c7cf2933SEtienne Carriere 	1700,
295c7cf2933SEtienne Carriere 	1700,
296c7cf2933SEtienne Carriere 	1700,
297c7cf2933SEtienne Carriere 	1700,
298c7cf2933SEtienne Carriere 	1700,
299c7cf2933SEtienne Carriere 	1700,
300c7cf2933SEtienne Carriere 	1800,
301c7cf2933SEtienne Carriere 	1900,
302c7cf2933SEtienne Carriere 	2000,
303c7cf2933SEtienne Carriere 	2100,
304c7cf2933SEtienne Carriere 	2200,
305c7cf2933SEtienne Carriere 	2300,
306c7cf2933SEtienne Carriere 	2400,
307c7cf2933SEtienne Carriere 	2500,
308c7cf2933SEtienne Carriere 	2600,
309c7cf2933SEtienne Carriere 	2700,
310c7cf2933SEtienne Carriere 	2800,
311c7cf2933SEtienne Carriere 	2900,
312c7cf2933SEtienne Carriere 	3000,
313c7cf2933SEtienne Carriere 	3100,
314c7cf2933SEtienne Carriere 	3200,
315c7cf2933SEtienne Carriere 	3300,
316c7cf2933SEtienne Carriere };
317c7cf2933SEtienne Carriere 
318c7cf2933SEtienne Carriere static const uint16_t ldo3_voltage_table[] = {
319c7cf2933SEtienne Carriere 	1700,
320c7cf2933SEtienne Carriere 	1700,
321c7cf2933SEtienne Carriere 	1700,
322c7cf2933SEtienne Carriere 	1700,
323c7cf2933SEtienne Carriere 	1700,
324c7cf2933SEtienne Carriere 	1700,
325c7cf2933SEtienne Carriere 	1700,
326c7cf2933SEtienne Carriere 	1700,
327c7cf2933SEtienne Carriere 	1700,
328c7cf2933SEtienne Carriere 	1800,
329c7cf2933SEtienne Carriere 	1900,
330c7cf2933SEtienne Carriere 	2000,
331c7cf2933SEtienne Carriere 	2100,
332c7cf2933SEtienne Carriere 	2200,
333c7cf2933SEtienne Carriere 	2300,
334c7cf2933SEtienne Carriere 	2400,
335c7cf2933SEtienne Carriere 	2500,
336c7cf2933SEtienne Carriere 	2600,
337c7cf2933SEtienne Carriere 	2700,
338c7cf2933SEtienne Carriere 	2800,
339c7cf2933SEtienne Carriere 	2900,
340c7cf2933SEtienne Carriere 	3000,
341c7cf2933SEtienne Carriere 	3100,
342c7cf2933SEtienne Carriere 	3200,
343c7cf2933SEtienne Carriere 	3300,
344c7cf2933SEtienne Carriere 	3300,
345c7cf2933SEtienne Carriere 	3300,
346c7cf2933SEtienne Carriere 	3300,
347c7cf2933SEtienne Carriere 	3300,
348c7cf2933SEtienne Carriere 	3300,
349c7cf2933SEtienne Carriere 	3300,
350f7e28951SEtienne Carriere 	500,	/* VOUT2/2 (Sink/source mode) */
351c7cf2933SEtienne Carriere 	0xFFFF, /* VREFDDR */
352c7cf2933SEtienne Carriere };
353c7cf2933SEtienne Carriere 
354c7cf2933SEtienne Carriere static const uint16_t ldo5_voltage_table[] = {
355c7cf2933SEtienne Carriere 	1700,
356c7cf2933SEtienne Carriere 	1700,
357c7cf2933SEtienne Carriere 	1700,
358c7cf2933SEtienne Carriere 	1700,
359c7cf2933SEtienne Carriere 	1700,
360c7cf2933SEtienne Carriere 	1700,
361c7cf2933SEtienne Carriere 	1700,
362c7cf2933SEtienne Carriere 	1700,
363c7cf2933SEtienne Carriere 	1700,
364c7cf2933SEtienne Carriere 	1800,
365c7cf2933SEtienne Carriere 	1900,
366c7cf2933SEtienne Carriere 	2000,
367c7cf2933SEtienne Carriere 	2100,
368c7cf2933SEtienne Carriere 	2200,
369c7cf2933SEtienne Carriere 	2300,
370c7cf2933SEtienne Carriere 	2400,
371c7cf2933SEtienne Carriere 	2500,
372c7cf2933SEtienne Carriere 	2600,
373c7cf2933SEtienne Carriere 	2700,
374c7cf2933SEtienne Carriere 	2800,
375c7cf2933SEtienne Carriere 	2900,
376c7cf2933SEtienne Carriere 	3000,
377c7cf2933SEtienne Carriere 	3100,
378c7cf2933SEtienne Carriere 	3200,
379c7cf2933SEtienne Carriere 	3300,
380c7cf2933SEtienne Carriere 	3400,
381c7cf2933SEtienne Carriere 	3500,
382c7cf2933SEtienne Carriere 	3600,
383c7cf2933SEtienne Carriere 	3700,
384c7cf2933SEtienne Carriere 	3800,
385c7cf2933SEtienne Carriere 	3900,
386c7cf2933SEtienne Carriere };
387c7cf2933SEtienne Carriere 
388c7cf2933SEtienne Carriere static const uint16_t ldo6_voltage_table[] = {
389c7cf2933SEtienne Carriere 	900,
390c7cf2933SEtienne Carriere 	1000,
391c7cf2933SEtienne Carriere 	1100,
392c7cf2933SEtienne Carriere 	1200,
393c7cf2933SEtienne Carriere 	1300,
394c7cf2933SEtienne Carriere 	1400,
395c7cf2933SEtienne Carriere 	1500,
396c7cf2933SEtienne Carriere 	1600,
397c7cf2933SEtienne Carriere 	1700,
398c7cf2933SEtienne Carriere 	1800,
399c7cf2933SEtienne Carriere 	1900,
400c7cf2933SEtienne Carriere 	2000,
401c7cf2933SEtienne Carriere 	2100,
402c7cf2933SEtienne Carriere 	2200,
403c7cf2933SEtienne Carriere 	2300,
404c7cf2933SEtienne Carriere 	2400,
405c7cf2933SEtienne Carriere 	2500,
406c7cf2933SEtienne Carriere 	2600,
407c7cf2933SEtienne Carriere 	2700,
408c7cf2933SEtienne Carriere 	2800,
409c7cf2933SEtienne Carriere 	2900,
410c7cf2933SEtienne Carriere 	3000,
411c7cf2933SEtienne Carriere 	3100,
412c7cf2933SEtienne Carriere 	3200,
413c7cf2933SEtienne Carriere 	3300,
414c7cf2933SEtienne Carriere };
415c7cf2933SEtienne Carriere 
416c7cf2933SEtienne Carriere static const uint16_t ldo4_voltage_table[] = {
417c7cf2933SEtienne Carriere 	3300,
418c7cf2933SEtienne Carriere };
419c7cf2933SEtienne Carriere 
420c7cf2933SEtienne Carriere static const uint16_t vref_ddr_voltage_table[] = {
421c7cf2933SEtienne Carriere 	3300,
422c7cf2933SEtienne Carriere };
423c7cf2933SEtienne Carriere 
4243f692bdfSEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = {
4253f692bdfSEtienne Carriere 	5000,
4263f692bdfSEtienne Carriere };
4273f692bdfSEtienne Carriere 
428c7cf2933SEtienne Carriere /* Table of Regulators in PMIC SoC */
429c7cf2933SEtienne Carriere static const struct regul_struct regulators_table[] = {
430c7cf2933SEtienne Carriere 	{
431c7cf2933SEtienne Carriere 		.dt_node_name	= "buck1",
432c7cf2933SEtienne Carriere 		.voltage_table	= buck1_voltage_table,
433c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
434c7cf2933SEtienne Carriere 		.control_reg	= BUCK1_CONTROL_REG,
435c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK1_PWRCTRL_REG,
43668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
437c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
438c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK1_PULL_DOWN_SHIFT,
439c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
440c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
441c7cf2933SEtienne Carriere 	},
442c7cf2933SEtienne Carriere 	{
443c7cf2933SEtienne Carriere 		.dt_node_name	= "buck2",
444c7cf2933SEtienne Carriere 		.voltage_table	= buck2_voltage_table,
445c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
446c7cf2933SEtienne Carriere 		.control_reg	= BUCK2_CONTROL_REG,
447c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK2_PWRCTRL_REG,
44868cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
449c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
450c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK2_PULL_DOWN_SHIFT,
451c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
452c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
453c7cf2933SEtienne Carriere 	},
454c7cf2933SEtienne Carriere 	{
455c7cf2933SEtienne Carriere 		.dt_node_name	= "buck3",
456c7cf2933SEtienne Carriere 		.voltage_table	= buck3_voltage_table,
457c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
458c7cf2933SEtienne Carriere 		.control_reg	= BUCK3_CONTROL_REG,
459c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK3_PWRCTRL_REG,
46068cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
461c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
462c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK3_PULL_DOWN_SHIFT,
463c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
464c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
465c7cf2933SEtienne Carriere 	},
466c7cf2933SEtienne Carriere 	{
467c7cf2933SEtienne Carriere 		.dt_node_name	= "buck4",
468c7cf2933SEtienne Carriere 		.voltage_table	= buck4_voltage_table,
469c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
470c7cf2933SEtienne Carriere 		.control_reg	= BUCK4_CONTROL_REG,
471c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK4_PWRCTRL_REG,
47268cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
473c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
474c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK4_PULL_DOWN_SHIFT,
475c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
476c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
477c7cf2933SEtienne Carriere 	},
478c7cf2933SEtienne Carriere 	{
479c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo1",
480c7cf2933SEtienne Carriere 		.voltage_table	= ldo1_voltage_table,
481c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
482c7cf2933SEtienne Carriere 		.control_reg	= LDO1_CONTROL_REG,
483c7cf2933SEtienne Carriere 		.low_power_reg	= LDO1_PWRCTRL_REG,
48468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
485c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
486c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO1_MASK_RESET_SHIFT,
487c7cf2933SEtienne Carriere 	},
488c7cf2933SEtienne Carriere 	{
489c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo2",
490c7cf2933SEtienne Carriere 		.voltage_table	= ldo2_voltage_table,
491c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
492c7cf2933SEtienne Carriere 		.control_reg	= LDO2_CONTROL_REG,
493c7cf2933SEtienne Carriere 		.low_power_reg	= LDO2_PWRCTRL_REG,
49468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
495c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
496c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO2_MASK_RESET_SHIFT,
497c7cf2933SEtienne Carriere 	},
498c7cf2933SEtienne Carriere 	{
499c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo3",
500c7cf2933SEtienne Carriere 		.voltage_table	= ldo3_voltage_table,
501c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
502c7cf2933SEtienne Carriere 		.control_reg	= LDO3_CONTROL_REG,
503c7cf2933SEtienne Carriere 		.low_power_reg	= LDO3_PWRCTRL_REG,
50468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
505c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
506c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO3_MASK_RESET_SHIFT,
507c7cf2933SEtienne Carriere 	},
508c7cf2933SEtienne Carriere 	{
509c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo4",
510c7cf2933SEtienne Carriere 		.voltage_table	= ldo4_voltage_table,
511c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
512c7cf2933SEtienne Carriere 		.control_reg	= LDO4_CONTROL_REG,
513c7cf2933SEtienne Carriere 		.low_power_reg	= LDO4_PWRCTRL_REG,
51468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
515c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
516c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO4_MASK_RESET_SHIFT,
517c7cf2933SEtienne Carriere 	},
518c7cf2933SEtienne Carriere 	{
519c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo5",
520c7cf2933SEtienne Carriere 		.voltage_table	= ldo5_voltage_table,
521c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
522c7cf2933SEtienne Carriere 		.control_reg	= LDO5_CONTROL_REG,
523c7cf2933SEtienne Carriere 		.low_power_reg	= LDO5_PWRCTRL_REG,
52468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
525c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
526c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO5_MASK_RESET_SHIFT,
527c7cf2933SEtienne Carriere 	},
528c7cf2933SEtienne Carriere 	{
529c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo6",
530c7cf2933SEtienne Carriere 		.voltage_table	= ldo6_voltage_table,
531c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
532c7cf2933SEtienne Carriere 		.control_reg	= LDO6_CONTROL_REG,
533c7cf2933SEtienne Carriere 		.low_power_reg	= LDO6_PWRCTRL_REG,
53468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
535c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
536c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO6_MASK_RESET_SHIFT,
537c7cf2933SEtienne Carriere 	},
538c7cf2933SEtienne Carriere 	{
539c7cf2933SEtienne Carriere 		.dt_node_name	= "vref_ddr",
540c7cf2933SEtienne Carriere 		.voltage_table	= vref_ddr_voltage_table,
541c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
542c7cf2933SEtienne Carriere 		.control_reg	= VREF_DDR_CONTROL_REG,
543c7cf2933SEtienne Carriere 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
54468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
545c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
546c7cf2933SEtienne Carriere 		.mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
547c7cf2933SEtienne Carriere 	},
548c7cf2933SEtienne Carriere 	{
549c7cf2933SEtienne Carriere 		.dt_node_name = "boost",
5503f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5513f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5523f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5533f692bdfSEtienne Carriere 		.enable_pos	= BOOST_ENABLED_POS,
554c7cf2933SEtienne Carriere 	},
555c7cf2933SEtienne Carriere 	{
556c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw1",
5573f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5583f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5593f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5603f692bdfSEtienne Carriere 		.enable_pos	= USBSW_OTG_SWITCH_ENABLED_POS,
561c7cf2933SEtienne Carriere 	},
562c7cf2933SEtienne Carriere 	{
563c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw2",
5643f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5653f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5663f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5673f692bdfSEtienne Carriere 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
568c7cf2933SEtienne Carriere 	},
569c7cf2933SEtienne Carriere };
570c7cf2933SEtienne Carriere 
571c7cf2933SEtienne Carriere static const struct regul_struct *get_regulator_data(const char *name)
572c7cf2933SEtienne Carriere {
573c7cf2933SEtienne Carriere 	unsigned int i = 0;
574c7cf2933SEtienne Carriere 
575c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
576c7cf2933SEtienne Carriere 		if (strcmp(name, regulators_table[i].dt_node_name) == 0)
577c7cf2933SEtienne Carriere 			return &regulators_table[i];
578c7cf2933SEtienne Carriere 
579c7cf2933SEtienne Carriere 	/* Regulator not found */
580c7cf2933SEtienne Carriere 	panic(name);
581c7cf2933SEtienne Carriere }
582c7cf2933SEtienne Carriere 
583c7cf2933SEtienne Carriere static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
584c7cf2933SEtienne Carriere {
585c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
586c7cf2933SEtienne Carriere 	unsigned int i = 0;
587c7cf2933SEtienne Carriere 
588c7cf2933SEtienne Carriere 	assert(regul->voltage_table);
589c7cf2933SEtienne Carriere 	for (i = 0; i < regul->voltage_table_size; i++)
590c7cf2933SEtienne Carriere 		if (regul->voltage_table[i] == millivolts)
591c7cf2933SEtienne Carriere 			return i;
592c7cf2933SEtienne Carriere 
593c7cf2933SEtienne Carriere 	/* Voltage not found */
594c7cf2933SEtienne Carriere 	panic(name);
595c7cf2933SEtienne Carriere }
596c7cf2933SEtienne Carriere 
597c7cf2933SEtienne Carriere int stpmic1_powerctrl_on(void)
598c7cf2933SEtienne Carriere {
599c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
600c7cf2933SEtienne Carriere 				       PWRCTRL_PIN_VALID);
601c7cf2933SEtienne Carriere }
602c7cf2933SEtienne Carriere 
603c7cf2933SEtienne Carriere int stpmic1_switch_off(void)
604c7cf2933SEtienne Carriere {
605c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
606c7cf2933SEtienne Carriere 				       SOFTWARE_SWITCH_OFF_ENABLED);
607c7cf2933SEtienne Carriere }
608c7cf2933SEtienne Carriere 
609c7cf2933SEtienne Carriere int stpmic1_regulator_enable(const char *name)
610c7cf2933SEtienne Carriere {
611c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
612c7cf2933SEtienne Carriere 
61368cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
61468cfb83dSEtienne Carriere 				       BIT(regul->enable_pos),
61568cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
616c7cf2933SEtienne Carriere }
617c7cf2933SEtienne Carriere 
618c7cf2933SEtienne Carriere int stpmic1_regulator_disable(const char *name)
619c7cf2933SEtienne Carriere {
620c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
621c7cf2933SEtienne Carriere 
62268cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg, 0,
62368cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
624c7cf2933SEtienne Carriere }
625c7cf2933SEtienne Carriere 
6262619b28cSEtienne Carriere bool stpmic1_is_regulator_enabled(const char *name)
627c7cf2933SEtienne Carriere {
628c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
629c7cf2933SEtienne Carriere 	uint8_t val = 0;
630c7cf2933SEtienne Carriere 
631c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &val))
632c7cf2933SEtienne Carriere 		panic();
633c7cf2933SEtienne Carriere 
63468cfb83dSEtienne Carriere 	return val & BIT(regul->enable_pos);
635c7cf2933SEtienne Carriere }
636c7cf2933SEtienne Carriere 
637c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
638c7cf2933SEtienne Carriere {
639c7cf2933SEtienne Carriere 	uint8_t voltage_index = voltage_to_index(name, millivolts);
640c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
641c7cf2933SEtienne Carriere 	uint8_t mask = 0;
642c7cf2933SEtienne Carriere 
643c7cf2933SEtienne Carriere 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
644c7cf2933SEtienne Carriere 	if (!strcmp(name, "buck"))
645c7cf2933SEtienne Carriere 		mask = BUCK_VOLTAGE_MASK;
646c7cf2933SEtienne Carriere 	else if (!strcmp(name, "ldo") && strcmp(name, "ldo4"))
647c7cf2933SEtienne Carriere 		mask = LDO_VOLTAGE_MASK;
648c7cf2933SEtienne Carriere 	else
649c7cf2933SEtienne Carriere 		return 0;
650c7cf2933SEtienne Carriere 
651c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
652c7cf2933SEtienne Carriere 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
653c7cf2933SEtienne Carriere 				       mask);
654c7cf2933SEtienne Carriere }
655c7cf2933SEtienne Carriere 
656c7cf2933SEtienne Carriere int stpmic1_regulator_mask_reset_set(const char *name)
657c7cf2933SEtienne Carriere {
658c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
659c7cf2933SEtienne Carriere 
6603f692bdfSEtienne Carriere 	if (regul->control_reg == USB_CONTROL_REG) {
6613f692bdfSEtienne Carriere 		DMSG("No reset for USB control");
6623f692bdfSEtienne Carriere 		return -1;
6633f692bdfSEtienne Carriere 	}
6643f692bdfSEtienne Carriere 
665c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->mask_reset_reg,
666c7cf2933SEtienne Carriere 				       BIT(regul->mask_reset_pos),
667c7cf2933SEtienne Carriere 				       LDO_BUCK_RESET_MASK <<
668c7cf2933SEtienne Carriere 				       regul->mask_reset_pos);
669c7cf2933SEtienne Carriere }
670c7cf2933SEtienne Carriere 
671*6149e2d8SEtienne Carriere int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
672*6149e2d8SEtienne Carriere {
673*6149e2d8SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
674*6149e2d8SEtienne Carriere 
675*6149e2d8SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
676*6149e2d8SEtienne Carriere 	cfg->enable_pos = regul->enable_pos;
677*6149e2d8SEtienne Carriere 
678*6149e2d8SEtienne Carriere 	return 0;
679*6149e2d8SEtienne Carriere }
680*6149e2d8SEtienne Carriere 
681eb5d5313SEtienne Carriere int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
682eb5d5313SEtienne Carriere {
68368cfb83dSEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg,
68468cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos),
68568cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos));
686eb5d5313SEtienne Carriere }
687eb5d5313SEtienne Carriere 
688eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
689eb5d5313SEtienne Carriere int stpmic1_bo_voltage_cfg(const char *name, uint16_t millivolts,
690eb5d5313SEtienne Carriere 			   struct stpmic1_bo_cfg *cfg)
691eb5d5313SEtienne Carriere {
692eb5d5313SEtienne Carriere 	uint8_t voltage_index = voltage_to_index(name, millivolts);
693eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
694eb5d5313SEtienne Carriere 	uint8_t mask = 0;
695eb5d5313SEtienne Carriere 
696eb5d5313SEtienne Carriere 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
697eb5d5313SEtienne Carriere 	if (!strcmp(name, "buck"))
698eb5d5313SEtienne Carriere 		mask = BUCK_VOLTAGE_MASK;
699eb5d5313SEtienne Carriere 	else if (!strcmp(name, "ldo") && strcmp(name, "ldo4"))
700eb5d5313SEtienne Carriere 		mask = LDO_VOLTAGE_MASK;
701eb5d5313SEtienne Carriere 	else
702eb5d5313SEtienne Carriere 		return 1;
703eb5d5313SEtienne Carriere 
704eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
705eb5d5313SEtienne Carriere 	cfg->value = voltage_index << LDO_BUCK_VOLTAGE_SHIFT;
706eb5d5313SEtienne Carriere 	cfg->mask = mask;
707eb5d5313SEtienne Carriere 
708eb5d5313SEtienne Carriere 	return 0;
709eb5d5313SEtienne Carriere }
710eb5d5313SEtienne Carriere 
711eb5d5313SEtienne Carriere int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
712eb5d5313SEtienne Carriere {
713eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg, cfg->value, cfg->mask);
714eb5d5313SEtienne Carriere }
715eb5d5313SEtienne Carriere 
716eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
717eb5d5313SEtienne Carriere {
718eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
719eb5d5313SEtienne Carriere 
720eb5d5313SEtienne Carriere 	cfg->pd_reg = regul->pull_down_reg;
721eb5d5313SEtienne Carriere 	cfg->pd_value = BIT(regul->pull_down_pos);
722eb5d5313SEtienne Carriere 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
723eb5d5313SEtienne Carriere 
724eb5d5313SEtienne Carriere 	return 0;
725eb5d5313SEtienne Carriere }
726eb5d5313SEtienne Carriere 
727eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
728eb5d5313SEtienne Carriere {
729eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
730eb5d5313SEtienne Carriere 				       cfg->pd_mask);
731eb5d5313SEtienne Carriere }
732eb5d5313SEtienne Carriere 
733eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
734eb5d5313SEtienne Carriere {
735eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
736eb5d5313SEtienne Carriere 
737eb5d5313SEtienne Carriere 	cfg->mrst_reg = regul->mask_reset_reg;
738eb5d5313SEtienne Carriere 	cfg->mrst_value = BIT(regul->mask_reset_pos);
739eb5d5313SEtienne Carriere 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
740eb5d5313SEtienne Carriere 
741eb5d5313SEtienne Carriere 	return 0;
742eb5d5313SEtienne Carriere }
743eb5d5313SEtienne Carriere 
744eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
745eb5d5313SEtienne Carriere {
746eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
747eb5d5313SEtienne Carriere 				       cfg->mrst_mask);
748eb5d5313SEtienne Carriere }
749eb5d5313SEtienne Carriere 
750c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_get(const char *name)
751c7cf2933SEtienne Carriere {
752c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
753c7cf2933SEtienne Carriere 	uint8_t value = 0;
754c7cf2933SEtienne Carriere 	uint8_t mask = 0;
755c7cf2933SEtienne Carriere 
756c7cf2933SEtienne Carriere 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
757c7cf2933SEtienne Carriere 	if (!strcmp(name, "buck"))
758c7cf2933SEtienne Carriere 		mask = BUCK_VOLTAGE_MASK;
759c7cf2933SEtienne Carriere 	else if (!strcmp(name, "ldo") && strcmp(name, "ldo4"))
760c7cf2933SEtienne Carriere 		mask = LDO_VOLTAGE_MASK;
761c7cf2933SEtienne Carriere 	else
762c7cf2933SEtienne Carriere 		return 0;
763c7cf2933SEtienne Carriere 
764c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &value))
765c7cf2933SEtienne Carriere 		return -1;
766c7cf2933SEtienne Carriere 
767c7cf2933SEtienne Carriere 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
768c7cf2933SEtienne Carriere 
769c7cf2933SEtienne Carriere 	if (value > regul->voltage_table_size)
770c7cf2933SEtienne Carriere 		return -1;
771c7cf2933SEtienne Carriere 
772c7cf2933SEtienne Carriere 	return regul->voltage_table[value];
773c7cf2933SEtienne Carriere }
774c7cf2933SEtienne Carriere 
775c7cf2933SEtienne Carriere int stpmic1_lp_copy_reg(const char *name)
776c7cf2933SEtienne Carriere {
777c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
778c7cf2933SEtienne Carriere 	uint8_t val = 0;
779c7cf2933SEtienne Carriere 	int status = 0;
780c7cf2933SEtienne Carriere 
781c7cf2933SEtienne Carriere 	status = stpmic1_register_read(regul->control_reg, &val);
782c7cf2933SEtienne Carriere 	if (status)
783c7cf2933SEtienne Carriere 		return status;
784c7cf2933SEtienne Carriere 
785c7cf2933SEtienne Carriere 	return stpmic1_register_write(regul->low_power_reg, val);
786c7cf2933SEtienne Carriere }
787c7cf2933SEtienne Carriere 
788eb5d5313SEtienne Carriere int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
789eb5d5313SEtienne Carriere {
790eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
791eb5d5313SEtienne Carriere 
792eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
793eb5d5313SEtienne Carriere 	cfg->lp_reg = regul->low_power_reg;
794eb5d5313SEtienne Carriere 
795eb5d5313SEtienne Carriere 	return 0;
796eb5d5313SEtienne Carriere }
797eb5d5313SEtienne Carriere 
798eb5d5313SEtienne Carriere int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
799eb5d5313SEtienne Carriere {
800eb5d5313SEtienne Carriere 	uint8_t val = 0;
801eb5d5313SEtienne Carriere 	int status = 0;
802eb5d5313SEtienne Carriere 
803eb5d5313SEtienne Carriere 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
804eb5d5313SEtienne Carriere 	if (!status)
805eb5d5313SEtienne Carriere 		status = stpmic1_register_write(cfg->lp_reg, val);
806eb5d5313SEtienne Carriere 
807eb5d5313SEtienne Carriere 	return status;
808eb5d5313SEtienne Carriere }
809eb5d5313SEtienne Carriere 
810c7cf2933SEtienne Carriere int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
811c7cf2933SEtienne Carriere {
812c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
813c7cf2933SEtienne Carriere 
814c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, enable,
815c7cf2933SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
816c7cf2933SEtienne Carriere }
817c7cf2933SEtienne Carriere 
818eb5d5313SEtienne Carriere int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
819eb5d5313SEtienne Carriere {
820eb5d5313SEtienne Carriere 	assert(enable == 0 || enable == 1);
821eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, enable,
822eb5d5313SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
823eb5d5313SEtienne Carriere }
824eb5d5313SEtienne Carriere 
825c7cf2933SEtienne Carriere int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
826c7cf2933SEtienne Carriere {
827c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
828c7cf2933SEtienne Carriere 
829c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg,
83042032ea0SEtienne Carriere 				       hplp << LDO_BUCK_HPLP_POS,
83142032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
832c7cf2933SEtienne Carriere }
833c7cf2933SEtienne Carriere 
834eb5d5313SEtienne Carriere int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
835eb5d5313SEtienne Carriere {
836eb5d5313SEtienne Carriere 	assert(mode == 0 || mode == 1);
837eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg,
83842032ea0SEtienne Carriere 				       mode << LDO_BUCK_HPLP_POS,
83942032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
840eb5d5313SEtienne Carriere }
841eb5d5313SEtienne Carriere 
842c7cf2933SEtienne Carriere int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
843c7cf2933SEtienne Carriere {
844c7cf2933SEtienne Carriere 	uint8_t voltage_index = voltage_to_index(name, millivolts);
845c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
846c7cf2933SEtienne Carriere 	uint8_t mask = 0;
847c7cf2933SEtienne Carriere 
848c7cf2933SEtienne Carriere 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
849c7cf2933SEtienne Carriere 	if (!strcmp(name, "buck"))
850c7cf2933SEtienne Carriere 		mask = BUCK_VOLTAGE_MASK;
851c7cf2933SEtienne Carriere 	else if (!strcmp(name, "ldo") && strcmp(name, "ldo4"))
852c7cf2933SEtienne Carriere 		mask = LDO_VOLTAGE_MASK;
853c7cf2933SEtienne Carriere 	else
854c7cf2933SEtienne Carriere 		return 0;
855c7cf2933SEtienne Carriere 
856c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
857c7cf2933SEtienne Carriere 				       mask);
858c7cf2933SEtienne Carriere }
859c7cf2933SEtienne Carriere 
860eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
861eb5d5313SEtienne Carriere int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
862eb5d5313SEtienne Carriere 			   struct stpmic1_lp_cfg *cfg)
863eb5d5313SEtienne Carriere 
864eb5d5313SEtienne Carriere {
865eb5d5313SEtienne Carriere 	uint8_t voltage_index = voltage_to_index(name, millivolts);
866eb5d5313SEtienne Carriere 	uint8_t mask = 0;
867eb5d5313SEtienne Carriere 
868eb5d5313SEtienne Carriere 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
869eb5d5313SEtienne Carriere 	if (!strcmp(name, "buck"))
870eb5d5313SEtienne Carriere 		mask = BUCK_VOLTAGE_MASK;
871eb5d5313SEtienne Carriere 	else if (!strcmp(name, "ldo") && strcmp(name, "ldo4"))
872eb5d5313SEtienne Carriere 		mask = LDO_VOLTAGE_MASK;
873eb5d5313SEtienne Carriere 	else
874eb5d5313SEtienne Carriere 		return 1;
875eb5d5313SEtienne Carriere 
876eb5d5313SEtienne Carriere 	assert(cfg->lp_reg == get_regulator_data(name)->low_power_reg);
877eb5d5313SEtienne Carriere 	cfg->value = voltage_index << 2;
878eb5d5313SEtienne Carriere 	cfg->mask = mask;
879eb5d5313SEtienne Carriere 
880eb5d5313SEtienne Carriere 	return 0;
881eb5d5313SEtienne Carriere }
882eb5d5313SEtienne Carriere 
883eb5d5313SEtienne Carriere int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
884eb5d5313SEtienne Carriere {
885eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
886eb5d5313SEtienne Carriere }
887eb5d5313SEtienne Carriere 
888c7cf2933SEtienne Carriere int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
889c7cf2933SEtienne Carriere {
890c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
891c7cf2933SEtienne Carriere 
892eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
893eb5d5313SEtienne Carriere 					    register_id, value,
894eb5d5313SEtienne Carriere 					    false /* !write */);
895c7cf2933SEtienne Carriere }
896c7cf2933SEtienne Carriere 
897c7cf2933SEtienne Carriere int stpmic1_register_write(uint8_t register_id, uint8_t value)
898c7cf2933SEtienne Carriere {
899c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
900c7cf2933SEtienne Carriere 	uint8_t val = value;
901c7cf2933SEtienne Carriere 
902eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
903eb5d5313SEtienne Carriere 					    register_id, &val,
904eb5d5313SEtienne Carriere 					    true /* write */);
905c7cf2933SEtienne Carriere }
906c7cf2933SEtienne Carriere 
907c7cf2933SEtienne Carriere int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
908c7cf2933SEtienne Carriere {
909c7cf2933SEtienne Carriere 	int status = 0;
910c7cf2933SEtienne Carriere 	uint8_t val = 0;
911c7cf2933SEtienne Carriere 
912c7cf2933SEtienne Carriere 	status = stpmic1_register_read(register_id, &val);
913c7cf2933SEtienne Carriere 	if (status)
914c7cf2933SEtienne Carriere 		return status;
915c7cf2933SEtienne Carriere 
916c7cf2933SEtienne Carriere 	val = (val & ~mask) | (value & mask);
917c7cf2933SEtienne Carriere 
918c7cf2933SEtienne Carriere 	return stpmic1_register_write(register_id, val);
919c7cf2933SEtienne Carriere }
920c7cf2933SEtienne Carriere 
921c7cf2933SEtienne Carriere void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
922c7cf2933SEtienne Carriere {
923c7cf2933SEtienne Carriere 	pmic_i2c_handle = i2c_handle;
924c7cf2933SEtienne Carriere 	pmic_i2c_addr = i2c_addr;
925c7cf2933SEtienne Carriere }
926c7cf2933SEtienne Carriere 
927c7cf2933SEtienne Carriere void stpmic1_dump_regulators(void)
928c7cf2933SEtienne Carriere {
929c7cf2933SEtienne Carriere 	size_t i = 0;
930c7cf2933SEtienne Carriere 	char __maybe_unused const *name = NULL;
931c7cf2933SEtienne Carriere 
932c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
933c7cf2933SEtienne Carriere 		if (!regulators_table[i].control_reg)
934c7cf2933SEtienne Carriere 			continue;
935c7cf2933SEtienne Carriere 
936c7cf2933SEtienne Carriere 		name = regulators_table[i].dt_node_name;
937c7cf2933SEtienne Carriere 		DMSG("PMIC regul %s: %sable, %dmV",
938c7cf2933SEtienne Carriere 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
939c7cf2933SEtienne Carriere 		     stpmic1_regulator_voltage_get(name));
940c7cf2933SEtienne Carriere 	}
941c7cf2933SEtienne Carriere }
942c7cf2933SEtienne Carriere 
943c7cf2933SEtienne Carriere int stpmic1_get_version(unsigned long *version)
944c7cf2933SEtienne Carriere {
945c7cf2933SEtienne Carriere 	uint8_t read_val = 0;
946c7cf2933SEtienne Carriere 
947c7cf2933SEtienne Carriere 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
948c7cf2933SEtienne Carriere 		return -1;
949c7cf2933SEtienne Carriere 
950c7cf2933SEtienne Carriere 	*version = read_val;
951c7cf2933SEtienne Carriere 	return 0;
952c7cf2933SEtienne Carriere }
953