xref: /openbmc/u-boot/drivers/power/regulator/stpmu1.c (revision 069f0b63547456e9744e8bd1cdc4c62551b24b9a)
1*069f0b63SChristophe Kerello // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2*069f0b63SChristophe Kerello /*
3*069f0b63SChristophe Kerello  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4*069f0b63SChristophe Kerello  * Author: Christophe Kerello <christophe.kerello@st.com>
5*069f0b63SChristophe Kerello  */
6*069f0b63SChristophe Kerello 
7*069f0b63SChristophe Kerello #include <common.h>
8*069f0b63SChristophe Kerello #include <dm.h>
9*069f0b63SChristophe Kerello #include <errno.h>
10*069f0b63SChristophe Kerello #include <power/pmic.h>
11*069f0b63SChristophe Kerello #include <power/regulator.h>
12*069f0b63SChristophe Kerello #include <power/stpmu1.h>
13*069f0b63SChristophe Kerello 
14*069f0b63SChristophe Kerello struct stpmu1_range {
15*069f0b63SChristophe Kerello 	int min_uv;
16*069f0b63SChristophe Kerello 	int min_sel;
17*069f0b63SChristophe Kerello 	int max_sel;
18*069f0b63SChristophe Kerello 	int step;
19*069f0b63SChristophe Kerello };
20*069f0b63SChristophe Kerello 
21*069f0b63SChristophe Kerello struct stpmu1_output_range {
22*069f0b63SChristophe Kerello 	const struct stpmu1_range *ranges;
23*069f0b63SChristophe Kerello 	int nbranges;
24*069f0b63SChristophe Kerello };
25*069f0b63SChristophe Kerello 
26*069f0b63SChristophe Kerello #define STPMU1_MODE(_id, _val, _name) { \
27*069f0b63SChristophe Kerello 	.id = _id,			\
28*069f0b63SChristophe Kerello 	.register_value = _val,		\
29*069f0b63SChristophe Kerello 	.name = _name,			\
30*069f0b63SChristophe Kerello }
31*069f0b63SChristophe Kerello 
32*069f0b63SChristophe Kerello #define STPMU1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \
33*069f0b63SChristophe Kerello 	.min_uv = _min_uv,		\
34*069f0b63SChristophe Kerello 	.min_sel = _min_sel,		\
35*069f0b63SChristophe Kerello 	.max_sel = _max_sel,		\
36*069f0b63SChristophe Kerello 	.step = _step,			\
37*069f0b63SChristophe Kerello }
38*069f0b63SChristophe Kerello 
39*069f0b63SChristophe Kerello #define STPMU1_OUTPUT_RANGE(_ranges, _nbranges) { \
40*069f0b63SChristophe Kerello 	.ranges = _ranges,		\
41*069f0b63SChristophe Kerello 	.nbranges = _nbranges,		\
42*069f0b63SChristophe Kerello }
43*069f0b63SChristophe Kerello 
44*069f0b63SChristophe Kerello static int stpmu1_output_find_uv(int sel,
45*069f0b63SChristophe Kerello 				 const struct stpmu1_output_range *output_range)
46*069f0b63SChristophe Kerello {
47*069f0b63SChristophe Kerello 	const struct stpmu1_range *range;
48*069f0b63SChristophe Kerello 	int i;
49*069f0b63SChristophe Kerello 
50*069f0b63SChristophe Kerello 	for (i = 0, range = output_range->ranges;
51*069f0b63SChristophe Kerello 	     i < output_range->nbranges; i++, range++) {
52*069f0b63SChristophe Kerello 		if (sel >= range->min_sel && sel <= range->max_sel)
53*069f0b63SChristophe Kerello 			return range->min_uv +
54*069f0b63SChristophe Kerello 			       (sel - range->min_sel) * range->step;
55*069f0b63SChristophe Kerello 	}
56*069f0b63SChristophe Kerello 
57*069f0b63SChristophe Kerello 	return -EINVAL;
58*069f0b63SChristophe Kerello }
59*069f0b63SChristophe Kerello 
60*069f0b63SChristophe Kerello static int stpmu1_output_find_sel(int uv,
61*069f0b63SChristophe Kerello 				  const struct stpmu1_output_range *output_range)
62*069f0b63SChristophe Kerello {
63*069f0b63SChristophe Kerello 	const struct stpmu1_range *range;
64*069f0b63SChristophe Kerello 	int i;
65*069f0b63SChristophe Kerello 
66*069f0b63SChristophe Kerello 	for (i = 0, range = output_range->ranges;
67*069f0b63SChristophe Kerello 	     i < output_range->nbranges; i++, range++) {
68*069f0b63SChristophe Kerello 		if (uv == range->min_uv && !range->step)
69*069f0b63SChristophe Kerello 			return range->min_sel;
70*069f0b63SChristophe Kerello 
71*069f0b63SChristophe Kerello 		if (uv >= range->min_uv &&
72*069f0b63SChristophe Kerello 		    uv <= range->min_uv +
73*069f0b63SChristophe Kerello 			  (range->max_sel - range->min_sel) * range->step)
74*069f0b63SChristophe Kerello 			return range->min_sel +
75*069f0b63SChristophe Kerello 			       (uv - range->min_uv) / range->step;
76*069f0b63SChristophe Kerello 	}
77*069f0b63SChristophe Kerello 
78*069f0b63SChristophe Kerello 	return -EINVAL;
79*069f0b63SChristophe Kerello }
80*069f0b63SChristophe Kerello 
81*069f0b63SChristophe Kerello /*
82*069f0b63SChristophe Kerello  * BUCK regulators
83*069f0b63SChristophe Kerello  */
84*069f0b63SChristophe Kerello 
85*069f0b63SChristophe Kerello static const struct stpmu1_range buck1_ranges[] = {
86*069f0b63SChristophe Kerello 	STPMU1_RANGE(600000, 0, 30, 25000),
87*069f0b63SChristophe Kerello 	STPMU1_RANGE(1350000, 31, 63, 0),
88*069f0b63SChristophe Kerello };
89*069f0b63SChristophe Kerello 
90*069f0b63SChristophe Kerello static const struct stpmu1_range buck2_ranges[] = {
91*069f0b63SChristophe Kerello 	STPMU1_RANGE(1000000, 0, 17, 0),
92*069f0b63SChristophe Kerello 	STPMU1_RANGE(1050000, 18, 19, 0),
93*069f0b63SChristophe Kerello 	STPMU1_RANGE(1100000, 20, 21, 0),
94*069f0b63SChristophe Kerello 	STPMU1_RANGE(1150000, 22, 23, 0),
95*069f0b63SChristophe Kerello 	STPMU1_RANGE(1200000, 24, 25, 0),
96*069f0b63SChristophe Kerello 	STPMU1_RANGE(1250000, 26, 27, 0),
97*069f0b63SChristophe Kerello 	STPMU1_RANGE(1300000, 28, 29, 0),
98*069f0b63SChristophe Kerello 	STPMU1_RANGE(1350000, 30, 31, 0),
99*069f0b63SChristophe Kerello 	STPMU1_RANGE(1400000, 32, 33, 0),
100*069f0b63SChristophe Kerello 	STPMU1_RANGE(1450000, 34, 35, 0),
101*069f0b63SChristophe Kerello 	STPMU1_RANGE(1500000, 36, 63, 0),
102*069f0b63SChristophe Kerello };
103*069f0b63SChristophe Kerello 
104*069f0b63SChristophe Kerello static const struct stpmu1_range buck3_ranges[] = {
105*069f0b63SChristophe Kerello 	STPMU1_RANGE(1000000, 0, 19, 0),
106*069f0b63SChristophe Kerello 	STPMU1_RANGE(1100000, 20, 23, 0),
107*069f0b63SChristophe Kerello 	STPMU1_RANGE(1200000, 24, 27, 0),
108*069f0b63SChristophe Kerello 	STPMU1_RANGE(1300000, 28, 31, 0),
109*069f0b63SChristophe Kerello 	STPMU1_RANGE(1400000, 32, 35, 0),
110*069f0b63SChristophe Kerello 	STPMU1_RANGE(1500000, 36, 55, 100000),
111*069f0b63SChristophe Kerello 	STPMU1_RANGE(3400000, 56, 63, 0),
112*069f0b63SChristophe Kerello };
113*069f0b63SChristophe Kerello 
114*069f0b63SChristophe Kerello static const struct stpmu1_range buck4_ranges[] = {
115*069f0b63SChristophe Kerello 	STPMU1_RANGE(600000, 0, 27, 25000),
116*069f0b63SChristophe Kerello 	STPMU1_RANGE(1300000, 28, 29, 0),
117*069f0b63SChristophe Kerello 	STPMU1_RANGE(1350000, 30, 31, 0),
118*069f0b63SChristophe Kerello 	STPMU1_RANGE(1400000, 32, 33, 0),
119*069f0b63SChristophe Kerello 	STPMU1_RANGE(1450000, 34, 35, 0),
120*069f0b63SChristophe Kerello 	STPMU1_RANGE(1500000, 36, 60, 100000),
121*069f0b63SChristophe Kerello 	STPMU1_RANGE(3900000, 61, 63, 0),
122*069f0b63SChristophe Kerello };
123*069f0b63SChristophe Kerello 
124*069f0b63SChristophe Kerello /* BUCK: 1,2,3,4 - voltage ranges */
125*069f0b63SChristophe Kerello static const struct stpmu1_output_range buck_voltage_range[] = {
126*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(buck1_ranges, ARRAY_SIZE(buck1_ranges)),
127*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(buck2_ranges, ARRAY_SIZE(buck2_ranges)),
128*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(buck3_ranges, ARRAY_SIZE(buck3_ranges)),
129*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(buck4_ranges, ARRAY_SIZE(buck4_ranges)),
130*069f0b63SChristophe Kerello };
131*069f0b63SChristophe Kerello 
132*069f0b63SChristophe Kerello /* BUCK modes */
133*069f0b63SChristophe Kerello static const struct dm_regulator_mode buck_modes[] = {
134*069f0b63SChristophe Kerello 	STPMU1_MODE(STPMU1_BUCK_MODE_HP, STPMU1_BUCK_MODE_HP, "HP"),
135*069f0b63SChristophe Kerello 	STPMU1_MODE(STPMU1_BUCK_MODE_LP, STPMU1_BUCK_MODE_LP, "LP"),
136*069f0b63SChristophe Kerello };
137*069f0b63SChristophe Kerello 
138*069f0b63SChristophe Kerello static int stpmu1_buck_get_uv(struct udevice *dev, int buck)
139*069f0b63SChristophe Kerello {
140*069f0b63SChristophe Kerello 	int sel;
141*069f0b63SChristophe Kerello 
142*069f0b63SChristophe Kerello 	sel = pmic_reg_read(dev, STPMU1_BUCKX_CTRL_REG(buck));
143*069f0b63SChristophe Kerello 	if (sel < 0)
144*069f0b63SChristophe Kerello 		return sel;
145*069f0b63SChristophe Kerello 
146*069f0b63SChristophe Kerello 	sel &= STPMU1_BUCK_OUTPUT_MASK;
147*069f0b63SChristophe Kerello 	sel >>= STPMU1_BUCK_OUTPUT_SHIFT;
148*069f0b63SChristophe Kerello 
149*069f0b63SChristophe Kerello 	return stpmu1_output_find_uv(sel, &buck_voltage_range[buck]);
150*069f0b63SChristophe Kerello }
151*069f0b63SChristophe Kerello 
152*069f0b63SChristophe Kerello static int stpmu1_buck_get_value(struct udevice *dev)
153*069f0b63SChristophe Kerello {
154*069f0b63SChristophe Kerello 	return stpmu1_buck_get_uv(dev->parent, dev->driver_data - 1);
155*069f0b63SChristophe Kerello }
156*069f0b63SChristophe Kerello 
157*069f0b63SChristophe Kerello static int stpmu1_buck_set_value(struct udevice *dev, int uv)
158*069f0b63SChristophe Kerello {
159*069f0b63SChristophe Kerello 	int sel, buck = dev->driver_data - 1;
160*069f0b63SChristophe Kerello 
161*069f0b63SChristophe Kerello 	sel = stpmu1_output_find_sel(uv, &buck_voltage_range[buck]);
162*069f0b63SChristophe Kerello 	if (sel < 0)
163*069f0b63SChristophe Kerello 		return sel;
164*069f0b63SChristophe Kerello 
165*069f0b63SChristophe Kerello 	return pmic_clrsetbits(dev->parent,
166*069f0b63SChristophe Kerello 			       STPMU1_BUCKX_CTRL_REG(buck),
167*069f0b63SChristophe Kerello 			       STPMU1_BUCK_OUTPUT_MASK,
168*069f0b63SChristophe Kerello 			       sel << STPMU1_BUCK_OUTPUT_SHIFT);
169*069f0b63SChristophe Kerello }
170*069f0b63SChristophe Kerello 
171*069f0b63SChristophe Kerello static int stpmu1_buck_get_enable(struct udevice *dev)
172*069f0b63SChristophe Kerello {
173*069f0b63SChristophe Kerello 	int ret;
174*069f0b63SChristophe Kerello 
175*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent,
176*069f0b63SChristophe Kerello 			    STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
177*069f0b63SChristophe Kerello 	if (ret < 0)
178*069f0b63SChristophe Kerello 		return false;
179*069f0b63SChristophe Kerello 
180*069f0b63SChristophe Kerello 	return ret & STPMU1_BUCK_EN ? true : false;
181*069f0b63SChristophe Kerello }
182*069f0b63SChristophe Kerello 
183*069f0b63SChristophe Kerello static int stpmu1_buck_set_enable(struct udevice *dev, bool enable)
184*069f0b63SChristophe Kerello {
185*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
186*069f0b63SChristophe Kerello 	int ret, uv;
187*069f0b63SChristophe Kerello 
188*069f0b63SChristophe Kerello 	/* if regulator is already in the wanted state, nothing to do */
189*069f0b63SChristophe Kerello 	if (stpmu1_buck_get_enable(dev) == enable)
190*069f0b63SChristophe Kerello 		return 0;
191*069f0b63SChristophe Kerello 
192*069f0b63SChristophe Kerello 	if (enable) {
193*069f0b63SChristophe Kerello 		uc_pdata = dev_get_uclass_platdata(dev);
194*069f0b63SChristophe Kerello 		uv = stpmu1_buck_get_value(dev);
195*069f0b63SChristophe Kerello 		if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
196*069f0b63SChristophe Kerello 			stpmu1_buck_set_value(dev, uc_pdata->min_uV);
197*069f0b63SChristophe Kerello 	}
198*069f0b63SChristophe Kerello 
199*069f0b63SChristophe Kerello 	ret = pmic_clrsetbits(dev->parent,
200*069f0b63SChristophe Kerello 			      STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
201*069f0b63SChristophe Kerello 			      STPMU1_BUCK_EN, enable ? STPMU1_BUCK_EN : 0);
202*069f0b63SChristophe Kerello 	if (enable)
203*069f0b63SChristophe Kerello 		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
204*069f0b63SChristophe Kerello 
205*069f0b63SChristophe Kerello 	return ret;
206*069f0b63SChristophe Kerello }
207*069f0b63SChristophe Kerello 
208*069f0b63SChristophe Kerello static int stpmu1_buck_get_mode(struct udevice *dev)
209*069f0b63SChristophe Kerello {
210*069f0b63SChristophe Kerello 	int ret;
211*069f0b63SChristophe Kerello 
212*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent,
213*069f0b63SChristophe Kerello 			    STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
214*069f0b63SChristophe Kerello 	if (ret < 0)
215*069f0b63SChristophe Kerello 		return ret;
216*069f0b63SChristophe Kerello 
217*069f0b63SChristophe Kerello 	return ret & STPMU1_BUCK_MODE ? STPMU1_BUCK_MODE_LP :
218*069f0b63SChristophe Kerello 					 STPMU1_BUCK_MODE_HP;
219*069f0b63SChristophe Kerello }
220*069f0b63SChristophe Kerello 
221*069f0b63SChristophe Kerello static int stpmu1_buck_set_mode(struct udevice *dev, int mode)
222*069f0b63SChristophe Kerello {
223*069f0b63SChristophe Kerello 	return pmic_clrsetbits(dev->parent,
224*069f0b63SChristophe Kerello 			       STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
225*069f0b63SChristophe Kerello 			       STPMU1_BUCK_MODE,
226*069f0b63SChristophe Kerello 			       mode ? STPMU1_BUCK_MODE : 0);
227*069f0b63SChristophe Kerello }
228*069f0b63SChristophe Kerello 
229*069f0b63SChristophe Kerello static int stpmu1_buck_probe(struct udevice *dev)
230*069f0b63SChristophe Kerello {
231*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
232*069f0b63SChristophe Kerello 
233*069f0b63SChristophe Kerello 	if (!dev->driver_data || dev->driver_data > STPMU1_MAX_BUCK)
234*069f0b63SChristophe Kerello 		return -EINVAL;
235*069f0b63SChristophe Kerello 
236*069f0b63SChristophe Kerello 	uc_pdata = dev_get_uclass_platdata(dev);
237*069f0b63SChristophe Kerello 
238*069f0b63SChristophe Kerello 	uc_pdata->type = REGULATOR_TYPE_BUCK;
239*069f0b63SChristophe Kerello 	uc_pdata->mode = (struct dm_regulator_mode *)buck_modes;
240*069f0b63SChristophe Kerello 	uc_pdata->mode_count = ARRAY_SIZE(buck_modes);
241*069f0b63SChristophe Kerello 
242*069f0b63SChristophe Kerello 	return 0;
243*069f0b63SChristophe Kerello }
244*069f0b63SChristophe Kerello 
245*069f0b63SChristophe Kerello static const struct dm_regulator_ops stpmu1_buck_ops = {
246*069f0b63SChristophe Kerello 	.get_value  = stpmu1_buck_get_value,
247*069f0b63SChristophe Kerello 	.set_value  = stpmu1_buck_set_value,
248*069f0b63SChristophe Kerello 	.get_enable = stpmu1_buck_get_enable,
249*069f0b63SChristophe Kerello 	.set_enable = stpmu1_buck_set_enable,
250*069f0b63SChristophe Kerello 	.get_mode   = stpmu1_buck_get_mode,
251*069f0b63SChristophe Kerello 	.set_mode   = stpmu1_buck_set_mode,
252*069f0b63SChristophe Kerello };
253*069f0b63SChristophe Kerello 
254*069f0b63SChristophe Kerello U_BOOT_DRIVER(stpmu1_buck) = {
255*069f0b63SChristophe Kerello 	.name = "stpmu1_buck",
256*069f0b63SChristophe Kerello 	.id = UCLASS_REGULATOR,
257*069f0b63SChristophe Kerello 	.ops = &stpmu1_buck_ops,
258*069f0b63SChristophe Kerello 	.probe = stpmu1_buck_probe,
259*069f0b63SChristophe Kerello };
260*069f0b63SChristophe Kerello 
261*069f0b63SChristophe Kerello /*
262*069f0b63SChristophe Kerello  * LDO regulators
263*069f0b63SChristophe Kerello  */
264*069f0b63SChristophe Kerello 
265*069f0b63SChristophe Kerello static const struct stpmu1_range ldo12_ranges[] = {
266*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 0, 7, 0),
267*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 8, 24, 100000),
268*069f0b63SChristophe Kerello 	STPMU1_RANGE(3300000, 25, 31, 0),
269*069f0b63SChristophe Kerello };
270*069f0b63SChristophe Kerello 
271*069f0b63SChristophe Kerello static const struct stpmu1_range ldo3_ranges[] = {
272*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 0, 7, 0),
273*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 8, 24, 100000),
274*069f0b63SChristophe Kerello 	STPMU1_RANGE(3300000, 25, 30, 0),
275*069f0b63SChristophe Kerello 	/* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */
276*069f0b63SChristophe Kerello };
277*069f0b63SChristophe Kerello 
278*069f0b63SChristophe Kerello static const struct stpmu1_range ldo5_ranges[] = {
279*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 0, 7, 0),
280*069f0b63SChristophe Kerello 	STPMU1_RANGE(1700000, 8, 30, 100000),
281*069f0b63SChristophe Kerello 	STPMU1_RANGE(3900000, 31, 31, 0),
282*069f0b63SChristophe Kerello };
283*069f0b63SChristophe Kerello 
284*069f0b63SChristophe Kerello static const struct stpmu1_range ldo6_ranges[] = {
285*069f0b63SChristophe Kerello 	STPMU1_RANGE(900000, 0, 24, 100000),
286*069f0b63SChristophe Kerello 	STPMU1_RANGE(3300000, 25, 31, 0),
287*069f0b63SChristophe Kerello };
288*069f0b63SChristophe Kerello 
289*069f0b63SChristophe Kerello /* LDO: 1,2,3,4,5,6 - voltage ranges */
290*069f0b63SChristophe Kerello static const struct stpmu1_output_range ldo_voltage_range[] = {
291*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
292*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
293*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)),
294*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(NULL, 0),
295*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)),
296*069f0b63SChristophe Kerello 	STPMU1_OUTPUT_RANGE(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)),
297*069f0b63SChristophe Kerello };
298*069f0b63SChristophe Kerello 
299*069f0b63SChristophe Kerello /* LDO modes */
300*069f0b63SChristophe Kerello static const struct dm_regulator_mode ldo_modes[] = {
301*069f0b63SChristophe Kerello 	STPMU1_MODE(STPMU1_LDO_MODE_NORMAL,
302*069f0b63SChristophe Kerello 		    STPMU1_LDO_MODE_NORMAL, "NORMAL"),
303*069f0b63SChristophe Kerello 	STPMU1_MODE(STPMU1_LDO_MODE_BYPASS,
304*069f0b63SChristophe Kerello 		    STPMU1_LDO_MODE_BYPASS, "BYPASS"),
305*069f0b63SChristophe Kerello 	STPMU1_MODE(STPMU1_LDO_MODE_SINK_SOURCE,
306*069f0b63SChristophe Kerello 		    STPMU1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"),
307*069f0b63SChristophe Kerello };
308*069f0b63SChristophe Kerello 
309*069f0b63SChristophe Kerello static int stpmu1_ldo_get_value(struct udevice *dev)
310*069f0b63SChristophe Kerello {
311*069f0b63SChristophe Kerello 	int sel, ldo = dev->driver_data - 1;
312*069f0b63SChristophe Kerello 
313*069f0b63SChristophe Kerello 	sel = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
314*069f0b63SChristophe Kerello 	if (sel < 0)
315*069f0b63SChristophe Kerello 		return sel;
316*069f0b63SChristophe Kerello 
317*069f0b63SChristophe Kerello 	/* ldo4 => 3,3V */
318*069f0b63SChristophe Kerello 	if (ldo == STPMU1_LDO4)
319*069f0b63SChristophe Kerello 		return STPMU1_LDO4_UV;
320*069f0b63SChristophe Kerello 
321*069f0b63SChristophe Kerello 	sel &= STPMU1_LDO12356_OUTPUT_MASK;
322*069f0b63SChristophe Kerello 	sel >>= STPMU1_LDO12356_OUTPUT_SHIFT;
323*069f0b63SChristophe Kerello 
324*069f0b63SChristophe Kerello 	/* ldo3, sel = 31 => BUCK2/2 */
325*069f0b63SChristophe Kerello 	if (ldo == STPMU1_LDO3 && sel == STPMU1_LDO3_DDR_SEL)
326*069f0b63SChristophe Kerello 		return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
327*069f0b63SChristophe Kerello 
328*069f0b63SChristophe Kerello 	return stpmu1_output_find_uv(sel, &ldo_voltage_range[ldo]);
329*069f0b63SChristophe Kerello }
330*069f0b63SChristophe Kerello 
331*069f0b63SChristophe Kerello static int stpmu1_ldo_set_value(struct udevice *dev, int uv)
332*069f0b63SChristophe Kerello {
333*069f0b63SChristophe Kerello 	int sel, ldo = dev->driver_data - 1;
334*069f0b63SChristophe Kerello 
335*069f0b63SChristophe Kerello 	/* ldo4 => not possible */
336*069f0b63SChristophe Kerello 	if (ldo == STPMU1_LDO4)
337*069f0b63SChristophe Kerello 		return -EINVAL;
338*069f0b63SChristophe Kerello 
339*069f0b63SChristophe Kerello 	sel = stpmu1_output_find_sel(uv, &ldo_voltage_range[ldo]);
340*069f0b63SChristophe Kerello 	if (sel < 0)
341*069f0b63SChristophe Kerello 		return sel;
342*069f0b63SChristophe Kerello 
343*069f0b63SChristophe Kerello 	return pmic_clrsetbits(dev->parent,
344*069f0b63SChristophe Kerello 			       STPMU1_LDOX_CTRL_REG(ldo),
345*069f0b63SChristophe Kerello 			       STPMU1_LDO12356_OUTPUT_MASK,
346*069f0b63SChristophe Kerello 			       sel << STPMU1_LDO12356_OUTPUT_SHIFT);
347*069f0b63SChristophe Kerello }
348*069f0b63SChristophe Kerello 
349*069f0b63SChristophe Kerello static int stpmu1_ldo_get_enable(struct udevice *dev)
350*069f0b63SChristophe Kerello {
351*069f0b63SChristophe Kerello 	int ret;
352*069f0b63SChristophe Kerello 
353*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent,
354*069f0b63SChristophe Kerello 			    STPMU1_LDOX_CTRL_REG(dev->driver_data - 1));
355*069f0b63SChristophe Kerello 	if (ret < 0)
356*069f0b63SChristophe Kerello 		return false;
357*069f0b63SChristophe Kerello 
358*069f0b63SChristophe Kerello 	return ret & STPMU1_LDO_EN ? true : false;
359*069f0b63SChristophe Kerello }
360*069f0b63SChristophe Kerello 
361*069f0b63SChristophe Kerello static int stpmu1_ldo_set_enable(struct udevice *dev, bool enable)
362*069f0b63SChristophe Kerello {
363*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
364*069f0b63SChristophe Kerello 	int ret, uv;
365*069f0b63SChristophe Kerello 
366*069f0b63SChristophe Kerello 	/* if regulator is already in the wanted state, nothing to do */
367*069f0b63SChristophe Kerello 	if (stpmu1_ldo_get_enable(dev) == enable)
368*069f0b63SChristophe Kerello 		return 0;
369*069f0b63SChristophe Kerello 
370*069f0b63SChristophe Kerello 	if (enable) {
371*069f0b63SChristophe Kerello 		uc_pdata = dev_get_uclass_platdata(dev);
372*069f0b63SChristophe Kerello 		uv = stpmu1_ldo_get_value(dev);
373*069f0b63SChristophe Kerello 		if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
374*069f0b63SChristophe Kerello 			stpmu1_ldo_set_value(dev, uc_pdata->min_uV);
375*069f0b63SChristophe Kerello 	}
376*069f0b63SChristophe Kerello 
377*069f0b63SChristophe Kerello 	ret = pmic_clrsetbits(dev->parent,
378*069f0b63SChristophe Kerello 			      STPMU1_LDOX_CTRL_REG(dev->driver_data - 1),
379*069f0b63SChristophe Kerello 			      STPMU1_LDO_EN, enable ? STPMU1_LDO_EN : 0);
380*069f0b63SChristophe Kerello 	if (enable)
381*069f0b63SChristophe Kerello 		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
382*069f0b63SChristophe Kerello 
383*069f0b63SChristophe Kerello 	return ret;
384*069f0b63SChristophe Kerello }
385*069f0b63SChristophe Kerello 
386*069f0b63SChristophe Kerello static int stpmu1_ldo_get_mode(struct udevice *dev)
387*069f0b63SChristophe Kerello {
388*069f0b63SChristophe Kerello 	int ret, ldo = dev->driver_data - 1;
389*069f0b63SChristophe Kerello 
390*069f0b63SChristophe Kerello 	if (ldo != STPMU1_LDO3)
391*069f0b63SChristophe Kerello 		return -EINVAL;
392*069f0b63SChristophe Kerello 
393*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
394*069f0b63SChristophe Kerello 	if (ret < 0)
395*069f0b63SChristophe Kerello 		return ret;
396*069f0b63SChristophe Kerello 
397*069f0b63SChristophe Kerello 	if (ret & STPMU1_LDO3_MODE)
398*069f0b63SChristophe Kerello 		return STPMU1_LDO_MODE_BYPASS;
399*069f0b63SChristophe Kerello 
400*069f0b63SChristophe Kerello 	ret &= STPMU1_LDO12356_OUTPUT_MASK;
401*069f0b63SChristophe Kerello 	ret >>= STPMU1_LDO12356_OUTPUT_SHIFT;
402*069f0b63SChristophe Kerello 
403*069f0b63SChristophe Kerello 	return ret == STPMU1_LDO3_DDR_SEL ? STPMU1_LDO_MODE_SINK_SOURCE :
404*069f0b63SChristophe Kerello 					     STPMU1_LDO_MODE_NORMAL;
405*069f0b63SChristophe Kerello }
406*069f0b63SChristophe Kerello 
407*069f0b63SChristophe Kerello static int stpmu1_ldo_set_mode(struct udevice *dev, int mode)
408*069f0b63SChristophe Kerello {
409*069f0b63SChristophe Kerello 	int ret, ldo = dev->driver_data - 1;
410*069f0b63SChristophe Kerello 
411*069f0b63SChristophe Kerello 	if (ldo != STPMU1_LDO3)
412*069f0b63SChristophe Kerello 		return -EINVAL;
413*069f0b63SChristophe Kerello 
414*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
415*069f0b63SChristophe Kerello 	if (ret < 0)
416*069f0b63SChristophe Kerello 		return ret;
417*069f0b63SChristophe Kerello 
418*069f0b63SChristophe Kerello 	switch (mode) {
419*069f0b63SChristophe Kerello 	case STPMU1_LDO_MODE_SINK_SOURCE:
420*069f0b63SChristophe Kerello 		ret &= ~STPMU1_LDO12356_OUTPUT_MASK;
421*069f0b63SChristophe Kerello 		ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
422*069f0b63SChristophe Kerello 	case STPMU1_LDO_MODE_NORMAL:
423*069f0b63SChristophe Kerello 		ret &= ~STPMU1_LDO3_MODE;
424*069f0b63SChristophe Kerello 		break;
425*069f0b63SChristophe Kerello 	case STPMU1_LDO_MODE_BYPASS:
426*069f0b63SChristophe Kerello 		ret |= STPMU1_LDO3_MODE;
427*069f0b63SChristophe Kerello 		break;
428*069f0b63SChristophe Kerello 	}
429*069f0b63SChristophe Kerello 
430*069f0b63SChristophe Kerello 	return pmic_reg_write(dev->parent, STPMU1_LDOX_CTRL_REG(ldo), ret);
431*069f0b63SChristophe Kerello }
432*069f0b63SChristophe Kerello 
433*069f0b63SChristophe Kerello static int stpmu1_ldo_probe(struct udevice *dev)
434*069f0b63SChristophe Kerello {
435*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
436*069f0b63SChristophe Kerello 
437*069f0b63SChristophe Kerello 	if (!dev->driver_data || dev->driver_data > STPMU1_MAX_LDO)
438*069f0b63SChristophe Kerello 		return -EINVAL;
439*069f0b63SChristophe Kerello 
440*069f0b63SChristophe Kerello 	uc_pdata = dev_get_uclass_platdata(dev);
441*069f0b63SChristophe Kerello 
442*069f0b63SChristophe Kerello 	uc_pdata->type = REGULATOR_TYPE_LDO;
443*069f0b63SChristophe Kerello 	if (dev->driver_data - 1 == STPMU1_LDO3) {
444*069f0b63SChristophe Kerello 		uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes;
445*069f0b63SChristophe Kerello 		uc_pdata->mode_count = ARRAY_SIZE(ldo_modes);
446*069f0b63SChristophe Kerello 	} else {
447*069f0b63SChristophe Kerello 		uc_pdata->mode_count = 0;
448*069f0b63SChristophe Kerello 	}
449*069f0b63SChristophe Kerello 
450*069f0b63SChristophe Kerello 	return 0;
451*069f0b63SChristophe Kerello }
452*069f0b63SChristophe Kerello 
453*069f0b63SChristophe Kerello static const struct dm_regulator_ops stpmu1_ldo_ops = {
454*069f0b63SChristophe Kerello 	.get_value  = stpmu1_ldo_get_value,
455*069f0b63SChristophe Kerello 	.set_value  = stpmu1_ldo_set_value,
456*069f0b63SChristophe Kerello 	.get_enable = stpmu1_ldo_get_enable,
457*069f0b63SChristophe Kerello 	.set_enable = stpmu1_ldo_set_enable,
458*069f0b63SChristophe Kerello 	.get_mode   = stpmu1_ldo_get_mode,
459*069f0b63SChristophe Kerello 	.set_mode   = stpmu1_ldo_set_mode,
460*069f0b63SChristophe Kerello };
461*069f0b63SChristophe Kerello 
462*069f0b63SChristophe Kerello U_BOOT_DRIVER(stpmu1_ldo) = {
463*069f0b63SChristophe Kerello 	.name = "stpmu1_ldo",
464*069f0b63SChristophe Kerello 	.id = UCLASS_REGULATOR,
465*069f0b63SChristophe Kerello 	.ops = &stpmu1_ldo_ops,
466*069f0b63SChristophe Kerello 	.probe = stpmu1_ldo_probe,
467*069f0b63SChristophe Kerello };
468*069f0b63SChristophe Kerello 
469*069f0b63SChristophe Kerello /*
470*069f0b63SChristophe Kerello  * VREF DDR regulator
471*069f0b63SChristophe Kerello  */
472*069f0b63SChristophe Kerello 
473*069f0b63SChristophe Kerello static int stpmu1_vref_ddr_get_value(struct udevice *dev)
474*069f0b63SChristophe Kerello {
475*069f0b63SChristophe Kerello 	/* BUCK2/2 */
476*069f0b63SChristophe Kerello 	return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
477*069f0b63SChristophe Kerello }
478*069f0b63SChristophe Kerello 
479*069f0b63SChristophe Kerello static int stpmu1_vref_ddr_get_enable(struct udevice *dev)
480*069f0b63SChristophe Kerello {
481*069f0b63SChristophe Kerello 	int ret;
482*069f0b63SChristophe Kerello 
483*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_VREF_CTRL_REG);
484*069f0b63SChristophe Kerello 	if (ret < 0)
485*069f0b63SChristophe Kerello 		return false;
486*069f0b63SChristophe Kerello 
487*069f0b63SChristophe Kerello 	return ret & STPMU1_VREF_EN ? true : false;
488*069f0b63SChristophe Kerello }
489*069f0b63SChristophe Kerello 
490*069f0b63SChristophe Kerello static int stpmu1_vref_ddr_set_enable(struct udevice *dev, bool enable)
491*069f0b63SChristophe Kerello {
492*069f0b63SChristophe Kerello 	int ret;
493*069f0b63SChristophe Kerello 
494*069f0b63SChristophe Kerello 	/* if regulator is already in the wanted state, nothing to do */
495*069f0b63SChristophe Kerello 	if (stpmu1_vref_ddr_get_enable(dev) == enable)
496*069f0b63SChristophe Kerello 		return 0;
497*069f0b63SChristophe Kerello 
498*069f0b63SChristophe Kerello 	ret = pmic_clrsetbits(dev->parent, STPMU1_VREF_CTRL_REG,
499*069f0b63SChristophe Kerello 			      STPMU1_VREF_EN, enable ? STPMU1_VREF_EN : 0);
500*069f0b63SChristophe Kerello 	if (enable)
501*069f0b63SChristophe Kerello 		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
502*069f0b63SChristophe Kerello 
503*069f0b63SChristophe Kerello 	return ret;
504*069f0b63SChristophe Kerello }
505*069f0b63SChristophe Kerello 
506*069f0b63SChristophe Kerello static int stpmu1_vref_ddr_probe(struct udevice *dev)
507*069f0b63SChristophe Kerello {
508*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
509*069f0b63SChristophe Kerello 
510*069f0b63SChristophe Kerello 	uc_pdata = dev_get_uclass_platdata(dev);
511*069f0b63SChristophe Kerello 
512*069f0b63SChristophe Kerello 	uc_pdata->type = REGULATOR_TYPE_FIXED;
513*069f0b63SChristophe Kerello 	uc_pdata->mode_count = 0;
514*069f0b63SChristophe Kerello 
515*069f0b63SChristophe Kerello 	return 0;
516*069f0b63SChristophe Kerello }
517*069f0b63SChristophe Kerello 
518*069f0b63SChristophe Kerello static const struct dm_regulator_ops stpmu1_vref_ddr_ops = {
519*069f0b63SChristophe Kerello 	.get_value  = stpmu1_vref_ddr_get_value,
520*069f0b63SChristophe Kerello 	.get_enable = stpmu1_vref_ddr_get_enable,
521*069f0b63SChristophe Kerello 	.set_enable = stpmu1_vref_ddr_set_enable,
522*069f0b63SChristophe Kerello };
523*069f0b63SChristophe Kerello 
524*069f0b63SChristophe Kerello U_BOOT_DRIVER(stpmu1_vref_ddr) = {
525*069f0b63SChristophe Kerello 	.name = "stpmu1_vref_ddr",
526*069f0b63SChristophe Kerello 	.id = UCLASS_REGULATOR,
527*069f0b63SChristophe Kerello 	.ops = &stpmu1_vref_ddr_ops,
528*069f0b63SChristophe Kerello 	.probe = stpmu1_vref_ddr_probe,
529*069f0b63SChristophe Kerello };
530*069f0b63SChristophe Kerello 
531*069f0b63SChristophe Kerello /*
532*069f0b63SChristophe Kerello  * BOOST regulator
533*069f0b63SChristophe Kerello  */
534*069f0b63SChristophe Kerello 
535*069f0b63SChristophe Kerello static int stpmu1_boost_get_enable(struct udevice *dev)
536*069f0b63SChristophe Kerello {
537*069f0b63SChristophe Kerello 	int ret;
538*069f0b63SChristophe Kerello 
539*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
540*069f0b63SChristophe Kerello 	if (ret < 0)
541*069f0b63SChristophe Kerello 		return false;
542*069f0b63SChristophe Kerello 
543*069f0b63SChristophe Kerello 	return ret & STPMU1_USB_BOOST_EN ? true : false;
544*069f0b63SChristophe Kerello }
545*069f0b63SChristophe Kerello 
546*069f0b63SChristophe Kerello static int stpmu1_boost_set_enable(struct udevice *dev, bool enable)
547*069f0b63SChristophe Kerello {
548*069f0b63SChristophe Kerello 	int ret;
549*069f0b63SChristophe Kerello 
550*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
551*069f0b63SChristophe Kerello 	if (ret < 0)
552*069f0b63SChristophe Kerello 		return ret;
553*069f0b63SChristophe Kerello 
554*069f0b63SChristophe Kerello 	if (!enable && ret & STPMU1_USB_PWR_SW_EN)
555*069f0b63SChristophe Kerello 		return -EINVAL;
556*069f0b63SChristophe Kerello 
557*069f0b63SChristophe Kerello 	/* if regulator is already in the wanted state, nothing to do */
558*069f0b63SChristophe Kerello 	if (!!(ret & STPMU1_USB_BOOST_EN) == enable)
559*069f0b63SChristophe Kerello 		return 0;
560*069f0b63SChristophe Kerello 
561*069f0b63SChristophe Kerello 	ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
562*069f0b63SChristophe Kerello 			      STPMU1_USB_BOOST_EN,
563*069f0b63SChristophe Kerello 			      enable ? STPMU1_USB_BOOST_EN : 0);
564*069f0b63SChristophe Kerello 	if (enable)
565*069f0b63SChristophe Kerello 		mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
566*069f0b63SChristophe Kerello 
567*069f0b63SChristophe Kerello 	return ret;
568*069f0b63SChristophe Kerello }
569*069f0b63SChristophe Kerello 
570*069f0b63SChristophe Kerello static int stpmu1_boost_probe(struct udevice *dev)
571*069f0b63SChristophe Kerello {
572*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
573*069f0b63SChristophe Kerello 
574*069f0b63SChristophe Kerello 	uc_pdata = dev_get_uclass_platdata(dev);
575*069f0b63SChristophe Kerello 
576*069f0b63SChristophe Kerello 	uc_pdata->type = REGULATOR_TYPE_FIXED;
577*069f0b63SChristophe Kerello 	uc_pdata->mode_count = 0;
578*069f0b63SChristophe Kerello 
579*069f0b63SChristophe Kerello 	return 0;
580*069f0b63SChristophe Kerello }
581*069f0b63SChristophe Kerello 
582*069f0b63SChristophe Kerello static const struct dm_regulator_ops stpmu1_boost_ops = {
583*069f0b63SChristophe Kerello 	.get_enable = stpmu1_boost_get_enable,
584*069f0b63SChristophe Kerello 	.set_enable = stpmu1_boost_set_enable,
585*069f0b63SChristophe Kerello };
586*069f0b63SChristophe Kerello 
587*069f0b63SChristophe Kerello U_BOOT_DRIVER(stpmu1_boost) = {
588*069f0b63SChristophe Kerello 	.name = "stpmu1_boost",
589*069f0b63SChristophe Kerello 	.id = UCLASS_REGULATOR,
590*069f0b63SChristophe Kerello 	.ops = &stpmu1_boost_ops,
591*069f0b63SChristophe Kerello 	.probe = stpmu1_boost_probe,
592*069f0b63SChristophe Kerello };
593*069f0b63SChristophe Kerello 
594*069f0b63SChristophe Kerello /*
595*069f0b63SChristophe Kerello  * USB power switch
596*069f0b63SChristophe Kerello  */
597*069f0b63SChristophe Kerello 
598*069f0b63SChristophe Kerello static int stpmu1_pwr_sw_get_enable(struct udevice *dev)
599*069f0b63SChristophe Kerello {
600*069f0b63SChristophe Kerello 	uint mask = 1 << dev->driver_data;
601*069f0b63SChristophe Kerello 	int ret;
602*069f0b63SChristophe Kerello 
603*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
604*069f0b63SChristophe Kerello 	if (ret < 0)
605*069f0b63SChristophe Kerello 		return false;
606*069f0b63SChristophe Kerello 
607*069f0b63SChristophe Kerello 	return ret & mask ? true : false;
608*069f0b63SChristophe Kerello }
609*069f0b63SChristophe Kerello 
610*069f0b63SChristophe Kerello static int stpmu1_pwr_sw_set_enable(struct udevice *dev, bool enable)
611*069f0b63SChristophe Kerello {
612*069f0b63SChristophe Kerello 	uint mask = 1 << dev->driver_data;
613*069f0b63SChristophe Kerello 	int ret;
614*069f0b63SChristophe Kerello 
615*069f0b63SChristophe Kerello 	ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
616*069f0b63SChristophe Kerello 	if (ret < 0)
617*069f0b63SChristophe Kerello 		return ret;
618*069f0b63SChristophe Kerello 
619*069f0b63SChristophe Kerello 	/* if regulator is already in the wanted state, nothing to do */
620*069f0b63SChristophe Kerello 	if (!!(ret & mask) == enable)
621*069f0b63SChristophe Kerello 		return 0;
622*069f0b63SChristophe Kerello 
623*069f0b63SChristophe Kerello 	/* Boost management */
624*069f0b63SChristophe Kerello 	if (enable && !(ret & STPMU1_USB_BOOST_EN)) {
625*069f0b63SChristophe Kerello 		pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
626*069f0b63SChristophe Kerello 				STPMU1_USB_BOOST_EN, STPMU1_USB_BOOST_EN);
627*069f0b63SChristophe Kerello 		mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
628*069f0b63SChristophe Kerello 	} else if (!enable && ret & STPMU1_USB_BOOST_EN &&
629*069f0b63SChristophe Kerello 		   (ret & STPMU1_USB_PWR_SW_EN) != STPMU1_USB_PWR_SW_EN) {
630*069f0b63SChristophe Kerello 		pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
631*069f0b63SChristophe Kerello 				STPMU1_USB_BOOST_EN, 0);
632*069f0b63SChristophe Kerello 	}
633*069f0b63SChristophe Kerello 
634*069f0b63SChristophe Kerello 	ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
635*069f0b63SChristophe Kerello 			      mask, enable ? mask : 0);
636*069f0b63SChristophe Kerello 	if (enable)
637*069f0b63SChristophe Kerello 		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
638*069f0b63SChristophe Kerello 
639*069f0b63SChristophe Kerello 	return ret;
640*069f0b63SChristophe Kerello }
641*069f0b63SChristophe Kerello 
642*069f0b63SChristophe Kerello static int stpmu1_pwr_sw_probe(struct udevice *dev)
643*069f0b63SChristophe Kerello {
644*069f0b63SChristophe Kerello 	struct dm_regulator_uclass_platdata *uc_pdata;
645*069f0b63SChristophe Kerello 
646*069f0b63SChristophe Kerello 	if (!dev->driver_data || dev->driver_data > STPMU1_MAX_PWR_SW)
647*069f0b63SChristophe Kerello 		return -EINVAL;
648*069f0b63SChristophe Kerello 
649*069f0b63SChristophe Kerello 	uc_pdata = dev_get_uclass_platdata(dev);
650*069f0b63SChristophe Kerello 
651*069f0b63SChristophe Kerello 	uc_pdata->type = REGULATOR_TYPE_FIXED;
652*069f0b63SChristophe Kerello 	uc_pdata->mode_count = 0;
653*069f0b63SChristophe Kerello 
654*069f0b63SChristophe Kerello 	return 0;
655*069f0b63SChristophe Kerello }
656*069f0b63SChristophe Kerello 
657*069f0b63SChristophe Kerello static const struct dm_regulator_ops stpmu1_pwr_sw_ops = {
658*069f0b63SChristophe Kerello 	.get_enable = stpmu1_pwr_sw_get_enable,
659*069f0b63SChristophe Kerello 	.set_enable = stpmu1_pwr_sw_set_enable,
660*069f0b63SChristophe Kerello };
661*069f0b63SChristophe Kerello 
662*069f0b63SChristophe Kerello U_BOOT_DRIVER(stpmu1_pwr_sw) = {
663*069f0b63SChristophe Kerello 	.name = "stpmu1_pwr_sw",
664*069f0b63SChristophe Kerello 	.id = UCLASS_REGULATOR,
665*069f0b63SChristophe Kerello 	.ops = &stpmu1_pwr_sw_ops,
666*069f0b63SChristophe Kerello 	.probe = stpmu1_pwr_sw_probe,
667*069f0b63SChristophe Kerello };
668