1 /*
2  * Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <power/pmic.h>
10 #include <power/regulator.h>
11 #include <power/tps65910_pmic.h>
12 
13 #define VOUT_CHOICE_COUNT 4
14 
15 /*
16  * struct regulator_props - Properties of a LDO and VIO SMPS regulator
17  *
18  * All of these regulators allow setting one out of four output voltages.
19  * These output voltages are only achievable when supplying the regulator
20  * with a minimum input voltage.
21  *
22  * @vin_min[]: minimum supply input voltage in uV required to achieve the
23  *             corresponding vout[] voltage
24  * @vout[]:    regulator output voltage in uV
25  * @reg:       I2C register used to set regulator voltage
26  */
27 struct regulator_props {
28 	int vin_min[VOUT_CHOICE_COUNT];
29 	int vout[VOUT_CHOICE_COUNT];
30 	int reg;
31 };
32 
33 static const struct regulator_props ldo_props_vdig1 = {
34 	.vin_min = { 1700000, 2100000, 2700000, 3200000 },
35 	.vout = { 1200000, 1500000, 1800000, 2700000 },
36 	.reg = TPS65910_REG_VDIG1
37 };
38 
39 static const struct regulator_props ldo_props_vdig2 = {
40 	.vin_min = { 1700000, 1700000, 1700000, 2700000 },
41 	.vout = { 1000000, 1100000, 1200000, 1800000 },
42 	.reg = TPS65910_REG_VDIG2
43 };
44 
45 static const struct regulator_props ldo_props_vpll = {
46 	.vin_min = { 2700000, 2700000, 2700000, 3000000 },
47 	.vout = { 1000000, 1100000, 1800000, 2500000 },
48 	.reg = TPS65910_REG_VPLL
49 };
50 
51 static const struct regulator_props ldo_props_vdac = {
52 	.vin_min = { 2700000, 3000000, 3200000, 3200000 },
53 	.vout = { 1800000, 2600000, 2800000, 2850000 },
54 	.reg = TPS65910_REG_VDAC
55 };
56 
57 static const struct regulator_props ldo_props_vaux1 = {
58 	.vin_min = { 2700000, 3200000, 3200000, 3200000 },
59 	.vout = { 1800000, 2500000, 2800000, 2850000 },
60 	.reg = TPS65910_REG_VAUX1
61 };
62 
63 static const struct regulator_props ldo_props_vaux2 = {
64 	.vin_min = { 2700000, 3200000, 3200000, 3600000 },
65 	.vout = { 1800000, 2800000, 2900000, 3300000 },
66 	.reg = TPS65910_REG_VAUX2
67 };
68 
69 static const struct regulator_props ldo_props_vaux33 = {
70 	.vin_min = { 2700000, 2700000, 3200000, 3600000 },
71 	.vout = { 1800000, 2000000, 2800000, 3300000 },
72 	.reg = TPS65910_REG_VAUX33
73 };
74 
75 static const struct regulator_props ldo_props_vmmc = {
76 	.vin_min = { 2700000, 3200000, 3200000, 3600000 },
77 	.vout = { 1800000, 2800000, 3000000, 3300000 },
78 	.reg = TPS65910_REG_VMMC
79 };
80 
81 static const struct regulator_props smps_props_vio = {
82 	.vin_min = { 3200000, 3200000, 4000000, 4400000 },
83 	.vout = { 1500000, 1800000, 2500000, 3300000 },
84 	.reg = TPS65910_REG_VIO
85 };
86 
87 /* lookup table of control registers indexed by regulator unit number */
88 static const int ctrl_regs[] = {
89 	TPS65910_REG_VRTC,
90 	TPS65910_REG_VIO,
91 	TPS65910_REG_VDD1,
92 	TPS65910_REG_VDD2,
93 	TPS65910_REG_VDD3,
94 	TPS65910_REG_VDIG1,
95 	TPS65910_REG_VDIG2,
96 	TPS65910_REG_VPLL,
97 	TPS65910_REG_VDAC,
98 	TPS65910_REG_VAUX1,
99 	TPS65910_REG_VAUX2,
100 	TPS65910_REG_VAUX33,
101 	TPS65910_REG_VMMC
102 };
103 
104 /* supply names as used in DT */
105 static const char * const supply_names[] = {
106 	"vccio-supply",
107 	"vcc1-supply",
108 	"vcc2-supply",
109 	"vcc3-supply",
110 	"vcc4-supply",
111 	"vcc5-supply",
112 	"vcc6-supply",
113 	"vcc7-supply"
114 };
115 
116 /* lookup table of regulator supplies indexed by regulator unit number */
117 static const int regulator_supplies[] = {
118 	TPS65910_SUPPLY_VCC7,
119 	TPS65910_SUPPLY_VCCIO,
120 	TPS65910_SUPPLY_VCC1,
121 	TPS65910_SUPPLY_VCC2,
122 	TPS65910_SUPPLY_VCC7,
123 	TPS65910_SUPPLY_VCC6,
124 	TPS65910_SUPPLY_VCC6,
125 	TPS65910_SUPPLY_VCC5,
126 	TPS65910_SUPPLY_VCC5,
127 	TPS65910_SUPPLY_VCC4,
128 	TPS65910_SUPPLY_VCC4,
129 	TPS65910_SUPPLY_VCC3,
130 	TPS65910_SUPPLY_VCC3
131 };
132 
133 static int get_ctrl_reg_from_unit_addr(const uint unit_addr)
134 {
135 	if (unit_addr < ARRAY_SIZE(ctrl_regs))
136 		return ctrl_regs[unit_addr];
137 	return -ENXIO;
138 }
139 
140 static int tps65910_regulator_get_value(struct udevice *dev,
141 					const struct regulator_props *rgp)
142 {
143 	int sel, val, vout;
144 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
145 	int vin = pdata->supply;
146 
147 	val = pmic_reg_read(dev->parent, rgp->reg);
148 	if (val < 0)
149 		return val;
150 	sel = (val & TPS65910_SEL_MASK) >> 2;
151 	vout = (vin >= *(rgp->vin_min + sel)) ? *(rgp->vout + sel) : 0;
152 	vout = ((val & TPS65910_SUPPLY_STATE_MASK) == 1) ? vout : 0;
153 
154 	return vout;
155 }
156 
157 static int tps65910_ldo_get_value(struct udevice *dev)
158 {
159 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
160 	int vin;
161 
162 	if (!pdata)
163 		return 0;
164 	vin = pdata->supply;
165 
166 	switch (pdata->unit) {
167 	case TPS65910_UNIT_VRTC:
168 		/* VRTC is fixed and can't be turned off */
169 		return (vin >= 2500000) ? 1830000 : 0;
170 	case TPS65910_UNIT_VDIG1:
171 		return tps65910_regulator_get_value(dev, &ldo_props_vdig1);
172 	case TPS65910_UNIT_VDIG2:
173 		return tps65910_regulator_get_value(dev, &ldo_props_vdig2);
174 	case TPS65910_UNIT_VPLL:
175 		return tps65910_regulator_get_value(dev, &ldo_props_vpll);
176 	case TPS65910_UNIT_VDAC:
177 		return tps65910_regulator_get_value(dev, &ldo_props_vdac);
178 	case TPS65910_UNIT_VAUX1:
179 		return tps65910_regulator_get_value(dev, &ldo_props_vaux1);
180 	case TPS65910_UNIT_VAUX2:
181 		return tps65910_regulator_get_value(dev, &ldo_props_vaux2);
182 	case TPS65910_UNIT_VAUX33:
183 		return tps65910_regulator_get_value(dev, &ldo_props_vaux33);
184 	case TPS65910_UNIT_VMMC:
185 		return tps65910_regulator_get_value(dev, &ldo_props_vmmc);
186 	default:
187 		return 0;
188 	}
189 }
190 
191 static int tps65910_regulator_set_value(struct udevice *dev,
192 					const struct regulator_props *ldo,
193 					int uV)
194 {
195 	int val;
196 	int sel = 0;
197 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
198 
199 	do {
200 		/* we only allow exact voltage matches */
201 		if (uV == *(ldo->vout + sel))
202 			break;
203 	} while (++sel < VOUT_CHOICE_COUNT);
204 	if (sel == VOUT_CHOICE_COUNT)
205 		return -EINVAL;
206 	if (pdata->supply < *(ldo->vin_min + sel))
207 		return -EINVAL;
208 
209 	val = pmic_reg_read(dev->parent, ldo->reg);
210 	if (val < 0)
211 		return val;
212 	val &= ~TPS65910_SEL_MASK;
213 	val |= sel << 2;
214 	return pmic_reg_write(dev->parent, ldo->reg, val);
215 }
216 
217 static int tps65910_ldo_set_value(struct udevice *dev, int uV)
218 {
219 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
220 	int vin = pdata->supply;
221 
222 	switch (pdata->unit) {
223 	case TPS65910_UNIT_VRTC:
224 		/* VRTC is fixed to 1.83V and can't be turned off */
225 		if (vin < 2500000)
226 			return -EINVAL;
227 		return 0;
228 	case TPS65910_UNIT_VDIG1:
229 		return tps65910_regulator_set_value(dev, &ldo_props_vdig1, uV);
230 	case TPS65910_UNIT_VDIG2:
231 		return tps65910_regulator_set_value(dev, &ldo_props_vdig2, uV);
232 	case TPS65910_UNIT_VPLL:
233 		return tps65910_regulator_set_value(dev, &ldo_props_vpll, uV);
234 	case TPS65910_UNIT_VDAC:
235 		return tps65910_regulator_set_value(dev, &ldo_props_vdac, uV);
236 	case TPS65910_UNIT_VAUX1:
237 		return tps65910_regulator_set_value(dev, &ldo_props_vaux1, uV);
238 	case TPS65910_UNIT_VAUX2:
239 		return tps65910_regulator_set_value(dev, &ldo_props_vaux2, uV);
240 	case TPS65910_UNIT_VAUX33:
241 		return tps65910_regulator_set_value(dev, &ldo_props_vaux33, uV);
242 	case TPS65910_UNIT_VMMC:
243 		return tps65910_regulator_set_value(dev, &ldo_props_vmmc, uV);
244 	default:
245 		return 0;
246 	}
247 }
248 
249 static int tps65910_get_enable(struct udevice *dev)
250 {
251 	int reg, val;
252 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
253 
254 	reg = get_ctrl_reg_from_unit_addr(pdata->unit);
255 	if (reg < 0)
256 		return reg;
257 
258 	val = pmic_reg_read(dev->parent, reg);
259 	if (val < 0)
260 		return val;
261 
262 	/* bits 1:0 of regulator control register define state */
263 	return ((val & TPS65910_SUPPLY_STATE_MASK) == 1);
264 }
265 
266 static int tps65910_set_enable(struct udevice *dev, bool enable)
267 {
268 	int reg;
269 	uint clr, set;
270 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
271 
272 	reg = get_ctrl_reg_from_unit_addr(pdata->unit);
273 	if (reg < 0)
274 		return reg;
275 
276 	if (enable) {
277 		clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_ON;
278 		set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_ON;
279 	} else {
280 		clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_OFF;
281 		set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_OFF;
282 	}
283 	return pmic_clrsetbits(dev->parent, reg, clr, set);
284 }
285 
286 static int buck_get_vdd1_vdd2_value(struct udevice *dev, int reg_vdd)
287 {
288 	int gain;
289 	int val = pmic_reg_read(dev, reg_vdd);
290 
291 	if (val < 0)
292 		return val;
293 	gain = (val & TPS65910_GAIN_SEL_MASK) >> 6;
294 	gain = (gain == 0) ? 1 : gain;
295 	val = pmic_reg_read(dev, reg_vdd + 1);
296 	if (val < 0)
297 		return val;
298 	if (val & TPS65910_VDD_SR_MASK)
299 		/* use smart reflex value instead */
300 		val = pmic_reg_read(dev, reg_vdd + 2);
301 	if (val < 0)
302 		return val;
303 	return (562500 + (val & TPS65910_VDD_SEL_MASK) * 12500) * gain;
304 }
305 
306 static int tps65910_buck_get_value(struct udevice *dev)
307 {
308 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
309 
310 	switch (pdata->unit) {
311 	case TPS65910_UNIT_VIO:
312 		return tps65910_regulator_get_value(dev, &smps_props_vio);
313 	case TPS65910_UNIT_VDD1:
314 		return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD1);
315 	case TPS65910_UNIT_VDD2:
316 		return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD2);
317 	default:
318 		return 0;
319 	}
320 }
321 
322 static int buck_set_vdd1_vdd2_value(struct udevice *dev, int uV)
323 {
324 	int ret, reg_vdd, gain;
325 	int val;
326 	struct dm_regulator_uclass_platdata *uc_pdata;
327 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
328 
329 	switch (pdata->unit) {
330 	case TPS65910_UNIT_VDD1:
331 		reg_vdd = TPS65910_REG_VDD1;
332 		break;
333 	case TPS65910_UNIT_VDD2:
334 		reg_vdd = TPS65910_REG_VDD2;
335 		break;
336 	default:
337 		return -EINVAL;
338 	}
339 	uc_pdata = dev_get_uclass_platdata(dev);
340 
341 	/* check setpoint is within limits */
342 	if (uV < uc_pdata->min_uV) {
343 		pr_err("voltage %duV for %s too low\n", uV, dev->name);
344 		return -EINVAL;
345 	}
346 	if (uV > uc_pdata->max_uV) {
347 		pr_err("voltage %duV for %s too high\n", uV, dev->name);
348 		return -EINVAL;
349 	}
350 
351 	val = pmic_reg_read(dev->parent, reg_vdd);
352 	if (val < 0)
353 		return val;
354 	gain = (val & TPS65910_GAIN_SEL_MASK) >> 6;
355 	gain = (gain == 0) ? 1 : gain;
356 	val = ((uV / gain) - 562500) / 12500;
357 	if (val < TPS65910_VDD_SEL_MIN || val > TPS65910_VDD_SEL_MAX)
358 		/*
359 		 * Neither do we change the gain, nor do we allow shutdown or
360 		 * any approximate value (for now)
361 		 */
362 		return -EPERM;
363 	val &= TPS65910_VDD_SEL_MASK;
364 	ret = pmic_reg_write(dev->parent, reg_vdd + 1, val);
365 	if (ret)
366 		return ret;
367 	return 0;
368 }
369 
370 static int tps65910_buck_set_value(struct udevice *dev, int uV)
371 {
372 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
373 
374 	if (pdata->unit == TPS65910_UNIT_VIO)
375 		return tps65910_regulator_set_value(dev, &smps_props_vio, uV);
376 
377 	return buck_set_vdd1_vdd2_value(dev, uV);
378 }
379 
380 static int tps65910_boost_get_value(struct udevice *dev)
381 {
382 	int vout;
383 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
384 
385 	vout = (pdata->supply >= 3000000) ? 5000000 : 0;
386 	return vout;
387 }
388 
389 static int tps65910_regulator_ofdata_to_platdata(struct udevice *dev)
390 {
391 	struct udevice *supply;
392 	int ret;
393 	const char *supply_name;
394 	struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev);
395 
396 	pdata->unit = dev_get_driver_data(dev);
397 	if (pdata->unit > TPS65910_UNIT_VMMC)
398 		return -EINVAL;
399 	supply_name = supply_names[regulator_supplies[pdata->unit]];
400 
401 	debug("Looking up supply power %s\n", supply_name);
402 	ret = device_get_supply_regulator(dev->parent, supply_name, &supply);
403 	if (ret) {
404 		debug("  missing supply power %s\n", supply_name);
405 		return ret;
406 	}
407 	pdata->supply = regulator_get_value(supply);
408 	if (pdata->supply < 0) {
409 		debug("  invalid supply voltage for regulator %s\n",
410 		      supply->name);
411 		return -EINVAL;
412 	}
413 
414 	return 0;
415 }
416 
417 static const struct dm_regulator_ops tps65910_boost_ops = {
418 	.get_value  = tps65910_boost_get_value,
419 	.get_enable = tps65910_get_enable,
420 	.set_enable = tps65910_set_enable,
421 };
422 
423 U_BOOT_DRIVER(tps65910_boost) = {
424 	.name = TPS65910_BOOST_DRIVER,
425 	.id = UCLASS_REGULATOR,
426 	.ops = &tps65910_boost_ops,
427 	.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
428 	.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
429 };
430 
431 static const struct dm_regulator_ops tps65910_buck_ops = {
432 	.get_value  = tps65910_buck_get_value,
433 	.set_value  = tps65910_buck_set_value,
434 	.get_enable = tps65910_get_enable,
435 	.set_enable = tps65910_set_enable,
436 };
437 
438 U_BOOT_DRIVER(tps65910_buck) = {
439 	.name = TPS65910_BUCK_DRIVER,
440 	.id = UCLASS_REGULATOR,
441 	.ops = &tps65910_buck_ops,
442 	.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
443 	.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
444 };
445 
446 static const struct dm_regulator_ops tps65910_ldo_ops = {
447 	.get_value  = tps65910_ldo_get_value,
448 	.set_value  = tps65910_ldo_set_value,
449 	.get_enable = tps65910_get_enable,
450 	.set_enable = tps65910_set_enable,
451 };
452 
453 U_BOOT_DRIVER(tps65910_ldo) = {
454 	.name = TPS65910_LDO_DRIVER,
455 	.id = UCLASS_REGULATOR,
456 	.ops = &tps65910_ldo_ops,
457 	.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata),
458 	.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata,
459 };
460