blob: 1d9fa6238aec10dcea3ea2f65c51cd4c05f93e0b [file] [log] [blame]
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001/*
2 * AXP20x regulators driver.
3 *
4 * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of this
8 * archive for more details.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Olliver Schinagldb4a5552018-11-26 17:27:42 +020016#include <linux/bitops.h>
Carlo Caionedfe7a1b2014-04-11 11:38:10 +020017#include <linux/err.h>
18#include <linux/init.h>
Olliver Schinagldb4a5552018-11-26 17:27:42 +020019#include <linux/mfd/axp20x.h>
Carlo Caionedfe7a1b2014-04-11 11:38:10 +020020#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/platform_device.h>
24#include <linux/regmap.h>
Carlo Caionedfe7a1b2014-04-11 11:38:10 +020025#include <linux/regulator/driver.h>
26#include <linux/regulator/of_regulator.h>
27
Olliver Schinagldb4a5552018-11-26 17:27:42 +020028#define AXP20X_GPIO0_FUNC_MASK GENMASK(3, 0)
29#define AXP20X_GPIO1_FUNC_MASK GENMASK(3, 0)
30
Carlo Caionedfe7a1b2014-04-11 11:38:10 +020031#define AXP20X_IO_ENABLED 0x03
32#define AXP20X_IO_DISABLED 0x07
33
Olliver Schinagldb4a5552018-11-26 17:27:42 +020034#define AXP20X_WORKMODE_DCDC2_MASK BIT_MASK(2)
35#define AXP20X_WORKMODE_DCDC3_MASK BIT_MASK(1)
36
37#define AXP20X_FREQ_DCDC_MASK GENMASK(3, 0)
38
39#define AXP20X_VBUS_IPSOUT_MGMT_MASK BIT_MASK(2)
40
41#define AXP20X_DCDC2_V_OUT_MASK GENMASK(5, 0)
42#define AXP20X_DCDC3_V_OUT_MASK GENMASK(7, 0)
43#define AXP20X_LDO24_V_OUT_MASK GENMASK(7, 4)
44#define AXP20X_LDO3_V_OUT_MASK GENMASK(6, 0)
45#define AXP20X_LDO5_V_OUT_MASK GENMASK(7, 4)
46
47#define AXP20X_PWR_OUT_EXTEN_MASK BIT_MASK(0)
48#define AXP20X_PWR_OUT_DCDC3_MASK BIT_MASK(1)
49#define AXP20X_PWR_OUT_LDO2_MASK BIT_MASK(2)
50#define AXP20X_PWR_OUT_LDO4_MASK BIT_MASK(3)
51#define AXP20X_PWR_OUT_DCDC2_MASK BIT_MASK(4)
52#define AXP20X_PWR_OUT_LDO3_MASK BIT_MASK(6)
53
Olliver Schinagld29f54d2018-12-11 17:17:06 +020054#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK BIT_MASK(0)
55#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(x) \
56 ((x) << 0)
57#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK BIT_MASK(1)
58#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(x) \
59 ((x) << 1)
60#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK BIT_MASK(2)
61#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN BIT(2)
62#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK BIT_MASK(3)
63#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN BIT(3)
64
Olliver Schinagldb4a5552018-11-26 17:27:42 +020065#define AXP20X_LDO4_V_OUT_1250mV_START 0x0
66#define AXP20X_LDO4_V_OUT_1250mV_STEPS 0
67#define AXP20X_LDO4_V_OUT_1250mV_END \
68 (AXP20X_LDO4_V_OUT_1250mV_START + AXP20X_LDO4_V_OUT_1250mV_STEPS)
69#define AXP20X_LDO4_V_OUT_1300mV_START 0x1
70#define AXP20X_LDO4_V_OUT_1300mV_STEPS 7
71#define AXP20X_LDO4_V_OUT_1300mV_END \
72 (AXP20X_LDO4_V_OUT_1300mV_START + AXP20X_LDO4_V_OUT_1300mV_STEPS)
73#define AXP20X_LDO4_V_OUT_2500mV_START 0x9
74#define AXP20X_LDO4_V_OUT_2500mV_STEPS 0
75#define AXP20X_LDO4_V_OUT_2500mV_END \
76 (AXP20X_LDO4_V_OUT_2500mV_START + AXP20X_LDO4_V_OUT_2500mV_STEPS)
77#define AXP20X_LDO4_V_OUT_2700mV_START 0xa
78#define AXP20X_LDO4_V_OUT_2700mV_STEPS 1
79#define AXP20X_LDO4_V_OUT_2700mV_END \
80 (AXP20X_LDO4_V_OUT_2700mV_START + AXP20X_LDO4_V_OUT_2700mV_STEPS)
81#define AXP20X_LDO4_V_OUT_3000mV_START 0xc
82#define AXP20X_LDO4_V_OUT_3000mV_STEPS 3
83#define AXP20X_LDO4_V_OUT_3000mV_END \
84 (AXP20X_LDO4_V_OUT_3000mV_START + AXP20X_LDO4_V_OUT_3000mV_STEPS)
85#define AXP20X_LDO4_V_OUT_NUM_VOLTAGES 16
86
Chen-Yu Tsai3cb99e22015-12-22 17:08:06 +080087#define AXP22X_IO_ENABLED 0x03
88#define AXP22X_IO_DISABLED 0x04
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +080089
Olliver Schinagldb4a5552018-11-26 17:27:42 +020090#define AXP22X_WORKMODE_DCDCX_MASK(x) BIT_MASK(x)
Carlo Caionedfe7a1b2014-04-11 11:38:10 +020091
Hans de Goede636e2a32016-06-03 18:59:44 +020092#define AXP22X_MISC_N_VBUSEN_FUNC BIT(4)
93
Olliver Schinagldb4a5552018-11-26 17:27:42 +020094#define AXP22X_DCDC1_V_OUT_MASK GENMASK(4, 0)
95#define AXP22X_DCDC2_V_OUT_MASK GENMASK(5, 0)
96#define AXP22X_DCDC3_V_OUT_MASK GENMASK(5, 0)
97#define AXP22X_DCDC4_V_OUT_MASK GENMASK(5, 0)
98#define AXP22X_DCDC5_V_OUT_MASK GENMASK(4, 0)
99#define AXP22X_DC5LDO_V_OUT_MASK GENMASK(2, 0)
100#define AXP22X_ALDO1_V_OUT_MASK GENMASK(4, 0)
101#define AXP22X_ALDO2_V_OUT_MASK GENMASK(4, 0)
102#define AXP22X_ALDO3_V_OUT_MASK GENMASK(4, 0)
103#define AXP22X_DLDO1_V_OUT_MASK GENMASK(4, 0)
104#define AXP22X_DLDO2_V_OUT_MASK GENMASK(4, 0)
105#define AXP22X_DLDO3_V_OUT_MASK GENMASK(4, 0)
106#define AXP22X_DLDO4_V_OUT_MASK GENMASK(4, 0)
107#define AXP22X_ELDO1_V_OUT_MASK GENMASK(4, 0)
108#define AXP22X_ELDO2_V_OUT_MASK GENMASK(4, 0)
109#define AXP22X_ELDO3_V_OUT_MASK GENMASK(4, 0)
110#define AXP22X_LDO_IO0_V_OUT_MASK GENMASK(4, 0)
111#define AXP22X_LDO_IO1_V_OUT_MASK GENMASK(4, 0)
112
113#define AXP22X_PWR_OUT_DC5LDO_MASK BIT_MASK(0)
114#define AXP22X_PWR_OUT_DCDC1_MASK BIT_MASK(1)
115#define AXP22X_PWR_OUT_DCDC2_MASK BIT_MASK(2)
116#define AXP22X_PWR_OUT_DCDC3_MASK BIT_MASK(3)
117#define AXP22X_PWR_OUT_DCDC4_MASK BIT_MASK(4)
118#define AXP22X_PWR_OUT_DCDC5_MASK BIT_MASK(5)
119#define AXP22X_PWR_OUT_ALDO1_MASK BIT_MASK(6)
120#define AXP22X_PWR_OUT_ALDO2_MASK BIT_MASK(7)
121
122#define AXP22X_PWR_OUT_SW_MASK BIT_MASK(6)
123#define AXP22X_PWR_OUT_DC1SW_MASK BIT_MASK(7)
124
125#define AXP22X_PWR_OUT_ELDO1_MASK BIT_MASK(0)
126#define AXP22X_PWR_OUT_ELDO2_MASK BIT_MASK(1)
127#define AXP22X_PWR_OUT_ELDO3_MASK BIT_MASK(2)
128#define AXP22X_PWR_OUT_DLDO1_MASK BIT_MASK(3)
129#define AXP22X_PWR_OUT_DLDO2_MASK BIT_MASK(4)
130#define AXP22X_PWR_OUT_DLDO3_MASK BIT_MASK(5)
131#define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
132#define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
133
134#define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
135#define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
136#define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
137#define AXP803_PWR_OUT_DCDC4_MASK BIT_MASK(3)
138#define AXP803_PWR_OUT_DCDC5_MASK BIT_MASK(4)
139#define AXP803_PWR_OUT_DCDC6_MASK BIT_MASK(5)
140
141#define AXP803_PWR_OUT_FLDO1_MASK BIT_MASK(2)
142#define AXP803_PWR_OUT_FLDO2_MASK BIT_MASK(3)
143
144#define AXP803_DCDC1_V_OUT_MASK GENMASK(4, 0)
145#define AXP803_DCDC2_V_OUT_MASK GENMASK(6, 0)
146#define AXP803_DCDC3_V_OUT_MASK GENMASK(6, 0)
147#define AXP803_DCDC4_V_OUT_MASK GENMASK(6, 0)
148#define AXP803_DCDC5_V_OUT_MASK GENMASK(6, 0)
149#define AXP803_DCDC6_V_OUT_MASK GENMASK(6, 0)
150
151#define AXP803_FLDO1_V_OUT_MASK GENMASK(3, 0)
152#define AXP803_FLDO2_V_OUT_MASK GENMASK(3, 0)
153
154#define AXP803_DCDC23_POLYPHASE_DUAL BIT(6)
155#define AXP803_DCDC56_POLYPHASE_DUAL BIT(5)
156
157#define AXP803_DCDC234_500mV_START 0x00
158#define AXP803_DCDC234_500mV_STEPS 70
159#define AXP803_DCDC234_500mV_END \
160 (AXP803_DCDC234_500mV_START + AXP803_DCDC234_500mV_STEPS)
161#define AXP803_DCDC234_1220mV_START 0x47
162#define AXP803_DCDC234_1220mV_STEPS 4
163#define AXP803_DCDC234_1220mV_END \
164 (AXP803_DCDC234_1220mV_START + AXP803_DCDC234_1220mV_STEPS)
165#define AXP803_DCDC234_NUM_VOLTAGES 76
166
167#define AXP803_DCDC5_800mV_START 0x00
168#define AXP803_DCDC5_800mV_STEPS 32
169#define AXP803_DCDC5_800mV_END \
170 (AXP803_DCDC5_800mV_START + AXP803_DCDC5_800mV_STEPS)
171#define AXP803_DCDC5_1140mV_START 0x21
172#define AXP803_DCDC5_1140mV_STEPS 35
173#define AXP803_DCDC5_1140mV_END \
174 (AXP803_DCDC5_1140mV_START + AXP803_DCDC5_1140mV_STEPS)
175#define AXP803_DCDC5_NUM_VOLTAGES 68
176
177#define AXP803_DCDC6_600mV_START 0x00
178#define AXP803_DCDC6_600mV_STEPS 50
179#define AXP803_DCDC6_600mV_END \
180 (AXP803_DCDC6_600mV_START + AXP803_DCDC6_600mV_STEPS)
181#define AXP803_DCDC6_1120mV_START 0x33
182#define AXP803_DCDC6_1120mV_STEPS 14
183#define AXP803_DCDC6_1120mV_END \
184 (AXP803_DCDC6_1120mV_START + AXP803_DCDC6_1120mV_STEPS)
185#define AXP803_DCDC6_NUM_VOLTAGES 72
186
187#define AXP803_DLDO2_700mV_START 0x00
188#define AXP803_DLDO2_700mV_STEPS 26
189#define AXP803_DLDO2_700mV_END \
190 (AXP803_DLDO2_700mV_START + AXP803_DLDO2_700mV_STEPS)
191#define AXP803_DLDO2_3400mV_START 0x1b
192#define AXP803_DLDO2_3400mV_STEPS 4
193#define AXP803_DLDO2_3400mV_END \
194 (AXP803_DLDO2_3400mV_START + AXP803_DLDO2_3400mV_STEPS)
195#define AXP803_DLDO2_NUM_VOLTAGES 32
196
197#define AXP806_DCDCA_V_CTRL_MASK GENMASK(6, 0)
198#define AXP806_DCDCB_V_CTRL_MASK GENMASK(4, 0)
199#define AXP806_DCDCC_V_CTRL_MASK GENMASK(6, 0)
200#define AXP806_DCDCD_V_CTRL_MASK GENMASK(5, 0)
201#define AXP806_DCDCE_V_CTRL_MASK GENMASK(4, 0)
202#define AXP806_ALDO1_V_CTRL_MASK GENMASK(4, 0)
203#define AXP806_ALDO2_V_CTRL_MASK GENMASK(4, 0)
204#define AXP806_ALDO3_V_CTRL_MASK GENMASK(4, 0)
205#define AXP806_BLDO1_V_CTRL_MASK GENMASK(3, 0)
206#define AXP806_BLDO2_V_CTRL_MASK GENMASK(3, 0)
207#define AXP806_BLDO3_V_CTRL_MASK GENMASK(3, 0)
208#define AXP806_BLDO4_V_CTRL_MASK GENMASK(3, 0)
209#define AXP806_CLDO1_V_CTRL_MASK GENMASK(4, 0)
210#define AXP806_CLDO2_V_CTRL_MASK GENMASK(4, 0)
211#define AXP806_CLDO3_V_CTRL_MASK GENMASK(4, 0)
212
213#define AXP806_PWR_OUT_DCDCA_MASK BIT_MASK(0)
214#define AXP806_PWR_OUT_DCDCB_MASK BIT_MASK(1)
215#define AXP806_PWR_OUT_DCDCC_MASK BIT_MASK(2)
216#define AXP806_PWR_OUT_DCDCD_MASK BIT_MASK(3)
217#define AXP806_PWR_OUT_DCDCE_MASK BIT_MASK(4)
218#define AXP806_PWR_OUT_ALDO1_MASK BIT_MASK(5)
219#define AXP806_PWR_OUT_ALDO2_MASK BIT_MASK(6)
220#define AXP806_PWR_OUT_ALDO3_MASK BIT_MASK(7)
221#define AXP806_PWR_OUT_BLDO1_MASK BIT_MASK(0)
222#define AXP806_PWR_OUT_BLDO2_MASK BIT_MASK(1)
223#define AXP806_PWR_OUT_BLDO3_MASK BIT_MASK(2)
224#define AXP806_PWR_OUT_BLDO4_MASK BIT_MASK(3)
225#define AXP806_PWR_OUT_CLDO1_MASK BIT_MASK(4)
226#define AXP806_PWR_OUT_CLDO2_MASK BIT_MASK(5)
227#define AXP806_PWR_OUT_CLDO3_MASK BIT_MASK(6)
228#define AXP806_PWR_OUT_SW_MASK BIT_MASK(7)
229
230#define AXP806_DCDCAB_POLYPHASE_DUAL 0x40
231#define AXP806_DCDCABC_POLYPHASE_TRI 0x80
232#define AXP806_DCDCABC_POLYPHASE_MASK GENMASK(7, 6)
233
234#define AXP806_DCDCDE_POLYPHASE_DUAL BIT(5)
235
236#define AXP806_DCDCA_600mV_START 0x00
237#define AXP806_DCDCA_600mV_STEPS 50
238#define AXP806_DCDCA_600mV_END \
239 (AXP806_DCDCA_600mV_START + AXP806_DCDCA_600mV_STEPS)
240#define AXP806_DCDCA_1120mV_START 0x33
241#define AXP806_DCDCA_1120mV_STEPS 14
242#define AXP806_DCDCA_1120mV_END \
243 (AXP806_DCDCA_1120mV_START + AXP806_DCDCA_1120mV_STEPS)
244#define AXP806_DCDCA_NUM_VOLTAGES 72
245
246#define AXP806_DCDCD_600mV_START 0x00
247#define AXP806_DCDCD_600mV_STEPS 45
248#define AXP806_DCDCD_600mV_END \
249 (AXP806_DCDCD_600mV_START + AXP806_DCDCD_600mV_STEPS)
250#define AXP806_DCDCD_1600mV_START 0x2e
251#define AXP806_DCDCD_1600mV_STEPS 17
252#define AXP806_DCDCD_1600mV_END \
253 (AXP806_DCDCD_1600mV_START + AXP806_DCDCD_1600mV_STEPS)
254#define AXP806_DCDCD_NUM_VOLTAGES 64
255
256#define AXP809_DCDC4_600mV_START 0x00
257#define AXP809_DCDC4_600mV_STEPS 47
258#define AXP809_DCDC4_600mV_END \
259 (AXP809_DCDC4_600mV_START + AXP809_DCDC4_600mV_STEPS)
260#define AXP809_DCDC4_1800mV_START 0x30
261#define AXP809_DCDC4_1800mV_STEPS 8
262#define AXP809_DCDC4_1800mV_END \
263 (AXP809_DCDC4_1800mV_START + AXP809_DCDC4_1800mV_STEPS)
264#define AXP809_DCDC4_NUM_VOLTAGES 57
265
266#define AXP813_DCDC7_V_OUT_MASK GENMASK(6, 0)
267
268#define AXP813_PWR_OUT_DCDC7_MASK BIT_MASK(6)
269
Boris BREZILLON866bd952015-04-10 12:09:03 +0800270#define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
271 _vmask, _ereg, _emask, _enable_val, _disable_val) \
272 [_family##_##_id] = { \
Chen-Yu Tsaie0bbb382016-02-15 18:31:22 +0800273 .name = (_match), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200274 .supply_name = (_supply), \
Chen-Yu Tsai880fe822015-01-10 00:23:43 +0800275 .of_match = of_match_ptr(_match), \
276 .regulators_node = of_match_ptr("regulators"), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200277 .type = REGULATOR_VOLTAGE, \
Boris BREZILLON866bd952015-04-10 12:09:03 +0800278 .id = _family##_##_id, \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200279 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
280 .owner = THIS_MODULE, \
281 .min_uV = (_min) * 1000, \
282 .uV_step = (_step) * 1000, \
283 .vsel_reg = (_vreg), \
284 .vsel_mask = (_vmask), \
285 .enable_reg = (_ereg), \
286 .enable_mask = (_emask), \
287 .enable_val = (_enable_val), \
288 .disable_val = (_disable_val), \
289 .ops = &axp20x_ops, \
290 }
291
Boris BREZILLON866bd952015-04-10 12:09:03 +0800292#define AXP_DESC(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
293 _vmask, _ereg, _emask) \
294 [_family##_##_id] = { \
Chen-Yu Tsaie0bbb382016-02-15 18:31:22 +0800295 .name = (_match), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200296 .supply_name = (_supply), \
Chen-Yu Tsai880fe822015-01-10 00:23:43 +0800297 .of_match = of_match_ptr(_match), \
298 .regulators_node = of_match_ptr("regulators"), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200299 .type = REGULATOR_VOLTAGE, \
Boris BREZILLON866bd952015-04-10 12:09:03 +0800300 .id = _family##_##_id, \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200301 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
302 .owner = THIS_MODULE, \
303 .min_uV = (_min) * 1000, \
304 .uV_step = (_step) * 1000, \
305 .vsel_reg = (_vreg), \
306 .vsel_mask = (_vmask), \
307 .enable_reg = (_ereg), \
308 .enable_mask = (_emask), \
309 .ops = &axp20x_ops, \
310 }
311
Chen-Yu Tsai94c39042016-02-02 18:27:37 +0800312#define AXP_DESC_SW(_family, _id, _match, _supply, _ereg, _emask) \
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800313 [_family##_##_id] = { \
Chen-Yu Tsaie0bbb382016-02-15 18:31:22 +0800314 .name = (_match), \
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800315 .supply_name = (_supply), \
316 .of_match = of_match_ptr(_match), \
317 .regulators_node = of_match_ptr("regulators"), \
318 .type = REGULATOR_VOLTAGE, \
319 .id = _family##_##_id, \
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800320 .owner = THIS_MODULE, \
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800321 .enable_reg = (_ereg), \
322 .enable_mask = (_emask), \
323 .ops = &axp20x_ops_sw, \
324 }
325
Boris BREZILLON866bd952015-04-10 12:09:03 +0800326#define AXP_DESC_FIXED(_family, _id, _match, _supply, _volt) \
327 [_family##_##_id] = { \
Chen-Yu Tsaie0bbb382016-02-15 18:31:22 +0800328 .name = (_match), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200329 .supply_name = (_supply), \
Chen-Yu Tsai880fe822015-01-10 00:23:43 +0800330 .of_match = of_match_ptr(_match), \
331 .regulators_node = of_match_ptr("regulators"), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200332 .type = REGULATOR_VOLTAGE, \
Boris BREZILLON866bd952015-04-10 12:09:03 +0800333 .id = _family##_##_id, \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200334 .n_voltages = 1, \
335 .owner = THIS_MODULE, \
336 .min_uV = (_volt) * 1000, \
337 .ops = &axp20x_ops_fixed \
338 }
339
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800340#define AXP_DESC_RANGES(_family, _id, _match, _supply, _ranges, _n_voltages, \
341 _vreg, _vmask, _ereg, _emask) \
Boris BREZILLON866bd952015-04-10 12:09:03 +0800342 [_family##_##_id] = { \
Chen-Yu Tsaie0bbb382016-02-15 18:31:22 +0800343 .name = (_match), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200344 .supply_name = (_supply), \
Chen-Yu Tsai880fe822015-01-10 00:23:43 +0800345 .of_match = of_match_ptr(_match), \
346 .regulators_node = of_match_ptr("regulators"), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200347 .type = REGULATOR_VOLTAGE, \
Boris BREZILLON866bd952015-04-10 12:09:03 +0800348 .id = _family##_##_id, \
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800349 .n_voltages = (_n_voltages), \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200350 .owner = THIS_MODULE, \
351 .vsel_reg = (_vreg), \
352 .vsel_mask = (_vmask), \
353 .enable_reg = (_ereg), \
354 .enable_mask = (_emask), \
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800355 .linear_ranges = (_ranges), \
356 .n_linear_ranges = ARRAY_SIZE(_ranges), \
357 .ops = &axp20x_ops_range, \
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200358 }
359
Olliver Schinagld29f54d2018-12-11 17:17:06 +0200360static const int axp209_dcdc2_ldo3_slew_rates[] = {
361 1600,
362 800,
363};
364
365static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
366{
367 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
368 const struct regulator_desc *desc = rdev->desc;
369 u8 reg, mask, enable, cfg = 0xff;
370 const int *slew_rates;
371 int rate_count = 0;
372
373 if (!rdev)
374 return -EINVAL;
375
376 switch (axp20x->variant) {
377 case AXP209_ID:
378 if (desc->id == AXP20X_DCDC2) {
379 rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
380 reg = AXP20X_DCDC2_LDO3_V_RAMP;
381 mask = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK |
382 AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK;
383 enable = (ramp > 0) ?
384 AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN :
385 !AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN;
386 break;
387 }
388
389 if (desc->id == AXP20X_LDO3) {
390 slew_rates = axp209_dcdc2_ldo3_slew_rates;
391 rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
392 reg = AXP20X_DCDC2_LDO3_V_RAMP;
393 mask = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK |
394 AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
395 enable = (ramp > 0) ?
396 AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN :
397 !AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN;
398 break;
399 }
400
401 if (rate_count > 0)
402 break;
403
404 /* fall through */
405 default:
406 /* Not supported for this regulator */
407 return -ENOTSUPP;
408 }
409
410 if (ramp == 0) {
411 cfg = enable;
412 } else {
413 int i;
414
415 for (i = 0; i < rate_count; i++) {
416 if (ramp <= slew_rates[i])
417 cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i);
418 else
419 break;
420 }
421
422 if (cfg == 0xff) {
423 dev_err(axp20x->dev, "unsupported ramp value %d", ramp);
424 return -EINVAL;
425 }
426
427 cfg |= enable;
428 }
429
430 return regmap_update_bits(axp20x->regmap, reg, mask, cfg);
431}
432
Bhumika Goyalef306e42017-01-28 19:28:01 +0530433static const struct regulator_ops axp20x_ops_fixed = {
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200434 .list_voltage = regulator_list_voltage_linear,
435};
436
Bhumika Goyalef306e42017-01-28 19:28:01 +0530437static const struct regulator_ops axp20x_ops_range = {
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200438 .set_voltage_sel = regulator_set_voltage_sel_regmap,
439 .get_voltage_sel = regulator_get_voltage_sel_regmap,
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800440 .list_voltage = regulator_list_voltage_linear_range,
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200441 .enable = regulator_enable_regmap,
442 .disable = regulator_disable_regmap,
443 .is_enabled = regulator_is_enabled_regmap,
444};
445
Bhumika Goyalef306e42017-01-28 19:28:01 +0530446static const struct regulator_ops axp20x_ops = {
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200447 .set_voltage_sel = regulator_set_voltage_sel_regmap,
448 .get_voltage_sel = regulator_get_voltage_sel_regmap,
449 .list_voltage = regulator_list_voltage_linear,
450 .enable = regulator_enable_regmap,
451 .disable = regulator_disable_regmap,
452 .is_enabled = regulator_is_enabled_regmap,
Olliver Schinagld29f54d2018-12-11 17:17:06 +0200453 .set_ramp_delay = axp20x_set_ramp_delay,
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200454};
455
Bhumika Goyalef306e42017-01-28 19:28:01 +0530456static const struct regulator_ops axp20x_ops_sw = {
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800457 .enable = regulator_enable_regmap,
458 .disable = regulator_disable_regmap,
459 .is_enabled = regulator_is_enabled_regmap,
460};
461
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800462static const struct regulator_linear_range axp20x_ldo4_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200463 REGULATOR_LINEAR_RANGE(1250000,
464 AXP20X_LDO4_V_OUT_1250mV_START,
465 AXP20X_LDO4_V_OUT_1250mV_END,
466 0),
467 REGULATOR_LINEAR_RANGE(1300000,
468 AXP20X_LDO4_V_OUT_1300mV_START,
469 AXP20X_LDO4_V_OUT_1300mV_END,
470 100000),
471 REGULATOR_LINEAR_RANGE(2500000,
472 AXP20X_LDO4_V_OUT_2500mV_START,
473 AXP20X_LDO4_V_OUT_2500mV_END,
474 0),
475 REGULATOR_LINEAR_RANGE(2700000,
476 AXP20X_LDO4_V_OUT_2700mV_START,
477 AXP20X_LDO4_V_OUT_2700mV_END,
478 100000),
479 REGULATOR_LINEAR_RANGE(3000000,
480 AXP20X_LDO4_V_OUT_3000mV_START,
481 AXP20X_LDO4_V_OUT_3000mV_END,
482 100000),
Chen-Yu Tsai13d57e62016-02-02 18:27:38 +0800483};
484
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200485static const struct regulator_desc axp20x_regulators[] = {
Boris BREZILLON866bd952015-04-10 12:09:03 +0800486 AXP_DESC(AXP20X, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200487 AXP20X_DCDC2_V_OUT, AXP20X_DCDC2_V_OUT_MASK,
488 AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_DCDC2_MASK),
Boris BREZILLON866bd952015-04-10 12:09:03 +0800489 AXP_DESC(AXP20X, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200490 AXP20X_DCDC3_V_OUT, AXP20X_DCDC3_V_OUT_MASK,
491 AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_DCDC3_MASK),
Boris BREZILLON866bd952015-04-10 12:09:03 +0800492 AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300),
493 AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200494 AXP20X_LDO24_V_OUT, AXP20X_LDO24_V_OUT_MASK,
495 AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO2_MASK),
Boris BREZILLON866bd952015-04-10 12:09:03 +0800496 AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200497 AXP20X_LDO3_V_OUT, AXP20X_LDO3_V_OUT_MASK,
498 AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO3_MASK),
499 AXP_DESC_RANGES(AXP20X, LDO4, "ldo4", "ldo24in",
500 axp20x_ldo4_ranges, AXP20X_LDO4_V_OUT_NUM_VOLTAGES,
501 AXP20X_LDO24_V_OUT, AXP20X_LDO24_V_OUT_MASK,
502 AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO4_MASK),
Boris BREZILLON866bd952015-04-10 12:09:03 +0800503 AXP_DESC_IO(AXP20X, LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200504 AXP20X_LDO5_V_OUT, AXP20X_LDO5_V_OUT_MASK,
505 AXP20X_GPIO0_CTRL, AXP20X_GPIO0_FUNC_MASK,
Boris BREZILLON866bd952015-04-10 12:09:03 +0800506 AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200507};
508
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800509static const struct regulator_desc axp22x_regulators[] = {
510 AXP_DESC(AXP22X, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200511 AXP22X_DCDC1_V_OUT, AXP22X_DCDC1_V_OUT_MASK,
512 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC1_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800513 AXP_DESC(AXP22X, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200514 AXP22X_DCDC2_V_OUT, AXP22X_DCDC2_V_OUT_MASK,
515 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC2_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800516 AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200517 AXP22X_DCDC3_V_OUT, AXP22X_DCDC3_V_OUT_MASK,
518 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC3_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800519 AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200520 AXP22X_DCDC4_V_OUT, AXP22X_DCDC4_V_OUT,
521 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC4_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800522 AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200523 AXP22X_DCDC5_V_OUT, AXP22X_DCDC5_V_OUT_MASK,
524 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC5_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800525 /* secondary switchable output of DCDC1 */
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200526 AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", NULL,
527 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800528 /* LDO regulator internally chained to DCDC5 */
Chen-Yu Tsai7118f192015-09-30 14:39:46 +0800529 AXP_DESC(AXP22X, DC5LDO, "dc5ldo", NULL, 700, 1400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200530 AXP22X_DC5LDO_V_OUT, AXP22X_DC5LDO_V_OUT_MASK,
531 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DC5LDO_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800532 AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200533 AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK,
534 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_ALDO1_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800535 AXP_DESC(AXP22X, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200536 AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT_MASK,
537 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_ALDO2_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800538 AXP_DESC(AXP22X, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200539 AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK,
540 AXP22X_PWR_OUT_CTRL3, AXP22X_PWR_OUT_ALDO3_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800541 AXP_DESC(AXP22X, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200542 AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK,
543 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800544 AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200545 AXP22X_DLDO2_V_OUT, AXP22X_PWR_OUT_DLDO2_MASK,
546 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800547 AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200548 AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK,
549 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO3_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800550 AXP_DESC(AXP22X, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200551 AXP22X_DLDO4_V_OUT, AXP22X_DLDO4_V_OUT_MASK,
552 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO4_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800553 AXP_DESC(AXP22X, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200554 AXP22X_ELDO1_V_OUT, AXP22X_ELDO1_V_OUT_MASK,
555 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800556 AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200557 AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK,
558 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK),
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800559 AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200560 AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK,
561 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK),
Hans de Goedef40d4892016-04-27 20:38:44 +0200562 /* Note the datasheet only guarantees reliable operation up to
563 * 3.3V, this needs to be enforced via dts provided constraints */
564 AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 700, 3800, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200565 AXP22X_LDO_IO0_V_OUT, AXP22X_LDO_IO0_V_OUT_MASK,
566 AXP20X_GPIO0_CTRL, AXP20X_GPIO0_FUNC_MASK,
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800567 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
Hans de Goedef40d4892016-04-27 20:38:44 +0200568 /* Note the datasheet only guarantees reliable operation up to
569 * 3.3V, this needs to be enforced via dts provided constraints */
570 AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 700, 3800, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200571 AXP22X_LDO_IO1_V_OUT, AXP22X_LDO_IO1_V_OUT_MASK,
572 AXP20X_GPIO1_CTRL, AXP20X_GPIO1_FUNC_MASK,
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800573 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
574 AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
575};
576
Hans de Goede636e2a32016-06-03 18:59:44 +0200577static const struct regulator_desc axp22x_drivevbus_regulator = {
578 .name = "drivevbus",
579 .supply_name = "drivevbus",
580 .of_match = of_match_ptr("drivevbus"),
581 .regulators_node = of_match_ptr("regulators"),
582 .type = REGULATOR_VOLTAGE,
583 .owner = THIS_MODULE,
584 .enable_reg = AXP20X_VBUS_IPSOUT_MGMT,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200585 .enable_mask = AXP20X_VBUS_IPSOUT_MGMT_MASK,
Hans de Goede636e2a32016-06-03 18:59:44 +0200586 .ops = &axp20x_ops_sw,
587};
588
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800589/* DCDC ranges shared with AXP813 */
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800590static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200591 REGULATOR_LINEAR_RANGE(500000,
592 AXP803_DCDC234_500mV_START,
593 AXP803_DCDC234_500mV_END,
594 10000),
595 REGULATOR_LINEAR_RANGE(1220000,
596 AXP803_DCDC234_1220mV_START,
597 AXP803_DCDC234_1220mV_END,
598 20000),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800599};
600
601static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200602 REGULATOR_LINEAR_RANGE(800000,
603 AXP803_DCDC5_800mV_START,
604 AXP803_DCDC5_800mV_END,
605 10000),
606 REGULATOR_LINEAR_RANGE(1140000,
607 AXP803_DCDC5_1140mV_START,
608 AXP803_DCDC5_1140mV_END,
609 20000),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800610};
611
612static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200613 REGULATOR_LINEAR_RANGE(600000,
614 AXP803_DCDC6_600mV_START,
615 AXP803_DCDC6_600mV_END,
616 10000),
617 REGULATOR_LINEAR_RANGE(1120000,
618 AXP803_DCDC6_1120mV_START,
619 AXP803_DCDC6_1120mV_END,
620 20000),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800621};
622
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200623/* AXP806's CLDO2 and AXP809's DLDO1 share the same range */
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800624static const struct regulator_linear_range axp803_dldo2_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200625 REGULATOR_LINEAR_RANGE(700000,
626 AXP803_DLDO2_700mV_START,
627 AXP803_DLDO2_700mV_END,
628 100000),
629 REGULATOR_LINEAR_RANGE(3400000,
630 AXP803_DLDO2_3400mV_START,
631 AXP803_DLDO2_3400mV_END,
632 200000),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800633};
634
635static const struct regulator_desc axp803_regulators[] = {
636 AXP_DESC(AXP803, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200637 AXP803_DCDC1_V_OUT, AXP803_DCDC1_V_OUT_MASK,
638 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC1_MASK),
639 AXP_DESC_RANGES(AXP803, DCDC2, "dcdc2", "vin2",
640 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
641 AXP803_DCDC2_V_OUT, AXP803_DCDC2_V_OUT_MASK,
642 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC2_MASK),
643 AXP_DESC_RANGES(AXP803, DCDC3, "dcdc3", "vin3",
644 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
645 AXP803_DCDC3_V_OUT, AXP803_DCDC3_V_OUT_MASK,
646 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC3_MASK),
647 AXP_DESC_RANGES(AXP803, DCDC4, "dcdc4", "vin4",
648 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
649 AXP803_DCDC4_V_OUT, AXP803_DCDC4_V_OUT_MASK,
650 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC4_MASK),
651 AXP_DESC_RANGES(AXP803, DCDC5, "dcdc5", "vin5",
652 axp803_dcdc5_ranges, AXP803_DCDC5_NUM_VOLTAGES,
653 AXP803_DCDC5_V_OUT, AXP803_DCDC5_V_OUT_MASK,
654 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC5_MASK),
655 AXP_DESC_RANGES(AXP803, DCDC6, "dcdc6", "vin6",
656 axp803_dcdc6_ranges, AXP803_DCDC6_NUM_VOLTAGES,
657 AXP803_DCDC6_V_OUT, AXP803_DCDC6_V_OUT_MASK,
658 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC6_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800659 /* secondary switchable output of DCDC1 */
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200660 AXP_DESC_SW(AXP803, DC1SW, "dc1sw", NULL,
661 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800662 AXP_DESC(AXP803, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200663 AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK,
664 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO1_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800665 AXP_DESC(AXP803, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200666 AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT,
667 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO2_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800668 AXP_DESC(AXP803, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200669 AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK,
670 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO3_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800671 AXP_DESC(AXP803, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200672 AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK,
673 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),
674 AXP_DESC_RANGES(AXP803, DLDO2, "dldo2", "dldoin",
675 axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES,
676 AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT,
677 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800678 AXP_DESC(AXP803, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200679 AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK,
680 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO3_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800681 AXP_DESC(AXP803, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200682 AXP22X_DLDO4_V_OUT, AXP22X_DLDO4_V_OUT_MASK,
683 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO4_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800684 AXP_DESC(AXP803, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200685 AXP22X_ELDO1_V_OUT, AXP22X_ELDO1_V_OUT_MASK,
686 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800687 AXP_DESC(AXP803, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200688 AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK,
689 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800690 AXP_DESC(AXP803, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200691 AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT,
692 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800693 AXP_DESC(AXP803, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200694 AXP803_FLDO1_V_OUT, AXP803_FLDO1_V_OUT_MASK,
695 AXP22X_PWR_OUT_CTRL3, AXP803_PWR_OUT_FLDO1_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800696 AXP_DESC(AXP803, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200697 AXP803_FLDO2_V_OUT, AXP803_FLDO2_V_OUT_MASK,
698 AXP22X_PWR_OUT_CTRL3, AXP803_PWR_OUT_FLDO2_MASK),
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800699 AXP_DESC_IO(AXP803, LDO_IO0, "ldo-io0", "ips", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200700 AXP22X_LDO_IO0_V_OUT, AXP22X_LDO_IO0_V_OUT_MASK,
701 AXP20X_GPIO0_CTRL, AXP20X_GPIO0_FUNC_MASK,
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800702 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
703 AXP_DESC_IO(AXP803, LDO_IO1, "ldo-io1", "ips", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200704 AXP22X_LDO_IO1_V_OUT, AXP22X_LDO_IO1_V_OUT_MASK,
705 AXP20X_GPIO1_CTRL, AXP20X_GPIO1_FUNC_MASK,
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800706 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
707 AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc-ldo", "ips", 3000),
708};
709
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800710static const struct regulator_linear_range axp806_dcdca_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200711 REGULATOR_LINEAR_RANGE(600000,
712 AXP806_DCDCA_600mV_START,
713 AXP806_DCDCA_600mV_END,
714 10000),
715 REGULATOR_LINEAR_RANGE(1120000,
716 AXP806_DCDCA_1120mV_START,
717 AXP806_DCDCA_1120mV_END,
718 20000),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800719};
720
721static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200722 REGULATOR_LINEAR_RANGE(600000,
723 AXP806_DCDCD_600mV_START,
724 AXP806_DCDCD_600mV_END,
725 20000),
726 REGULATOR_LINEAR_RANGE(1600000,
727 AXP806_DCDCD_600mV_START,
728 AXP806_DCDCD_600mV_END,
729 100000),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800730};
731
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800732static const struct regulator_desc axp806_regulators[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200733 AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina",
734 axp806_dcdca_ranges, AXP806_DCDCA_NUM_VOLTAGES,
735 AXP806_DCDCA_V_CTRL, AXP806_DCDCA_V_CTRL_MASK,
736 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCA_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800737 AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200738 AXP806_DCDCB_V_CTRL, AXP806_DCDCB_V_CTRL,
739 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCB_MASK),
740 AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc",
741 axp806_dcdca_ranges, AXP806_DCDCA_NUM_VOLTAGES,
742 AXP806_DCDCC_V_CTRL, AXP806_DCDCC_V_CTRL_MASK,
743 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCC_MASK),
744 AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind",
745 axp806_dcdcd_ranges, AXP806_DCDCD_NUM_VOLTAGES,
746 AXP806_DCDCD_V_CTRL, AXP806_DCDCD_V_CTRL_MASK,
747 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCD_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800748 AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200749 AXP806_DCDCE_V_CTRL, AXP806_DCDCE_V_CTRL_MASK,
750 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCE_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800751 AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200752 AXP806_ALDO1_V_CTRL, AXP806_ALDO1_V_CTRL_MASK,
753 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_ALDO1_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800754 AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200755 AXP806_ALDO2_V_CTRL, AXP806_ALDO2_V_CTRL_MASK,
756 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_ALDO2_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800757 AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200758 AXP806_ALDO3_V_CTRL, AXP806_ALDO3_V_CTRL_MASK,
759 AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_ALDO3_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800760 AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200761 AXP806_BLDO1_V_CTRL, AXP806_BLDO1_V_CTRL_MASK,
762 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO1_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800763 AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200764 AXP806_BLDO2_V_CTRL, AXP806_BLDO2_V_CTRL,
765 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO2_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800766 AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200767 AXP806_BLDO3_V_CTRL, AXP806_BLDO3_V_CTRL_MASK,
768 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO3_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800769 AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200770 AXP806_BLDO4_V_CTRL, AXP806_BLDO4_V_CTRL_MASK,
771 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO4_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800772 AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200773 AXP806_CLDO1_V_CTRL, AXP806_CLDO1_V_CTRL_MASK,
774 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_CLDO1_MASK),
775 AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin",
776 axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES,
777 AXP806_CLDO2_V_CTRL, AXP806_CLDO2_V_CTRL_MASK,
778 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_CLDO2_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800779 AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200780 AXP806_CLDO3_V_CTRL, AXP806_CLDO3_V_CTRL_MASK,
781 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_CLDO3_MASK),
782 AXP_DESC_SW(AXP806, SW, "sw", "swin",
783 AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_SW_MASK),
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800784};
785
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800786static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200787 REGULATOR_LINEAR_RANGE(600000,
788 AXP809_DCDC4_600mV_START,
789 AXP809_DCDC4_600mV_END,
790 20000),
791 REGULATOR_LINEAR_RANGE(1800000,
792 AXP809_DCDC4_1800mV_START,
793 AXP809_DCDC4_1800mV_END,
794 100000),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800795};
796
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800797static const struct regulator_desc axp809_regulators[] = {
798 AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200799 AXP22X_DCDC1_V_OUT, AXP22X_DCDC1_V_OUT_MASK,
800 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC1_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800801 AXP_DESC(AXP809, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200802 AXP22X_DCDC2_V_OUT, AXP22X_DCDC2_V_OUT_MASK,
803 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC2_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800804 AXP_DESC(AXP809, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200805 AXP22X_DCDC3_V_OUT, AXP22X_DCDC3_V_OUT_MASK,
806 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC3_MASK),
807 AXP_DESC_RANGES(AXP809, DCDC4, "dcdc4", "vin4",
808 axp809_dcdc4_ranges, AXP809_DCDC4_NUM_VOLTAGES,
809 AXP22X_DCDC4_V_OUT, AXP22X_DCDC4_V_OUT_MASK,
810 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC4_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800811 AXP_DESC(AXP809, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200812 AXP22X_DCDC5_V_OUT, AXP22X_DCDC5_V_OUT_MASK,
813 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC5_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800814 /* secondary switchable output of DCDC1 */
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200815 AXP_DESC_SW(AXP809, DC1SW, "dc1sw", NULL,
816 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800817 /* LDO regulator internally chained to DCDC5 */
818 AXP_DESC(AXP809, DC5LDO, "dc5ldo", NULL, 700, 1400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200819 AXP22X_DC5LDO_V_OUT, AXP22X_DC5LDO_V_OUT_MASK,
820 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DC5LDO_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800821 AXP_DESC(AXP809, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200822 AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK,
823 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_ALDO1_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800824 AXP_DESC(AXP809, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200825 AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT_MASK,
826 AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_ALDO2_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800827 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200828 AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK,
829 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ALDO3_MASK),
830 AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin",
831 axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES,
832 AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK,
833 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800834 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200835 AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT_MASK,
836 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800837 AXP_DESC(AXP809, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200838 AXP22X_ELDO1_V_OUT, AXP22X_ELDO1_V_OUT_MASK,
839 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800840 AXP_DESC(AXP809, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200841 AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK,
842 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800843 AXP_DESC(AXP809, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200844 AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK,
845 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK),
Chen-Yu Tsai618c80892016-11-11 11:12:43 +0800846 /*
847 * Note the datasheet only guarantees reliable operation up to
848 * 3.3V, this needs to be enforced via dts provided constraints
849 */
850 AXP_DESC_IO(AXP809, LDO_IO0, "ldo_io0", "ips", 700, 3800, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200851 AXP22X_LDO_IO0_V_OUT, AXP22X_LDO_IO0_V_OUT_MASK,
852 AXP20X_GPIO0_CTRL, AXP20X_GPIO0_FUNC_MASK,
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800853 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
Chen-Yu Tsai618c80892016-11-11 11:12:43 +0800854 /*
855 * Note the datasheet only guarantees reliable operation up to
856 * 3.3V, this needs to be enforced via dts provided constraints
857 */
858 AXP_DESC_IO(AXP809, LDO_IO1, "ldo_io1", "ips", 700, 3800, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200859 AXP22X_LDO_IO1_V_OUT, AXP22X_LDO_IO1_V_OUT_MASK,
860 AXP20X_GPIO1_CTRL, AXP20X_GPIO1_FUNC_MASK,
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800861 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
862 AXP_DESC_FIXED(AXP809, RTC_LDO, "rtc_ldo", "ips", 1800),
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200863 AXP_DESC_SW(AXP809, SW, "sw", "swin",
864 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_SW_MASK),
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800865};
866
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800867static const struct regulator_desc axp813_regulators[] = {
868 AXP_DESC(AXP813, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200869 AXP803_DCDC1_V_OUT, AXP803_DCDC1_V_OUT_MASK,
870 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC1_MASK),
871 AXP_DESC_RANGES(AXP813, DCDC2, "dcdc2", "vin2",
872 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
873 AXP803_DCDC2_V_OUT, AXP803_DCDC2_V_OUT_MASK,
874 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC2_MASK),
875 AXP_DESC_RANGES(AXP813, DCDC3, "dcdc3", "vin3",
876 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
877 AXP803_DCDC3_V_OUT, AXP803_DCDC3_V_OUT_MASK,
878 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC3_MASK),
879 AXP_DESC_RANGES(AXP813, DCDC4, "dcdc4", "vin4",
880 axp803_dcdc234_ranges, AXP803_DCDC234_NUM_VOLTAGES,
881 AXP803_DCDC4_V_OUT, AXP803_DCDC4_V_OUT_MASK,
882 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC4_MASK),
883 AXP_DESC_RANGES(AXP813, DCDC5, "dcdc5", "vin5",
884 axp803_dcdc5_ranges, AXP803_DCDC5_NUM_VOLTAGES,
885 AXP803_DCDC5_V_OUT, AXP803_DCDC5_V_OUT_MASK,
886 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC5_MASK),
887 AXP_DESC_RANGES(AXP813, DCDC6, "dcdc6", "vin6",
888 axp803_dcdc6_ranges, AXP803_DCDC6_NUM_VOLTAGES,
889 AXP803_DCDC6_V_OUT, AXP803_DCDC6_V_OUT_MASK,
890 AXP22X_PWR_OUT_CTRL1, AXP803_PWR_OUT_DCDC6_MASK),
891 AXP_DESC_RANGES(AXP813, DCDC7, "dcdc7", "vin7",
892 axp803_dcdc6_ranges, AXP803_DCDC6_NUM_VOLTAGES,
893 AXP813_DCDC7_V_OUT, AXP813_DCDC7_V_OUT_MASK,
894 AXP22X_PWR_OUT_CTRL1, AXP813_PWR_OUT_DCDC7_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800895 AXP_DESC(AXP813, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200896 AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK,
897 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO1_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800898 AXP_DESC(AXP813, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200899 AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT,
900 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO2_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800901 AXP_DESC(AXP813, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200902 AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK,
903 AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO3_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800904 AXP_DESC(AXP813, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200905 AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK,
906 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),
907 AXP_DESC_RANGES(AXP813, DLDO2, "dldo2", "dldoin",
908 axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES,
909 AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT,
910 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800911 AXP_DESC(AXP813, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200912 AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK,
913 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO3_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800914 AXP_DESC(AXP813, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200915 AXP22X_DLDO4_V_OUT, AXP22X_DLDO4_V_OUT_MASK,
916 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO4_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800917 AXP_DESC(AXP813, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200918 AXP22X_ELDO1_V_OUT, AXP22X_ELDO1_V_OUT_MASK,
919 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800920 AXP_DESC(AXP813, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200921 AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK,
922 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800923 AXP_DESC(AXP813, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200924 AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT,
925 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800926 /* to do / check ... */
927 AXP_DESC(AXP813, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200928 AXP803_FLDO1_V_OUT, AXP803_FLDO1_V_OUT_MASK,
929 AXP22X_PWR_OUT_CTRL3, AXP803_PWR_OUT_FLDO1_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800930 AXP_DESC(AXP813, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200931 AXP803_FLDO2_V_OUT, AXP803_FLDO2_V_OUT_MASK,
932 AXP22X_PWR_OUT_CTRL3, AXP803_PWR_OUT_FLDO2_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800933 /*
934 * TODO: FLDO3 = {DCDC5, FLDOIN} / 2
935 *
936 * This means FLDO3 effectively switches supplies at runtime,
937 * something the regulator subsystem does not support.
938 */
939 AXP_DESC_FIXED(AXP813, RTC_LDO, "rtc-ldo", "ips", 1800),
940 AXP_DESC_IO(AXP813, LDO_IO0, "ldo-io0", "ips", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200941 AXP22X_LDO_IO0_V_OUT, AXP22X_LDO_IO0_V_OUT_MASK,
942 AXP20X_GPIO0_CTRL, AXP20X_GPIO0_FUNC_MASK,
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800943 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
944 AXP_DESC_IO(AXP813, LDO_IO1, "ldo-io1", "ips", 700, 3300, 100,
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200945 AXP22X_LDO_IO1_V_OUT, AXP22X_LDO_IO1_V_OUT_MASK,
946 AXP20X_GPIO1_CTRL, AXP20X_GPIO1_FUNC_MASK,
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800947 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
Olliver Schinagldb4a5552018-11-26 17:27:42 +0200948 AXP_DESC_SW(AXP813, SW, "sw", "swin",
949 AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800950};
951
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200952static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
953{
954 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800955 unsigned int reg = AXP20X_DCDC_FREQ;
Boris BREZILLON866bd952015-04-10 12:09:03 +0800956 u32 min, max, def, step;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200957
Boris BREZILLON866bd952015-04-10 12:09:03 +0800958 switch (axp20x->variant) {
959 case AXP202_ID:
960 case AXP209_ID:
961 min = 750;
962 max = 1875;
963 def = 1500;
964 step = 75;
965 break;
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800966 case AXP803_ID:
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800967 case AXP813_ID:
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800968 /*
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +0800969 * AXP803/AXP813 DCDC work frequency setting has the same
970 * range and step as AXP22X, but at a different register.
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +0800971 * (See include/linux/mfd/axp20x.h)
972 */
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800973 reg = AXP803_DCDC_FREQ_CTRL;
Gustavo A. R. Silva4b03227a2018-10-04 14:52:34 +0200974 /* Fall through to the check below.*/
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +0800975 case AXP806_ID:
976 /*
977 * AXP806 also have DCDC work frequency setting register at a
978 * different position.
979 */
980 if (axp20x->variant == AXP806_ID)
981 reg = AXP806_DCDC_FREQ_CTRL;
Gustavo A. R. Silva4b03227a2018-10-04 14:52:34 +0200982 /* Fall through */
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800983 case AXP221_ID:
Chen-Yu Tsai04e09812016-02-12 10:02:45 +0800984 case AXP223_ID:
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +0800985 case AXP809_ID:
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +0800986 min = 1800;
987 max = 4050;
988 def = 3000;
989 step = 150;
990 break;
Boris BREZILLON866bd952015-04-10 12:09:03 +0800991 default:
992 dev_err(&pdev->dev,
993 "Setting DCDC frequency for unsupported AXP variant\n");
994 return -EINVAL;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +0200995 }
996
Boris BREZILLON866bd952015-04-10 12:09:03 +0800997 if (dcdcfreq == 0)
998 dcdcfreq = def;
999
1000 if (dcdcfreq < min) {
1001 dcdcfreq = min;
1002 dev_warn(&pdev->dev, "DCDC frequency too low. Set to %ukHz\n",
1003 min);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001004 }
1005
Boris BREZILLON866bd952015-04-10 12:09:03 +08001006 if (dcdcfreq > max) {
1007 dcdcfreq = max;
1008 dev_warn(&pdev->dev, "DCDC frequency too high. Set to %ukHz\n",
1009 max);
1010 }
1011
1012 dcdcfreq = (dcdcfreq - min) / step;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001013
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001014 return regmap_update_bits(axp20x->regmap, reg,
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001015 AXP20X_FREQ_DCDC_MASK, dcdcfreq);
1016}
1017
1018static int axp20x_regulator_parse_dt(struct platform_device *pdev)
1019{
1020 struct device_node *np, *regulators;
1021 int ret;
Boris BREZILLON866bd952015-04-10 12:09:03 +08001022 u32 dcdcfreq = 0;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001023
1024 np = of_node_get(pdev->dev.parent->of_node);
1025 if (!np)
1026 return 0;
1027
Boris BREZILLONa6016c52014-05-19 10:25:30 +02001028 regulators = of_get_child_by_name(np, "regulators");
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001029 if (!regulators) {
1030 dev_warn(&pdev->dev, "regulators node not found\n");
1031 } else {
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001032 of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
1033 ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
1034 if (ret < 0) {
1035 dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
1036 return ret;
1037 }
1038
1039 of_node_put(regulators);
1040 }
1041
1042 return 0;
1043}
1044
1045static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
1046{
Boris BREZILLON866bd952015-04-10 12:09:03 +08001047 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001048 unsigned int reg = AXP20X_DCDC_MODE;
Boris BREZILLON866bd952015-04-10 12:09:03 +08001049 unsigned int mask;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001050
Boris BREZILLON866bd952015-04-10 12:09:03 +08001051 switch (axp20x->variant) {
1052 case AXP202_ID:
1053 case AXP209_ID:
1054 if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
1055 return -EINVAL;
1056
1057 mask = AXP20X_WORKMODE_DCDC2_MASK;
1058 if (id == AXP20X_DCDC3)
1059 mask = AXP20X_WORKMODE_DCDC3_MASK;
1060
1061 workmode <<= ffs(mask) - 1;
1062 break;
1063
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001064 case AXP806_ID:
1065 reg = AXP806_DCDC_MODE_CTRL2;
1066 /*
1067 * AXP806 DCDC regulator IDs have the same range as AXP22X.
1068 * Fall through to the check below.
1069 * (See include/linux/mfd/axp20x.h)
1070 */
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +08001071 case AXP221_ID:
Chen-Yu Tsai04e09812016-02-12 10:02:45 +08001072 case AXP223_ID:
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001073 case AXP809_ID:
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +08001074 if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
1075 return -EINVAL;
1076
1077 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
1078 workmode <<= id - AXP22X_DCDC1;
1079 break;
1080
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001081 case AXP803_ID:
1082 if (id < AXP803_DCDC1 || id > AXP803_DCDC6)
1083 return -EINVAL;
1084
1085 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP803_DCDC1);
1086 workmode <<= id - AXP803_DCDC1;
1087 break;
1088
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +08001089 case AXP813_ID:
1090 if (id < AXP813_DCDC1 || id > AXP813_DCDC7)
1091 return -EINVAL;
1092
1093 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP813_DCDC1);
1094 workmode <<= id - AXP813_DCDC1;
1095 break;
1096
Boris BREZILLON866bd952015-04-10 12:09:03 +08001097 default:
1098 /* should not happen */
1099 WARN_ON(1);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001100 return -EINVAL;
Boris BREZILLON866bd952015-04-10 12:09:03 +08001101 }
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001102
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001103 return regmap_update_bits(rdev->regmap, reg, mask, workmode);
1104}
1105
1106/*
1107 * This function checks whether a regulator is part of a poly-phase
1108 * output setup based on the registers settings. Returns true if it is.
1109 */
1110static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
1111{
1112 u32 reg = 0;
1113
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001114 /*
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +08001115 * Currently in our supported AXP variants, only AXP803, AXP806,
1116 * and AXP813 have polyphase regulators.
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001117 */
1118 switch (axp20x->variant) {
1119 case AXP803_ID:
Axel Linad92cea2017-10-15 17:03:12 +08001120 case AXP813_ID:
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001121 regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg);
1122
1123 switch (id) {
1124 case AXP803_DCDC3:
Olliver Schinagldb4a5552018-11-26 17:27:42 +02001125 return !!(reg & AXP803_DCDC23_POLYPHASE_DUAL);
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001126 case AXP803_DCDC6:
Olliver Schinagldb4a5552018-11-26 17:27:42 +02001127 return !!(reg & AXP803_DCDC56_POLYPHASE_DUAL);
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001128 }
1129 break;
1130
1131 case AXP806_ID:
1132 regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
1133
1134 switch (id) {
1135 case AXP806_DCDCB:
Olliver Schinagldb4a5552018-11-26 17:27:42 +02001136 return (((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
1137 AXP806_DCDCAB_POLYPHASE_DUAL) ||
1138 ((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
1139 AXP806_DCDCABC_POLYPHASE_TRI));
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001140 case AXP806_DCDCC:
Olliver Schinagldb4a5552018-11-26 17:27:42 +02001141 return ((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
1142 AXP806_DCDCABC_POLYPHASE_TRI);
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001143 case AXP806_DCDCE:
Olliver Schinagldb4a5552018-11-26 17:27:42 +02001144 return !!(reg & AXP806_DCDCDE_POLYPHASE_DUAL);
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001145 }
1146 break;
1147
1148 default:
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001149 return false;
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001150 }
1151
1152 return false;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001153}
1154
1155static int axp20x_regulator_probe(struct platform_device *pdev)
1156{
1157 struct regulator_dev *rdev;
1158 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
Boris BREZILLON866bd952015-04-10 12:09:03 +08001159 const struct regulator_desc *regulators;
Chen-Yu Tsai765e8022015-01-10 00:23:44 +08001160 struct regulator_config config = {
1161 .dev = pdev->dev.parent,
1162 .regmap = axp20x->regmap,
Boris BREZILLON866bd952015-04-10 12:09:03 +08001163 .driver_data = axp20x,
Chen-Yu Tsai765e8022015-01-10 00:23:44 +08001164 };
Boris BREZILLON866bd952015-04-10 12:09:03 +08001165 int ret, i, nregulators;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001166 u32 workmode;
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001167 const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
1168 const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
Hans de Goede636e2a32016-06-03 18:59:44 +02001169 bool drivevbus = false;
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001170
Boris BREZILLON866bd952015-04-10 12:09:03 +08001171 switch (axp20x->variant) {
1172 case AXP202_ID:
1173 case AXP209_ID:
1174 regulators = axp20x_regulators;
1175 nregulators = AXP20X_REG_ID_MAX;
1176 break;
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +08001177 case AXP221_ID:
Chen-Yu Tsai04e09812016-02-12 10:02:45 +08001178 case AXP223_ID:
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +08001179 regulators = axp22x_regulators;
1180 nregulators = AXP22X_REG_ID_MAX;
Hans de Goede636e2a32016-06-03 18:59:44 +02001181 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
1182 "x-powers,drive-vbus-en");
Boris BREZILLON1b82b4e2015-04-10 12:09:04 +08001183 break;
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001184 case AXP803_ID:
1185 regulators = axp803_regulators;
1186 nregulators = AXP803_REG_ID_MAX;
Jagan Teki1f5d6462018-04-23 12:02:37 +05301187 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
1188 "x-powers,drive-vbus-en");
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001189 break;
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001190 case AXP806_ID:
1191 regulators = axp806_regulators;
1192 nregulators = AXP806_REG_ID_MAX;
1193 break;
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001194 case AXP809_ID:
1195 regulators = axp809_regulators;
1196 nregulators = AXP809_REG_ID_MAX;
1197 break;
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +08001198 case AXP813_ID:
1199 regulators = axp813_regulators;
1200 nregulators = AXP813_REG_ID_MAX;
1201 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
1202 "x-powers,drive-vbus-en");
1203 break;
Boris BREZILLON866bd952015-04-10 12:09:03 +08001204 default:
1205 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
1206 axp20x->variant);
1207 return -EINVAL;
1208 }
1209
Chen-Yu Tsai765e8022015-01-10 00:23:44 +08001210 /* This only sets the dcdc freq. Ignore any errors */
1211 axp20x_regulator_parse_dt(pdev);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001212
Boris BREZILLON866bd952015-04-10 12:09:03 +08001213 for (i = 0; i < nregulators; i++) {
Chen-Yu Tsai7118f192015-09-30 14:39:46 +08001214 const struct regulator_desc *desc = &regulators[i];
1215 struct regulator_desc *new_desc;
1216
1217 /*
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001218 * If this regulator is a slave in a poly-phase setup,
1219 * skip it, as its controls are bound to the master
1220 * regulator and won't work.
1221 */
1222 if (axp20x_is_polyphase_slave(axp20x, i))
1223 continue;
1224
Chen-Yu Tsaid81851c2017-09-29 11:25:09 +08001225 /* Support for AXP813's FLDO3 is not implemented */
1226 if (axp20x->variant == AXP813_ID && i == AXP813_FLDO3)
1227 continue;
1228
Chen-Yu Tsai2ca342d2016-08-27 15:55:39 +08001229 /*
Chen-Yu Tsai7118f192015-09-30 14:39:46 +08001230 * Regulators DC1SW and DC5LDO are connected internally,
1231 * so we have to handle their supply names separately.
1232 *
1233 * We always register the regulators in proper sequence,
1234 * so the supply names are correctly read. See the last
1235 * part of this loop to see where we save the DT defined
1236 * name.
1237 */
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001238 if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
Icenowy Zheng1dbe0cc2017-05-18 15:16:49 +08001239 (regulators == axp803_regulators && i == AXP803_DC1SW) ||
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001240 (regulators == axp809_regulators && i == AXP809_DC1SW)) {
1241 new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
1242 GFP_KERNEL);
Gustavo A. R. Silvada262962017-07-06 16:49:18 -05001243 if (!new_desc)
1244 return -ENOMEM;
1245
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001246 *new_desc = regulators[i];
1247 new_desc->supply_name = dcdc1_name;
1248 desc = new_desc;
1249 }
1250
1251 if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
1252 (regulators == axp809_regulators && i == AXP809_DC5LDO)) {
1253 new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
1254 GFP_KERNEL);
Gustavo A. R. Silvada262962017-07-06 16:49:18 -05001255 if (!new_desc)
1256 return -ENOMEM;
1257
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001258 *new_desc = regulators[i];
1259 new_desc->supply_name = dcdc5_name;
1260 desc = new_desc;
Chen-Yu Tsai7118f192015-09-30 14:39:46 +08001261 }
1262
1263 rdev = devm_regulator_register(&pdev->dev, desc, &config);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001264 if (IS_ERR(rdev)) {
1265 dev_err(&pdev->dev, "Failed to register %s\n",
Boris BREZILLON866bd952015-04-10 12:09:03 +08001266 regulators[i].name);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001267
1268 return PTR_ERR(rdev);
1269 }
1270
Chen-Yu Tsai765e8022015-01-10 00:23:44 +08001271 ret = of_property_read_u32(rdev->dev.of_node,
1272 "x-powers,dcdc-workmode",
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001273 &workmode);
1274 if (!ret) {
1275 if (axp20x_set_dcdc_workmode(rdev, i, workmode))
1276 dev_err(&pdev->dev, "Failed to set workmode on %s\n",
Boris BREZILLON866bd952015-04-10 12:09:03 +08001277 rdev->desc->name);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001278 }
Chen-Yu Tsai7118f192015-09-30 14:39:46 +08001279
1280 /*
1281 * Save AXP22X DCDC1 / DCDC5 regulator names for later.
1282 */
Chen-Yu Tsaia51f9f42016-06-01 00:23:19 +08001283 if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) ||
1284 (regulators == axp809_regulators && i == AXP809_DCDC1))
1285 of_property_read_string(rdev->dev.of_node,
1286 "regulator-name",
1287 &dcdc1_name);
1288
1289 if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) ||
1290 (regulators == axp809_regulators && i == AXP809_DCDC5))
1291 of_property_read_string(rdev->dev.of_node,
1292 "regulator-name",
1293 &dcdc5_name);
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001294 }
1295
Hans de Goede636e2a32016-06-03 18:59:44 +02001296 if (drivevbus) {
1297 /* Change N_VBUSEN sense pin to DRIVEVBUS output pin */
1298 regmap_update_bits(axp20x->regmap, AXP20X_OVER_TMP,
1299 AXP22X_MISC_N_VBUSEN_FUNC, 0);
1300 rdev = devm_regulator_register(&pdev->dev,
1301 &axp22x_drivevbus_regulator,
1302 &config);
1303 if (IS_ERR(rdev)) {
1304 dev_err(&pdev->dev, "Failed to register drivevbus\n");
1305 return PTR_ERR(rdev);
1306 }
1307 }
1308
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001309 return 0;
1310}
1311
1312static struct platform_driver axp20x_regulator_driver = {
1313 .probe = axp20x_regulator_probe,
1314 .driver = {
1315 .name = "axp20x-regulator",
Carlo Caionedfe7a1b2014-04-11 11:38:10 +02001316 },
1317};
1318
1319module_platform_driver(axp20x_regulator_driver);
1320
1321MODULE_LICENSE("GPL v2");
1322MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
1323MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
Ian Campbelld4ea7d82015-08-01 18:13:25 +01001324MODULE_ALIAS("platform:axp20x-regulator");