cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

axp20x.c (35538B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * MFD core driver for the X-Powers' Power Management ICs
      4 *
      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.
      8 *
      9 * This file contains the interface independent core functions.
     10 *
     11 * Copyright (C) 2014 Carlo Caione
     12 *
     13 * Author: Carlo Caione <carlo@caione.org>
     14 */
     15
     16#include <linux/acpi.h>
     17#include <linux/bitops.h>
     18#include <linux/delay.h>
     19#include <linux/err.h>
     20#include <linux/interrupt.h>
     21#include <linux/kernel.h>
     22#include <linux/mfd/axp20x.h>
     23#include <linux/mfd/core.h>
     24#include <linux/module.h>
     25#include <linux/of_device.h>
     26#include <linux/pm_runtime.h>
     27#include <linux/regmap.h>
     28#include <linux/regulator/consumer.h>
     29
     30#define AXP20X_OFF	BIT(7)
     31
     32#define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE	0
     33#define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE	BIT(4)
     34
     35static const char * const axp20x_model_names[] = {
     36	"AXP152",
     37	"AXP202",
     38	"AXP209",
     39	"AXP221",
     40	"AXP223",
     41	"AXP288",
     42	"AXP803",
     43	"AXP806",
     44	"AXP809",
     45	"AXP813",
     46};
     47
     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
     69static const struct regmap_range axp20x_writeable_ranges[] = {
     70	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
     71	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
     72	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
     73	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
     74};
     75
     76static const struct regmap_range axp20x_volatile_ranges[] = {
     77	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
     78	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
     79	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
     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),
     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
     95/* AXP22x ranges are shared with the AXP809, as they cover the same range */
     96static const struct regmap_range axp22x_writeable_ranges[] = {
     97	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
     98	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP22X_CHRG_CTRL3),
     99	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
    100};
    101
    102static const struct regmap_range axp22x_volatile_ranges[] = {
    103	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
    104	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
    105	regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
    106	regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L),
    107	regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
    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
    120/* AXP288 ranges are shared with the AXP803, as they cover the same range */
    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[] = {
    127	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
    128	regmap_reg_range(AXP22X_PWR_OUT_CTRL1, AXP22X_ALDO3_V_OUT),
    129	regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
    130	regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
    131	regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
    132	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
    133	regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
    134	regmap_reg_range(AXP20X_GPIO1_CTRL, AXP22X_GPIO_STATE),
    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),
    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
    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),
    154	regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
    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
    171static const struct resource axp152_pek_resources[] = {
    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
    176static const struct resource axp20x_ac_power_supply_resources[] = {
    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
    182static const struct resource axp20x_pek_resources[] = {
    183	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
    184	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
    185};
    186
    187static const struct resource axp20x_usb_power_supply_resources[] = {
    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
    194static const struct resource axp22x_usb_power_supply_resources[] = {
    195	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
    196	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
    197};
    198
    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
    205static const struct resource axp22x_pek_resources[] = {
    206	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
    207	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
    208};
    209
    210static const struct resource axp288_power_button_resources[] = {
    211	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"),
    212	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"),
    213};
    214
    215static const struct resource axp288_fuel_gauge_resources[] = {
    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),
    222};
    223
    224static const struct resource axp803_pek_resources[] = {
    225	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
    226	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
    227};
    228
    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
    234static const struct resource axp809_pek_resources[] = {
    235	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
    236	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
    237};
    238
    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
    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,
    253	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
    254	.cache_type	= REGCACHE_RBTREE,
    255};
    256
    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
    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
    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,
    280	.max_register	= AXP806_REG_ADDR_EXT,
    281	.cache_type	= REGCACHE_RBTREE,
    282};
    283
    284#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)			\
    285	[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
    286
    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
    307static const struct regmap_irq axp20x_regmap_irqs[] = {
    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
    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
    375/* some IRQs are compatible with axp20x models */
    376static const struct regmap_irq axp288_regmap_irqs[] = {
    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),
    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),
    383
    384	INIT_REGMAP_IRQ(AXP288, DONE,                   1, 2),
    385	INIT_REGMAP_IRQ(AXP288, CHARGING,               1, 3),
    386	INIT_REGMAP_IRQ(AXP288, SAFE_QUIT,              1, 4),
    387	INIT_REGMAP_IRQ(AXP288, SAFE_ENTER,             1, 5),
    388	INIT_REGMAP_IRQ(AXP288, ABSENT,                 1, 6),
    389	INIT_REGMAP_IRQ(AXP288, APPEND,                 1, 7),
    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),
    394	INIT_REGMAP_IRQ(AXP288, WBTO,                   2, 3),
    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),
    412	INIT_REGMAP_IRQ(AXP288, TIMER,                  4, 7),
    413
    414	INIT_REGMAP_IRQ(AXP288, MV_CHNG,                5, 0),
    415	INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
    416};
    417
    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
    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),
    463	INIT_REGMAP_IRQ(AXP806, POK_LONG,		1, 0),
    464	INIT_REGMAP_IRQ(AXP806, POK_SHORT,		1, 1),
    465	INIT_REGMAP_IRQ(AXP806, WAKEUP,			1, 4),
    466	INIT_REGMAP_IRQ(AXP806, POK_FALL,		1, 5),
    467	INIT_REGMAP_IRQ(AXP806, POK_RISE,		1, 6),
    468};
    469
    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
    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
    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,
    522	.mask_invert		= true,
    523	.init_ack_masked	= true,
    524	.irqs			= axp20x_regmap_irqs,
    525	.num_irqs		= ARRAY_SIZE(axp20x_regmap_irqs),
    526	.num_regs		= 5,
    527
    528};
    529
    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
    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,
    547	.mask_invert		= true,
    548	.init_ack_masked	= true,
    549	.irqs			= axp288_regmap_irqs,
    550	.num_irqs		= ARRAY_SIZE(axp288_regmap_irqs),
    551	.num_regs		= 6,
    552
    553};
    554
    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
    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
    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
    591static const struct mfd_cell axp20x_cells[] = {
    592	{
    593		.name		= "axp20x-gpio",
    594		.of_compatible	= "x-powers,axp209-gpio",
    595	}, {
    596		.name		= "axp20x-pek",
    597		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
    598		.resources	= axp20x_pek_resources,
    599	}, {
    600		.name		= "axp20x-regulator",
    601	}, {
    602		.name		= "axp20x-adc",
    603		.of_compatible	= "x-powers,axp209-adc",
    604	}, {
    605		.name		= "axp20x-battery-power-supply",
    606		.of_compatible	= "x-powers,axp209-battery-power-supply",
    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,
    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,
    617	},
    618};
    619
    620static const struct mfd_cell axp221_cells[] = {
    621	{
    622		.name		= "axp221-pek",
    623		.num_resources	= ARRAY_SIZE(axp22x_pek_resources),
    624		.resources	= axp22x_pek_resources,
    625	}, {
    626		.name		= "axp20x-regulator",
    627	}, {
    628		.name		= "axp22x-adc",
    629		.of_compatible	= "x-powers,axp221-adc",
    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,
    635	}, {
    636		.name		= "axp20x-battery-power-supply",
    637		.of_compatible	= "x-powers,axp221-battery-power-supply",
    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
    646static const struct mfd_cell axp223_cells[] = {
    647	{
    648		.name		= "axp221-pek",
    649		.num_resources	= ARRAY_SIZE(axp22x_pek_resources),
    650		.resources	= axp22x_pek_resources,
    651	}, {
    652		.name		= "axp22x-adc",
    653		.of_compatible	= "x-powers,axp221-adc",
    654	}, {
    655		.name		= "axp20x-battery-power-supply",
    656		.of_compatible	= "x-powers,axp221-battery-power-supply",
    657	}, {
    658		.name		= "axp20x-regulator",
    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,
    664	}, {
    665		.name		= "axp20x-usb-power-supply",
    666		.of_compatible	= "x-powers,axp223-usb-power-supply",
    667		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
    668		.resources	= axp22x_usb_power_supply_resources,
    669	},
    670};
    671
    672static const struct mfd_cell axp152_cells[] = {
    673	{
    674		.name		= "axp20x-pek",
    675		.num_resources	= ARRAY_SIZE(axp152_pek_resources),
    676		.resources	= axp152_pek_resources,
    677	},
    678};
    679
    680static const struct resource axp288_adc_resources[] = {
    681	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
    682};
    683
    684static const struct resource axp288_extcon_resources[] = {
    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),
    689};
    690
    691static const struct resource axp288_charger_resources[] = {
    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),
    701};
    702
    703static const char * const axp288_fuel_gauge_suppliers[] = { "axp288_charger" };
    704
    705static const struct property_entry axp288_fuel_gauge_properties[] = {
    706	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", axp288_fuel_gauge_suppliers),
    707	{ }
    708};
    709
    710static const struct software_node axp288_fuel_gauge_sw_node = {
    711	.name = "axp288_fuel_gauge",
    712	.properties = axp288_fuel_gauge_properties,
    713};
    714
    715static const struct mfd_cell axp288_cells[] = {
    716	{
    717		.name		= "axp288_adc",
    718		.num_resources	= ARRAY_SIZE(axp288_adc_resources),
    719		.resources	= axp288_adc_resources,
    720	}, {
    721		.name		= "axp288_extcon",
    722		.num_resources	= ARRAY_SIZE(axp288_extcon_resources),
    723		.resources	= axp288_extcon_resources,
    724	}, {
    725		.name		= "axp288_charger",
    726		.num_resources	= ARRAY_SIZE(axp288_charger_resources),
    727		.resources	= axp288_charger_resources,
    728	}, {
    729		.name		= "axp288_fuel_gauge",
    730		.num_resources	= ARRAY_SIZE(axp288_fuel_gauge_resources),
    731		.resources	= axp288_fuel_gauge_resources,
    732		.swnode		= &axp288_fuel_gauge_sw_node,
    733	}, {
    734		.name		= "axp221-pek",
    735		.num_resources	= ARRAY_SIZE(axp288_power_button_resources),
    736		.resources	= axp288_power_button_resources,
    737	}, {
    738		.name		= "axp288_pmic_acpi",
    739	},
    740};
    741
    742static const struct mfd_cell axp803_cells[] = {
    743	{
    744		.name		= "axp221-pek",
    745		.num_resources	= ARRAY_SIZE(axp803_pek_resources),
    746		.resources	= axp803_pek_resources,
    747	}, {
    748		.name		= "axp20x-gpio",
    749		.of_compatible	= "x-powers,axp813-gpio",
    750	}, {
    751		.name		= "axp813-adc",
    752		.of_compatible	= "x-powers,axp813-adc",
    753	}, {
    754		.name		= "axp20x-battery-power-supply",
    755		.of_compatible	= "x-powers,axp813-battery-power-supply",
    756	}, {
    757		.name		= "axp20x-ac-power-supply",
    758		.of_compatible	= "x-powers,axp813-ac-power-supply",
    759		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
    760		.resources	= axp20x_ac_power_supply_resources,
    761	}, {
    762		.name		= "axp20x-usb-power-supply",
    763		.num_resources	= ARRAY_SIZE(axp803_usb_power_supply_resources),
    764		.resources	= axp803_usb_power_supply_resources,
    765		.of_compatible	= "x-powers,axp813-usb-power-supply",
    766	},
    767	{	.name		= "axp20x-regulator" },
    768};
    769
    770static const struct mfd_cell axp806_self_working_cells[] = {
    771	{
    772		.name		= "axp221-pek",
    773		.num_resources	= ARRAY_SIZE(axp806_pek_resources),
    774		.resources	= axp806_pek_resources,
    775	},
    776	{	.name		= "axp20x-regulator" },
    777};
    778
    779static const struct mfd_cell axp806_cells[] = {
    780	{
    781		.id		= 2,
    782		.name		= "axp20x-regulator",
    783	},
    784};
    785
    786static const struct mfd_cell axp809_cells[] = {
    787	{
    788		.name		= "axp221-pek",
    789		.num_resources	= ARRAY_SIZE(axp809_pek_resources),
    790		.resources	= axp809_pek_resources,
    791	}, {
    792		.id		= 1,
    793		.name		= "axp20x-regulator",
    794	},
    795};
    796
    797static const struct mfd_cell axp813_cells[] = {
    798	{
    799		.name		= "axp221-pek",
    800		.num_resources	= ARRAY_SIZE(axp803_pek_resources),
    801		.resources	= axp803_pek_resources,
    802	}, {
    803		.name		= "axp20x-regulator",
    804	}, {
    805		.name		= "axp20x-gpio",
    806		.of_compatible	= "x-powers,axp813-gpio",
    807	}, {
    808		.name		= "axp813-adc",
    809		.of_compatible	= "x-powers,axp813-adc",
    810	}, {
    811		.name		= "axp20x-battery-power-supply",
    812		.of_compatible	= "x-powers,axp813-battery-power-supply",
    813	}, {
    814		.name		= "axp20x-ac-power-supply",
    815		.of_compatible	= "x-powers,axp813-ac-power-supply",
    816		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
    817		.resources	= axp20x_ac_power_supply_resources,
    818	}, {
    819		.name		= "axp20x-usb-power-supply",
    820		.num_resources	= ARRAY_SIZE(axp803_usb_power_supply_resources),
    821		.resources	= axp803_usb_power_supply_resources,
    822		.of_compatible	= "x-powers,axp813-usb-power-supply",
    823	},
    824};
    825
    826static struct axp20x_dev *axp20x_pm_power_off;
    827static void axp20x_power_off(void)
    828{
    829	if (axp20x_pm_power_off->variant == AXP288_ID)
    830		return;
    831
    832	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
    833		     AXP20X_OFF);
    834
    835	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
    836	msleep(500);
    837}
    838
    839int axp20x_match_device(struct axp20x_dev *axp20x)
    840{
    841	struct device *dev = axp20x->dev;
    842	const struct acpi_device_id *acpi_id;
    843	const struct of_device_id *of_id;
    844
    845	if (dev->of_node) {
    846		of_id = of_match_device(dev->driver->of_match_table, dev);
    847		if (!of_id) {
    848			dev_err(dev, "Unable to match OF ID\n");
    849			return -ENODEV;
    850		}
    851		axp20x->variant = (long)of_id->data;
    852	} else {
    853		acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
    854		if (!acpi_id || !acpi_id->driver_data) {
    855			dev_err(dev, "Unable to match ACPI ID and data\n");
    856			return -ENODEV;
    857		}
    858		axp20x->variant = (long)acpi_id->driver_data;
    859	}
    860
    861	switch (axp20x->variant) {
    862	case AXP152_ID:
    863		axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
    864		axp20x->cells = axp152_cells;
    865		axp20x->regmap_cfg = &axp152_regmap_config;
    866		axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
    867		break;
    868	case AXP202_ID:
    869	case AXP209_ID:
    870		axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
    871		axp20x->cells = axp20x_cells;
    872		axp20x->regmap_cfg = &axp20x_regmap_config;
    873		axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
    874		break;
    875	case AXP221_ID:
    876		axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
    877		axp20x->cells = axp221_cells;
    878		axp20x->regmap_cfg = &axp22x_regmap_config;
    879		axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
    880		break;
    881	case AXP223_ID:
    882		axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
    883		axp20x->cells = axp223_cells;
    884		axp20x->regmap_cfg = &axp22x_regmap_config;
    885		axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
    886		break;
    887	case AXP288_ID:
    888		axp20x->cells = axp288_cells;
    889		axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
    890		axp20x->regmap_cfg = &axp288_regmap_config;
    891		axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
    892		axp20x->irq_flags = IRQF_TRIGGER_LOW;
    893		break;
    894	case AXP803_ID:
    895		axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
    896		axp20x->cells = axp803_cells;
    897		axp20x->regmap_cfg = &axp288_regmap_config;
    898		axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
    899		break;
    900	case AXP806_ID:
    901		/*
    902		 * Don't register the power key part if in slave mode or
    903		 * if there is no interrupt line.
    904		 */
    905		if (of_property_read_bool(axp20x->dev->of_node,
    906					  "x-powers,self-working-mode") &&
    907		    axp20x->irq > 0) {
    908			axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
    909			axp20x->cells = axp806_self_working_cells;
    910		} else {
    911			axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
    912			axp20x->cells = axp806_cells;
    913		}
    914		axp20x->regmap_cfg = &axp806_regmap_config;
    915		axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
    916		break;
    917	case AXP809_ID:
    918		axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
    919		axp20x->cells = axp809_cells;
    920		axp20x->regmap_cfg = &axp22x_regmap_config;
    921		axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
    922		break;
    923	case AXP813_ID:
    924		axp20x->nr_cells = ARRAY_SIZE(axp813_cells);
    925		axp20x->cells = axp813_cells;
    926		axp20x->regmap_cfg = &axp288_regmap_config;
    927		/*
    928		 * The IRQ table given in the datasheet is incorrect.
    929		 * In IRQ enable/status registers 1, there are separate
    930		 * IRQs for ACIN and VBUS, instead of bits [7:5] being
    931		 * the same as bits [4:2]. So it shares the same IRQs
    932		 * as the AXP803, rather than the AXP288.
    933		 */
    934		axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
    935		break;
    936	default:
    937		dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
    938		return -EINVAL;
    939	}
    940	dev_info(dev, "AXP20x variant %s found\n",
    941		 axp20x_model_names[axp20x->variant]);
    942
    943	return 0;
    944}
    945EXPORT_SYMBOL(axp20x_match_device);
    946
    947int axp20x_device_probe(struct axp20x_dev *axp20x)
    948{
    949	int ret;
    950
    951	/*
    952	 * The AXP806 supports either master/standalone or slave mode.
    953	 * Slave mode allows sharing the serial bus, even with multiple
    954	 * AXP806 which all have the same hardware address.
    955	 *
    956	 * This is done with extra "serial interface address extension",
    957	 * or AXP806_BUS_ADDR_EXT, and "register address extension", or
    958	 * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
    959	 * 1 bit customizable at the factory, and 1 bit depending on the
    960	 * state of an external pin. The latter is writable. The device
    961	 * will only respond to operations to its other registers when
    962	 * the these device addressing bits (in the upper 4 bits of the
    963	 * registers) match.
    964	 *
    965	 * By default we support an AXP806 chained to an AXP809 in slave
    966	 * mode. Boards which use an AXP806 in master mode can set the
    967	 * property "x-powers,master-mode" to override the default.
    968	 */
    969	if (axp20x->variant == AXP806_ID) {
    970		if (of_property_read_bool(axp20x->dev->of_node,
    971					  "x-powers,master-mode") ||
    972		    of_property_read_bool(axp20x->dev->of_node,
    973					  "x-powers,self-working-mode"))
    974			regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
    975				     AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
    976		else
    977			regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
    978				     AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
    979	}
    980
    981	/* Only if there is an interrupt line connected towards the CPU. */
    982	if (axp20x->irq > 0) {
    983		ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
    984				IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
    985				-1, axp20x->regmap_irq_chip,
    986				&axp20x->regmap_irqc);
    987		if (ret) {
    988			dev_err(axp20x->dev, "failed to add irq chip: %d\n",
    989				ret);
    990			return ret;
    991		}
    992	}
    993
    994	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
    995			      axp20x->nr_cells, NULL, 0, NULL);
    996
    997	if (ret) {
    998		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
    999		regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
   1000		return ret;
   1001	}
   1002
   1003	if (!pm_power_off) {
   1004		axp20x_pm_power_off = axp20x;
   1005		pm_power_off = axp20x_power_off;
   1006	}
   1007
   1008	dev_info(axp20x->dev, "AXP20X driver loaded\n");
   1009
   1010	return 0;
   1011}
   1012EXPORT_SYMBOL(axp20x_device_probe);
   1013
   1014void axp20x_device_remove(struct axp20x_dev *axp20x)
   1015{
   1016	if (axp20x == axp20x_pm_power_off) {
   1017		axp20x_pm_power_off = NULL;
   1018		pm_power_off = NULL;
   1019	}
   1020
   1021	mfd_remove_devices(axp20x->dev);
   1022	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
   1023}
   1024EXPORT_SYMBOL(axp20x_device_remove);
   1025
   1026MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
   1027MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
   1028MODULE_LICENSE("GPL");