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,
25 #include <asm/arch/gpio.h>
29 #define MAX77686_RTC_INT (0 << 0)
36 /* not supported mode has '0xff' */
38 unsigned char standby;
44 struct max77686_data {
47 struct pmic_opmode opmode;
48 unsigned char opmodes[5];
52 static const char *opmode_str[] = { "OFF", "STANDBY", "LPM", "ON" };
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 */
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 */
97 static const char * pwron_source[] = {
108 static struct max77686_platform_data *pmic_pd;
110 static unsigned int pmic_bus = 5;
112 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex);
114 void max77686_bus_init(int bus_num)
119 void show_pwron_source(char *buf)
122 unsigned char addr = MAX77686_PMIC_ADDR;
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);
130 sprintf(buf, "PWRON: %s (0x%02x)", pwron_source[i], val);
135 int max77686_check_acokb_pwron(void)
137 unsigned char addr = MAX77686_PMIC_ADDR;
140 if (max77686_probe())
143 i2c_read(addr, MAX77686_PWRON, 1, &val, 1);
145 return !!(val & MAX77686_PWRON_ACOKB);
148 int max77686_rtc_init(void)
150 unsigned char addr = MAX77686_RTC_ADDR;
153 i2c_set_bus_num(pmic_bus);
155 if (i2c_probe(addr)) {
156 puts("Can't found max77686\n");
160 i2c_read(addr, MAX77686_RTC_INT, 1, &val, 1);
165 int max77686_probe(void)
167 unsigned char addr = MAX77686_PMIC_ADDR;
169 i2c_set_bus_num(pmic_bus);
171 if (i2c_probe(addr)) {
172 puts("Can't found max77686\n");
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)
184 int max77686_get_irq(int irq)
186 unsigned char addr = MAX77686_PMIC_ADDR;
187 unsigned char val[2];
192 if (max77686_probe())
212 i2c_read(addr, 0x2, 1, val, 2);
214 ret = val[reg] & (1 << shift);
219 /* get irq value at power on */
220 int max77686_get_irq_booton(int irq)
222 unsigned char addr = MAX77686_PMIC_ADDR;
223 unsigned char val[2];
227 static int first = 1;
229 if (max77686_probe())
250 i2c_read(addr, 0x2, 1, val, 2);
254 ret = val[reg] & (1 << shift);
259 static int max77686_status(void)
261 unsigned char addr = MAX77686_PMIC_ADDR;
262 unsigned char val[2];
263 unsigned char opmode;
266 if (max77686_probe())
269 for (i = 1; i <= 9; i++) {
270 printf("BUCK%d\t: ", i);
272 if (2 <= i && i <= 4)
273 i2c_read(addr, bucks[i].reg + 2, 1, val, 1);
275 i2c_read(addr, bucks[i].reg + 1, 1, val, 1);
277 printf("%7uuV, ", max77686_hex_to_voltage(i, 0, val[0]));
279 i2c_read(addr, bucks[i].reg, 1, val, 1);
281 opmode = val[0] & bucks[i].u.opmode.mask;
282 if (opmode == bucks[i].u.opmode.off)
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)
288 else if (opmode == bucks[i].u.opmode.on)
291 printf("unknown (0x%x)\n", val[0]);
294 for (i = 1; i <= 26; i++) {
295 printf("LDO%d\t: ", i);
297 i2c_read(addr, ldos[i].reg, 1, val, 1);
299 printf("%7uuV, ", max77686_hex_to_voltage(0, i, val[0] & ~ldos[i].u.opmode.mask));
301 opmode = val[0] & ldos[i].u.opmode.mask;
302 if (opmode == ldos[i].u.opmode.off)
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)
311 printf("unknown (0x%x)\n", val[0]);
317 static ulong max77686_hex_to_voltage(int buck, int ldo, int hex)
329 /* 0x00..0x3f: 0.800V ~ 2.375V */
331 printf("warn: out of range (0x%x<0x3f)\n", hex);
335 uV = 800000 + hex * 25000;
338 /* 0x00..0x3f: 0.800V ~ 3.950V*/
340 printf("warn: out of range (0x%x<0x3f)\n", hex);
344 uV = 800000 + hex * 50000;
356 /* 0x00..0xff: 0.600V ~ 3.7875V */
358 printf("warn: out of range (0x%x<0xff)\n", hex);
362 uV = 600000 + hex * 12500;
365 /* 0x00..0x3f: 0.750V ~ 3.900V*/
367 printf("warn: out of range (0x%x<0x3f)\n", hex);
371 uV = 750000 + hex * 50000;
379 static int max77686_voltage_to_hex(int buck, int ldo, ulong uV)
381 unsigned int set = 0;
393 else if (uV > 2375000)
396 set = (uV - 800000) / 25000;
401 else if (uV > 3950000)
404 set = (uV - 800000) / 50000;
417 else if (uV > 3787500)
420 set = (uV - 600000) / 12500;
425 else if (uV > 3900000)
428 set = (uV - 750000) / 50000;
435 static int max77686_set_voltage(int buck, int ldo, ulong uV)
437 unsigned char addr = MAX77686_PMIC_ADDR;
438 unsigned char val[2];
439 unsigned int reg = 0, set = 0, mask = 0;
442 if (ldo < 1 || ldo > 26)
448 if (buck < 1 || buck > 9)
455 reg = bucks[buck].reg + 2;
459 reg = bucks[buck].reg + 1;
465 set = max77686_voltage_to_hex(buck, ldo, uV) & mask;
467 if (max77686_probe())
470 i2c_read(addr, reg, 1, val, 1);
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",
481 int max77686_set_ldo_voltage(int ldo, ulong uV)
483 return max77686_set_voltage(0, ldo, uV);
486 int max77686_set_buck_voltage(int buck, ulong uV)
488 return max77686_set_voltage(buck, 0, uV);
491 static int max77686_set_output(int buck, int ldo, opmode_type mode)
493 unsigned char addr = MAX77686_PMIC_ADDR;
494 unsigned char val[2];
495 unsigned int reg, set, mask;
498 if (ldo < 1 || ldo > 26)
501 mask = ldos[ldo].u.opmode.mask;
502 set = ldos[ldo].u.opmodes[mode];
504 if (buck < 1 || buck > 9)
506 reg = bucks[buck].reg;
507 mask = bucks[buck].u.opmode.mask;
508 set = bucks[buck].u.opmodes[mode];
512 if (max77686_probe())
516 printf("%s is not supported on LDO%d\n", opmode_str[mode], ldo);
520 i2c_read(addr, reg, 1, val, 1);
523 i2c_write(addr, reg, 1, val, 1);
524 i2c_read(addr, reg, 1, val, 1);
529 int max77686_set_ldo_mode(int ldo, opmode_type mode)
531 return max77686_set_output(0, ldo, mode);
534 int max77686_set_buck_mode(int buck, opmode_type mode)
536 return max77686_set_output(buck, 0, mode);
539 int max77686_set_32khz(unsigned char mode)
541 unsigned char addr = MAX77686_PMIC_ADDR;
542 unsigned char val[2];
544 if (max77686_probe())
548 i2c_write(addr, 0x7f, 1, val, 1);
553 static int max77686_gpio_control(int port, int value)
560 gpio_cfg_pin(pmic_pd->bank, pmic_pd->uart_sel, 1);
561 gpio_set_value(pmic_pd->bank, pmic_pd->uart_sel, value);
570 void max77686_set_platform_data(struct max77686_platform_data *pd)
573 puts("pd is NULL.\n");
580 static int do_max77686(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
582 int buck = 0, ldo = 0, on = -1;
587 if (strncmp(argv[1], "status", 6) == 0)
588 return max77686_status();
591 if (strncmp(argv[1], "uart", 4) != 0)
594 if (strncmp(argv[2], "ap", 2) == 0)
596 else if (strncmp(argv[2], "cp", 2) == 0)
601 ret = max77686_gpio_control(PMIC_UART_SEL, on);
604 printf("pmic: %s %s\n", argv[1], argv[2]);
606 printf("pmic_pd is not valid\n");
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);
615 printf("Option = \"%s\" ? \n", argv[1]);
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);
628 ulong volt = simple_strtoul(argv[3], NULL, 10);
629 printf("volt = %uuV\n", volt);
633 ret = max77686_set_voltage(buck, ldo, volt);
637 printf("%s %s %s\n", argv[1], argv[2], argv[3]);
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"