]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/mfd/axp20x.c
UBUNTU: Ubuntu-5.4.0-117.132
[mirror_ubuntu-focal-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 127 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
320f7a4d 128 regmap_reg_range(AXP22X_PWR_OUT_CTRL1, AXP22X_ALDO3_V_OUT),
cd532166 129 regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
d18db5e0 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),
320f7a4d 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 {
f4463633 622 .name = "axp221-pek",
4c650561
QS
623 .num_resources = ARRAY_SIZE(axp22x_pek_resources),
624 .resources = axp22x_pek_resources,
625 }, {
626 .name = "axp20x-regulator",
4d5e5c34 627 }, {
034c3c95
QS
628 .name = "axp22x-adc",
629 .of_compatible = "x-powers,axp221-adc",
95c4f531
QS
630 }, {
631 .name = "axp20x-ac-power-supply",
632 .of_compatible = "x-powers,axp221-ac-power-supply",
633 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
634 .resources = axp20x_ac_power_supply_resources,
b4aeceb6
QS
635 }, {
636 .name = "axp20x-battery-power-supply",
637 .of_compatible = "x-powers,axp221-battery-power-supply",
4c650561
QS
638 }, {
639 .name = "axp20x-usb-power-supply",
640 .of_compatible = "x-powers,axp221-usb-power-supply",
641 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
642 .resources = axp22x_usb_power_supply_resources,
643 },
644};
645
531a469e 646static const struct mfd_cell axp223_cells[] = {
f05be589 647 {
753a8d08
CYT
648 .name = "axp221-pek",
649 .num_resources = ARRAY_SIZE(axp22x_pek_resources),
650 .resources = axp22x_pek_resources,
4d5e5c34
QS
651 }, {
652 .name = "axp22x-adc",
034c3c95 653 .of_compatible = "x-powers,axp221-adc",
b4aeceb6
QS
654 }, {
655 .name = "axp20x-battery-power-supply",
656 .of_compatible = "x-powers,axp221-battery-power-supply",
6d4fa89d 657 }, {
753a8d08 658 .name = "axp20x-regulator",
95c4f531
QS
659 }, {
660 .name = "axp20x-ac-power-supply",
661 .of_compatible = "x-powers,axp221-ac-power-supply",
662 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
663 .resources = axp20x_ac_power_supply_resources,
ecd98cce
HG
664 }, {
665 .name = "axp20x-usb-power-supply",
4c650561 666 .of_compatible = "x-powers,axp223-usb-power-supply",
ecd98cce
HG
667 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
668 .resources = axp22x_usb_power_supply_resources,
f05be589
BB
669 },
670};
671
531a469e 672static const struct mfd_cell axp152_cells[] = {
d8d79f8f 673 {
753a8d08
CYT
674 .name = "axp20x-pek",
675 .num_resources = ARRAY_SIZE(axp152_pek_resources),
676 .resources = axp152_pek_resources,
d8d79f8f
MS
677 },
678};
679
531a469e 680static const struct resource axp288_adc_resources[] = {
e26f87e5 681 DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
af7e9069
JP
682};
683
531a469e 684static const struct resource axp288_extcon_resources[] = {
e26f87e5
CYT
685 DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL),
686 DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE),
687 DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG),
688 DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG),
bdb01f78
RP
689};
690
531a469e 691static const struct resource axp288_charger_resources[] = {
e26f87e5
CYT
692 DEFINE_RES_IRQ(AXP288_IRQ_OV),
693 DEFINE_RES_IRQ(AXP288_IRQ_DONE),
694 DEFINE_RES_IRQ(AXP288_IRQ_CHARGING),
695 DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT),
696 DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER),
697 DEFINE_RES_IRQ(AXP288_IRQ_QCBTU),
698 DEFINE_RES_IRQ(AXP288_IRQ_CBTU),
699 DEFINE_RES_IRQ(AXP288_IRQ_QCBTO),
700 DEFINE_RES_IRQ(AXP288_IRQ_CBTO),
af7e9069
JP
701};
702
531a469e 703static const struct mfd_cell axp288_cells[] = {
af7e9069 704 {
753a8d08
CYT
705 .name = "axp288_adc",
706 .num_resources = ARRAY_SIZE(axp288_adc_resources),
707 .resources = axp288_adc_resources,
708 }, {
709 .name = "axp288_extcon",
710 .num_resources = ARRAY_SIZE(axp288_extcon_resources),
711 .resources = axp288_extcon_resources,
712 }, {
713 .name = "axp288_charger",
714 .num_resources = ARRAY_SIZE(axp288_charger_resources),
715 .resources = axp288_charger_resources,
716 }, {
717 .name = "axp288_fuel_gauge",
718 .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources),
719 .resources = axp288_fuel_gauge_resources,
720 }, {
721 .name = "axp221-pek",
722 .num_resources = ARRAY_SIZE(axp288_power_button_resources),
723 .resources = axp288_power_button_resources,
724 }, {
725 .name = "axp288_pmic_acpi",
d8139f63 726 },
af7e9069
JP
727};
728
531a469e 729static const struct mfd_cell axp803_cells[] = {
1578353e 730 {
753a8d08
CYT
731 .name = "axp221-pek",
732 .num_resources = ARRAY_SIZE(axp803_pek_resources),
733 .resources = axp803_pek_resources,
ea90e7b4
OL
734 }, {
735 .name = "axp20x-gpio",
736 .of_compatible = "x-powers,axp813-gpio",
737 }, {
738 .name = "axp813-adc",
739 .of_compatible = "x-powers,axp813-adc",
740 }, {
741 .name = "axp20x-battery-power-supply",
742 .of_compatible = "x-powers,axp813-battery-power-supply",
743 }, {
744 .name = "axp20x-ac-power-supply",
745 .of_compatible = "x-powers,axp813-ac-power-supply",
746 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
747 .resources = axp20x_ac_power_supply_resources,
e7037d75
CYT
748 }, {
749 .name = "axp20x-usb-power-supply",
750 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
751 .resources = axp803_usb_power_supply_resources,
752 .of_compatible = "x-powers,axp813-usb-power-supply",
9b79ff10 753 },
753a8d08 754 { .name = "axp20x-regulator" },
1578353e
IZ
755};
756
06f49010
CYT
757static const struct mfd_cell axp806_self_working_cells[] = {
758 {
753a8d08
CYT
759 .name = "axp221-pek",
760 .num_resources = ARRAY_SIZE(axp806_pek_resources),
761 .resources = axp806_pek_resources,
06f49010 762 },
753a8d08 763 { .name = "axp20x-regulator" },
06f49010
CYT
764};
765
531a469e 766static const struct mfd_cell axp806_cells[] = {
8824ee85 767 {
753a8d08
CYT
768 .id = 2,
769 .name = "axp20x-regulator",
8824ee85
CYT
770 },
771};
772
531a469e 773static const struct mfd_cell axp809_cells[] = {
20147f0d 774 {
753a8d08
CYT
775 .name = "axp221-pek",
776 .num_resources = ARRAY_SIZE(axp809_pek_resources),
777 .resources = axp809_pek_resources,
20147f0d 778 }, {
753a8d08
CYT
779 .id = 1,
780 .name = "axp20x-regulator",
20147f0d
CYT
781 },
782};
783
531a469e 784static const struct mfd_cell axp813_cells[] = {
7303733a 785 {
753a8d08
CYT
786 .name = "axp221-pek",
787 .num_resources = ARRAY_SIZE(axp803_pek_resources),
788 .resources = axp803_pek_resources,
9a43206b 789 }, {
753a8d08 790 .name = "axp20x-regulator",
2bb3253c 791 }, {
753a8d08
CYT
792 .name = "axp20x-gpio",
793 .of_compatible = "x-powers,axp813-gpio",
e5d590fa 794 }, {
753a8d08
CYT
795 .name = "axp813-adc",
796 .of_compatible = "x-powers,axp813-adc",
6720328f
QS
797 }, {
798 .name = "axp20x-battery-power-supply",
799 .of_compatible = "x-powers,axp813-battery-power-supply",
4a19f9a6
OL
800 }, {
801 .name = "axp20x-ac-power-supply",
802 .of_compatible = "x-powers,axp813-ac-power-supply",
803 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
804 .resources = axp20x_ac_power_supply_resources,
129fc677
QS
805 }, {
806 .name = "axp20x-usb-power-supply",
807 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
808 .resources = axp803_usb_power_supply_resources,
809 .of_compatible = "x-powers,axp813-usb-power-supply",
e5d590fa 810 },
7303733a
CYT
811};
812
cfb61a41
CC
813static struct axp20x_dev *axp20x_pm_power_off;
814static void axp20x_power_off(void)
815{
af7e9069
JP
816 if (axp20x_pm_power_off->variant == AXP288_ID)
817 return;
818
cfb61a41
CC
819 regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
820 AXP20X_OFF);
179dc63d
HG
821
822 /* Give capacitors etc. time to drain to avoid kernel panic msg. */
823 msleep(500);
cfb61a41
CC
824}
825
4fd41151 826int axp20x_match_device(struct axp20x_dev *axp20x)
af7e9069 827{
e47a3cf7 828 struct device *dev = axp20x->dev;
af7e9069
JP
829 const struct acpi_device_id *acpi_id;
830 const struct of_device_id *of_id;
831
832 if (dev->of_node) {
af7acc3d 833 of_id = of_match_device(dev->driver->of_match_table, dev);
af7e9069
JP
834 if (!of_id) {
835 dev_err(dev, "Unable to match OF ID\n");
836 return -ENODEV;
837 }
2260a453 838 axp20x->variant = (long)of_id->data;
af7e9069
JP
839 } else {
840 acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
841 if (!acpi_id || !acpi_id->driver_data) {
842 dev_err(dev, "Unable to match ACPI ID and data\n");
843 return -ENODEV;
844 }
2260a453 845 axp20x->variant = (long)acpi_id->driver_data;
af7e9069
JP
846 }
847
848 switch (axp20x->variant) {
d8d79f8f
MS
849 case AXP152_ID:
850 axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
851 axp20x->cells = axp152_cells;
852 axp20x->regmap_cfg = &axp152_regmap_config;
853 axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
854 break;
af7e9069
JP
855 case AXP202_ID:
856 case AXP209_ID:
857 axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
858 axp20x->cells = axp20x_cells;
859 axp20x->regmap_cfg = &axp20x_regmap_config;
860 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
861 break;
f05be589 862 case AXP221_ID:
4c650561
QS
863 axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
864 axp20x->cells = axp221_cells;
865 axp20x->regmap_cfg = &axp22x_regmap_config;
866 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
867 break;
02071f0f 868 case AXP223_ID:
4c650561
QS
869 axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
870 axp20x->cells = axp223_cells;
f05be589
BB
871 axp20x->regmap_cfg = &axp22x_regmap_config;
872 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
873 break;
af7e9069
JP
874 case AXP288_ID:
875 axp20x->cells = axp288_cells;
876 axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
877 axp20x->regmap_cfg = &axp288_regmap_config;
878 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
0a5454c9 879 axp20x->irq_flags = IRQF_TRIGGER_LOW;
af7e9069 880 break;
1578353e
IZ
881 case AXP803_ID:
882 axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
883 axp20x->cells = axp803_cells;
884 axp20x->regmap_cfg = &axp288_regmap_config;
885 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
886 break;
8824ee85 887 case AXP806_ID:
06f49010
CYT
888 if (of_property_read_bool(axp20x->dev->of_node,
889 "x-powers,self-working-mode")) {
890 axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
891 axp20x->cells = axp806_self_working_cells;
892 } else {
893 axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
894 axp20x->cells = axp806_cells;
895 }
8824ee85
CYT
896 axp20x->regmap_cfg = &axp806_regmap_config;
897 axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
898 break;
20147f0d
CYT
899 case AXP809_ID:
900 axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
901 axp20x->cells = axp809_cells;
902 axp20x->regmap_cfg = &axp22x_regmap_config;
903 axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
904 break;
7303733a
CYT
905 case AXP813_ID:
906 axp20x->nr_cells = ARRAY_SIZE(axp813_cells);
907 axp20x->cells = axp813_cells;
908 axp20x->regmap_cfg = &axp288_regmap_config;
909 /*
910 * The IRQ table given in the datasheet is incorrect.
911 * In IRQ enable/status registers 1, there are separate
912 * IRQs for ACIN and VBUS, instead of bits [7:5] being
913 * the same as bits [4:2]. So it shares the same IRQs
914 * as the AXP803, rather than the AXP288.
915 */
916 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
917 break;
af7e9069
JP
918 default:
919 dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
920 return -EINVAL;
921 }
922 dev_info(dev, "AXP20x variant %s found\n",
2260a453 923 axp20x_model_names[axp20x->variant]);
af7e9069
JP
924
925 return 0;
926}
4fd41151 927EXPORT_SYMBOL(axp20x_match_device);
af7e9069 928
4fd41151 929int axp20x_device_probe(struct axp20x_dev *axp20x)
cfb61a41 930{
cfb61a41
CC
931 int ret;
932
696f0b3f
CYT
933 /*
934 * The AXP806 supports either master/standalone or slave mode.
935 * Slave mode allows sharing the serial bus, even with multiple
936 * AXP806 which all have the same hardware address.
937 *
938 * This is done with extra "serial interface address extension",
939 * or AXP806_BUS_ADDR_EXT, and "register address extension", or
940 * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
941 * 1 bit customizable at the factory, and 1 bit depending on the
942 * state of an external pin. The latter is writable. The device
943 * will only respond to operations to its other registers when
944 * the these device addressing bits (in the upper 4 bits of the
945 * registers) match.
946 *
c0369698
RIL
947 * By default we support an AXP806 chained to an AXP809 in slave
948 * mode. Boards which use an AXP806 in master mode can set the
949 * property "x-powers,master-mode" to override the default.
696f0b3f 950 */
c0369698
RIL
951 if (axp20x->variant == AXP806_ID) {
952 if (of_property_read_bool(axp20x->dev->of_node,
06f49010
CYT
953 "x-powers,master-mode") ||
954 of_property_read_bool(axp20x->dev->of_node,
955 "x-powers,self-working-mode"))
c0369698
RIL
956 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
957 AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
958 else
959 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
960 AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
961 }
696f0b3f 962
4fd41151 963 ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
0a5454c9
HG
964 IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
965 -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc);
cfb61a41 966 if (ret) {
4fd41151 967 dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret);
cfb61a41
CC
968 return ret;
969 }
970
af7e9069 971 ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
2260a453 972 axp20x->nr_cells, NULL, 0, NULL);
cfb61a41
CC
973
974 if (ret) {
4fd41151
CYT
975 dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
976 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
cfb61a41
CC
977 return ret;
978 }
979
980 if (!pm_power_off) {
981 axp20x_pm_power_off = axp20x;
982 pm_power_off = axp20x_power_off;
983 }
984
4fd41151 985 dev_info(axp20x->dev, "AXP20X driver loaded\n");
cfb61a41
CC
986
987 return 0;
988}
4fd41151 989EXPORT_SYMBOL(axp20x_device_probe);
cfb61a41 990
4fd41151 991int axp20x_device_remove(struct axp20x_dev *axp20x)
cfb61a41 992{
cfb61a41
CC
993 if (axp20x == axp20x_pm_power_off) {
994 axp20x_pm_power_off = NULL;
995 pm_power_off = NULL;
996 }
997
998 mfd_remove_devices(axp20x->dev);
4fd41151 999 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
cfb61a41
CC
1000
1001 return 0;
1002}
4fd41151 1003EXPORT_SYMBOL(axp20x_device_remove);
cfb61a41
CC
1004
1005MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
1006MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
1007MODULE_LICENSE("GPL");