Re: [linux-sunxi] [PATCH 2/8] regulator: axp20x: add support for set_ramp_delay for AXP209

2018-12-12 Thread Priit Laes
On Wed, Dec 12, 2018 at 12:14:57AM +1100, Julian Calaby wrote:
> Hi Priit and Olliver,
> 
> On Tue, Dec 11, 2018 at 5:42 AM Priit Laes  wrote:
> >
> > From: Olliver Schinagl 
> >
> > The AXP209 supports ramping up voltages on several regulators such as
> > DCDC2 and LDO3.
> >
> > This patch adds preliminary support for the regulator-ramp-delay property
> > for these 2 regulators. Note that the voltage ramp only works when
> > regulator is already enabled. E.g. when going from say 0.7 V to 3.6 V.
> >
> > When turning on the regulator, no voltage ramp is performed in hardware.
> >
> > What this means, is that if the bootloader brings up the voltage at 0.7 V,
> > the ramp delay property is properly applied. If however, the bootloader
> > leaves the power off, no ramp delay is applied when the power is
> > enabled by the regulator framework.
> >
> > Signed-off-by: Olliver Schinagl 
> > Signed-off-by: Priit Laes 
> > ---
> >  drivers/regulator/axp20x-regulator.c | 85 +-
> >  1 file changed, 85 insertions(+)
> >
> > diff --git a/drivers/regulator/axp20x-regulator.c 
> > b/drivers/regulator/axp20x-regulator.c
> > index 9a2db28..1d9fa62 100644
> > --- a/drivers/regulator/axp20x-regulator.c
> > +++ b/drivers/regulator/axp20x-regulator.c
> > @@ -346,6 +357,79 @@
> > .ops= _ops_range,
> > \
> > }
> >
> > +static const int axp209_dcdc2_ldo3_slew_rates[] = {
> > +   1600,
> > +800,
> > +};
> > +
> > +static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
> > +{
> > +   struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
> > +   const struct regulator_desc *desc = rdev->desc;
> > +   u8 reg, mask, enable, cfg = 0xff;
> > +   const int *slew_rates;
> > +   int rate_count = 0;
> > +
> > +   if (!rdev)
> > +   return -EINVAL;
> > +
> > +   switch (axp20x->variant) {
> > +   case AXP209_ID:
> > +   if (desc->id == AXP20X_DCDC2) {
> 
> Is slew_rates supposed to be set here?

Yes, nice catch.
> 
> > +   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;
> > +   enable = (ramp > 0) ?
> > +AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN :
> > +!AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN;
> > +   break;
> > +   }
> > +
> > +   if (desc->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_LDO3_RATE_MASK |
> > +  AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
> > +   enable = (ramp > 0) ?
> > +AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN :
> > +!AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN;
> > +   break;
> > +   }
> > +
> > +   if (rate_count > 0)
> > +   break;
> 
> You could save one to two tests by combining the above three if statements, 
> i.e.
> 
> if (DCDC2) {
> // set DCDC2 stuff
> 
> break;
> } else if (LDO3) {
> // set LDO3 stuff
> 
> break;
> }

OK, will look into it.
> 
> As written, the rate_count > 0 test will never be true as every block
> that sets rate_count breaks out of the switch block.

Yes, it is somewhat superfluous, as each regulator which supports ramping
should break out of the switch itself.

> You could then calculate rate_count below the switch block.
>
> > +
> > +   /* fall through */
> > +   default:
> > +   /* Not supported for this regulator */
> > +   return -ENOTSUPP;
> > +   }
> > +
> > +   if (ramp == 0) {
> > +   cfg = enable;
> > +   } else {
> > +   int i;
> > +
> > +   for (i = 0; i < rate_count; i++) {
> > +   if (ramp <= slew_rates[i])
> > +   cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i);
> > +   else
> > +   break;
> > +   }
> > +
> > +   if (cfg == 0xff) {
> > +   dev_err(axp20x->dev, "unsupported ramp value %d", 
> > ramp);
> > +   return -EINVAL;
> > +   }
> > +
> > +   cfg |= enable;
> > +   }
> > +
> > +   return regmap_update_bits(axp20x->regmap, reg, mask, cfg);
> > +}
> > +
> 
> 
> 
> -- 
> Julian Calaby
> 
> Email: julian.cal...@gmail.com
> Profile: 

