]> git.sur5r.net Git - u-boot/blob - drivers/power/regulator/tps65910_regulator.c
power: pmic/regulator: Add basic support for TPS65910
[u-boot] / drivers / power / regulator / tps65910_regulator.c
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                 error("voltage %duV for %s too low\n", uV, dev->name);
344                 return -EINVAL;
345         }
346         if (uV > uc_pdata->max_uV) {
347                 error("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 };