diff options
Diffstat (limited to 'drivers/mfd/axp20x.c')
-rw-r--r-- | drivers/mfd/axp20x.c | 129 |
1 files changed, 120 insertions, 9 deletions
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 25115fe2acdf..1dc6235778eb 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -31,6 +31,7 @@ #define AXP20X_OFF 0x80 +#define AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE 0 #define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4) static const char * const axp20x_model_names[] = { @@ -40,6 +41,7 @@ static const char * const axp20x_model_names[] = { "AXP221", "AXP223", "AXP288", + "AXP803", "AXP806", "AXP809", }; @@ -67,6 +69,7 @@ static const struct regmap_access_table axp152_volatile_table = { static const struct regmap_range axp20x_writeable_ranges[] = { regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), + regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2), regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)), }; @@ -93,6 +96,7 @@ static const struct regmap_access_table axp20x_volatile_table = { /* AXP22x ranges are shared with the AXP809, as they cover the same range */ static const struct regmap_range axp22x_writeable_ranges[] = { regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), + regmap_reg_range(AXP20X_CHRG_CTRL1, AXP22X_CHRG_CTRL3), regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1), }; @@ -100,7 +104,7 @@ static const struct regmap_range axp22x_volatile_ranges[] = { regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE), regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), - regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L), + regmap_reg_range(AXP22X_PMIC_TEMP_H, AXP20X_IPSOUT_V_HIGH_L), regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES), }; @@ -114,6 +118,7 @@ static const struct regmap_access_table axp22x_volatile_table = { .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges), }; +/* AXP288 ranges are shared with the AXP803, as they cover the same range */ static const struct regmap_range axp288_writeable_ranges[] = { regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), @@ -261,6 +266,20 @@ static struct resource axp288_fuel_gauge_resources[] = { }, }; +static struct resource axp803_pek_resources[] = { + { + .name = "PEK_DBR", + .start = AXP803_IRQ_PEK_RIS_EDGE, + .end = AXP803_IRQ_PEK_RIS_EDGE, + .flags = IORESOURCE_IRQ, + }, { + .name = "PEK_DBF", + .start = AXP803_IRQ_PEK_FAL_EDGE, + .end = AXP803_IRQ_PEK_FAL_EDGE, + .flags = IORESOURCE_IRQ, + }, +}; + static struct resource axp809_pek_resources[] = { { .name = "PEK_DBR", @@ -454,6 +473,43 @@ static const struct regmap_irq axp288_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), }; +static const struct regmap_irq axp803_regmap_irqs[] = { + INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7), + INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6), + INIT_REGMAP_IRQ(AXP803, ACIN_REMOVAL, 0, 5), + INIT_REGMAP_IRQ(AXP803, VBUS_OVER_V, 0, 4), + INIT_REGMAP_IRQ(AXP803, VBUS_PLUGIN, 0, 3), + INIT_REGMAP_IRQ(AXP803, VBUS_REMOVAL, 0, 2), + INIT_REGMAP_IRQ(AXP803, BATT_PLUGIN, 1, 7), + INIT_REGMAP_IRQ(AXP803, BATT_REMOVAL, 1, 6), + INIT_REGMAP_IRQ(AXP803, BATT_ENT_ACT_MODE, 1, 5), + INIT_REGMAP_IRQ(AXP803, BATT_EXIT_ACT_MODE, 1, 4), + INIT_REGMAP_IRQ(AXP803, CHARG, 1, 3), + INIT_REGMAP_IRQ(AXP803, CHARG_DONE, 1, 2), + INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH, 2, 7), + INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_HIGH_END, 2, 6), + INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW, 2, 5), + INIT_REGMAP_IRQ(AXP803, BATT_CHG_TEMP_LOW_END, 2, 4), + INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH, 2, 3), + INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_HIGH_END, 2, 2), + INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW, 2, 1), + INIT_REGMAP_IRQ(AXP803, BATT_ACT_TEMP_LOW_END, 2, 0), + INIT_REGMAP_IRQ(AXP803, DIE_TEMP_HIGH, 3, 7), + INIT_REGMAP_IRQ(AXP803, GPADC, 3, 2), + INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL1, 3, 1), + INIT_REGMAP_IRQ(AXP803, LOW_PWR_LVL2, 3, 0), + INIT_REGMAP_IRQ(AXP803, TIMER, 4, 7), + INIT_REGMAP_IRQ(AXP803, PEK_RIS_EDGE, 4, 6), + INIT_REGMAP_IRQ(AXP803, PEK_FAL_EDGE, 4, 5), + INIT_REGMAP_IRQ(AXP803, PEK_SHORT, 4, 4), + INIT_REGMAP_IRQ(AXP803, PEK_LONG, 4, 3), + INIT_REGMAP_IRQ(AXP803, PEK_OVER_OFF, 4, 2), + INIT_REGMAP_IRQ(AXP803, GPIO1_INPUT, 4, 1), + INIT_REGMAP_IRQ(AXP803, GPIO0_INPUT, 4, 0), + INIT_REGMAP_IRQ(AXP803, BC_USB_CHNG, 5, 1), + INIT_REGMAP_IRQ(AXP803, MV_CHNG, 5, 0), +}; + static const struct regmap_irq axp806_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0), INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1), @@ -554,6 +610,18 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = { }; +static const struct regmap_irq_chip axp803_regmap_irq_chip = { + .name = "axp803", + .status_base = AXP20X_IRQ1_STATE, + .ack_base = AXP20X_IRQ1_STATE, + .mask_base = AXP20X_IRQ1_EN, + .mask_invert = true, + .init_ack_masked = true, + .irqs = axp803_regmap_irqs, + .num_irqs = ARRAY_SIZE(axp803_regmap_irqs), + .num_regs = 6, +}; + static const struct regmap_irq_chip axp806_regmap_irq_chip = { .name = "axp806", .status_base = AXP20X_IRQ1_STATE, @@ -589,6 +657,11 @@ static struct mfd_cell axp20x_cells[] = { }, { .name = "axp20x-regulator", }, { + .name = "axp20x-adc", + }, { + .name = "axp20x-battery-power-supply", + .of_compatible = "x-powers,axp209-battery-power-supply", + }, { .name = "axp20x-ac-power-supply", .of_compatible = "x-powers,axp202-ac-power-supply", .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), @@ -609,6 +682,16 @@ static struct mfd_cell axp221_cells[] = { }, { .name = "axp20x-regulator", }, { + .name = "axp22x-adc" + }, { + .name = "axp20x-ac-power-supply", + .of_compatible = "x-powers,axp221-ac-power-supply", + .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), + .resources = axp20x_ac_power_supply_resources, + }, { + .name = "axp20x-battery-power-supply", + .of_compatible = "x-powers,axp221-battery-power-supply", + }, { .name = "axp20x-usb-power-supply", .of_compatible = "x-powers,axp221-usb-power-supply", .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), @@ -622,8 +705,18 @@ static struct mfd_cell axp223_cells[] = { .num_resources = ARRAY_SIZE(axp22x_pek_resources), .resources = axp22x_pek_resources, }, { + .name = "axp22x-adc", + }, { + .name = "axp20x-battery-power-supply", + .of_compatible = "x-powers,axp221-battery-power-supply", + }, { .name = "axp20x-regulator", }, { + .name = "axp20x-ac-power-supply", + .of_compatible = "x-powers,axp221-ac-power-supply", + .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), + .resources = axp20x_ac_power_supply_resources, + }, { .name = "axp20x-usb-power-supply", .of_compatible = "x-powers,axp223-usb-power-supply", .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources), @@ -750,6 +843,14 @@ static struct mfd_cell axp288_cells[] = { }, }; +static struct mfd_cell axp803_cells[] = { + { + .name = "axp20x-pek", + .num_resources = ARRAY_SIZE(axp803_pek_resources), + .resources = axp803_pek_resources, + } +}; + static struct mfd_cell axp806_cells[] = { { .id = 2, @@ -836,6 +937,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x) axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; axp20x->irq_flags = IRQF_TRIGGER_LOW; break; + case AXP803_ID: + axp20x->nr_cells = ARRAY_SIZE(axp803_cells); + axp20x->cells = axp803_cells; + axp20x->regmap_cfg = &axp288_regmap_config; + axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; + break; case AXP806_ID: axp20x->nr_cells = ARRAY_SIZE(axp806_cells); axp20x->cells = axp806_cells; @@ -877,15 +984,19 @@ int axp20x_device_probe(struct axp20x_dev *axp20x) * the these device addressing bits (in the upper 4 bits of the * registers) match. * - * Since we only support an AXP806 chained to an AXP809 in slave - * mode, and there isn't any existing hardware which uses AXP806 - * in master mode, or has 2 AXP806s in the same system, we can - * just program the register address extension to the slave mode - * address. + * By default we support an AXP806 chained to an AXP809 in slave + * mode. Boards which use an AXP806 in master mode can set the + * property "x-powers,master-mode" to override the default. */ - if (axp20x->variant == AXP806_ID) - regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, - AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE); + if (axp20x->variant == AXP806_ID) { + if (of_property_read_bool(axp20x->dev->of_node, + "x-powers,master-mode")) + regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, + AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE); + else + regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT, + AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE); + } ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags, |