1 /* 2 * MFD core driver for the X-Powers' Power Management ICs 3 * 4 * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC 5 * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature 6 * as well as configurable GPIOs. 7 * 8 * This file contains the interface independent core functions. 9 * 10 * Copyright (C) 2014 Carlo Caione 11 * 12 * Author: Carlo Caione <carlo@caione.org> 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 as 16 * published by the Free Software Foundation. 17 */ 18 19 #include <linux/err.h> 20 #include <linux/delay.h> 21 #include <linux/interrupt.h> 22 #include <linux/kernel.h> 23 #include <linux/module.h> 24 #include <linux/pm_runtime.h> 25 #include <linux/regmap.h> 26 #include <linux/regulator/consumer.h> 27 #include <linux/mfd/axp20x.h> 28 #include <linux/mfd/core.h> 29 #include <linux/of_device.h> 30 #include <linux/acpi.h> 31 32 #define AXP20X_OFF 0x80 33 34 #define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE 0 35 #define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4) 36 37 static const char * const axp20x_model_names[] = { 38 "AXP152", 39 "AXP202", 40 "AXP209", 41 "AXP221", 42 "AXP223", 43 "AXP288", 44 "AXP803", 45 "AXP806", 46 "AXP809", 47 "AXP813", 48 }; 49 50 static const struct regmap_range axp152_writeable_ranges[] = { 51 regmap_reg_range(AXP152_LDO3456_DC1234_CTRL, AXP152_IRQ3_STATE), 52 regmap_reg_range(AXP152_DCDC_MODE, AXP152_PWM1_DUTY_CYCLE), 53 }; 54 55 static const struct regmap_range axp152_volatile_ranges[] = { 56 regmap_reg_range(AXP152_PWR_OP_MODE, AXP152_PWR_OP_MODE), 57 regmap_reg_range(AXP152_IRQ1_EN, AXP152_IRQ3_STATE), 58 regmap_reg_range(AXP152_GPIO_INPUT, AXP152_GPIO_INPUT), 59 }; 60 61 static const struct regmap_access_table axp152_writeable_table = { 62 .yes_ranges = axp152_writeable_ranges, 63 .n_yes_ranges = ARRAY_SIZE(axp152_writeable_ranges), 64 }; 65 66 static const struct regmap_access_table axp152_volatile_table = { 67 .yes_ranges = axp152_volatile_ranges, 68 .n_yes_ranges = ARRAY_SIZE(axp152_volatile_ranges), 69 }; 70 71 static const struct regmap_range axp20x_writeable_ranges[] = { 72 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), 73 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2), 74 regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), 75 regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)), 76 }; 77 78 static const struct regmap_range axp20x_volatile_ranges[] = { 79 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS), 80 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2), 81 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), 82 regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), 83 regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL), 84 regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L), 85 }; 86 87 static const struct regmap_access_table axp20x_writeable_table = { 88 .yes_ranges = axp20x_writeable_ranges, 89 .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges), 90 }; 91 92 static const struct regmap_access_table axp20x_volatile_table = { 93 .yes_ranges = axp20x_volatile_ranges, 94 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), 95 }; 96 97 /* AXP22x ranges are shared with the AXP809, as they cover the same range */ 98 static const struct regmap_range axp22x_writeable_ranges[] = { 99 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), 100 regmap_reg_range(AXP20X_CHRG_CTRL1, AXP22X_CHRG_CTRL3), 101 regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1), 102 }; 103 104 static const struct regmap_range axp22x_volatile_ranges[] = { 105 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE), 106 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), 107 regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), 108 regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L), 109 regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES), 110 }; 111 112 static const struct regmap_access_table axp22x_writeable_table = { 113 .yes_ranges = axp22x_writeable_ranges, 114 .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges), 115 }; 116 117 static const struct regmap_access_table axp22x_volatile_table = { 118 .yes_ranges = axp22x_volatile_ranges, 119 .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges), 120 }; 121 122 /* AXP288 ranges are shared with the AXP803, as they cover the same range */ 123 static const struct regmap_range axp288_writeable_ranges[] = { 124 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), 125 regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), 126 }; 127 128 static const struct regmap_range axp288_volatile_ranges[] = { 129 regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON), 130 regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), 131 regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT), 132 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), 133 regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), 134 regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), 135 regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L), 136 regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG), 137 }; 138 139 static const struct regmap_access_table axp288_writeable_table = { 140 .yes_ranges = axp288_writeable_ranges, 141 .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges), 142 }; 143 144 static const struct regmap_access_table axp288_volatile_table = { 145 .yes_ranges = axp288_volatile_ranges, 146 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), 147 }; 148 149 static const struct regmap_range axp806_writeable_ranges[] = { 150 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)), 151 regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL), 152 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN), 153 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 154 regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT), 155 }; 156 157 static const struct regmap_range axp806_volatile_ranges[] = { 158 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 159 }; 160 161 static const struct regmap_access_table axp806_writeable_table = { 162 .yes_ranges = axp806_writeable_ranges, 163 .n_yes_ranges = ARRAY_SIZE(axp806_writeable_ranges), 164 }; 165 166 static const struct regmap_access_table axp806_volatile_table = { 167 .yes_ranges = axp806_volatile_ranges, 168 .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges), 169 }; 170 171 static struct resource axp152_pek_resources[] = { 172 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"), 173 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), 174 }; 175 176 static struct resource axp20x_ac_power_supply_resources[] = { 177 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), 178 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), 179 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), 180 }; 181 182 static struct resource axp20x_pek_resources[] = { 183 { 184 .name = "PEK_DBR", 185 .start = AXP20X_IRQ_PEK_RIS_EDGE, 186 .end = AXP20X_IRQ_PEK_RIS_EDGE, 187 .flags = IORESOURCE_IRQ, 188 }, { 189 .name = "PEK_DBF", 190 .start = AXP20X_IRQ_PEK_FAL_EDGE, 191 .end = AXP20X_IRQ_PEK_FAL_EDGE, 192 .flags = IORESOURCE_IRQ, 193 }, 194 }; 195 196 static struct resource axp20x_usb_power_supply_resources[] = { 197 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 198 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 199 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"), 200 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), 201 }; 202 203 static struct resource axp22x_usb_power_supply_resources[] = { 204 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 205 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 206 }; 207 208 static struct resource axp22x_pek_resources[] = { 209 { 210 .name = "PEK_DBR", 211 .start = AXP22X_IRQ_PEK_RIS_EDGE, 212 .end = AXP22X_IRQ_PEK_RIS_EDGE, 213 .flags = IORESOURCE_IRQ, 214 }, { 215 .name = "PEK_DBF", 216 .start = AXP22X_IRQ_PEK_FAL_EDGE, 217 .end = AXP22X_IRQ_PEK_FAL_EDGE, 218 .flags = IORESOURCE_IRQ, 219 }, 220 }; 221 222 static struct resource axp288_power_button_resources[] = { 223 { 224 .name = "PEK_DBR", 225 .start = AXP288_IRQ_POKP, 226 .end = AXP288_IRQ_POKP, 227 .flags = IORESOURCE_IRQ, 228 }, 229 { 230 .name = "PEK_DBF", 231 .start = AXP288_IRQ_POKN, 232 .end = AXP288_IRQ_POKN, 233 .flags = IORESOURCE_IRQ, 234 }, 235 }; 236 237 static struct resource axp288_fuel_gauge_resources[] = { 238 { 239 .start = AXP288_IRQ_QWBTU, 240 .end = AXP288_IRQ_QWBTU, 241 .flags = IORESOURCE_IRQ, 242 }, 243 { 244 .start = AXP288_IRQ_WBTU, 245 .end = AXP288_IRQ_WBTU, 246 .flags = IORESOURCE_IRQ, 247 }, 248 { 249 .start = AXP288_IRQ_QWBTO, 250 .end = AXP288_IRQ_QWBTO, 251 .flags = IORESOURCE_IRQ, 252 }, 253 { 254 .start = AXP288_IRQ_WBTO, 255 .end = AXP288_IRQ_WBTO, 256 .flags = IORESOURCE_IRQ, 257 }, 258 { 259 .start = AXP288_IRQ_WL2, 260 .end = AXP288_IRQ_WL2, 261 .flags = IORESOURCE_IRQ, 262 }, 263 { 264 .start = AXP288_IRQ_WL1, 265 .end = AXP288_IRQ_WL1, 266 .flags = IORESOURCE_IRQ, 267 }, 268 }; 269 270 static struct resource axp803_pek_resources[] = { 271 { 272 .name = "PEK_DBR", 273 .start = AXP803_IRQ_PEK_RIS_EDGE, 274 .end = AXP803_IRQ_PEK_RIS_EDGE, 275 .flags = IORESOURCE_IRQ, 276 }, { 277 .name = "PEK_DBF", 278 .start = AXP803_IRQ_PEK_FAL_EDGE, 279 .end = AXP803_IRQ_PEK_FAL_EDGE, 280 .flags = IORESOURCE_IRQ, 281 }, 282 }; 283 284 static struct resource axp809_pek_resources[] = { 285 { 286 .name = "PEK_DBR", 287 .start = AXP809_IRQ_PEK_RIS_EDGE, 288 .end = AXP809_IRQ_PEK_RIS_EDGE, 289 .flags = IORESOURCE_IRQ, 290 }, { 291 .name = "PEK_DBF", 292 .start = AXP809_IRQ_PEK_FAL_EDGE, 293 .end = AXP809_IRQ_PEK_FAL_EDGE, 294 .flags = IORESOURCE_IRQ, 295 }, 296 }; 297 298 static const struct regmap_config axp152_regmap_config = { 299 .reg_bits = 8, 300 .val_bits = 8, 301 .wr_table = &axp152_writeable_table, 302 .volatile_table = &axp152_volatile_table, 303 .max_register = AXP152_PWM1_DUTY_CYCLE, 304 .cache_type = REGCACHE_RBTREE, 305 }; 306 307 static const struct regmap_config axp20x_regmap_config = { 308 .reg_bits = 8, 309 .val_bits = 8, 310 .wr_table = &axp20x_writeable_table, 311 .volatile_table = &axp20x_volatile_table, 312 .max_register = AXP20X_OCV(AXP20X_OCV_MAX), 313 .cache_type = REGCACHE_RBTREE, 314 }; 315 316 static const struct regmap_config axp22x_regmap_config = { 317 .reg_bits = 8, 318 .val_bits = 8, 319 .wr_table = &axp22x_writeable_table, 320 .volatile_table = &axp22x_volatile_table, 321 .max_register = AXP22X_BATLOW_THRES1, 322 .cache_type = REGCACHE_RBTREE, 323 }; 324 325 static const struct regmap_config axp288_regmap_config = { 326 .reg_bits = 8, 327 .val_bits = 8, 328 .wr_table = &axp288_writeable_table, 329 .volatile_table = &axp288_volatile_table, 330 .max_register = AXP288_FG_TUNE5, 331 .cache_type = REGCACHE_RBTREE, 332 }; 333 334 static const struct regmap_config axp806_regmap_config = { 335 .reg_bits = 8, 336 .val_bits = 8, 337 .wr_table = &axp806_writeable_table, 338 .volatile_table = &axp806_volatile_table, 339 .max_register = AXP806_REG_ADDR_EXT, 340 .cache_type = REGCACHE_RBTREE, 341 }; 342 343 #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ 344 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } 345 346 static const struct regmap_irq axp152_regmap_irqs[] = { 347 INIT_REGMAP_IRQ(AXP152, LDO0IN_CONNECT, 0, 6), 348 INIT_REGMAP_IRQ(AXP152, LDO0IN_REMOVAL, 0, 5), 349 INIT_REGMAP_IRQ(AXP152, ALDO0IN_CONNECT, 0, 3), 350 INIT_REGMAP_IRQ(AXP152, ALDO0IN_REMOVAL, 0, 2), 351 INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW, 1, 5), 352 INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW, 1, 4), 353 INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW, 1, 3), 354 INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW, 1, 2), 355 INIT_REGMAP_IRQ(AXP152, PEK_SHORT, 1, 1), 356 INIT_REGMAP_IRQ(AXP152, PEK_LONG, 1, 0), 357 INIT_REGMAP_IRQ(AXP152, TIMER, 2, 7), 358 INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE, 2, 6), 359 INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE, 2, 5), 360 INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT, 2, 3), 361 INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT, 2, 2), 362 INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT, 2, 1), 363 INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), 364 }; 365 366 static const struct regmap_irq axp20x_regmap_irqs[] = { 367 INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), 368 INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6), 369 INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL, 0, 5), 370 INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V, 0, 4), 371 INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN, 0, 3), 372 INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL, 0, 2), 373 INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW, 0, 1), 374 INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN, 1, 7), 375 INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL, 1, 6), 376 INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE, 1, 5), 377 INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4), 378 INIT_REGMAP_IRQ(AXP20X, CHARG, 1, 3), 379 INIT_REGMAP_IRQ(AXP20X, CHARG_DONE, 1, 2), 380 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH, 1, 1), 381 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW, 1, 0), 382 INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH, 2, 7), 383 INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW, 2, 6), 384 INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG, 2, 5), 385 INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG, 2, 4), 386 INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG, 2, 3), 387 INIT_REGMAP_IRQ(AXP20X, PEK_SHORT, 2, 1), 388 INIT_REGMAP_IRQ(AXP20X, PEK_LONG, 2, 0), 389 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON, 3, 7), 390 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF, 3, 6), 391 INIT_REGMAP_IRQ(AXP20X, VBUS_VALID, 3, 5), 392 INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID, 3, 4), 393 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID, 3, 3), 394 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END, 3, 2), 395 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1, 3, 1), 396 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2, 3, 0), 397 INIT_REGMAP_IRQ(AXP20X, TIMER, 4, 7), 398 INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE, 4, 6), 399 INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE, 4, 5), 400 INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT, 4, 3), 401 INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT, 4, 2), 402 INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT, 4, 1), 403 INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0), 404 }; 405 406 static const struct regmap_irq axp22x_regmap_irqs[] = { 407 INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V, 0, 7), 408 INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN, 0, 6), 409 INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL, 0, 5), 410 INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V, 0, 4), 411 INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN, 0, 3), 412 INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL, 0, 2), 413 INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW, 0, 1), 414 INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN, 1, 7), 415 INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL, 1, 6), 416 INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE, 1, 5), 417 INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4), 418 INIT_REGMAP_IRQ(AXP22X, CHARG, 1, 3), 419 INIT_REGMAP_IRQ(AXP22X, CHARG_DONE, 1, 2), 420 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH, 1, 1), 421 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW, 1, 0), 422 INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH, 2, 7), 423 INIT_REGMAP_IRQ(AXP22X, PEK_SHORT, 2, 1), 424 INIT_REGMAP_IRQ(AXP22X, PEK_LONG, 2, 0), 425 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1, 3, 1), 426 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2, 3, 0), 427 INIT_REGMAP_IRQ(AXP22X, TIMER, 4, 7), 428 INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE, 4, 6), 429 INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE, 4, 5), 430 INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT, 4, 1), 431 INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT, 4, 0), 432 }; 433 434 /* some IRQs are compatible with axp20x models */ 435 static const struct regmap_irq axp288_regmap_irqs[] = { 436 INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2), 437 INIT_REGMAP_IRQ(AXP288, VBUS_RISE, 0, 3), 438 INIT_REGMAP_IRQ(AXP288, OV, 0, 4), 439 INIT_REGMAP_IRQ(AXP288, FALLING_ALT, 0, 5), 440 INIT_REGMAP_IRQ(AXP288, RISING_ALT, 0, 6), 441 INIT_REGMAP_IRQ(AXP288, OV_ALT, 0, 7), 442 443 INIT_REGMAP_IRQ(AXP288, DONE, 1, 2), 444 INIT_REGMAP_IRQ(AXP288, CHARGING, 1, 3), 445 INIT_REGMAP_IRQ(AXP288, SAFE_QUIT, 1, 4), 446 INIT_REGMAP_IRQ(AXP288, SAFE_ENTER, 1, 5), 447 INIT_REGMAP_IRQ(AXP288, ABSENT, 1, 6), 448 INIT_REGMAP_IRQ(AXP288, APPEND, 1, 7), 449 450 INIT_REGMAP_IRQ(AXP288, QWBTU, 2, 0), 451 INIT_REGMAP_IRQ(AXP288, WBTU, 2, 1), 452 INIT_REGMAP_IRQ(AXP288, QWBTO, 2, 2), 453 INIT_REGMAP_IRQ(AXP288, WBTO, 2, 3), 454 INIT_REGMAP_IRQ(AXP288, QCBTU, 2, 4), 455 INIT_REGMAP_IRQ(AXP288, CBTU, 2, 5), 456 INIT_REGMAP_IRQ(AXP288, QCBTO, 2, 6), 457 INIT_REGMAP_IRQ(AXP288, CBTO, 2, 7), 458 459 INIT_REGMAP_IRQ(AXP288, WL2, 3, 0), 460 INIT_REGMAP_IRQ(AXP288, WL1, 3, 1), 461 INIT_REGMAP_IRQ(AXP288, GPADC, 3, 2), 462 INIT_REGMAP_IRQ(AXP288, OT, 3, 7), 463 464 INIT_REGMAP_IRQ(AXP288, GPIO0, 4, 0), 465 INIT_REGMAP_IRQ(AXP288, GPIO1, 4, 1), 466 INIT_REGMAP_IRQ(AXP288, POKO, 4, 2), 467 INIT_REGMAP_IRQ(AXP288, POKL, 4, 3), 468 INIT_REGMAP_IRQ(AXP288, POKS, 4, 4), 469 INIT_REGMAP_IRQ(AXP288, POKN, 4, 5), 470 INIT_REGMAP_IRQ(AXP288, POKP, 4, 6), 471 INIT_REGMAP_IRQ(AXP288, TIMER, 4, 7), 472 473 INIT_REGMAP_IRQ(AXP288, MV_CHNG, 5, 0), 474 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), 475 }; 476 477 static const struct regmap_irq axp803_regmap_irqs[] = { 478 INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7), 479 INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6), 480 INIT_REGMAP_IRQ(AXP803, ACIN_REMOVAL, 0, 5), 481 INIT_REGMAP_IRQ(AXP803, VBUS_OVER_V, 0, 4), 482 INIT_REGMAP_IRQ(AXP803, VBUS_PLUGIN, 0, 3), 483 INIT_REGMAP_IRQ(AXP803, VBUS_REMOVAL, 0, 2), 484 INIT_REGMAP_IRQ(AXP803, BATT_PLUGIN, 1, 7), 485 INIT_REGMAP_IRQ(AXP803, BATT_REMOVAL, 1, 6), 486 INIT_REGMAP_IRQ(AXP803, BATT_ENT_ACT_MODE, 1, 5), 487 INIT_REGMAP_IRQ(AXP803, BATT_EXIT_ACT_MODE, 1, 4), 488 INIT_REGMAP_IRQ(AXP803, CHARG, 1, 3), 489 INIT_REGMAP_IRQ(AXP803, CHARG_DONE, 1, 2), 490 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH, 2, 7), 491 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH_END, 2, 6), 492 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW, 2, 5), 493 INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW_END, 2, 4), 494 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH, 2, 3), 495 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH_END, 2, 2), 496 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW, 2, 1), 497 INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW_END, 2, 0), 498 INIT_REGMAP_IRQ(AXP803, DIE_TEMP_HIGH, 3, 7), 499 INIT_REGMAP_IRQ(AXP803, GPADC, 3, 2), 500 INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL1, 3, 1), 501 INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL2, 3, 0), 502 INIT_REGMAP_IRQ(AXP803, TIMER, 4, 7), 503 INIT_REGMAP_IRQ(AXP803, PEK_RIS_EDGE, 4, 6), 504 INIT_REGMAP_IRQ(AXP803, PEK_FAL_EDGE, 4, 5), 505 INIT_REGMAP_IRQ(AXP803, PEK_SHORT, 4, 4), 506 INIT_REGMAP_IRQ(AXP803, PEK_LONG, 4, 3), 507 INIT_REGMAP_IRQ(AXP803, PEK_OVER_OFF, 4, 2), 508 INIT_REGMAP_IRQ(AXP803, GPIO1_INPUT, 4, 1), 509 INIT_REGMAP_IRQ(AXP803, GPIO0_INPUT, 4, 0), 510 INIT_REGMAP_IRQ(AXP803, BC_USB_CHNG, 5, 1), 511 INIT_REGMAP_IRQ(AXP803, MV_CHNG, 5, 0), 512 }; 513 514 static const struct regmap_irq axp806_regmap_irqs[] = { 515 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0), 516 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1), 517 INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW, 0, 3), 518 INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW, 0, 4), 519 INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5), 520 INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6), 521 INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7), 522 INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0), 523 INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1), 524 INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4), 525 INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5), 526 INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6), 527 }; 528 529 static const struct regmap_irq axp809_regmap_irqs[] = { 530 INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7), 531 INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6), 532 INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL, 0, 5), 533 INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V, 0, 4), 534 INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN, 0, 3), 535 INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL, 0, 2), 536 INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW, 0, 1), 537 INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN, 1, 7), 538 INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL, 1, 6), 539 INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE, 1, 5), 540 INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE, 1, 4), 541 INIT_REGMAP_IRQ(AXP809, CHARG, 1, 3), 542 INIT_REGMAP_IRQ(AXP809, CHARG_DONE, 1, 2), 543 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH, 2, 7), 544 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END, 2, 6), 545 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW, 2, 5), 546 INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END, 2, 4), 547 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH, 2, 3), 548 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END, 2, 2), 549 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW, 2, 1), 550 INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END, 2, 0), 551 INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH, 3, 7), 552 INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1, 3, 1), 553 INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2, 3, 0), 554 INIT_REGMAP_IRQ(AXP809, TIMER, 4, 7), 555 INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE, 4, 6), 556 INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE, 4, 5), 557 INIT_REGMAP_IRQ(AXP809, PEK_SHORT, 4, 4), 558 INIT_REGMAP_IRQ(AXP809, PEK_LONG, 4, 3), 559 INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF, 4, 2), 560 INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT, 4, 1), 561 INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0), 562 }; 563 564 static const struct regmap_irq_chip axp152_regmap_irq_chip = { 565 .name = "axp152_irq_chip", 566 .status_base = AXP152_IRQ1_STATE, 567 .ack_base = AXP152_IRQ1_STATE, 568 .mask_base = AXP152_IRQ1_EN, 569 .mask_invert = true, 570 .init_ack_masked = true, 571 .irqs = axp152_regmap_irqs, 572 .num_irqs = ARRAY_SIZE(axp152_regmap_irqs), 573 .num_regs = 3, 574 }; 575 576 static const struct regmap_irq_chip axp20x_regmap_irq_chip = { 577 .name = "axp20x_irq_chip", 578 .status_base = AXP20X_IRQ1_STATE, 579 .ack_base = AXP20X_IRQ1_STATE, 580 .mask_base = AXP20X_IRQ1_EN, 581 .mask_invert = true, 582 .init_ack_masked = true, 583 .irqs = axp20x_regmap_irqs, 584 .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), 585 .num_regs = 5, 586 587 }; 588 589 static const struct regmap_irq_chip axp22x_regmap_irq_chip = { 590 .name = "axp22x_irq_chip", 591 .status_base = AXP20X_IRQ1_STATE, 592 .ack_base = AXP20X_IRQ1_STATE, 593 .mask_base = AXP20X_IRQ1_EN, 594 .mask_invert = true, 595 .init_ack_masked = true, 596 .irqs = axp22x_regmap_irqs, 597 .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs), 598 .num_regs = 5, 599 }; 600 601 static const struct regmap_irq_chip axp288_regmap_irq_chip = { 602 .name = "axp288_irq_chip", 603 .status_base = AXP20X_IRQ1_STATE, 604 .ack_base = AXP20X_IRQ1_STATE, 605 .mask_base = AXP20X_IRQ1_EN, 606 .mask_invert = true, 607 .init_ack_masked = true, 608 .irqs = axp288_regmap_irqs, 609 .num_irqs = ARRAY_SIZE(axp288_regmap_irqs), 610 .num_regs = 6, 611 612 }; 613 614 static const struct regmap_irq_chip axp803_regmap_irq_chip = { 615 .name = "axp803", 616 .status_base = AXP20X_IRQ1_STATE, 617 .ack_base = AXP20X_IRQ1_STATE, 618 .mask_base = AXP20X_IRQ1_EN, 619 .mask_invert = true, 620 .init_ack_masked = true, 621 .irqs = axp803_regmap_irqs, 622 .num_irqs = ARRAY_SIZE(axp803_regmap_irqs), 623 .num_regs = 6, 624 }; 625 626 static const struct regmap_irq_chip axp806_regmap_irq_chip = { 627 .name = "axp806", 628 .status_base = AXP20X_IRQ1_STATE, 629 .ack_base = AXP20X_IRQ1_STATE, 630 .mask_base = AXP20X_IRQ1_EN, 631 .mask_invert = true, 632 .init_ack_masked = true, 633 .irqs = axp806_regmap_irqs, 634 .num_irqs = ARRAY_SIZE(axp806_regmap_irqs), 635 .num_regs = 2, 636 }; 637 638 static const struct regmap_irq_chip axp809_regmap_irq_chip = { 639 .name = "axp809", 640 .status_base = AXP20X_IRQ1_STATE, 641 .ack_base = AXP20X_IRQ1_STATE, 642 .mask_base = AXP20X_IRQ1_EN, 643 .mask_invert = true, 644 .init_ack_masked = true, 645 .irqs = axp809_regmap_irqs, 646 .num_irqs = ARRAY_SIZE(axp809_regmap_irqs), 647 .num_regs = 5, 648 }; 649 650 static struct mfd_cell axp20x_cells[] = { 651 { 652 .name = "axp20x-gpio", 653 .of_compatible = "x-powers,axp209-gpio", 654 }, { 655 .name = "axp20x-pek", 656 .num_resources = ARRAY_SIZE(axp20x_pek_resources), 657 .resources = axp20x_pek_resources, 658 }, { 659 .name = "axp20x-regulator", 660 }, { 661 .name = "axp20x-adc", 662 }, { 663 .name = "axp20x-battery-power-supply", 664 .of_compatible = "x-powers,axp209-battery-power-supply", 665 }, { 666 .name = "axp20x-ac-power-supply", 667 .of_compatible = "x-powers,axp202-ac-power-supply", 668 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 669 .resources = axp20x_ac_power_supply_resources, 670 }, { 671 .name = "axp20x-usb-power-supply", 672 .of_compatible = "x-powers,axp202-usb-power-supply", 673 .num_resources = ARRAY_SIZE(axp20x_usb_power_supply_resources), 674 .resources = axp20x_usb_power_supply_resources, 675 }, 676 }; 677 678 static struct mfd_cell axp221_cells[] = { 679 { 680 .name = "axp221-pek", 681 .num_resources = ARRAY_SIZE(axp22x_pek_resources), 682 .resources = axp22x_pek_resources, 683 }, { 684 .name = "axp20x-regulator", 685 }, { 686 .name = "axp22x-adc" 687 }, { 688 .name = "axp20x-ac-power-supply", 689 .of_compatible = "x-powers,axp221-ac-power-supply", 690 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 691 .resources = axp20x_ac_power_supply_resources, 692 }, { 693 .name = "axp20x-battery-power-supply", 694 .of_compatible = "x-powers,axp221-battery-power-supply", 695 }, { 696 .name = "axp20x-usb-power-supply", 697 .of_compatible = "x-powers,axp221-usb-power-supply", 698 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), 699 .resources = axp22x_usb_power_supply_resources, 700 }, 701 }; 702 703 static struct mfd_cell axp223_cells[] = { 704 { 705 .name = "axp221-pek", 706 .num_resources = ARRAY_SIZE(axp22x_pek_resources), 707 .resources = axp22x_pek_resources, 708 }, { 709 .name = "axp22x-adc", 710 }, { 711 .name = "axp20x-battery-power-supply", 712 .of_compatible = "x-powers,axp221-battery-power-supply", 713 }, { 714 .name = "axp20x-regulator", 715 }, { 716 .name = "axp20x-ac-power-supply", 717 .of_compatible = "x-powers,axp221-ac-power-supply", 718 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 719 .resources = axp20x_ac_power_supply_resources, 720 }, { 721 .name = "axp20x-usb-power-supply", 722 .of_compatible = "x-powers,axp223-usb-power-supply", 723 .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), 724 .resources = axp22x_usb_power_supply_resources, 725 }, 726 }; 727 728 static struct mfd_cell axp152_cells[] = { 729 { 730 .name = "axp20x-pek", 731 .num_resources = ARRAY_SIZE(axp152_pek_resources), 732 .resources = axp152_pek_resources, 733 }, 734 }; 735 736 static struct resource axp288_adc_resources[] = { 737 { 738 .name = "GPADC", 739 .start = AXP288_IRQ_GPADC, 740 .end = AXP288_IRQ_GPADC, 741 .flags = IORESOURCE_IRQ, 742 }, 743 }; 744 745 static struct resource axp288_extcon_resources[] = { 746 { 747 .start = AXP288_IRQ_VBUS_FALL, 748 .end = AXP288_IRQ_VBUS_FALL, 749 .flags = IORESOURCE_IRQ, 750 }, 751 { 752 .start = AXP288_IRQ_VBUS_RISE, 753 .end = AXP288_IRQ_VBUS_RISE, 754 .flags = IORESOURCE_IRQ, 755 }, 756 { 757 .start = AXP288_IRQ_MV_CHNG, 758 .end = AXP288_IRQ_MV_CHNG, 759 .flags = IORESOURCE_IRQ, 760 }, 761 { 762 .start = AXP288_IRQ_BC_USB_CHNG, 763 .end = AXP288_IRQ_BC_USB_CHNG, 764 .flags = IORESOURCE_IRQ, 765 }, 766 }; 767 768 static struct resource axp288_charger_resources[] = { 769 { 770 .start = AXP288_IRQ_OV, 771 .end = AXP288_IRQ_OV, 772 .flags = IORESOURCE_IRQ, 773 }, 774 { 775 .start = AXP288_IRQ_DONE, 776 .end = AXP288_IRQ_DONE, 777 .flags = IORESOURCE_IRQ, 778 }, 779 { 780 .start = AXP288_IRQ_CHARGING, 781 .end = AXP288_IRQ_CHARGING, 782 .flags = IORESOURCE_IRQ, 783 }, 784 { 785 .start = AXP288_IRQ_SAFE_QUIT, 786 .end = AXP288_IRQ_SAFE_QUIT, 787 .flags = IORESOURCE_IRQ, 788 }, 789 { 790 .start = AXP288_IRQ_SAFE_ENTER, 791 .end = AXP288_IRQ_SAFE_ENTER, 792 .flags = IORESOURCE_IRQ, 793 }, 794 { 795 .start = AXP288_IRQ_QCBTU, 796 .end = AXP288_IRQ_QCBTU, 797 .flags = IORESOURCE_IRQ, 798 }, 799 { 800 .start = AXP288_IRQ_CBTU, 801 .end = AXP288_IRQ_CBTU, 802 .flags = IORESOURCE_IRQ, 803 }, 804 { 805 .start = AXP288_IRQ_QCBTO, 806 .end = AXP288_IRQ_QCBTO, 807 .flags = IORESOURCE_IRQ, 808 }, 809 { 810 .start = AXP288_IRQ_CBTO, 811 .end = AXP288_IRQ_CBTO, 812 .flags = IORESOURCE_IRQ, 813 }, 814 }; 815 816 static struct mfd_cell axp288_cells[] = { 817 { 818 .name = "axp288_adc", 819 .num_resources = ARRAY_SIZE(axp288_adc_resources), 820 .resources = axp288_adc_resources, 821 }, 822 { 823 .name = "axp288_extcon", 824 .num_resources = ARRAY_SIZE(axp288_extcon_resources), 825 .resources = axp288_extcon_resources, 826 }, 827 { 828 .name = "axp288_charger", 829 .num_resources = ARRAY_SIZE(axp288_charger_resources), 830 .resources = axp288_charger_resources, 831 }, 832 { 833 .name = "axp288_fuel_gauge", 834 .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), 835 .resources = axp288_fuel_gauge_resources, 836 }, 837 { 838 .name = "axp221-pek", 839 .num_resources = ARRAY_SIZE(axp288_power_button_resources), 840 .resources = axp288_power_button_resources, 841 }, 842 { 843 .name = "axp288_pmic_acpi", 844 }, 845 }; 846 847 static struct mfd_cell axp803_cells[] = { 848 { 849 .name = "axp221-pek", 850 .num_resources = ARRAY_SIZE(axp803_pek_resources), 851 .resources = axp803_pek_resources, 852 }, 853 { .name = "axp20x-regulator" }, 854 }; 855 856 static struct mfd_cell axp806_cells[] = { 857 { 858 .id = 2, 859 .name = "axp20x-regulator", 860 }, 861 }; 862 863 static struct mfd_cell axp809_cells[] = { 864 { 865 .name = "axp221-pek", 866 .num_resources = ARRAY_SIZE(axp809_pek_resources), 867 .resources = axp809_pek_resources, 868 }, { 869 .id = 1, 870 .name = "axp20x-regulator", 871 }, 872 }; 873 874 static struct mfd_cell axp813_cells[] = { 875 { 876 .name = "axp221-pek", 877 .num_resources = ARRAY_SIZE(axp803_pek_resources), 878 .resources = axp803_pek_resources, 879 }, { 880 .name = "axp20x-regulator", 881 } 882 }; 883 884 static struct axp20x_dev *axp20x_pm_power_off; 885 static void axp20x_power_off(void) 886 { 887 if (axp20x_pm_power_off->variant == AXP288_ID) 888 return; 889 890 regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, 891 AXP20X_OFF); 892 893 /* Give capacitors etc. time to drain to avoid kernel panic msg. */ 894 msleep(500); 895 } 896 897 int axp20x_match_device(struct axp20x_dev *axp20x) 898 { 899 struct device *dev = axp20x->dev; 900 const struct acpi_device_id *acpi_id; 901 const struct of_device_id *of_id; 902 903 if (dev->of_node) { 904 of_id = of_match_device(dev->driver->of_match_table, dev); 905 if (!of_id) { 906 dev_err(dev, "Unable to match OF ID\n"); 907 return -ENODEV; 908 } 909 axp20x->variant = (long)of_id->data; 910 } else { 911 acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); 912 if (!acpi_id || !acpi_id->driver_data) { 913 dev_err(dev, "Unable to match ACPI ID and data\n"); 914 return -ENODEV; 915 } 916 axp20x->variant = (long)acpi_id->driver_data; 917 } 918 919 switch (axp20x->variant) { 920 case AXP152_ID: 921 axp20x->nr_cells = ARRAY_SIZE(axp152_cells); 922 axp20x->cells = axp152_cells; 923 axp20x->regmap_cfg = &axp152_regmap_config; 924 axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; 925 break; 926 case AXP202_ID: 927 case AXP209_ID: 928 axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); 929 axp20x->cells = axp20x_cells; 930 axp20x->regmap_cfg = &axp20x_regmap_config; 931 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip; 932 break; 933 case AXP221_ID: 934 axp20x->nr_cells = ARRAY_SIZE(axp221_cells); 935 axp20x->cells = axp221_cells; 936 axp20x->regmap_cfg = &axp22x_regmap_config; 937 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip; 938 break; 939 case AXP223_ID: 940 axp20x->nr_cells = ARRAY_SIZE(axp223_cells); 941 axp20x->cells = axp223_cells; 942 axp20x->regmap_cfg = &axp22x_regmap_config; 943 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip; 944 break; 945 case AXP288_ID: 946 axp20x->cells = axp288_cells; 947 axp20x->nr_cells = ARRAY_SIZE(axp288_cells); 948 axp20x->regmap_cfg = &axp288_regmap_config; 949 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; 950 axp20x->irq_flags = IRQF_TRIGGER_LOW; 951 break; 952 case AXP803_ID: 953 axp20x->nr_cells = ARRAY_SIZE(axp803_cells); 954 axp20x->cells = axp803_cells; 955 axp20x->regmap_cfg = &axp288_regmap_config; 956 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; 957 break; 958 case AXP806_ID: 959 axp20x->nr_cells = ARRAY_SIZE(axp806_cells); 960 axp20x->cells = axp806_cells; 961 axp20x->regmap_cfg = &axp806_regmap_config; 962 axp20x->regmap_irq_chip = &axp806_regmap_irq_chip; 963 break; 964 case AXP809_ID: 965 axp20x->nr_cells = ARRAY_SIZE(axp809_cells); 966 axp20x->cells = axp809_cells; 967 axp20x->regmap_cfg = &axp22x_regmap_config; 968 axp20x->regmap_irq_chip = &axp809_regmap_irq_chip; 969 break; 970 case AXP813_ID: 971 axp20x->nr_cells = ARRAY_SIZE(axp813_cells); 972 axp20x->cells = axp813_cells; 973 axp20x->regmap_cfg = &axp288_regmap_config; 974 /* 975 * The IRQ table given in the datasheet is incorrect. 976 * In IRQ enable/status registers 1, there are separate 977 * IRQs for ACIN and VBUS, instead of bits [7:5] being 978 * the same as bits [4:2]. So it shares the same IRQs 979 * as the AXP803, rather than the AXP288. 980 */ 981 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; 982 break; 983 default: 984 dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); 985 return -EINVAL; 986 } 987 dev_info(dev, "AXP20x variant %s found\n", 988 axp20x_model_names[axp20x->variant]); 989 990 return 0; 991 } 992 EXPORT_SYMBOL(axp20x_match_device); 993 994 int axp20x_device_probe(struct axp20x_dev *axp20x) 995 { 996 int ret; 997 998 /* 999 * The AXP806 supports either master/standalone or slave mode. 1000 * Slave mode allows sharing the serial bus, even with multiple 1001 * AXP806 which all have the same hardware address. 1002 * 1003 * This is done with extra "serial interface address extension", 1004 * or AXP806_BUS_ADDR_EXT, and "register address extension", or 1005 * AXP806_REG_ADDR_EXT, registers. The former is read-only, with 1006 * 1 bit customizable at the factory, and 1 bit depending on the 1007 * state of an external pin. The latter is writable. The device 1008 * will only respond to operations to its other registers when 1009 * the these device addressing bits (in the upper 4 bits of the 1010 * registers) match. 1011 * 1012 * By default we support an AXP806 chained to an AXP809 in slave 1013 * mode. Boards which use an AXP806 in master mode can set the 1014 * property "x-powers,master-mode" to override the default. 1015 */ 1016 if (axp20x->variant == AXP806_ID) { 1017 if (of_property_read_bool(axp20x->dev->of_node, 1018 "x-powers,master-mode")) 1019 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, 1020 AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE); 1021 else 1022 regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, 1023 AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE); 1024 } 1025 1026 ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, 1027 IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags, 1028 -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc); 1029 if (ret) { 1030 dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret); 1031 return ret; 1032 } 1033 1034 ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells, 1035 axp20x->nr_cells, NULL, 0, NULL); 1036 1037 if (ret) { 1038 dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret); 1039 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); 1040 return ret; 1041 } 1042 1043 if (!pm_power_off) { 1044 axp20x_pm_power_off = axp20x; 1045 pm_power_off = axp20x_power_off; 1046 } 1047 1048 dev_info(axp20x->dev, "AXP20X driver loaded\n"); 1049 1050 return 0; 1051 } 1052 EXPORT_SYMBOL(axp20x_device_probe); 1053 1054 int axp20x_device_remove(struct axp20x_dev *axp20x) 1055 { 1056 if (axp20x == axp20x_pm_power_off) { 1057 axp20x_pm_power_off = NULL; 1058 pm_power_off = NULL; 1059 } 1060 1061 mfd_remove_devices(axp20x->dev); 1062 regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); 1063 1064 return 0; 1065 } 1066 EXPORT_SYMBOL(axp20x_device_remove); 1067 1068 MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X"); 1069 MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); 1070 MODULE_LICENSE("GPL"); 1071