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