mfd: axp20x: Support AXP803 variant
authorIcenowy Zheng <icenowy@aosc.io>
Mon, 17 Apr 2017 11:57:40 +0000 (19:57 +0800)
committerLee Jones <lee.jones@linaro.org>
Thu, 27 Apr 2017 10:54:49 +0000 (11:54 +0100)
AXP803 is a new PMIC chip produced by X-Powers, usually paired with A64
via RSB bus. The PMIC itself is like AXP288, but with RSB support and
dedicated VBUS and ACIN.

Add support for it in the axp20x mfd driver.

Currently only power key function is supported.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
drivers/mfd/axp20x-rsb.c
drivers/mfd/axp20x.c
include/linux/mfd/axp20x.h

index a732cb50bcffc6df1644aaec410ac82ff7c12bb0..fd5c7267b136c4b127286687154373a1eea3213e 100644 (file)
@@ -61,6 +61,7 @@ static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
 
 static const struct of_device_id axp20x_rsb_of_match[] = {
        { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+       { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
        { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
        { .compatible = "x-powers,axp809", .data = (void *)AXP809_ID },
        { },
index e6f55079876e6cbc539b35f4365d1c1ad981eb7c..1dc6235778eb1e584845079f40962d181a4ac9f0 100644 (file)
@@ -41,6 +41,7 @@ static const char * const axp20x_model_names[] = {
        "AXP221",
        "AXP223",
        "AXP288",
+       "AXP803",
        "AXP806",
        "AXP809",
 };
@@ -117,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),
@@ -264,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",
@@ -457,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),
@@ -557,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,
@@ -778,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,
@@ -864,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;
index dc8798cf2a2473d7280ca06e135cf2523542c859..cde56cfe8446b17b9696b2e1182c13cb29f9e727 100644 (file)
@@ -20,6 +20,7 @@ enum axp20x_variants {
        AXP221_ID,
        AXP223_ID,
        AXP288_ID,
+       AXP803_ID,
        AXP806_ID,
        AXP809_ID,
        NR_AXP20X_VARIANTS,
@@ -234,7 +235,7 @@ enum axp20x_variants {
 #define AXP22X_TS_ADC_L                        0x59
 #define AXP22X_BATLOW_THRES1           0xe6
 
-/* AXP288 specific registers */
+/* AXP288/AXP803 specific registers */
 #define AXP288_POWER_REASON            0x02
 #define AXP288_BC_GLOBAL               0x2c
 #define AXP288_BC_VBUS_CNTL            0x2d
@@ -475,6 +476,43 @@ enum axp288_irqs {
        AXP288_IRQ_BC_USB_CHNG,
 };
 
+enum axp803_irqs {
+       AXP803_IRQ_ACIN_OVER_V = 1,
+       AXP803_IRQ_ACIN_PLUGIN,
+       AXP803_IRQ_ACIN_REMOVAL,
+       AXP803_IRQ_VBUS_OVER_V,
+       AXP803_IRQ_VBUS_PLUGIN,
+       AXP803_IRQ_VBUS_REMOVAL,
+       AXP803_IRQ_BATT_PLUGIN,
+       AXP803_IRQ_BATT_REMOVAL,
+       AXP803_IRQ_BATT_ENT_ACT_MODE,
+       AXP803_IRQ_BATT_EXIT_ACT_MODE,
+       AXP803_IRQ_CHARG,
+       AXP803_IRQ_CHARG_DONE,
+       AXP803_IRQ_BATT_CHG_TEMP_HIGH,
+       AXP803_IRQ_BATT_CHG_TEMP_HIGH_END,
+       AXP803_IRQ_BATT_CHG_TEMP_LOW,
+       AXP803_IRQ_BATT_CHG_TEMP_LOW_END,
+       AXP803_IRQ_BATT_ACT_TEMP_HIGH,
+       AXP803_IRQ_BATT_ACT_TEMP_HIGH_END,
+       AXP803_IRQ_BATT_ACT_TEMP_LOW,
+       AXP803_IRQ_BATT_ACT_TEMP_LOW_END,
+       AXP803_IRQ_DIE_TEMP_HIGH,
+       AXP803_IRQ_GPADC,
+       AXP803_IRQ_LOW_PWR_LVL1,
+       AXP803_IRQ_LOW_PWR_LVL2,
+       AXP803_IRQ_TIMER,
+       AXP803_IRQ_PEK_RIS_EDGE,
+       AXP803_IRQ_PEK_FAL_EDGE,
+       AXP803_IRQ_PEK_SHORT,
+       AXP803_IRQ_PEK_LONG,
+       AXP803_IRQ_PEK_OVER_OFF,
+       AXP803_IRQ_GPIO1_INPUT,
+       AXP803_IRQ_GPIO0_INPUT,
+       AXP803_IRQ_BC_USB_CHNG,
+       AXP803_IRQ_MV_CHNG,
+};
+
 enum axp806_irqs {
        AXP806_IRQ_DIE_TEMP_HIGH_LV1,
        AXP806_IRQ_DIE_TEMP_HIGH_LV2,