Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * MFD core driver for the X-Powers' Power Management ICs
0004  *
0005  * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
0006  * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
0007  * as well as configurable GPIOs.
0008  *
0009  * This file contains the interface independent core functions.
0010  *
0011  * Copyright (C) 2014 Carlo Caione
0012  *
0013  * Author: Carlo Caione <carlo@caione.org>
0014  */
0015 
0016 #include <linux/acpi.h>
0017 #include <linux/bitops.h>
0018 #include <linux/delay.h>
0019 #include <linux/err.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/kernel.h>
0022 #include <linux/mfd/axp20x.h>
0023 #include <linux/mfd/core.h>
0024 #include <linux/module.h>
0025 #include <linux/of_device.h>
0026 #include <linux/pm_runtime.h>
0027 #include <linux/regmap.h>
0028 #include <linux/regulator/consumer.h>
0029 
0030 #define AXP20X_OFF  BIT(7)
0031 
0032 #define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE    0
0033 #define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4)
0034 
0035 static const char * const axp20x_model_names[] = {
0036     "AXP152",
0037     "AXP202",
0038     "AXP209",
0039     "AXP221",
0040     "AXP223",
0041     "AXP288",
0042     "AXP803",
0043     "AXP806",
0044     "AXP809",
0045     "AXP813",
0046 };
0047 
0048 static const struct regmap_range axp152_writeable_ranges[] = {
0049     regmap_reg_range(AXP152_LDO3456_DC1234_CTRL, AXP152_IRQ3_STATE),
0050     regmap_reg_range(AXP152_DCDC_MODE, AXP152_PWM1_DUTY_CYCLE),
0051 };
0052 
0053 static const struct regmap_range axp152_volatile_ranges[] = {
0054     regmap_reg_range(AXP152_PWR_OP_MODE, AXP152_PWR_OP_MODE),
0055     regmap_reg_range(AXP152_IRQ1_EN, AXP152_IRQ3_STATE),
0056     regmap_reg_range(AXP152_GPIO_INPUT, AXP152_GPIO_INPUT),
0057 };
0058 
0059 static const struct regmap_access_table axp152_writeable_table = {
0060     .yes_ranges = axp152_writeable_ranges,
0061     .n_yes_ranges   = ARRAY_SIZE(axp152_writeable_ranges),
0062 };
0063 
0064 static const struct regmap_access_table axp152_volatile_table = {
0065     .yes_ranges = axp152_volatile_ranges,
0066     .n_yes_ranges   = ARRAY_SIZE(axp152_volatile_ranges),
0067 };
0068 
0069 static const struct regmap_range axp20x_writeable_ranges[] = {
0070     regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
0071     regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
0072     regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
0073     regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
0074 };
0075 
0076 static const struct regmap_range axp20x_volatile_ranges[] = {
0077     regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
0078     regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
0079     regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
0080     regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
0081     regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
0082     regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
0083 };
0084 
0085 static const struct regmap_access_table axp20x_writeable_table = {
0086     .yes_ranges = axp20x_writeable_ranges,
0087     .n_yes_ranges   = ARRAY_SIZE(axp20x_writeable_ranges),
0088 };
0089 
0090 static const struct regmap_access_table axp20x_volatile_table = {
0091     .yes_ranges = axp20x_volatile_ranges,
0092     .n_yes_ranges   = ARRAY_SIZE(axp20x_volatile_ranges),
0093 };
0094 
0095 /* AXP22x ranges are shared with the AXP809, as they cover the same range */
0096 static const struct regmap_range axp22x_writeable_ranges[] = {
0097     regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
0098     regmap_reg_range(AXP20X_CHRG_CTRL1, AXP22X_CHRG_CTRL3),
0099     regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
0100 };
0101 
0102 static const struct regmap_range axp22x_volatile_ranges[] = {
0103     regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
0104     regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
0105     regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
0106     regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L),
0107     regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
0108 };
0109 
0110 static const struct regmap_access_table axp22x_writeable_table = {
0111     .yes_ranges = axp22x_writeable_ranges,
0112     .n_yes_ranges   = ARRAY_SIZE(axp22x_writeable_ranges),
0113 };
0114 
0115 static const struct regmap_access_table axp22x_volatile_table = {
0116     .yes_ranges = axp22x_volatile_ranges,
0117     .n_yes_ranges   = ARRAY_SIZE(axp22x_volatile_ranges),
0118 };
0119 
0120 /* AXP288 ranges are shared with the AXP803, as they cover the same range */
0121 static const struct regmap_range axp288_writeable_ranges[] = {
0122     regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
0123     regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
0124 };
0125 
0126 static const struct regmap_range axp288_volatile_ranges[] = {
0127     regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
0128     regmap_reg_range(AXP22X_PWR_OUT_CTRL1, AXP22X_ALDO3_V_OUT),
0129     regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
0130     regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
0131     regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
0132     regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
0133     regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
0134     regmap_reg_range(AXP20X_GPIO1_CTRL, AXP22X_GPIO_STATE),
0135     regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L),
0136     regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG),
0137 };
0138 
0139 static const struct regmap_access_table axp288_writeable_table = {
0140     .yes_ranges = axp288_writeable_ranges,
0141     .n_yes_ranges   = ARRAY_SIZE(axp288_writeable_ranges),
0142 };
0143 
0144 static const struct regmap_access_table axp288_volatile_table = {
0145     .yes_ranges = axp288_volatile_ranges,
0146     .n_yes_ranges   = ARRAY_SIZE(axp288_volatile_ranges),
0147 };
0148 
0149 static const struct regmap_range axp806_writeable_ranges[] = {
0150     regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
0151     regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
0152     regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
0153     regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
0154     regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
0155 };
0156 
0157 static const struct regmap_range axp806_volatile_ranges[] = {
0158     regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
0159 };
0160 
0161 static const struct regmap_access_table axp806_writeable_table = {
0162     .yes_ranges = axp806_writeable_ranges,
0163     .n_yes_ranges   = ARRAY_SIZE(axp806_writeable_ranges),
0164 };
0165 
0166 static const struct regmap_access_table axp806_volatile_table = {
0167     .yes_ranges = axp806_volatile_ranges,
0168     .n_yes_ranges   = ARRAY_SIZE(axp806_volatile_ranges),
0169 };
0170 
0171 static const struct resource axp152_pek_resources[] = {
0172     DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
0173     DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
0174 };
0175 
0176 static const struct resource axp20x_ac_power_supply_resources[] = {
0177     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
0178     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
0179     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
0180 };
0181 
0182 static const struct resource axp20x_pek_resources[] = {
0183     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
0184     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
0185 };
0186 
0187 static const struct resource axp20x_usb_power_supply_resources[] = {
0188     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
0189     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
0190     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
0191     DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
0192 };
0193 
0194 static const struct resource axp22x_usb_power_supply_resources[] = {
0195     DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
0196     DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
0197 };
0198 
0199 /* AXP803 and AXP813/AXP818 share the same interrupts */
0200 static const struct resource axp803_usb_power_supply_resources[] = {
0201     DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
0202     DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
0203 };
0204 
0205 static const struct resource axp22x_pek_resources[] = {
0206     DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
0207     DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
0208 };
0209 
0210 static const struct resource axp288_power_button_resources[] = {
0211     DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"),
0212     DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"),
0213 };
0214 
0215 static const struct resource axp288_fuel_gauge_resources[] = {
0216     DEFINE_RES_IRQ(AXP288_IRQ_QWBTU),
0217     DEFINE_RES_IRQ(AXP288_IRQ_WBTU),
0218     DEFINE_RES_IRQ(AXP288_IRQ_QWBTO),
0219     DEFINE_RES_IRQ(AXP288_IRQ_WBTO),
0220     DEFINE_RES_IRQ(AXP288_IRQ_WL2),
0221     DEFINE_RES_IRQ(AXP288_IRQ_WL1),
0222 };
0223 
0224 static const struct resource axp803_pek_resources[] = {
0225     DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
0226     DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
0227 };
0228 
0229 static const struct resource axp806_pek_resources[] = {
0230     DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_RISE, "PEK_DBR"),
0231     DEFINE_RES_IRQ_NAMED(AXP806_IRQ_POK_FALL, "PEK_DBF"),
0232 };
0233 
0234 static const struct resource axp809_pek_resources[] = {
0235     DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
0236     DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
0237 };
0238 
0239 static const struct regmap_config axp152_regmap_config = {
0240     .reg_bits   = 8,
0241     .val_bits   = 8,
0242     .wr_table   = &axp152_writeable_table,
0243     .volatile_table = &axp152_volatile_table,
0244     .max_register   = AXP152_PWM1_DUTY_CYCLE,
0245     .cache_type = REGCACHE_RBTREE,
0246 };
0247 
0248 static const struct regmap_config axp20x_regmap_config = {
0249     .reg_bits   = 8,
0250     .val_bits   = 8,
0251     .wr_table   = &axp20x_writeable_table,
0252     .volatile_table = &axp20x_volatile_table,
0253     .max_register   = AXP20X_OCV(AXP20X_OCV_MAX),
0254     .cache_type = REGCACHE_RBTREE,
0255 };
0256 
0257 static const struct regmap_config axp22x_regmap_config = {
0258     .reg_bits   = 8,
0259     .val_bits   = 8,
0260     .wr_table   = &axp22x_writeable_table,
0261     .volatile_table = &axp22x_volatile_table,
0262     .max_register   = AXP22X_BATLOW_THRES1,
0263     .cache_type = REGCACHE_RBTREE,
0264 };
0265 
0266 static const struct regmap_config axp288_regmap_config = {
0267     .reg_bits   = 8,
0268     .val_bits   = 8,
0269     .wr_table   = &axp288_writeable_table,
0270     .volatile_table = &axp288_volatile_table,
0271     .max_register   = AXP288_FG_TUNE5,
0272     .cache_type = REGCACHE_RBTREE,
0273 };
0274 
0275 static const struct regmap_config axp806_regmap_config = {
0276     .reg_bits   = 8,
0277     .val_bits   = 8,
0278     .wr_table   = &axp806_writeable_table,
0279     .volatile_table = &axp806_volatile_table,
0280     .max_register   = AXP806_REG_ADDR_EXT,
0281     .cache_type = REGCACHE_RBTREE,
0282 };
0283 
0284 #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)            \
0285     [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
0286 
0287 static const struct regmap_irq axp152_regmap_irqs[] = {
0288     INIT_REGMAP_IRQ(AXP152, LDO0IN_CONNECT,     0, 6),
0289     INIT_REGMAP_IRQ(AXP152, LDO0IN_REMOVAL,     0, 5),
0290     INIT_REGMAP_IRQ(AXP152, ALDO0IN_CONNECT,    0, 3),
0291     INIT_REGMAP_IRQ(AXP152, ALDO0IN_REMOVAL,    0, 2),
0292     INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW,        1, 5),
0293     INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW,        1, 4),
0294     INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW,        1, 3),
0295     INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW,        1, 2),
0296     INIT_REGMAP_IRQ(AXP152, PEK_SHORT,      1, 1),
0297     INIT_REGMAP_IRQ(AXP152, PEK_LONG,       1, 0),
0298     INIT_REGMAP_IRQ(AXP152, TIMER,          2, 7),
0299     INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE,       2, 6),
0300     INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE,       2, 5),
0301     INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT,        2, 3),
0302     INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT,        2, 2),
0303     INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT,        2, 1),
0304     INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT,        2, 0),
0305 };
0306 
0307 static const struct regmap_irq axp20x_regmap_irqs[] = {
0308     INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V,        0, 7),
0309     INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN,        0, 6),
0310     INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL,           0, 5),
0311     INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V,        0, 4),
0312     INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN,        0, 3),
0313     INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL,           0, 2),
0314     INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW,     0, 1),
0315     INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN,        1, 7),
0316     INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL,           1, 6),
0317     INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE,  1, 5),
0318     INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4),
0319     INIT_REGMAP_IRQ(AXP20X, CHARG,              1, 3),
0320     INIT_REGMAP_IRQ(AXP20X, CHARG_DONE,     1, 2),
0321     INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH,         1, 1),
0322     INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW,          1, 0),
0323     INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH,          2, 7),
0324     INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW,        2, 6),
0325     INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG,           2, 5),
0326     INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG,           2, 4),
0327     INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG,           2, 3),
0328     INIT_REGMAP_IRQ(AXP20X, PEK_SHORT,      2, 1),
0329     INIT_REGMAP_IRQ(AXP20X, PEK_LONG,       2, 0),
0330     INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON,        3, 7),
0331     INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF,           3, 6),
0332     INIT_REGMAP_IRQ(AXP20X, VBUS_VALID,     3, 5),
0333     INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID,         3, 4),
0334     INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID,    3, 3),
0335     INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END,          3, 2),
0336     INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1,           3, 1),
0337     INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2,           3, 0),
0338     INIT_REGMAP_IRQ(AXP20X, TIMER,              4, 7),
0339     INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE,           4, 6),
0340     INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE,           4, 5),
0341     INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT,        4, 3),
0342     INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT,        4, 2),
0343     INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT,        4, 1),
0344     INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT,        4, 0),
0345 };
0346 
0347 static const struct regmap_irq axp22x_regmap_irqs[] = {
0348     INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V,        0, 7),
0349     INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN,        0, 6),
0350     INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL,           0, 5),
0351     INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V,        0, 4),
0352     INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN,        0, 3),
0353     INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL,           0, 2),
0354     INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW,     0, 1),
0355     INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN,        1, 7),
0356     INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL,           1, 6),
0357     INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE,  1, 5),
0358     INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4),
0359     INIT_REGMAP_IRQ(AXP22X, CHARG,              1, 3),
0360     INIT_REGMAP_IRQ(AXP22X, CHARG_DONE,     1, 2),
0361     INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH,         1, 1),
0362     INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW,          1, 0),
0363     INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH,          2, 7),
0364     INIT_REGMAP_IRQ(AXP22X, PEK_SHORT,      2, 1),
0365     INIT_REGMAP_IRQ(AXP22X, PEK_LONG,       2, 0),
0366     INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1,           3, 1),
0367     INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2,           3, 0),
0368     INIT_REGMAP_IRQ(AXP22X, TIMER,              4, 7),
0369     INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE,           4, 6),
0370     INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE,           4, 5),
0371     INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT,        4, 1),
0372     INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT,        4, 0),
0373 };
0374 
0375 /* some IRQs are compatible with axp20x models */
0376 static const struct regmap_irq axp288_regmap_irqs[] = {
0377     INIT_REGMAP_IRQ(AXP288, VBUS_FALL,              0, 2),
0378     INIT_REGMAP_IRQ(AXP288, VBUS_RISE,              0, 3),
0379     INIT_REGMAP_IRQ(AXP288, OV,                     0, 4),
0380     INIT_REGMAP_IRQ(AXP288, FALLING_ALT,            0, 5),
0381     INIT_REGMAP_IRQ(AXP288, RISING_ALT,             0, 6),
0382     INIT_REGMAP_IRQ(AXP288, OV_ALT,                 0, 7),
0383 
0384     INIT_REGMAP_IRQ(AXP288, DONE,                   1, 2),
0385     INIT_REGMAP_IRQ(AXP288, CHARGING,               1, 3),
0386     INIT_REGMAP_IRQ(AXP288, SAFE_QUIT,              1, 4),
0387     INIT_REGMAP_IRQ(AXP288, SAFE_ENTER,             1, 5),
0388     INIT_REGMAP_IRQ(AXP288, ABSENT,                 1, 6),
0389     INIT_REGMAP_IRQ(AXP288, APPEND,                 1, 7),
0390 
0391     INIT_REGMAP_IRQ(AXP288, QWBTU,                  2, 0),
0392     INIT_REGMAP_IRQ(AXP288, WBTU,                   2, 1),
0393     INIT_REGMAP_IRQ(AXP288, QWBTO,                  2, 2),
0394     INIT_REGMAP_IRQ(AXP288, WBTO,                   2, 3),
0395     INIT_REGMAP_IRQ(AXP288, QCBTU,                  2, 4),
0396     INIT_REGMAP_IRQ(AXP288, CBTU,                   2, 5),
0397     INIT_REGMAP_IRQ(AXP288, QCBTO,                  2, 6),
0398     INIT_REGMAP_IRQ(AXP288, CBTO,                   2, 7),
0399 
0400     INIT_REGMAP_IRQ(AXP288, WL2,                    3, 0),
0401     INIT_REGMAP_IRQ(AXP288, WL1,                    3, 1),
0402     INIT_REGMAP_IRQ(AXP288, GPADC,                  3, 2),
0403     INIT_REGMAP_IRQ(AXP288, OT,                     3, 7),
0404 
0405     INIT_REGMAP_IRQ(AXP288, GPIO0,                  4, 0),
0406     INIT_REGMAP_IRQ(AXP288, GPIO1,                  4, 1),
0407     INIT_REGMAP_IRQ(AXP288, POKO,                   4, 2),
0408     INIT_REGMAP_IRQ(AXP288, POKL,                   4, 3),
0409     INIT_REGMAP_IRQ(AXP288, POKS,                   4, 4),
0410     INIT_REGMAP_IRQ(AXP288, POKN,                   4, 5),
0411     INIT_REGMAP_IRQ(AXP288, POKP,                   4, 6),
0412     INIT_REGMAP_IRQ(AXP288, TIMER,                  4, 7),
0413 
0414     INIT_REGMAP_IRQ(AXP288, MV_CHNG,                5, 0),
0415     INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
0416 };
0417 
0418 static const struct regmap_irq axp803_regmap_irqs[] = {
0419     INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V,        0, 7),
0420     INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN,        0, 6),
0421     INIT_REGMAP_IRQ(AXP803, ACIN_REMOVAL,           0, 5),
0422     INIT_REGMAP_IRQ(AXP803, VBUS_OVER_V,        0, 4),
0423     INIT_REGMAP_IRQ(AXP803, VBUS_PLUGIN,        0, 3),
0424     INIT_REGMAP_IRQ(AXP803, VBUS_REMOVAL,           0, 2),
0425     INIT_REGMAP_IRQ(AXP803, BATT_PLUGIN,        1, 7),
0426     INIT_REGMAP_IRQ(AXP803, BATT_REMOVAL,           1, 6),
0427     INIT_REGMAP_IRQ(AXP803, BATT_ENT_ACT_MODE,  1, 5),
0428     INIT_REGMAP_IRQ(AXP803, BATT_EXIT_ACT_MODE, 1, 4),
0429     INIT_REGMAP_IRQ(AXP803, CHARG,              1, 3),
0430     INIT_REGMAP_IRQ(AXP803, CHARG_DONE,     1, 2),
0431     INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH, 2, 7),
0432     INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH_END, 2, 6),
0433     INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW,  2, 5),
0434     INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW_END,  2, 4),
0435     INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH, 2, 3),
0436     INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH_END, 2, 2),
0437     INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW,  2, 1),
0438     INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW_END,  2, 0),
0439     INIT_REGMAP_IRQ(AXP803, DIE_TEMP_HIGH,          3, 7),
0440     INIT_REGMAP_IRQ(AXP803, GPADC,              3, 2),
0441     INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL1,           3, 1),
0442     INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL2,           3, 0),
0443     INIT_REGMAP_IRQ(AXP803, TIMER,              4, 7),
0444     INIT_REGMAP_IRQ(AXP803, PEK_RIS_EDGE,           4, 6),
0445     INIT_REGMAP_IRQ(AXP803, PEK_FAL_EDGE,           4, 5),
0446     INIT_REGMAP_IRQ(AXP803, PEK_SHORT,      4, 4),
0447     INIT_REGMAP_IRQ(AXP803, PEK_LONG,       4, 3),
0448     INIT_REGMAP_IRQ(AXP803, PEK_OVER_OFF,       4, 2),
0449     INIT_REGMAP_IRQ(AXP803, GPIO1_INPUT,        4, 1),
0450     INIT_REGMAP_IRQ(AXP803, GPIO0_INPUT,        4, 0),
0451     INIT_REGMAP_IRQ(AXP803, BC_USB_CHNG,            5, 1),
0452     INIT_REGMAP_IRQ(AXP803, MV_CHNG,                5, 0),
0453 };
0454 
0455 static const struct regmap_irq axp806_regmap_irqs[] = {
0456     INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1,  0, 0),
0457     INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2,  0, 1),
0458     INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW,        0, 3),
0459     INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW,        0, 4),
0460     INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW,        0, 5),
0461     INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW,        0, 6),
0462     INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW,        0, 7),
0463     INIT_REGMAP_IRQ(AXP806, POK_LONG,       1, 0),
0464     INIT_REGMAP_IRQ(AXP806, POK_SHORT,      1, 1),
0465     INIT_REGMAP_IRQ(AXP806, WAKEUP,         1, 4),
0466     INIT_REGMAP_IRQ(AXP806, POK_FALL,       1, 5),
0467     INIT_REGMAP_IRQ(AXP806, POK_RISE,       1, 6),
0468 };
0469 
0470 static const struct regmap_irq axp809_regmap_irqs[] = {
0471     INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V,        0, 7),
0472     INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN,        0, 6),
0473     INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL,           0, 5),
0474     INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V,        0, 4),
0475     INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN,        0, 3),
0476     INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL,           0, 2),
0477     INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW,     0, 1),
0478     INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN,        1, 7),
0479     INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL,           1, 6),
0480     INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE,  1, 5),
0481     INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE, 1, 4),
0482     INIT_REGMAP_IRQ(AXP809, CHARG,              1, 3),
0483     INIT_REGMAP_IRQ(AXP809, CHARG_DONE,     1, 2),
0484     INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH, 2, 7),
0485     INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END, 2, 6),
0486     INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW,  2, 5),
0487     INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END,  2, 4),
0488     INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH, 2, 3),
0489     INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END, 2, 2),
0490     INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW,  2, 1),
0491     INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END,  2, 0),
0492     INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH,          3, 7),
0493     INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1,           3, 1),
0494     INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2,           3, 0),
0495     INIT_REGMAP_IRQ(AXP809, TIMER,              4, 7),
0496     INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE,           4, 6),
0497     INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE,           4, 5),
0498     INIT_REGMAP_IRQ(AXP809, PEK_SHORT,      4, 4),
0499     INIT_REGMAP_IRQ(AXP809, PEK_LONG,       4, 3),
0500     INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF,       4, 2),
0501     INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT,        4, 1),
0502     INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT,        4, 0),
0503 };
0504 
0505 static const struct regmap_irq_chip axp152_regmap_irq_chip = {
0506     .name           = "axp152_irq_chip",
0507     .status_base        = AXP152_IRQ1_STATE,
0508     .ack_base       = AXP152_IRQ1_STATE,
0509     .mask_base      = AXP152_IRQ1_EN,
0510     .mask_invert        = true,
0511     .init_ack_masked    = true,
0512     .irqs           = axp152_regmap_irqs,
0513     .num_irqs       = ARRAY_SIZE(axp152_regmap_irqs),
0514     .num_regs       = 3,
0515 };
0516 
0517 static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
0518     .name           = "axp20x_irq_chip",
0519     .status_base        = AXP20X_IRQ1_STATE,
0520     .ack_base       = AXP20X_IRQ1_STATE,
0521     .mask_base      = AXP20X_IRQ1_EN,
0522     .mask_invert        = true,
0523     .init_ack_masked    = true,
0524     .irqs           = axp20x_regmap_irqs,
0525     .num_irqs       = ARRAY_SIZE(axp20x_regmap_irqs),
0526     .num_regs       = 5,
0527 
0528 };
0529 
0530 static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
0531     .name           = "axp22x_irq_chip",
0532     .status_base        = AXP20X_IRQ1_STATE,
0533     .ack_base       = AXP20X_IRQ1_STATE,
0534     .mask_base      = AXP20X_IRQ1_EN,
0535     .mask_invert        = true,
0536     .init_ack_masked    = true,
0537     .irqs           = axp22x_regmap_irqs,
0538     .num_irqs       = ARRAY_SIZE(axp22x_regmap_irqs),
0539     .num_regs       = 5,
0540 };
0541 
0542 static const struct regmap_irq_chip axp288_regmap_irq_chip = {
0543     .name           = "axp288_irq_chip",
0544     .status_base        = AXP20X_IRQ1_STATE,
0545     .ack_base       = AXP20X_IRQ1_STATE,
0546     .mask_base      = AXP20X_IRQ1_EN,
0547     .mask_invert        = true,
0548     .init_ack_masked    = true,
0549     .irqs           = axp288_regmap_irqs,
0550     .num_irqs       = ARRAY_SIZE(axp288_regmap_irqs),
0551     .num_regs       = 6,
0552 
0553 };
0554 
0555 static const struct regmap_irq_chip axp803_regmap_irq_chip = {
0556     .name           = "axp803",
0557     .status_base        = AXP20X_IRQ1_STATE,
0558     .ack_base       = AXP20X_IRQ1_STATE,
0559     .mask_base      = AXP20X_IRQ1_EN,
0560     .mask_invert        = true,
0561     .init_ack_masked    = true,
0562     .irqs           = axp803_regmap_irqs,
0563     .num_irqs       = ARRAY_SIZE(axp803_regmap_irqs),
0564     .num_regs       = 6,
0565 };
0566 
0567 static const struct regmap_irq_chip axp806_regmap_irq_chip = {
0568     .name           = "axp806",
0569     .status_base        = AXP20X_IRQ1_STATE,
0570     .ack_base       = AXP20X_IRQ1_STATE,
0571     .mask_base      = AXP20X_IRQ1_EN,
0572     .mask_invert        = true,
0573     .init_ack_masked    = true,
0574     .irqs           = axp806_regmap_irqs,
0575     .num_irqs       = ARRAY_SIZE(axp806_regmap_irqs),
0576     .num_regs       = 2,
0577 };
0578 
0579 static const struct regmap_irq_chip axp809_regmap_irq_chip = {
0580     .name           = "axp809",
0581     .status_base        = AXP20X_IRQ1_STATE,
0582     .ack_base       = AXP20X_IRQ1_STATE,
0583     .mask_base      = AXP20X_IRQ1_EN,
0584     .mask_invert        = true,
0585     .init_ack_masked    = true,
0586     .irqs           = axp809_regmap_irqs,
0587     .num_irqs       = ARRAY_SIZE(axp809_regmap_irqs),
0588     .num_regs       = 5,
0589 };
0590 
0591 static const struct mfd_cell axp20x_cells[] = {
0592     {
0593         .name       = "axp20x-gpio",
0594         .of_compatible  = "x-powers,axp209-gpio",
0595     }, {
0596         .name       = "axp20x-pek",
0597         .num_resources  = ARRAY_SIZE(axp20x_pek_resources),
0598         .resources  = axp20x_pek_resources,
0599     }, {
0600         .name       = "axp20x-regulator",
0601     }, {
0602         .name       = "axp20x-adc",
0603         .of_compatible  = "x-powers,axp209-adc",
0604     }, {
0605         .name       = "axp20x-battery-power-supply",
0606         .of_compatible  = "x-powers,axp209-battery-power-supply",
0607     }, {
0608         .name       = "axp20x-ac-power-supply",
0609         .of_compatible  = "x-powers,axp202-ac-power-supply",
0610         .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
0611         .resources  = axp20x_ac_power_supply_resources,
0612     }, {
0613         .name       = "axp20x-usb-power-supply",
0614         .of_compatible  = "x-powers,axp202-usb-power-supply",
0615         .num_resources  = ARRAY_SIZE(axp20x_usb_power_supply_resources),
0616         .resources  = axp20x_usb_power_supply_resources,
0617     },
0618 };
0619 
0620 static const struct mfd_cell axp221_cells[] = {
0621     {
0622         .name       = "axp20x-gpio",
0623         .of_compatible  = "x-powers,axp221-gpio",
0624     }, {
0625         .name       = "axp221-pek",
0626         .num_resources  = ARRAY_SIZE(axp22x_pek_resources),
0627         .resources  = axp22x_pek_resources,
0628     }, {
0629         .name       = "axp20x-regulator",
0630     }, {
0631         .name       = "axp22x-adc",
0632         .of_compatible  = "x-powers,axp221-adc",
0633     }, {
0634         .name       = "axp20x-ac-power-supply",
0635         .of_compatible  = "x-powers,axp221-ac-power-supply",
0636         .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
0637         .resources  = axp20x_ac_power_supply_resources,
0638     }, {
0639         .name       = "axp20x-battery-power-supply",
0640         .of_compatible  = "x-powers,axp221-battery-power-supply",
0641     }, {
0642         .name       = "axp20x-usb-power-supply",
0643         .of_compatible  = "x-powers,axp221-usb-power-supply",
0644         .num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
0645         .resources  = axp22x_usb_power_supply_resources,
0646     },
0647 };
0648 
0649 static const struct mfd_cell axp223_cells[] = {
0650     {
0651         .name       = "axp20x-gpio",
0652         .of_compatible  = "x-powers,axp221-gpio",
0653     }, {
0654         .name       = "axp221-pek",
0655         .num_resources  = ARRAY_SIZE(axp22x_pek_resources),
0656         .resources  = axp22x_pek_resources,
0657     }, {
0658         .name       = "axp22x-adc",
0659         .of_compatible  = "x-powers,axp221-adc",
0660     }, {
0661         .name       = "axp20x-battery-power-supply",
0662         .of_compatible  = "x-powers,axp221-battery-power-supply",
0663     }, {
0664         .name       = "axp20x-regulator",
0665     }, {
0666         .name       = "axp20x-ac-power-supply",
0667         .of_compatible  = "x-powers,axp221-ac-power-supply",
0668         .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
0669         .resources  = axp20x_ac_power_supply_resources,
0670     }, {
0671         .name       = "axp20x-usb-power-supply",
0672         .of_compatible  = "x-powers,axp223-usb-power-supply",
0673         .num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
0674         .resources  = axp22x_usb_power_supply_resources,
0675     },
0676 };
0677 
0678 static const struct mfd_cell axp152_cells[] = {
0679     {
0680         .name       = "axp20x-pek",
0681         .num_resources  = ARRAY_SIZE(axp152_pek_resources),
0682         .resources  = axp152_pek_resources,
0683     },
0684 };
0685 
0686 static const struct resource axp288_adc_resources[] = {
0687     DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
0688 };
0689 
0690 static const struct resource axp288_extcon_resources[] = {
0691     DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL),
0692     DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE),
0693     DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG),
0694     DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG),
0695 };
0696 
0697 static const struct resource axp288_charger_resources[] = {
0698     DEFINE_RES_IRQ(AXP288_IRQ_OV),
0699     DEFINE_RES_IRQ(AXP288_IRQ_DONE),
0700     DEFINE_RES_IRQ(AXP288_IRQ_CHARGING),
0701     DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT),
0702     DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER),
0703     DEFINE_RES_IRQ(AXP288_IRQ_QCBTU),
0704     DEFINE_RES_IRQ(AXP288_IRQ_CBTU),
0705     DEFINE_RES_IRQ(AXP288_IRQ_QCBTO),
0706     DEFINE_RES_IRQ(AXP288_IRQ_CBTO),
0707 };
0708 
0709 static const char * const axp288_fuel_gauge_suppliers[] = { "axp288_charger" };
0710 
0711 static const struct property_entry axp288_fuel_gauge_properties[] = {
0712     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", axp288_fuel_gauge_suppliers),
0713     { }
0714 };
0715 
0716 static const struct software_node axp288_fuel_gauge_sw_node = {
0717     .name = "axp288_fuel_gauge",
0718     .properties = axp288_fuel_gauge_properties,
0719 };
0720 
0721 static const struct mfd_cell axp288_cells[] = {
0722     {
0723         .name       = "axp288_adc",
0724         .num_resources  = ARRAY_SIZE(axp288_adc_resources),
0725         .resources  = axp288_adc_resources,
0726     }, {
0727         .name       = "axp288_extcon",
0728         .num_resources  = ARRAY_SIZE(axp288_extcon_resources),
0729         .resources  = axp288_extcon_resources,
0730     }, {
0731         .name       = "axp288_charger",
0732         .num_resources  = ARRAY_SIZE(axp288_charger_resources),
0733         .resources  = axp288_charger_resources,
0734     }, {
0735         .name       = "axp288_fuel_gauge",
0736         .num_resources  = ARRAY_SIZE(axp288_fuel_gauge_resources),
0737         .resources  = axp288_fuel_gauge_resources,
0738         .swnode     = &axp288_fuel_gauge_sw_node,
0739     }, {
0740         .name       = "axp221-pek",
0741         .num_resources  = ARRAY_SIZE(axp288_power_button_resources),
0742         .resources  = axp288_power_button_resources,
0743     }, {
0744         .name       = "axp288_pmic_acpi",
0745     },
0746 };
0747 
0748 static const struct mfd_cell axp803_cells[] = {
0749     {
0750         .name       = "axp221-pek",
0751         .num_resources  = ARRAY_SIZE(axp803_pek_resources),
0752         .resources  = axp803_pek_resources,
0753     }, {
0754         .name       = "axp20x-gpio",
0755         .of_compatible  = "x-powers,axp813-gpio",
0756     }, {
0757         .name       = "axp813-adc",
0758         .of_compatible  = "x-powers,axp813-adc",
0759     }, {
0760         .name       = "axp20x-battery-power-supply",
0761         .of_compatible  = "x-powers,axp813-battery-power-supply",
0762     }, {
0763         .name       = "axp20x-ac-power-supply",
0764         .of_compatible  = "x-powers,axp813-ac-power-supply",
0765         .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
0766         .resources  = axp20x_ac_power_supply_resources,
0767     }, {
0768         .name       = "axp20x-usb-power-supply",
0769         .num_resources  = ARRAY_SIZE(axp803_usb_power_supply_resources),
0770         .resources  = axp803_usb_power_supply_resources,
0771         .of_compatible  = "x-powers,axp813-usb-power-supply",
0772     },
0773     {   .name       = "axp20x-regulator" },
0774 };
0775 
0776 static const struct mfd_cell axp806_self_working_cells[] = {
0777     {
0778         .name       = "axp221-pek",
0779         .num_resources  = ARRAY_SIZE(axp806_pek_resources),
0780         .resources  = axp806_pek_resources,
0781     },
0782     {   .name       = "axp20x-regulator" },
0783 };
0784 
0785 static const struct mfd_cell axp806_cells[] = {
0786     {
0787         .id     = 2,
0788         .name       = "axp20x-regulator",
0789     },
0790 };
0791 
0792 static const struct mfd_cell axp809_cells[] = {
0793     {
0794         .name       = "axp20x-gpio",
0795         .of_compatible  = "x-powers,axp221-gpio",
0796     }, {
0797         .name       = "axp221-pek",
0798         .num_resources  = ARRAY_SIZE(axp809_pek_resources),
0799         .resources  = axp809_pek_resources,
0800     }, {
0801         .id     = 1,
0802         .name       = "axp20x-regulator",
0803     },
0804 };
0805 
0806 static const struct mfd_cell axp813_cells[] = {
0807     {
0808         .name       = "axp221-pek",
0809         .num_resources  = ARRAY_SIZE(axp803_pek_resources),
0810         .resources  = axp803_pek_resources,
0811     }, {
0812         .name       = "axp20x-regulator",
0813     }, {
0814         .name       = "axp20x-gpio",
0815         .of_compatible  = "x-powers,axp813-gpio",
0816     }, {
0817         .name       = "axp813-adc",
0818         .of_compatible  = "x-powers,axp813-adc",
0819     }, {
0820         .name       = "axp20x-battery-power-supply",
0821         .of_compatible  = "x-powers,axp813-battery-power-supply",
0822     }, {
0823         .name       = "axp20x-ac-power-supply",
0824         .of_compatible  = "x-powers,axp813-ac-power-supply",
0825         .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
0826         .resources  = axp20x_ac_power_supply_resources,
0827     }, {
0828         .name       = "axp20x-usb-power-supply",
0829         .num_resources  = ARRAY_SIZE(axp803_usb_power_supply_resources),
0830         .resources  = axp803_usb_power_supply_resources,
0831         .of_compatible  = "x-powers,axp813-usb-power-supply",
0832     },
0833 };
0834 
0835 static struct axp20x_dev *axp20x_pm_power_off;
0836 static void axp20x_power_off(void)
0837 {
0838     if (axp20x_pm_power_off->variant == AXP288_ID)
0839         return;
0840 
0841     regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
0842              AXP20X_OFF);
0843 
0844     /* Give capacitors etc. time to drain to avoid kernel panic msg. */
0845     msleep(500);
0846 }
0847 
0848 int axp20x_match_device(struct axp20x_dev *axp20x)
0849 {
0850     struct device *dev = axp20x->dev;
0851     const struct acpi_device_id *acpi_id;
0852     const struct of_device_id *of_id;
0853 
0854     if (dev->of_node) {
0855         of_id = of_match_device(dev->driver->of_match_table, dev);
0856         if (!of_id) {
0857             dev_err(dev, "Unable to match OF ID\n");
0858             return -ENODEV;
0859         }
0860         axp20x->variant = (long)of_id->data;
0861     } else {
0862         acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
0863         if (!acpi_id || !acpi_id->driver_data) {
0864             dev_err(dev, "Unable to match ACPI ID and data\n");
0865             return -ENODEV;
0866         }
0867         axp20x->variant = (long)acpi_id->driver_data;
0868     }
0869 
0870     switch (axp20x->variant) {
0871     case AXP152_ID:
0872         axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
0873         axp20x->cells = axp152_cells;
0874         axp20x->regmap_cfg = &axp152_regmap_config;
0875         axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
0876         break;
0877     case AXP202_ID:
0878     case AXP209_ID:
0879         axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
0880         axp20x->cells = axp20x_cells;
0881         axp20x->regmap_cfg = &axp20x_regmap_config;
0882         axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
0883         break;
0884     case AXP221_ID:
0885         axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
0886         axp20x->cells = axp221_cells;
0887         axp20x->regmap_cfg = &axp22x_regmap_config;
0888         axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
0889         break;
0890     case AXP223_ID:
0891         axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
0892         axp20x->cells = axp223_cells;
0893         axp20x->regmap_cfg = &axp22x_regmap_config;
0894         axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
0895         break;
0896     case AXP288_ID:
0897         axp20x->cells = axp288_cells;
0898         axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
0899         axp20x->regmap_cfg = &axp288_regmap_config;
0900         axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
0901         axp20x->irq_flags = IRQF_TRIGGER_LOW;
0902         break;
0903     case AXP803_ID:
0904         axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
0905         axp20x->cells = axp803_cells;
0906         axp20x->regmap_cfg = &axp288_regmap_config;
0907         axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
0908         break;
0909     case AXP806_ID:
0910         /*
0911          * Don't register the power key part if in slave mode or
0912          * if there is no interrupt line.
0913          */
0914         if (of_property_read_bool(axp20x->dev->of_node,
0915                       "x-powers,self-working-mode") &&
0916             axp20x->irq > 0) {
0917             axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
0918             axp20x->cells = axp806_self_working_cells;
0919         } else {
0920             axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
0921             axp20x->cells = axp806_cells;
0922         }
0923         axp20x->regmap_cfg = &axp806_regmap_config;
0924         axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
0925         break;
0926     case AXP809_ID:
0927         axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
0928         axp20x->cells = axp809_cells;
0929         axp20x->regmap_cfg = &axp22x_regmap_config;
0930         axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
0931         break;
0932     case AXP813_ID:
0933         axp20x->nr_cells = ARRAY_SIZE(axp813_cells);
0934         axp20x->cells = axp813_cells;
0935         axp20x->regmap_cfg = &axp288_regmap_config;
0936         /*
0937          * The IRQ table given in the datasheet is incorrect.
0938          * In IRQ enable/status registers 1, there are separate
0939          * IRQs for ACIN and VBUS, instead of bits [7:5] being
0940          * the same as bits [4:2]. So it shares the same IRQs
0941          * as the AXP803, rather than the AXP288.
0942          */
0943         axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
0944         break;
0945     default:
0946         dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
0947         return -EINVAL;
0948     }
0949     dev_info(dev, "AXP20x variant %s found\n",
0950          axp20x_model_names[axp20x->variant]);
0951 
0952     return 0;
0953 }
0954 EXPORT_SYMBOL(axp20x_match_device);
0955 
0956 int axp20x_device_probe(struct axp20x_dev *axp20x)
0957 {
0958     int ret;
0959 
0960     /*
0961      * The AXP806 supports either master/standalone or slave mode.
0962      * Slave mode allows sharing the serial bus, even with multiple
0963      * AXP806 which all have the same hardware address.
0964      *
0965      * This is done with extra "serial interface address extension",
0966      * or AXP806_BUS_ADDR_EXT, and "register address extension", or
0967      * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
0968      * 1 bit customizable at the factory, and 1 bit depending on the
0969      * state of an external pin. The latter is writable. The device
0970      * will only respond to operations to its other registers when
0971      * the these device addressing bits (in the upper 4 bits of the
0972      * registers) match.
0973      *
0974      * By default we support an AXP806 chained to an AXP809 in slave
0975      * mode. Boards which use an AXP806 in master mode can set the
0976      * property "x-powers,master-mode" to override the default.
0977      */
0978     if (axp20x->variant == AXP806_ID) {
0979         if (of_property_read_bool(axp20x->dev->of_node,
0980                       "x-powers,master-mode") ||
0981             of_property_read_bool(axp20x->dev->of_node,
0982                       "x-powers,self-working-mode"))
0983             regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
0984                      AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
0985         else
0986             regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
0987                      AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
0988     }
0989 
0990     /* Only if there is an interrupt line connected towards the CPU. */
0991     if (axp20x->irq > 0) {
0992         ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
0993                 IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
0994                 -1, axp20x->regmap_irq_chip,
0995                 &axp20x->regmap_irqc);
0996         if (ret) {
0997             dev_err(axp20x->dev, "failed to add irq chip: %d\n",
0998                 ret);
0999             return ret;
1000         }
1001     }
1002 
1003     ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
1004                   axp20x->nr_cells, NULL, 0, NULL);
1005 
1006     if (ret) {
1007         dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
1008         regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
1009         return ret;
1010     }
1011 
1012     if (!pm_power_off) {
1013         axp20x_pm_power_off = axp20x;
1014         pm_power_off = axp20x_power_off;
1015     }
1016 
1017     dev_info(axp20x->dev, "AXP20X driver loaded\n");
1018 
1019     return 0;
1020 }
1021 EXPORT_SYMBOL(axp20x_device_probe);
1022 
1023 void axp20x_device_remove(struct axp20x_dev *axp20x)
1024 {
1025     if (axp20x == axp20x_pm_power_off) {
1026         axp20x_pm_power_off = NULL;
1027         pm_power_off = NULL;
1028     }
1029 
1030     mfd_remove_devices(axp20x->dev);
1031     regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
1032 }
1033 EXPORT_SYMBOL(axp20x_device_remove);
1034 
1035 MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
1036 MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
1037 MODULE_LICENSE("GPL");