blob: 37ebe94521c99691a563044eb15b27fbb303aaea [file] [log] [blame]
Przemyslaw Marczak1757df42015-04-20 20:07:47 +02001/*
2 * Copyright (C) 2012-2015 Samsung Electronics
3 *
4 * Rajeshwari Shinde <rajeshwari.s@samsung.com>
5 * Przemyslaw Marczak <p.marczak@samsung.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <common.h>
11#include <fdtdec.h>
12#include <errno.h>
13#include <dm.h>
14#include <i2c.h>
15#include <power/pmic.h>
16#include <power/regulator.h>
17#include <power/max77686_pmic.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21#define MODE(_id, _val, _name) { \
22 .id = _id, \
23 .register_value = _val, \
24 .name = _name, \
25}
26
27/* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
28static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
29 MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
30 MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
31 MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
32 MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
33};
34
35/* LDO: 2,6,7,8,10,11,12,14,15,16 */
36static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
37 MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
38 MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
39 MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
40 MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
41};
42
43/* Buck: 1 */
44static struct dm_regulator_mode max77686_buck_mode_standby[] = {
45 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
46 MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
47 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
48};
49
50/* Buck: 2,3,4 */
51static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
52 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
53 MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
54 MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
55 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
56};
57
58/* Buck: 5,6,7,8,9 */
59static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
60 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
61 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
62};
63
64static const char max77686_buck_addr[] = {
65 0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
66};
67
68static int max77686_buck_volt2hex(int buck, int uV)
69{
70 unsigned int hex = 0;
71 unsigned int hex_max = 0;
72
73 switch (buck) {
74 case 2:
75 case 3:
76 case 4:
77 /* hex = (uV - 600000) / 12500; */
78 hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
79 hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
80 /**
81 * Those use voltage scaller - temporary not implemented
82 * so return just 0
83 */
84 return -ENOSYS;
85 default:
86 /* hex = (uV - 750000) / 50000; */
87 hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
88 hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
89 break;
90 }
91
92 if (hex >= 0 && hex <= hex_max)
93 return hex;
94
95 error("Value: %d uV is wrong for BUCK%d", uV, buck);
96 return -EINVAL;
97}
98
99static int max77686_buck_hex2volt(int buck, int hex)
100{
101 unsigned uV = 0;
102 unsigned int hex_max = 0;
103
104 if (hex < 0)
105 goto bad_hex;
106
107 switch (buck) {
108 case 2:
109 case 3:
110 case 4:
111 hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
112 if (hex > hex_max)
113 goto bad_hex;
114
115 /* uV = hex * 12500 + 600000; */
116 uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
117 break;
118 default:
119 hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
120 if (hex > hex_max)
121 goto bad_hex;
122
123 /* uV = hex * 50000 + 750000; */
124 uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
125 break;
126 }
127
128 return uV;
129
130bad_hex:
131 error("Value: %#x is wrong for BUCK%d", hex, buck);
132 return -EINVAL;
133}
134
135static int max77686_ldo_volt2hex(int ldo, int uV)
136{
137 unsigned int hex = 0;
138
139 switch (ldo) {
140 case 1:
141 case 2:
142 case 6:
143 case 7:
144 case 8:
145 case 15:
146 hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
147 /* hex = (uV - 800000) / 25000; */
148 break;
149 default:
150 hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
151 /* hex = (uV - 800000) / 50000; */
152 }
153
154 if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
155 return hex;
156
157 error("Value: %d uV is wrong for LDO%d", uV, ldo);
158 return -EINVAL;
159}
160
161static int max77686_ldo_hex2volt(int ldo, int hex)
162{
163 unsigned int uV = 0;
164
165 if (hex > MAX77686_LDO_VOLT_MAX_HEX)
166 goto bad_hex;
167
168 switch (ldo) {
169 case 1:
170 case 2:
171 case 6:
172 case 7:
173 case 8:
174 case 15:
175 /* uV = hex * 25000 + 800000; */
176 uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
177 break;
178 default:
179 /* uV = hex * 50000 + 800000; */
180 uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
181 }
182
183 return uV;
184
185bad_hex:
186 error("Value: %#x is wrong for ldo%d", hex, ldo);
187 return -EINVAL;
188}
189
190static int max77686_ldo_hex2mode(int ldo, int hex)
191{
192 if (hex > MAX77686_LDO_MODE_MASK)
193 return -EINVAL;
194
195 switch (hex) {
196 case MAX77686_LDO_MODE_OFF:
197 return OPMODE_OFF;
198 case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
199 /* The same mode values but different meaning for each ldo */
200 switch (ldo) {
201 case 2:
202 case 6:
203 case 7:
204 case 8:
205 case 10:
206 case 11:
207 case 12:
208 case 14:
209 case 15:
210 case 16:
211 return OPMODE_STANDBY;
212 default:
213 return OPMODE_LPM;
214 }
215 case MAX77686_LDO_MODE_STANDBY_LPM:
216 return OPMODE_STANDBY_LPM;
217 case MAX77686_LDO_MODE_ON:
218 return OPMODE_ON;
219 default:
220 return -EINVAL;
221 }
222}
223
224static int max77686_buck_hex2mode(int buck, int hex)
225{
226 if (hex > MAX77686_BUCK_MODE_MASK)
227 return -EINVAL;
228
229 switch (hex) {
230 case MAX77686_BUCK_MODE_OFF:
231 return OPMODE_OFF;
232 case MAX77686_BUCK_MODE_ON:
233 return OPMODE_ON;
234 case MAX77686_BUCK_MODE_STANDBY:
235 switch (buck) {
236 case 1:
237 case 2:
238 case 3:
239 case 4:
240 return OPMODE_STANDBY;
241 default:
242 return -EINVAL;
243 }
244 case MAX77686_BUCK_MODE_LPM:
245 switch (buck) {
246 case 2:
247 case 3:
248 case 4:
249 return OPMODE_LPM;
250 default:
251 return -EINVAL;
252 }
253 default:
254 return -EINVAL;
255 }
256}
257
258static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
259{
260 int ret = -EINVAL;
261
262 if (buck < 1 || buck > MAX77686_BUCK_NUM)
263 return ret;
264
265 switch (buck) {
266 case 1:
267 *modesp = max77686_buck_mode_standby;
268 ret = ARRAY_SIZE(max77686_buck_mode_standby);
269 break;
270 case 2:
271 case 3:
272 case 4:
273 *modesp = max77686_buck_mode_lpm;
274 ret = ARRAY_SIZE(max77686_buck_mode_lpm);
275 break;
276 default:
277 *modesp = max77686_buck_mode_onoff;
278 ret = ARRAY_SIZE(max77686_buck_mode_onoff);
279 }
280
281 return ret;
282}
283
284static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
285 struct udevice *dev)
286{
287 int ret = -EINVAL;
288
289 if (ldo < 1 || ldo > MAX77686_LDO_NUM)
290 return ret;
291
292 switch (ldo) {
293 case 2:
294 case 6:
295 case 7:
296 case 8:
297 case 10:
298 case 11:
299 case 12:
300 case 14:
301 case 15:
302 case 16:
303 *modesp = max77686_ldo_mode_standby2;
304 ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
305 break;
306 default:
307 *modesp = max77686_ldo_mode_standby1;
308 ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
309 }
310
311 return ret;
312}
313
314static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
315{
316 unsigned int ret, hex, adr;
317 unsigned char val;
318 int ldo;
319
320 if (op == PMIC_OP_GET)
321 *uV = 0;
322
323 ldo = dev->driver_data;
324 if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
325 error("Wrong ldo number: %d", ldo);
326 return -EINVAL;
327 }
328
329 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
330
331 ret = pmic_read(dev->parent, adr, &val, 1);
332 if (ret)
333 return ret;
334
335 if (op == PMIC_OP_GET) {
336 val &= MAX77686_LDO_VOLT_MASK;
337 ret = max77686_ldo_hex2volt(ldo, val);
338 if (ret < 0)
339 return ret;
340 *uV = ret;
341 return 0;
342 }
343
344 hex = max77686_ldo_volt2hex(ldo, *uV);
345 if (hex < 0)
346 return hex;
347
348 val &= ~MAX77686_LDO_VOLT_MASK;
349 val |= hex;
350 ret = pmic_write(dev->parent, adr, &val, 1);
351
352 return ret;
353}
354
355static int max77686_buck_val(struct udevice *dev, int op, int *uV)
356{
357 unsigned int hex, ret, mask, adr;
358 unsigned char val;
359 int buck;
360
361 buck = dev->driver_data;
362 if (buck < 1 || buck > MAX77686_BUCK_NUM) {
363 error("Wrong buck number: %d", buck);
364 return -EINVAL;
365 }
366
367 if (op == PMIC_OP_GET)
368 *uV = 0;
369
370 /* &buck_out = ctrl + 1 */
371 adr = max77686_buck_addr[buck] + 1;
372
373 /* mask */
374 switch (buck) {
375 case 2:
376 case 3:
377 case 4:
378 /* Those use voltage scallers - will support in the future */
379 mask = MAX77686_BUCK234_VOLT_MASK;
380 return -ENOSYS;
381 default:
382 mask = MAX77686_BUCK_VOLT_MASK;
383 }
384
385 ret = pmic_read(dev->parent, adr, &val, 1);
386 if (ret)
387 return ret;
388
389 if (op == PMIC_OP_GET) {
390 val &= mask;
391 ret = max77686_buck_hex2volt(buck, val);
392 if (ret < 0)
393 return ret;
394 *uV = ret;
395 return 0;
396 }
397
398 hex = max77686_buck_volt2hex(buck, *uV);
399 if (hex < 0)
400 return hex;
401
402 val &= ~mask;
403 val |= hex;
404 ret = pmic_write(dev->parent, adr, &val, 1);
405
406 return ret;
407}
408
409static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
410{
411 unsigned int ret, adr, mode;
412 unsigned char val;
413 int ldo;
414
415 if (op == PMIC_OP_GET)
416 *opmode = -EINVAL;
417
418 ldo = dev->driver_data;
419 if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
420 error("Wrong ldo number: %d", ldo);
421 return -EINVAL;
422 }
423
424 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
425
426 ret = pmic_read(dev->parent, adr, &val, 1);
427 if (ret)
428 return ret;
429
430 if (op == PMIC_OP_GET) {
431 val &= MAX77686_LDO_MODE_MASK;
432 ret = max77686_ldo_hex2mode(ldo, val);
433 if (ret < 0)
434 return ret;
435 *opmode = ret;
436 return 0;
437 }
438
439 /* mode */
440 switch (*opmode) {
441 case OPMODE_OFF:
442 mode = MAX77686_LDO_MODE_OFF;
443 break;
444 case OPMODE_LPM:
445 switch (ldo) {
446 case 2:
447 case 6:
448 case 7:
449 case 8:
450 case 10:
451 case 11:
452 case 12:
453 case 14:
454 case 15:
455 case 16:
456 return -EINVAL;
457 default:
458 mode = MAX77686_LDO_MODE_LPM;
459 }
460 break;
461 case OPMODE_STANDBY:
462 switch (ldo) {
463 case 2:
464 case 6:
465 case 7:
466 case 8:
467 case 10:
468 case 11:
469 case 12:
470 case 14:
471 case 15:
472 case 16:
473 mode = MAX77686_LDO_MODE_STANDBY;
474 break;
475 default:
476 return -EINVAL;
477 }
478 break;
479 case OPMODE_STANDBY_LPM:
480 mode = MAX77686_LDO_MODE_STANDBY_LPM;
481 break;
482 case OPMODE_ON:
483 mode = MAX77686_LDO_MODE_ON;
484 break;
485 default:
486 mode = 0xff;
487 }
488
489 if (mode == 0xff) {
490 error("Wrong mode: %d for ldo%d", *opmode, ldo);
491 return -EINVAL;
492 }
493
494 val &= ~MAX77686_LDO_MODE_MASK;
495 val |= mode;
496 ret = pmic_write(dev->parent, adr, &val, 1);
497
498 return ret;
499}
500
501static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
502{
503 int ret, on_off;
504
505 if (op == PMIC_OP_GET) {
506 ret = max77686_ldo_mode(dev, op, &on_off);
507 if (ret)
508 return ret;
509
510 switch (on_off) {
511 case OPMODE_OFF:
512 *enable = 0;
513 break;
514 case OPMODE_ON:
515 *enable = 1;
516 break;
517 default:
518 return -EINVAL;
519 }
520 } else if (op == PMIC_OP_SET) {
521 switch (*enable) {
522 case 0:
523 on_off = OPMODE_OFF;
524 break;
525 case 1:
526 on_off = OPMODE_ON;
527 break;
528 default:
529 return -EINVAL;
530 }
531
532 ret = max77686_ldo_mode(dev, op, &on_off);
533 if (ret)
534 return ret;
535 }
536
537 return 0;
538}
539
540static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
541{
542 unsigned int ret, mask, adr, mode, mode_shift;
543 unsigned char val;
544 int buck;
545
546 buck = dev->driver_data;
547 if (buck < 1 || buck > MAX77686_BUCK_NUM) {
548 error("Wrong buck number: %d", buck);
549 return -EINVAL;
550 }
551
552 adr = max77686_buck_addr[buck];
553
554 /* mask */
555 switch (buck) {
556 case 2:
557 case 3:
558 case 4:
559 mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
560 break;
561 default:
562 mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
563 }
564
565 mask = MAX77686_BUCK_MODE_MASK << mode_shift;
566
567 ret = pmic_read(dev->parent, adr, &val, 1);
568 if (ret)
569 return ret;
570
571 if (op == PMIC_OP_GET) {
572 val &= mask;
573 val >>= mode_shift;
574 ret = max77686_buck_hex2mode(buck, val);
575 if (ret < 0)
576 return ret;
577 *opmode = ret;
578 return 0;
579 }
580
581 /* mode */
582 switch (*opmode) {
583 case OPMODE_OFF:
584 mode = MAX77686_BUCK_MODE_OFF;
585 break;
586 case OPMODE_STANDBY:
587 switch (buck) {
588 case 1:
589 case 2:
590 case 3:
591 case 4:
592 mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
593 break;
594 default:
595 mode = 0xff;
596 }
597 break;
598 case OPMODE_LPM:
599 switch (buck) {
600 case 2:
601 case 3:
602 case 4:
603 mode = MAX77686_BUCK_MODE_LPM << mode_shift;
604 break;
605 default:
606 mode = 0xff;
607 }
608 break;
609 case OPMODE_ON:
610 mode = MAX77686_BUCK_MODE_ON << mode_shift;
611 break;
612 default:
613 mode = 0xff;
614 }
615
616 if (mode == 0xff) {
617 error("Wrong mode: %d for buck: %d\n", *opmode, buck);
618 return -EINVAL;
619 }
620
621 val &= ~mask;
622 val |= mode;
623 ret = pmic_write(dev->parent, adr, &val, 1);
624
625 return ret;
626}
627
628static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
629{
630 int ret, on_off;
631
632 if (op == PMIC_OP_GET) {
633 ret = max77686_buck_mode(dev, op, &on_off);
634 if (ret)
635 return ret;
636
637 switch (on_off) {
638 case OPMODE_OFF:
639 *enable = false;
640 break;
641 case OPMODE_ON:
642 *enable = true;
643 break;
644 default:
645 return -EINVAL;
646 }
647 } else if (op == PMIC_OP_SET) {
648 switch (*enable) {
649 case 0:
650 on_off = OPMODE_OFF;
651 break;
652 case 1:
653 on_off = OPMODE_ON;
654 break;
655 default:
656 return -EINVAL;
657 }
658
659 ret = max77686_buck_mode(dev, op, &on_off);
660 if (ret)
661 return ret;
662 }
663
664 return 0;
665}
666
667static int max77686_ldo_probe(struct udevice *dev)
668{
669 struct dm_regulator_uclass_platdata *uc_pdata;
670
671 uc_pdata = dev_get_uclass_platdata(dev);
672
673 uc_pdata->type = REGULATOR_TYPE_LDO;
674 uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
675 &uc_pdata->mode, dev);
676
677 return 0;
678}
679
680static int ldo_get_value(struct udevice *dev)
681{
682 int uV;
683 int ret;
684
685 ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
686 if (ret)
687 return ret;
688
689 return uV;
690}
691
692static int ldo_set_value(struct udevice *dev, int uV)
693{
694 return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
695}
696
697static bool ldo_get_enable(struct udevice *dev)
698{
699 bool enable = false;
700 int ret;
701
702 ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
703 if (ret)
704 return ret;
705
706 return enable;
707}
708
709static int ldo_set_enable(struct udevice *dev, bool enable)
710{
711 return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
712}
713
714static int ldo_get_mode(struct udevice *dev)
715{
716 int mode;
717 int ret;
718
719 ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
720 if (ret)
721 return ret;
722
723 return mode;
724}
725
726static int ldo_set_mode(struct udevice *dev, int mode)
727{
728 return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
729}
730
731static int max77686_buck_probe(struct udevice *dev)
732{
733 struct dm_regulator_uclass_platdata *uc_pdata;
734
735 uc_pdata = dev_get_uclass_platdata(dev);
736
737 uc_pdata->type = REGULATOR_TYPE_BUCK;
738 uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
739 &uc_pdata->mode);
740
741 return 0;
742}
743
744static int buck_get_value(struct udevice *dev)
745{
746 int uV;
747 int ret;
748
749 ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
750 if (ret)
751 return ret;
752
753 return uV;
754}
755
756static int buck_set_value(struct udevice *dev, int uV)
757{
758 return max77686_buck_val(dev, PMIC_OP_SET, &uV);
759}
760
761static bool buck_get_enable(struct udevice *dev)
762{
763 bool enable = false;
764 int ret;
765
766 ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
767 if (ret)
768 return ret;
769
770 return enable;
771}
772
773static int buck_set_enable(struct udevice *dev, bool enable)
774{
775 return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
776}
777
778static int buck_get_mode(struct udevice *dev)
779{
780 int mode;
781 int ret;
782
783 ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
784 if (ret)
785 return ret;
786
787 return mode;
788}
789
790static int buck_set_mode(struct udevice *dev, int mode)
791{
792 return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
793}
794
795static const struct dm_regulator_ops max77686_ldo_ops = {
796 .get_value = ldo_get_value,
797 .set_value = ldo_set_value,
798 .get_enable = ldo_get_enable,
799 .set_enable = ldo_set_enable,
800 .get_mode = ldo_get_mode,
801 .set_mode = ldo_set_mode,
802};
803
804U_BOOT_DRIVER(max77686_ldo) = {
805 .name = MAX77686_LDO_DRIVER,
806 .id = UCLASS_REGULATOR,
807 .ops = &max77686_ldo_ops,
808 .probe = max77686_ldo_probe,
809};
810
811static const struct dm_regulator_ops max77686_buck_ops = {
812 .get_value = buck_get_value,
813 .set_value = buck_set_value,
814 .get_enable = buck_get_enable,
815 .set_enable = buck_set_enable,
816 .get_mode = buck_get_mode,
817 .set_mode = buck_set_mode,
818};
819
820U_BOOT_DRIVER(max77686_buck) = {
821 .name = MAX77686_BUCK_DRIVER,
822 .id = UCLASS_REGULATOR,
823 .ops = &max77686_buck_ops,
824 .probe = max77686_buck_probe,
825};