diff mbox series

[v4,07/15] regulator: axp20x: Add support for AXP192

Message ID 20220629143046.213584-8-aidanmacdonald.0x0@gmail.com (mailing list archive)
State Handled Elsewhere
Headers show
Series Add support for AXP192 PMIC | expand

Commit Message

Aidan MacDonald June 29, 2022, 2:30 p.m. UTC
Add support for the AXP192 PMIC.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 drivers/regulator/axp20x-regulator.c | 100 ++++++++++++++++++++++++---
 1 file changed, 91 insertions(+), 9 deletions(-)

Comments

Andy Shevchenko June 30, 2022, 7:58 a.m. UTC | #1
On Wed, Jun 29, 2022 at 4:29 PM Aidan MacDonald
<aidanmacdonald.0x0@gmail.com> wrote:
>
> Add support for the AXP192 PMIC.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Acked-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  drivers/regulator/axp20x-regulator.c | 100 ++++++++++++++++++++++++---
>  1 file changed, 91 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
> index d260c442b788..ee79a9ed0249 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;
>                 }
>
> @@ -415,7 +445,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 +542,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 +1062,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 +1160,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 +1298,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
>
diff mbox series

Patch

diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index d260c442b788..ee79a9ed0249 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;
 		}
 
@@ -415,7 +445,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 +542,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 +1062,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 +1160,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 +1298,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;