blob: 6e4ac02036e41573d0d64a6ca326755638976cdf [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
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020019#define MODE(_id, _val, _name) { \
20 .id = _id, \
21 .register_value = _val, \
22 .name = _name, \
23}
24
25/* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
26static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
27 MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
28 MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
29 MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
30 MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
31};
32
33/* LDO: 2,6,7,8,10,11,12,14,15,16 */
34static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
35 MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
36 MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
37 MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
38 MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
39};
40
41/* Buck: 1 */
42static struct dm_regulator_mode max77686_buck_mode_standby[] = {
43 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
44 MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
45 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
46};
47
48/* Buck: 2,3,4 */
49static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
50 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
51 MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
52 MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
53 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
54};
55
56/* Buck: 5,6,7,8,9 */
57static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
58 MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
59 MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
60};
61
Simon Glass8c428702015-07-02 18:16:04 -060062static const char max77686_buck_ctrl[] = {
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020063 0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
64};
65
Simon Glass8c428702015-07-02 18:16:04 -060066static const char max77686_buck_out[] = {
67 0xff, 0x11, 0x14, 0x1e, 0x28, 0x31, 0x33, 0x35, 0x37, 0x39
68};
69
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020070static int max77686_buck_volt2hex(int buck, int uV)
71{
Tom Riniaae78fa2017-05-10 15:20:17 -040072 int hex = 0;
73 int hex_max = 0;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020074
75 switch (buck) {
76 case 2:
77 case 3:
78 case 4:
79 /* hex = (uV - 600000) / 12500; */
80 hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
81 hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
Simon Glass75a429f2015-08-03 08:19:25 -060082 break;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020083 default:
Simon Glass75a429f2015-08-03 08:19:25 -060084 /*
85 * hex = (uV - 750000) / 50000. We assume that dynamic voltage
86 * scaling via GPIOs is not enabled and don't support that.
87 * If this is enabled then the driver will need to take that
Simon Glasse6b606d2015-08-09 09:10:57 -060088 * into account and check different registers depending on
89 * the current setting. See the datasheet for details.
Simon Glass75a429f2015-08-03 08:19:25 -060090 */
Przemyslaw Marczak1757df42015-04-20 20:07:47 +020091 hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
92 hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
93 break;
94 }
95
96 if (hex >= 0 && hex <= hex_max)
97 return hex;
98
Masahiro Yamada9b643e32017-09-16 14:10:41 +090099 pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200100 return -EINVAL;
101}
102
103static int max77686_buck_hex2volt(int buck, int hex)
104{
105 unsigned uV = 0;
Tom Riniaae78fa2017-05-10 15:20:17 -0400106 int hex_max = 0;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200107
108 if (hex < 0)
109 goto bad_hex;
110
111 switch (buck) {
112 case 2:
113 case 3:
114 case 4:
115 hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
116 if (hex > hex_max)
117 goto bad_hex;
118
119 /* uV = hex * 12500 + 600000; */
120 uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
121 break;
122 default:
123 hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
124 if (hex > hex_max)
125 goto bad_hex;
126
127 /* uV = hex * 50000 + 750000; */
128 uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
129 break;
130 }
131
132 return uV;
133
134bad_hex:
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900135 pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200136 return -EINVAL;
137}
138
139static int max77686_ldo_volt2hex(int ldo, int uV)
140{
Tom Riniaae78fa2017-05-10 15:20:17 -0400141 int hex = 0;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200142
143 switch (ldo) {
144 case 1:
145 case 2:
146 case 6:
147 case 7:
148 case 8:
149 case 15:
150 hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
151 /* hex = (uV - 800000) / 25000; */
152 break;
153 default:
154 hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
155 /* hex = (uV - 800000) / 50000; */
156 }
157
158 if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
159 return hex;
160
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900161 pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200162 return -EINVAL;
163}
164
165static int max77686_ldo_hex2volt(int ldo, int hex)
166{
167 unsigned int uV = 0;
168
169 if (hex > MAX77686_LDO_VOLT_MAX_HEX)
170 goto bad_hex;
171
172 switch (ldo) {
173 case 1:
174 case 2:
175 case 6:
176 case 7:
177 case 8:
178 case 15:
179 /* uV = hex * 25000 + 800000; */
180 uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
181 break;
182 default:
183 /* uV = hex * 50000 + 800000; */
184 uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
185 }
186
187 return uV;
188
189bad_hex:
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900190 pr_err("Value: %#x is wrong for ldo%d", hex, ldo);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200191 return -EINVAL;
192}
193
194static int max77686_ldo_hex2mode(int ldo, int hex)
195{
196 if (hex > MAX77686_LDO_MODE_MASK)
197 return -EINVAL;
198
199 switch (hex) {
200 case MAX77686_LDO_MODE_OFF:
201 return OPMODE_OFF;
202 case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
203 /* The same mode values but different meaning for each ldo */
204 switch (ldo) {
205 case 2:
206 case 6:
207 case 7:
208 case 8:
209 case 10:
210 case 11:
211 case 12:
212 case 14:
213 case 15:
214 case 16:
215 return OPMODE_STANDBY;
216 default:
217 return OPMODE_LPM;
218 }
219 case MAX77686_LDO_MODE_STANDBY_LPM:
220 return OPMODE_STANDBY_LPM;
221 case MAX77686_LDO_MODE_ON:
222 return OPMODE_ON;
223 default:
224 return -EINVAL;
225 }
226}
227
228static int max77686_buck_hex2mode(int buck, int hex)
229{
230 if (hex > MAX77686_BUCK_MODE_MASK)
231 return -EINVAL;
232
233 switch (hex) {
234 case MAX77686_BUCK_MODE_OFF:
235 return OPMODE_OFF;
236 case MAX77686_BUCK_MODE_ON:
237 return OPMODE_ON;
238 case MAX77686_BUCK_MODE_STANDBY:
239 switch (buck) {
240 case 1:
241 case 2:
242 case 3:
243 case 4:
244 return OPMODE_STANDBY;
245 default:
246 return -EINVAL;
247 }
248 case MAX77686_BUCK_MODE_LPM:
249 switch (buck) {
250 case 2:
251 case 3:
252 case 4:
253 return OPMODE_LPM;
254 default:
255 return -EINVAL;
256 }
257 default:
258 return -EINVAL;
259 }
260}
261
262static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
263{
264 int ret = -EINVAL;
265
266 if (buck < 1 || buck > MAX77686_BUCK_NUM)
267 return ret;
268
269 switch (buck) {
270 case 1:
271 *modesp = max77686_buck_mode_standby;
272 ret = ARRAY_SIZE(max77686_buck_mode_standby);
273 break;
274 case 2:
275 case 3:
276 case 4:
277 *modesp = max77686_buck_mode_lpm;
278 ret = ARRAY_SIZE(max77686_buck_mode_lpm);
279 break;
280 default:
281 *modesp = max77686_buck_mode_onoff;
282 ret = ARRAY_SIZE(max77686_buck_mode_onoff);
283 }
284
285 return ret;
286}
287
288static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
289 struct udevice *dev)
290{
291 int ret = -EINVAL;
292
293 if (ldo < 1 || ldo > MAX77686_LDO_NUM)
294 return ret;
295
296 switch (ldo) {
297 case 2:
298 case 6:
299 case 7:
300 case 8:
301 case 10:
302 case 11:
303 case 12:
304 case 14:
305 case 15:
306 case 16:
307 *modesp = max77686_ldo_mode_standby2;
308 ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
309 break;
310 default:
311 *modesp = max77686_ldo_mode_standby1;
312 ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
313 }
314
315 return ret;
316}
317
318static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
319{
Tom Riniaae78fa2017-05-10 15:20:17 -0400320 unsigned int adr;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200321 unsigned char val;
Tom Riniaae78fa2017-05-10 15:20:17 -0400322 int hex, ldo, ret;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200323
324 if (op == PMIC_OP_GET)
325 *uV = 0;
326
327 ldo = dev->driver_data;
328 if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900329 pr_err("Wrong ldo number: %d", ldo);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200330 return -EINVAL;
331 }
332
333 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
334
335 ret = pmic_read(dev->parent, adr, &val, 1);
336 if (ret)
337 return ret;
338
339 if (op == PMIC_OP_GET) {
340 val &= MAX77686_LDO_VOLT_MASK;
341 ret = max77686_ldo_hex2volt(ldo, val);
342 if (ret < 0)
343 return ret;
344 *uV = ret;
345 return 0;
346 }
347
348 hex = max77686_ldo_volt2hex(ldo, *uV);
349 if (hex < 0)
350 return hex;
351
352 val &= ~MAX77686_LDO_VOLT_MASK;
353 val |= hex;
354 ret = pmic_write(dev->parent, adr, &val, 1);
355
356 return ret;
357}
358
359static int max77686_buck_val(struct udevice *dev, int op, int *uV)
360{
Tom Riniaae78fa2017-05-10 15:20:17 -0400361 unsigned int mask, adr;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200362 unsigned char val;
Tom Riniaae78fa2017-05-10 15:20:17 -0400363 int hex, buck, ret;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200364
365 buck = dev->driver_data;
366 if (buck < 1 || buck > MAX77686_BUCK_NUM) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900367 pr_err("Wrong buck number: %d", buck);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200368 return -EINVAL;
369 }
370
371 if (op == PMIC_OP_GET)
372 *uV = 0;
373
374 /* &buck_out = ctrl + 1 */
Simon Glass8c428702015-07-02 18:16:04 -0600375 adr = max77686_buck_out[buck];
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200376
377 /* mask */
378 switch (buck) {
379 case 2:
380 case 3:
381 case 4:
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200382 mask = MAX77686_BUCK234_VOLT_MASK;
Simon Glass75a429f2015-08-03 08:19:25 -0600383 break;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200384 default:
385 mask = MAX77686_BUCK_VOLT_MASK;
Simon Glass75a429f2015-08-03 08:19:25 -0600386 break;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200387 }
388
389 ret = pmic_read(dev->parent, adr, &val, 1);
390 if (ret)
391 return ret;
392
393 if (op == PMIC_OP_GET) {
394 val &= mask;
395 ret = max77686_buck_hex2volt(buck, val);
396 if (ret < 0)
397 return ret;
398 *uV = ret;
399 return 0;
400 }
401
402 hex = max77686_buck_volt2hex(buck, *uV);
403 if (hex < 0)
404 return hex;
405
406 val &= ~mask;
407 val |= hex;
408 ret = pmic_write(dev->parent, adr, &val, 1);
409
410 return ret;
411}
412
413static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
414{
Peng Fan86405222015-07-28 22:47:08 +0800415 unsigned int adr, mode;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200416 unsigned char val;
Peng Fan86405222015-07-28 22:47:08 +0800417 int ldo, ret;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200418
419 if (op == PMIC_OP_GET)
420 *opmode = -EINVAL;
421
422 ldo = dev->driver_data;
423 if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900424 pr_err("Wrong ldo number: %d", ldo);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200425 return -EINVAL;
426 }
427
428 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
429
430 ret = pmic_read(dev->parent, adr, &val, 1);
431 if (ret)
432 return ret;
433
434 if (op == PMIC_OP_GET) {
435 val &= MAX77686_LDO_MODE_MASK;
436 ret = max77686_ldo_hex2mode(ldo, val);
437 if (ret < 0)
438 return ret;
439 *opmode = ret;
440 return 0;
441 }
442
443 /* mode */
444 switch (*opmode) {
445 case OPMODE_OFF:
446 mode = MAX77686_LDO_MODE_OFF;
447 break;
448 case OPMODE_LPM:
449 switch (ldo) {
450 case 2:
451 case 6:
452 case 7:
453 case 8:
454 case 10:
455 case 11:
456 case 12:
457 case 14:
458 case 15:
459 case 16:
460 return -EINVAL;
461 default:
462 mode = MAX77686_LDO_MODE_LPM;
463 }
464 break;
465 case OPMODE_STANDBY:
466 switch (ldo) {
467 case 2:
468 case 6:
469 case 7:
470 case 8:
471 case 10:
472 case 11:
473 case 12:
474 case 14:
475 case 15:
476 case 16:
477 mode = MAX77686_LDO_MODE_STANDBY;
478 break;
479 default:
480 return -EINVAL;
481 }
482 break;
483 case OPMODE_STANDBY_LPM:
484 mode = MAX77686_LDO_MODE_STANDBY_LPM;
485 break;
486 case OPMODE_ON:
487 mode = MAX77686_LDO_MODE_ON;
488 break;
489 default:
490 mode = 0xff;
491 }
492
493 if (mode == 0xff) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900494 pr_err("Wrong mode: %d for ldo%d", *opmode, ldo);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200495 return -EINVAL;
496 }
497
498 val &= ~MAX77686_LDO_MODE_MASK;
499 val |= mode;
500 ret = pmic_write(dev->parent, adr, &val, 1);
501
502 return ret;
503}
504
505static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
506{
507 int ret, on_off;
508
509 if (op == PMIC_OP_GET) {
510 ret = max77686_ldo_mode(dev, op, &on_off);
511 if (ret)
512 return ret;
513
514 switch (on_off) {
515 case OPMODE_OFF:
Tom Rini6d6aece2016-01-17 02:44:37 +0000516 *enable = false;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200517 break;
518 case OPMODE_ON:
Tom Rini6d6aece2016-01-17 02:44:37 +0000519 *enable = true;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200520 break;
521 default:
522 return -EINVAL;
523 }
524 } else if (op == PMIC_OP_SET) {
Tom Rini6d6aece2016-01-17 02:44:37 +0000525 if (*enable)
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200526 on_off = OPMODE_ON;
Tom Rini6d6aece2016-01-17 02:44:37 +0000527 else
528 on_off = OPMODE_OFF;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200529
530 ret = max77686_ldo_mode(dev, op, &on_off);
531 if (ret)
532 return ret;
533 }
534
535 return 0;
536}
537
538static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
539{
Peng Fan86405222015-07-28 22:47:08 +0800540 unsigned int mask, adr, mode, mode_shift;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200541 unsigned char val;
Peng Fan86405222015-07-28 22:47:08 +0800542 int buck, ret;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200543
544 buck = dev->driver_data;
545 if (buck < 1 || buck > MAX77686_BUCK_NUM) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900546 pr_err("Wrong buck number: %d", buck);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200547 return -EINVAL;
548 }
549
Simon Glass8c428702015-07-02 18:16:04 -0600550 adr = max77686_buck_ctrl[buck];
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200551
552 /* mask */
553 switch (buck) {
554 case 2:
555 case 3:
556 case 4:
557 mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
558 break;
559 default:
560 mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
561 }
562
563 mask = MAX77686_BUCK_MODE_MASK << mode_shift;
564
565 ret = pmic_read(dev->parent, adr, &val, 1);
566 if (ret)
567 return ret;
568
569 if (op == PMIC_OP_GET) {
570 val &= mask;
571 val >>= mode_shift;
572 ret = max77686_buck_hex2mode(buck, val);
573 if (ret < 0)
574 return ret;
575 *opmode = ret;
576 return 0;
577 }
578
579 /* mode */
580 switch (*opmode) {
581 case OPMODE_OFF:
582 mode = MAX77686_BUCK_MODE_OFF;
583 break;
584 case OPMODE_STANDBY:
585 switch (buck) {
586 case 1:
587 case 2:
588 case 3:
589 case 4:
590 mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
591 break;
592 default:
593 mode = 0xff;
594 }
595 break;
596 case OPMODE_LPM:
597 switch (buck) {
598 case 2:
599 case 3:
600 case 4:
601 mode = MAX77686_BUCK_MODE_LPM << mode_shift;
602 break;
603 default:
604 mode = 0xff;
605 }
606 break;
607 case OPMODE_ON:
608 mode = MAX77686_BUCK_MODE_ON << mode_shift;
609 break;
610 default:
611 mode = 0xff;
612 }
613
614 if (mode == 0xff) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900615 pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200616 return -EINVAL;
617 }
618
619 val &= ~mask;
620 val |= mode;
621 ret = pmic_write(dev->parent, adr, &val, 1);
622
623 return ret;
624}
625
626static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
627{
628 int ret, on_off;
629
630 if (op == PMIC_OP_GET) {
631 ret = max77686_buck_mode(dev, op, &on_off);
632 if (ret)
633 return ret;
634
635 switch (on_off) {
636 case OPMODE_OFF:
637 *enable = false;
638 break;
639 case OPMODE_ON:
640 *enable = true;
641 break;
642 default:
643 return -EINVAL;
644 }
645 } else if (op == PMIC_OP_SET) {
Tom Rini6d6aece2016-01-17 02:44:37 +0000646 if (*enable)
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200647 on_off = OPMODE_ON;
Tom Rini6d6aece2016-01-17 02:44:37 +0000648 else
649 on_off = OPMODE_OFF;
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200650
651 ret = max77686_buck_mode(dev, op, &on_off);
652 if (ret)
653 return ret;
654 }
655
656 return 0;
657}
658
659static int max77686_ldo_probe(struct udevice *dev)
660{
661 struct dm_regulator_uclass_platdata *uc_pdata;
662
663 uc_pdata = dev_get_uclass_platdata(dev);
664
665 uc_pdata->type = REGULATOR_TYPE_LDO;
666 uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
667 &uc_pdata->mode, dev);
668
669 return 0;
670}
671
672static int ldo_get_value(struct udevice *dev)
673{
674 int uV;
675 int ret;
676
677 ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
678 if (ret)
679 return ret;
680
681 return uV;
682}
683
684static int ldo_set_value(struct udevice *dev, int uV)
685{
686 return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
687}
688
Keerthyb6168352017-06-13 09:53:48 +0530689static int ldo_get_enable(struct udevice *dev)
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200690{
691 bool enable = false;
692 int ret;
693
694 ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
695 if (ret)
696 return ret;
697
698 return enable;
699}
700
701static int ldo_set_enable(struct udevice *dev, bool enable)
702{
703 return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
704}
705
706static int ldo_get_mode(struct udevice *dev)
707{
708 int mode;
709 int ret;
710
711 ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
712 if (ret)
713 return ret;
714
715 return mode;
716}
717
718static int ldo_set_mode(struct udevice *dev, int mode)
719{
720 return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
721}
722
723static int max77686_buck_probe(struct udevice *dev)
724{
725 struct dm_regulator_uclass_platdata *uc_pdata;
726
727 uc_pdata = dev_get_uclass_platdata(dev);
728
729 uc_pdata->type = REGULATOR_TYPE_BUCK;
730 uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
731 &uc_pdata->mode);
732
733 return 0;
734}
735
736static int buck_get_value(struct udevice *dev)
737{
738 int uV;
739 int ret;
740
741 ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
742 if (ret)
743 return ret;
744
745 return uV;
746}
747
748static int buck_set_value(struct udevice *dev, int uV)
749{
750 return max77686_buck_val(dev, PMIC_OP_SET, &uV);
751}
752
Keerthyb6168352017-06-13 09:53:48 +0530753static int buck_get_enable(struct udevice *dev)
Przemyslaw Marczak1757df42015-04-20 20:07:47 +0200754{
755 bool enable = false;
756 int ret;
757
758 ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
759 if (ret)
760 return ret;
761
762 return enable;
763}
764
765static int buck_set_enable(struct udevice *dev, bool enable)
766{
767 return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
768}
769
770static int buck_get_mode(struct udevice *dev)
771{
772 int mode;
773 int ret;
774
775 ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
776 if (ret)
777 return ret;
778
779 return mode;
780}
781
782static int buck_set_mode(struct udevice *dev, int mode)
783{
784 return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
785}
786
787static const struct dm_regulator_ops max77686_ldo_ops = {
788 .get_value = ldo_get_value,
789 .set_value = ldo_set_value,
790 .get_enable = ldo_get_enable,
791 .set_enable = ldo_set_enable,
792 .get_mode = ldo_get_mode,
793 .set_mode = ldo_set_mode,
794};
795
796U_BOOT_DRIVER(max77686_ldo) = {
797 .name = MAX77686_LDO_DRIVER,
798 .id = UCLASS_REGULATOR,
799 .ops = &max77686_ldo_ops,
800 .probe = max77686_ldo_probe,
801};
802
803static const struct dm_regulator_ops max77686_buck_ops = {
804 .get_value = buck_get_value,
805 .set_value = buck_set_value,
806 .get_enable = buck_get_enable,
807 .set_enable = buck_set_enable,
808 .get_mode = buck_get_mode,
809 .set_mode = buck_set_mode,
810};
811
812U_BOOT_DRIVER(max77686_buck) = {
813 .name = MAX77686_BUCK_DRIVER,
814 .id = UCLASS_REGULATOR,
815 .ops = &max77686_buck_ops,
816 .probe = max77686_buck_probe,
817};