3f8be6c8e46eeca285e68e6e2013a9589ec5af0b
[oweals/u-boot.git] / drivers / power / regulator / tps65941_regulator.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019
4  * Texas Instruments Incorporated, <www.ti.com>
5  *
6  * Keerthy <j-keerthy@ti.com>
7  */
8
9 #include <common.h>
10 #include <fdtdec.h>
11 #include <errno.h>
12 #include <dm.h>
13 #include <i2c.h>
14 #include <log.h>
15 #include <power/pmic.h>
16 #include <power/regulator.h>
17 #include <power/tps65941.h>
18
19 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
20                                                                 0xC};
21 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
22                                                                 0x14, 0x16};
23 static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = {0x1D, 0x1E, 0x1F,
24                                                                 0x20};
25 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
26                                                                 0x26};
27
28 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
29 {
30         int ret;
31         unsigned int adr;
32         struct dm_regulator_uclass_platdata *uc_pdata;
33
34         uc_pdata = dev_get_uclass_platdata(dev);
35         adr = uc_pdata->ctrl_reg;
36
37         ret = pmic_reg_read(dev->parent, adr);
38         if (ret < 0)
39                 return ret;
40
41         if (op == PMIC_OP_GET) {
42                 ret &= TPS65941_BUCK_MODE_MASK;
43
44                 if (ret)
45                         *enable = true;
46                 else
47                         *enable = false;
48
49                 return 0;
50         } else if (op == PMIC_OP_SET) {
51                 if (*enable)
52                         ret |= TPS65941_BUCK_MODE_MASK;
53                 else
54                         ret &= ~TPS65941_BUCK_MODE_MASK;
55                 ret = pmic_reg_write(dev->parent, adr, ret);
56                 if (ret)
57                         return ret;
58         }
59
60         return 0;
61 }
62
63 static int tps65941_buck_volt2val(int uV)
64 {
65         if (uV > TPS65941_BUCK_VOLT_MAX)
66                 return -EINVAL;
67         else if (uV > 1650000)
68                 return (uV - 1660000) / 20000 + 0xAB;
69         else if (uV > 1110000)
70                 return (uV - 1110000) / 10000 + 0x73;
71         else if (uV > 600000)
72                 return (uV - 600000) / 5000 + 0x0F;
73         else if (uV >= 300000)
74                 return (uV - 300000) / 20000 + 0x00;
75         else
76                 return -EINVAL;
77 }
78
79 static int tps65941_buck_val2volt(int val)
80 {
81         if (val > TPS65941_BUCK_VOLT_MAX_HEX)
82                 return -EINVAL;
83         else if (val > 0xAB)
84                 return 1660000 + (val - 0xAB) * 20000;
85         else if (val > 0x73)
86                 return 1100000 + (val - 0x73) * 10000;
87         else if (val > 0xF)
88                 return 600000 + (val - 0xF) * 5000;
89         else if (val >= 0x0)
90                 return 300000 + val * 5000;
91         else
92                 return -EINVAL;
93 }
94
95 int tps65941_lookup_slew(int id)
96 {
97         switch (id) {
98         case 0:
99                 return 33000;
100         case 1:
101                 return 20000;
102         case 2:
103                 return 10000;
104         case 3:
105                 return 5000;
106         case 4:
107                 return 2500;
108         case 5:
109                 return 1300;
110         case 6:
111                 return 630;
112         case 7:
113                 return 310;
114         default:
115                 return -1;
116         }
117 }
118
119 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
120 {
121         unsigned int hex, adr;
122         int ret, delta, uwait, slew;
123         struct dm_regulator_uclass_platdata *uc_pdata;
124
125         uc_pdata = dev_get_uclass_platdata(dev);
126
127         if (op == PMIC_OP_GET)
128                 *uV = 0;
129
130         adr = uc_pdata->volt_reg;
131
132         ret = pmic_reg_read(dev->parent, adr);
133         if (ret < 0)
134                 return ret;
135
136         ret &= TPS65941_BUCK_VOLT_MASK;
137         ret = tps65941_buck_val2volt(ret);
138         if (ret < 0)
139                 return ret;
140
141         if (op == PMIC_OP_GET) {
142                 *uV = ret;
143                 return 0;
144         }
145
146         /*
147          * Compute the delta voltage, find the slew rate and wait
148          * for the appropriate amount of time after voltage switch
149          */
150         if (*uV > ret)
151                 delta = *uV - ret;
152         else
153                 delta = ret - *uV;
154
155         slew = pmic_reg_read(dev->parent, uc_pdata->ctrl_reg + 1);
156         if (slew < 0)
157                 return ret;
158
159         slew &= TP65941_BUCK_CONF_SLEW_MASK;
160         slew = tps65941_lookup_slew(slew);
161         if (slew <= 0)
162                 return ret;
163
164         uwait = delta / slew;
165
166         hex = tps65941_buck_volt2val(*uV);
167         if (hex < 0)
168                 return hex;
169
170         ret &= 0x0;
171         ret = hex;
172
173         ret = pmic_reg_write(dev->parent, adr, ret);
174
175         udelay(uwait);
176
177         return ret;
178 }
179
180 static int tps65941_ldo_enable(struct udevice *dev, int op, bool *enable)
181 {
182         int ret;
183         unsigned int adr;
184         struct dm_regulator_uclass_platdata *uc_pdata;
185
186         uc_pdata = dev_get_uclass_platdata(dev);
187         adr = uc_pdata->ctrl_reg;
188
189         ret = pmic_reg_read(dev->parent, adr);
190         if (ret < 0)
191                 return ret;
192
193         if (op == PMIC_OP_GET) {
194                 ret &= TPS65941_LDO_MODE_MASK;
195
196                 if (ret)
197                         *enable = true;
198                 else
199                         *enable = false;
200
201                 return 0;
202         } else if (op == PMIC_OP_SET) {
203                 if (*enable)
204                         ret |= TPS65941_LDO_MODE_MASK;
205                 else
206                         ret &= ~TPS65941_LDO_MODE_MASK;
207                 ret = pmic_reg_write(dev->parent, adr, ret);
208                 if (ret)
209                         return ret;
210         }
211
212         return 0;
213 }
214
215 static int tps65941_ldo_val2volt(int val)
216 {
217         if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
218                 return -EINVAL;
219         else if (val >= TPS65941_LDO_VOLT_MIN_HEX)
220                 return 600000 + (val - TPS65941_LDO_VOLT_MIN_HEX) * 50000;
221         else
222                 return -EINVAL;
223 }
224
225 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
226 {
227         unsigned int hex, adr;
228         int ret;
229         struct dm_regulator_uclass_platdata *uc_pdata;
230
231         uc_pdata = dev_get_uclass_platdata(dev);
232
233         if (op == PMIC_OP_GET)
234                 *uV = 0;
235
236         adr = uc_pdata->volt_reg;
237
238         ret = pmic_reg_read(dev->parent, adr);
239         if (ret < 0)
240                 return ret;
241
242         ret &= TPS65941_LDO_VOLT_MASK;
243         ret = tps65941_ldo_val2volt(ret);
244         if (ret < 0)
245                 return ret;
246
247         if (op == PMIC_OP_GET) {
248                 *uV = ret;
249                 return 0;
250         }
251
252         hex = tps65941_buck_volt2val(*uV);
253         if (hex < 0)
254                 return hex;
255
256         ret &= 0x0;
257         ret = hex;
258
259         ret = pmic_reg_write(dev->parent, adr, ret);
260
261         return ret;
262 }
263
264 static int tps65941_ldo_probe(struct udevice *dev)
265 {
266         struct dm_regulator_uclass_platdata *uc_pdata;
267         int idx;
268
269         uc_pdata = dev_get_uclass_platdata(dev);
270         uc_pdata->type = REGULATOR_TYPE_LDO;
271
272         idx = dev->driver_data;
273         if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
274                 debug("Single phase regulator\n");
275         } else {
276                 printf("Wrong ID for regulator\n");
277                 return -EINVAL;
278         }
279
280         uc_pdata->ctrl_reg = tps65941_ldo_ctrl[idx - 1];
281         uc_pdata->volt_reg = tps65941_ldo_vout[idx - 1];
282
283         return 0;
284 }
285
286 static int tps65941_buck_probe(struct udevice *dev)
287 {
288         struct dm_regulator_uclass_platdata *uc_pdata;
289         int idx;
290
291         uc_pdata = dev_get_uclass_platdata(dev);
292         uc_pdata->type = REGULATOR_TYPE_BUCK;
293
294         idx = dev->driver_data;
295         if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
296                 debug("Single phase regulator\n");
297         } else if (idx == 12) {
298                 idx = 1;
299         } else if (idx == 34) {
300                 idx = 3;
301         } else if (idx == 1234) {
302                 idx = 1;
303         } else {
304                 printf("Wrong ID for regulator\n");
305                 return -EINVAL;
306         }
307
308         uc_pdata->ctrl_reg = tps65941_buck_ctrl[idx - 1];
309         uc_pdata->volt_reg = tps65941_buck_vout[idx - 1];
310
311         return 0;
312 }
313
314 static int ldo_get_value(struct udevice *dev)
315 {
316         int uV;
317         int ret;
318
319         ret = tps65941_ldo_val(dev, PMIC_OP_GET, &uV);
320         if (ret)
321                 return ret;
322
323         return uV;
324 }
325
326 static int ldo_set_value(struct udevice *dev, int uV)
327 {
328         return tps65941_ldo_val(dev, PMIC_OP_SET, &uV);
329 }
330
331 static int ldo_get_enable(struct udevice *dev)
332 {
333         bool enable = false;
334         int ret;
335
336         ret = tps65941_ldo_enable(dev, PMIC_OP_GET, &enable);
337         if (ret)
338                 return ret;
339
340         return enable;
341 }
342
343 static int ldo_set_enable(struct udevice *dev, bool enable)
344 {
345         return tps65941_ldo_enable(dev, PMIC_OP_SET, &enable);
346 }
347
348 static int buck_get_value(struct udevice *dev)
349 {
350         int uV;
351         int ret;
352
353         ret = tps65941_buck_val(dev, PMIC_OP_GET, &uV);
354         if (ret)
355                 return ret;
356
357         return uV;
358 }
359
360 static int buck_set_value(struct udevice *dev, int uV)
361 {
362         return tps65941_buck_val(dev, PMIC_OP_SET, &uV);
363 }
364
365 static int buck_get_enable(struct udevice *dev)
366 {
367         bool enable = false;
368         int ret;
369
370         ret = tps65941_buck_enable(dev, PMIC_OP_GET, &enable);
371         if (ret)
372                 return ret;
373
374         return enable;
375 }
376
377 static int buck_set_enable(struct udevice *dev, bool enable)
378 {
379         return tps65941_buck_enable(dev, PMIC_OP_SET, &enable);
380 }
381
382 static const struct dm_regulator_ops tps65941_ldo_ops = {
383         .get_value  = ldo_get_value,
384         .set_value  = ldo_set_value,
385         .get_enable = ldo_get_enable,
386         .set_enable = ldo_set_enable,
387 };
388
389 U_BOOT_DRIVER(tps65941_ldo) = {
390         .name = TPS65941_LDO_DRIVER,
391         .id = UCLASS_REGULATOR,
392         .ops = &tps65941_ldo_ops,
393         .probe = tps65941_ldo_probe,
394 };
395
396 static const struct dm_regulator_ops tps65941_buck_ops = {
397         .get_value  = buck_get_value,
398         .set_value  = buck_set_value,
399         .get_enable = buck_get_enable,
400         .set_enable = buck_set_enable,
401 };
402
403 U_BOOT_DRIVER(tps65941_buck) = {
404         .name = TPS65941_BUCK_DRIVER,
405         .id = UCLASS_REGULATOR,
406         .ops = &tps65941_buck_ops,
407         .probe = tps65941_buck_probe,
408 };