[PATCH 02/18] drivers: regulator: Fixes for TPS65941 LDO voltage conversion
Apelete Seketeli
aseketeli at baylibre.com
Fri May 12 15:17:29 CEST 2023
From: Jerome Neanne <jneanne at baylibre.com>
Fixes: 065a452ae6a power: regulator: tps65941: add regulator support
LDO voltage conversion was incorrect.
This was checked by writing and reading back value.
Signed-off-by: Jerome Neanne <jneanne at baylibre.com>
Signed-off-by: Apelete Seketeli <aseketeli at baylibre.com>
---
drivers/power/regulator/tps65941_regulator.c | 71 +++++++++++++++++---
1 file changed, 63 insertions(+), 8 deletions(-)
diff --git a/drivers/power/regulator/tps65941_regulator.c b/drivers/power/regulator/tps65941_regulator.c
index b041126775..7afd68c5c4 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -212,12 +212,55 @@ static int tps65941_ldo_enable(struct udevice *dev, int op, bool *enable)
return 0;
}
-static int tps65941_ldo_val2volt(int val)
+static int tps65941_ldo_volt2val(int idx, int uV)
{
- if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
+ int base = TPS65941_LDO123_VOLT_MIN;
+ int max = TPS65941_LDO_VOLT_MAX;
+ int offset = TPS65941_LDO123_VSET_MIN;
+ int step = TPS65941_LDO123_STEP;
+
+ if (idx > 2) {
+ base = TPS65941_LDO4_VOLT_MIN;
+ offset = TPS65941_LDO4_VSET_MIN;
+ step = TPS65941_LDO4_STEP;
+ }
+
+ if (uV > max)
return -EINVAL;
- else if (val >= TPS65941_LDO_VOLT_MIN_HEX)
- return 600000 + (val - TPS65941_LDO_VOLT_MIN_HEX) * 50000;
+ else if (uV >= base)
+ return (uV - base) / step + offset;
+ else
+ return -EINVAL;
+}
+
+static int tps65941_ldo_val2volt(int idx, int val)
+{
+ int reg_base = TPS65941_LDO123_VSET_MIN;
+ int reg_max = TPS65941_LDO123_VSET_MAX;
+ int base = TPS65941_LDO123_VOLT_MIN;
+ int max = TPS65941_LDO_VOLT_MAX;
+ int step = TPS65941_LDO123_STEP;
+ int mask = TPS65941_LDO_VOLT_MASK >> 1;
+
+ if (idx > 2) {
+ base = TPS65941_LDO4_VOLT_MIN;
+ max = TPS65941_LDO_VOLT_MAX;
+ reg_base = TPS65941_LDO4_VSET_MIN;
+ reg_max = TPS65941_LDO4_VSET_MAX;
+ step = TPS65941_LDO4_STEP;
+ mask = TPS65941_LDO_VOLT_MASK;
+ } else {
+ val = val >> 1;
+ }
+
+ if (val > mask || val < 0)
+ return -EINVAL;
+ else if (val >= reg_max)
+ return max;
+ else if (val <= reg_base)
+ return base;
+ else if (val >= 0)
+ return base + (step * (val - reg_base));
else
return -EINVAL;
}
@@ -227,7 +270,9 @@ static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
unsigned int hex, adr;
int ret;
struct dm_regulator_uclass_plat *uc_pdata;
+ int idx;
+ idx = dev->driver_data - 1;
uc_pdata = dev_get_uclass_plat(dev);
if (op == PMIC_OP_GET)
@@ -240,7 +285,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
return ret;
ret &= TPS65941_LDO_VOLT_MASK;
- ret = tps65941_ldo_val2volt(ret);
+ ret = tps65941_ldo_val2volt(idx, ret);
+
if (ret < 0)
return ret;
@@ -249,12 +295,21 @@ static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
return 0;
}
- hex = tps65941_buck_volt2val(*uV);
+ /* LDO1, LDO2 & LDO3 in BYPASS mode only supports 1.7V min to 3.6V max */
+ if (idx < 2 &&
+ (ret & BIT(TPS65941_LDO123_BYP_CONFIG)) &&
+ *uV < TPS65941_LDO123_VOLT_BYP_MIN)
+ return -EINVAL;
+
+ hex = tps65941_ldo_volt2val(idx, *uV);
if (hex < 0)
return hex;
- ret &= 0x0;
- ret = hex;
+ if (idx < 2)
+ hex = hex << 1;
+
+ ret &= ~TPS65941_LDO_VOLT_MASK;
+ ret |= hex;
ret = pmic_reg_write(dev->parent, adr, ret);
--
2.34.1
More information about the U-Boot
mailing list