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