Skip to content

Commit 3b88f5f

Browse files
committed
regulator: Add X-Powers AXP15060/AXP313a PMIC
Merge series from Andre Przywara <andre.przywara@arm.com>: This patch series adds support for the X-Powers AXP15060 and AXP313a PMIC, which are general purpose PMICs as seen on different boards with different SOCs, mostly from Allwinner. This is mostly a repost of the previous patches, combining both the AXP313a and AXP15060 series, rebased on top of v6.4-rc3, and omitting the patches that already got merged. The first two patches are the successors of the AXP313a v10 post, the third patch is based on Shengyu's AXP15060 v3 post. There were no code changes, just some tiny context differences due to the rebase, plus I added the newly gained tags. As the DT bindings and the AXP15060 MFD part are already in the tree, this is just completing support with the MFD part for the AXP313a, and the regulator support for both PMICs.
2 parents 9defeb9 + 9e72869 commit 3b88f5f

4 files changed

Lines changed: 393 additions & 9 deletions

File tree

drivers/mfd/axp20x-i2c.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
6363
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
6464
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
6565
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
66+
{ .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
6667
{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
6768
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
6869
{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
@@ -77,6 +78,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
7778
{ "axp209", 0 },
7879
{ "axp221", 0 },
7980
{ "axp223", 0 },
81+
{ "axp313a", 0 },
8082
{ "axp803", 0 },
8183
{ "axp806", 0 },
8284
{ "axp15060", 0 },

drivers/mfd/axp20x.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static const char * const axp20x_model_names[] = {
3939
"AXP221",
4040
"AXP223",
4141
"AXP288",
42+
"AXP313a",
4243
"AXP803",
4344
"AXP806",
4445
"AXP809",
@@ -156,6 +157,25 @@ static const struct regmap_range axp806_writeable_ranges[] = {
156157
regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
157158
};
158159

160+
static const struct regmap_range axp313a_writeable_ranges[] = {
161+
regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
162+
};
163+
164+
static const struct regmap_range axp313a_volatile_ranges[] = {
165+
regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
166+
regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
167+
};
168+
169+
static const struct regmap_access_table axp313a_writeable_table = {
170+
.yes_ranges = axp313a_writeable_ranges,
171+
.n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
172+
};
173+
174+
static const struct regmap_access_table axp313a_volatile_table = {
175+
.yes_ranges = axp313a_volatile_ranges,
176+
.n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
177+
};
178+
159179
static const struct regmap_range axp806_volatile_ranges[] = {
160180
regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
161181
};
@@ -248,6 +268,11 @@ static const struct resource axp288_fuel_gauge_resources[] = {
248268
DEFINE_RES_IRQ(AXP288_IRQ_WL1),
249269
};
250270

271+
static const struct resource axp313a_pek_resources[] = {
272+
DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
273+
DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
274+
};
275+
251276
static const struct resource axp803_pek_resources[] = {
252277
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
253278
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -304,6 +329,15 @@ static const struct regmap_config axp288_regmap_config = {
304329
.cache_type = REGCACHE_RBTREE,
305330
};
306331

332+
static const struct regmap_config axp313a_regmap_config = {
333+
.reg_bits = 8,
334+
.val_bits = 8,
335+
.wr_table = &axp313a_writeable_table,
336+
.volatile_table = &axp313a_volatile_table,
337+
.max_register = AXP313A_IRQ_STATE,
338+
.cache_type = REGCACHE_RBTREE,
339+
};
340+
307341
static const struct regmap_config axp806_regmap_config = {
308342
.reg_bits = 8,
309343
.val_bits = 8,
@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
456490
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
457491
};
458492

493+
static const struct regmap_irq axp313a_regmap_irqs[] = {
494+
INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
495+
INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
496+
INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
497+
INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
498+
INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
499+
INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
500+
INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
501+
};
502+
459503
static const struct regmap_irq axp803_regmap_irqs[] = {
460504
INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
461505
INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
@@ -606,6 +650,17 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
606650

607651
};
608652

653+
static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
654+
.name = "axp313a_irq_chip",
655+
.status_base = AXP313A_IRQ_STATE,
656+
.ack_base = AXP313A_IRQ_STATE,
657+
.unmask_base = AXP313A_IRQ_EN,
658+
.init_ack_masked = true,
659+
.irqs = axp313a_regmap_irqs,
660+
.num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
661+
.num_regs = 1,
662+
};
663+
609664
static const struct regmap_irq_chip axp803_regmap_irq_chip = {
610665
.name = "axp803",
611666
.status_base = AXP20X_IRQ1_STATE,
@@ -745,6 +800,11 @@ static const struct mfd_cell axp152_cells[] = {
745800
},
746801
};
747802

803+
static struct mfd_cell axp313a_cells[] = {
804+
MFD_CELL_NAME("axp20x-regulator"),
805+
MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
806+
};
807+
748808
static const struct resource axp288_adc_resources[] = {
749809
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
750810
};
@@ -914,8 +974,18 @@ static const struct mfd_cell axp_regulator_only_cells[] = {
914974
static int axp20x_power_off(struct sys_off_data *data)
915975
{
916976
struct axp20x_dev *axp20x = data->cb_data;
977+
unsigned int shutdown_reg;
917978

918-
regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
979+
switch (axp20x->variant) {
980+
case AXP313A_ID:
981+
shutdown_reg = AXP313A_SHUTDOWN_CTRL;
982+
break;
983+
default:
984+
shutdown_reg = AXP20X_OFF_CTRL;
985+
break;
986+
}
987+
988+
regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
919989

920990
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
921991
mdelay(500);
@@ -978,6 +1048,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
9781048
axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
9791049
axp20x->irq_flags = IRQF_TRIGGER_LOW;
9801050
break;
1051+
case AXP313A_ID:
1052+
axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
1053+
axp20x->cells = axp313a_cells;
1054+
axp20x->regmap_cfg = &axp313a_regmap_config;
1055+
axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
1056+
break;
9811057
case AXP803_ID:
9821058
axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
9831059
axp20x->cells = axp803_cells;

0 commit comments

Comments
 (0)