Re: [linux-sunxi] [PATCH 2/8] regulator: axp20x: add support for set_ramp_delay for AXP209

2018-12-11 Thread Julian Calaby
Hi Priit and Olliver,

On Tue, Dec 11, 2018 at 5:42 AM Priit Laes  wrote:
>
> From: Olliver Schinagl 
>
> The AXP209 supports ramping up voltages on several regulators such as
> DCDC2 and LDO3.
>
> This patch adds preliminary support for the regulator-ramp-delay property
> for these 2 regulators. Note that the voltage ramp only works when
> regulator is already enabled. E.g. when going from say 0.7 V to 3.6 V.
>
> When turning on the regulator, no voltage ramp is performed in hardware.
>
> What this means, is that if the bootloader brings up the voltage at 0.7 V,
> the ramp delay property is properly applied. If however, the bootloader
> leaves the power off, no ramp delay is applied when the power is
> enabled by the regulator framework.
>
> Signed-off-by: Olliver Schinagl 
> Signed-off-by: Priit Laes 
> ---
>  drivers/regulator/axp20x-regulator.c | 85 +-
>  1 file changed, 85 insertions(+)
>
> diff --git a/drivers/regulator/axp20x-regulator.c 
> b/drivers/regulator/axp20x-regulator.c
> index 9a2db28..1d9fa62 100644
> --- a/drivers/regulator/axp20x-regulator.c
> +++ b/drivers/regulator/axp20x-regulator.c
> @@ -346,6 +357,79 @@
> .ops= _ops_range,  
>   \
> }
>
> +static const int axp209_dcdc2_ldo3_slew_rates[] = {
> +   1600,
> +800,
> +};
> +
> +static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
> +{
> +   struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
> +   const struct regulator_desc *desc = rdev->desc;
> +   u8 reg, mask, enable, cfg = 0xff;
> +   const int *slew_rates;
> +   int rate_count = 0;
> +
> +   if (!rdev)
> +   return -EINVAL;
> +
> +   switch (axp20x->variant) {
> +   case AXP209_ID:
> +   if (desc->id == AXP20X_DCDC2) {

Is slew_rates supposed to be set here?

> +   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;
> +   enable = (ramp > 0) ?
> +AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN :
> +!AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN;
> +   break;
> +   }
> +
> +   if (desc->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_LDO3_RATE_MASK |
> +  AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
> +   enable = (ramp > 0) ?
> +AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN :
> +!AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN;
> +   break;
> +   }
> +
> +   if (rate_count > 0)
> +   break;

You could save one to two tests by combining the above three if statements, i.e.

if (DCDC2) {
// set DCDC2 stuff

break;
} else if (LDO3) {
// set LDO3 stuff

break;
}

As written, the rate_count > 0 test will never be true as every block
that sets rate_count breaks out of the switch block.

You could then calculate rate_count below the switch block.

> +
> +   /* fall through */
> +   default:
> +   /* Not supported for this regulator */
> +   return -ENOTSUPP;
> +   }
> +
> +   if (ramp == 0) {
> +   cfg = enable;
> +   } else {
> +   int i;
> +
> +   for (i = 0; i < rate_count; i++) {
> +   if (ramp <= slew_rates[i])
> +   cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i);
> +   else
> +   break;
> +   }
> +
> +   if (cfg == 0xff) {
> +   dev_err(axp20x->dev, "unsupported ramp value %d", 
> ramp);
> +   return -EINVAL;
> +   }
> +
> +   cfg |= enable;
> +   }
> +
> +   return regmap_update_bits(axp20x->regmap, reg, mask, cfg);
> +}
> +



