Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: axp20x: Add support for AXP192

The AXP192 PMIC is similar to the AXP202/AXP209, but with different
regulators, additional GPIOs, and a different IRQ register layout.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
Link: https://lore.kernel.org/r/20230511092609.76183-1-aidanmacdonald.0x0@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Aidan MacDonald and committed by
Lee Jones
63eeabbc 35d5ebfa

+227
+2
drivers/mfd/axp20x-i2c.c
··· 59 59 #ifdef CONFIG_OF 60 60 static const struct of_device_id axp20x_i2c_of_match[] = { 61 61 { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID }, 62 + { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID }, 62 63 { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID }, 63 64 { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, 64 65 { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, ··· 75 74 76 75 static const struct i2c_device_id axp20x_i2c_id[] = { 77 76 { "axp152", 0 }, 77 + { "axp192", 0 }, 78 78 { "axp202", 0 }, 79 79 { "axp209", 0 }, 80 80 { "axp221", 0 },
+141
drivers/mfd/axp20x.c
··· 34 34 35 35 static const char * const axp20x_model_names[] = { 36 36 "AXP152", 37 + "AXP192", 37 38 "AXP202", 38 39 "AXP209", 39 40 "AXP221", ··· 93 92 static const struct regmap_access_table axp20x_volatile_table = { 94 93 .yes_ranges = axp20x_volatile_ranges, 95 94 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), 95 + }; 96 + 97 + static const struct regmap_range axp192_writeable_ranges[] = { 98 + regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)), 99 + regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE), 100 + regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL), 101 + regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL), 102 + }; 103 + 104 + static const struct regmap_range axp192_volatile_ranges[] = { 105 + regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS), 106 + regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE), 107 + regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE), 108 + regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), 109 + regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), 110 + regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE), 111 + regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE), 112 + regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL), 113 + regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL), 114 + }; 115 + 116 + static const struct regmap_access_table axp192_writeable_table = { 117 + .yes_ranges = axp192_writeable_ranges, 118 + .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges), 119 + }; 120 + 121 + static const struct regmap_access_table axp192_volatile_table = { 122 + .yes_ranges = axp192_volatile_ranges, 123 + .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges), 96 124 }; 97 125 98 126 /* AXP22x ranges are shared with the AXP809, as they cover the same range */ ··· 250 220 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), 251 221 }; 252 222 223 + static const struct resource axp192_ac_power_supply_resources[] = { 224 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), 225 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), 226 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), 227 + }; 228 + 229 + static const struct resource axp192_usb_power_supply_resources[] = { 230 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 231 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 232 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"), 233 + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), 234 + }; 235 + 253 236 static const struct resource axp20x_ac_power_supply_resources[] = { 254 237 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), 255 238 DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), ··· 345 302 .cache_type = REGCACHE_RBTREE, 346 303 }; 347 304 305 + static const struct regmap_config axp192_regmap_config = { 306 + .reg_bits = 8, 307 + .val_bits = 8, 308 + .wr_table = &axp192_writeable_table, 309 + .volatile_table = &axp192_volatile_table, 310 + .max_register = AXP20X_CC_CTRL, 311 + .cache_type = REGCACHE_RBTREE, 312 + }; 313 + 348 314 static const struct regmap_config axp20x_regmap_config = { 349 315 .reg_bits = 8, 350 316 .val_bits = 8, ··· 429 377 INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT, 2, 2), 430 378 INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT, 2, 1), 431 379 INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), 380 + }; 381 + 382 + static const struct regmap_irq axp192_regmap_irqs[] = { 383 + INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7), 384 + INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6), 385 + INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5), 386 + INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4), 387 + INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3), 388 + INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2), 389 + INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1), 390 + INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7), 391 + INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6), 392 + INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5), 393 + INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4), 394 + INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3), 395 + INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2), 396 + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1), 397 + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0), 398 + INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7), 399 + INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6), 400 + INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5), 401 + INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4), 402 + INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3), 403 + INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1), 404 + INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0), 405 + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7), 406 + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6), 407 + INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5), 408 + INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4), 409 + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3), 410 + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2), 411 + INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0), 412 + INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7), 413 + INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2), 414 + INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1), 415 + INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0), 432 416 }; 433 417 434 418 static const struct regmap_irq axp20x_regmap_irqs[] = { ··· 703 615 .num_regs = 3, 704 616 }; 705 617 618 + static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data, 619 + unsigned int base, int index) 620 + { 621 + /* linear mapping for IRQ1 to IRQ4 */ 622 + if (index < 4) 623 + return base + index; 624 + 625 + /* handle IRQ5 separately */ 626 + if (base == AXP192_IRQ1_EN) 627 + return AXP192_IRQ5_EN; 628 + 629 + return AXP192_IRQ5_STATE; 630 + } 631 + 632 + static const struct regmap_irq_chip axp192_regmap_irq_chip = { 633 + .name = "axp192_irq_chip", 634 + .status_base = AXP192_IRQ1_STATE, 635 + .ack_base = AXP192_IRQ1_STATE, 636 + .unmask_base = AXP192_IRQ1_EN, 637 + .init_ack_masked = true, 638 + .irqs = axp192_regmap_irqs, 639 + .num_irqs = ARRAY_SIZE(axp192_regmap_irqs), 640 + .num_regs = 5, 641 + .get_irq_reg = axp192_get_irq_reg, 642 + }; 643 + 706 644 static const struct regmap_irq_chip axp20x_regmap_irq_chip = { 707 645 .name = "axp20x_irq_chip", 708 646 .status_base = AXP20X_IRQ1_STATE, ··· 817 703 .irqs = axp15060_regmap_irqs, 818 704 .num_irqs = ARRAY_SIZE(axp15060_regmap_irqs), 819 705 .num_regs = 2, 706 + }; 707 + 708 + static const struct mfd_cell axp192_cells[] = { 709 + { 710 + .name = "axp192-adc", 711 + .of_compatible = "x-powers,axp192-adc", 712 + }, { 713 + .name = "axp20x-battery-power-supply", 714 + .of_compatible = "x-powers,axp192-battery-power-supply", 715 + }, { 716 + .name = "axp20x-ac-power-supply", 717 + .of_compatible = "x-powers,axp202-ac-power-supply", 718 + .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources), 719 + .resources = axp192_ac_power_supply_resources, 720 + }, { 721 + .name = "axp20x-usb-power-supply", 722 + .of_compatible = "x-powers,axp192-usb-power-supply", 723 + .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources), 724 + .resources = axp192_usb_power_supply_resources, 725 + }, 726 + { .name = "axp20x-regulator" }, 820 727 }; 821 728 822 729 static const struct mfd_cell axp20x_cells[] = { ··· 1156 1021 axp20x->cells = axp152_cells; 1157 1022 axp20x->regmap_cfg = &axp152_regmap_config; 1158 1023 axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; 1024 + break; 1025 + case AXP192_ID: 1026 + axp20x->nr_cells = ARRAY_SIZE(axp192_cells); 1027 + axp20x->cells = axp192_cells; 1028 + axp20x->regmap_cfg = &axp192_regmap_config; 1029 + axp20x->regmap_irq_chip = &axp192_regmap_irq_chip; 1159 1030 break; 1160 1031 case AXP202_ID: 1161 1032 case AXP209_ID:
+84
include/linux/mfd/axp20x.h
··· 12 12 13 13 enum axp20x_variants { 14 14 AXP152_ID = 0, 15 + AXP192_ID, 15 16 AXP202_ID, 16 17 AXP209_ID, 17 18 AXP221_ID, ··· 27 26 NR_AXP20X_VARIANTS, 28 27 }; 29 28 29 + #define AXP192_DATACACHE(m) (0x06 + (m)) 30 30 #define AXP20X_DATACACHE(m) (0x04 + (m)) 31 31 32 32 /* Power supply */ ··· 48 46 #define AXP152_PEK_KEY 0x36 49 47 #define AXP152_DCDC_FREQ 0x37 50 48 #define AXP152_DCDC_MODE 0x80 49 + 50 + #define AXP192_USB_OTG_STATUS 0x04 51 + #define AXP192_PWR_OUT_CTRL 0x12 52 + #define AXP192_DCDC2_V_OUT 0x23 53 + #define AXP192_DCDC1_V_OUT 0x26 54 + #define AXP192_DCDC3_V_OUT 0x27 55 + #define AXP192_LDO2_3_V_OUT 0x28 51 56 52 57 #define AXP20X_PWR_INPUT_STATUS 0x00 53 58 #define AXP20X_PWR_OP_MODE 0x01 ··· 194 185 #define AXP152_IRQ2_STATE 0x49 195 186 #define AXP152_IRQ3_STATE 0x4a 196 187 188 + #define AXP192_IRQ1_EN 0x40 189 + #define AXP192_IRQ2_EN 0x41 190 + #define AXP192_IRQ3_EN 0x42 191 + #define AXP192_IRQ4_EN 0x43 192 + #define AXP192_IRQ1_STATE 0x44 193 + #define AXP192_IRQ2_STATE 0x45 194 + #define AXP192_IRQ3_STATE 0x46 195 + #define AXP192_IRQ4_STATE 0x47 196 + #define AXP192_IRQ5_EN 0x4a 197 + #define AXP192_IRQ5_STATE 0x4d 198 + 197 199 #define AXP20X_IRQ1_EN 0x40 198 200 #define AXP20X_IRQ2_EN 0x41 199 201 #define AXP20X_IRQ3_EN 0x42 ··· 224 204 #define AXP15060_IRQ2_STATE 0x49 225 205 226 206 /* ADC */ 207 + #define AXP192_GPIO2_V_ADC_H 0x68 208 + #define AXP192_GPIO2_V_ADC_L 0x69 209 + #define AXP192_GPIO3_V_ADC_H 0x6a 210 + #define AXP192_GPIO3_V_ADC_L 0x6b 211 + 227 212 #define AXP20X_ACIN_V_ADC_H 0x56 228 213 #define AXP20X_ACIN_V_ADC_L 0x57 229 214 #define AXP20X_ACIN_I_ADC_H 0x58 ··· 258 233 #define AXP20X_IPSOUT_V_HIGH_L 0x7f 259 234 260 235 /* Power supply */ 236 + #define AXP192_GPIO30_IN_RANGE 0x85 237 + 261 238 #define AXP20X_DCDC_MODE 0x80 262 239 #define AXP20X_ADC_EN1 0x82 263 240 #define AXP20X_ADC_EN2 0x83 ··· 287 260 #define AXP152_PWM1_FREQ_X 0x9b 288 261 #define AXP152_PWM1_FREQ_Y 0x9c 289 262 #define AXP152_PWM1_DUTY_CYCLE 0x9d 263 + 264 + #define AXP192_GPIO0_CTRL 0x90 265 + #define AXP192_LDO_IO0_V_OUT 0x91 266 + #define AXP192_GPIO1_CTRL 0x92 267 + #define AXP192_GPIO2_CTRL 0x93 268 + #define AXP192_GPIO2_0_STATE 0x94 269 + #define AXP192_GPIO4_3_CTRL 0x95 270 + #define AXP192_GPIO4_3_STATE 0x96 271 + #define AXP192_GPIO2_0_PULL 0x97 272 + #define AXP192_N_RSTO_CTRL 0x9e 290 273 291 274 #define AXP20X_GPIO0_CTRL 0x90 292 275 #define AXP20X_LDO5_V_OUT 0x91 ··· 377 340 #define AXP288_FG_TUNE5 0xed 378 341 379 342 /* Regulators IDs */ 343 + enum { 344 + AXP192_DCDC1 = 0, 345 + AXP192_DCDC2, 346 + AXP192_DCDC3, 347 + AXP192_LDO1, 348 + AXP192_LDO2, 349 + AXP192_LDO3, 350 + AXP192_LDO_IO0, 351 + AXP192_REG_ID_MAX 352 + }; 353 + 380 354 enum { 381 355 AXP20X_LDO1 = 0, 382 356 AXP20X_LDO2, ··· 577 529 AXP152_IRQ_GPIO2_INPUT, 578 530 AXP152_IRQ_GPIO1_INPUT, 579 531 AXP152_IRQ_GPIO0_INPUT, 532 + }; 533 + 534 + enum axp192_irqs { 535 + AXP192_IRQ_ACIN_OVER_V = 1, 536 + AXP192_IRQ_ACIN_PLUGIN, 537 + AXP192_IRQ_ACIN_REMOVAL, 538 + AXP192_IRQ_VBUS_OVER_V, 539 + AXP192_IRQ_VBUS_PLUGIN, 540 + AXP192_IRQ_VBUS_REMOVAL, 541 + AXP192_IRQ_VBUS_V_LOW, 542 + AXP192_IRQ_BATT_PLUGIN, 543 + AXP192_IRQ_BATT_REMOVAL, 544 + AXP192_IRQ_BATT_ENT_ACT_MODE, 545 + AXP192_IRQ_BATT_EXIT_ACT_MODE, 546 + AXP192_IRQ_CHARG, 547 + AXP192_IRQ_CHARG_DONE, 548 + AXP192_IRQ_BATT_TEMP_HIGH, 549 + AXP192_IRQ_BATT_TEMP_LOW, 550 + AXP192_IRQ_DIE_TEMP_HIGH, 551 + AXP192_IRQ_CHARG_I_LOW, 552 + AXP192_IRQ_DCDC1_V_LONG, 553 + AXP192_IRQ_DCDC2_V_LONG, 554 + AXP192_IRQ_DCDC3_V_LONG, 555 + AXP192_IRQ_PEK_SHORT = 22, 556 + AXP192_IRQ_PEK_LONG, 557 + AXP192_IRQ_N_OE_PWR_ON, 558 + AXP192_IRQ_N_OE_PWR_OFF, 559 + AXP192_IRQ_VBUS_VALID, 560 + AXP192_IRQ_VBUS_NOT_VALID, 561 + AXP192_IRQ_VBUS_SESS_VALID, 562 + AXP192_IRQ_VBUS_SESS_END, 563 + AXP192_IRQ_LOW_PWR_LVL = 31, 564 + AXP192_IRQ_TIMER, 565 + AXP192_IRQ_GPIO2_INPUT = 37, 566 + AXP192_IRQ_GPIO1_INPUT, 567 + AXP192_IRQ_GPIO0_INPUT, 580 568 }; 581 569 582 570 enum {