2 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
4 * See file CREDITS for list of people who contributed to this
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.
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.
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,
28 * MAX77686 PMIC Registers
30 #define MAX77686_DEVICE_ID 0x00
31 #define MAX77686_INTSRC 0x01
32 #define MAX77686_INT1 0x02
33 #define MAX77686_INT2 0x03
34 #define MAX77686_INT1MSK 0x04
35 #define MAX77686_INT2MSK 0x05
36 #define MAX77686_STATUS1 0x06
37 #define MAX77686_STATUS2 0x07
38 #define MAX77686_PWRON 0x08
39 #define MAX77686_ONOFF_DELAY 0x09
40 #define MAX77686_MRSTB 0x0A
43 #define MAX77686_INT1_MRSTB (1 << 7)
44 #define MAX77686_INT1_ONKEY1S (1 << 6)
45 #define MAX77686_INT1_ACOKBR (1 << 5)
46 #define MAX77686_INT1_ACOKBF (1 << 4)
47 #define MAX77686_INT1_PWRONR (1 << 1)
48 #define MAX77686_INT1_PWRONF (1 << 0)
50 #define MAX77686_PWRON_WTSRON (1 << 7)
51 #define MAX77686_PWRON_SMPLON (1 << 6)
52 #define MAX77686_PWRON_RTCA2 (1 << 5)
53 #define MAX77686_PWRON_RTCA1 (1 << 4)
54 #define MAX77686_PWRON_MRSTB (1 << 3)
55 #define MAX77686_PWRON_ACOKB (1 << 2)
56 #define MAX77686_PWRON_JIGONB (1 << 1)
57 #define MAX77686_PWRON_PWRON (1 << 0)
61 * MAX77686 RTC Registers
63 #define MAX77686_RTC_INT 0x00
64 #define MAX77686_RTC_UPDATE0 0x04
65 #define MAX77686_RTC_WTSR_SMPL 0x06
68 /* not supported mode has '0xff' */
70 unsigned char standby;
76 struct max77686_data {
79 struct pmic_opmode opmode;
80 unsigned char opmodes[5];
84 static const char *opmode_str[] = { "OFF", "STANDBY", "LPM", "ON" };
86 static const struct max77686_data bucks[] = {
87 {.reg = 0xff,.u.opmode = {0xff, 0xff, 0xff, 0xff, 0xff},}, /* dummy */
88 {.reg = 0x10,.u.opmode = {0x00, 0x01, 0xff, 0x03, 0x03},}, /* BUCK1 */
89 {.reg = 0x12,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},}, /* BUCK2 */
90 {.reg = 0x1c,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},}, /* BUCK3 */
91 {.reg = 0x26,.u.opmode = {0x00, 0x10, 0x20, 0x30, 0x30},}, /* BUCK4 */
92 {.reg = 0x30,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},}, /* BUCK5 */
93 {.reg = 0x32,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},}, /* BUCK6 */
94 {.reg = 0x34,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},}, /* BUCK7 */
95 {.reg = 0x36,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},}, /* BUCK8 */
96 {.reg = 0x38,.u.opmode = {0x00, 0xff, 0xff, 0x03, 0x03},}, /* BUCK9 */
99 static const struct max77686_data ldos[] = {
100 {.reg = 0xff,.u.opmode = {0xff, 0xff, 0xff, 0xff, 0xff},}, /* dummy */
101 {.reg = 0x40,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO1 */
102 {.reg = 0x41,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO2 */
103 {.reg = 0x42,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO3 */
104 {.reg = 0x43,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO4 */
105 {.reg = 0x44,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO5 */
106 {.reg = 0x45,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO6 */
107 {.reg = 0x46,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO7 */
108 {.reg = 0x47,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO8 */
109 {.reg = 0x48,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO9 */
110 {.reg = 0x49,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO10 */
111 {.reg = 0x4a,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO11 */
112 {.reg = 0x4b,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO12 */
113 {.reg = 0x4c,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO13 */
114 {.reg = 0x4d,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO14 */
115 {.reg = 0x4e,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO15 */
116 {.reg = 0x4f,.u.opmode = {0x00, 0x40, 0x80, 0xc0, 0xc0},}, /* LDO16 */
117 {.reg = 0x50,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO17 */
118 {.reg = 0x51,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO18 */
119 {.reg = 0x52,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO19 */
120 {.reg = 0x53,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO20 */
121 {.reg = 0x54,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO21 */
122 {.reg = 0x55,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO22 */
123 {.reg = 0x56,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO23 */
124 {.reg = 0x57,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO24 */
125 {.reg = 0x58,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO25 */
126 {.reg = 0x59,.u.opmode = {0x00, 0xff, 0x80, 0xc0, 0xc0},}, /* LDO26 */
129 static const char * pwron_source[] = {
140 static unsigned int pmic_bus = -1;
142 static unsigned char reg_int1 = -1;
143 static unsigned char reg_pwron = -1;
145 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex);
147 void max77686_bus_init(int bus_num)
152 void show_pwron_source(char *buf)
155 unsigned char addr = MAX77686_PMIC_ADDR;
158 i2c_read(addr, MAX77686_PWRON, 1, &val, 1);
159 for (i = 0; i < 8; i++) {
160 if (val & (0x1 << i)) {
161 printf("PWRON:\t%s (0x%02x)\n", pwron_source[i], val);
163 sprintf(buf, "PWRON: %s (0x%02x)", pwron_source[i], val);
171 static int max77686_rtc_probe(void)
173 unsigned char addr = MAX77686_RTC_ADDR;
175 i2c_set_bus_num(pmic_bus);
177 if (i2c_probe(addr)) {
178 puts("Can't found max77686-rtc\n");
185 static void max77686_rtc_read_update()
187 unsigned char addr = MAX77686_RTC_ADDR;
190 if (max77686_rtc_probe())
194 i2c_write(addr, MAX77686_RTC_UPDATE0, 1, &val, 1);
198 static void max77686_rtc_write_update()
200 unsigned char addr = MAX77686_RTC_ADDR;
203 if (max77686_rtc_probe())
207 i2c_write(addr, MAX77686_RTC_UPDATE0, 1, &val, 1);
211 void max77686_rtc_disable_wtsr_smpl(void)
213 unsigned char addr = MAX77686_RTC_ADDR;
216 if (max77686_rtc_probe())
220 i2c_write(addr, MAX77686_RTC_WTSR_SMPL, 1, &val, 1);
221 max77686_rtc_write_update();
224 int max77686_rtc_init(void)
226 unsigned char addr = MAX77686_RTC_ADDR;
229 if (max77686_rtc_probe())
233 i2c_read(addr, MAX77686_RTC_INT, 1, &val, 1);
241 static int max77686_probe(void)
243 unsigned char addr = MAX77686_PMIC_ADDR;
245 i2c_set_bus_num(pmic_bus);
247 if (i2c_probe(addr)) {
248 puts("Can't found max77686\n");
255 int max77686_init(void)
257 unsigned char addr = MAX77686_PMIC_ADDR;
262 if (max77686_probe())
265 i2c_read(addr, MAX77686_INT1, 1, ®_int1, 1);
266 i2c_read(addr, MAX77686_PWRON, 1, ®_pwron, 1);
271 int max77686_check_pwron_pwrkey(void)
273 /* check int1, not pwron */
274 return !!(reg_int1 & MAX77686_INT1_PWRONR);
277 int max77686_check_pwron_wtsr(void)
279 return !!(reg_pwron & MAX77686_PWRON_WTSRON);
282 int max77686_check_pwron_smpl(void)
284 return !!(reg_pwron & MAX77686_PWRON_SMPLON);
287 unsigned char max77686_get_reg_pwron(void)
292 int max77686_check_acokb_pwron(void)
294 unsigned char addr = MAX77686_PMIC_ADDR;
297 if (max77686_probe())
300 i2c_read(addr, MAX77686_PWRON, 1, &val, 1);
302 return !!(val & MAX77686_PWRON_ACOKB);
305 int max77686_check_pwrkey(void)
307 unsigned char addr = MAX77686_PMIC_ADDR;
310 if (max77686_probe())
313 i2c_read(addr, MAX77686_INT1, 1, &val, 1);
315 return !!(val & MAX77686_INT1_PWRONR);
318 int max77686_clear_irq(void)
320 unsigned char addr = MAX77686_PMIC_ADDR;
321 unsigned char val[2];
323 if (max77686_probe())
326 i2c_read(addr, MAX77686_INT1, 1, val, 2);
331 static int max77686_status(void)
333 unsigned char addr = MAX77686_PMIC_ADDR;
334 unsigned char val[2];
335 unsigned char opmode;
338 if (max77686_probe())
341 for (i = 1; i <= 9; i++) {
342 printf("BUCK%d\t: ", i);
344 if (2 <= i && i <= 4)
345 i2c_read(addr, bucks[i].reg + 2, 1, val, 1);
347 i2c_read(addr, bucks[i].reg + 1, 1, val, 1);
349 printf("%7uuV, ", max77686_hex_to_voltage(i, 0, val[0]));
351 i2c_read(addr, bucks[i].reg, 1, val, 1);
353 opmode = val[0] & bucks[i].u.opmode.mask;
354 if (opmode == bucks[i].u.opmode.off)
356 else if (opmode == bucks[i].u.opmode.standby)
357 puts("STANDBY (ON/OFF by PWRREQ)\n");
358 else if (opmode == bucks[i].u.opmode.lpm)
360 else if (opmode == bucks[i].u.opmode.on)
363 printf("unknown (0x%x)\n", val[0]);
366 for (i = 1; i <= 26; i++) {
367 printf("LDO%d\t: ", i);
369 i2c_read(addr, ldos[i].reg, 1, val, 1);
371 printf("%7uuV, ", max77686_hex_to_voltage(0, i, val[0] & ~ldos[i].u.opmode.mask));
373 opmode = val[0] & ldos[i].u.opmode.mask;
374 if (opmode == ldos[i].u.opmode.off)
376 else if (opmode == ldos[i].u.opmode.standby)
377 puts("STANDBY (ON/OFF by PWRREQ)\n");
378 else if (opmode == ldos[i].u.opmode.lpm)
379 puts("LP (ON with LPM by PWRREQ)\n");
380 else if (opmode == ldos[i].u.opmode.on)
383 printf("unknown (0x%x)\n", val[0]);
389 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex)
401 /* 0x00..0x3f: 0.800V ~ 2.375V */
403 printf("warn: out of range (0x%x<0x3f)\n", hex);
407 uV = 800000 + hex * 25000;
410 /* 0x00..0x3f: 0.800V ~ 3.950V*/
412 printf("warn: out of range (0x%x<0x3f)\n", hex);
416 uV = 800000 + hex * 50000;
428 /* 0x00..0xff: 0.600V ~ 3.7875V */
430 printf("warn: out of range (0x%x<0xff)\n", hex);
434 uV = 600000 + hex * 12500;
437 /* 0x00..0x3f: 0.750V ~ 3.900V*/
439 printf("warn: out of range (0x%x<0x3f)\n", hex);
443 uV = 750000 + hex * 50000;
451 static int max77686_voltage_to_hex(int buck, int ldo, ulong uV)
453 unsigned int set = 0;
465 else if (uV > 2375000)
468 set = (uV - 800000) / 25000;
473 else if (uV > 3950000)
476 set = (uV - 800000) / 50000;
489 else if (uV > 3787500)
492 set = (uV - 600000) / 12500;
497 else if (uV > 3900000)
500 set = (uV - 750000) / 50000;
507 static int max77686_set_voltage(int buck, int ldo, ulong uV)
509 unsigned char addr = MAX77686_PMIC_ADDR;
510 unsigned char val[2];
511 unsigned int reg = 0, set = 0, mask = 0;
514 if (ldo < 1 || ldo > 26)
520 if (buck < 1 || buck > 9)
527 reg = bucks[buck].reg + 2;
531 reg = bucks[buck].reg + 1;
537 set = max77686_voltage_to_hex(buck, ldo, uV) & mask;
539 if (max77686_probe())
542 i2c_read(addr, reg, 1, val, 1);
545 i2c_write(addr, reg, 1, val, 1);
546 i2c_read(addr, reg, 1, val, 1);
547 debug("MAX77686 REG %2.2xh has %2.2xh\n",
553 int max77686_set_ldo_voltage(int ldo, ulong uV)
555 return max77686_set_voltage(0, ldo, uV);
558 int max77686_set_buck_voltage(int buck, ulong uV)
560 return max77686_set_voltage(buck, 0, uV);
563 static int max77686_set_output(int buck, int ldo, opmode_type mode)
565 unsigned char addr = MAX77686_PMIC_ADDR;
566 unsigned char val[2];
567 unsigned int reg, set, mask;
570 if (ldo < 1 || ldo > 26)
573 mask = ldos[ldo].u.opmode.mask;
574 set = ldos[ldo].u.opmodes[mode];
576 if (buck < 1 || buck > 9)
578 reg = bucks[buck].reg;
579 mask = bucks[buck].u.opmode.mask;
580 set = bucks[buck].u.opmodes[mode];
584 if (max77686_probe())
588 printf("%s is not supported on LDO%d\n", opmode_str[mode], ldo);
592 i2c_read(addr, reg, 1, val, 1);
595 i2c_write(addr, reg, 1, val, 1);
596 i2c_read(addr, reg, 1, val, 1);
601 int max77686_set_ldo_mode(int ldo, opmode_type mode)
603 return max77686_set_output(0, ldo, mode);
606 int max77686_set_buck_mode(int buck, opmode_type mode)
608 return max77686_set_output(buck, 0, mode);
611 int max77686_set_32khz(unsigned char mode)
613 unsigned char addr = MAX77686_PMIC_ADDR;
614 unsigned char val[2];
616 if (max77686_probe())
620 i2c_write(addr, 0x7f, 1, val, 1);
625 static int do_max77686(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
627 int buck = 0, ldo = 0, on = -1;
632 if (strncmp(argv[1], "status", 6) == 0)
633 return max77686_status();
637 if (argv[1][0] == 'l')
638 ldo = simple_strtoul(argv[2], NULL, 10);
639 else if (argv[1][0] == 'b')
640 buck = simple_strtoul(argv[2], NULL, 10);
642 printf("Option = \"%s\" ? \n", argv[1]);
646 if (!strncmp(argv[3], "on", 2))
647 ret = max77686_set_output(buck, ldo, OPMODE_ON);
648 else if (!strncmp(argv[3], "lpm", 3))
649 ret = max77686_set_output(buck, ldo, OPMODE_LPM);
650 else if (!strncmp(argv[3], "standby", 3))
651 ret = max77686_set_output(buck, ldo, OPMODE_STANDBY);
652 else if (!strncmp(argv[3], "off", 3))
653 ret = max77686_set_output(buck, ldo, OPMODE_OFF);
655 ulong volt = simple_strtoul(argv[3], NULL, 10);
656 printf("volt = %uuV\n", volt);
660 ret = max77686_set_voltage(buck, ldo, volt);
664 printf("%s %s %s\n", argv[1], argv[2], argv[3]);
677 max77686, 4, 1, do_max77686,
678 "PMIC LDO & BUCK control for MAX77686",
679 "status - Display PMIC LDO & BUCK status\n"
680 "max77686 ldo num volt - Set LDO voltage\n"
681 "max77686 ldo num on/lpm/standby/off - Set LDO output mode\n"
682 "max77686 buck num volt - Set BUCK voltage\n"
683 "max77686 buck num on/lpm/standby/off - Set BUCK output mode\n"
684 " volt is voltage in uV\n"