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