blob: 819b168a84b101866a11cf1dc9f968997fcbc0b1 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +02002/*
3 * (C) Copyright 2012
4 * Henrik Nordstrom <henrik@henriknordstrom.net>
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +02005 */
6
7#include <common.h>
Michael van Slingerland467e92b2015-12-13 13:17:31 +01008#include <command.h>
Hans de Goede30490b52015-10-03 16:12:27 +02009#include <asm/arch/pmic_bus.h>
Hans de Goede6944aff2015-10-03 15:18:33 +020010#include <axp_pmic.h>
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020011
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020012static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
13{
14 if (mvolt < min)
15 mvolt = min;
16 else if (mvolt > max)
17 mvolt = max;
18
19 return (mvolt - min) / div;
20}
21
Hans de Goede6944aff2015-10-03 15:18:33 +020022int axp_set_dcdc2(unsigned int mvolt)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020023{
24 int rc;
25 u8 cfg, current;
26
Hans de Goedebeba4012015-10-04 12:01:17 +020027 if (mvolt == 0)
28 return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
29 AXP209_OUTPUT_CTRL_DCDC2);
30
31 rc = pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_DCDC2);
32 if (rc)
33 return rc;
34
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020035 cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25);
36
37 /* Do we really need to be this gentle? It has built-in voltage slope */
Hans de Goede30490b52015-10-03 16:12:27 +020038 while ((rc = pmic_bus_read(AXP209_DCDC2_VOLTAGE, &current)) == 0 &&
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020039 current != cfg) {
40 if (current < cfg)
41 current++;
42 else
43 current--;
44
Hans de Goede30490b52015-10-03 16:12:27 +020045 rc = pmic_bus_write(AXP209_DCDC2_VOLTAGE, current);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020046 if (rc)
47 break;
48 }
49
50 return rc;
51}
52
Hans de Goede6944aff2015-10-03 15:18:33 +020053int axp_set_dcdc3(unsigned int mvolt)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020054{
55 u8 cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
Hans de Goedebeba4012015-10-04 12:01:17 +020056 int rc;
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020057
Hans de Goedebeba4012015-10-04 12:01:17 +020058 if (mvolt == 0)
59 return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
60 AXP209_OUTPUT_CTRL_DCDC3);
61
62 rc = pmic_bus_write(AXP209_DCDC3_VOLTAGE, cfg);
63 if (rc)
64 return rc;
65
66 return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_DCDC3);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020067}
68
Hans de Goede6944aff2015-10-03 15:18:33 +020069int axp_set_aldo2(unsigned int mvolt)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020070{
71 int rc;
72 u8 cfg, reg;
73
Hans de Goedebeba4012015-10-04 12:01:17 +020074 if (mvolt == 0)
75 return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
76 AXP209_OUTPUT_CTRL_LDO2);
77
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020078 cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100);
79
Hans de Goede30490b52015-10-03 16:12:27 +020080 rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, &reg);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020081 if (rc)
82 return rc;
83
Olliver Schinagl3f7d76a2018-11-21 20:05:29 +020084 reg |= AXP209_LDO24_LDO2_SET(reg, cfg);
Hans de Goedebeba4012015-10-04 12:01:17 +020085 rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
86 if (rc)
87 return rc;
88
89 return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO2);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020090}
91
Hans de Goede6944aff2015-10-03 15:18:33 +020092int axp_set_aldo3(unsigned int mvolt)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +020093{
94 u8 cfg;
Hans de Goedebeba4012015-10-04 12:01:17 +020095 int rc;
96
97 if (mvolt == 0)
98 return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
99 AXP209_OUTPUT_CTRL_LDO3);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200100
Olliver Schinagl3f7d76a2018-11-21 20:05:29 +0200101 if (mvolt == -1) {
102 cfg = AXP209_LDO3_VOLTAGE_FROM_LDO3IN;
103 } else {
Iain Paton99deda12015-03-25 16:03:26 +0000104 cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
Olliver Schinagl3f7d76a2018-11-21 20:05:29 +0200105 cfg = AXP209_LDO3_VOLTAGE_SET(cfg);
106 }
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200107
Hans de Goedebeba4012015-10-04 12:01:17 +0200108 rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, cfg);
109 if (rc)
110 return rc;
111
112 return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO3);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200113}
114
Hans de Goede6944aff2015-10-03 15:18:33 +0200115int axp_set_aldo4(unsigned int mvolt)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200116{
117 int rc;
Hans de Goede6944aff2015-10-03 15:18:33 +0200118 static const unsigned int vindex[] = {
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200119 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500,
120 2700, 2800, 3000, 3100, 3200, 3300
121 };
122 u8 cfg, reg;
123
Hans de Goedebeba4012015-10-04 12:01:17 +0200124 if (mvolt == 0)
125 return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
126 AXP209_OUTPUT_CTRL_LDO4);
127
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200128 /* Translate mvolt to register cfg value, requested <= selected */
129 for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--);
130
Hans de Goede30490b52015-10-03 16:12:27 +0200131 rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, &reg);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200132 if (rc)
133 return rc;
134
Olliver Schinagl3f7d76a2018-11-21 20:05:29 +0200135 reg |= AXP209_LDO24_LDO4_SET(reg, cfg);
Hans de Goedebeba4012015-10-04 12:01:17 +0200136 rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
137 if (rc)
138 return rc;
139
140 return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO4);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200141}
142
Hans de Goede6944aff2015-10-03 15:18:33 +0200143int axp_init(void)
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200144{
145 u8 ver;
Hans de Goede9dcf68f2015-01-17 16:39:20 +0100146 int i, rc;
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200147
Hans de Goede30490b52015-10-03 16:12:27 +0200148 rc = pmic_bus_init();
149 if (rc)
150 return rc;
151
152 rc = pmic_bus_read(AXP209_CHIP_VERSION, &ver);
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200153 if (rc)
154 return rc;
155
Olliver Schinaglf5eebc72018-11-21 20:05:28 +0200156 if ((ver & AXP209_CHIP_VERSION_MASK) != 0x1)
Jaehoon Chung505cf472016-12-15 20:49:50 +0900157 return -EINVAL;
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200158
Hans de Goede9dcf68f2015-01-17 16:39:20 +0100159 /* Mask all interrupts */
160 for (i = AXP209_IRQ_ENABLE1; i <= AXP209_IRQ_ENABLE5; i++) {
Hans de Goede30490b52015-10-03 16:12:27 +0200161 rc = pmic_bus_write(i, 0);
Hans de Goede9dcf68f2015-01-17 16:39:20 +0100162 if (rc)
163 return rc;
164 }
165
Hans de Goede253e62b2016-09-12 09:52:52 +0200166 /*
167 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
168 * from android these are sometimes on.
169 */
170 rc = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
171 if (rc)
172 return rc;
173
174 rc = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
175 if (rc)
176 return rc;
177
178 rc = pmic_bus_write(AXP_GPIO2_CTRL, AXP_GPIO_CTRL_INPUT);
179 if (rc)
180 return rc;
181
Henrik Nordstrom14bc66b2014-06-13 22:55:50 +0200182 return 0;
183}
Michael van Slingerland467e92b2015-12-13 13:17:31 +0100184
185int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
186{
187 pmic_bus_write(AXP209_SHUTDOWN, AXP209_POWEROFF);
188
189 /* infinite loop during shutdown */
190 while (1) {}
191
192 /* not reached */
193 return 0;
194}