merge with master
[kernel/u-boot.git] / drivers / misc / max77686.c
1 /*
2  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <common.h>
24 #include <i2c.h>
25 #include <asm/arch/gpio.h>
26 #include <max77686.h>
27
28
29 #define MAX77686_RTC_INT        (0 << 0)
30
31 enum {
32         PMIC_UART_SEL
33 };
34
35 struct pmic_opmode {
36         /* not supported mode has '0xff' */
37         unsigned char off;
38         unsigned char standby;
39         unsigned char lpm;
40         unsigned char on;
41         unsigned char mask;
42 };
43
44 struct max77686_data {
45         unsigned char reg;
46         union opmode {
47                 struct pmic_opmode opmode;
48                 unsigned char opmodes[5];
49         } u;
50 };
51
52 static const char *opmode_str[] = { "OFF", "STANDBY", "LPM", "ON" };
53
54 static const struct max77686_data bucks[] = {
55         {.reg = 0xff,.u.opmode = {0xff, 0xff, 0xff, 0xff, 0xff},},      /* dummy */
56         {.reg = 0x10,.u.opmode = {0x00, 0x01, 0xff, 0x03, 0x03},},      /* BUCK1 */
57         {.reg = 0x12,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},},      /* BUCK2 */
58         {.reg = 0x1c,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},},      /* BUCK3 */
59         {.reg = 0x26,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},},      /* BUCK4 */
60         {.reg = 0x30,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},},      /* BUCK5 */
61         {.reg = 0x32,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},},      /* BUCK6 */
62         {.reg = 0x34,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},},      /* BUCK7 */
63         {.reg = 0x36,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},},      /* BUCK8 */
64         {.reg = 0x38,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},},      /* BUCK9 */
65 };
66
67 static const struct max77686_data ldos[] = {
68         {.reg = 0xff,.u.opmode = {0xff, 0xff, 0xff, 0xff, 0xff},},      /* dummy */
69         {.reg = 0x40,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO1 */
70         {.reg = 0x41,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO2 */
71         {.reg = 0x42,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO3 */
72         {.reg = 0x43,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO4 */
73         {.reg = 0x44,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO5 */
74         {.reg = 0x45,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO6 */
75         {.reg = 0x46,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO7 */
76         {.reg = 0x47,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO8 */
77         {.reg = 0x48,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO9 */
78         {.reg = 0x49,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO10 */
79         {.reg = 0x4a,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO11 */
80         {.reg = 0x4b,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO12 */
81         {.reg = 0x4c,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO13 */
82         {.reg = 0x4d,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO14 */
83         {.reg = 0x4e,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO15 */
84         {.reg = 0x4f,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},},      /* LDO16 */
85         {.reg = 0x50,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO17 */
86         {.reg = 0x51,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO18 */
87         {.reg = 0x52,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO19 */
88         {.reg = 0x53,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO20 */
89         {.reg = 0x54,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO21 */
90         {.reg = 0x55,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO22 */
91         {.reg = 0x56,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO23 */
92         {.reg = 0x57,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO24 */
93         {.reg = 0x58,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO25 */
94         {.reg = 0x59,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},},      /* LDO26 */
95 };
96
97 static const char * pwron_source[] = {
98         "PWRON",
99         "JIGONB",
100         "ACOKB",
101         "MRSTB",
102         "RTCA1",
103         "RTCA2",
104         "SMPLON",
105         "WTSRON"
106 };
107
108 static struct max77686_platform_data *pmic_pd;
109
110 static unsigned int pmic_bus = 5;
111
112 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex);
113
114 void max77686_bus_init(int bus_num)
115 {
116         pmic_bus = bus_num;
117 }
118
119 void show_pwron_source(char *buf)
120 {
121         int i;
122         unsigned char addr = MAX77686_PMIC_ADDR;
123         unsigned char val;
124
125         i2c_read(addr, MAX77686_PWRON, 1, &val, 1);
126         for (i = 0; i < 8; i++) {
127                 if (val & (0x1 << i)) {
128                         printf("PWRON:\t%s (0x%02x)\n", pwron_source[i], val);
129                         if (buf)
130                                 sprintf(buf, "PWRON: %s (0x%02x)", pwron_source[i], val);
131                 }
132         }
133 }
134
135 int max77686_check_acokb_pwron(void)
136 {
137         unsigned char addr = MAX77686_PMIC_ADDR;
138         unsigned char val;
139
140         if (max77686_probe())
141                 return -1;
142
143         i2c_read(addr, MAX77686_PWRON, 1, &val, 1);
144
145         return !!(val & MAX77686_PWRON_ACOKB);
146 }
147
148 int max77686_rtc_init(void)
149 {
150         unsigned char addr = MAX77686_RTC_ADDR;
151         unsigned char val;
152
153         i2c_set_bus_num(pmic_bus);
154
155         if (i2c_probe(addr)) {
156                 puts("Can't found max77686\n");
157                 return -1;
158         }
159
160         i2c_read(addr, MAX77686_RTC_INT, 1, &val, 1);
161
162         return 0;
163 }
164
165 int max77686_probe(void)
166 {
167         unsigned char addr = MAX77686_PMIC_ADDR;
168
169         i2c_set_bus_num(pmic_bus);
170
171         if (i2c_probe(addr)) {
172                 puts("Can't found max77686\n");
173                 return -1;
174         }
175
176         return 0;
177 }
178
179 #ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
180 #define i2c_read(addr, reg, alen, val, len)     \
181                         i2c_read_r(addr, reg, alen, val, len)
182 #endif
183
184 int max77686_get_irq(int irq)
185 {
186         unsigned char addr = MAX77686_PMIC_ADDR;
187         unsigned char val[2];
188         unsigned int ret;
189         unsigned int reg;
190         unsigned int shift;
191
192         if (max77686_probe())
193                 return 0;
194
195         switch (irq) {
196         case PWRONR:
197                 reg = 0;
198                 shift = 1;
199                 break;
200         case PWRONF:
201                 reg = 0;
202                 shift = 0;
203                 break;
204         case PWRON1S:
205                 reg = 0;
206                 shift = 6;
207                 break;
208         default:
209                 return 0;
210         }
211
212         i2c_read(addr, 0x2, 1, val, 2);
213
214         ret = val[reg] & (1 << shift);
215
216         return !!ret;
217 }
218
219 /* get irq value at power on */
220 int max77686_get_irq_booton(int irq)
221 {
222         unsigned char addr = MAX77686_PMIC_ADDR;
223         unsigned char val[2];
224         unsigned int ret;
225         unsigned int reg;
226         unsigned int shift;
227         static int first = 1;
228
229         if (max77686_probe())
230                 return 0;
231
232         switch (irq) {
233         case PWRONR:
234                 reg = 0;
235                 shift = 1;
236                 break;
237         case PWRONF:
238                 reg = 0;
239                 shift = 0;
240                 break;
241         case PWRON1S:
242                 reg = 0;
243                 shift = 6;
244                 break;
245         default:
246                 return 0;
247         }
248
249         if (first) {
250                 i2c_read(addr, 0x2, 1, val, 2);
251                 first = 0;
252         }
253
254         ret = val[reg] & (1 << shift);
255
256         return !!ret;
257 }
258
259 static int max77686_status(void)
260 {
261         unsigned char addr = MAX77686_PMIC_ADDR;
262         unsigned char val[2];
263         unsigned char opmode;
264         int i;
265
266         if (max77686_probe())
267                 return -1;
268
269         for (i = 1; i <= 9; i++) {
270                 printf("BUCK%d\t: ", i);
271
272                 if (2 <= i && i <= 4)
273                         i2c_read(addr, bucks[i].reg + 2, 1, val, 1);
274                 else
275                         i2c_read(addr, bucks[i].reg + 1, 1, val, 1);
276
277                 printf("%7uuV, ", max77686_hex_to_voltage(i, 0, val[0]));
278
279                 i2c_read(addr, bucks[i].reg, 1, val, 1);
280
281                 opmode = val[0] & bucks[i].u.opmode.mask;
282                 if (opmode == bucks[i].u.opmode.off)
283                         puts("OFF\n");
284                 else if (opmode == bucks[i].u.opmode.standby)
285                         puts("STANDBY (ON/OFF by PWRREQ)\n");
286                 else if (opmode == bucks[i].u.opmode.lpm)
287                         puts("LP\n");
288                 else if (opmode == bucks[i].u.opmode.on)
289                         puts("ON\n");
290                 else
291                         printf("unknown (0x%x)\n", val[0]);
292         }
293
294         for (i = 1; i <= 26; i++) {
295                 printf("LDO%d\t: ", i);
296
297                 i2c_read(addr, ldos[i].reg, 1, val, 1);
298
299                 printf("%7uuV, ", max77686_hex_to_voltage(0, i, val[0] & ~ldos[i].u.opmode.mask));
300
301                 opmode = val[0] & ldos[i].u.opmode.mask;
302                 if (opmode == ldos[i].u.opmode.off)
303                         puts("OFF\n");
304                 else if (opmode == ldos[i].u.opmode.standby)
305                         puts("STANDBY (ON/OFF by PWRREQ)\n");
306                 else if (opmode == ldos[i].u.opmode.lpm)
307                         puts("LP (ON with LPM by PWRREQ)\n");
308                 else if (opmode == ldos[i].u.opmode.on)
309                         puts("ON\n");
310                 else
311                         printf("unknown (0x%x)\n", val[0]);
312         }
313
314         return 0;
315 }
316
317 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex)
318 {
319         ulong uV;
320
321         if (ldo) {
322                 switch (ldo) {
323                 case 1:
324                 case 2:
325                 case 6:
326                 case 7:
327                 case 8:
328                 case 15:
329                         /* 0x00..0x3f: 0.800V ~ 2.375V */
330                         if (hex > 0x3f) {
331                                 printf("warn: out of range (0x%x<0x3f)\n", hex);
332                                 hex = 0x3f;
333                         }
334
335                         uV = 800000 + hex * 25000;
336                         break;
337                 default:
338                         /* 0x00..0x3f: 0.800V ~ 3.950V*/
339                         if (hex > 0x3f) {
340                                 printf("warn: out of range (0x%x<0x3f)\n", hex);
341                                 hex = 0x3f;
342                         }
343
344                         uV = 800000 + hex * 50000;
345                         break;
346                 }
347
348                 return uV;
349         }
350
351         if (buck) {
352                 switch (buck) {
353                 case 2:
354                 case 3:
355                 case 4:
356                         /* 0x00..0xff: 0.600V ~ 3.7875V */
357                         if (hex > 0xff) {
358                                 printf("warn: out of range (0x%x<0xff)\n", hex);
359                                 hex = 0xff;
360                         }
361
362                         uV = 600000 + hex * 12500;
363                         break;
364                 default:
365                         /* 0x00..0x3f: 0.750V ~ 3.900V*/
366                         if (hex > 0x3f) {
367                                 printf("warn: out of range (0x%x<0x3f)\n", hex);
368                                 hex = 0x3f;
369                         }
370
371                         uV = 750000 + hex * 50000;
372                         break;
373                 }
374
375                 return uV;
376         }
377 }
378
379 static int max77686_voltage_to_hex(int buck, int ldo, ulong uV)
380 {
381         unsigned int set = 0;
382
383         if (ldo) {
384                 switch (ldo) {
385                 case 1:
386                 case 2:
387                 case 6:
388                 case 7:
389                 case 8:
390                 case 15:
391                         if (uV < 800000)
392                                 set = 0x0;
393                         else if (uV > 2375000)
394                                 set = 0x3f;
395                         else
396                                 set = (uV - 800000) / 25000;
397                         break;
398                 default:
399                         if (uV < 800000)
400                                 set = 0x0;
401                         else if (uV > 3950000)
402                                 set = 0x3f;
403                         else
404                                 set = (uV - 800000) / 50000;
405                 }
406
407                 return set;
408         }
409
410         if (buck) {
411                 switch (buck) {
412                 case 2:
413                 case 3:
414                 case 4:
415                         if (uV < 600000)
416                                 set = 0;
417                         else if (uV > 3787500)
418                                 set = 0xff;
419                         else
420                                 set = (uV - 600000) / 12500;
421                         break;
422                 default:
423                         if (uV < 750000)
424                                 set = 0;
425                         else if (uV > 3900000)
426                                 set = 0x3f;
427                         else
428                                 set = (uV - 750000) / 50000;
429                 }
430
431                 return set;
432         }
433 }
434
435 static int max77686_set_voltage(int buck, int ldo, ulong uV)
436 {
437         unsigned char addr = MAX77686_PMIC_ADDR;
438         unsigned char val[2];
439         unsigned int reg = 0, set = 0, mask = 0;
440
441         if (ldo) {
442                 if (ldo < 1 || ldo > 26)
443                         return -1;
444
445                 reg = ldos[ldo].reg;
446                 mask = 0x3f;
447         } else if (buck) {
448                 if (buck < 1 || buck > 9)
449                         return -1;
450
451                 switch (buck) {
452                 case 2:
453                 case 3:
454                 case 4:
455                         reg = bucks[buck].reg + 2;
456                         mask = 0xff;
457                         break;
458                 default:
459                         reg = bucks[buck].reg + 1;
460                         mask = 0x3f;
461                 }
462         } else
463                 return -1;
464
465         set = max77686_voltage_to_hex(buck, ldo, uV) & mask;
466
467         if (max77686_probe())
468                 return -1;
469
470         i2c_read(addr, reg, 1, val, 1);
471         val[0] &= ~mask;
472         val[0] |= set;
473         i2c_write(addr, reg, 1, val, 1);
474         i2c_read(addr, reg, 1, val, 1);
475         debug("MAX77686 REG %2.2xh has %2.2xh\n",
476                         reg, val[0]);
477
478         return 0;
479 }
480
481 int max77686_set_ldo_voltage(int ldo, ulong uV)
482 {
483         return max77686_set_voltage(0, ldo, uV);
484 }
485
486 int max77686_set_buck_voltage(int buck, ulong uV)
487 {
488         return max77686_set_voltage(buck, 0, uV);
489 }
490
491 static int max77686_set_output(int buck, int ldo, opmode_type mode)
492 {
493         unsigned char addr = MAX77686_PMIC_ADDR;
494         unsigned char val[2];
495         unsigned int reg, set, mask;
496
497         if (ldo) {
498                 if (ldo < 1 || ldo > 26)
499                         return -1;
500                 reg = ldos[ldo].reg;
501                 mask = ldos[ldo].u.opmode.mask;
502                 set = ldos[ldo].u.opmodes[mode];
503         } else if (buck) {
504                 if (buck < 1 || buck > 9)
505                         return -1;
506                 reg = bucks[buck].reg;
507                 mask = bucks[buck].u.opmode.mask;
508                 set = bucks[buck].u.opmodes[mode];
509         } else
510                 return -1;
511
512         if (max77686_probe())
513                 return -1;
514
515         if (set == 0xff) {
516                 printf("%s is not supported on LDO%d\n", opmode_str[mode], ldo);
517                 return -1;
518         }
519
520         i2c_read(addr, reg, 1, val, 1);
521         val[0] &= ~mask;
522         val[0] |= set;
523         i2c_write(addr, reg, 1, val, 1);
524         i2c_read(addr, reg, 1, val, 1);
525
526         return 0;
527 }
528
529 int max77686_set_ldo_mode(int ldo, opmode_type mode)
530 {
531         return max77686_set_output(0, ldo, mode);
532 }
533
534 int max77686_set_buck_mode(int buck, opmode_type mode)
535 {
536         return max77686_set_output(buck, 0, mode);
537 }
538
539 int max77686_set_32khz(unsigned char mode)
540 {
541         unsigned char addr = MAX77686_PMIC_ADDR;
542         unsigned char val[2];
543
544         if (max77686_probe())
545                 return -1;
546
547         val[0] = mode;
548         i2c_write(addr, 0x7f, 1, val, 1);
549
550         return 0;
551 }
552
553 static int max77686_gpio_control(int port, int value)
554 {
555         if (pmic_pd == NULL)
556                 return 1;
557
558         switch (port) {
559         case PMIC_UART_SEL:
560                 gpio_cfg_pin(pmic_pd->bank, pmic_pd->uart_sel, 1);
561                 gpio_set_value(pmic_pd->bank, pmic_pd->uart_sel, value);
562                 break;
563         default:
564                 break;
565         }
566
567         return 0;
568 }
569
570 void max77686_set_platform_data(struct max77686_platform_data *pd)
571 {
572         if (pd == NULL) {
573                 puts("pd is NULL.\n");
574                 return;
575         }
576
577         pmic_pd = pd;
578 }
579
580 static int do_max77686(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
581 {
582         int buck = 0, ldo = 0, on = -1;
583         int ret = 0;
584
585         switch (argc) {
586         case 2:
587                 if (strncmp(argv[1], "status", 6) == 0)
588                         return max77686_status();
589                 break;
590         case 3:
591                 if (strncmp(argv[1], "uart", 4) != 0)
592                         break;
593
594                 if (strncmp(argv[2], "ap", 2) == 0)
595                         on = 1;
596                 else if (strncmp(argv[2], "cp", 2) == 0)
597                         on = 0;
598                 else
599                         break;
600
601                 ret = max77686_gpio_control(PMIC_UART_SEL, on);
602
603                 if (!ret)
604                         printf("pmic: %s %s\n", argv[1], argv[2]);
605                 else
606                         printf("pmic_pd is not valid\n");
607
608                 return ret;
609         case 4:
610                 if (argv[1][0] == 'l')
611                         ldo = simple_strtoul(argv[2], NULL, 10);
612                 else if (argv[1][0] == 'b')
613                         buck = simple_strtoul(argv[2], NULL, 10);
614                 else {
615                         printf("Option = \"%s\" ? \n", argv[1]);
616                         break;
617                 }
618
619                 if (!strncmp(argv[3], "on", 2))
620                         ret = max77686_set_output(buck, ldo, OPMODE_ON);
621                 else if (!strncmp(argv[3], "lpm", 3))
622                         ret = max77686_set_output(buck, ldo, OPMODE_LPM);
623                 else if (!strncmp(argv[3], "standby", 3))
624                         ret = max77686_set_output(buck, ldo, OPMODE_STANDBY);
625                 else if (!strncmp(argv[3], "off", 3))
626                         ret = max77686_set_output(buck, ldo, OPMODE_OFF);
627                 else {
628                         ulong volt = simple_strtoul(argv[3], NULL, 10);
629                         printf("volt = %uuV\n", volt);
630                         if (volt <= 0)
631                                 ret = -1;
632                         else
633                                 ret = max77686_set_voltage(buck, ldo, volt);
634                 }
635
636                 if (!ret)
637                         printf("%s %s %s\n", argv[1], argv[2], argv[3]);
638                 if (ret < 0)
639                         printf("Error.\n");
640                 return ret;
641         default:
642                 break;
643         }
644
645         cmd_usage(cmdtp);
646         return 1;
647 }
648
649 U_BOOT_CMD(
650         max77686, 4, 1, do_max77686,
651         "PMIC LDO & BUCK control for MAX77686",
652         "status - Display PMIC LDO & BUCK status\n"
653         "max77686 uart ap/cp - Change uart path\n"
654         "max77686 ldo num volt - Set LDO voltage\n"
655         "max77686 ldo num on/lpm/standby/off - Set LDO output mode\n"
656         "max77686 buck num volt - Set BUCK voltage\n"
657         "max77686 buck num on/lpm/standby/off - Set BUCK output mode\n"
658         "       volt is voltage in uV\n"
659 );