-- 
Julian Calaby

Email: julian.cal...@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 2/8] regulator: axp20x: add support for set_ramp_delay for AXP209

2018-12-10 Thread Priit Laes
From: Olliver Schinagl 

The AXP209 supports ramping up voltages on several regulators such as
DCDC2 and LDO3.

This patch adds preliminary support for the regulator-ramp-delay property
for these 2 regulators. Note that the voltage ramp only works when
regulator is already enabled. E.g. when going from say 0.7 V to 3.6 V.

When turning on the regulator, no voltage ramp is performed in hardware.

What this means, is that if the bootloader brings up the voltage at 0.7 V,
the ramp delay property is properly applied. If however, the bootloader
leaves the power off, no ramp delay is applied when the power is
enabled by the regulator framework.

Signed-off-by: Olliver Schinagl 
Signed-off-by: Priit Laes 
---
 drivers/regulator/axp20x-regulator.c | 85 +-
 1 file changed, 85 insertions(+)

diff --git a/drivers/regulator/axp20x-regulator.c 
b/drivers/regulator/axp20x-regulator.c
index 9a2db28..1d9fa62 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -51,6 +51,17 @@
 #define AXP20X_PWR_OUT_DCDC2_MASK  BIT_MASK(4)
 #define AXP20X_PWR_OUT_LDO3_MASK   BIT_MASK(6)
 
+#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK   BIT_MASK(0)
+#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(x) \
+   ((x) << 0)
+#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASKBIT_MASK(1)
+#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(x) \
+   ((x) << 1)
+#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK BIT_MASK(2)
+#define AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN  BIT(2)
+#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK  BIT_MASK(3)
+#define AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN   BIT(3)
+
 #define AXP20X_LDO4_V_OUT_1250mV_START 0x0
 #define AXP20X_LDO4_V_OUT_1250mV_STEPS 0
 #define AXP20X_LDO4_V_OUT_1250mV_END   \
@@ -346,6 +357,79 @@
.ops= _ops_range,
\
}
 
+static const int axp209_dcdc2_ldo3_slew_rates[] = {
+   1600,
+800,
+};
+
+static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
+{
+   struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
+   const struct regulator_desc *desc = rdev->desc;
+   u8 reg, mask, enable, cfg = 0xff;
+   const int *slew_rates;
+   int rate_count = 0;
+
+   if (!rdev)
+   return -EINVAL;
+
+   switch (axp20x->variant) {
+   case AXP209_ID:
+   if (desc->id == AXP20X_DCDC2) {
+   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;
+   enable = (ramp > 0) ?
+AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN :
+!AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN;
+   break;
+   }
+
+   if (desc->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_LDO3_RATE_MASK |
+  AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK;
+   enable = (ramp > 0) ?
+AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN :
+!AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN;
+   break;
+   }
+
+   if (rate_count > 0)
+   break;
+
+   /* fall through */
+   default:
+   /* Not supported for this regulator */
+   return -ENOTSUPP;
+   }
+
+   if (ramp == 0) {
+   cfg = enable;
+   } else {
+   int i;
+
+   for (i = 0; i < rate_count; i++) {
+   if (ramp <= slew_rates[i])
+   cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i);
+   else
+   break;
+   }
+
+   if (cfg == 0xff) {
+   dev_err(axp20x->dev, "unsupported ramp value %d", ramp);
+   return -EINVAL;
+   }
+
+   cfg |= enable;
+   }
+
+   return regmap_update_bits(axp20x->regmap, reg, mask, cfg);
+}
+
 static const struct regulator_ops axp20x_ops_fixed = {
.list_voltage   = regulator_list_voltage_linear,
 };
@@ -366,6 +450,7 @@ static const struct regulator_ops axp20x_ops = {
.enable = regulator_enable_regmap,
.disable= regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
+   .set_ramp_delay = axp20x_set_ramp_delay,
 };
 
 static const struct regulator_ops axp20x_ops_sw = {
-- 
git-series