xref: /openbmc/linux/drivers/mfd/axp20x.c (revision 696f0b3f)
1cfb61a41SCarlo Caione /*
24fd41151SChen-Yu Tsai  * MFD core driver for the X-Powers' Power Management ICs
3cfb61a41SCarlo Caione  *
4af7e9069SJacob Pan  * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
5af7e9069SJacob Pan  * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
6af7e9069SJacob Pan  * as well as configurable GPIOs.
7cfb61a41SCarlo Caione  *
84fd41151SChen-Yu Tsai  * This file contains the interface independent core functions.
94fd41151SChen-Yu Tsai  *
10e740235dSChen-Yu Tsai  * Copyright (C) 2014 Carlo Caione
11e740235dSChen-Yu Tsai  *
12cfb61a41SCarlo Caione  * Author: Carlo Caione <carlo@caione.org>
13cfb61a41SCarlo Caione  *
14cfb61a41SCarlo Caione  * This program is free software; you can redistribute it and/or modify
15cfb61a41SCarlo Caione  * it under the terms of the GNU General Public License version 2 as
16cfb61a41SCarlo Caione  * published by the Free Software Foundation.
17cfb61a41SCarlo Caione  */
18cfb61a41SCarlo Caione 
19cfb61a41SCarlo Caione #include <linux/err.h>
20179dc63dSHans de Goede #include <linux/delay.h>
21cfb61a41SCarlo Caione #include <linux/interrupt.h>
22cfb61a41SCarlo Caione #include <linux/kernel.h>
23cfb61a41SCarlo Caione #include <linux/module.h>
24cfb61a41SCarlo Caione #include <linux/pm_runtime.h>
25cfb61a41SCarlo Caione #include <linux/regmap.h>
26cfb61a41SCarlo Caione #include <linux/regulator/consumer.h>
27cfb61a41SCarlo Caione #include <linux/mfd/axp20x.h>
28cfb61a41SCarlo Caione #include <linux/mfd/core.h>
29cfb61a41SCarlo Caione #include <linux/of_device.h>
30af7e9069SJacob Pan #include <linux/acpi.h>
31cfb61a41SCarlo Caione 
32cfb61a41SCarlo Caione #define AXP20X_OFF	0x80
33cfb61a41SCarlo Caione 
34696f0b3fSChen-Yu Tsai #define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE	BIT(4)
35696f0b3fSChen-Yu Tsai 
36c31e858bSKrzysztof Kozlowski static const char * const axp20x_model_names[] = {
37d8d79f8fSMichal Suchanek 	"AXP152",
38af7e9069SJacob Pan 	"AXP202",
39af7e9069SJacob Pan 	"AXP209",
40f05be589SBoris BREZILLON 	"AXP221",
4102071f0fSChen-Yu Tsai 	"AXP223",
42af7e9069SJacob Pan 	"AXP288",
438824ee85SChen-Yu Tsai 	"AXP806",
4420147f0dSChen-Yu Tsai 	"AXP809",
45af7e9069SJacob Pan };
46af7e9069SJacob Pan 
47d8d79f8fSMichal Suchanek static const struct regmap_range axp152_writeable_ranges[] = {
48d8d79f8fSMichal Suchanek 	regmap_reg_range(AXP152_LDO3456_DC1234_CTRL, AXP152_IRQ3_STATE),
49d8d79f8fSMichal Suchanek 	regmap_reg_range(AXP152_DCDC_MODE, AXP152_PWM1_DUTY_CYCLE),
50d8d79f8fSMichal Suchanek };
51d8d79f8fSMichal Suchanek 
52d8d79f8fSMichal Suchanek static const struct regmap_range axp152_volatile_ranges[] = {
53d8d79f8fSMichal Suchanek 	regmap_reg_range(AXP152_PWR_OP_MODE, AXP152_PWR_OP_MODE),
54d8d79f8fSMichal Suchanek 	regmap_reg_range(AXP152_IRQ1_EN, AXP152_IRQ3_STATE),
55d8d79f8fSMichal Suchanek 	regmap_reg_range(AXP152_GPIO_INPUT, AXP152_GPIO_INPUT),
56d8d79f8fSMichal Suchanek };
57d8d79f8fSMichal Suchanek 
58d8d79f8fSMichal Suchanek static const struct regmap_access_table axp152_writeable_table = {
59d8d79f8fSMichal Suchanek 	.yes_ranges	= axp152_writeable_ranges,
60d8d79f8fSMichal Suchanek 	.n_yes_ranges	= ARRAY_SIZE(axp152_writeable_ranges),
61d8d79f8fSMichal Suchanek };
62d8d79f8fSMichal Suchanek 
63d8d79f8fSMichal Suchanek static const struct regmap_access_table axp152_volatile_table = {
64d8d79f8fSMichal Suchanek 	.yes_ranges	= axp152_volatile_ranges,
65d8d79f8fSMichal Suchanek 	.n_yes_ranges	= ARRAY_SIZE(axp152_volatile_ranges),
66d8d79f8fSMichal Suchanek };
67d8d79f8fSMichal Suchanek 
68cfb61a41SCarlo Caione static const struct regmap_range axp20x_writeable_ranges[] = {
69cfb61a41SCarlo Caione 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
70cfb61a41SCarlo Caione 	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
71553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
72cfb61a41SCarlo Caione };
73cfb61a41SCarlo Caione 
74cfb61a41SCarlo Caione static const struct regmap_range axp20x_volatile_ranges[] = {
75553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
76553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
77cfb61a41SCarlo Caione 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
78553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
79553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
80553ed4b5SBruno Prémont 	regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
81cfb61a41SCarlo Caione };
82cfb61a41SCarlo Caione 
83cfb61a41SCarlo Caione static const struct regmap_access_table axp20x_writeable_table = {
84cfb61a41SCarlo Caione 	.yes_ranges	= axp20x_writeable_ranges,
85cfb61a41SCarlo Caione 	.n_yes_ranges	= ARRAY_SIZE(axp20x_writeable_ranges),
86cfb61a41SCarlo Caione };
87cfb61a41SCarlo Caione 
88cfb61a41SCarlo Caione static const struct regmap_access_table axp20x_volatile_table = {
89cfb61a41SCarlo Caione 	.yes_ranges	= axp20x_volatile_ranges,
90cfb61a41SCarlo Caione 	.n_yes_ranges	= ARRAY_SIZE(axp20x_volatile_ranges),
91cfb61a41SCarlo Caione };
92cfb61a41SCarlo Caione 
9320147f0dSChen-Yu Tsai /* AXP22x ranges are shared with the AXP809, as they cover the same range */
94f05be589SBoris BREZILLON static const struct regmap_range axp22x_writeable_ranges[] = {
95f05be589SBoris BREZILLON 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
96f05be589SBoris BREZILLON 	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
97f05be589SBoris BREZILLON };
98f05be589SBoris BREZILLON 
99f05be589SBoris BREZILLON static const struct regmap_range axp22x_volatile_ranges[] = {
10015093250SHans de Goede 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
101f05be589SBoris BREZILLON 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
10215093250SHans de Goede 	regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
1033f89586bSIcenowy Zheng 	regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
10415093250SHans de Goede 	regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
105f05be589SBoris BREZILLON };
106f05be589SBoris BREZILLON 
107f05be589SBoris BREZILLON static const struct regmap_access_table axp22x_writeable_table = {
108f05be589SBoris BREZILLON 	.yes_ranges	= axp22x_writeable_ranges,
109f05be589SBoris BREZILLON 	.n_yes_ranges	= ARRAY_SIZE(axp22x_writeable_ranges),
110f05be589SBoris BREZILLON };
111f05be589SBoris BREZILLON 
112f05be589SBoris BREZILLON static const struct regmap_access_table axp22x_volatile_table = {
113f05be589SBoris BREZILLON 	.yes_ranges	= axp22x_volatile_ranges,
114f05be589SBoris BREZILLON 	.n_yes_ranges	= ARRAY_SIZE(axp22x_volatile_ranges),
115f05be589SBoris BREZILLON };
116f05be589SBoris BREZILLON 
117af7e9069SJacob Pan static const struct regmap_range axp288_writeable_ranges[] = {
118af7e9069SJacob Pan 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
119af7e9069SJacob Pan 	regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
120af7e9069SJacob Pan };
121af7e9069SJacob Pan 
122af7e9069SJacob Pan static const struct regmap_range axp288_volatile_ranges[] = {
123cd532166SHans de Goede 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
124cd532166SHans de Goede 	regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
125cd532166SHans de Goede 	regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
126af7e9069SJacob Pan 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
127cd532166SHans de Goede 	regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
128cd532166SHans de Goede 	regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
129cd532166SHans de Goede 	regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L),
130cd532166SHans de Goede 	regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG),
131af7e9069SJacob Pan };
132af7e9069SJacob Pan 
133af7e9069SJacob Pan static const struct regmap_access_table axp288_writeable_table = {
134af7e9069SJacob Pan 	.yes_ranges	= axp288_writeable_ranges,
135af7e9069SJacob Pan 	.n_yes_ranges	= ARRAY_SIZE(axp288_writeable_ranges),
136af7e9069SJacob Pan };
137af7e9069SJacob Pan 
138af7e9069SJacob Pan static const struct regmap_access_table axp288_volatile_table = {
139af7e9069SJacob Pan 	.yes_ranges	= axp288_volatile_ranges,
140af7e9069SJacob Pan 	.n_yes_ranges	= ARRAY_SIZE(axp288_volatile_ranges),
141af7e9069SJacob Pan };
142af7e9069SJacob Pan 
1438824ee85SChen-Yu Tsai static const struct regmap_range axp806_writeable_ranges[] = {
1448824ee85SChen-Yu Tsai 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
1458824ee85SChen-Yu Tsai 	regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
1468824ee85SChen-Yu Tsai 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
1478824ee85SChen-Yu Tsai 	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
14834d9030bSChen-Yu Tsai 	regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
1498824ee85SChen-Yu Tsai };
1508824ee85SChen-Yu Tsai 
1518824ee85SChen-Yu Tsai static const struct regmap_range axp806_volatile_ranges[] = {
1528824ee85SChen-Yu Tsai 	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
1538824ee85SChen-Yu Tsai };
1548824ee85SChen-Yu Tsai 
1558824ee85SChen-Yu Tsai static const struct regmap_access_table axp806_writeable_table = {
1568824ee85SChen-Yu Tsai 	.yes_ranges	= axp806_writeable_ranges,
1578824ee85SChen-Yu Tsai 	.n_yes_ranges	= ARRAY_SIZE(axp806_writeable_ranges),
1588824ee85SChen-Yu Tsai };
1598824ee85SChen-Yu Tsai 
1608824ee85SChen-Yu Tsai static const struct regmap_access_table axp806_volatile_table = {
1618824ee85SChen-Yu Tsai 	.yes_ranges	= axp806_volatile_ranges,
1628824ee85SChen-Yu Tsai 	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
1638824ee85SChen-Yu Tsai };
1648824ee85SChen-Yu Tsai 
165d8d79f8fSMichal Suchanek static struct resource axp152_pek_resources[] = {
166d8d79f8fSMichal Suchanek 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
167d8d79f8fSMichal Suchanek 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
168d8d79f8fSMichal Suchanek };
169d8d79f8fSMichal Suchanek 
170cd7cf27bSMichael Haas static struct resource axp20x_ac_power_supply_resources[] = {
171cd7cf27bSMichael Haas 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
172cd7cf27bSMichael Haas 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
173cd7cf27bSMichael Haas 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
174cd7cf27bSMichael Haas };
175cd7cf27bSMichael Haas 
176cfb61a41SCarlo Caione static struct resource axp20x_pek_resources[] = {
177cfb61a41SCarlo Caione 	{
178cfb61a41SCarlo Caione 		.name	= "PEK_DBR",
179cfb61a41SCarlo Caione 		.start	= AXP20X_IRQ_PEK_RIS_EDGE,
180cfb61a41SCarlo Caione 		.end	= AXP20X_IRQ_PEK_RIS_EDGE,
181cfb61a41SCarlo Caione 		.flags	= IORESOURCE_IRQ,
182cfb61a41SCarlo Caione 	}, {
183cfb61a41SCarlo Caione 		.name	= "PEK_DBF",
184cfb61a41SCarlo Caione 		.start	= AXP20X_IRQ_PEK_FAL_EDGE,
185cfb61a41SCarlo Caione 		.end	= AXP20X_IRQ_PEK_FAL_EDGE,
186cfb61a41SCarlo Caione 		.flags	= IORESOURCE_IRQ,
187cfb61a41SCarlo Caione 	},
188cfb61a41SCarlo Caione };
189cfb61a41SCarlo Caione 
1908de4efdaSHans de Goede static struct resource axp20x_usb_power_supply_resources[] = {
1918de4efdaSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
1928de4efdaSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
1938de4efdaSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
1948de4efdaSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
1958de4efdaSHans de Goede };
1968de4efdaSHans de Goede 
197ecd98cceSHans de Goede static struct resource axp22x_usb_power_supply_resources[] = {
198ecd98cceSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
199ecd98cceSHans de Goede 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
200ecd98cceSHans de Goede };
201ecd98cceSHans de Goede 
202f05be589SBoris BREZILLON static struct resource axp22x_pek_resources[] = {
203f05be589SBoris BREZILLON 	{
204f05be589SBoris BREZILLON 		.name   = "PEK_DBR",
205f05be589SBoris BREZILLON 		.start  = AXP22X_IRQ_PEK_RIS_EDGE,
206f05be589SBoris BREZILLON 		.end    = AXP22X_IRQ_PEK_RIS_EDGE,
207f05be589SBoris BREZILLON 		.flags  = IORESOURCE_IRQ,
208f05be589SBoris BREZILLON 	}, {
209f05be589SBoris BREZILLON 		.name   = "PEK_DBF",
210f05be589SBoris BREZILLON 		.start  = AXP22X_IRQ_PEK_FAL_EDGE,
211f05be589SBoris BREZILLON 		.end    = AXP22X_IRQ_PEK_FAL_EDGE,
212f05be589SBoris BREZILLON 		.flags  = IORESOURCE_IRQ,
213f05be589SBoris BREZILLON 	},
214f05be589SBoris BREZILLON };
215f05be589SBoris BREZILLON 
216e56e5ad6SBorun Fu static struct resource axp288_power_button_resources[] = {
217e56e5ad6SBorun Fu 	{
218e56e5ad6SBorun Fu 		.name	= "PEK_DBR",
2191af468ebSHans de Goede 		.start	= AXP288_IRQ_POKP,
2201af468ebSHans de Goede 		.end	= AXP288_IRQ_POKP,
221e56e5ad6SBorun Fu 		.flags	= IORESOURCE_IRQ,
222e56e5ad6SBorun Fu 	},
223e56e5ad6SBorun Fu 	{
224e56e5ad6SBorun Fu 		.name	= "PEK_DBF",
2251af468ebSHans de Goede 		.start	= AXP288_IRQ_POKN,
2261af468ebSHans de Goede 		.end	= AXP288_IRQ_POKN,
227e56e5ad6SBorun Fu 		.flags	= IORESOURCE_IRQ,
228e56e5ad6SBorun Fu 	},
229e56e5ad6SBorun Fu };
230e56e5ad6SBorun Fu 
231d6387874STodd Brandt static struct resource axp288_fuel_gauge_resources[] = {
232af7e9069SJacob Pan 	{
233af7e9069SJacob Pan 		.start = AXP288_IRQ_QWBTU,
234af7e9069SJacob Pan 		.end   = AXP288_IRQ_QWBTU,
235af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
236af7e9069SJacob Pan 	},
237af7e9069SJacob Pan 	{
238af7e9069SJacob Pan 		.start = AXP288_IRQ_WBTU,
239af7e9069SJacob Pan 		.end   = AXP288_IRQ_WBTU,
240af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
241af7e9069SJacob Pan 	},
242af7e9069SJacob Pan 	{
243af7e9069SJacob Pan 		.start = AXP288_IRQ_QWBTO,
244af7e9069SJacob Pan 		.end   = AXP288_IRQ_QWBTO,
245af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
246af7e9069SJacob Pan 	},
247af7e9069SJacob Pan 	{
248af7e9069SJacob Pan 		.start = AXP288_IRQ_WBTO,
249af7e9069SJacob Pan 		.end   = AXP288_IRQ_WBTO,
250af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
251af7e9069SJacob Pan 	},
252af7e9069SJacob Pan 	{
253af7e9069SJacob Pan 		.start = AXP288_IRQ_WL2,
254af7e9069SJacob Pan 		.end   = AXP288_IRQ_WL2,
255af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
256af7e9069SJacob Pan 	},
257af7e9069SJacob Pan 	{
258af7e9069SJacob Pan 		.start = AXP288_IRQ_WL1,
259af7e9069SJacob Pan 		.end   = AXP288_IRQ_WL1,
260af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
261af7e9069SJacob Pan 	},
262af7e9069SJacob Pan };
263af7e9069SJacob Pan 
26420147f0dSChen-Yu Tsai static struct resource axp809_pek_resources[] = {
26520147f0dSChen-Yu Tsai 	{
26620147f0dSChen-Yu Tsai 		.name   = "PEK_DBR",
26720147f0dSChen-Yu Tsai 		.start  = AXP809_IRQ_PEK_RIS_EDGE,
26820147f0dSChen-Yu Tsai 		.end    = AXP809_IRQ_PEK_RIS_EDGE,
26920147f0dSChen-Yu Tsai 		.flags  = IORESOURCE_IRQ,
27020147f0dSChen-Yu Tsai 	}, {
27120147f0dSChen-Yu Tsai 		.name   = "PEK_DBF",
27220147f0dSChen-Yu Tsai 		.start  = AXP809_IRQ_PEK_FAL_EDGE,
27320147f0dSChen-Yu Tsai 		.end    = AXP809_IRQ_PEK_FAL_EDGE,
27420147f0dSChen-Yu Tsai 		.flags  = IORESOURCE_IRQ,
27520147f0dSChen-Yu Tsai 	},
27620147f0dSChen-Yu Tsai };
27720147f0dSChen-Yu Tsai 
278d8d79f8fSMichal Suchanek static const struct regmap_config axp152_regmap_config = {
279d8d79f8fSMichal Suchanek 	.reg_bits	= 8,
280d8d79f8fSMichal Suchanek 	.val_bits	= 8,
281d8d79f8fSMichal Suchanek 	.wr_table	= &axp152_writeable_table,
282d8d79f8fSMichal Suchanek 	.volatile_table	= &axp152_volatile_table,
283d8d79f8fSMichal Suchanek 	.max_register	= AXP152_PWM1_DUTY_CYCLE,
284d8d79f8fSMichal Suchanek 	.cache_type	= REGCACHE_RBTREE,
285d8d79f8fSMichal Suchanek };
286d8d79f8fSMichal Suchanek 
287cfb61a41SCarlo Caione static const struct regmap_config axp20x_regmap_config = {
288cfb61a41SCarlo Caione 	.reg_bits	= 8,
289cfb61a41SCarlo Caione 	.val_bits	= 8,
290cfb61a41SCarlo Caione 	.wr_table	= &axp20x_writeable_table,
291cfb61a41SCarlo Caione 	.volatile_table	= &axp20x_volatile_table,
292553ed4b5SBruno Prémont 	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
293cfb61a41SCarlo Caione 	.cache_type	= REGCACHE_RBTREE,
294cfb61a41SCarlo Caione };
295cfb61a41SCarlo Caione 
296f05be589SBoris BREZILLON static const struct regmap_config axp22x_regmap_config = {
297f05be589SBoris BREZILLON 	.reg_bits	= 8,
298f05be589SBoris BREZILLON 	.val_bits	= 8,
299f05be589SBoris BREZILLON 	.wr_table	= &axp22x_writeable_table,
300f05be589SBoris BREZILLON 	.volatile_table	= &axp22x_volatile_table,
301f05be589SBoris BREZILLON 	.max_register	= AXP22X_BATLOW_THRES1,
302f05be589SBoris BREZILLON 	.cache_type	= REGCACHE_RBTREE,
303f05be589SBoris BREZILLON };
304f05be589SBoris BREZILLON 
305af7e9069SJacob Pan static const struct regmap_config axp288_regmap_config = {
306af7e9069SJacob Pan 	.reg_bits	= 8,
307af7e9069SJacob Pan 	.val_bits	= 8,
308af7e9069SJacob Pan 	.wr_table	= &axp288_writeable_table,
309af7e9069SJacob Pan 	.volatile_table	= &axp288_volatile_table,
310af7e9069SJacob Pan 	.max_register	= AXP288_FG_TUNE5,
311af7e9069SJacob Pan 	.cache_type	= REGCACHE_RBTREE,
312af7e9069SJacob Pan };
313af7e9069SJacob Pan 
3148824ee85SChen-Yu Tsai static const struct regmap_config axp806_regmap_config = {
3158824ee85SChen-Yu Tsai 	.reg_bits	= 8,
3168824ee85SChen-Yu Tsai 	.val_bits	= 8,
3178824ee85SChen-Yu Tsai 	.wr_table	= &axp806_writeable_table,
3188824ee85SChen-Yu Tsai 	.volatile_table	= &axp806_volatile_table,
31934d9030bSChen-Yu Tsai 	.max_register	= AXP806_REG_ADDR_EXT,
3208824ee85SChen-Yu Tsai 	.cache_type	= REGCACHE_RBTREE,
3218824ee85SChen-Yu Tsai };
3228824ee85SChen-Yu Tsai 
323af7e9069SJacob Pan #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)			\
324af7e9069SJacob Pan 	[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
325cfb61a41SCarlo Caione 
326d8d79f8fSMichal Suchanek static const struct regmap_irq axp152_regmap_irqs[] = {
327d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, LDO0IN_CONNECT,		0, 6),
328d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, LDO0IN_REMOVAL,		0, 5),
329d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, ALDO0IN_CONNECT,	0, 3),
330d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, ALDO0IN_REMOVAL,	0, 2),
331d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW,		1, 5),
332d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW,		1, 4),
333d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW,		1, 3),
334d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW,		1, 2),
335d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, PEK_SHORT,		1, 1),
336d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, PEK_LONG,		1, 0),
337d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, TIMER,			2, 7),
338d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE,		2, 6),
339d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE,		2, 5),
340d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT,		2, 3),
341d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT,		2, 2),
342d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT,		2, 1),
343d8d79f8fSMichal Suchanek 	INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT,		2, 0),
344d8d79f8fSMichal Suchanek };
345d8d79f8fSMichal Suchanek 
346cfb61a41SCarlo Caione static const struct regmap_irq axp20x_regmap_irqs[] = {
347af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V,		0, 7),
348af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN,		0, 6),
349af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL,	        0, 5),
350af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V,		0, 4),
351af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN,		0, 3),
352af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL,	        0, 2),
353af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW,		0, 1),
354af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN,		1, 7),
355af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL,	        1, 6),
356af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE,	1, 5),
357af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE,	1, 4),
358af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, CHARG,		        1, 3),
359af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, CHARG_DONE,		1, 2),
360af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH,	        1, 1),
361af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW,	        1, 0),
362af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH,	        2, 7),
363af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW,		2, 6),
364af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG,	        2, 5),
365af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG,	        2, 4),
366af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG,	        2, 3),
367af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, PEK_SHORT,		2, 1),
368af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, PEK_LONG,		2, 0),
369af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON,		3, 7),
370af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF,	        3, 6),
371af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_VALID,		3, 5),
372af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID,	        3, 4),
373af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID,	3, 3),
374af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END,	        3, 2),
375af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1,	        3, 1),
376af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2,	        3, 0),
377af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, TIMER,		        4, 7),
378af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE,	        4, 6),
379af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE,	        4, 5),
380af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT,		4, 3),
381af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT,		4, 2),
382af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT,		4, 1),
383af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT,		4, 0),
384af7e9069SJacob Pan };
385af7e9069SJacob Pan 
386f05be589SBoris BREZILLON static const struct regmap_irq axp22x_regmap_irqs[] = {
387f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V,		0, 7),
388f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN,		0, 6),
389f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL,	        0, 5),
390f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V,		0, 4),
391f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN,		0, 3),
392f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL,	        0, 2),
393f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW,		0, 1),
394f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN,		1, 7),
395f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL,	        1, 6),
396f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE,	1, 5),
397f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE,	1, 4),
398f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, CHARG,		        1, 3),
399f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, CHARG_DONE,		1, 2),
400f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH,	        1, 1),
401f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW,	        1, 0),
402f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH,	        2, 7),
403f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, PEK_SHORT,		2, 1),
404f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, PEK_LONG,		2, 0),
405f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1,	        3, 1),
406f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2,	        3, 0),
407f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, TIMER,		        4, 7),
408f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE,	        4, 6),
409f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE,	        4, 5),
410f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT,		4, 1),
411f05be589SBoris BREZILLON 	INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT,		4, 0),
412f05be589SBoris BREZILLON };
413f05be589SBoris BREZILLON 
414af7e9069SJacob Pan /* some IRQs are compatible with axp20x models */
415af7e9069SJacob Pan static const struct regmap_irq axp288_regmap_irqs[] = {
416ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, VBUS_FALL,              0, 2),
417ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, VBUS_RISE,              0, 3),
418ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, OV,                     0, 4),
4198b44e678SHans de Goede 	INIT_REGMAP_IRQ(AXP288, FALLING_ALT,            0, 5),
4208b44e678SHans de Goede 	INIT_REGMAP_IRQ(AXP288, RISING_ALT,             0, 6),
4218b44e678SHans de Goede 	INIT_REGMAP_IRQ(AXP288, OV_ALT,                 0, 7),
422af7e9069SJacob Pan 
423ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, DONE,                   1, 2),
424ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, CHARGING,               1, 3),
425af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, SAFE_QUIT,              1, 4),
426af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, SAFE_ENTER,             1, 5),
427ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, ABSENT,                 1, 6),
428ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, APPEND,                 1, 7),
429af7e9069SJacob Pan 
430af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, QWBTU,                  2, 0),
431af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, WBTU,                   2, 1),
432af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, QWBTO,                  2, 2),
433ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, WBTO,                   2, 3),
434af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, QCBTU,                  2, 4),
435af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, CBTU,                   2, 5),
436af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, QCBTO,                  2, 6),
437af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, CBTO,                   2, 7),
438af7e9069SJacob Pan 
439af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, WL2,                    3, 0),
440af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, WL1,                    3, 1),
441af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, GPADC,                  3, 2),
442af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, OT,                     3, 7),
443af7e9069SJacob Pan 
444af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, GPIO0,                  4, 0),
445af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, GPIO1,                  4, 1),
446af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, POKO,                   4, 2),
447af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, POKL,                   4, 3),
448af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, POKS,                   4, 4),
449af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, POKN,                   4, 5),
450af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, POKP,                   4, 6),
451ff3bbc5cSJacob Pan 	INIT_REGMAP_IRQ(AXP288, TIMER,                  4, 7),
452af7e9069SJacob Pan 
453af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, MV_CHNG,                5, 0),
454af7e9069SJacob Pan 	INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
455cfb61a41SCarlo Caione };
456cfb61a41SCarlo Caione 
4578824ee85SChen-Yu Tsai static const struct regmap_irq axp806_regmap_irqs[] = {
4588824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1,	0, 0),
4598824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2,	0, 1),
4608824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW,		0, 3),
4618824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW,		0, 4),
4628824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW,		0, 5),
4638824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW,		0, 6),
4648824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW,		0, 7),
4658824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, PWROK_LONG,		1, 0),
4668824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, PWROK_SHORT,		1, 1),
4678824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, WAKEUP,			1, 4),
4688824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, PWROK_FALL,		1, 5),
4698824ee85SChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP806, PWROK_RISE,		1, 6),
4708824ee85SChen-Yu Tsai };
4718824ee85SChen-Yu Tsai 
47220147f0dSChen-Yu Tsai static const struct regmap_irq axp809_regmap_irqs[] = {
47320147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V,		0, 7),
47420147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN,		0, 6),
47520147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL,	        0, 5),
47620147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V,		0, 4),
47720147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN,		0, 3),
47820147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL,	        0, 2),
47920147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW,		0, 1),
48020147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN,		1, 7),
48120147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL,	        1, 6),
48220147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE,	1, 5),
48320147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE,	1, 4),
48420147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, CHARG,		        1, 3),
48520147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, CHARG_DONE,		1, 2),
48620147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH,	2, 7),
48720147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END,	2, 6),
48820147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW,	2, 5),
48920147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END,	2, 4),
49020147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH,	2, 3),
49120147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END,	2, 2),
49220147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW,	2, 1),
49320147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END,	2, 0),
49420147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH,	        3, 7),
49520147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1,	        3, 1),
49620147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2,	        3, 0),
49720147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, TIMER,		        4, 7),
49820147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE,	        4, 6),
49920147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE,	        4, 5),
50020147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, PEK_SHORT,		4, 4),
50120147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, PEK_LONG,		4, 3),
50220147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF,		4, 2),
50320147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT,		4, 1),
50420147f0dSChen-Yu Tsai 	INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT,		4, 0),
50520147f0dSChen-Yu Tsai };
50620147f0dSChen-Yu Tsai 
507d8d79f8fSMichal Suchanek static const struct regmap_irq_chip axp152_regmap_irq_chip = {
508d8d79f8fSMichal Suchanek 	.name			= "axp152_irq_chip",
509d8d79f8fSMichal Suchanek 	.status_base		= AXP152_IRQ1_STATE,
510d8d79f8fSMichal Suchanek 	.ack_base		= AXP152_IRQ1_STATE,
511d8d79f8fSMichal Suchanek 	.mask_base		= AXP152_IRQ1_EN,
512d8d79f8fSMichal Suchanek 	.mask_invert		= true,
513d8d79f8fSMichal Suchanek 	.init_ack_masked	= true,
514d8d79f8fSMichal Suchanek 	.irqs			= axp152_regmap_irqs,
515d8d79f8fSMichal Suchanek 	.num_irqs		= ARRAY_SIZE(axp152_regmap_irqs),
516d8d79f8fSMichal Suchanek 	.num_regs		= 3,
517d8d79f8fSMichal Suchanek };
518d8d79f8fSMichal Suchanek 
519cfb61a41SCarlo Caione static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
520cfb61a41SCarlo Caione 	.name			= "axp20x_irq_chip",
521cfb61a41SCarlo Caione 	.status_base		= AXP20X_IRQ1_STATE,
522cfb61a41SCarlo Caione 	.ack_base		= AXP20X_IRQ1_STATE,
523cfb61a41SCarlo Caione 	.mask_base		= AXP20X_IRQ1_EN,
524cfb61a41SCarlo Caione 	.mask_invert		= true,
525cfb61a41SCarlo Caione 	.init_ack_masked	= true,
526af7e9069SJacob Pan 	.irqs			= axp20x_regmap_irqs,
527af7e9069SJacob Pan 	.num_irqs		= ARRAY_SIZE(axp20x_regmap_irqs),
528af7e9069SJacob Pan 	.num_regs		= 5,
529af7e9069SJacob Pan 
530af7e9069SJacob Pan };
531af7e9069SJacob Pan 
532f05be589SBoris BREZILLON static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
533f05be589SBoris BREZILLON 	.name			= "axp22x_irq_chip",
534f05be589SBoris BREZILLON 	.status_base		= AXP20X_IRQ1_STATE,
535f05be589SBoris BREZILLON 	.ack_base		= AXP20X_IRQ1_STATE,
536f05be589SBoris BREZILLON 	.mask_base		= AXP20X_IRQ1_EN,
537f05be589SBoris BREZILLON 	.mask_invert		= true,
538f05be589SBoris BREZILLON 	.init_ack_masked	= true,
539f05be589SBoris BREZILLON 	.irqs			= axp22x_regmap_irqs,
540f05be589SBoris BREZILLON 	.num_irqs		= ARRAY_SIZE(axp22x_regmap_irqs),
541f05be589SBoris BREZILLON 	.num_regs		= 5,
542f05be589SBoris BREZILLON };
543f05be589SBoris BREZILLON 
544af7e9069SJacob Pan static const struct regmap_irq_chip axp288_regmap_irq_chip = {
545af7e9069SJacob Pan 	.name			= "axp288_irq_chip",
546af7e9069SJacob Pan 	.status_base		= AXP20X_IRQ1_STATE,
547af7e9069SJacob Pan 	.ack_base		= AXP20X_IRQ1_STATE,
548af7e9069SJacob Pan 	.mask_base		= AXP20X_IRQ1_EN,
549af7e9069SJacob Pan 	.mask_invert		= true,
550af7e9069SJacob Pan 	.init_ack_masked	= true,
551af7e9069SJacob Pan 	.irqs			= axp288_regmap_irqs,
552af7e9069SJacob Pan 	.num_irqs		= ARRAY_SIZE(axp288_regmap_irqs),
553af7e9069SJacob Pan 	.num_regs		= 6,
554af7e9069SJacob Pan 
555cfb61a41SCarlo Caione };
556cfb61a41SCarlo Caione 
5578824ee85SChen-Yu Tsai static const struct regmap_irq_chip axp806_regmap_irq_chip = {
5588824ee85SChen-Yu Tsai 	.name			= "axp806",
5598824ee85SChen-Yu Tsai 	.status_base		= AXP20X_IRQ1_STATE,
5608824ee85SChen-Yu Tsai 	.ack_base		= AXP20X_IRQ1_STATE,
5618824ee85SChen-Yu Tsai 	.mask_base		= AXP20X_IRQ1_EN,
5628824ee85SChen-Yu Tsai 	.mask_invert		= true,
5638824ee85SChen-Yu Tsai 	.init_ack_masked	= true,
5648824ee85SChen-Yu Tsai 	.irqs			= axp806_regmap_irqs,
5658824ee85SChen-Yu Tsai 	.num_irqs		= ARRAY_SIZE(axp806_regmap_irqs),
5668824ee85SChen-Yu Tsai 	.num_regs		= 2,
5678824ee85SChen-Yu Tsai };
5688824ee85SChen-Yu Tsai 
56920147f0dSChen-Yu Tsai static const struct regmap_irq_chip axp809_regmap_irq_chip = {
57020147f0dSChen-Yu Tsai 	.name			= "axp809",
57120147f0dSChen-Yu Tsai 	.status_base		= AXP20X_IRQ1_STATE,
57220147f0dSChen-Yu Tsai 	.ack_base		= AXP20X_IRQ1_STATE,
57320147f0dSChen-Yu Tsai 	.mask_base		= AXP20X_IRQ1_EN,
57420147f0dSChen-Yu Tsai 	.mask_invert		= true,
57520147f0dSChen-Yu Tsai 	.init_ack_masked	= true,
57620147f0dSChen-Yu Tsai 	.irqs			= axp809_regmap_irqs,
57720147f0dSChen-Yu Tsai 	.num_irqs		= ARRAY_SIZE(axp809_regmap_irqs),
57820147f0dSChen-Yu Tsai 	.num_regs		= 5,
57920147f0dSChen-Yu Tsai };
58020147f0dSChen-Yu Tsai 
581cfb61a41SCarlo Caione static struct mfd_cell axp20x_cells[] = {
582cfb61a41SCarlo Caione 	{
583b419c16bSMaxime Ripard 		.name		= "axp20x-gpio",
584b419c16bSMaxime Ripard 		.of_compatible	= "x-powers,axp209-gpio",
585b419c16bSMaxime Ripard 	}, {
586cfb61a41SCarlo Caione 		.name		= "axp20x-pek",
587cfb61a41SCarlo Caione 		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
588cfb61a41SCarlo Caione 		.resources	= axp20x_pek_resources,
589cfb61a41SCarlo Caione 	}, {
590cfb61a41SCarlo Caione 		.name		= "axp20x-regulator",
5918de4efdaSHans de Goede 	}, {
592cd7cf27bSMichael Haas 		.name		= "axp20x-ac-power-supply",
593cd7cf27bSMichael Haas 		.of_compatible	= "x-powers,axp202-ac-power-supply",
594cd7cf27bSMichael Haas 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
595cd7cf27bSMichael Haas 		.resources	= axp20x_ac_power_supply_resources,
596cd7cf27bSMichael Haas 	}, {
5978de4efdaSHans de Goede 		.name		= "axp20x-usb-power-supply",
5988de4efdaSHans de Goede 		.of_compatible	= "x-powers,axp202-usb-power-supply",
5998de4efdaSHans de Goede 		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
6008de4efdaSHans de Goede 		.resources	= axp20x_usb_power_supply_resources,
601cfb61a41SCarlo Caione 	},
602cfb61a41SCarlo Caione };
603cfb61a41SCarlo Caione 
6044c650561SQuentin Schulz static struct mfd_cell axp221_cells[] = {
605f05be589SBoris BREZILLON 	{
606f05be589SBoris BREZILLON 		.name		= "axp20x-pek",
607f05be589SBoris BREZILLON 		.num_resources	= ARRAY_SIZE(axp22x_pek_resources),
608f05be589SBoris BREZILLON 		.resources	= axp22x_pek_resources,
6096d4fa89dSChen-Yu Tsai 	}, {
6106d4fa89dSChen-Yu Tsai 		.name		= "axp20x-regulator",
611ecd98cceSHans de Goede 	}, {
612ecd98cceSHans de Goede 		.name		= "axp20x-usb-power-supply",
613ecd98cceSHans de Goede 		.of_compatible	= "x-powers,axp221-usb-power-supply",
614ecd98cceSHans de Goede 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
615ecd98cceSHans de Goede 		.resources	= axp22x_usb_power_supply_resources,
616f05be589SBoris BREZILLON 	},
617f05be589SBoris BREZILLON };
618f05be589SBoris BREZILLON 
6194c650561SQuentin Schulz static struct mfd_cell axp223_cells[] = {
6204c650561SQuentin Schulz 	{
6214c650561SQuentin Schulz 		.name			= "axp20x-pek",
6224c650561SQuentin Schulz 		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
6234c650561SQuentin Schulz 		.resources		= axp22x_pek_resources,
6244c650561SQuentin Schulz 	}, {
6254c650561SQuentin Schulz 		.name			= "axp20x-regulator",
6264c650561SQuentin Schulz 	}, {
6274c650561SQuentin Schulz 		.name		= "axp20x-usb-power-supply",
6284c650561SQuentin Schulz 		.of_compatible	= "x-powers,axp223-usb-power-supply",
6294c650561SQuentin Schulz 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
6304c650561SQuentin Schulz 		.resources	= axp22x_usb_power_supply_resources,
6314c650561SQuentin Schulz 	},
6324c650561SQuentin Schulz };
6334c650561SQuentin Schulz 
634d8d79f8fSMichal Suchanek static struct mfd_cell axp152_cells[] = {
635d8d79f8fSMichal Suchanek 	{
636d8d79f8fSMichal Suchanek 		.name			= "axp20x-pek",
637d8d79f8fSMichal Suchanek 		.num_resources		= ARRAY_SIZE(axp152_pek_resources),
638d8d79f8fSMichal Suchanek 		.resources		= axp152_pek_resources,
639d8d79f8fSMichal Suchanek 	},
640d8d79f8fSMichal Suchanek };
641d8d79f8fSMichal Suchanek 
642af7e9069SJacob Pan static struct resource axp288_adc_resources[] = {
643af7e9069SJacob Pan 	{
644af7e9069SJacob Pan 		.name  = "GPADC",
645af7e9069SJacob Pan 		.start = AXP288_IRQ_GPADC,
646af7e9069SJacob Pan 		.end   = AXP288_IRQ_GPADC,
647af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
648af7e9069SJacob Pan 	},
649af7e9069SJacob Pan };
650af7e9069SJacob Pan 
651bdb01f78SRamakrishna Pallala static struct resource axp288_extcon_resources[] = {
652bdb01f78SRamakrishna Pallala 	{
653bdb01f78SRamakrishna Pallala 		.start = AXP288_IRQ_VBUS_FALL,
654bdb01f78SRamakrishna Pallala 		.end   = AXP288_IRQ_VBUS_FALL,
655bdb01f78SRamakrishna Pallala 		.flags = IORESOURCE_IRQ,
656bdb01f78SRamakrishna Pallala 	},
657bdb01f78SRamakrishna Pallala 	{
658bdb01f78SRamakrishna Pallala 		.start = AXP288_IRQ_VBUS_RISE,
659bdb01f78SRamakrishna Pallala 		.end   = AXP288_IRQ_VBUS_RISE,
660bdb01f78SRamakrishna Pallala 		.flags = IORESOURCE_IRQ,
661bdb01f78SRamakrishna Pallala 	},
662bdb01f78SRamakrishna Pallala 	{
663bdb01f78SRamakrishna Pallala 		.start = AXP288_IRQ_MV_CHNG,
664bdb01f78SRamakrishna Pallala 		.end   = AXP288_IRQ_MV_CHNG,
665bdb01f78SRamakrishna Pallala 		.flags = IORESOURCE_IRQ,
666bdb01f78SRamakrishna Pallala 	},
667bdb01f78SRamakrishna Pallala 	{
668bdb01f78SRamakrishna Pallala 		.start = AXP288_IRQ_BC_USB_CHNG,
669bdb01f78SRamakrishna Pallala 		.end   = AXP288_IRQ_BC_USB_CHNG,
670bdb01f78SRamakrishna Pallala 		.flags = IORESOURCE_IRQ,
671bdb01f78SRamakrishna Pallala 	},
672bdb01f78SRamakrishna Pallala };
673bdb01f78SRamakrishna Pallala 
674af7e9069SJacob Pan static struct resource axp288_charger_resources[] = {
675af7e9069SJacob Pan 	{
676af7e9069SJacob Pan 		.start = AXP288_IRQ_OV,
677af7e9069SJacob Pan 		.end   = AXP288_IRQ_OV,
678af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
679af7e9069SJacob Pan 	},
680af7e9069SJacob Pan 	{
681af7e9069SJacob Pan 		.start = AXP288_IRQ_DONE,
682af7e9069SJacob Pan 		.end   = AXP288_IRQ_DONE,
683af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
684af7e9069SJacob Pan 	},
685af7e9069SJacob Pan 	{
686af7e9069SJacob Pan 		.start = AXP288_IRQ_CHARGING,
687af7e9069SJacob Pan 		.end   = AXP288_IRQ_CHARGING,
688af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
689af7e9069SJacob Pan 	},
690af7e9069SJacob Pan 	{
691af7e9069SJacob Pan 		.start = AXP288_IRQ_SAFE_QUIT,
692af7e9069SJacob Pan 		.end   = AXP288_IRQ_SAFE_QUIT,
693af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
694af7e9069SJacob Pan 	},
695af7e9069SJacob Pan 	{
696af7e9069SJacob Pan 		.start = AXP288_IRQ_SAFE_ENTER,
697af7e9069SJacob Pan 		.end   = AXP288_IRQ_SAFE_ENTER,
698af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
699af7e9069SJacob Pan 	},
700af7e9069SJacob Pan 	{
701af7e9069SJacob Pan 		.start = AXP288_IRQ_QCBTU,
702af7e9069SJacob Pan 		.end   = AXP288_IRQ_QCBTU,
703af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
704af7e9069SJacob Pan 	},
705af7e9069SJacob Pan 	{
706af7e9069SJacob Pan 		.start = AXP288_IRQ_CBTU,
707af7e9069SJacob Pan 		.end   = AXP288_IRQ_CBTU,
708af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
709af7e9069SJacob Pan 	},
710af7e9069SJacob Pan 	{
711af7e9069SJacob Pan 		.start = AXP288_IRQ_QCBTO,
712af7e9069SJacob Pan 		.end   = AXP288_IRQ_QCBTO,
713af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
714af7e9069SJacob Pan 	},
715af7e9069SJacob Pan 	{
716af7e9069SJacob Pan 		.start = AXP288_IRQ_CBTO,
717af7e9069SJacob Pan 		.end   = AXP288_IRQ_CBTO,
718af7e9069SJacob Pan 		.flags = IORESOURCE_IRQ,
719af7e9069SJacob Pan 	},
720af7e9069SJacob Pan };
721af7e9069SJacob Pan 
722af7e9069SJacob Pan static struct mfd_cell axp288_cells[] = {
723af7e9069SJacob Pan 	{
724af7e9069SJacob Pan 		.name = "axp288_adc",
725af7e9069SJacob Pan 		.num_resources = ARRAY_SIZE(axp288_adc_resources),
726af7e9069SJacob Pan 		.resources = axp288_adc_resources,
727af7e9069SJacob Pan 	},
728af7e9069SJacob Pan 	{
729bdb01f78SRamakrishna Pallala 		.name = "axp288_extcon",
730bdb01f78SRamakrishna Pallala 		.num_resources = ARRAY_SIZE(axp288_extcon_resources),
731bdb01f78SRamakrishna Pallala 		.resources = axp288_extcon_resources,
732bdb01f78SRamakrishna Pallala 	},
733bdb01f78SRamakrishna Pallala 	{
734af7e9069SJacob Pan 		.name = "axp288_charger",
735af7e9069SJacob Pan 		.num_resources = ARRAY_SIZE(axp288_charger_resources),
736af7e9069SJacob Pan 		.resources = axp288_charger_resources,
737af7e9069SJacob Pan 	},
738af7e9069SJacob Pan 	{
739d6387874STodd Brandt 		.name = "axp288_fuel_gauge",
740d6387874STodd Brandt 		.num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources),
741d6387874STodd Brandt 		.resources = axp288_fuel_gauge_resources,
742af7e9069SJacob Pan 	},
743d8139f63SAaron Lu 	{
744e56e5ad6SBorun Fu 		.name = "axp20x-pek",
745e56e5ad6SBorun Fu 		.num_resources = ARRAY_SIZE(axp288_power_button_resources),
746e56e5ad6SBorun Fu 		.resources = axp288_power_button_resources,
747e56e5ad6SBorun Fu 	},
748e56e5ad6SBorun Fu 	{
749d8139f63SAaron Lu 		.name = "axp288_pmic_acpi",
750d8139f63SAaron Lu 	},
751af7e9069SJacob Pan };
752af7e9069SJacob Pan 
7538824ee85SChen-Yu Tsai static struct mfd_cell axp806_cells[] = {
7548824ee85SChen-Yu Tsai 	{
7558824ee85SChen-Yu Tsai 		.id			= 2,
7568824ee85SChen-Yu Tsai 		.name			= "axp20x-regulator",
7578824ee85SChen-Yu Tsai 	},
7588824ee85SChen-Yu Tsai };
7598824ee85SChen-Yu Tsai 
76020147f0dSChen-Yu Tsai static struct mfd_cell axp809_cells[] = {
76120147f0dSChen-Yu Tsai 	{
76220147f0dSChen-Yu Tsai 		.name			= "axp20x-pek",
76320147f0dSChen-Yu Tsai 		.num_resources		= ARRAY_SIZE(axp809_pek_resources),
76420147f0dSChen-Yu Tsai 		.resources		= axp809_pek_resources,
76520147f0dSChen-Yu Tsai 	}, {
7668824ee85SChen-Yu Tsai 		.id			= 1,
76720147f0dSChen-Yu Tsai 		.name			= "axp20x-regulator",
76820147f0dSChen-Yu Tsai 	},
76920147f0dSChen-Yu Tsai };
77020147f0dSChen-Yu Tsai 
771cfb61a41SCarlo Caione static struct axp20x_dev *axp20x_pm_power_off;
772cfb61a41SCarlo Caione static void axp20x_power_off(void)
773cfb61a41SCarlo Caione {
774af7e9069SJacob Pan 	if (axp20x_pm_power_off->variant == AXP288_ID)
775af7e9069SJacob Pan 		return;
776af7e9069SJacob Pan 
777cfb61a41SCarlo Caione 	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
778cfb61a41SCarlo Caione 		     AXP20X_OFF);
779179dc63dSHans de Goede 
780179dc63dSHans de Goede 	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
781179dc63dSHans de Goede 	msleep(500);
782cfb61a41SCarlo Caione }
783cfb61a41SCarlo Caione 
7844fd41151SChen-Yu Tsai int axp20x_match_device(struct axp20x_dev *axp20x)
785af7e9069SJacob Pan {
786e47a3cf7SChen-Yu Tsai 	struct device *dev = axp20x->dev;
787af7e9069SJacob Pan 	const struct acpi_device_id *acpi_id;
788af7e9069SJacob Pan 	const struct of_device_id *of_id;
789af7e9069SJacob Pan 
790af7e9069SJacob Pan 	if (dev->of_node) {
791af7acc3dSChen-Yu Tsai 		of_id = of_match_device(dev->driver->of_match_table, dev);
792af7e9069SJacob Pan 		if (!of_id) {
793af7e9069SJacob Pan 			dev_err(dev, "Unable to match OF ID\n");
794af7e9069SJacob Pan 			return -ENODEV;
795af7e9069SJacob Pan 		}
796af7e9069SJacob Pan 		axp20x->variant = (long)of_id->data;
797af7e9069SJacob Pan 	} else {
798af7e9069SJacob Pan 		acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
799af7e9069SJacob Pan 		if (!acpi_id || !acpi_id->driver_data) {
800af7e9069SJacob Pan 			dev_err(dev, "Unable to match ACPI ID and data\n");
801af7e9069SJacob Pan 			return -ENODEV;
802af7e9069SJacob Pan 		}
803af7e9069SJacob Pan 		axp20x->variant = (long)acpi_id->driver_data;
804af7e9069SJacob Pan 	}
805af7e9069SJacob Pan 
806af7e9069SJacob Pan 	switch (axp20x->variant) {
807d8d79f8fSMichal Suchanek 	case AXP152_ID:
808d8d79f8fSMichal Suchanek 		axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
809d8d79f8fSMichal Suchanek 		axp20x->cells = axp152_cells;
810d8d79f8fSMichal Suchanek 		axp20x->regmap_cfg = &axp152_regmap_config;
811d8d79f8fSMichal Suchanek 		axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
812d8d79f8fSMichal Suchanek 		break;
813af7e9069SJacob Pan 	case AXP202_ID:
814af7e9069SJacob Pan 	case AXP209_ID:
815af7e9069SJacob Pan 		axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
816af7e9069SJacob Pan 		axp20x->cells = axp20x_cells;
817af7e9069SJacob Pan 		axp20x->regmap_cfg = &axp20x_regmap_config;
818af7e9069SJacob Pan 		axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
819af7e9069SJacob Pan 		break;
820f05be589SBoris BREZILLON 	case AXP221_ID:
8214c650561SQuentin Schulz 		axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
8224c650561SQuentin Schulz 		axp20x->cells = axp221_cells;
8234c650561SQuentin Schulz 		axp20x->regmap_cfg = &axp22x_regmap_config;
8244c650561SQuentin Schulz 		axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
8254c650561SQuentin Schulz 		break;
82602071f0fSChen-Yu Tsai 	case AXP223_ID:
8274c650561SQuentin Schulz 		axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
8284c650561SQuentin Schulz 		axp20x->cells = axp223_cells;
829f05be589SBoris BREZILLON 		axp20x->regmap_cfg = &axp22x_regmap_config;
830f05be589SBoris BREZILLON 		axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
831f05be589SBoris BREZILLON 		break;
832af7e9069SJacob Pan 	case AXP288_ID:
833af7e9069SJacob Pan 		axp20x->cells = axp288_cells;
834af7e9069SJacob Pan 		axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
835af7e9069SJacob Pan 		axp20x->regmap_cfg = &axp288_regmap_config;
836af7e9069SJacob Pan 		axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
8370a5454c9SHans de Goede 		axp20x->irq_flags = IRQF_TRIGGER_LOW;
838af7e9069SJacob Pan 		break;
8398824ee85SChen-Yu Tsai 	case AXP806_ID:
8408824ee85SChen-Yu Tsai 		axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
8418824ee85SChen-Yu Tsai 		axp20x->cells = axp806_cells;
8428824ee85SChen-Yu Tsai 		axp20x->regmap_cfg = &axp806_regmap_config;
8438824ee85SChen-Yu Tsai 		axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
8448824ee85SChen-Yu Tsai 		break;
84520147f0dSChen-Yu Tsai 	case AXP809_ID:
84620147f0dSChen-Yu Tsai 		axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
84720147f0dSChen-Yu Tsai 		axp20x->cells = axp809_cells;
84820147f0dSChen-Yu Tsai 		axp20x->regmap_cfg = &axp22x_regmap_config;
84920147f0dSChen-Yu Tsai 		axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
85020147f0dSChen-Yu Tsai 		break;
851af7e9069SJacob Pan 	default:
852af7e9069SJacob Pan 		dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
853af7e9069SJacob Pan 		return -EINVAL;
854af7e9069SJacob Pan 	}
855af7e9069SJacob Pan 	dev_info(dev, "AXP20x variant %s found\n",
856af7e9069SJacob Pan 		 axp20x_model_names[axp20x->variant]);
857af7e9069SJacob Pan 
858af7e9069SJacob Pan 	return 0;
859af7e9069SJacob Pan }
8604fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_match_device);
861af7e9069SJacob Pan 
8624fd41151SChen-Yu Tsai int axp20x_device_probe(struct axp20x_dev *axp20x)
863cfb61a41SCarlo Caione {
864cfb61a41SCarlo Caione 	int ret;
865cfb61a41SCarlo Caione 
866696f0b3fSChen-Yu Tsai 	/*
867696f0b3fSChen-Yu Tsai 	 * The AXP806 supports either master/standalone or slave mode.
868696f0b3fSChen-Yu Tsai 	 * Slave mode allows sharing the serial bus, even with multiple
869696f0b3fSChen-Yu Tsai 	 * AXP806 which all have the same hardware address.
870696f0b3fSChen-Yu Tsai 	 *
871696f0b3fSChen-Yu Tsai 	 * This is done with extra "serial interface address extension",
872696f0b3fSChen-Yu Tsai 	 * or AXP806_BUS_ADDR_EXT, and "register address extension", or
873696f0b3fSChen-Yu Tsai 	 * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
874696f0b3fSChen-Yu Tsai 	 * 1 bit customizable at the factory, and 1 bit depending on the
875696f0b3fSChen-Yu Tsai 	 * state of an external pin. The latter is writable. The device
876696f0b3fSChen-Yu Tsai 	 * will only respond to operations to its other registers when
877696f0b3fSChen-Yu Tsai 	 * the these device addressing bits (in the upper 4 bits of the
878696f0b3fSChen-Yu Tsai 	 * registers) match.
879696f0b3fSChen-Yu Tsai 	 *
880696f0b3fSChen-Yu Tsai 	 * Since we only support an AXP806 chained to an AXP809 in slave
881696f0b3fSChen-Yu Tsai 	 * mode, and there isn't any existing hardware which uses AXP806
882696f0b3fSChen-Yu Tsai 	 * in master mode, or has 2 AXP806s in the same system, we can
883696f0b3fSChen-Yu Tsai 	 * just program the register address extension to the slave mode
884696f0b3fSChen-Yu Tsai 	 * address.
885696f0b3fSChen-Yu Tsai 	 */
886696f0b3fSChen-Yu Tsai 	if (axp20x->variant == AXP806_ID)
887696f0b3fSChen-Yu Tsai 		regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
888696f0b3fSChen-Yu Tsai 			     AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
889696f0b3fSChen-Yu Tsai 
8904fd41151SChen-Yu Tsai 	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
8910a5454c9SHans de Goede 			  IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
8920a5454c9SHans de Goede 			   -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc);
893cfb61a41SCarlo Caione 	if (ret) {
8944fd41151SChen-Yu Tsai 		dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret);
895cfb61a41SCarlo Caione 		return ret;
896cfb61a41SCarlo Caione 	}
897cfb61a41SCarlo Caione 
898af7e9069SJacob Pan 	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
899af7e9069SJacob Pan 			      axp20x->nr_cells, NULL, 0, NULL);
900cfb61a41SCarlo Caione 
901cfb61a41SCarlo Caione 	if (ret) {
9024fd41151SChen-Yu Tsai 		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
9034fd41151SChen-Yu Tsai 		regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
904cfb61a41SCarlo Caione 		return ret;
905cfb61a41SCarlo Caione 	}
906cfb61a41SCarlo Caione 
907cfb61a41SCarlo Caione 	if (!pm_power_off) {
908cfb61a41SCarlo Caione 		axp20x_pm_power_off = axp20x;
909cfb61a41SCarlo Caione 		pm_power_off = axp20x_power_off;
910cfb61a41SCarlo Caione 	}
911cfb61a41SCarlo Caione 
9124fd41151SChen-Yu Tsai 	dev_info(axp20x->dev, "AXP20X driver loaded\n");
913cfb61a41SCarlo Caione 
914cfb61a41SCarlo Caione 	return 0;
915cfb61a41SCarlo Caione }
9164fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_device_probe);
917cfb61a41SCarlo Caione 
9184fd41151SChen-Yu Tsai int axp20x_device_remove(struct axp20x_dev *axp20x)
919cfb61a41SCarlo Caione {
920cfb61a41SCarlo Caione 	if (axp20x == axp20x_pm_power_off) {
921cfb61a41SCarlo Caione 		axp20x_pm_power_off = NULL;
922cfb61a41SCarlo Caione 		pm_power_off = NULL;
923cfb61a41SCarlo Caione 	}
924cfb61a41SCarlo Caione 
925cfb61a41SCarlo Caione 	mfd_remove_devices(axp20x->dev);
9264fd41151SChen-Yu Tsai 	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
927cfb61a41SCarlo Caione 
928cfb61a41SCarlo Caione 	return 0;
929cfb61a41SCarlo Caione }
9304fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_device_remove);
931cfb61a41SCarlo Caione 
932cfb61a41SCarlo Caione MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
933cfb61a41SCarlo Caione MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
934cfb61a41SCarlo Caione MODULE_LICENSE("GPL");
935