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