[PATCH v3 09/16] regulator: axp20x: Add support for AXP192

From: Aidan MacDonald
Date: Sat Jun 18 2022 - 17:40:38 EST


Add support for the AXP192 PMIC.

Acked-by: Mark Brown <broonie@xxxxxxxxxx>
Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@xxxxxxxxx>
---
drivers/regulator/axp20x-regulator.c | 101 ++++++++++++++++++++++++---
1 file changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index d260c442b788..2c59f398f6dd 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -27,6 +27,29 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>

+#define AXP192_GPIO0_FUNC_MASK GENMASK(2, 0)
+
+#define AXP192_IO_ENABLED 0x02
+#define AXP192_IO_DISABLED 0x06
+
+#define AXP192_WORKMODE_DCDC1_MASK BIT_MASK(3)
+#define AXP192_WORKMODE_DCDC2_MASK BIT_MASK(2)
+#define AXP192_WORKMODE_DCDC3_MASK BIT_MASK(1)
+
+#define AXP192_DCDC1_V_OUT_MASK GENMASK(6, 0)
+#define AXP192_DCDC2_V_OUT_MASK GENMASK(5, 0)
+#define AXP192_DCDC3_V_OUT_MASK GENMASK(6, 0)
+#define AXP192_LDO2_V_OUT_MASK GENMASK(7, 4)
+#define AXP192_LDO3_V_OUT_MASK GENMASK(3, 0)
+#define AXP192_LDO_IO0_V_OUT_MASK GENMASK(7, 4)
+
+#define AXP192_PWR_OUT_EXTEN_MASK BIT_MASK(6)
+#define AXP192_PWR_OUT_DCDC2_MASK BIT_MASK(4)
+#define AXP192_PWR_OUT_LDO3_MASK BIT_MASK(3)
+#define AXP192_PWR_OUT_LDO2_MASK BIT_MASK(2)
+#define AXP192_PWR_OUT_DCDC3_MASK BIT_MASK(1)
+#define AXP192_PWR_OUT_DCDC1_MASK BIT_MASK(0)
+
#define AXP20X_GPIO0_FUNC_MASK GENMASK(3, 0)
#define AXP20X_GPIO1_FUNC_MASK GENMASK(3, 0)

@@ -375,25 +398,32 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)

switch (axp20x->variant) {
case AXP209_ID:
- if (id == AXP20X_DCDC2) {
+ if (id == AXP20X_LDO3) {
slew_rates = axp209_dcdc2_ldo3_slew_rates;
rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
reg = AXP20X_DCDC2_LDO3_V_RAMP;
- mask = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK |
- AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK;
+ mask = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK |
+ AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
enable = (ramp > 0) ?
- AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN : 0;
+ AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN : 0;
break;
}

- if (id == AXP20X_LDO3) {
+ fallthrough;
+
+ case AXP192_ID:
+ /*
+ * AXP192 and AXP209 share the same DCDC2 ramp configuration
+ */
+ if ((axp20x->variant == AXP209_ID && id == AXP20X_DCDC2) ||
+ (axp20x->variant == AXP192_ID && id == AXP192_DCDC2)) {
slew_rates = axp209_dcdc2_ldo3_slew_rates;
rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
reg = AXP20X_DCDC2_LDO3_V_RAMP;
- mask = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK |
- AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
+ mask = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK |
+ AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK;
enable = (ramp > 0) ?
- AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN : 0;
+ AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN : 0;
break;
}

@@ -401,6 +431,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
break;

fallthrough;
+
default:
/* Not supported for this regulator */
return -ENOTSUPP;
@@ -415,7 +446,8 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
if (ramp > slew_rates[i])
break;

- if (id == AXP20X_DCDC2)
+ if ((axp20x->variant == AXP209_ID && id == AXP20X_DCDC2) ||
+ (axp20x->variant == AXP192_ID && id == AXP192_DCDC2))
cfg = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(i);
else
cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i);
@@ -511,6 +543,29 @@ static const struct regulator_ops axp20x_ops_sw = {
.is_enabled = regulator_is_enabled_regmap,
};

+static const struct regulator_desc axp192_regulators[] = {
+ AXP_DESC(AXP192, DCDC1, "dcdc1", "vin1", 700, 3500, 25,
+ AXP192_DCDC1_V_OUT, AXP192_DCDC1_V_OUT_MASK,
+ AXP192_PWR_OUT_CTRL, AXP192_PWR_OUT_DCDC1_MASK),
+ AXP_DESC(AXP192, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
+ AXP192_DCDC2_V_OUT, AXP192_DCDC2_V_OUT_MASK,
+ AXP192_PWR_OUT_CTRL, AXP192_PWR_OUT_DCDC2_MASK),
+ AXP_DESC(AXP192, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
+ AXP192_DCDC3_V_OUT, AXP192_DCDC3_V_OUT_MASK,
+ AXP192_PWR_OUT_CTRL, AXP192_PWR_OUT_DCDC3_MASK),
+ AXP_DESC_FIXED(AXP192, LDO1, "ldo1", "acin", 1250),
+ AXP_DESC(AXP192, LDO2, "ldo2", "ldoin", 1800, 3300, 100,
+ AXP192_LDO2_3_V_OUT, AXP192_LDO2_V_OUT_MASK,
+ AXP192_PWR_OUT_CTRL, AXP192_PWR_OUT_LDO2_MASK),
+ AXP_DESC(AXP192, LDO3, "ldo3", "ldoin", 1800, 3300, 100,
+ AXP192_LDO2_3_V_OUT, AXP192_LDO3_V_OUT_MASK,
+ AXP192_PWR_OUT_CTRL, AXP192_PWR_OUT_LDO3_MASK),
+ AXP_DESC_IO(AXP192, LDO_IO0, "ldo_io0", "ips", 700, 3300, 100,
+ AXP192_LDO_IO0_V_OUT, AXP192_LDO_IO0_V_OUT_MASK,
+ AXP192_GPIO0_CTRL, AXP192_GPIO0_FUNC_MASK,
+ AXP192_IO_ENABLED, AXP192_IO_DISABLED),
+};
+
static const struct linear_range axp20x_ldo4_ranges[] = {
REGULATOR_LINEAR_RANGE(1250000,
AXP20X_LDO4_V_OUT_1250mV_START,
@@ -1008,6 +1063,12 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
u32 min, max, def, step;

switch (axp20x->variant) {
+ case AXP192_ID:
+ min = 900;
+ max = 2025;
+ def = 1500;
+ step = 75;
+ break;
case AXP202_ID:
case AXP209_ID:
min = 750;
@@ -1100,6 +1161,24 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
unsigned int mask;

switch (axp20x->variant) {
+ case AXP192_ID:
+ switch (id) {
+ case AXP192_DCDC1:
+ mask = AXP192_WORKMODE_DCDC1_MASK;
+ break;
+ case AXP192_DCDC2:
+ mask = AXP192_WORKMODE_DCDC2_MASK;
+ break;
+ case AXP192_DCDC3:
+ mask = AXP192_WORKMODE_DCDC3_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ workmode <<= ffs(mask) - 1;
+ break;
+
case AXP202_ID:
case AXP209_ID:
if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
@@ -1220,6 +1299,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
bool drivevbus = false;

switch (axp20x->variant) {
+ case AXP192_ID:
+ regulators = axp192_regulators;
+ nregulators = AXP192_REG_ID_MAX;
+ break;
case AXP202_ID:
case AXP209_ID:
regulators = axp20x_regulators;
--
2.35.1