]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/mfd/axp20x.c
Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm...
[mirror_ubuntu-hirsute-kernel.git] / drivers / mfd / axp20x.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
cfb61a41 2/*
4fd41151 3 * MFD core driver for the X-Powers' Power Management ICs
cfb61a41 4 *
af7e9069
JP
5 * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
6 * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
7 * as well as configurable GPIOs.
cfb61a41 8 *
4fd41151
CYT
9 * This file contains the interface independent core functions.
10 *
e740235d
CYT
11 * Copyright (C) 2014 Carlo Caione
12 *
cfb61a41 13 * Author: Carlo Caione <carlo@caione.org>
cfb61a41
CC
14 */
15
dcea4d5c
OS
16#include <linux/acpi.h>
17#include <linux/bitops.h>
179dc63d 18#include <linux/delay.h>
dcea4d5c 19#include <linux/err.h>
cfb61a41
CC
20#include <linux/interrupt.h>
21#include <linux/kernel.h>
dcea4d5c
OS
22#include <linux/mfd/axp20x.h>
23#include <linux/mfd/core.h>
cfb61a41 24#include <linux/module.h>
dcea4d5c 25#include <linux/of_device.h>
cfb61a41
CC
26#include <linux/pm_runtime.h>
27#include <linux/regmap.h>
cfb61a41 28#include <linux/regulator/consumer.h>
cfb61a41 29
82b4d997 30#define AXP20X_OFF BIT(7)
cfb61a41 31
c0369698 32#define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE 0
696f0b3f
CYT
33#define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4)
34
c31e858b 35static const char * const axp20x_model_names[] = {
d8d79f8f 36 "AXP152",
af7e9069
JP
37 "AXP202",
38 "AXP209",
f05be589 39 "AXP221",
02071f0f 40 "AXP223",
af7e9069 41 "AXP288",
1578353e 42 "AXP803",
8824ee85 43 "AXP806",
20147f0d 44 "AXP809",
7303733a 45 "AXP813",
af7e9069
JP
46};
47
d8d79f8f
MS
48static const struct regmap_range axp152_writeable_ranges[] = {
49 regmap_reg_range(AXP152_LDO3456_DC1234_CTRL, AXP152_IRQ3_STATE),
50 regmap_reg_range(AXP152_DCDC_MODE, AXP152_PWM1_DUTY_CYCLE),
51};
52
53static const struct regmap_range axp152_volatile_ranges[] = {
54 regmap_reg_range(AXP152_PWR_OP_MODE, AXP152_PWR_OP_MODE),
55 regmap_reg_range(AXP152_IRQ1_EN, AXP152_IRQ3_STATE),
56 regmap_reg_range(AXP152_GPIO_INPUT, AXP152_GPIO_INPUT),
57};
58
59static const struct regmap_access_table axp152_writeable_table = {
60 .yes_ranges = axp152_writeable_ranges,
61 .n_yes_ranges = ARRAY_SIZE(axp152_writeable_ranges),
62};
63
64static const struct regmap_access_table axp152_volatile_table = {
65 .yes_ranges = axp152_volatile_ranges,
66 .n_yes_ranges = ARRAY_SIZE(axp152_volatile_ranges),
67};
68
cfb61a41
CC
69static const struct regmap_range axp20x_writeable_ranges[] = {
70 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
97602370 71 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
cfb61a41 72 regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
553ed4b5 73 regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
cfb61a41
CC
74};
75
76static const struct regmap_range axp20x_volatile_ranges[] = {
553ed4b5
BP
77 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
78 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
cfb61a41 79 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
553ed4b5
BP
80 regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
81 regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
82 regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
cfb61a41
CC
83};
84
85static const struct regmap_access_table axp20x_writeable_table = {
86 .yes_ranges = axp20x_writeable_ranges,
87 .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges),
88};
89
90static const struct regmap_access_table axp20x_volatile_table = {
91 .yes_ranges = axp20x_volatile_ranges,
92 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
93};
94
20147f0d 95/* AXP22x ranges are shared with the AXP809, as they cover the same range */
f05be589
BB
96static const struct regmap_range axp22x_writeable_ranges[] = {
97 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
97602370 98 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP22X_CHRG_CTRL3),
f05be589
BB
99 regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
100};
101
102static const struct regmap_range axp22x_volatile_ranges[] = {
15093250 103 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
f05be589 104 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
15093250 105 regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
ed7311f0 106 regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L),
15093250 107 regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
f05be589
BB
108};
109
110static const struct regmap_access_table axp22x_writeable_table = {
111 .yes_ranges = axp22x_writeable_ranges,
112 .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges),
113};
114
115static const struct regmap_access_table axp22x_volatile_table = {
116 .yes_ranges = axp22x_volatile_ranges,
117 .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges),
118};
119
1578353e 120/* AXP288 ranges are shared with the AXP803, as they cover the same range */
af7e9069
JP
121static const struct regmap_range axp288_writeable_ranges[] = {
122 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
123 regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
124};
125
126static const struct regmap_range axp288_volatile_ranges[] = {
cd532166
HG
127 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
128 regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
dc91c3b6 129 regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
0c384fc8 130 regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
af7e9069 131 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
cd532166
HG
132 regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
133 regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
134 regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L),
135 regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG),
af7e9069
JP
136};
137
138static const struct regmap_access_table axp288_writeable_table = {
139 .yes_ranges = axp288_writeable_ranges,
140 .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges),
141};
142
143static const struct regmap_access_table axp288_volatile_table = {
144 .yes_ranges = axp288_volatile_ranges,
145 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges),
146};
147
8824ee85
CYT
148static const struct regmap_range axp806_writeable_ranges[] = {
149 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
150 regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
151 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
152 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
34d9030b 153 regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
8824ee85
CYT
154};
155
156static const struct regmap_range axp806_volatile_ranges[] = {
157 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
158};
159
160static const struct regmap_access_table axp806_writeable_table = {
161 .yes_ranges = axp806_writeable_ranges,
162 .n_yes_ranges = ARRAY_SIZE(axp806_writeable_ranges),
163};
164
165static const struct regmap_access_table axp806_volatile_table = {
166 .yes_ranges = axp806_volatile_ranges,
167 .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
168};
169
531a469e 170static const struct resource axp152_pek_resources[] = {
d8d79f8f
MS
171 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
172 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
173};
174
531a469e 175static const struct resource axp20x_ac_power_supply_resources[] = {
cd7cf27b
MH
176 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
177 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
178 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
179};
180
531a469e 181static const struct resource axp20x_pek_resources[] = {
e26f87e5
CYT
182 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
183 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
cfb61a41
CC
184};
185
531a469e 186static const struct resource axp20x_usb_power_supply_resources[] = {
8de4efda
HG
187 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
188 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
189 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
190 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
191};
192
531a469e 193static const struct resource axp22x_usb_power_supply_resources[] = {
ecd98cce
HG
194 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
195 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
196};
197
129fc677
QS
198/* AXP803 and AXP813/AXP818 share the same interrupts */
199static const struct resource axp803_usb_power_supply_resources[] = {
200 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
201 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
202};
203
531a469e 204static const struct resource axp22x_pek_resources[] = {
e26f87e5
CYT
205 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
206 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
f05be589
BB
207};
208
531a469e 209static const struct resource axp288_power_button_resources[] = {
e26f87e5
CYT
210 DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"),
211 DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"),
e56e5ad6
BF
212};
213
531a469e 214static const struct resource axp288_fuel_gauge_resources[] = {
e26f87e5
CYT
215 DEFINE_RES_IRQ(AXP288_IRQ_QWBTU),
216 DEFINE_RES_IRQ(AXP288_IRQ_WBTU),
217 DEFINE_RES_IRQ(AXP288_IRQ_QWBTO),
218 DEFINE_RES_IRQ(AXP288_IRQ_WBTO),
219 DEFINE_RES_IRQ(AXP288_IRQ_WL2),
220 DEFINE_RES_IRQ(AXP288_IRQ_WL1),
af7e9069
JP
221};
222
531a469e 223static const struct resource axp803_pek_resources[] = {
e26f87e5
CYT
224 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
225 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
1578353e
IZ
226};
227
06f49010
CYT
228static const struct resource axp806_pek_resources[] = {
229 DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_RISE, "PEK_DBR"),
230 DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_FALL, "PEK_DBF"),
231};
232
531a469e 233static const struct resource axp809_pek_resources[] = {
e26f87e5
CYT
234 DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
235 DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
20147f0d
CYT
236};
237
d8d79f8f
MS
238static const struct regmap_config axp152_regmap_config = {
239 .reg_bits = 8,
240 .val_bits = 8,
241 .wr_table = &axp152_writeable_table,
242 .volatile_table = &axp152_volatile_table,
243 .max_register = AXP152_PWM1_DUTY_CYCLE,
244 .cache_type = REGCACHE_RBTREE,
245};
246
cfb61a41
CC
247static const struct regmap_config axp20x_regmap_config = {
248 .reg_bits = 8,
249 .val_bits = 8,
250 .wr_table = &axp20x_writeable_table,
251 .volatile_table = &axp20x_volatile_table,
553ed4b5 252 .max_register = AXP20X_OCV(AXP20X_OCV_MAX),
cfb61a41
CC
253 .cache_type = REGCACHE_RBTREE,
254};
255
f05be589
BB
256static const struct regmap_config axp22x_regmap_config = {
257 .reg_bits = 8,
258 .val_bits = 8,
259 .wr_table = &axp22x_writeable_table,
260 .volatile_table = &axp22x_volatile_table,
261 .max_register = AXP22X_BATLOW_THRES1,
262 .cache_type = REGCACHE_RBTREE,
263};
264
af7e9069
JP
265static const struct regmap_config axp288_regmap_config = {
266 .reg_bits = 8,
267 .val_bits = 8,
268 .wr_table = &axp288_writeable_table,
269 .volatile_table = &axp288_volatile_table,
270 .max_register = AXP288_FG_TUNE5,
271 .cache_type = REGCACHE_RBTREE,
272};
273
8824ee85
CYT
274static const struct regmap_config axp806_regmap_config = {
275 .reg_bits = 8,
276 .val_bits = 8,
277 .wr_table = &axp806_writeable_table,
278 .volatile_table = &axp806_volatile_table,
34d9030b 279 .max_register = AXP806_REG_ADDR_EXT,
8824ee85
CYT
280 .cache_type = REGCACHE_RBTREE,
281};
282
af7e9069
JP
283#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
284 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
cfb61a41 285
d8d79f8f
MS
286static const struct regmap_irq axp152_regmap_irqs[] = {
287 INIT_REGMAP_IRQ(AXP152, LDO0IN_CONNECT, 0, 6),
288 INIT_REGMAP_IRQ(AXP152, LDO0IN_REMOVAL, 0, 5),
289 INIT_REGMAP_IRQ(AXP152, ALDO0IN_CONNECT, 0, 3),
290 INIT_REGMAP_IRQ(AXP152, ALDO0IN_REMOVAL, 0, 2),
291 INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW, 1, 5),
292 INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW, 1, 4),
293 INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW, 1, 3),
294 INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW, 1, 2),
295 INIT_REGMAP_IRQ(AXP152, PEK_SHORT, 1, 1),
296 INIT_REGMAP_IRQ(AXP152, PEK_LONG, 1, 0),
297 INIT_REGMAP_IRQ(AXP152, TIMER, 2, 7),
298 INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE, 2, 6),
299 INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE, 2, 5),
300 INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT, 2, 3),
301 INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT, 2, 2),
302 INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT, 2, 1),
303 INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0),
304};
305
cfb61a41 306static const struct regmap_irq axp20x_regmap_irqs[] = {
af7e9069
JP
307 INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
308 INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
309 INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL, 0, 5),
310 INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V, 0, 4),
311 INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN, 0, 3),
312 INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL, 0, 2),
313 INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW, 0, 1),
314 INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN, 1, 7),
315 INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL, 1, 6),
316 INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE, 1, 5),
317 INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4),
318 INIT_REGMAP_IRQ(AXP20X, CHARG, 1, 3),
319 INIT_REGMAP_IRQ(AXP20X, CHARG_DONE, 1, 2),
320 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH, 1, 1),
321 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW, 1, 0),
322 INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH, 2, 7),
323 INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW, 2, 6),
324 INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG, 2, 5),
325 INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG, 2, 4),
326 INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG, 2, 3),
327 INIT_REGMAP_IRQ(AXP20X, PEK_SHORT, 2, 1),
328 INIT_REGMAP_IRQ(AXP20X, PEK_LONG, 2, 0),
329 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON, 3, 7),
330 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF, 3, 6),
331 INIT_REGMAP_IRQ(AXP20X, VBUS_VALID, 3, 5),
332 INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID, 3, 4),
333 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID, 3, 3),
334 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END, 3, 2),
335 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1, 3, 1),
336 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2, 3, 0),
337 INIT_REGMAP_IRQ(AXP20X, TIMER, 4, 7),
338 INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE, 4, 6),
339 INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE, 4, 5),
340 INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT, 4, 3),
341 INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT, 4, 2),
342 INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT, 4, 1),
343 INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0),
344};
345
f05be589
BB
346static const struct regmap_irq axp22x_regmap_irqs[] = {
347 INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V, 0, 7),
348 INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN, 0, 6),
349 INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL, 0, 5),
350 INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V, 0, 4),
351 INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN, 0, 3),
352 INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL, 0, 2),
353 INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW, 0, 1),
354 INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN, 1, 7),
355 INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL, 1, 6),
356 INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE, 1, 5),
357 INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4),
358 INIT_REGMAP_IRQ(AXP22X, CHARG, 1, 3),
359 INIT_REGMAP_IRQ(AXP22X, CHARG_DONE, 1, 2),
360 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH, 1, 1),
361 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW, 1, 0),
362 INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH, 2, 7),
363 INIT_REGMAP_IRQ(AXP22X, PEK_SHORT, 2, 1),
364 INIT_REGMAP_IRQ(AXP22X, PEK_LONG, 2, 0),
365 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1, 3, 1),
366 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2, 3, 0),
367 INIT_REGMAP_IRQ(AXP22X, TIMER, 4, 7),
368 INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE, 4, 6),
369 INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE, 4, 5),
370 INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT, 4, 1),
371 INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT, 4, 0),
372};
373
af7e9069
JP
374/* some IRQs are compatible with axp20x models */
375static const struct regmap_irq axp288_regmap_irqs[] = {
ff3bbc5c
JP
376 INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2),
377 INIT_REGMAP_IRQ(AXP288, VBUS_RISE, 0, 3),
378 INIT_REGMAP_IRQ(AXP288, OV, 0, 4),
8b44e678
HG
379 INIT_REGMAP_IRQ(AXP288, FALLING_ALT, 0, 5),
380 INIT_REGMAP_IRQ(AXP288, RISING_ALT, 0, 6),
381 INIT_REGMAP_IRQ(AXP288, OV_ALT, 0, 7),
af7e9069 382
ff3bbc5c
JP
383 INIT_REGMAP_IRQ(AXP288, DONE, 1, 2),
384 INIT_REGMAP_IRQ(AXP288, CHARGING, 1, 3),
af7e9069
JP
385 INIT_REGMAP_IRQ(AXP288, SAFE_QUIT, 1, 4),
386 INIT_REGMAP_IRQ(AXP288, SAFE_ENTER, 1, 5),
ff3bbc5c
JP
387 INIT_REGMAP_IRQ(AXP288, ABSENT, 1, 6),
388 INIT_REGMAP_IRQ(AXP288, APPEND, 1, 7),
af7e9069
JP
389
390 INIT_REGMAP_IRQ(AXP288, QWBTU, 2, 0),
391 INIT_REGMAP_IRQ(AXP288, WBTU, 2, 1),
392 INIT_REGMAP_IRQ(AXP288, QWBTO, 2, 2),
ff3bbc5c 393 INIT_REGMAP_IRQ(AXP288, WBTO, 2, 3),
af7e9069
JP
394 INIT_REGMAP_IRQ(AXP288, QCBTU, 2, 4),
395 INIT_REGMAP_IRQ(AXP288, CBTU, 2, 5),
396 INIT_REGMAP_IRQ(AXP288, QCBTO, 2, 6),
397 INIT_REGMAP_IRQ(AXP288, CBTO, 2, 7),
398
399 INIT_REGMAP_IRQ(AXP288, WL2, 3, 0),
400 INIT_REGMAP_IRQ(AXP288, WL1, 3, 1),
401 INIT_REGMAP_IRQ(AXP288, GPADC, 3, 2),
402 INIT_REGMAP_IRQ(AXP288, OT, 3, 7),
403
404 INIT_REGMAP_IRQ(AXP288, GPIO0, 4, 0),
405 INIT_REGMAP_IRQ(AXP288, GPIO1, 4, 1),
406 INIT_REGMAP_IRQ(AXP288, POKO, 4, 2),
407 INIT_REGMAP_IRQ(AXP288, POKL, 4, 3),
408 INIT_REGMAP_IRQ(AXP288, POKS, 4, 4),
409 INIT_REGMAP_IRQ(AXP288, POKN, 4, 5),
410 INIT_REGMAP_IRQ(AXP288, POKP, 4, 6),
ff3bbc5c 411 INIT_REGMAP_IRQ(AXP288, TIMER, 4, 7),
af7e9069
JP
412
413 INIT_REGMAP_IRQ(AXP288, MV_CHNG, 5, 0),
414 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
cfb61a41
CC
415};
416
1578353e
IZ
417static const struct regmap_irq axp803_regmap_irqs[] = {
418 INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
419 INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
420 INIT_REGMAP_IRQ(AXP803, ACIN_REMOVAL, 0, 5),
421 INIT_REGMAP_IRQ(AXP803, VBUS_OVER_V, 0, 4),
422 INIT_REGMAP_IRQ(AXP803, VBUS_PLUGIN, 0, 3),
423 INIT_REGMAP_IRQ(AXP803, VBUS_REMOVAL, 0, 2),
424 INIT_REGMAP_IRQ(AXP803, BATT_PLUGIN, 1, 7),
425 INIT_REGMAP_IRQ(AXP803, BATT_REMOVAL, 1, 6),
426 INIT_REGMAP_IRQ(AXP803, BATT_ENT_ACT_MODE, 1, 5),
427 INIT_REGMAP_IRQ(AXP803, BATT_EXIT_ACT_MODE, 1, 4),
428 INIT_REGMAP_IRQ(AXP803, CHARG, 1, 3),
429 INIT_REGMAP_IRQ(AXP803, CHARG_DONE, 1, 2),
430 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH, 2, 7),
431 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH_END, 2, 6),
432 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW, 2, 5),
433 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW_END, 2, 4),
434 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH, 2, 3),
435 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH_END, 2, 2),
436 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW, 2, 1),
437 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW_END, 2, 0),
438 INIT_REGMAP_IRQ(AXP803, DIE_TEMP_HIGH, 3, 7),
439 INIT_REGMAP_IRQ(AXP803, GPADC, 3, 2),
440 INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL1, 3, 1),
441 INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL2, 3, 0),
442 INIT_REGMAP_IRQ(AXP803, TIMER, 4, 7),
443 INIT_REGMAP_IRQ(AXP803, PEK_RIS_EDGE, 4, 6),
444 INIT_REGMAP_IRQ(AXP803, PEK_FAL_EDGE, 4, 5),
445 INIT_REGMAP_IRQ(AXP803, PEK_SHORT, 4, 4),
446 INIT_REGMAP_IRQ(AXP803, PEK_LONG, 4, 3),
447 INIT_REGMAP_IRQ(AXP803, PEK_OVER_OFF, 4, 2),
448 INIT_REGMAP_IRQ(AXP803, GPIO1_INPUT, 4, 1),
449 INIT_REGMAP_IRQ(AXP803, GPIO0_INPUT, 4, 0),
450 INIT_REGMAP_IRQ(AXP803, BC_USB_CHNG, 5, 1),
451 INIT_REGMAP_IRQ(AXP803, MV_CHNG, 5, 0),
452};
453
8824ee85
CYT
454static const struct regmap_irq axp806_regmap_irqs[] = {
455 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0),
456 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1),
457 INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW, 0, 3),
458 INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW, 0, 4),
459 INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5),
460 INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6),
461 INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7),
eef2b53a
CYT
462 INIT_REGMAP_IRQ(AXP806, POK_LONG, 1, 0),
463 INIT_REGMAP_IRQ(AXP806, POK_SHORT, 1, 1),
8824ee85 464 INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4),
eef2b53a
CYT
465 INIT_REGMAP_IRQ(AXP806, POK_FALL, 1, 5),
466 INIT_REGMAP_IRQ(AXP806, POK_RISE, 1, 6),
8824ee85
CYT
467};
468
20147f0d
CYT
469static const struct regmap_irq axp809_regmap_irqs[] = {
470 INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7),
471 INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6),
472 INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL, 0, 5),
473 INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V, 0, 4),
474 INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN, 0, 3),
475 INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL, 0, 2),
476 INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW, 0, 1),
477 INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN, 1, 7),
478 INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL, 1, 6),
479 INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE, 1, 5),
480 INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE, 1, 4),
481 INIT_REGMAP_IRQ(AXP809, CHARG, 1, 3),
482 INIT_REGMAP_IRQ(AXP809, CHARG_DONE, 1, 2),
483 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH, 2, 7),
484 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END, 2, 6),
485 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW, 2, 5),
486 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END, 2, 4),
487 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH, 2, 3),
488 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END, 2, 2),
489 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW, 2, 1),
490 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END, 2, 0),
491 INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH, 3, 7),
492 INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1, 3, 1),
493 INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2, 3, 0),
494 INIT_REGMAP_IRQ(AXP809, TIMER, 4, 7),
495 INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE, 4, 6),
496 INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE, 4, 5),
497 INIT_REGMAP_IRQ(AXP809, PEK_SHORT, 4, 4),
498 INIT_REGMAP_IRQ(AXP809, PEK_LONG, 4, 3),
499 INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF, 4, 2),
500 INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT, 4, 1),
501 INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
502};
503
d8d79f8f
MS
504static const struct regmap_irq_chip axp152_regmap_irq_chip = {
505 .name = "axp152_irq_chip",
506 .status_base = AXP152_IRQ1_STATE,
507 .ack_base = AXP152_IRQ1_STATE,
508 .mask_base = AXP152_IRQ1_EN,
509 .mask_invert = true,
510 .init_ack_masked = true,
511 .irqs = axp152_regmap_irqs,
512 .num_irqs = ARRAY_SIZE(axp152_regmap_irqs),
513 .num_regs = 3,
514};
515
cfb61a41
CC
516static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
517 .name = "axp20x_irq_chip",
518 .status_base = AXP20X_IRQ1_STATE,
519 .ack_base = AXP20X_IRQ1_STATE,
520 .mask_base = AXP20X_IRQ1_EN,
af7e9069
JP
521 .mask_invert = true,
522 .init_ack_masked = true,
cfb61a41
CC
523 .irqs = axp20x_regmap_irqs,
524 .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs),
af7e9069
JP
525 .num_regs = 5,
526
527};
528
f05be589
BB
529static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
530 .name = "axp22x_irq_chip",
531 .status_base = AXP20X_IRQ1_STATE,
532 .ack_base = AXP20X_IRQ1_STATE,
533 .mask_base = AXP20X_IRQ1_EN,
534 .mask_invert = true,
535 .init_ack_masked = true,
536 .irqs = axp22x_regmap_irqs,
537 .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs),
538 .num_regs = 5,
539};
540
af7e9069
JP
541static const struct regmap_irq_chip axp288_regmap_irq_chip = {
542 .name = "axp288_irq_chip",
543 .status_base = AXP20X_IRQ1_STATE,
544 .ack_base = AXP20X_IRQ1_STATE,
545 .mask_base = AXP20X_IRQ1_EN,
cfb61a41
CC
546 .mask_invert = true,
547 .init_ack_masked = true,
af7e9069
JP
548 .irqs = axp288_regmap_irqs,
549 .num_irqs = ARRAY_SIZE(axp288_regmap_irqs),
550 .num_regs = 6,
551
cfb61a41
CC
552};
553
1578353e
IZ
554static const struct regmap_irq_chip axp803_regmap_irq_chip = {
555 .name = "axp803",
556 .status_base = AXP20X_IRQ1_STATE,
557 .ack_base = AXP20X_IRQ1_STATE,
558 .mask_base = AXP20X_IRQ1_EN,
559 .mask_invert = true,
560 .init_ack_masked = true,
561 .irqs = axp803_regmap_irqs,
562 .num_irqs = ARRAY_SIZE(axp803_regmap_irqs),
563 .num_regs = 6,
564};
565
8824ee85
CYT
566static const struct regmap_irq_chip axp806_regmap_irq_chip = {
567 .name = "axp806",
568 .status_base = AXP20X_IRQ1_STATE,
569 .ack_base = AXP20X_IRQ1_STATE,
570 .mask_base = AXP20X_IRQ1_EN,
571 .mask_invert = true,
572 .init_ack_masked = true,
573 .irqs = axp806_regmap_irqs,
574 .num_irqs = ARRAY_SIZE(axp806_regmap_irqs),
575 .num_regs = 2,
576};
577
20147f0d
CYT
578static const struct regmap_irq_chip axp809_regmap_irq_chip = {
579 .name = "axp809",
580 .status_base = AXP20X_IRQ1_STATE,
581 .ack_base = AXP20X_IRQ1_STATE,
582 .mask_base = AXP20X_IRQ1_EN,
583 .mask_invert = true,
584 .init_ack_masked = true,
585 .irqs = axp809_regmap_irqs,
586 .num_irqs = ARRAY_SIZE(axp809_regmap_irqs),
587 .num_regs = 5,
588};
589
531a469e 590static const struct mfd_cell axp20x_cells[] = {
cfb61a41 591 {
b419c16b
MR
592 .name = "axp20x-gpio",
593 .of_compatible = "x-powers,axp209-gpio",
594 }, {
8de4efda
HG
595 .name = "axp20x-pek",
596 .num_resources = ARRAY_SIZE(axp20x_pek_resources),
597 .resources = axp20x_pek_resources,
cfb61a41 598 }, {
8de4efda 599 .name = "axp20x-regulator",
4d5e5c34
QS
600 }, {
601 .name = "axp20x-adc",
034c3c95 602 .of_compatible = "x-powers,axp209-adc",
b4aeceb6
QS
603 }, {
604 .name = "axp20x-battery-power-supply",
605 .of_compatible = "x-powers,axp209-battery-power-supply",
cd7cf27b
MH
606 }, {
607 .name = "axp20x-ac-power-supply",
608 .of_compatible = "x-powers,axp202-ac-power-supply",
609 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
610 .resources = axp20x_ac_power_supply_resources,
8de4efda
HG
611 }, {
612 .name = "axp20x-usb-power-supply",
613 .of_compatible = "x-powers,axp202-usb-power-supply",
614 .num_resources = ARRAY_SIZE(axp20x_usb_power_supply_resources),
615 .resources = axp20x_usb_power_supply_resources,
cfb61a41
CC
616 },
617};
618
531a469e 619static const struct mfd_cell axp221_cells[] = {
4c650561 620 {
f4463633 621 .name = "axp221-pek",
4c650561
QS
622 .num_resources = ARRAY_SIZE(axp22x_pek_resources),
623 .resources = axp22x_pek_resources,
624 }, {
625 .name = "axp20x-regulator",
4d5e5c34 626 }, {
034c3c95
QS
627 .name = "axp22x-adc",
628 .of_compatible = "x-powers,axp221-adc",
95c4f531
QS
629 }, {
630 .name = "axp20x-ac-power-supply",
631 .of_compatible = "x-powers,axp221-ac-power-supply",
632 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
633 .resources = axp20x_ac_power_supply_resources,
b4aeceb6
QS
634 }, {
635 .name = "axp20x-battery-power-supply",
636 .of_compatible = "x-powers,axp221-battery-power-supply",
4c650561
QS
637 }, {
638 .name = "axp20x-usb-power-supply",
639 .of_compatible = "x-powers,axp221-usb-power-supply",
640 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
641 .resources = axp22x_usb_power_supply_resources,
642 },
643};
644
531a469e 645static const struct mfd_cell axp223_cells[] = {
f05be589 646 {
753a8d08
CYT
647 .name = "axp221-pek",
648 .num_resources = ARRAY_SIZE(axp22x_pek_resources),
649 .resources = axp22x_pek_resources,
4d5e5c34
QS
650 }, {
651 .name = "axp22x-adc",
034c3c95 652 .of_compatible = "x-powers,axp221-adc",
b4aeceb6
QS
653 }, {
654 .name = "axp20x-battery-power-supply",
655 .of_compatible = "x-powers,axp221-battery-power-supply",
6d4fa89d 656 }, {
753a8d08 657 .name = "axp20x-regulator",
95c4f531
QS
658 }, {
659 .name = "axp20x-ac-power-supply",
660 .of_compatible = "x-powers,axp221-ac-power-supply",
661 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
662 .resources = axp20x_ac_power_supply_resources,
ecd98cce
HG
663 }, {
664 .name = "axp20x-usb-power-supply",
4c650561 665 .of_compatible = "x-powers,axp223-usb-power-supply",
ecd98cce
HG
666 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
667 .resources = axp22x_usb_power_supply_resources,
f05be589
BB
668 },
669};
670
531a469e 671static const struct mfd_cell axp152_cells[] = {
d8d79f8f 672 {
753a8d08
CYT
673 .name = "axp20x-pek",
674 .num_resources = ARRAY_SIZE(axp152_pek_resources),
675 .resources = axp152_pek_resources,
d8d79f8f
MS
676 },
677};
678
531a469e 679static const struct resource axp288_adc_resources[] = {
e26f87e5 680 DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
af7e9069
JP
681};
682
531a469e 683static const struct resource axp288_extcon_resources[] = {
e26f87e5
CYT
684 DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL),
685 DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE),
686 DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG),
687 DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG),
bdb01f78
RP
688};
689
531a469e 690static const struct resource axp288_charger_resources[] = {
e26f87e5
CYT
691 DEFINE_RES_IRQ(AXP288_IRQ_OV),
692 DEFINE_RES_IRQ(AXP288_IRQ_DONE),
693 DEFINE_RES_IRQ(AXP288_IRQ_CHARGING),
694 DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT),
695 DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER),
696 DEFINE_RES_IRQ(AXP288_IRQ_QCBTU),
697 DEFINE_RES_IRQ(AXP288_IRQ_CBTU),
698 DEFINE_RES_IRQ(AXP288_IRQ_QCBTO),
699 DEFINE_RES_IRQ(AXP288_IRQ_CBTO),
af7e9069
JP
700};
701
531a469e 702static const struct mfd_cell axp288_cells[] = {
af7e9069 703 {
753a8d08
CYT
704 .name = "axp288_adc",
705 .num_resources = ARRAY_SIZE(axp288_adc_resources),
706 .resources = axp288_adc_resources,
707 }, {
708 .name = "axp288_extcon",
709 .num_resources = ARRAY_SIZE(axp288_extcon_resources),
710 .resources = axp288_extcon_resources,
711 }, {
712 .name = "axp288_charger",
713 .num_resources = ARRAY_SIZE(axp288_charger_resources),
714 .resources = axp288_charger_resources,
715 }, {
716 .name = "axp288_fuel_gauge",
717 .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources),
718 .resources = axp288_fuel_gauge_resources,
719 }, {
720 .name = "axp221-pek",
721 .num_resources = ARRAY_SIZE(axp288_power_button_resources),
722 .resources = axp288_power_button_resources,
723 }, {
724 .name = "axp288_pmic_acpi",
d8139f63 725 },
af7e9069
JP
726};
727
531a469e 728static const struct mfd_cell axp803_cells[] = {
1578353e 729 {
753a8d08
CYT
730 .name = "axp221-pek",
731 .num_resources = ARRAY_SIZE(axp803_pek_resources),
732 .resources = axp803_pek_resources,
ea90e7b4
OL
733 }, {
734 .name = "axp20x-gpio",
735 .of_compatible = "x-powers,axp813-gpio",
736 }, {
737 .name = "axp813-adc",
738 .of_compatible = "x-powers,axp813-adc",
739 }, {
740 .name = "axp20x-battery-power-supply",
741 .of_compatible = "x-powers,axp813-battery-power-supply",
742 }, {
743 .name = "axp20x-ac-power-supply",
744 .of_compatible = "x-powers,axp813-ac-power-supply",
745 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
746 .resources = axp20x_ac_power_supply_resources,
e7037d75
CYT
747 }, {
748 .name = "axp20x-usb-power-supply",
749 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
750 .resources = axp803_usb_power_supply_resources,
751 .of_compatible = "x-powers,axp813-usb-power-supply",
9b79ff10 752 },
753a8d08 753 { .name = "axp20x-regulator" },
1578353e
IZ
754};
755
06f49010
CYT
756static const struct mfd_cell axp806_self_working_cells[] = {
757 {
753a8d08
CYT
758 .name = "axp221-pek",
759 .num_resources = ARRAY_SIZE(axp806_pek_resources),
760 .resources = axp806_pek_resources,
06f49010 761 },
753a8d08 762 { .name = "axp20x-regulator" },
06f49010
CYT
763};
764
531a469e 765static const struct mfd_cell axp806_cells[] = {
8824ee85 766 {
753a8d08
CYT
767 .id = 2,
768 .name = "axp20x-regulator",
8824ee85
CYT
769 },
770};
771
531a469e 772static const struct mfd_cell axp809_cells[] = {
20147f0d 773 {
753a8d08
CYT
774 .name = "axp221-pek",
775 .num_resources = ARRAY_SIZE(axp809_pek_resources),
776 .resources = axp809_pek_resources,
20147f0d 777 }, {
753a8d08
CYT
778 .id = 1,
779 .name = "axp20x-regulator",
20147f0d
CYT
780 },
781};
782
531a469e 783static const struct mfd_cell axp813_cells[] = {
7303733a 784 {
753a8d08
CYT
785 .name = "axp221-pek",
786 .num_resources = ARRAY_SIZE(axp803_pek_resources),
787 .resources = axp803_pek_resources,
9a43206b 788 }, {
753a8d08 789 .name = "axp20x-regulator",
2bb3253c 790 }, {
753a8d08
CYT
791 .name = "axp20x-gpio",
792 .of_compatible = "x-powers,axp813-gpio",
e5d590fa 793 }, {
753a8d08
CYT
794 .name = "axp813-adc",
795 .of_compatible = "x-powers,axp813-adc",
6720328f
QS
796 }, {
797 .name = "axp20x-battery-power-supply",
798 .of_compatible = "x-powers,axp813-battery-power-supply",
4a19f9a6
OL
799 }, {
800 .name = "axp20x-ac-power-supply",
801 .of_compatible = "x-powers,axp813-ac-power-supply",
802 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
803 .resources = axp20x_ac_power_supply_resources,
129fc677
QS
804 }, {
805 .name = "axp20x-usb-power-supply",
806 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
807 .resources = axp803_usb_power_supply_resources,
808 .of_compatible = "x-powers,axp813-usb-power-supply",
e5d590fa 809 },
7303733a
CYT
810};
811
cfb61a41
CC
812static struct axp20x_dev *axp20x_pm_power_off;
813static void axp20x_power_off(void)
814{
af7e9069
JP
815 if (axp20x_pm_power_off->variant == AXP288_ID)
816 return;
817
cfb61a41
CC
818 regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
819 AXP20X_OFF);
179dc63d
HG
820
821 /* Give capacitors etc. time to drain to avoid kernel panic msg. */
822 msleep(500);
cfb61a41
CC
823}
824
4fd41151 825int axp20x_match_device(struct axp20x_dev *axp20x)
af7e9069 826{
e47a3cf7 827 struct device *dev = axp20x->dev;
af7e9069
JP
828 const struct acpi_device_id *acpi_id;
829 const struct of_device_id *of_id;
830
831 if (dev->of_node) {
af7acc3d 832 of_id = of_match_device(dev->driver->of_match_table, dev);
af7e9069
JP
833 if (!of_id) {
834 dev_err(dev, "Unable to match OF ID\n");
835 return -ENODEV;
836 }
2260a453 837 axp20x->variant = (long)of_id->data;
af7e9069
JP
838 } else {
839 acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
840 if (!acpi_id || !acpi_id->driver_data) {
841 dev_err(dev, "Unable to match ACPI ID and data\n");
842 return -ENODEV;
843 }
2260a453 844 axp20x->variant = (long)acpi_id->driver_data;
af7e9069
JP
845 }
846
847 switch (axp20x->variant) {
d8d79f8f
MS
848 case AXP152_ID:
849 axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
850 axp20x->cells = axp152_cells;
851 axp20x->regmap_cfg = &axp152_regmap_config;
852 axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
853 break;
af7e9069
JP
854 case AXP202_ID:
855 case AXP209_ID:
856 axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
857 axp20x->cells = axp20x_cells;
858 axp20x->regmap_cfg = &axp20x_regmap_config;
859 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
860 break;
f05be589 861 case AXP221_ID:
4c650561
QS
862 axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
863 axp20x->cells = axp221_cells;
864 axp20x->regmap_cfg = &axp22x_regmap_config;
865 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
866 break;
02071f0f 867 case AXP223_ID:
4c650561
QS
868 axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
869 axp20x->cells = axp223_cells;
f05be589
BB
870 axp20x->regmap_cfg = &axp22x_regmap_config;
871 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
872 break;
af7e9069
JP
873 case AXP288_ID:
874 axp20x->cells = axp288_cells;
875 axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
876 axp20x->regmap_cfg = &axp288_regmap_config;
877 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
0a5454c9 878 axp20x->irq_flags = IRQF_TRIGGER_LOW;
af7e9069 879 break;
1578353e
IZ
880 case AXP803_ID:
881 axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
882 axp20x->cells = axp803_cells;
883 axp20x->regmap_cfg = &axp288_regmap_config;
884 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
885 break;
8824ee85 886 case AXP806_ID:
06f49010
CYT
887 if (of_property_read_bool(axp20x->dev->of_node,
888 "x-powers,self-working-mode")) {
889 axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
890 axp20x->cells = axp806_self_working_cells;
891 } else {
892 axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
893 axp20x->cells = axp806_cells;
894 }
8824ee85
CYT
895 axp20x->regmap_cfg = &axp806_regmap_config;
896 axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
897 break;
20147f0d
CYT
898 case AXP809_ID:
899 axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
900 axp20x->cells = axp809_cells;
901 axp20x->regmap_cfg = &axp22x_regmap_config;
902 axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
903 break;
7303733a
CYT
904 case AXP813_ID:
905 axp20x->nr_cells = ARRAY_SIZE(axp813_cells);
906 axp20x->cells = axp813_cells;
907 axp20x->regmap_cfg = &axp288_regmap_config;
908 /*
909 * The IRQ table given in the datasheet is incorrect.
910 * In IRQ enable/status registers 1, there are separate
911 * IRQs for ACIN and VBUS, instead of bits [7:5] being
912 * the same as bits [4:2]. So it shares the same IRQs
913 * as the AXP803, rather than the AXP288.
914 */
915 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
916 break;
af7e9069
JP
917 default:
918 dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
919 return -EINVAL;
920 }
921 dev_info(dev, "AXP20x variant %s found\n",
2260a453 922 axp20x_model_names[axp20x->variant]);
af7e9069
JP
923
924 return 0;
925}
4fd41151 926EXPORT_SYMBOL(axp20x_match_device);
af7e9069 927
4fd41151 928int axp20x_device_probe(struct axp20x_dev *axp20x)
cfb61a41 929{
cfb61a41
CC
930 int ret;
931
696f0b3f
CYT
932 /*
933 * The AXP806 supports either master/standalone or slave mode.
934 * Slave mode allows sharing the serial bus, even with multiple
935 * AXP806 which all have the same hardware address.
936 *
937 * This is done with extra "serial interface address extension",
938 * or AXP806_BUS_ADDR_EXT, and "register address extension", or
939 * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
940 * 1 bit customizable at the factory, and 1 bit depending on the
941 * state of an external pin. The latter is writable. The device
942 * will only respond to operations to its other registers when
943 * the these device addressing bits (in the upper 4 bits of the
944 * registers) match.
945 *
c0369698
RIL
946 * By default we support an AXP806 chained to an AXP809 in slave
947 * mode. Boards which use an AXP806 in master mode can set the
948 * property "x-powers,master-mode" to override the default.
696f0b3f 949 */
c0369698
RIL
950 if (axp20x->variant == AXP806_ID) {
951 if (of_property_read_bool(axp20x->dev->of_node,
06f49010
CYT
952 "x-powers,master-mode") ||
953 of_property_read_bool(axp20x->dev->of_node,
954 "x-powers,self-working-mode"))
c0369698
RIL
955 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
956 AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
957 else
958 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
959 AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
960 }
696f0b3f 961
4fd41151 962 ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
0a5454c9
HG
963 IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
964 -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc);
cfb61a41 965 if (ret) {
4fd41151 966 dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret);
cfb61a41
CC
967 return ret;
968 }
969
af7e9069 970 ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
2260a453 971 axp20x->nr_cells, NULL, 0, NULL);
cfb61a41
CC
972
973 if (ret) {
4fd41151
CYT
974 dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
975 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
cfb61a41
CC
976 return ret;
977 }
978
979 if (!pm_power_off) {
980 axp20x_pm_power_off = axp20x;
981 pm_power_off = axp20x_power_off;
982 }
983
4fd41151 984 dev_info(axp20x->dev, "AXP20X driver loaded\n");
cfb61a41
CC
985
986 return 0;
987}
4fd41151 988EXPORT_SYMBOL(axp20x_device_probe);
cfb61a41 989
4fd41151 990int axp20x_device_remove(struct axp20x_dev *axp20x)
cfb61a41 991{
cfb61a41
CC
992 if (axp20x == axp20x_pm_power_off) {
993 axp20x_pm_power_off = NULL;
994 pm_power_off = NULL;
995 }
996
997 mfd_remove_devices(axp20x->dev);
4fd41151 998 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
cfb61a41
CC
999
1000 return 0;
1001}
4fd41151 1002EXPORT_SYMBOL(axp20x_device_remove);
cfb61a41
CC
1003
1004MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
1005MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
1006MODULE_LICENSE("GPL");