Merge git://git.denx.de/u-boot-imx
[platform/kernel/u-boot.git] / drivers / power / regulator / s2mps11_regulator.c
1 /*
2  *  Copyright (C) 2018 Samsung Electronics
3  *  Jaehoon Chung <jh80.chung@samsung.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0
6  */
7
8 #include <common.h>
9 #include <fdtdec.h>
10 #include <errno.h>
11 #include <dm.h>
12 #include <i2c.h>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
15 #include <power/s2mps11.h>
16
17 #define MODE(_id, _val, _name) { \
18         .id = _id, \
19         .register_value = _val, \
20         .name = _name, \
21 }
22
23 /* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */
24 static struct dm_regulator_mode s2mps11_buck_modes[] = {
25         MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"),
26         MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"),
27         MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"),
28 };
29
30 static struct dm_regulator_mode s2mps11_ldo_modes[] = {
31         MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"),
32         MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"),
33         MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"),
34         MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
35 };
36
37 static const char s2mps11_buck_ctrl[] = {
38         0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
39 };
40
41 static const char s2mps11_buck_out[] = {
42         0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
43 };
44
45 static int s2mps11_buck_hex2volt(int buck, int hex)
46 {
47         unsigned int uV = 0;
48
49         if (hex < 0)
50                 goto bad;
51
52         switch (buck) {
53         case 7:
54         case 8:
55         case 10:
56                 if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
57                         goto bad;
58
59                 uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN;
60                 break;
61         case 9:
62                 if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
63                         goto bad;
64                 uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN;
65                 break;
66         default:
67                 if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
68                         goto bad;
69                 else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
70                         goto bad;
71
72                 uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN;
73                 break;
74         }
75
76         return uV;
77 bad:
78         pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
79         return -EINVAL;
80 }
81
82 static int s2mps11_buck_volt2hex(int buck, int uV)
83 {
84         int hex;
85
86         switch (buck) {
87         case 7:
88         case 8:
89         case 10:
90                 hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP;
91                 if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
92                         goto bad;
93
94                 break;
95         case 9:
96                 hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP;
97                 if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
98                         goto bad;
99                 break;
100         default:
101                 hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP;
102                 if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
103                         goto bad;
104                 else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
105                         goto bad;
106                 break;
107         };
108
109         if (hex >= 0)
110                 return hex;
111
112 bad:
113         pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
114         return -EINVAL;
115 }
116
117 static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
118 {
119         int hex, buck, ret;
120         u32 mask, addr;
121         u8 val;
122
123         buck = dev->driver_data;
124         if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
125                 pr_err("Wrong buck number: %d\n", buck);
126                 return -EINVAL;
127         }
128
129         if (op == PMIC_OP_GET)
130                 *uV = 0;
131
132         addr = s2mps11_buck_out[buck];
133
134         switch (buck) {
135         case 9:
136                 mask = S2MPS11_BUCK9_VOLT_MASK;
137                 break;
138         default:
139                 mask = S2MPS11_BUCK_VOLT_MASK;
140                 break;
141         }
142
143         ret = pmic_read(dev->parent, addr, &val, 1);
144         if (ret)
145                 return ret;
146
147         if (op == PMIC_OP_GET) {
148                 val &= mask;
149                 ret = s2mps11_buck_hex2volt(buck, val);
150                 if (ret < 0)
151                         return ret;
152                 *uV = ret;
153                 return 0;
154         }
155
156         hex = s2mps11_buck_volt2hex(buck, *uV);
157         if (hex < 0)
158                 return hex;
159
160         val &= ~mask;
161         val |= hex;
162         ret = pmic_write(dev->parent, addr, &val, 1);
163
164         return ret;
165 }
166
167 static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
168 {
169         unsigned int addr, mode;
170         unsigned char val;
171         int buck, ret;
172
173         buck = dev->driver_data;
174         if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
175                 pr_err("Wrong buck number: %d\n", buck);
176                 return -EINVAL;
177         }
178
179         addr = s2mps11_buck_ctrl[buck];
180
181         ret = pmic_read(dev->parent, addr, &val, 1);
182         if (ret)
183                 return ret;
184
185         if (op == PMIC_OP_GET) {
186                 val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
187                 switch (val) {
188                 case S2MPS11_BUCK_MODE_OFF:
189                         *opmode = OP_OFF;
190                         break;
191                 case S2MPS11_BUCK_MODE_STANDBY:
192                         *opmode = OP_STANDBY;
193                         break;
194                 case S2MPS11_BUCK_MODE_ON:
195                         *opmode = OP_ON;
196                         break;
197                 default:
198                         return -EINVAL;
199                 }
200                 return 0;
201         }
202
203         switch (*opmode) {
204         case OP_OFF:
205                 mode = S2MPS11_BUCK_MODE_OFF;
206                 break;
207         case OP_STANDBY:
208                 mode = S2MPS11_BUCK_MODE_STANDBY;
209                 break;
210         case OP_ON:
211                 mode = S2MPS11_BUCK_MODE_ON;
212                 break;
213         default:
214                 pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
215                 return -EINVAL;
216         }
217
218         val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
219         val |= mode;
220         ret = pmic_write(dev->parent, addr, &val, 1);
221
222         return ret;
223 }
224
225 static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable)
226 {
227         int ret, on_off;
228
229         if (op == PMIC_OP_GET) {
230                 ret = s2mps11_buck_mode(dev, op, &on_off);
231                 if (ret)
232                         return ret;
233                 switch (on_off) {
234                 case OP_OFF:
235                         *enable = false;
236                         break;
237                 case OP_ON:
238                         *enable = true;
239                         break;
240                 default:
241                         return -EINVAL;
242                 }
243         } else if (op == PMIC_OP_SET) {
244                 if (*enable)
245                         on_off = OP_ON;
246                 else
247                         on_off = OP_OFF;
248
249                 ret = s2mps11_buck_mode(dev, op, &on_off);
250                 if (ret)
251                         return ret;
252         }
253
254         return 0;
255 }
256
257 static int buck_get_value(struct udevice *dev)
258 {
259         int uV;
260         int ret;
261
262         ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV);
263         if (ret)
264                 return ret;
265         return uV;
266 }
267
268 static int buck_set_value(struct udevice *dev, int uV)
269 {
270         return s2mps11_buck_val(dev, PMIC_OP_SET, &uV);
271 }
272
273 static int buck_get_enable(struct udevice *dev)
274 {
275         bool enable = false;
276         int ret;
277
278         ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable);
279         if (ret)
280                 return ret;
281         return enable;
282 }
283
284 static int buck_set_enable(struct udevice *dev, bool enable)
285 {
286         return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable);
287 }
288
289 static int buck_get_mode(struct udevice *dev)
290 {
291         int mode;
292         int ret;
293
294         ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode);
295         if (ret)
296                 return ret;
297
298         return mode;
299 }
300
301 static int buck_set_mode(struct udevice *dev, int mode)
302 {
303         return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode);
304 }
305
306 static int s2mps11_buck_probe(struct udevice *dev)
307 {
308         struct dm_regulator_uclass_platdata *uc_pdata;
309
310         uc_pdata = dev_get_uclass_platdata(dev);
311
312         uc_pdata->type = REGULATOR_TYPE_BUCK;
313         uc_pdata->mode = s2mps11_buck_modes;
314         uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
315
316         return 0;
317 }
318
319 static const struct dm_regulator_ops s2mps11_buck_ops = {
320         .get_value      = buck_get_value,
321         .set_value      = buck_set_value,
322         .get_enable     = buck_get_enable,
323         .set_enable     = buck_set_enable,
324         .get_mode       = buck_get_mode,
325         .set_mode       = buck_set_mode,
326 };
327
328 U_BOOT_DRIVER(s2mps11_buck) = {
329         .name = S2MPS11_BUCK_DRIVER,
330         .id = UCLASS_REGULATOR,
331         .ops = &s2mps11_buck_ops,
332         .probe = s2mps11_buck_probe,
333 };
334
335 static int s2mps11_ldo_hex2volt(int ldo, int hex)
336 {
337         unsigned int uV = 0;
338
339         if (hex > S2MPS11_LDO_VOLT_MAX_HEX) {
340                 pr_err("Value: %#x is wrong for LDO%d", hex, ldo);
341                 return -EINVAL;
342         }
343
344         switch (ldo) {
345         case 1:
346         case 6:
347         case 11:
348         case 22:
349         case 23:
350                 uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
351                 break;
352         default:
353                 uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
354                 break;
355         }
356
357         return uV;
358 }
359
360 static int s2mps11_ldo_volt2hex(int ldo, int uV)
361 {
362         int hex = 0;
363
364         switch (ldo) {
365         case 1:
366         case 6:
367         case 11:
368         case 22:
369         case 23:
370                 hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
371                 break;
372         default:
373                 hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
374                 break;
375         }
376
377         if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
378                 return hex;
379
380         pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
381         return -EINVAL;
382
383         return 0;
384 }
385
386 static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
387 {
388         unsigned int addr;
389         unsigned char val;
390         int hex, ldo, ret;
391
392         ldo = dev->driver_data;
393         if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
394                 pr_err("Wrong ldo number: %d\n", ldo);
395                 return -EINVAL;
396         }
397
398         addr = S2MPS11_REG_L1CTRL + ldo - 1;
399
400         ret = pmic_read(dev->parent, addr, &val, 1);
401         if (ret)
402                 return ret;
403
404         if (op == PMIC_OP_GET) {
405                 *uV = 0;
406                 val &= S2MPS11_LDO_VOLT_MASK;
407                 ret = s2mps11_ldo_hex2volt(ldo, val);
408                 if (ret < 0)
409                         return ret;
410
411                 *uV = ret;
412                 return 0;
413         }
414
415         hex = s2mps11_ldo_volt2hex(ldo, *uV);
416         if (hex < 0)
417                 return hex;
418
419         val &= ~S2MPS11_LDO_VOLT_MASK;
420         val |= hex;
421         ret = pmic_write(dev->parent, addr, &val, 1);
422
423         return ret;
424 }
425
426 static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
427 {
428         unsigned int addr, mode;
429         unsigned char val;
430         int ldo, ret;
431
432         ldo = dev->driver_data;
433         if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
434                 pr_err("Wrong ldo number: %d\n", ldo);
435                 return -EINVAL;
436         }
437         addr = S2MPS11_REG_L1CTRL + ldo - 1;
438
439         ret = pmic_read(dev->parent, addr, &val, 1);
440         if (ret)
441                 return ret;
442
443         if (op == PMIC_OP_GET) {
444                 val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
445                 switch (val) {
446                 case S2MPS11_LDO_MODE_OFF:
447                         *opmode = OP_OFF;
448                         break;
449                 case S2MPS11_LDO_MODE_STANDBY:
450                         *opmode = OP_STANDBY;
451                         break;
452                 case S2MPS11_LDO_MODE_STANDBY_LPM:
453                         *opmode = OP_STANDBY_LPM;
454                         break;
455                 case S2MPS11_LDO_MODE_ON:
456                         *opmode = OP_ON;
457                         break;
458                 default:
459                         return -EINVAL;
460                 }
461                 return 0;
462         }
463
464         switch (*opmode) {
465         case OP_OFF:
466                 mode = S2MPS11_LDO_MODE_OFF;
467                 break;
468         case OP_STANDBY:
469                 mode = S2MPS11_LDO_MODE_STANDBY;
470                 break;
471         case OP_STANDBY_LPM:
472                 mode = S2MPS11_LDO_MODE_STANDBY_LPM;
473                 break;
474         case OP_ON:
475                 mode = S2MPS11_LDO_MODE_ON;
476                 break;
477         default:
478                 pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
479                 return -EINVAL;
480         }
481
482         val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
483         val |= mode;
484         ret = pmic_write(dev->parent, addr, &val, 1);
485
486         return ret;
487 }
488
489 static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
490 {
491         int ret, on_off;
492
493         if (op == PMIC_OP_GET) {
494                 ret = s2mps11_ldo_mode(dev, op, &on_off);
495                 if (ret)
496                         return ret;
497                 switch (on_off) {
498                 case OP_OFF:
499                         *enable = false;
500                         break;
501                 case OP_ON:
502                         *enable = true;
503                         break;
504                 default:
505                         return -EINVAL;
506                 }
507         } else if (op == PMIC_OP_SET) {
508                 if (*enable)
509                         on_off = OP_ON;
510                 else
511                         on_off = OP_OFF;
512
513                 ret = s2mps11_ldo_mode(dev, op, &on_off);
514                 if (ret)
515                         return ret;
516         }
517
518         return 0;
519 }
520
521 static int ldo_get_value(struct udevice *dev)
522 {
523         int uV;
524         int ret;
525
526         ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV);
527         if (ret)
528                 return ret;
529
530         return uV;
531 }
532
533 static int ldo_set_value(struct udevice *dev, int uV)
534 {
535         return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV);
536 }
537
538 static int ldo_get_enable(struct udevice *dev)
539 {
540         bool enable = false;
541         int ret;
542
543         ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable);
544         if (ret)
545                 return ret;
546         return enable;
547 }
548
549 static int ldo_set_enable(struct udevice *dev, bool enable)
550 {
551         return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
552 }
553
554 static int ldo_get_mode(struct udevice *dev)
555 {
556         int mode, ret;
557
558         ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode);
559         if (ret)
560                 return ret;
561         return mode;
562 }
563
564 static int ldo_set_mode(struct udevice *dev, int mode)
565 {
566         return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode);
567 }
568
569 static int s2mps11_ldo_probe(struct udevice *dev)
570 {
571         struct dm_regulator_uclass_platdata *uc_pdata;
572
573         uc_pdata = dev_get_uclass_platdata(dev);
574         uc_pdata->type = REGULATOR_TYPE_LDO;
575         uc_pdata->mode = s2mps11_ldo_modes;
576         uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
577
578         return 0;
579 }
580
581 static const struct dm_regulator_ops s2mps11_ldo_ops = {
582         .get_value      = ldo_get_value,
583         .set_value      = ldo_set_value,
584         .get_enable     = ldo_get_enable,
585         .set_enable     = ldo_set_enable,
586         .get_mode       = ldo_get_mode,
587         .set_mode       = ldo_set_mode,
588 };
589
590 U_BOOT_DRIVER(s2mps11_ldo) = {
591         .name = S2MPS11_LDO_DRIVER,
592         .id = UCLASS_REGULATOR,
593         .ops = &s2mps11_ldo_ops,
594         .probe = s2mps11_ldo_probe,
595 };