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 34c0369698SRask Ingemann Lambertsen #define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE 0 35696f0b3fSChen-Yu Tsai #define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4) 36696f0b3fSChen-Yu Tsai 37c31e858bSKrzysztof Kozlowski static const char * const axp20x_model_names[] = { 38d8d79f8fSMichal Suchanek "AXP152", 39af7e9069SJacob Pan "AXP202", 40af7e9069SJacob Pan "AXP209", 41f05be589SBoris BREZILLON "AXP221", 4202071f0fSChen-Yu Tsai "AXP223", 43af7e9069SJacob Pan "AXP288", 448824ee85SChen-Yu Tsai "AXP806", 4520147f0dSChen-Yu Tsai "AXP809", 46af7e9069SJacob Pan }; 47af7e9069SJacob Pan 48d8d79f8fSMichal Suchanek static const struct regmap_range axp152_writeable_ranges[] = { 49d8d79f8fSMichal Suchanek regmap_reg_range(AXP152_LDO3456_DC1234_CTRL, AXP152_IRQ3_STATE), 50d8d79f8fSMichal Suchanek regmap_reg_range(AXP152_DCDC_MODE, AXP152_PWM1_DUTY_CYCLE), 51d8d79f8fSMichal Suchanek }; 52d8d79f8fSMichal Suchanek 53d8d79f8fSMichal Suchanek static const struct regmap_range axp152_volatile_ranges[] = { 54d8d79f8fSMichal Suchanek regmap_reg_range(AXP152_PWR_OP_MODE, AXP152_PWR_OP_MODE), 55d8d79f8fSMichal Suchanek regmap_reg_range(AXP152_IRQ1_EN, AXP152_IRQ3_STATE), 56d8d79f8fSMichal Suchanek regmap_reg_range(AXP152_GPIO_INPUT, AXP152_GPIO_INPUT), 57d8d79f8fSMichal Suchanek }; 58d8d79f8fSMichal Suchanek 59d8d79f8fSMichal Suchanek static const struct regmap_access_table axp152_writeable_table = { 60d8d79f8fSMichal Suchanek .yes_ranges = axp152_writeable_ranges, 61d8d79f8fSMichal Suchanek .n_yes_ranges = ARRAY_SIZE(axp152_writeable_ranges), 62d8d79f8fSMichal Suchanek }; 63d8d79f8fSMichal Suchanek 64d8d79f8fSMichal Suchanek static const struct regmap_access_table axp152_volatile_table = { 65d8d79f8fSMichal Suchanek .yes_ranges = axp152_volatile_ranges, 66d8d79f8fSMichal Suchanek .n_yes_ranges = ARRAY_SIZE(axp152_volatile_ranges), 67d8d79f8fSMichal Suchanek }; 68d8d79f8fSMichal Suchanek 69cfb61a41SCarlo Caione static const struct regmap_range axp20x_writeable_ranges[] = { 70cfb61a41SCarlo Caione regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), 71cfb61a41SCarlo Caione regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), 72553ed4b5SBruno Prémont regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)), 73cfb61a41SCarlo Caione }; 74cfb61a41SCarlo Caione 75cfb61a41SCarlo Caione static const struct regmap_range axp20x_volatile_ranges[] = { 76553ed4b5SBruno Prémont regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS), 77553ed4b5SBruno Prémont regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2), 78cfb61a41SCarlo Caione regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), 79553ed4b5SBruno Prémont regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), 80553ed4b5SBruno Prémont regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL), 81553ed4b5SBruno Prémont regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L), 82cfb61a41SCarlo Caione }; 83cfb61a41SCarlo Caione 84cfb61a41SCarlo Caione static const struct regmap_access_table axp20x_writeable_table = { 85cfb61a41SCarlo Caione .yes_ranges = axp20x_writeable_ranges, 86cfb61a41SCarlo Caione .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges), 87cfb61a41SCarlo Caione }; 88cfb61a41SCarlo Caione 89cfb61a41SCarlo Caione static const struct regmap_access_table axp20x_volatile_table = { 90cfb61a41SCarlo Caione .yes_ranges = axp20x_volatile_ranges, 91cfb61a41SCarlo Caione .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), 92cfb61a41SCarlo Caione }; 93cfb61a41SCarlo Caione 9420147f0dSChen-Yu Tsai /* AXP22x ranges are shared with the AXP809, as they cover the same range */ 95f05be589SBoris BREZILLON static const struct regmap_range axp22x_writeable_ranges[] = { 96f05be589SBoris BREZILLON regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), 97f05be589SBoris BREZILLON regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1), 98f05be589SBoris BREZILLON }; 99f05be589SBoris BREZILLON 100f05be589SBoris BREZILLON static const struct regmap_range axp22x_volatile_ranges[] = { 10115093250SHans de Goede regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE), 102f05be589SBoris BREZILLON regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), 10315093250SHans de Goede regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), 104ed7311f0SQuentin Schulz regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L), 10515093250SHans de Goede regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES), 106f05be589SBoris BREZILLON }; 107f05be589SBoris BREZILLON 108f05be589SBoris BREZILLON static const struct regmap_access_table axp22x_writeable_table = { 109f05be589SBoris BREZILLON .yes_ranges = axp22x_writeable_ranges, 110f05be589SBoris BREZILLON .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges), 111f05be589SBoris BREZILLON }; 112f05be589SBoris BREZILLON 113f05be589SBoris BREZILLON static const struct regmap_access_table axp22x_volatile_table = { 114f05be589SBoris BREZILLON .yes_ranges = axp22x_volatile_ranges, 115f05be589SBoris BREZILLON .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges), 116f05be589SBoris BREZILLON }; 117f05be589SBoris BREZILLON 118af7e9069SJacob Pan static const struct regmap_range axp288_writeable_ranges[] = { 119af7e9069SJacob Pan regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), 120af7e9069SJacob Pan regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), 121af7e9069SJacob Pan }; 122af7e9069SJacob Pan 123af7e9069SJacob Pan static const struct regmap_range axp288_volatile_ranges[] = { 124cd532166SHans de Goede regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON), 125cd532166SHans de Goede regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), 126cd532166SHans de Goede regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT), 127af7e9069SJacob Pan regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), 128cd532166SHans de Goede regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), 129cd532166SHans de Goede regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), 130cd532166SHans de Goede regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L), 131cd532166SHans de Goede regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG), 132af7e9069SJacob Pan }; 133af7e9069SJacob Pan 134af7e9069SJacob Pan static const struct regmap_access_table axp288_writeable_table = { 135af7e9069SJacob Pan .yes_ranges = axp288_writeable_ranges, 136af7e9069SJacob Pan .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges), 137af7e9069SJacob Pan }; 138af7e9069SJacob Pan 139af7e9069SJacob Pan static const struct regmap_access_table axp288_volatile_table = { 140af7e9069SJacob Pan .yes_ranges = axp288_volatile_ranges, 141af7e9069SJacob Pan .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), 142af7e9069SJacob Pan }; 143af7e9069SJacob Pan 1448824ee85SChen-Yu Tsai static const struct regmap_range axp806_writeable_ranges[] = { 1458824ee85SChen-Yu Tsai regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)), 1468824ee85SChen-Yu Tsai regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL), 1478824ee85SChen-Yu Tsai regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN), 1488824ee85SChen-Yu Tsai regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 14934d9030bSChen-Yu Tsai regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT), 1508824ee85SChen-Yu Tsai }; 1518824ee85SChen-Yu Tsai 1528824ee85SChen-Yu Tsai static const struct regmap_range axp806_volatile_ranges[] = { 1538824ee85SChen-Yu Tsai regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 1548824ee85SChen-Yu Tsai }; 1558824ee85SChen-Yu Tsai 1568824ee85SChen-Yu Tsai static const struct regmap_access_table axp806_writeable_table = { 1578824ee85SChen-Yu Tsai .yes_ranges = axp806_writeable_ranges, 1588824ee85SChen-Yu Tsai .n_yes_ranges = ARRAY_SIZE(axp806_writeable_ranges), 1598824ee85SChen-Yu Tsai }; 1608824ee85SChen-Yu Tsai 1618824ee85SChen-Yu Tsai static const struct regmap_access_table axp806_volatile_table = { 1628824ee85SChen-Yu Tsai .yes_ranges = axp806_volatile_ranges, 1638824ee85SChen-Yu Tsai .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges), 1648824ee85SChen-Yu Tsai }; 1658824ee85SChen-Yu Tsai 166d8d79f8fSMichal Suchanek static struct resource axp152_pek_resources[] = { 167d8d79f8fSMichal Suchanek DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"), 168d8d79f8fSMichal Suchanek DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), 169d8d79f8fSMichal Suchanek }; 170d8d79f8fSMichal Suchanek 171cd7cf27bSMichael Haas static struct resource axp20x_ac_power_supply_resources[] = { 172cd7cf27bSMichael Haas DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), 173cd7cf27bSMichael Haas DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), 174cd7cf27bSMichael Haas DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), 175cd7cf27bSMichael Haas }; 176cd7cf27bSMichael Haas 177cfb61a41SCarlo Caione static struct resource axp20x_pek_resources[] = { 178cfb61a41SCarlo Caione { 179cfb61a41SCarlo Caione .name = "PEK_DBR", 180cfb61a41SCarlo Caione .start = AXP20X_IRQ_PEK_RIS_EDGE, 181cfb61a41SCarlo Caione .end = AXP20X_IRQ_PEK_RIS_EDGE, 182cfb61a41SCarlo Caione .flags = IORESOURCE_IRQ, 183cfb61a41SCarlo Caione }, { 184cfb61a41SCarlo Caione .name = "PEK_DBF", 185cfb61a41SCarlo Caione .start = AXP20X_IRQ_PEK_FAL_EDGE, 186cfb61a41SCarlo Caione .end = AXP20X_IRQ_PEK_FAL_EDGE, 187cfb61a41SCarlo Caione .flags = IORESOURCE_IRQ, 188cfb61a41SCarlo Caione }, 189cfb61a41SCarlo Caione }; 190cfb61a41SCarlo Caione 1918de4efdaSHans de Goede static struct resource axp20x_usb_power_supply_resources[] = { 1928de4efdaSHans de Goede DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 1938de4efdaSHans de Goede DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 1948de4efdaSHans de Goede DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"), 1958de4efdaSHans de Goede DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), 1968de4efdaSHans de Goede }; 1978de4efdaSHans de Goede 198ecd98cceSHans de Goede static struct resource axp22x_usb_power_supply_resources[] = { 199ecd98cceSHans de Goede DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 200ecd98cceSHans de Goede DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 201ecd98cceSHans de Goede }; 202ecd98cceSHans de Goede 203f05be589SBoris BREZILLON static struct resource axp22x_pek_resources[] = { 204f05be589SBoris BREZILLON { 205f05be589SBoris BREZILLON .name = "PEK_DBR", 206f05be589SBoris BREZILLON .start = AXP22X_IRQ_PEK_RIS_EDGE, 207f05be589SBoris BREZILLON .end = AXP22X_IRQ_PEK_RIS_EDGE, 208f05be589SBoris BREZILLON .flags = IORESOURCE_IRQ, 209f05be589SBoris BREZILLON }, { 210f05be589SBoris BREZILLON .name = "PEK_DBF", 211f05be589SBoris BREZILLON .start = AXP22X_IRQ_PEK_FAL_EDGE, 212f05be589SBoris BREZILLON .end = AXP22X_IRQ_PEK_FAL_EDGE, 213f05be589SBoris BREZILLON .flags = IORESOURCE_IRQ, 214f05be589SBoris BREZILLON }, 215f05be589SBoris BREZILLON }; 216f05be589SBoris BREZILLON 217e56e5ad6SBorun Fu static struct resource axp288_power_button_resources[] = { 218e56e5ad6SBorun Fu { 219e56e5ad6SBorun Fu .name = "PEK_DBR", 2201af468ebSHans de Goede .start = AXP288_IRQ_POKP, 2211af468ebSHans de Goede .end = AXP288_IRQ_POKP, 222e56e5ad6SBorun Fu .flags = IORESOURCE_IRQ, 223e56e5ad6SBorun Fu }, 224e56e5ad6SBorun Fu { 225e56e5ad6SBorun Fu .name = "PEK_DBF", 2261af468ebSHans de Goede .start = AXP288_IRQ_POKN, 2271af468ebSHans de Goede .end = AXP288_IRQ_POKN, 228e56e5ad6SBorun Fu .flags = IORESOURCE_IRQ, 229e56e5ad6SBorun Fu }, 230e56e5ad6SBorun Fu }; 231e56e5ad6SBorun Fu 232d6387874STodd Brandt static struct resource axp288_fuel_gauge_resources[] = { 233af7e9069SJacob Pan { 234af7e9069SJacob Pan .start = AXP288_IRQ_QWBTU, 235af7e9069SJacob Pan .end = AXP288_IRQ_QWBTU, 236af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 237af7e9069SJacob Pan }, 238af7e9069SJacob Pan { 239af7e9069SJacob Pan .start = AXP288_IRQ_WBTU, 240af7e9069SJacob Pan .end = AXP288_IRQ_WBTU, 241af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 242af7e9069SJacob Pan }, 243af7e9069SJacob Pan { 244af7e9069SJacob Pan .start = AXP288_IRQ_QWBTO, 245af7e9069SJacob Pan .end = AXP288_IRQ_QWBTO, 246af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 247af7e9069SJacob Pan }, 248af7e9069SJacob Pan { 249af7e9069SJacob Pan .start = AXP288_IRQ_WBTO, 250af7e9069SJacob Pan .end = AXP288_IRQ_WBTO, 251af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 252af7e9069SJacob Pan }, 253af7e9069SJacob Pan { 254af7e9069SJacob Pan .start = AXP288_IRQ_WL2, 255af7e9069SJacob Pan .end = AXP288_IRQ_WL2, 256af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 257af7e9069SJacob Pan }, 258af7e9069SJacob Pan { 259af7e9069SJacob Pan .start = AXP288_IRQ_WL1, 260af7e9069SJacob Pan .end = AXP288_IRQ_WL1, 261af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 262af7e9069SJacob Pan }, 263af7e9069SJacob Pan }; 264af7e9069SJacob Pan 26520147f0dSChen-Yu Tsai static struct resource axp809_pek_resources[] = { 26620147f0dSChen-Yu Tsai { 26720147f0dSChen-Yu Tsai .name = "PEK_DBR", 26820147f0dSChen-Yu Tsai .start = AXP809_IRQ_PEK_RIS_EDGE, 26920147f0dSChen-Yu Tsai .end = AXP809_IRQ_PEK_RIS_EDGE, 27020147f0dSChen-Yu Tsai .flags = IORESOURCE_IRQ, 27120147f0dSChen-Yu Tsai }, { 27220147f0dSChen-Yu Tsai .name = "PEK_DBF", 27320147f0dSChen-Yu Tsai .start = AXP809_IRQ_PEK_FAL_EDGE, 27420147f0dSChen-Yu Tsai .end = AXP809_IRQ_PEK_FAL_EDGE, 27520147f0dSChen-Yu Tsai .flags = IORESOURCE_IRQ, 27620147f0dSChen-Yu Tsai }, 27720147f0dSChen-Yu Tsai }; 27820147f0dSChen-Yu Tsai 279d8d79f8fSMichal Suchanek static const struct regmap_config axp152_regmap_config = { 280d8d79f8fSMichal Suchanek .reg_bits = 8, 281d8d79f8fSMichal Suchanek .val_bits = 8, 282d8d79f8fSMichal Suchanek .wr_table = &axp152_writeable_table, 283d8d79f8fSMichal Suchanek .volatile_table = &axp152_volatile_table, 284d8d79f8fSMichal Suchanek .max_register = AXP152_PWM1_DUTY_CYCLE, 285d8d79f8fSMichal Suchanek .cache_type = REGCACHE_RBTREE, 286d8d79f8fSMichal Suchanek }; 287d8d79f8fSMichal Suchanek 288cfb61a41SCarlo Caione static const struct regmap_config axp20x_regmap_config = { 289cfb61a41SCarlo Caione .reg_bits = 8, 290cfb61a41SCarlo Caione .val_bits = 8, 291cfb61a41SCarlo Caione .wr_table = &axp20x_writeable_table, 292cfb61a41SCarlo Caione .volatile_table = &axp20x_volatile_table, 293553ed4b5SBruno Prémont .max_register = AXP20X_OCV(AXP20X_OCV_MAX), 294cfb61a41SCarlo Caione .cache_type = REGCACHE_RBTREE, 295cfb61a41SCarlo Caione }; 296cfb61a41SCarlo Caione 297f05be589SBoris BREZILLON static const struct regmap_config axp22x_regmap_config = { 298f05be589SBoris BREZILLON .reg_bits = 8, 299f05be589SBoris BREZILLON .val_bits = 8, 300f05be589SBoris BREZILLON .wr_table = &axp22x_writeable_table, 301f05be589SBoris BREZILLON .volatile_table = &axp22x_volatile_table, 302f05be589SBoris BREZILLON .max_register = AXP22X_BATLOW_THRES1, 303f05be589SBoris BREZILLON .cache_type = REGCACHE_RBTREE, 304f05be589SBoris BREZILLON }; 305f05be589SBoris BREZILLON 306af7e9069SJacob Pan static const struct regmap_config axp288_regmap_config = { 307af7e9069SJacob Pan .reg_bits = 8, 308af7e9069SJacob Pan .val_bits = 8, 309af7e9069SJacob Pan .wr_table = &axp288_writeable_table, 310af7e9069SJacob Pan .volatile_table = &axp288_volatile_table, 311af7e9069SJacob Pan .max_register = AXP288_FG_TUNE5, 312af7e9069SJacob Pan .cache_type = REGCACHE_RBTREE, 313af7e9069SJacob Pan }; 314af7e9069SJacob Pan 3158824ee85SChen-Yu Tsai static const struct regmap_config axp806_regmap_config = { 3168824ee85SChen-Yu Tsai .reg_bits = 8, 3178824ee85SChen-Yu Tsai .val_bits = 8, 3188824ee85SChen-Yu Tsai .wr_table = &axp806_writeable_table, 3198824ee85SChen-Yu Tsai .volatile_table = &axp806_volatile_table, 32034d9030bSChen-Yu Tsai .max_register = AXP806_REG_ADDR_EXT, 3218824ee85SChen-Yu Tsai .cache_type = REGCACHE_RBTREE, 3228824ee85SChen-Yu Tsai }; 3238824ee85SChen-Yu Tsai 324af7e9069SJacob Pan #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ 325af7e9069SJacob Pan [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } 326cfb61a41SCarlo Caione 327d8d79f8fSMichal Suchanek static const struct regmap_irq axp152_regmap_irqs[] = { 328d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, LDO0IN_CONNECT, 0, 6), 329d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, LDO0IN_REMOVAL, 0, 5), 330d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, ALDO0IN_CONNECT, 0, 3), 331d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, ALDO0IN_REMOVAL, 0, 2), 332d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW, 1, 5), 333d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW, 1, 4), 334d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW, 1, 3), 335d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW, 1, 2), 336d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, PEK_SHORT, 1, 1), 337d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, PEK_LONG, 1, 0), 338d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, TIMER, 2, 7), 339d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE, 2, 6), 340d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE, 2, 5), 341d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT, 2, 3), 342d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT, 2, 2), 343d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT, 2, 1), 344d8d79f8fSMichal Suchanek INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), 345d8d79f8fSMichal Suchanek }; 346d8d79f8fSMichal Suchanek 347cfb61a41SCarlo Caione static const struct regmap_irq axp20x_regmap_irqs[] = { 348af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), 349af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6), 350af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL, 0, 5), 351af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V, 0, 4), 352af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN, 0, 3), 353af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL, 0, 2), 354af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW, 0, 1), 355af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN, 1, 7), 356af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL, 1, 6), 357af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE, 1, 5), 358af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4), 359af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, CHARG, 1, 3), 360af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, CHARG_DONE, 1, 2), 361af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH, 1, 1), 362af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW, 1, 0), 363af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH, 2, 7), 364af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW, 2, 6), 365af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG, 2, 5), 366af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG, 2, 4), 367af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG, 2, 3), 368af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, PEK_SHORT, 2, 1), 369af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, PEK_LONG, 2, 0), 370af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON, 3, 7), 371af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF, 3, 6), 372af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_VALID, 3, 5), 373af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID, 3, 4), 374af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID, 3, 3), 375af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END, 3, 2), 376af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1, 3, 1), 377af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2, 3, 0), 378af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, TIMER, 4, 7), 379af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE, 4, 6), 380af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE, 4, 5), 381af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT, 4, 3), 382af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT, 4, 2), 383af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT, 4, 1), 384af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0), 385af7e9069SJacob Pan }; 386af7e9069SJacob Pan 387f05be589SBoris BREZILLON static const struct regmap_irq axp22x_regmap_irqs[] = { 388f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V, 0, 7), 389f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN, 0, 6), 390f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL, 0, 5), 391f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V, 0, 4), 392f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN, 0, 3), 393f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL, 0, 2), 394f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW, 0, 1), 395f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN, 1, 7), 396f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL, 1, 6), 397f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE, 1, 5), 398f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4), 399f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, CHARG, 1, 3), 400f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, CHARG_DONE, 1, 2), 401f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH, 1, 1), 402f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW, 1, 0), 403f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH, 2, 7), 404f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, PEK_SHORT, 2, 1), 405f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, PEK_LONG, 2, 0), 406f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1, 3, 1), 407f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2, 3, 0), 408f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, TIMER, 4, 7), 409f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE, 4, 6), 410f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE, 4, 5), 411f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT, 4, 1), 412f05be589SBoris BREZILLON INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT, 4, 0), 413f05be589SBoris BREZILLON }; 414f05be589SBoris BREZILLON 415af7e9069SJacob Pan /* some IRQs are compatible with axp20x models */ 416af7e9069SJacob Pan static const struct regmap_irq axp288_regmap_irqs[] = { 417ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2), 418ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, VBUS_RISE, 0, 3), 419ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, OV, 0, 4), 4208b44e678SHans de Goede INIT_REGMAP_IRQ(AXP288, FALLING_ALT, 0, 5), 4218b44e678SHans de Goede INIT_REGMAP_IRQ(AXP288, RISING_ALT, 0, 6), 4228b44e678SHans de Goede INIT_REGMAP_IRQ(AXP288, OV_ALT, 0, 7), 423af7e9069SJacob Pan 424ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, DONE, 1, 2), 425ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, CHARGING, 1, 3), 426af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, SAFE_QUIT, 1, 4), 427af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, SAFE_ENTER, 1, 5), 428ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, ABSENT, 1, 6), 429ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, APPEND, 1, 7), 430af7e9069SJacob Pan 431af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, QWBTU, 2, 0), 432af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, WBTU, 2, 1), 433af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, QWBTO, 2, 2), 434ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, WBTO, 2, 3), 435af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, QCBTU, 2, 4), 436af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, CBTU, 2, 5), 437af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, QCBTO, 2, 6), 438af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, CBTO, 2, 7), 439af7e9069SJacob Pan 440af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, WL2, 3, 0), 441af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, WL1, 3, 1), 442af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, GPADC, 3, 2), 443af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, OT, 3, 7), 444af7e9069SJacob Pan 445af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, GPIO0, 4, 0), 446af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, GPIO1, 4, 1), 447af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, POKO, 4, 2), 448af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, POKL, 4, 3), 449af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, POKS, 4, 4), 450af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, POKN, 4, 5), 451af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, POKP, 4, 6), 452ff3bbc5cSJacob Pan INIT_REGMAP_IRQ(AXP288, TIMER, 4, 7), 453af7e9069SJacob Pan 454af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, MV_CHNG, 5, 0), 455af7e9069SJacob Pan INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), 456cfb61a41SCarlo Caione }; 457cfb61a41SCarlo Caione 4588824ee85SChen-Yu Tsai static const struct regmap_irq axp806_regmap_irqs[] = { 4598824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0), 4608824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1), 4618824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW, 0, 3), 4628824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW, 0, 4), 4638824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5), 4648824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6), 4658824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7), 4668824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0), 4678824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1), 4688824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4), 4698824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5), 4708824ee85SChen-Yu Tsai INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6), 4718824ee85SChen-Yu Tsai }; 4728824ee85SChen-Yu Tsai 47320147f0dSChen-Yu Tsai static const struct regmap_irq axp809_regmap_irqs[] = { 47420147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7), 47520147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6), 47620147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL, 0, 5), 47720147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V, 0, 4), 47820147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN, 0, 3), 47920147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL, 0, 2), 48020147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW, 0, 1), 48120147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN, 1, 7), 48220147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL, 1, 6), 48320147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE, 1, 5), 48420147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE, 1, 4), 48520147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, CHARG, 1, 3), 48620147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, CHARG_DONE, 1, 2), 48720147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH, 2, 7), 48820147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END, 2, 6), 48920147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW, 2, 5), 49020147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END, 2, 4), 49120147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH, 2, 3), 49220147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END, 2, 2), 49320147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW, 2, 1), 49420147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END, 2, 0), 49520147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH, 3, 7), 49620147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1, 3, 1), 49720147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2, 3, 0), 49820147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, TIMER, 4, 7), 49920147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE, 4, 6), 50020147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE, 4, 5), 50120147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, PEK_SHORT, 4, 4), 50220147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, PEK_LONG, 4, 3), 50320147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF, 4, 2), 50420147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT, 4, 1), 50520147f0dSChen-Yu Tsai INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0), 50620147f0dSChen-Yu Tsai }; 50720147f0dSChen-Yu Tsai 508d8d79f8fSMichal Suchanek static const struct regmap_irq_chip axp152_regmap_irq_chip = { 509d8d79f8fSMichal Suchanek .name = "axp152_irq_chip", 510d8d79f8fSMichal Suchanek .status_base = AXP152_IRQ1_STATE, 511d8d79f8fSMichal Suchanek .ack_base = AXP152_IRQ1_STATE, 512d8d79f8fSMichal Suchanek .mask_base = AXP152_IRQ1_EN, 513d8d79f8fSMichal Suchanek .mask_invert = true, 514d8d79f8fSMichal Suchanek .init_ack_masked = true, 515d8d79f8fSMichal Suchanek .irqs = axp152_regmap_irqs, 516d8d79f8fSMichal Suchanek .num_irqs = ARRAY_SIZE(axp152_regmap_irqs), 517d8d79f8fSMichal Suchanek .num_regs = 3, 518d8d79f8fSMichal Suchanek }; 519d8d79f8fSMichal Suchanek 520cfb61a41SCarlo Caione static const struct regmap_irq_chip axp20x_regmap_irq_chip = { 521cfb61a41SCarlo Caione .name = "axp20x_irq_chip", 522cfb61a41SCarlo Caione .status_base = AXP20X_IRQ1_STATE, 523cfb61a41SCarlo Caione .ack_base = AXP20X_IRQ1_STATE, 524cfb61a41SCarlo Caione .mask_base = AXP20X_IRQ1_EN, 525cfb61a41SCarlo Caione .mask_invert = true, 526cfb61a41SCarlo Caione .init_ack_masked = true, 527af7e9069SJacob Pan .irqs = axp20x_regmap_irqs, 528af7e9069SJacob Pan .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), 529af7e9069SJacob Pan .num_regs = 5, 530af7e9069SJacob Pan 531af7e9069SJacob Pan }; 532af7e9069SJacob Pan 533f05be589SBoris BREZILLON static const struct regmap_irq_chip axp22x_regmap_irq_chip = { 534f05be589SBoris BREZILLON .name = "axp22x_irq_chip", 535f05be589SBoris BREZILLON .status_base = AXP20X_IRQ1_STATE, 536f05be589SBoris BREZILLON .ack_base = AXP20X_IRQ1_STATE, 537f05be589SBoris BREZILLON .mask_base = AXP20X_IRQ1_EN, 538f05be589SBoris BREZILLON .mask_invert = true, 539f05be589SBoris BREZILLON .init_ack_masked = true, 540f05be589SBoris BREZILLON .irqs = axp22x_regmap_irqs, 541f05be589SBoris BREZILLON .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs), 542f05be589SBoris BREZILLON .num_regs = 5, 543f05be589SBoris BREZILLON }; 544f05be589SBoris BREZILLON 545af7e9069SJacob Pan static const struct regmap_irq_chip axp288_regmap_irq_chip = { 546af7e9069SJacob Pan .name = "axp288_irq_chip", 547af7e9069SJacob Pan .status_base = AXP20X_IRQ1_STATE, 548af7e9069SJacob Pan .ack_base = AXP20X_IRQ1_STATE, 549af7e9069SJacob Pan .mask_base = AXP20X_IRQ1_EN, 550af7e9069SJacob Pan .mask_invert = true, 551af7e9069SJacob Pan .init_ack_masked = true, 552af7e9069SJacob Pan .irqs = axp288_regmap_irqs, 553af7e9069SJacob Pan .num_irqs = ARRAY_SIZE(axp288_regmap_irqs), 554af7e9069SJacob Pan .num_regs = 6, 555af7e9069SJacob Pan 556cfb61a41SCarlo Caione }; 557cfb61a41SCarlo Caione 5588824ee85SChen-Yu Tsai static const struct regmap_irq_chip axp806_regmap_irq_chip = { 5598824ee85SChen-Yu Tsai .name = "axp806", 5608824ee85SChen-Yu Tsai .status_base = AXP20X_IRQ1_STATE, 5618824ee85SChen-Yu Tsai .ack_base = AXP20X_IRQ1_STATE, 5628824ee85SChen-Yu Tsai .mask_base = AXP20X_IRQ1_EN, 5638824ee85SChen-Yu Tsai .mask_invert = true, 5648824ee85SChen-Yu Tsai .init_ack_masked = true, 5658824ee85SChen-Yu Tsai .irqs = axp806_regmap_irqs, 5668824ee85SChen-Yu Tsai .num_irqs = ARRAY_SIZE(axp806_regmap_irqs), 5678824ee85SChen-Yu Tsai .num_regs = 2, 5688824ee85SChen-Yu Tsai }; 5698824ee85SChen-Yu Tsai 57020147f0dSChen-Yu Tsai static const struct regmap_irq_chip axp809_regmap_irq_chip = { 57120147f0dSChen-Yu Tsai .name = "axp809", 57220147f0dSChen-Yu Tsai .status_base = AXP20X_IRQ1_STATE, 57320147f0dSChen-Yu Tsai .ack_base = AXP20X_IRQ1_STATE, 57420147f0dSChen-Yu Tsai .mask_base = AXP20X_IRQ1_EN, 57520147f0dSChen-Yu Tsai .mask_invert = true, 57620147f0dSChen-Yu Tsai .init_ack_masked = true, 57720147f0dSChen-Yu Tsai .irqs = axp809_regmap_irqs, 57820147f0dSChen-Yu Tsai .num_irqs = ARRAY_SIZE(axp809_regmap_irqs), 57920147f0dSChen-Yu Tsai .num_regs = 5, 58020147f0dSChen-Yu Tsai }; 58120147f0dSChen-Yu Tsai 582cfb61a41SCarlo Caione static struct mfd_cell axp20x_cells[] = { 583cfb61a41SCarlo Caione { 584b419c16bSMaxime Ripard .name = "axp20x-gpio", 585b419c16bSMaxime Ripard .of_compatible = "x-powers,axp209-gpio", 586b419c16bSMaxime Ripard }, { 587cfb61a41SCarlo Caione .name = "axp20x-pek", 588cfb61a41SCarlo Caione .num_resources = ARRAY_SIZE(axp20x_pek_resources), 589cfb61a41SCarlo Caione .resources = axp20x_pek_resources, 590cfb61a41SCarlo Caione }, { 591cfb61a41SCarlo Caione .name = "axp20x-regulator", 5928de4efdaSHans de Goede }, { 5934d5e5c34SQuentin Schulz .name = "axp20x-adc", 5944d5e5c34SQuentin Schulz }, { 595cd7cf27bSMichael Haas .name = "axp20x-ac-power-supply", 596cd7cf27bSMichael Haas .of_compatible = "x-powers,axp202-ac-power-supply", 597cd7cf27bSMichael Haas .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 598cd7cf27bSMichael Haas .resources = axp20x_ac_power_supply_resources, 599cd7cf27bSMichael Haas }, { 6008de4efdaSHans de Goede .name = "axp20x-usb-power-supply", 6018de4efdaSHans de Goede .of_compatible = "x-powers,axp202-usb-power-supply", 6028de4efdaSHans de Goede .num_resources = ARRAY_SIZE(axp20x_usb_power_supply_resources), 6038de4efdaSHans de Goede .resources = axp20x_usb_power_supply_resources, 604cfb61a41SCarlo Caione }, 605cfb61a41SCarlo Caione }; 606cfb61a41SCarlo Caione 6074c650561SQuentin Schulz static struct mfd_cell axp221_cells[] = { 608f05be589SBoris BREZILLON { 609f05be589SBoris BREZILLON .name = "axp20x-pek", 610f05be589SBoris BREZILLON .num_resources = ARRAY_SIZE(axp22x_pek_resources), 611f05be589SBoris BREZILLON .resources = axp22x_pek_resources, 6126d4fa89dSChen-Yu Tsai }, { 6136d4fa89dSChen-Yu Tsai .name = "axp20x-regulator", 614ecd98cceSHans de Goede }, { 6154d5e5c34SQuentin Schulz .name = "axp22x-adc" 6164d5e5c34SQuentin Schulz }, { 617ecd98cceSHans de Goede .name = "axp20x-usb-power-supply", 618ecd98cceSHans de Goede .of_compatible = "x-powers,axp221-usb-power-supply", 619ecd98cceSHans de Goede .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), 620ecd98cceSHans de Goede .resources = axp22x_usb_power_supply_resources, 621f05be589SBoris BREZILLON }, 622f05be589SBoris BREZILLON }; 623f05be589SBoris BREZILLON 6244c650561SQuentin Schulz static struct mfd_cell axp223_cells[] = { 6254c650561SQuentin Schulz { 6264c650561SQuentin Schulz .name = "axp20x-pek", 6274c650561SQuentin Schulz .num_resources = ARRAY_SIZE(axp22x_pek_resources), 6284c650561SQuentin Schulz .resources = axp22x_pek_resources, 6294c650561SQuentin Schulz }, { 6304d5e5c34SQuentin Schulz .name = "axp22x-adc", 6314d5e5c34SQuentin Schulz }, { 6324c650561SQuentin Schulz .name = "axp20x-regulator", 6334c650561SQuentin Schulz }, { 6344c650561SQuentin Schulz .name = "axp20x-usb-power-supply", 6354c650561SQuentin Schulz .of_compatible = "x-powers,axp223-usb-power-supply", 6364c650561SQuentin Schulz .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), 6374c650561SQuentin Schulz .resources = axp22x_usb_power_supply_resources, 6384c650561SQuentin Schulz }, 6394c650561SQuentin Schulz }; 6404c650561SQuentin Schulz 641d8d79f8fSMichal Suchanek static struct mfd_cell axp152_cells[] = { 642d8d79f8fSMichal Suchanek { 643d8d79f8fSMichal Suchanek .name = "axp20x-pek", 644d8d79f8fSMichal Suchanek .num_resources = ARRAY_SIZE(axp152_pek_resources), 645d8d79f8fSMichal Suchanek .resources = axp152_pek_resources, 646d8d79f8fSMichal Suchanek }, 647d8d79f8fSMichal Suchanek }; 648d8d79f8fSMichal Suchanek 649af7e9069SJacob Pan static struct resource axp288_adc_resources[] = { 650af7e9069SJacob Pan { 651af7e9069SJacob Pan .name = "GPADC", 652af7e9069SJacob Pan .start = AXP288_IRQ_GPADC, 653af7e9069SJacob Pan .end = AXP288_IRQ_GPADC, 654af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 655af7e9069SJacob Pan }, 656af7e9069SJacob Pan }; 657af7e9069SJacob Pan 658bdb01f78SRamakrishna Pallala static struct resource axp288_extcon_resources[] = { 659bdb01f78SRamakrishna Pallala { 660bdb01f78SRamakrishna Pallala .start = AXP288_IRQ_VBUS_FALL, 661bdb01f78SRamakrishna Pallala .end = AXP288_IRQ_VBUS_FALL, 662bdb01f78SRamakrishna Pallala .flags = IORESOURCE_IRQ, 663bdb01f78SRamakrishna Pallala }, 664bdb01f78SRamakrishna Pallala { 665bdb01f78SRamakrishna Pallala .start = AXP288_IRQ_VBUS_RISE, 666bdb01f78SRamakrishna Pallala .end = AXP288_IRQ_VBUS_RISE, 667bdb01f78SRamakrishna Pallala .flags = IORESOURCE_IRQ, 668bdb01f78SRamakrishna Pallala }, 669bdb01f78SRamakrishna Pallala { 670bdb01f78SRamakrishna Pallala .start = AXP288_IRQ_MV_CHNG, 671bdb01f78SRamakrishna Pallala .end = AXP288_IRQ_MV_CHNG, 672bdb01f78SRamakrishna Pallala .flags = IORESOURCE_IRQ, 673bdb01f78SRamakrishna Pallala }, 674bdb01f78SRamakrishna Pallala { 675bdb01f78SRamakrishna Pallala .start = AXP288_IRQ_BC_USB_CHNG, 676bdb01f78SRamakrishna Pallala .end = AXP288_IRQ_BC_USB_CHNG, 677bdb01f78SRamakrishna Pallala .flags = IORESOURCE_IRQ, 678bdb01f78SRamakrishna Pallala }, 679bdb01f78SRamakrishna Pallala }; 680bdb01f78SRamakrishna Pallala 681af7e9069SJacob Pan static struct resource axp288_charger_resources[] = { 682af7e9069SJacob Pan { 683af7e9069SJacob Pan .start = AXP288_IRQ_OV, 684af7e9069SJacob Pan .end = AXP288_IRQ_OV, 685af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 686af7e9069SJacob Pan }, 687af7e9069SJacob Pan { 688af7e9069SJacob Pan .start = AXP288_IRQ_DONE, 689af7e9069SJacob Pan .end = AXP288_IRQ_DONE, 690af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 691af7e9069SJacob Pan }, 692af7e9069SJacob Pan { 693af7e9069SJacob Pan .start = AXP288_IRQ_CHARGING, 694af7e9069SJacob Pan .end = AXP288_IRQ_CHARGING, 695af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 696af7e9069SJacob Pan }, 697af7e9069SJacob Pan { 698af7e9069SJacob Pan .start = AXP288_IRQ_SAFE_QUIT, 699af7e9069SJacob Pan .end = AXP288_IRQ_SAFE_QUIT, 700af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 701af7e9069SJacob Pan }, 702af7e9069SJacob Pan { 703af7e9069SJacob Pan .start = AXP288_IRQ_SAFE_ENTER, 704af7e9069SJacob Pan .end = AXP288_IRQ_SAFE_ENTER, 705af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 706af7e9069SJacob Pan }, 707af7e9069SJacob Pan { 708af7e9069SJacob Pan .start = AXP288_IRQ_QCBTU, 709af7e9069SJacob Pan .end = AXP288_IRQ_QCBTU, 710af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 711af7e9069SJacob Pan }, 712af7e9069SJacob Pan { 713af7e9069SJacob Pan .start = AXP288_IRQ_CBTU, 714af7e9069SJacob Pan .end = AXP288_IRQ_CBTU, 715af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 716af7e9069SJacob Pan }, 717af7e9069SJacob Pan { 718af7e9069SJacob Pan .start = AXP288_IRQ_QCBTO, 719af7e9069SJacob Pan .end = AXP288_IRQ_QCBTO, 720af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 721af7e9069SJacob Pan }, 722af7e9069SJacob Pan { 723af7e9069SJacob Pan .start = AXP288_IRQ_CBTO, 724af7e9069SJacob Pan .end = AXP288_IRQ_CBTO, 725af7e9069SJacob Pan .flags = IORESOURCE_IRQ, 726af7e9069SJacob Pan }, 727af7e9069SJacob Pan }; 728af7e9069SJacob Pan 729af7e9069SJacob Pan static struct mfd_cell axp288_cells[] = { 730af7e9069SJacob Pan { 731af7e9069SJacob Pan .name = "axp288_adc", 732af7e9069SJacob Pan .num_resources = ARRAY_SIZE(axp288_adc_resources), 733af7e9069SJacob Pan .resources = axp288_adc_resources, 734af7e9069SJacob Pan }, 735af7e9069SJacob Pan { 736bdb01f78SRamakrishna Pallala .name = "axp288_extcon", 737bdb01f78SRamakrishna Pallala .num_resources = ARRAY_SIZE(axp288_extcon_resources), 738bdb01f78SRamakrishna Pallala .resources = axp288_extcon_resources, 739bdb01f78SRamakrishna Pallala }, 740bdb01f78SRamakrishna Pallala { 741af7e9069SJacob Pan .name = "axp288_charger", 742af7e9069SJacob Pan .num_resources = ARRAY_SIZE(axp288_charger_resources), 743af7e9069SJacob Pan .resources = axp288_charger_resources, 744af7e9069SJacob Pan }, 745af7e9069SJacob Pan { 746d6387874STodd Brandt .name = "axp288_fuel_gauge", 747d6387874STodd Brandt .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), 748d6387874STodd Brandt .resources = axp288_fuel_gauge_resources, 749af7e9069SJacob Pan }, 750d8139f63SAaron Lu { 751e56e5ad6SBorun Fu .name = "axp20x-pek", 752e56e5ad6SBorun Fu .num_resources = ARRAY_SIZE(axp288_power_button_resources), 753e56e5ad6SBorun Fu .resources = axp288_power_button_resources, 754e56e5ad6SBorun Fu }, 755e56e5ad6SBorun Fu { 756d8139f63SAaron Lu .name = "axp288_pmic_acpi", 757d8139f63SAaron Lu }, 758af7e9069SJacob Pan }; 759af7e9069SJacob Pan 7608824ee85SChen-Yu Tsai static struct mfd_cell axp806_cells[] = { 7618824ee85SChen-Yu Tsai { 7628824ee85SChen-Yu Tsai .id = 2, 7638824ee85SChen-Yu Tsai .name = "axp20x-regulator", 7648824ee85SChen-Yu Tsai }, 7658824ee85SChen-Yu Tsai }; 7668824ee85SChen-Yu Tsai 76720147f0dSChen-Yu Tsai static struct mfd_cell axp809_cells[] = { 76820147f0dSChen-Yu Tsai { 76920147f0dSChen-Yu Tsai .name = "axp20x-pek", 77020147f0dSChen-Yu Tsai .num_resources = ARRAY_SIZE(axp809_pek_resources), 77120147f0dSChen-Yu Tsai .resources = axp809_pek_resources, 77220147f0dSChen-Yu Tsai }, { 7738824ee85SChen-Yu Tsai .id = 1, 77420147f0dSChen-Yu Tsai .name = "axp20x-regulator", 77520147f0dSChen-Yu Tsai }, 77620147f0dSChen-Yu Tsai }; 77720147f0dSChen-Yu Tsai 778cfb61a41SCarlo Caione static struct axp20x_dev *axp20x_pm_power_off; 779cfb61a41SCarlo Caione static void axp20x_power_off(void) 780cfb61a41SCarlo Caione { 781af7e9069SJacob Pan if (axp20x_pm_power_off->variant == AXP288_ID) 782af7e9069SJacob Pan return; 783af7e9069SJacob Pan 784cfb61a41SCarlo Caione regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, 785cfb61a41SCarlo Caione AXP20X_OFF); 786179dc63dSHans de Goede 787179dc63dSHans de Goede /* Give capacitors etc. time to drain to avoid kernel panic msg. */ 788179dc63dSHans de Goede msleep(500); 789cfb61a41SCarlo Caione } 790cfb61a41SCarlo Caione 7914fd41151SChen-Yu Tsai int axp20x_match_device(struct axp20x_dev *axp20x) 792af7e9069SJacob Pan { 793e47a3cf7SChen-Yu Tsai struct device *dev = axp20x->dev; 794af7e9069SJacob Pan const struct acpi_device_id *acpi_id; 795af7e9069SJacob Pan const struct of_device_id *of_id; 796af7e9069SJacob Pan 797af7e9069SJacob Pan if (dev->of_node) { 798af7acc3dSChen-Yu Tsai of_id = of_match_device(dev->driver->of_match_table, dev); 799af7e9069SJacob Pan if (!of_id) { 800af7e9069SJacob Pan dev_err(dev, "Unable to match OF ID\n"); 801af7e9069SJacob Pan return -ENODEV; 802af7e9069SJacob Pan } 803af7e9069SJacob Pan axp20x->variant = (long)of_id->data; 804af7e9069SJacob Pan } else { 805af7e9069SJacob Pan acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); 806af7e9069SJacob Pan if (!acpi_id || !acpi_id->driver_data) { 807af7e9069SJacob Pan dev_err(dev, "Unable to match ACPI ID and data\n"); 808af7e9069SJacob Pan return -ENODEV; 809af7e9069SJacob Pan } 810af7e9069SJacob Pan axp20x->variant = (long)acpi_id->driver_data; 811af7e9069SJacob Pan } 812af7e9069SJacob Pan 813af7e9069SJacob Pan switch (axp20x->variant) { 814d8d79f8fSMichal Suchanek case AXP152_ID: 815d8d79f8fSMichal Suchanek axp20x->nr_cells = ARRAY_SIZE(axp152_cells); 816d8d79f8fSMichal Suchanek axp20x->cells = axp152_cells; 817d8d79f8fSMichal Suchanek axp20x->regmap_cfg = &axp152_regmap_config; 818d8d79f8fSMichal Suchanek axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; 819d8d79f8fSMichal Suchanek break; 820af7e9069SJacob Pan case AXP202_ID: 821af7e9069SJacob Pan case AXP209_ID: 822af7e9069SJacob Pan axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); 823af7e9069SJacob Pan axp20x->cells = axp20x_cells; 824af7e9069SJacob Pan axp20x->regmap_cfg = &axp20x_regmap_config; 825af7e9069SJacob Pan axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip; 826af7e9069SJacob Pan break; 827f05be589SBoris BREZILLON case AXP221_ID: 8284c650561SQuentin Schulz axp20x->nr_cells = ARRAY_SIZE(axp221_cells); 8294c650561SQuentin Schulz axp20x->cells = axp221_cells; 8304c650561SQuentin Schulz axp20x->regmap_cfg = &axp22x_regmap_config; 8314c650561SQuentin Schulz axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip; 8324c650561SQuentin Schulz break; 83302071f0fSChen-Yu Tsai case AXP223_ID: 8344c650561SQuentin Schulz axp20x->nr_cells = ARRAY_SIZE(axp223_cells); 8354c650561SQuentin Schulz axp20x->cells = axp223_cells; 836f05be589SBoris BREZILLON axp20x->regmap_cfg = &axp22x_regmap_config; 837f05be589SBoris BREZILLON axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip; 838f05be589SBoris BREZILLON break; 839af7e9069SJacob Pan case AXP288_ID: 840af7e9069SJacob Pan axp20x->cells = axp288_cells; 841af7e9069SJacob Pan axp20x->nr_cells = ARRAY_SIZE(axp288_cells); 842af7e9069SJacob Pan axp20x->regmap_cfg = &axp288_regmap_config; 843af7e9069SJacob Pan axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; 8440a5454c9SHans de Goede axp20x->irq_flags = IRQF_TRIGGER_LOW; 845af7e9069SJacob Pan break; 8468824ee85SChen-Yu Tsai case AXP806_ID: 8478824ee85SChen-Yu Tsai axp20x->nr_cells = ARRAY_SIZE(axp806_cells); 8488824ee85SChen-Yu Tsai axp20x->cells = axp806_cells; 8498824ee85SChen-Yu Tsai axp20x->regmap_cfg = &axp806_regmap_config; 8508824ee85SChen-Yu Tsai axp20x->regmap_irq_chip = &axp806_regmap_irq_chip; 8518824ee85SChen-Yu Tsai break; 85220147f0dSChen-Yu Tsai case AXP809_ID: 85320147f0dSChen-Yu Tsai axp20x->nr_cells = ARRAY_SIZE(axp809_cells); 85420147f0dSChen-Yu Tsai axp20x->cells = axp809_cells; 85520147f0dSChen-Yu Tsai axp20x->regmap_cfg = &axp22x_regmap_config; 85620147f0dSChen-Yu Tsai axp20x->regmap_irq_chip = &axp809_regmap_irq_chip; 85720147f0dSChen-Yu Tsai break; 858af7e9069SJacob Pan default: 859af7e9069SJacob Pan dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); 860af7e9069SJacob Pan return -EINVAL; 861af7e9069SJacob Pan } 862af7e9069SJacob Pan dev_info(dev, "AXP20x variant %s found\n", 863af7e9069SJacob Pan axp20x_model_names[axp20x->variant]); 864af7e9069SJacob Pan 865af7e9069SJacob Pan return 0; 866af7e9069SJacob Pan } 8674fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_match_device); 868af7e9069SJacob Pan 8694fd41151SChen-Yu Tsai int axp20x_device_probe(struct axp20x_dev *axp20x) 870cfb61a41SCarlo Caione { 871cfb61a41SCarlo Caione int ret; 872cfb61a41SCarlo Caione 873696f0b3fSChen-Yu Tsai /* 874696f0b3fSChen-Yu Tsai * The AXP806 supports either master/standalone or slave mode. 875696f0b3fSChen-Yu Tsai * Slave mode allows sharing the serial bus, even with multiple 876696f0b3fSChen-Yu Tsai * AXP806 which all have the same hardware address. 877696f0b3fSChen-Yu Tsai * 878696f0b3fSChen-Yu Tsai * This is done with extra "serial interface address extension", 879696f0b3fSChen-Yu Tsai * or AXP806_BUS_ADDR_EXT, and "register address extension", or 880696f0b3fSChen-Yu Tsai * AXP806_REG_ADDR_EXT, registers. The former is read-only, with 881696f0b3fSChen-Yu Tsai * 1 bit customizable at the factory, and 1 bit depending on the 882696f0b3fSChen-Yu Tsai * state of an external pin. The latter is writable. The device 883696f0b3fSChen-Yu Tsai * will only respond to operations to its other registers when 884696f0b3fSChen-Yu Tsai * the these device addressing bits (in the upper 4 bits of the 885696f0b3fSChen-Yu Tsai * registers) match. 886696f0b3fSChen-Yu Tsai * 887c0369698SRask Ingemann Lambertsen * By default we support an AXP806 chained to an AXP809 in slave 888c0369698SRask Ingemann Lambertsen * mode. Boards which use an AXP806 in master mode can set the 889c0369698SRask Ingemann Lambertsen * property "x-powers,master-mode" to override the default. 890696f0b3fSChen-Yu Tsai */ 891c0369698SRask Ingemann Lambertsen if (axp20x->variant == AXP806_ID) { 892c0369698SRask Ingemann Lambertsen if (of_property_read_bool(axp20x->dev->of_node, 893c0369698SRask Ingemann Lambertsen "x-powers,master-mode")) 894c0369698SRask Ingemann Lambertsen regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, 895c0369698SRask Ingemann Lambertsen AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE); 896c0369698SRask Ingemann Lambertsen else 897696f0b3fSChen-Yu Tsai regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, 898696f0b3fSChen-Yu Tsai AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE); 899c0369698SRask Ingemann Lambertsen } 900696f0b3fSChen-Yu Tsai 9014fd41151SChen-Yu Tsai ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, 9020a5454c9SHans de Goede IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags, 9030a5454c9SHans de Goede -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc); 904cfb61a41SCarlo Caione if (ret) { 9054fd41151SChen-Yu Tsai dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret); 906cfb61a41SCarlo Caione return ret; 907cfb61a41SCarlo Caione } 908cfb61a41SCarlo Caione 909af7e9069SJacob Pan ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells, 910af7e9069SJacob Pan axp20x->nr_cells, NULL, 0, NULL); 911cfb61a41SCarlo Caione 912cfb61a41SCarlo Caione if (ret) { 9134fd41151SChen-Yu Tsai dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret); 9144fd41151SChen-Yu Tsai regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); 915cfb61a41SCarlo Caione return ret; 916cfb61a41SCarlo Caione } 917cfb61a41SCarlo Caione 918cfb61a41SCarlo Caione if (!pm_power_off) { 919cfb61a41SCarlo Caione axp20x_pm_power_off = axp20x; 920cfb61a41SCarlo Caione pm_power_off = axp20x_power_off; 921cfb61a41SCarlo Caione } 922cfb61a41SCarlo Caione 9234fd41151SChen-Yu Tsai dev_info(axp20x->dev, "AXP20X driver loaded\n"); 924cfb61a41SCarlo Caione 925cfb61a41SCarlo Caione return 0; 926cfb61a41SCarlo Caione } 9274fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_device_probe); 928cfb61a41SCarlo Caione 9294fd41151SChen-Yu Tsai int axp20x_device_remove(struct axp20x_dev *axp20x) 930cfb61a41SCarlo Caione { 931cfb61a41SCarlo Caione if (axp20x == axp20x_pm_power_off) { 932cfb61a41SCarlo Caione axp20x_pm_power_off = NULL; 933cfb61a41SCarlo Caione pm_power_off = NULL; 934cfb61a41SCarlo Caione } 935cfb61a41SCarlo Caione 936cfb61a41SCarlo Caione mfd_remove_devices(axp20x->dev); 9374fd41151SChen-Yu Tsai regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); 938cfb61a41SCarlo Caione 939cfb61a41SCarlo Caione return 0; 940cfb61a41SCarlo Caione } 9414fd41151SChen-Yu Tsai EXPORT_SYMBOL(axp20x_device_remove); 942cfb61a41SCarlo Caione 943cfb61a41SCarlo Caione MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X"); 944cfb61a41SCarlo Caione MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); 945cfb61a41SCarlo Caione MODULE_LICENSE("GPL"); 946