axp20x: Add support for AXP313a PMIC
The X-Powers AXP313a is a PMIC used on some devices with the Allwinner H616 or H313 SoC. Signed-off-by: Martin Botka <martin.botka@somainline.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
e91aa6bfb2
commit
e9b7c2cabb
@ -88,6 +88,7 @@ properties:
|
||||
- x-powers,axp209
|
||||
- x-powers,axp221
|
||||
- x-powers,axp223
|
||||
- x-powers,axp313a
|
||||
- x-powers,axp803
|
||||
- x-powers,axp806
|
||||
- x-powers,axp809
|
||||
|
||||
@ -64,6 +64,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
|
||||
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
|
||||
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
|
||||
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
|
||||
{ .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID},
|
||||
{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
|
||||
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
|
||||
{ },
|
||||
@ -77,6 +78,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ "axp209", 0 },
|
||||
{ "axp221", 0 },
|
||||
{ "axp223", 0 },
|
||||
{ "axp313a", 0 },
|
||||
{ "axp803", 0 },
|
||||
{ "axp806", 0 },
|
||||
{ },
|
||||
|
||||
@ -39,6 +39,7 @@ static const char * const axp20x_model_names[] = {
|
||||
"AXP221",
|
||||
"AXP223",
|
||||
"AXP288",
|
||||
"AXP313a",
|
||||
"AXP803",
|
||||
"AXP806",
|
||||
"AXP809",
|
||||
@ -154,6 +155,24 @@ static const struct regmap_range axp806_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp313a_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp313a_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp313a_writeable_table = {
|
||||
.yes_ranges = axp313a_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp313a_volatile_table = {
|
||||
.yes_ranges = axp313a_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp806_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
|
||||
};
|
||||
@ -272,6 +291,15 @@ static const struct regmap_config axp288_regmap_config = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config axp313a_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp313a_writeable_table,
|
||||
.volatile_table = &axp313a_volatile_table,
|
||||
.max_register = AXP313A_IRQ_STATE,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config axp806_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -415,6 +443,16 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp313a_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
|
||||
INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
|
||||
INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
|
||||
INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
|
||||
};
|
||||
|
||||
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),
|
||||
@ -552,6 +590,17 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
|
||||
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
|
||||
.name = "axp313a_irq_chip",
|
||||
.status_base = AXP313A_IRQ_STATE,
|
||||
.ack_base = AXP313A_IRQ_STATE,
|
||||
.unmask_base = AXP313A_IRQ_EN,
|
||||
.init_ack_masked = true,
|
||||
.irqs = axp313a_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp803_regmap_irq_chip = {
|
||||
.name = "axp803",
|
||||
.status_base = AXP20X_IRQ1_STATE,
|
||||
@ -683,6 +732,12 @@ static const struct mfd_cell axp152_cells[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp313a_cells[] = {
|
||||
{
|
||||
.name = "axp20x-regulator",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct resource axp288_adc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
|
||||
};
|
||||
@ -900,6 +955,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 AXP313A_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
|
||||
axp20x->cells = axp313a_cells;
|
||||
axp20x->regmap_cfg = &axp313a_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
|
||||
break;
|
||||
case AXP803_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
|
||||
axp20x->cells = axp803_cells;
|
||||
|
||||
@ -134,6 +134,11 @@
|
||||
#define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
|
||||
#define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
|
||||
|
||||
#define AXP313A_DCDC1_NUM_VOLTAGES 107
|
||||
#define AXP313A_DCDC23_NUM_VOLTAGES 88
|
||||
#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
|
||||
#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
|
||||
|
||||
#define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
|
||||
#define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
|
||||
#define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
|
||||
@ -638,6 +643,48 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
|
||||
.ops = &axp20x_ops_sw,
|
||||
};
|
||||
|
||||
static const struct linear_range axp313a_dcdc1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
|
||||
};
|
||||
|
||||
static const struct linear_range axp313a_dcdc2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
|
||||
};
|
||||
|
||||
/*
|
||||
* This is deviating from the datasheet. The values here are taken from the
|
||||
* BSP driver and have been confirmed by measurements.
|
||||
*/
|
||||
static const struct linear_range axp313a_dcdc3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
|
||||
};
|
||||
|
||||
static const struct regulator_desc axp313a_regulators[] = {
|
||||
AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
|
||||
axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
|
||||
AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(0)),
|
||||
AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
|
||||
axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
|
||||
AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(1)),
|
||||
AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
|
||||
axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
|
||||
AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(2)),
|
||||
AXP_DESC(AXP313A, LDO1, "ldo1", "vin1", 500, 3500, 100,
|
||||
AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(3)),
|
||||
AXP_DESC(AXP313A, LDO2, "ldo2", "vin1", 500, 3500, 100,
|
||||
AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(4)),
|
||||
AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
|
||||
};
|
||||
|
||||
/* DCDC ranges shared with AXP813 */
|
||||
static const struct linear_range axp803_dcdc234_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000,
|
||||
@ -1040,6 +1087,15 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
|
||||
def = 3000;
|
||||
step = 150;
|
||||
break;
|
||||
case AXP313A_ID:
|
||||
/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
|
||||
if (dcdcfreq != 3000000) {
|
||||
dev_err(&pdev->dev,
|
||||
"DCDC frequency on AXP313a is fixed to 3 MHz.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
default:
|
||||
dev_err(&pdev->dev,
|
||||
"Setting DCDC frequency for unsupported AXP variant\n");
|
||||
@ -1232,6 +1288,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
|
||||
"x-powers,drive-vbus-en");
|
||||
break;
|
||||
case AXP313A_ID:
|
||||
regulators = axp313a_regulators;
|
||||
nregulators = AXP313A_REG_ID_MAX;
|
||||
break;
|
||||
case AXP803_ID:
|
||||
regulators = axp803_regulators;
|
||||
nregulators = AXP803_REG_ID_MAX;
|
||||
|
||||
@ -17,6 +17,7 @@ enum axp20x_variants {
|
||||
AXP221_ID,
|
||||
AXP223_ID,
|
||||
AXP288_ID,
|
||||
AXP313A_ID,
|
||||
AXP803_ID,
|
||||
AXP806_ID,
|
||||
AXP809_ID,
|
||||
@ -91,6 +92,17 @@ enum axp20x_variants {
|
||||
#define AXP22X_ALDO3_V_OUT 0x2a
|
||||
#define AXP22X_CHRG_CTRL3 0x35
|
||||
|
||||
#define AXP313A_ON_INDICATE 0x00
|
||||
#define AXP313A_OUTPUT_CONTROL 0x10
|
||||
#define AXP313A_DCDC1_CONRTOL 0x13
|
||||
#define AXP313A_DCDC2_CONRTOL 0x14
|
||||
#define AXP313A_DCDC3_CONRTOL 0x15
|
||||
#define AXP313A_ALDO1_CONRTOL 0x16
|
||||
#define AXP313A_DLDO1_CONRTOL 0x17
|
||||
#define AXP313A_OUTPUT_MONITOR 0x1d
|
||||
#define AXP313A_IRQ_EN 0x20
|
||||
#define AXP313A_IRQ_STATE 0x21
|
||||
|
||||
#define AXP806_STARTUP_SRC 0x00
|
||||
#define AXP806_CHIP_ID 0x03
|
||||
#define AXP806_PWR_OUT_CTRL1 0x10
|
||||
@ -322,6 +334,16 @@ enum {
|
||||
AXP22X_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP313A_DCDC1 = 0,
|
||||
AXP313A_DCDC2,
|
||||
AXP313A_DCDC3,
|
||||
AXP313A_LDO1,
|
||||
AXP313A_LDO2,
|
||||
AXP313A_RTC_LDO,
|
||||
AXP313A_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP806_DCDCA = 0,
|
||||
AXP806_DCDCB,
|
||||
@ -545,6 +567,16 @@ enum axp288_irqs {
|
||||
AXP288_IRQ_BC_USB_CHNG,
|
||||
};
|
||||
|
||||
enum axp313a_irqs {
|
||||
AXP313A_IRQ_DIE_TEMP_HIGH,
|
||||
AXP313A_IRQ_DCDC2_V_LOW = 2,
|
||||
AXP313A_IRQ_DCDC3_V_LOW,
|
||||
AXP313A_IRQ_PEK_LONG,
|
||||
AXP313A_IRQ_PEK_SHORT,
|
||||
AXP313A_IRQ_PEK_FAL_EDGE,
|
||||
AXP313A_IRQ_PEK_RIS_EDGE,
|
||||
};
|
||||
|
||||
enum axp803_irqs {
|
||||
AXP803_IRQ_ACIN_OVER_V = 1,
|
||||
AXP803_IRQ_ACIN_PLUGIN,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user