[PATCH v4 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-04-22 Thread Bhargav Raviprakash
Reuse TPS65941 regulator driver to adds support for
TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
BUCK1 and BUCK2 can be configured in dual phase mode.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 280 ++-
 1 file changed, 267 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index d879c2301b..5809a53fa2 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -37,6 +37,8 @@
 
 #define TPS65941_BUCK_CONV_OPS_IDX  0
 #define TPS65941_LDO_CONV_OPS_IDX   0
+#define TPS65224_LDO_CONV_OPS_IDX   1
+#define TPS65224_BUCK_CONV_OPS_IDX  1
 
 struct tps65941_reg_conv_ops {
int volt_mask;
@@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
{0x1D, 0x1E, 0x1F,
 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
0x26};
 
+static inline int tps65941_get_chip_id(struct udevice *dev)
+{
+   return dev->parent->driver_data;
+}
+
 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
 {
int ret;
@@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   /* This functions maps a value which is in micro Volts to the VSET 
value.
+* The mapping is as per the datasheet of TPS65224.
+*/
+
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
+* converting b/w micro_volt and VSET hex values
+*
+* VSET value starts from 0x00 for 0.5V, and for every increment
+* in VSET value the output voltage increases by 25mV. This is 
upto
+* 1.15V where VSET is 0x1A.
+*
+* For 0x1B the output voltage is 1.2V, and for every increment 
of
+* VSET the output voltage increases by 50mV upto the max 
voltage of
+* 3.3V
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
+* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
+*/
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
+* voltage and VSET value.
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
+* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
+* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
+* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
+*
+*/
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   /* This function does the opposite to the tps65224_buck_volt2val 
function
+* described above.
+* This maps the VSET value to micro volts. Please refer to the ranges
+* mentioned the comments of tps65224_buck_volt2val.
+*/
+
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+   return 120 + (val - 0x1B) * 5;
+   else if (val >= 0x00)
+   return 50 + (val - 0x00) * 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0xAB)
+   return 166 + (val - 0xAB) * 2;
+   else if (val >= 0x73)
+   return 110 + (val - 0x73) * 1;
+   else if (val >= 0xF)
+   return 60 + (val - 0xF) * 5000;
+   else if (val >= 0xA)
+   return 50 + (val - 0xA) * 2;
+   else
+   return -EINVAL;
+}
+
+int tps65224_lookup_slew(int id)
+{
+   switch (id) {
+  

[PATCH v4 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-04-22 Thread Bhargav Raviprakash
Use function callbacks for volt2val, val2volt and slewrate lookups.
This makes it easier to add support for TPS65224 PMIC regulators.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Jaehoon Chung 
---
 drivers/power/regulator/tps65941_regulator.c | 61 +++-
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cf54e30df5..d879c2301b 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -35,6 +35,17 @@
 #define TPS65941_LDO_ID_3 3
 #define TPS65941_LDO_ID_4 4
 
+#define TPS65941_BUCK_CONV_OPS_IDX  0
+#define TPS65941_LDO_CONV_OPS_IDX   0
+
+struct tps65941_reg_conv_ops {
+   int volt_mask;
+   int (*volt2val)(int idx, int uV);
+   int (*val2volt)(int idx, int volt);
+   int slew_mask;
+   int (*lookup_slew)(int id);
+};
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int op, 
bool *enable)
return 0;
 }
 
-static int tps65941_buck_volt2val(int uV)
+static int tps65941_buck_volt2val(__maybe_unused int idx, int uV)
 {
if (uV > TPS65941_BUCK_VOLT_MAX)
return -EINVAL;
@@ -95,7 +106,7 @@ static int tps65941_buck_volt2val(int uV)
return -EINVAL;
 }
 
-static int tps65941_buck_val2volt(int val)
+static int tps65941_buck_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_BUCK_VOLT_MAX_HEX)
return -EINVAL;
@@ -135,12 +146,25 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
+   [TPS65941_BUCK_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_BUCK_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_buck_val2volt,
+   .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
+   .lookup_slew = tps65941_lookup_slew,
+   },
+};
+
 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret, delta, uwait, slew;
+   int ret, delta, uwait, slew, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -152,8 +176,8 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_BUCK_VOLT_MASK;
-   ret = tps65941_buck_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret = conv_ops->val2volt(idx, ret);
if (ret < 0)
return ret;
 
@@ -175,14 +199,14 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (slew < 0)
return ret;
 
-   slew &= TP65941_BUCK_CONF_SLEW_MASK;
-   slew = tps65941_lookup_slew(slew);
+   slew &= conv_ops->slew_mask;
+   slew = conv_ops->lookup_slew(slew);
if (slew <= 0)
return ret;
 
uwait = delta / slew;
 
-   hex = tps65941_buck_volt2val(*uV);
+   hex = conv_ops->volt2val(idx, *uV);
if (hex < 0)
return hex;
 
@@ -231,7 +255,7 @@ 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_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
return -EINVAL;
@@ -241,12 +265,23 @@ static int tps65941_ldo_val2volt(int val)
return -EINVAL;
 }
 
+static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
+   [TPS65941_LDO_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_LDO_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_ldo_val2volt,
+   },
+};
+
 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret;
+   int ret, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_LDO_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -258,8 +293,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_LDO_VOLT_MASK;
-   ret = tps65941_ldo_val2volt(ret

[PATCH v4 3/5] power: regulator: tps65941: Added macros for BUCK ID

2024-04-22 Thread Bhargav Raviprakash
Adds macros for buck and ldo ids and switched to using switch
case instead of if else in probe functions. Helps in adding
support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
Reviewed-by: Jaehoon Chung 
---
 drivers/power/regulator/tps65941_regulator.c | 54 +++-
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index b041126775..cf54e30df5 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -16,6 +16,25 @@
 #include 
 #include 
 
+/* Single Phase Buck IDs */
+#define TPS65941_BUCK_ID_11
+#define TPS65941_BUCK_ID_22
+#define TPS65941_BUCK_ID_33
+#define TPS65941_BUCK_ID_44
+#define TPS65941_BUCK_ID_55
+
+/* Multi Phase Buck IDs */
+#define TPS65941_BUCK_ID_12  12
+#define TPS65941_BUCK_ID_34  34
+#define TPS65941_BUCK_ID_123123
+#define TPS65941_BUCK_ID_1234  1234
+
+/* LDO IDs */
+#define TPS65941_LDO_ID_1 1
+#define TPS65941_LDO_ID_2 2
+#define TPS65941_LDO_ID_3 3
+#define TPS65941_LDO_ID_4 4
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -270,10 +289,15 @@ static int tps65941_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
+   switch (idx) {
+   case TPS65941_LDO_ID_1:
+   case TPS65941_LDO_ID_2:
+   case TPS65941_LDO_ID_3:
+   case TPS65941_LDO_ID_4:
debug("Single phase regulator\n");
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
@@ -292,18 +316,24 @@ static int tps65941_buck_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_BUCK;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
+   switch (idx) {
+   case TPS65941_BUCK_ID_1:
+   case TPS65941_BUCK_ID_2:
+   case TPS65941_BUCK_ID_3:
+   case TPS65941_BUCK_ID_4:
+   case TPS65941_BUCK_ID_5:
debug("Single phase regulator\n");
-   } else if (idx == 12) {
+   break;
+   case TPS65941_BUCK_ID_12:
+   case TPS65941_BUCK_ID_123:
+   case TPS65941_BUCK_ID_1234:
idx = 1;
-   } else if (idx == 34) {
+   break;
+   case TPS65941_BUCK_ID_34:
idx = 3;
-   } else if (idx == 123) {
-   idx = 1;
-   } else if (idx == 1234) {
-   idx = 1;
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
-- 
2.25.1



[PATCH v4 2/5] power: pmic: tps65941: Add TI TPS65224 PMIC

2024-04-22 Thread Bhargav Raviprakash
Adds compatible and data field values of TPS65224 driver in
TPS65941 PMIC driver.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
Reviewed-by: Jaehoon Chung 
---
 drivers/power/pmic/tps65941.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index 727b42747a..ef63eb733a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -75,6 +75,7 @@ static const struct udevice_id tps65941_ids[] = {
{ .compatible = "ti,tps659412", .data = TPS659411 },
{ .compatible = "ti,tps659413", .data = TPS659413 },
{ .compatible = "ti,lp876441",  .data =  LP876441 },
+   { .compatible = "ti,tps65224",  .data =  TPS65224 },
{ }
 };
 
-- 
2.25.1



[PATCH v4 1/5] power: tps65941: Add macros of TPS65224 PMIC

2024-04-22 Thread Bhargav Raviprakash
Re-use the TPS65941 PMIC driver for TPS65224 PMIC.
Add additional macros of TPS65224 to aid in the driver
re-use.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
Reviewed-by: Jaehoon Chung 
---
 include/power/tps65941.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/power/tps65941.h b/include/power/tps65941.h
index a2bc6814ba..cec85333f0 100644
--- a/include/power/tps65941.h
+++ b/include/power/tps65941.h
@@ -3,11 +3,14 @@
 #define TPS659413  0x2
 #define TPS659414  0x3
 #define  LP876441  0x4
+#define  TPS65224  0x5
 
 /* I2C device address for pmic tps65941 */
 #define TPS65941_I2C_ADDR  (0x12 >> 1)
 #define TPS65941_LDO_NUM   4
 #define TPS65941_BUCK_NUM  5
+#define TPS65224_LDO_NUM   3
+#define TPS65224_BUCK_NUM  4
 
 /* Drivers name */
 #define TPS65941_LDO_DRIVER"tps65941_ldo"
@@ -25,3 +28,30 @@
 #define TPS65941_LDO_MODE_MASK 0x1
 #define TPS65941_LDO_BYPASS_EN 0x80
 #define TP65941_BUCK_CONF_SLEW_MASK0x7
+
+#define TPS65224_BUCK_VOLT_MAX 330
+#define TPS65224_BUCK1_VOLT_MAX_HEX  0xFD
+#define TPS65224_BUCK234_VOLT_MAX_HEX0x45
+
+#define TPS65224_BUCK_CONF_SLEW_MASK 0x3
+#define TPS65224_LDO_VOLT_MASK(0x3F << 1)
+
+#define TPS65224_LDO1_VOLT_MIN_HEX   0x0C
+#define TPS65224_LDO23_VOLT_MIN_HEX  0x00
+#define TPS65224_LDO1_VOLT_MAX_HEX   0x36
+#define TPS65224_LDO23_VOLT_MAX_HEX  0x38
+
+#define TPS65224_LDO1_VOLT_MAX330
+#define TPS65224_LDO23_VOLT_MAX   340
+#define TPS65224_LDO1_VOLT_MIN120
+#define TPS65224_LDO23_VOLT_MIN60
+
+#define TPS65224_LDO_STEP   5
+
+#define TPS65224_LDO_BYP_CONFIG 7
+
+#define TPS65224_LDO1_VOLT_BYP_MIN220
+#define TPS65224_LDO1_VOLT_BYP_MAX360
+
+#define TPS65224_LDO23_VOLT_BYP_MIN   150
+#define TPS65224_LDO23_VOLT_BYP_MAX   550
-- 
2.25.1



[PATCH v4 0/5] Add support for TI TPS65224 PMIC

2024-04-22 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
in U-boot. This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62P EVM using U-boot's
pmic list, regulator list, regulator status and regulator value commands.
Since, support for Ti's AM62P is absent in u-boot next, the patches
were applied on ti-u-boot ti-u-boot-2023.04-next and tested.

Changelog v3 -> v4:
- refactoring ldo probe function: removed a redundant branch

Bhargav Raviprakash (5):
  power: tps65941: Add macros of TPS65224 PMIC
  power: pmic: tps65941: Add TI TPS65224 PMIC
  power: regulator: tps65941: Added macros for BUCK ID
  power: regulator: tps65941: use function callbacks for conversion ops
  power: regulator: tps65941: Add TPS65224 PMIC regulator support

 drivers/power/pmic/tps65941.c|   1 +
 drivers/power/regulator/tps65941_regulator.c | 381 +--
 include/power/tps65941.h |  30 ++
 3 files changed, 381 insertions(+), 31 deletions(-)

-- 
2.25.1



Re: [RESEND PATCH v3 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-04-22 Thread Bhargav Raviprakash
On Thu, 18 Apr 2024 09:33:30 +0900, Jaehoon Chung wrote:
> On 3/18/24 18:49, Bhargav Raviprakash wrote:
> > Reuse TPS65941 regulator driver to adds support for
> > TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
> > BUCK1 and BUCK2 can be configured in dual phase mode.
> > 
> > Signed-off-by: Bhargav Raviprakash 
> > ---
> >  drivers/power/regulator/tps65941_regulator.c | 283 ++-
> >  1 file changed, 270 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/power/regulator/tps65941_regulator.c 
> > b/drivers/power/regulator/tps65941_regulator.c
> > index d879c2301b..b1b9462fd3 100644
> > --- a/drivers/power/regulator/tps65941_regulator.c
> > +++ b/drivers/power/regulator/tps65941_regulator.c
> > @@ -37,6 +37,8 @@
> >  
> >  #define TPS65941_BUCK_CONV_OPS_IDX  0
> >  #define TPS65941_LDO_CONV_OPS_IDX   0
> > +#define TPS65224_LDO_CONV_OPS_IDX   1
> > +#define TPS65224_BUCK_CONV_OPS_IDX  1
> >  
> >  struct tps65941_reg_conv_ops {
> > int volt_mask;
> > @@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
> > {0x1D, 0x1E, 0x1F,
> >  static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
> > 0x26};
> >  
> > +static inline int tps65941_get_chip_id(struct udevice *dev)
> > +{
> > +   return dev->parent->driver_data;
> > +}
> > +
> >  static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
> >  {
> > int ret;
> > @@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
> > }
> >  }
> >  
> > +static int tps65224_buck_volt2val(int idx, int uV)
> > +{
> > +   /* This functions maps a value which is in micro Volts to the VSET 
> > value.
> > +* The mapping is as per the datasheet of TPS65224.
> > +*/
> > +
> > +   if (uV > TPS65224_BUCK_VOLT_MAX)
> > +   return -EINVAL;
> > +
> > +   if (idx > 0) {
> > +   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
> > +* converting b/w micro_volt and VSET hex values
> > +*
> > +* VSET value starts from 0x00 for 0.5V, and for every increment
> > +* in VSET value the output voltage increases by 25mV. This is 
> > upto
> > +* 1.15V where VSET is 0x1A.
> > +*
> > +* For 0x1B the output voltage is 1.2V, and for every increment 
> > of
> > +* VSET the output voltage increases by 50mV upto the max 
> > voltage of
> > +* 3.3V
> > +*
> > +* | Voltage Ranges  | VSET Ranges  | Voltage Step |
> > +* +-+--+--+
> > +* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
> > +* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
> > +*/
> > +   if (uV >= 120)
> > +   return (uV - 120) / 5 + 0x1B;
> > +   else if (uV >= 50)
> > +   return (uV - 50) / 25000;
> > +   else
> > +   return -EINVAL;
> > +   }
> > +
> > +   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
> > +* voltage and VSET value.
> > +*
> > +* | Voltage Ranges  | VSET Ranges  | Voltage Step |
> > +* +-+--+--+
> > +* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
> > +* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
> > +* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
> > +* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
> > +*
> > +*/
> > +   if (uV >= 166)
> > +   return (uV - 166) / 2 + 0xAB;
> > +   else if (uV >= 110)
> > +   return (uV - 110) / 1 + 0x73;
> > +   else if (uV >= 60)
> > +   return (uV - 60) / 5000 + 0x0F;
> > +   else if (uV >= 50)
> > +   return (uV - 50) / 2 + 0x0A;
> > +   else
> > +   return -EINVAL;
> > +}
> > +
> > +static int tps65224_buck_val2volt(int idx, int val)
> > +{
> > +   /* This function does the opposite to the tps65224_buck_volt2val 
> > function
> > +* described above.
> > +* This maps the VSET value to micro volts. Please refer to the ranges
> > +* mentioned the comments of tps65224_buck_volt2val.
> > +

[RESEND PATCH v3 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-03-18 Thread Bhargav Raviprakash
Use function callbacks for volt2val, val2volt and slewrate lookups.
This makes it easier to add support for TPS65224 PMIC regulators.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 61 +++-
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cf54e30df5..d879c2301b 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -35,6 +35,17 @@
 #define TPS65941_LDO_ID_3 3
 #define TPS65941_LDO_ID_4 4
 
+#define TPS65941_BUCK_CONV_OPS_IDX  0
+#define TPS65941_LDO_CONV_OPS_IDX   0
+
+struct tps65941_reg_conv_ops {
+   int volt_mask;
+   int (*volt2val)(int idx, int uV);
+   int (*val2volt)(int idx, int volt);
+   int slew_mask;
+   int (*lookup_slew)(int id);
+};
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int op, 
bool *enable)
return 0;
 }
 
-static int tps65941_buck_volt2val(int uV)
+static int tps65941_buck_volt2val(__maybe_unused int idx, int uV)
 {
if (uV > TPS65941_BUCK_VOLT_MAX)
return -EINVAL;
@@ -95,7 +106,7 @@ static int tps65941_buck_volt2val(int uV)
return -EINVAL;
 }
 
-static int tps65941_buck_val2volt(int val)
+static int tps65941_buck_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_BUCK_VOLT_MAX_HEX)
return -EINVAL;
@@ -135,12 +146,25 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
+   [TPS65941_BUCK_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_BUCK_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_buck_val2volt,
+   .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
+   .lookup_slew = tps65941_lookup_slew,
+   },
+};
+
 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret, delta, uwait, slew;
+   int ret, delta, uwait, slew, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -152,8 +176,8 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_BUCK_VOLT_MASK;
-   ret = tps65941_buck_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret = conv_ops->val2volt(idx, ret);
if (ret < 0)
return ret;
 
@@ -175,14 +199,14 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (slew < 0)
return ret;
 
-   slew &= TP65941_BUCK_CONF_SLEW_MASK;
-   slew = tps65941_lookup_slew(slew);
+   slew &= conv_ops->slew_mask;
+   slew = conv_ops->lookup_slew(slew);
if (slew <= 0)
return ret;
 
uwait = delta / slew;
 
-   hex = tps65941_buck_volt2val(*uV);
+   hex = conv_ops->volt2val(idx, *uV);
if (hex < 0)
return hex;
 
@@ -231,7 +255,7 @@ 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_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
return -EINVAL;
@@ -241,12 +265,23 @@ static int tps65941_ldo_val2volt(int val)
return -EINVAL;
 }
 
+static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
+   [TPS65941_LDO_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_LDO_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_ldo_val2volt,
+   },
+};
+
 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret;
+   int ret, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_LDO_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -258,8 +293,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_LDO_VOLT_MASK;
-   ret = tps65941_ldo_val2volt(ret);
+   ret &= conv_

[RESEND PATCH v3 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-03-18 Thread Bhargav Raviprakash
Reuse TPS65941 regulator driver to adds support for
TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
BUCK1 and BUCK2 can be configured in dual phase mode.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 283 ++-
 1 file changed, 270 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index d879c2301b..b1b9462fd3 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -37,6 +37,8 @@
 
 #define TPS65941_BUCK_CONV_OPS_IDX  0
 #define TPS65941_LDO_CONV_OPS_IDX   0
+#define TPS65224_LDO_CONV_OPS_IDX   1
+#define TPS65224_BUCK_CONV_OPS_IDX  1
 
 struct tps65941_reg_conv_ops {
int volt_mask;
@@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
{0x1D, 0x1E, 0x1F,
 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
0x26};
 
+static inline int tps65941_get_chip_id(struct udevice *dev)
+{
+   return dev->parent->driver_data;
+}
+
 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
 {
int ret;
@@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   /* This functions maps a value which is in micro Volts to the VSET 
value.
+* The mapping is as per the datasheet of TPS65224.
+*/
+
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
+* converting b/w micro_volt and VSET hex values
+*
+* VSET value starts from 0x00 for 0.5V, and for every increment
+* in VSET value the output voltage increases by 25mV. This is 
upto
+* 1.15V where VSET is 0x1A.
+*
+* For 0x1B the output voltage is 1.2V, and for every increment 
of
+* VSET the output voltage increases by 50mV upto the max 
voltage of
+* 3.3V
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
+* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
+*/
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
+* voltage and VSET value.
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
+* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
+* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
+* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
+*
+*/
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   /* This function does the opposite to the tps65224_buck_volt2val 
function
+* described above.
+* This maps the VSET value to micro volts. Please refer to the ranges
+* mentioned the comments of tps65224_buck_volt2val.
+*/
+
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+   return 120 + (val - 0x1B) * 5;
+   else if (val >= 0x00)
+   return 50 + (val - 0x00) * 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0xAB)
+   return 166 + (val - 0xAB) * 2;
+   else if (val >= 0x73)
+   return 110 + (val - 0x73) * 1;
+   else if (val >= 0xF)
+   return 60 + (val - 0xF) * 5000;
+   else if (val >= 0xA)
+   return 50 + (val - 0xA) * 2;
+   else
+   return -EINVAL;
+}
+
+int tps65224_lookup_slew(int id)
+{
+   switch (id) {
+  

[RESEND PATCH v3 3/5] power: regulator: tps65941: Added macros for BUCK ID

2024-03-18 Thread Bhargav Raviprakash
Adds macros for buck and ldo ids and switched to using switch
case instead of if else in probe functions. Helps in adding
support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
---
 drivers/power/regulator/tps65941_regulator.c | 54 +++-
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index b041126775..cf54e30df5 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -16,6 +16,25 @@
 #include 
 #include 
 
+/* Single Phase Buck IDs */
+#define TPS65941_BUCK_ID_11
+#define TPS65941_BUCK_ID_22
+#define TPS65941_BUCK_ID_33
+#define TPS65941_BUCK_ID_44
+#define TPS65941_BUCK_ID_55
+
+/* Multi Phase Buck IDs */
+#define TPS65941_BUCK_ID_12  12
+#define TPS65941_BUCK_ID_34  34
+#define TPS65941_BUCK_ID_123123
+#define TPS65941_BUCK_ID_1234  1234
+
+/* LDO IDs */
+#define TPS65941_LDO_ID_1 1
+#define TPS65941_LDO_ID_2 2
+#define TPS65941_LDO_ID_3 3
+#define TPS65941_LDO_ID_4 4
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -270,10 +289,15 @@ static int tps65941_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
+   switch (idx) {
+   case TPS65941_LDO_ID_1:
+   case TPS65941_LDO_ID_2:
+   case TPS65941_LDO_ID_3:
+   case TPS65941_LDO_ID_4:
debug("Single phase regulator\n");
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
@@ -292,18 +316,24 @@ static int tps65941_buck_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_BUCK;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
+   switch (idx) {
+   case TPS65941_BUCK_ID_1:
+   case TPS65941_BUCK_ID_2:
+   case TPS65941_BUCK_ID_3:
+   case TPS65941_BUCK_ID_4:
+   case TPS65941_BUCK_ID_5:
debug("Single phase regulator\n");
-   } else if (idx == 12) {
+   break;
+   case TPS65941_BUCK_ID_12:
+   case TPS65941_BUCK_ID_123:
+   case TPS65941_BUCK_ID_1234:
idx = 1;
-   } else if (idx == 34) {
+   break;
+   case TPS65941_BUCK_ID_34:
idx = 3;
-   } else if (idx == 123) {
-   idx = 1;
-   } else if (idx == 1234) {
-   idx = 1;
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
-- 
2.25.1



[RESEND PATCH v3 2/5] power: pmic: tps65941: Add TI TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
Adds compatible and data field values of TPS65224 driver in
TPS65941 PMIC driver.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
---
 drivers/power/pmic/tps65941.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index 727b42747a..ef63eb733a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -75,6 +75,7 @@ static const struct udevice_id tps65941_ids[] = {
{ .compatible = "ti,tps659412", .data = TPS659411 },
{ .compatible = "ti,tps659413", .data = TPS659413 },
{ .compatible = "ti,lp876441",  .data =  LP876441 },
+   { .compatible = "ti,tps65224",  .data =  TPS65224 },
{ }
 };
 
-- 
2.25.1



[RESEND PATCH v3 1/5] power: tps65941: Add macros of TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
Re-use the TPS65941 PMIC driver for TPS65224 PMIC.
Add additional macros of TPS65224 to aid in the driver
re-use.

Signed-off-by: Bhargav Raviprakash 
Reviewed-by: Dhruva Gole 
---
 include/power/tps65941.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/power/tps65941.h b/include/power/tps65941.h
index a2bc6814ba..cec85333f0 100644
--- a/include/power/tps65941.h
+++ b/include/power/tps65941.h
@@ -3,11 +3,14 @@
 #define TPS659413  0x2
 #define TPS659414  0x3
 #define  LP876441  0x4
+#define  TPS65224  0x5
 
 /* I2C device address for pmic tps65941 */
 #define TPS65941_I2C_ADDR  (0x12 >> 1)
 #define TPS65941_LDO_NUM   4
 #define TPS65941_BUCK_NUM  5
+#define TPS65224_LDO_NUM   3
+#define TPS65224_BUCK_NUM  4
 
 /* Drivers name */
 #define TPS65941_LDO_DRIVER"tps65941_ldo"
@@ -25,3 +28,30 @@
 #define TPS65941_LDO_MODE_MASK 0x1
 #define TPS65941_LDO_BYPASS_EN 0x80
 #define TP65941_BUCK_CONF_SLEW_MASK0x7
+
+#define TPS65224_BUCK_VOLT_MAX 330
+#define TPS65224_BUCK1_VOLT_MAX_HEX  0xFD
+#define TPS65224_BUCK234_VOLT_MAX_HEX0x45
+
+#define TPS65224_BUCK_CONF_SLEW_MASK 0x3
+#define TPS65224_LDO_VOLT_MASK(0x3F << 1)
+
+#define TPS65224_LDO1_VOLT_MIN_HEX   0x0C
+#define TPS65224_LDO23_VOLT_MIN_HEX  0x00
+#define TPS65224_LDO1_VOLT_MAX_HEX   0x36
+#define TPS65224_LDO23_VOLT_MAX_HEX  0x38
+
+#define TPS65224_LDO1_VOLT_MAX330
+#define TPS65224_LDO23_VOLT_MAX   340
+#define TPS65224_LDO1_VOLT_MIN120
+#define TPS65224_LDO23_VOLT_MIN60
+
+#define TPS65224_LDO_STEP   5
+
+#define TPS65224_LDO_BYP_CONFIG 7
+
+#define TPS65224_LDO1_VOLT_BYP_MIN220
+#define TPS65224_LDO1_VOLT_BYP_MAX360
+
+#define TPS65224_LDO23_VOLT_BYP_MIN   150
+#define TPS65224_LDO23_VOLT_BYP_MAX   550
-- 
2.25.1



[RESEND PATCH v3 0/5] Add support for TI TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
in U-boot. This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62P EVM using U-boot's
pmic list, regulator list, regulator status and regulator value commands.
Since, support for Ti's AM62P is absent in u-boot next, the patches
were applied on ti-u-boot ti-u-boot-2023.04-next and tested.

Changelog v2 -> v3:
- use pr_err instead of printf
- comments added in ldo conversion functions

Bhargav Raviprakash (5):
  power: tps65941: Add macros of TPS65224 PMIC
  power: pmic: tps65941: Add TI TPS65224 PMIC
  power: regulator: tps65941: Added macros for BUCK ID
  power: regulator: tps65941: use function callbacks for conversion ops
  power: regulator: tps65941: Add TPS65224 PMIC regulator support

 drivers/power/pmic/tps65941.c|   1 +
 drivers/power/regulator/tps65941_regulator.c | 384 +--
 include/power/tps65941.h |  30 ++
 3 files changed, 384 insertions(+), 31 deletions(-)


base-commit: 4b151562bb8e54160adedbc6a1c0c749c00a2f84
-- 
2.25.1



Re: Add support for TI TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
Hello,

On Mon, 18 Mar 2024 14:59:54 +0530, Bhargav wrote:
> 
> TPS65224 is a Power Management IC which provides regulators and others
> features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
> and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
> can communicate through the I2C.
> 
> Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1
> 
> Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
> in U-boot. This includes driver for PMIC and regulator.
> 
> The driver was tested on Ti's custom AM62P EVM using U-boot's
> pmic list, regulator list, regulator status and regulator value commands.
> Since, support for Ti's AM62P is absent in u-boot next, the patches
> were applied on ti-u-boot ti-u-boot-2023.04-next and tested.
> 
> Changelog v2 -> v3:
> - use pr_err instead of printf
> - comments added in ldo conversion functions
> 

Please ignore this patch set.

I sent old patches again by mistake.
I will be re-sending the v3 patch with updated changes.

Regards,
Bhargav


[PATCH v3 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-03-18 Thread Bhargav Raviprakash
Reuse TPS65941 regulator driver to adds support for
TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
BUCK1 and BUCK2 can be configured in dual phase mode.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 280 ++-
 1 file changed, 267 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index d879c2301b..826bc0c63e 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -37,6 +37,8 @@
 
 #define TPS65941_BUCK_CONV_OPS_IDX  0
 #define TPS65941_LDO_CONV_OPS_IDX   0
+#define TPS65224_LDO_CONV_OPS_IDX   1
+#define TPS65224_BUCK_CONV_OPS_IDX  1
 
 struct tps65941_reg_conv_ops {
int volt_mask;
@@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
{0x1D, 0x1E, 0x1F,
 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
0x26};
 
+static inline int tps65941_get_chip_id(struct udevice *dev)
+{
+   return dev->parent->driver_data;
+}
+
 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
 {
int ret;
@@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   /* This functions maps a value which is in micro Volts to the VSET 
value.
+* The mapping is as per the datasheet of TPS65224.
+*/
+
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
+* converting b/w micro_volt and VSET hex values
+*
+* VSET value starts from 0x00 for 0.5V, and for every increment
+* in VSET value the output voltage increases by 25mV. This is 
upto
+* 1.15V where VSET is 0x1A.
+*
+* For 0x1B the output voltage is 1.2V, and for every increment 
of
+* VSET the output voltage increases by 50mV upto the max 
voltage of
+* 3.3V
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
+* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
+*/
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
+* voltage and VSET value.
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
+* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
+* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
+* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
+*
+*/
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   /* This function does the opposite to the tps65224_buck_volt2val 
function
+* described above.
+* This maps the VSET value to micro volts. Please refer to the ranges
+* mentioned the comments of tps65224_buck_volt2val.
+*/
+
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+   return 120 + (val - 0x1B) * 5;
+   else if (val >= 0x00)
+   return 50 + (val - 0x00) * 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0xAB)
+   return 166 + (val - 0xAB) * 2;
+   else if (val >= 0x73)
+   return 110 + (val - 0x73) * 1;
+   else if (val >= 0xF)
+   return 60 + (val - 0xF) * 5000;
+   else if (val >= 0xA)
+   return 50 + (val - 0xA) * 2;
+   else
+   return -EINVAL;
+}
+
+int tps65224_lookup_slew(int id)
+{
+   switch (id) {
+  

[PATCH v3 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-03-18 Thread Bhargav Raviprakash
Use function callbacks for volt2val, val2volt and slewrate lookups.
This makes it easier to add support for TPS65224 PMIC regulators.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 61 +++-
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cf54e30df5..d879c2301b 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -35,6 +35,17 @@
 #define TPS65941_LDO_ID_3 3
 #define TPS65941_LDO_ID_4 4
 
+#define TPS65941_BUCK_CONV_OPS_IDX  0
+#define TPS65941_LDO_CONV_OPS_IDX   0
+
+struct tps65941_reg_conv_ops {
+   int volt_mask;
+   int (*volt2val)(int idx, int uV);
+   int (*val2volt)(int idx, int volt);
+   int slew_mask;
+   int (*lookup_slew)(int id);
+};
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int op, 
bool *enable)
return 0;
 }
 
-static int tps65941_buck_volt2val(int uV)
+static int tps65941_buck_volt2val(__maybe_unused int idx, int uV)
 {
if (uV > TPS65941_BUCK_VOLT_MAX)
return -EINVAL;
@@ -95,7 +106,7 @@ static int tps65941_buck_volt2val(int uV)
return -EINVAL;
 }
 
-static int tps65941_buck_val2volt(int val)
+static int tps65941_buck_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_BUCK_VOLT_MAX_HEX)
return -EINVAL;
@@ -135,12 +146,25 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
+   [TPS65941_BUCK_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_BUCK_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_buck_val2volt,
+   .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
+   .lookup_slew = tps65941_lookup_slew,
+   },
+};
+
 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret, delta, uwait, slew;
+   int ret, delta, uwait, slew, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -152,8 +176,8 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_BUCK_VOLT_MASK;
-   ret = tps65941_buck_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret = conv_ops->val2volt(idx, ret);
if (ret < 0)
return ret;
 
@@ -175,14 +199,14 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (slew < 0)
return ret;
 
-   slew &= TP65941_BUCK_CONF_SLEW_MASK;
-   slew = tps65941_lookup_slew(slew);
+   slew &= conv_ops->slew_mask;
+   slew = conv_ops->lookup_slew(slew);
if (slew <= 0)
return ret;
 
uwait = delta / slew;
 
-   hex = tps65941_buck_volt2val(*uV);
+   hex = conv_ops->volt2val(idx, *uV);
if (hex < 0)
return hex;
 
@@ -231,7 +255,7 @@ 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_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
return -EINVAL;
@@ -241,12 +265,23 @@ static int tps65941_ldo_val2volt(int val)
return -EINVAL;
 }
 
+static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
+   [TPS65941_LDO_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_LDO_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_ldo_val2volt,
+   },
+};
+
 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret;
+   int ret, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_LDO_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -258,8 +293,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_LDO_VOLT_MASK;
-   ret = tps65941_ldo_val2volt(ret);
+   ret &= conv_

[PATCH v3 2/5] power: pmic: tps65941: Add TI TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
Adds compatible and data field values of TPS65224 driver in
TPS65941 PMIC driver.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/pmic/tps65941.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index 727b42747a..ef63eb733a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -75,6 +75,7 @@ static const struct udevice_id tps65941_ids[] = {
{ .compatible = "ti,tps659412", .data = TPS659411 },
{ .compatible = "ti,tps659413", .data = TPS659413 },
{ .compatible = "ti,lp876441",  .data =  LP876441 },
+   { .compatible = "ti,tps65224",  .data =  TPS65224 },
{ }
 };
 
-- 
2.25.1



[PATCH v3 1/5] power: tps65941: Add macros of TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
Re-use the TPS65941 PMIC driver for TPS65224 PMIC.
Add additional macros of TPS65224 to aid in the driver
re-use.

Signed-off-by: Bhargav Raviprakash 
---
 include/power/tps65941.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/power/tps65941.h b/include/power/tps65941.h
index a2bc6814ba..cec85333f0 100644
--- a/include/power/tps65941.h
+++ b/include/power/tps65941.h
@@ -3,11 +3,14 @@
 #define TPS659413  0x2
 #define TPS659414  0x3
 #define  LP876441  0x4
+#define  TPS65224  0x5
 
 /* I2C device address for pmic tps65941 */
 #define TPS65941_I2C_ADDR  (0x12 >> 1)
 #define TPS65941_LDO_NUM   4
 #define TPS65941_BUCK_NUM  5
+#define TPS65224_LDO_NUM   3
+#define TPS65224_BUCK_NUM  4
 
 /* Drivers name */
 #define TPS65941_LDO_DRIVER"tps65941_ldo"
@@ -25,3 +28,30 @@
 #define TPS65941_LDO_MODE_MASK 0x1
 #define TPS65941_LDO_BYPASS_EN 0x80
 #define TP65941_BUCK_CONF_SLEW_MASK0x7
+
+#define TPS65224_BUCK_VOLT_MAX 330
+#define TPS65224_BUCK1_VOLT_MAX_HEX  0xFD
+#define TPS65224_BUCK234_VOLT_MAX_HEX0x45
+
+#define TPS65224_BUCK_CONF_SLEW_MASK 0x3
+#define TPS65224_LDO_VOLT_MASK(0x3F << 1)
+
+#define TPS65224_LDO1_VOLT_MIN_HEX   0x0C
+#define TPS65224_LDO23_VOLT_MIN_HEX  0x00
+#define TPS65224_LDO1_VOLT_MAX_HEX   0x36
+#define TPS65224_LDO23_VOLT_MAX_HEX  0x38
+
+#define TPS65224_LDO1_VOLT_MAX330
+#define TPS65224_LDO23_VOLT_MAX   340
+#define TPS65224_LDO1_VOLT_MIN120
+#define TPS65224_LDO23_VOLT_MIN60
+
+#define TPS65224_LDO_STEP   5
+
+#define TPS65224_LDO_BYP_CONFIG 7
+
+#define TPS65224_LDO1_VOLT_BYP_MIN220
+#define TPS65224_LDO1_VOLT_BYP_MAX360
+
+#define TPS65224_LDO23_VOLT_BYP_MIN   150
+#define TPS65224_LDO23_VOLT_BYP_MAX   550
-- 
2.25.1



[PATCH v3 3/5] power: regulator: tps65941: Added macros for BUCK ID

2024-03-18 Thread Bhargav Raviprakash
Adds macros for buck and ldo ids and switched to using switch
case instead of if else in probe functions. Helps in adding
support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 54 +++-
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index b041126775..cf54e30df5 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -16,6 +16,25 @@
 #include 
 #include 
 
+/* Single Phase Buck IDs */
+#define TPS65941_BUCK_ID_11
+#define TPS65941_BUCK_ID_22
+#define TPS65941_BUCK_ID_33
+#define TPS65941_BUCK_ID_44
+#define TPS65941_BUCK_ID_55
+
+/* Multi Phase Buck IDs */
+#define TPS65941_BUCK_ID_12  12
+#define TPS65941_BUCK_ID_34  34
+#define TPS65941_BUCK_ID_123123
+#define TPS65941_BUCK_ID_1234  1234
+
+/* LDO IDs */
+#define TPS65941_LDO_ID_1 1
+#define TPS65941_LDO_ID_2 2
+#define TPS65941_LDO_ID_3 3
+#define TPS65941_LDO_ID_4 4
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -270,10 +289,15 @@ static int tps65941_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
+   switch (idx) {
+   case TPS65941_LDO_ID_1:
+   case TPS65941_LDO_ID_2:
+   case TPS65941_LDO_ID_3:
+   case TPS65941_LDO_ID_4:
debug("Single phase regulator\n");
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
@@ -292,18 +316,24 @@ static int tps65941_buck_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_BUCK;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
+   switch (idx) {
+   case TPS65941_BUCK_ID_1:
+   case TPS65941_BUCK_ID_2:
+   case TPS65941_BUCK_ID_3:
+   case TPS65941_BUCK_ID_4:
+   case TPS65941_BUCK_ID_5:
debug("Single phase regulator\n");
-   } else if (idx == 12) {
+   break;
+   case TPS65941_BUCK_ID_12:
+   case TPS65941_BUCK_ID_123:
+   case TPS65941_BUCK_ID_1234:
idx = 1;
-   } else if (idx == 34) {
+   break;
+   case TPS65941_BUCK_ID_34:
idx = 3;
-   } else if (idx == 123) {
-   idx = 1;
-   } else if (idx == 1234) {
-   idx = 1;
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
-- 
2.25.1



[PATCH v3 0/5] Add support for TI TPS65224 PMIC

2024-03-18 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
in U-boot. This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62P EVM using U-boot's
pmic list, regulator list, regulator status and regulator value commands.
Since, support for Ti's AM62P is absent in u-boot next, the patches
were applied on ti-u-boot ti-u-boot-2023.04-next and tested.

Changelog v2 -> v3:
- use pr_err instead of printf
- comments added in ldo conversion functions

Bhargav Raviprakash (5):
  power: tps65941: Add macros of TPS65224 PMIC
  power: pmic: tps65941: Add TI TPS65224 PMIC
  power: regulator: tps65941: Added macros for BUCK ID
  power: regulator: tps65941: use function callbacks for conversion ops
  power: regulator: tps65941: Add TPS65224 PMIC regulator support

 drivers/power/pmic/tps65941.c|   1 +
 drivers/power/regulator/tps65941_regulator.c | 381 +--
 include/power/tps65941.h |  30 ++
 3 files changed, 381 insertions(+), 31 deletions(-)


base-commit: 4b151562bb8e54160adedbc6a1c0c749c00a2f84
-- 
2.25.1



[PATCH v2 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-03-06 Thread Bhargav Raviprakash
Use function callbacks for volt2val, val2volt and slewrate lookups.
This makes it easier to add support for TPS65224 PMIC regulators.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 61 +++-
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cf54e30df5..d879c2301b 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -35,6 +35,17 @@
 #define TPS65941_LDO_ID_3 3
 #define TPS65941_LDO_ID_4 4
 
+#define TPS65941_BUCK_CONV_OPS_IDX  0
+#define TPS65941_LDO_CONV_OPS_IDX   0
+
+struct tps65941_reg_conv_ops {
+   int volt_mask;
+   int (*volt2val)(int idx, int uV);
+   int (*val2volt)(int idx, int volt);
+   int slew_mask;
+   int (*lookup_slew)(int id);
+};
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int op, 
bool *enable)
return 0;
 }
 
-static int tps65941_buck_volt2val(int uV)
+static int tps65941_buck_volt2val(__maybe_unused int idx, int uV)
 {
if (uV > TPS65941_BUCK_VOLT_MAX)
return -EINVAL;
@@ -95,7 +106,7 @@ static int tps65941_buck_volt2val(int uV)
return -EINVAL;
 }
 
-static int tps65941_buck_val2volt(int val)
+static int tps65941_buck_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_BUCK_VOLT_MAX_HEX)
return -EINVAL;
@@ -135,12 +146,25 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
+   [TPS65941_BUCK_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_BUCK_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_buck_val2volt,
+   .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
+   .lookup_slew = tps65941_lookup_slew,
+   },
+};
+
 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret, delta, uwait, slew;
+   int ret, delta, uwait, slew, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -152,8 +176,8 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_BUCK_VOLT_MASK;
-   ret = tps65941_buck_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret = conv_ops->val2volt(idx, ret);
if (ret < 0)
return ret;
 
@@ -175,14 +199,14 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (slew < 0)
return ret;
 
-   slew &= TP65941_BUCK_CONF_SLEW_MASK;
-   slew = tps65941_lookup_slew(slew);
+   slew &= conv_ops->slew_mask;
+   slew = conv_ops->lookup_slew(slew);
if (slew <= 0)
return ret;
 
uwait = delta / slew;
 
-   hex = tps65941_buck_volt2val(*uV);
+   hex = conv_ops->volt2val(idx, *uV);
if (hex < 0)
return hex;
 
@@ -231,7 +255,7 @@ 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_val2volt(__maybe_unused int idx, int val)
 {
if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
return -EINVAL;
@@ -241,12 +265,23 @@ static int tps65941_ldo_val2volt(int val)
return -EINVAL;
 }
 
+static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
+   [TPS65941_LDO_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_LDO_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_ldo_val2volt,
+   },
+};
+
 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret;
+   int ret, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_LDO_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -258,8 +293,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_LDO_VOLT_MASK;
-   ret = tps65941_ldo_val2volt(ret);
+   ret &= conv_

[PATCH v2 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-03-06 Thread Bhargav Raviprakash
Reuse TPS65941 regulator driver to adds support for
TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
BUCK1 and BUCK2 can be configured in dual phase mode.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 280 ++-
 1 file changed, 267 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index d879c2301b..826bc0c63e 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -37,6 +37,8 @@
 
 #define TPS65941_BUCK_CONV_OPS_IDX  0
 #define TPS65941_LDO_CONV_OPS_IDX   0
+#define TPS65224_LDO_CONV_OPS_IDX   1
+#define TPS65224_BUCK_CONV_OPS_IDX  1
 
 struct tps65941_reg_conv_ops {
int volt_mask;
@@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
{0x1D, 0x1E, 0x1F,
 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
0x26};
 
+static inline int tps65941_get_chip_id(struct udevice *dev)
+{
+   return dev->parent->driver_data;
+}
+
 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
 {
int ret;
@@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   /* This functions maps a value which is in micro Volts to the VSET 
value.
+* The mapping is as per the datasheet of TPS65224.
+*/
+
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
+* converting b/w micro_volt and VSET hex values
+*
+* VSET value starts from 0x00 for 0.5V, and for every increment
+* in VSET value the output voltage increases by 25mV. This is 
upto
+* 1.15V where VSET is 0x1A.
+*
+* For 0x1B the output voltage is 1.2V, and for every increment 
of
+* VSET the output voltage increases by 50mV upto the max 
voltage of
+* 3.3V
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
+* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
+*/
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
+* voltage and VSET value.
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
+* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
+* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
+* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
+*
+*/
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   /* This function does the opposite to the tps65224_buck_volt2val 
function
+* described above.
+* This maps the VSET value to micro volts. Please refer to the ranges
+* mentioned the comments of tps65224_buck_volt2val.
+*/
+
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+   return 120 + (val - 0x1B) * 5;
+   else if (val >= 0x00)
+   return 50 + (val - 0x00) * 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0xAB)
+   return 166 + (val - 0xAB) * 2;
+   else if (val >= 0x73)
+   return 110 + (val - 0x73) * 1;
+   else if (val >= 0xF)
+   return 60 + (val - 0xF) * 5000;
+   else if (val >= 0xA)
+   return 50 + (val - 0xA) * 2;
+   else
+   return -EINVAL;
+}
+
+int tps65224_lookup_slew(int id)
+{
+   switch (id) {
+  

[PATCH v2 2/5] power: pmic: tps65941: Add TI TPS65224 PMIC

2024-03-06 Thread Bhargav Raviprakash
Adds compatible and data field values of TPS65224 driver in
TPS65941 PMIC driver.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/pmic/tps65941.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index 727b42747a..ef63eb733a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -75,6 +75,7 @@ static const struct udevice_id tps65941_ids[] = {
{ .compatible = "ti,tps659412", .data = TPS659411 },
{ .compatible = "ti,tps659413", .data = TPS659413 },
{ .compatible = "ti,lp876441",  .data =  LP876441 },
+   { .compatible = "ti,tps65224",  .data =  TPS65224 },
{ }
 };
 
-- 
2.25.1



[PATCH v2 3/5] power: regulator: tps65941: Added macros for BUCK ID

2024-03-06 Thread Bhargav Raviprakash
Adds macros for buck and ldo ids and switched to using switch
case instead of if else in probe functions. Helps in adding
support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 54 +++-
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index b041126775..cf54e30df5 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -16,6 +16,25 @@
 #include 
 #include 
 
+/* Single Phase Buck IDs */
+#define TPS65941_BUCK_ID_11
+#define TPS65941_BUCK_ID_22
+#define TPS65941_BUCK_ID_33
+#define TPS65941_BUCK_ID_44
+#define TPS65941_BUCK_ID_55
+
+/* Multi Phase Buck IDs */
+#define TPS65941_BUCK_ID_12  12
+#define TPS65941_BUCK_ID_34  34
+#define TPS65941_BUCK_ID_123123
+#define TPS65941_BUCK_ID_1234  1234
+
+/* LDO IDs */
+#define TPS65941_LDO_ID_1 1
+#define TPS65941_LDO_ID_2 2
+#define TPS65941_LDO_ID_3 3
+#define TPS65941_LDO_ID_4 4
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -270,10 +289,15 @@ static int tps65941_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
+   switch (idx) {
+   case TPS65941_LDO_ID_1:
+   case TPS65941_LDO_ID_2:
+   case TPS65941_LDO_ID_3:
+   case TPS65941_LDO_ID_4:
debug("Single phase regulator\n");
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
@@ -292,18 +316,24 @@ static int tps65941_buck_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_BUCK;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
+   switch (idx) {
+   case TPS65941_BUCK_ID_1:
+   case TPS65941_BUCK_ID_2:
+   case TPS65941_BUCK_ID_3:
+   case TPS65941_BUCK_ID_4:
+   case TPS65941_BUCK_ID_5:
debug("Single phase regulator\n");
-   } else if (idx == 12) {
+   break;
+   case TPS65941_BUCK_ID_12:
+   case TPS65941_BUCK_ID_123:
+   case TPS65941_BUCK_ID_1234:
idx = 1;
-   } else if (idx == 34) {
+   break;
+   case TPS65941_BUCK_ID_34:
idx = 3;
-   } else if (idx == 123) {
-   idx = 1;
-   } else if (idx == 1234) {
-   idx = 1;
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
-- 
2.25.1



[PATCH v2 1/5] power: tps65941: Add macros of TPS65224 PMIC

2024-03-06 Thread Bhargav Raviprakash
Re-use the TPS65941 PMIC driver for TPS65224 PMIC.
Add additional macros of TPS65224 to aid in the driver
re-use.

Signed-off-by: Bhargav Raviprakash 
---
 include/power/tps65941.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/power/tps65941.h b/include/power/tps65941.h
index a2bc6814ba..cec85333f0 100644
--- a/include/power/tps65941.h
+++ b/include/power/tps65941.h
@@ -3,11 +3,14 @@
 #define TPS659413  0x2
 #define TPS659414  0x3
 #define  LP876441  0x4
+#define  TPS65224  0x5
 
 /* I2C device address for pmic tps65941 */
 #define TPS65941_I2C_ADDR  (0x12 >> 1)
 #define TPS65941_LDO_NUM   4
 #define TPS65941_BUCK_NUM  5
+#define TPS65224_LDO_NUM   3
+#define TPS65224_BUCK_NUM  4
 
 /* Drivers name */
 #define TPS65941_LDO_DRIVER"tps65941_ldo"
@@ -25,3 +28,30 @@
 #define TPS65941_LDO_MODE_MASK 0x1
 #define TPS65941_LDO_BYPASS_EN 0x80
 #define TP65941_BUCK_CONF_SLEW_MASK0x7
+
+#define TPS65224_BUCK_VOLT_MAX 330
+#define TPS65224_BUCK1_VOLT_MAX_HEX  0xFD
+#define TPS65224_BUCK234_VOLT_MAX_HEX0x45
+
+#define TPS65224_BUCK_CONF_SLEW_MASK 0x3
+#define TPS65224_LDO_VOLT_MASK(0x3F << 1)
+
+#define TPS65224_LDO1_VOLT_MIN_HEX   0x0C
+#define TPS65224_LDO23_VOLT_MIN_HEX  0x00
+#define TPS65224_LDO1_VOLT_MAX_HEX   0x36
+#define TPS65224_LDO23_VOLT_MAX_HEX  0x38
+
+#define TPS65224_LDO1_VOLT_MAX330
+#define TPS65224_LDO23_VOLT_MAX   340
+#define TPS65224_LDO1_VOLT_MIN120
+#define TPS65224_LDO23_VOLT_MIN60
+
+#define TPS65224_LDO_STEP   5
+
+#define TPS65224_LDO_BYP_CONFIG 7
+
+#define TPS65224_LDO1_VOLT_BYP_MIN220
+#define TPS65224_LDO1_VOLT_BYP_MAX360
+
+#define TPS65224_LDO23_VOLT_BYP_MIN   150
+#define TPS65224_LDO23_VOLT_BYP_MAX   550
-- 
2.25.1



[PATCH v2 0/5] Add support for TI TPS65224 PMIC

2024-03-06 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
in U-boot. This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62P EVM using U-boot's
pmic list, regulator list, regulator status and regulator value commands.
Since, support for Ti's AM62P is absent in u-boot next, the patches
were applied on ti-u-boot ti-u-boot-2023.04-next and tested.

Changelog v1 -> v2:
- use __maybe_unused attrinute istead of commenting variable name in
  function params.
- refactoring tps65224_ldo_val2volt function

Bhargav Raviprakash (5):
  power: tps65941: Add macros of TPS65224 PMIC
  power: pmic: tps65941: Add TI TPS65224 PMIC
  power: regulator: tps65941: Added macros for BUCK ID
  power: regulator: tps65941: use function callbacks for conversion ops
  power: regulator: tps65941: Add TPS65224 PMIC regulator support

 drivers/power/pmic/tps65941.c|   1 +
 drivers/power/regulator/tps65941_regulator.c | 381 +--
 include/power/tps65941.h |  30 ++
 3 files changed, 381 insertions(+), 31 deletions(-)


base-commit: 4b151562bb8e54160adedbc6a1c0c749c00a2f84
-- 
2.25.1



Re: [PATCH v1 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-03-06 Thread Bhargav Raviprakash
On Fri, 23 Feb 2024 14:37:48 +0300, Dan Carpenter wrote:
> On Fri, Feb 23, 2024 at 02:42:12PM +0530, Bhargav Raviprakash wrote:
> > +   int mask = TPS65224_LDO_VOLT_MASK >> 1;
> > +
> > +   if (idx > 0) {
> > +   base = TPS65224_LDO23_VOLT_MIN;
> > +   max = TPS65224_LDO23_VOLT_MAX;
> > +   reg_base = TPS65224_LDO23_VOLT_MIN_HEX;
> > +   reg_max = TPS65224_LDO23_VOLT_MAX_HEX;
> > +   }
> > +
> > +   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;
> 
> Instead of "if (val >= 0)" it would be more clear to write
> "if (value > reg_base)".  Or something like this:
> 
>   val = val >> 1;
>   if (val < 0 || val > mask)
>   return -EINVAL;
> 
>   if (val <= reg_base)
>   return base;
>   if (val >= reg_max)
>   return max;
> 
>   return base + (step * (val - reg_base));
> 
> regards,
> dan carpenter

Thanks! Will change it accordingly in next version.

Regards,
Bhargav


Re: [PATCH v1 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-03-06 Thread Bhargav Raviprakash
On Fri, 23 Feb 2024 15:11:56 +0530, Dhruva Gole wrote:
> On Feb 23, 2024 at 14:42:11 +0530, Bhargav Raviprakash wrote:
> > Use function callbacks for volt2val, val2volt and slewrate lookups.
> > This makes it easier to add support for TPS65224 PMIC regulators.
> > 
> > Signed-off-by: Bhargav Raviprakash 
> > ---
> >  drivers/power/regulator/tps65941_regulator.c | 61 +++-
> >  1 file changed, 48 insertions(+), 13 deletions(-)
> 
> Add Tom Rini in To or CC please.
> 

Sure

> > 
> > diff --git a/drivers/power/regulator/tps65941_regulator.c 
> > b/drivers/power/regulator/tps65941_regulator.c
> > index cf54e30df5..cdfbc3f4de 100644
> > --- a/drivers/power/regulator/tps65941_regulator.c
> > +++ b/drivers/power/regulator/tps65941_regulator.c
> > @@ -35,6 +35,17 @@
> >  #define TPS65941_LDO_ID_3 3
> >  #define TPS65941_LDO_ID_4 4
> >  
> > +#define TPS65941_BUCK_CONV_OPS_IDX  0
> > +#define TPS65941_LDO_CONV_OPS_IDX   0
> > +
> > +struct tps65941_reg_conv_ops {
> > +   int volt_mask;
> > +   int (*volt2val)(int idx, int uV);
> > +   int (*val2volt)(int idx, int volt);
> > +   int slew_mask;
> > +   int (*lookup_slew)(int id);
> > +};
> > +
> >  static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 
> > 0xA,
> > 0xC};
> >  static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
> > @@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int 
> > op, bool *enable)
> > return 0;
> >  }
> >  
> > -static int tps65941_buck_volt2val(int uV)
> > +static int tps65941_buck_volt2val(int /*idx*/, int uV)
> 
> IMHO /*idx*/ does NOT look good.
> Check something like __maybe_unused attribute
> 
> [...]
> 
> -- 
> Best regards,
> Dhruva Gole 

Thanks for the feedback. Will use '__maybe_unused' in next version.

Regards,
Bhargav


[PATCH v1 5/5] power: regulator: tps65941: Add TPS65224 PMIC regulator support

2024-02-23 Thread Bhargav Raviprakash
Reuse TPS65941 regulator driver to adds support for
TPS65224 PMIC's regulators. 4 BUCKs and 3 LDOs, where
BUCK1 and BUCK2 can be configured in dual phase mode.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 279 ++-
 1 file changed, 266 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cdfbc3f4de..dd587e9db3 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -37,6 +37,8 @@
 
 #define TPS65941_BUCK_CONV_OPS_IDX  0
 #define TPS65941_LDO_CONV_OPS_IDX   0
+#define TPS65224_LDO_CONV_OPS_IDX   1
+#define TPS65224_BUCK_CONV_OPS_IDX  1
 
 struct tps65941_reg_conv_ops {
int volt_mask;
@@ -55,6 +57,11 @@ static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = 
{0x1D, 0x1E, 0x1F,
 static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
0x26};
 
+static inline int tps65941_get_chip_id(struct udevice *dev)
+{
+   return dev->parent->driver_data;
+}
+
 static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
 {
int ret;
@@ -146,6 +153,112 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   /* This functions maps a value which is in micro Volts to the VSET 
value.
+* The mapping is as per the datasheet of TPS65224.
+*/
+
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
+* converting b/w micro_volt and VSET hex values
+*
+* VSET value starts from 0x00 for 0.5V, and for every increment
+* in VSET value the output voltage increases by 25mV. This is 
upto
+* 1.15V where VSET is 0x1A.
+*
+* For 0x1B the output voltage is 1.2V, and for every increment 
of
+* VSET the output voltage increases by 50mV upto the max 
voltage of
+* 3.3V
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 1.50V   | 0x00 to 0x1A |  25mV|
+* | 1.2V to 3.3V| 0x1B to 0x45 |  50mV|
+*/
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   /* Buck1 and Buck12(dual phase) has a different mapping b/w output
+* voltage and VSET value.
+*
+* | Voltage Ranges  | VSET Ranges  | Voltage Step |
+* +-+--+--+
+* | 0.5V to 0.58V   | 0xA to 0xE   |  20mV|
+* | 0.6V to 1.095V  | 0xF to 0x72  |  5mV |
+* | 1.1V to 1.65V   | 0x73 to 0xAA |  10mV|
+* | 1.6V to 3.3V| 0xAB to 0xFD |  20mV|
+*
+*/
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   /* This function does the opposite to the tps65224_buck_volt2val 
function
+* described above.
+* This maps the VSET value to micro volts. Please refer to the ranges
+* mentioned the comments of tps65224_buck_volt2val.
+*/
+
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+   return 120 + (val - 0x1B) * 5;
+   else if (val >= 0x00)
+   return 50 + (val - 0x00) * 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0xAB)
+   return 166 + (val - 0xAB) * 2;
+   else if (val >= 0x73)
+   return 110 + (val - 0x73) * 1;
+   else if (val >= 0xF)
+   return 60 + (val - 0xF) * 5000;
+   else if (val >= 0xA)
+   return 50 + (val - 0xA) * 2;
+   else
+   return -EINVAL;
+}
+
+int tps65224_lookup_slew(int id)
+{
+   switch (id) {
+  

[PATCH v1 2/5] power: pmic: tps65941: Add TI TPS65224 PMIC

2024-02-23 Thread Bhargav Raviprakash
Adds compatible and data field values of TPS65224 driver in
TPS65941 PMIC driver.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/pmic/tps65941.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index 727b42747a..ef63eb733a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -75,6 +75,7 @@ static const struct udevice_id tps65941_ids[] = {
{ .compatible = "ti,tps659412", .data = TPS659411 },
{ .compatible = "ti,tps659413", .data = TPS659413 },
{ .compatible = "ti,lp876441",  .data =  LP876441 },
+   { .compatible = "ti,tps65224",  .data =  TPS65224 },
{ }
 };
 
-- 
2.25.1



[PATCH v1 4/5] power: regulator: tps65941: use function callbacks for conversion ops

2024-02-23 Thread Bhargav Raviprakash
Use function callbacks for volt2val, val2volt and slewrate lookups.
This makes it easier to add support for TPS65224 PMIC regulators.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 61 +++-
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index cf54e30df5..cdfbc3f4de 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -35,6 +35,17 @@
 #define TPS65941_LDO_ID_3 3
 #define TPS65941_LDO_ID_4 4
 
+#define TPS65941_BUCK_CONV_OPS_IDX  0
+#define TPS65941_LDO_CONV_OPS_IDX   0
+
+struct tps65941_reg_conv_ops {
+   int volt_mask;
+   int (*volt2val)(int idx, int uV);
+   int (*val2volt)(int idx, int volt);
+   int slew_mask;
+   int (*lookup_slew)(int id);
+};
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -79,7 +90,7 @@ static int tps65941_buck_enable(struct udevice *dev, int op, 
bool *enable)
return 0;
 }
 
-static int tps65941_buck_volt2val(int uV)
+static int tps65941_buck_volt2val(int /*idx*/, int uV)
 {
if (uV > TPS65941_BUCK_VOLT_MAX)
return -EINVAL;
@@ -95,7 +106,7 @@ static int tps65941_buck_volt2val(int uV)
return -EINVAL;
 }
 
-static int tps65941_buck_val2volt(int val)
+static int tps65941_buck_val2volt(int /*idx*/, int val)
 {
if (val > TPS65941_BUCK_VOLT_MAX_HEX)
return -EINVAL;
@@ -135,12 +146,25 @@ int tps65941_lookup_slew(int id)
}
 }
 
+static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
+   [TPS65941_BUCK_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_BUCK_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_buck_val2volt,
+   .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
+   .lookup_slew = tps65941_lookup_slew,
+   },
+};
+
 static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret, delta, uwait, slew;
+   int ret, delta, uwait, slew, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -152,8 +176,8 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_BUCK_VOLT_MASK;
-   ret = tps65941_buck_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret = conv_ops->val2volt(idx, ret);
if (ret < 0)
return ret;
 
@@ -175,14 +199,14 @@ static int tps65941_buck_val(struct udevice *dev, int op, 
int *uV)
if (slew < 0)
return ret;
 
-   slew &= TP65941_BUCK_CONF_SLEW_MASK;
-   slew = tps65941_lookup_slew(slew);
+   slew &= conv_ops->slew_mask;
+   slew = conv_ops->lookup_slew(slew);
if (slew <= 0)
return ret;
 
uwait = delta / slew;
 
-   hex = tps65941_buck_volt2val(*uV);
+   hex = conv_ops->volt2val(idx, *uV);
if (hex < 0)
return hex;
 
@@ -231,7 +255,7 @@ 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_val2volt(int /*idx*/, int val)
 {
if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
return -EINVAL;
@@ -241,12 +265,23 @@ static int tps65941_ldo_val2volt(int val)
return -EINVAL;
 }
 
+static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
+   [TPS65941_LDO_CONV_OPS_IDX] = {
+   .volt_mask = TPS65941_LDO_VOLT_MASK,
+   .volt2val = tps65941_buck_volt2val,
+   .val2volt = tps65941_ldo_val2volt,
+   },
+};
+
 static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
 {
unsigned int hex, adr;
-   int ret;
+   int ret, idx;
struct dm_regulator_uclass_plat *uc_pdata;
+   const struct tps65941_reg_conv_ops *conv_ops;
 
+   idx = dev->driver_data;
+   conv_ops = _conv_ops[TPS65941_LDO_CONV_OPS_IDX];
uc_pdata = dev_get_uclass_plat(dev);
 
if (op == PMIC_OP_GET)
@@ -258,8 +293,8 @@ static int tps65941_ldo_val(struct udevice *dev, int op, 
int *uV)
if (ret < 0)
return ret;
 
-   ret &= TPS65941_LDO_VOLT_MASK;
-   ret = tps65941_ldo_val2volt(ret);
+   ret &= conv_ops->volt_mask;
+   ret =

[PATCH v1 3/5] power: regulator: tps65941: Added macros for BUCK ID

2024-02-23 Thread Bhargav Raviprakash
Adds macros for buck and ldo ids and switched to using switch
case instead of if else in probe functions. Helps in adding
support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/tps65941_regulator.c | 54 +++-
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/power/regulator/tps65941_regulator.c 
b/drivers/power/regulator/tps65941_regulator.c
index b041126775..cf54e30df5 100644
--- a/drivers/power/regulator/tps65941_regulator.c
+++ b/drivers/power/regulator/tps65941_regulator.c
@@ -16,6 +16,25 @@
 #include 
 #include 
 
+/* Single Phase Buck IDs */
+#define TPS65941_BUCK_ID_11
+#define TPS65941_BUCK_ID_22
+#define TPS65941_BUCK_ID_33
+#define TPS65941_BUCK_ID_44
+#define TPS65941_BUCK_ID_55
+
+/* Multi Phase Buck IDs */
+#define TPS65941_BUCK_ID_12  12
+#define TPS65941_BUCK_ID_34  34
+#define TPS65941_BUCK_ID_123123
+#define TPS65941_BUCK_ID_1234  1234
+
+/* LDO IDs */
+#define TPS65941_LDO_ID_1 1
+#define TPS65941_LDO_ID_2 2
+#define TPS65941_LDO_ID_3 3
+#define TPS65941_LDO_ID_4 4
+
 static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
0xC};
 static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
@@ -270,10 +289,15 @@ static int tps65941_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4) {
+   switch (idx) {
+   case TPS65941_LDO_ID_1:
+   case TPS65941_LDO_ID_2:
+   case TPS65941_LDO_ID_3:
+   case TPS65941_LDO_ID_4:
debug("Single phase regulator\n");
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
@@ -292,18 +316,24 @@ static int tps65941_buck_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_BUCK;
 
idx = dev->driver_data;
-   if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) {
+   switch (idx) {
+   case TPS65941_BUCK_ID_1:
+   case TPS65941_BUCK_ID_2:
+   case TPS65941_BUCK_ID_3:
+   case TPS65941_BUCK_ID_4:
+   case TPS65941_BUCK_ID_5:
debug("Single phase regulator\n");
-   } else if (idx == 12) {
+   break;
+   case TPS65941_BUCK_ID_12:
+   case TPS65941_BUCK_ID_123:
+   case TPS65941_BUCK_ID_1234:
idx = 1;
-   } else if (idx == 34) {
+   break;
+   case TPS65941_BUCK_ID_34:
idx = 3;
-   } else if (idx == 123) {
-   idx = 1;
-   } else if (idx == 1234) {
-   idx = 1;
-   } else {
-   printf("Wrong ID for regulator\n");
+   break;
+   default:
+   pr_err("Wrong ID for regulator\n");
return -EINVAL;
}
 
-- 
2.25.1



[PATCH v1 1/5] power: tps65941: Add macros of TPS65224 PMIC

2024-02-23 Thread Bhargav Raviprakash
Re-use the TPS65941 PMIC driver for TPS65224 PMIC.
Add additional macros of TPS65224 to aid in the driver
re-use.

Signed-off-by: Bhargav Raviprakash 
---
 include/power/tps65941.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/power/tps65941.h b/include/power/tps65941.h
index a2bc6814ba..cec85333f0 100644
--- a/include/power/tps65941.h
+++ b/include/power/tps65941.h
@@ -3,11 +3,14 @@
 #define TPS659413  0x2
 #define TPS659414  0x3
 #define  LP876441  0x4
+#define  TPS65224  0x5
 
 /* I2C device address for pmic tps65941 */
 #define TPS65941_I2C_ADDR  (0x12 >> 1)
 #define TPS65941_LDO_NUM   4
 #define TPS65941_BUCK_NUM  5
+#define TPS65224_LDO_NUM   3
+#define TPS65224_BUCK_NUM  4
 
 /* Drivers name */
 #define TPS65941_LDO_DRIVER"tps65941_ldo"
@@ -25,3 +28,30 @@
 #define TPS65941_LDO_MODE_MASK 0x1
 #define TPS65941_LDO_BYPASS_EN 0x80
 #define TP65941_BUCK_CONF_SLEW_MASK0x7
+
+#define TPS65224_BUCK_VOLT_MAX 330
+#define TPS65224_BUCK1_VOLT_MAX_HEX  0xFD
+#define TPS65224_BUCK234_VOLT_MAX_HEX0x45
+
+#define TPS65224_BUCK_CONF_SLEW_MASK 0x3
+#define TPS65224_LDO_VOLT_MASK(0x3F << 1)
+
+#define TPS65224_LDO1_VOLT_MIN_HEX   0x0C
+#define TPS65224_LDO23_VOLT_MIN_HEX  0x00
+#define TPS65224_LDO1_VOLT_MAX_HEX   0x36
+#define TPS65224_LDO23_VOLT_MAX_HEX  0x38
+
+#define TPS65224_LDO1_VOLT_MAX330
+#define TPS65224_LDO23_VOLT_MAX   340
+#define TPS65224_LDO1_VOLT_MIN120
+#define TPS65224_LDO23_VOLT_MIN60
+
+#define TPS65224_LDO_STEP   5
+
+#define TPS65224_LDO_BYP_CONFIG 7
+
+#define TPS65224_LDO1_VOLT_BYP_MIN220
+#define TPS65224_LDO1_VOLT_BYP_MAX360
+
+#define TPS65224_LDO23_VOLT_BYP_MIN   150
+#define TPS65224_LDO23_VOLT_BYP_MAX   550
-- 
2.25.1



[PATCH v1 0/5] Add support for TI TPS65224 PMIC

2024-02-23 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Reusing the TPS65941 PMIC driver to add support for TPS65224 PMIC 
in U-boot. This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62P EVM using U-boot's
pmic list, regulator list, regulator status and regulator value commands.
Since, support for Ti's AM62P is absent in u-boot next, the patches
were applied on ti-u-boot ti-u-boot-2023.04-next and tested.

Bhargav Raviprakash (5):
  power: tps65941: Add macros of TPS65224 PMIC
  power: pmic: tps65941: Add TI TPS65224 PMIC
  power: regulator: tps65941: Added macros for BUCK ID
  power: regulator: tps65941: use function callbacks for conversion ops
  power: regulator: tps65941: Add TPS65224 PMIC regulator support

 drivers/power/pmic/tps65941.c|   1 +
 drivers/power/regulator/tps65941_regulator.c | 380 +--
 include/power/tps65941.h |  30 ++
 3 files changed, 380 insertions(+), 31 deletions(-)


base-commit: 4b151562bb8e54160adedbc6a1c0c749c00a2f84
-- 
2.25.1



Re: [PATCH v2 1/2] driver: power: add support for TPS65224

2023-11-08 Thread Bhargav Raviprakash
Hello Jaehoon,

> > Hi Bhargav,
> > 
> > On Mon, 6 Nov 2023 at 10:11, Bhargav Raviprakash  wrote:
> > >
> > > Added support for PMIC TPS65224. Includes driver for pmic,
> > > and disabling Watchdog.
> > >
> > > Signed-off-by: Bhargav Raviprakash 
> > > ---
> > >  drivers/power/pmic/Kconfig|   6 ++
> > >  drivers/power/pmic/Makefile   |   1 +
> > >  drivers/power/pmic/tps65224.c | 141 ++
> > >  include/power/tps65224.h  |  57 ++
> > >  4 files changed, 205 insertions(+)
> > >  create mode 100644 drivers/power/pmic/tps65224.c
> > >  create mode 100644 include/power/tps65224.h
> > >
> > > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> > > index 4a6f0ce093..b06bd31823 100644
> > > --- a/drivers/power/pmic/Kconfig
> > > +++ b/drivers/power/pmic/Kconfig
> > > @@ -378,6 +378,12 @@ config PMIC_TPS65941
> > > The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
> > > This driver binds the pmic children.
> > >
> > > +config PMIC_TPS65224
> > > +   bool "Enable driver for Texas Instruments TPS65224 PMIC"
> > > +   help
> > > +   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
> > > +   This driver binds the pmic children.
> > > +
> > >  config PMIC_TPS65219
> > > bool "Enable driver for Texas Instruments TPS65219 PMIC"
> > > depends on DM_PMIC
> > > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
> > > index 0b3b3d62d0..cec16e57d3 100644
> > > --- a/drivers/power/pmic/Makefile
> > > +++ b/drivers/power/pmic/Makefile
> > > @@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
> > >  obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
> > >  obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
> > >  obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
> > > +obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
> > >  obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
> > >
> > >  ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
> > > diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
> > > new file mode 100644
> > > index 00..33395f6edf
> > > --- /dev/null
> > > +++ b/drivers/power/pmic/tps65224.c
> > > @@ -0,0 +1,141 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * (C) Copyright 2023 Texas Instruments Incorporated, 
> > > + */
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +static const struct pmic_child_info pmic_children_info[] = {
> > > +   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
> > > +   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
> > > +   { },
> > > +};
> > > +
> > > +static int tps65224_write(struct udevice *dev, uint reg, const uint8_t 
> > > *buff,
> > > + int len)
> > > +{
> > > +   if (dm_i2c_write(dev, reg, buff, len)) {
> > > +   pr_err("write error to device: %p register: %#x!\n", dev, 
> > > reg);
> > > +   return -EIO;
> > > +   }
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, 
> > > int len)
> > > +{
> > > +   if (dm_i2c_read(dev, reg, buff, len)) {
> > > +   pr_err("read error from device: %p register: %#x!\n", 
> > > dev, reg);
> > > +   return -EIO;
> > > +   }
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +static int tps65224_bind(struct udevice *dev)
> > > +{
> > > +   ofnode regulators_node;
> > > +   int children;
> > > +
> > > +   if (dev->driver_data == TPS65224_WD)
> > > +   return 0;
> > > +
> > > +   regulators_node = dev_read_subnode(dev, "regulators");
> > > +   if (!ofnode_valid(regulators_node)) {
> > > +   debug("%s: %s regulators subnode not found!\n", __func__,
> > > + dev->name);
>

Re: [PATCH v2 1/2] driver: power: add support for TPS65224

2023-11-08 Thread Bhargav Raviprakash
> Hi Bhargav,
> 
> On Mon, 6 Nov 2023 at 10:11, Bhargav Raviprakash  wrote:
> >
> > Added support for PMIC TPS65224. Includes driver for pmic,
> > and disabling Watchdog.
> >
> > Signed-off-by: Bhargav Raviprakash 
> > ---
> >  drivers/power/pmic/Kconfig|   6 ++
> >  drivers/power/pmic/Makefile   |   1 +
> >  drivers/power/pmic/tps65224.c | 141 ++
> >  include/power/tps65224.h  |  57 ++
> >  4 files changed, 205 insertions(+)
> >  create mode 100644 drivers/power/pmic/tps65224.c
> >  create mode 100644 include/power/tps65224.h
> >
> > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> > index 4a6f0ce093..b06bd31823 100644
> > --- a/drivers/power/pmic/Kconfig
> > +++ b/drivers/power/pmic/Kconfig
> > @@ -378,6 +378,12 @@ config PMIC_TPS65941
> > The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
> > This driver binds the pmic children.
> >
> > +config PMIC_TPS65224
> > +   bool "Enable driver for Texas Instruments TPS65224 PMIC"
> > +   help
> > +   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
> > +   This driver binds the pmic children.
> > +
> >  config PMIC_TPS65219
> > bool "Enable driver for Texas Instruments TPS65219 PMIC"
> > depends on DM_PMIC
> > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
> > index 0b3b3d62d0..cec16e57d3 100644
> > --- a/drivers/power/pmic/Makefile
> > +++ b/drivers/power/pmic/Makefile
> > @@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
> >  obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
> >  obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
> >  obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
> > +obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
> >  obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
> >
> >  ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
> > diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
> > new file mode 100644
> > index 00..33395f6edf
> > --- /dev/null
> > +++ b/drivers/power/pmic/tps65224.c
> > @@ -0,0 +1,141 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2023 Texas Instruments Incorporated, 
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +static const struct pmic_child_info pmic_children_info[] = {
> > +   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
> > +   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
> > +   { },
> > +};
> > +
> > +static int tps65224_write(struct udevice *dev, uint reg, const uint8_t 
> > *buff,
> > + int len)
> > +{
> > +   if (dm_i2c_write(dev, reg, buff, len)) {
> > +   pr_err("write error to device: %p register: %#x!\n", dev, 
> > reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, int 
> > len)
> > +{
> > +   if (dm_i2c_read(dev, reg, buff, len)) {
> > +   pr_err("read error from device: %p register: %#x!\n", dev, 
> > reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_bind(struct udevice *dev)
> > +{
> > +   ofnode regulators_node;
> > +   int children;
> > +
> > +   if (dev->driver_data == TPS65224_WD)
> > +   return 0;
> > +
> > +   regulators_node = dev_read_subnode(dev, "regulators");
> > +   if (!ofnode_valid(regulators_node)) {
> > +   debug("%s: %s regulators subnode not found!\n", __func__,
> > + dev->name);
> > +   return -ENXIO;
> > +   }
> > +
> > +   debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
> > +
> > +   children = pmic_bind_children(dev, regulators_node, 
> > pmic_children_info);
> > +   if (!children)
> > +   printf("%s: %s - no child found\n", __func__, dev->name);
> > +
> > +   /* Probe all the child devices */
> 
> bind, not probe
> 
> > +   return dm_scan_fdt_dev(dev);
>

Re: [PATCH v2 1/2] driver: power: add support for TPS65224

2023-11-08 Thread Bhargav Raviprakash
> Hi Bhargav,
> 
> > -Original Message-
> > From: Bhargav Raviprakash 
> > Sent: Monday, November 6, 2023 11:07 PM
> > To: u-boot@lists.denx.de
> > Cc: jh80.ch...@samsung.com; Bhargav Raviprakash 
> > Subject: [PATCH v2 1/2] driver: power: add support for TPS65224
> > 
> > Added support for PMIC TPS65224. Includes driver for pmic,
> > and disabling Watchdog.
> > 
> > Signed-off-by: Bhargav Raviprakash 
> > ---
> >  drivers/power/pmic/Kconfig|   6 ++
> >  drivers/power/pmic/Makefile   |   1 +
> >  drivers/power/pmic/tps65224.c | 141 ++
> >  include/power/tps65224.h  |  57 ++
> >  4 files changed, 205 insertions(+)
> >  create mode 100644 drivers/power/pmic/tps65224.c
> >  create mode 100644 include/power/tps65224.h
> > 
> > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> > index 4a6f0ce093..b06bd31823 100644
> > --- a/drivers/power/pmic/Kconfig
> > +++ b/drivers/power/pmic/Kconfig
> > @@ -378,6 +378,12 @@ config PMIC_TPS65941
> > The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
> > This driver binds the pmic children.
> > 
> > +config PMIC_TPS65224
> > +   bool "Enable driver for Texas Instruments TPS65224 PMIC"
> > +   help
> > +   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
> > +   This driver binds the pmic children.
> > +
> >  config PMIC_TPS65219
> > bool "Enable driver for Texas Instruments TPS65219 PMIC"
> > depends on DM_PMIC
> > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
> > index 0b3b3d62d0..cec16e57d3 100644
> > --- a/drivers/power/pmic/Makefile
> > +++ b/drivers/power/pmic/Makefile
> > @@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
> >  obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
> >  obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
> >  obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
> > +obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
> 
> Ordering this. Maybe it can be located at tps65941.o.
> 

Sure, will do!

> >  obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
> > 
> >  ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
> > diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
> > new file mode 100644
> > index 00..33395f6edf
> > --- /dev/null
> > +++ b/drivers/power/pmic/tps65224.c
> > @@ -0,0 +1,141 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2023 Texas Instruments Incorporated, 
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +static const struct pmic_child_info pmic_children_info[] = {
> > +   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
> > +   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
> > +   { },
> > +};
> > +
> > +static int tps65224_write(struct udevice *dev, uint reg, const uint8_t 
> > *buff,
> > + int len)
> > +{
> > +   if (dm_i2c_write(dev, reg, buff, len)) {
> > +   pr_err("write error to device: %p register: %#x!\n", dev, reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, int 
> > len)
> > +{
> > +   if (dm_i2c_read(dev, reg, buff, len)) {
> > +   pr_err("read error from device: %p register: %#x!\n", dev, reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_bind(struct udevice *dev)
> > +{
> > +   ofnode regulators_node;
> > +   int children;
> > +
> > +   if (dev->driver_data == TPS65224_WD)
> > +   return 0;
> > +
> > +   regulators_node = dev_read_subnode(dev, "regulators");
> > +   if (!ofnode_valid(regulators_node)) {
> > +   debug("%s: %s regulators subnode not found!\n", __func__,
> > + dev->name);
> > +   return -ENXIO;
> > +   }
> > +
> > +   debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
> > +
> > +   children = pmic_bind_children(dev, regulators_node, pmic_children_info);
> > +   if (!children)
> > +   printf("%s: %s - no child found\n", __func__, dev->

Re: [PATCH v2 1/2] driver: power: add support for TPS65224

2023-11-08 Thread Bhargav Raviprakash
> Hi Bhargav,
> 
> On Mon, 6 Nov 2023 at 10:11, Bhargav Raviprakash  wrote:
> >
> > Added support for PMIC TPS65224. Includes driver for pmic,
> > and disabling Watchdog.
> >
> > Signed-off-by: Bhargav Raviprakash 
> > ---
> >  drivers/power/pmic/Kconfig|   6 ++
> >  drivers/power/pmic/Makefile   |   1 +
> >  drivers/power/pmic/tps65224.c | 141 ++
> >  include/power/tps65224.h  |  57 ++
> >  4 files changed, 205 insertions(+)
> >  create mode 100644 drivers/power/pmic/tps65224.c
> >  create mode 100644 include/power/tps65224.h
> >
> > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> > index 4a6f0ce093..b06bd31823 100644
> > --- a/drivers/power/pmic/Kconfig
> > +++ b/drivers/power/pmic/Kconfig
> > @@ -378,6 +378,12 @@ config PMIC_TPS65941
> > The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
> > This driver binds the pmic children.
> >
> > +config PMIC_TPS65224
> > +   bool "Enable driver for Texas Instruments TPS65224 PMIC"
> > +   help
> > +   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
> > +   This driver binds the pmic children.
> > +
> >  config PMIC_TPS65219
> > bool "Enable driver for Texas Instruments TPS65219 PMIC"
> > depends on DM_PMIC
> > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
> > index 0b3b3d62d0..cec16e57d3 100644
> > --- a/drivers/power/pmic/Makefile
> > +++ b/drivers/power/pmic/Makefile
> > @@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
> >  obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
> >  obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
> >  obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
> > +obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
> >  obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
> >
> >  ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
> > diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
> > new file mode 100644
> > index 00..33395f6edf
> > --- /dev/null
> > +++ b/drivers/power/pmic/tps65224.c
> > @@ -0,0 +1,141 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2023 Texas Instruments Incorporated, 
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +static const struct pmic_child_info pmic_children_info[] = {
> > +   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
> > +   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
> > +   { },
> > +};
> > +
> > +static int tps65224_write(struct udevice *dev, uint reg, const uint8_t 
> > *buff,
> > + int len)
> > +{
> > +   if (dm_i2c_write(dev, reg, buff, len)) {
> > +   pr_err("write error to device: %p register: %#x!\n", dev, 
> > reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, int 
> > len)
> > +{
> > +   if (dm_i2c_read(dev, reg, buff, len)) {
> > +   pr_err("read error from device: %p register: %#x!\n", dev, 
> > reg);
> > +   return -EIO;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int tps65224_bind(struct udevice *dev)
> > +{
> > +   ofnode regulators_node;
> > +   int children;
> > +
> > +   if (dev->driver_data == TPS65224_WD)
> > +   return 0;
> > +
> > +   regulators_node = dev_read_subnode(dev, "regulators");
> > +   if (!ofnode_valid(regulators_node)) {
> > +   debug("%s: %s regulators subnode not found!\n", __func__,
> > + dev->name);
> > +   return -ENXIO;
> > +   }
> > +
> > +   debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
> > +
> > +   children = pmic_bind_children(dev, regulators_node, 
> > pmic_children_info);
> > +   if (!children)
> > +   printf("%s: %s - no child found\n", __func__, dev->name);
> > +
> > +   /* Probe all the child devices */
> 
> bind, not probe
> 
> > +   return dm_scan_fdt_dev(dev);
>

[PATCH v2 2/2] driver: power: regulator: add support for TPS65224 regulator

2023-11-06 Thread Bhargav Raviprakash
Added support for PMIC TPS65224 regulators. Includes driver for
buck and ldo.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/Kconfig  |  10 +
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/tps65224_regulator.c | 495 +++
 include/power/tps65224.h |   6 +-
 4 files changed, 510 insertions(+), 2 deletions(-)
 create mode 100644 drivers/power/regulator/tps65224_regulator.c

diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index eb5aa38c1c..cb86025a22 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -408,6 +408,16 @@ config DM_REGULATOR_TPS65941
be configured in multi phase modes & 4 LDOs. The driver implements
get/set api for value and enable.
 
+config DM_REGULATOR_TPS65224
+   bool "Enable driver for TPS65224 PMIC regulators"
+depends on PMIC_TPS65224
+   help
+   This enables implementation of driver-model regulator uclass
+   features for REGULATOR TPS65224 and the family of TPS65224 PMICs.
+   TPS65224 series of PMICs have 4 single phase BUCKs that can also
+   be configured in multi phase modes & 3 LDOs. The driver implements
+   get/set api for value and enable.
+
 config DM_REGULATOR_SCMI
bool "Enable driver for SCMI voltage domain regulators"
depends on DM_REGULATOR
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index d9e0cd5949..d4b9b7233f 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o
 obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o
 obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o
+obj-$(CONFIG_DM_REGULATOR_TPS65224) += tps65224_regulator.o
 obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_ANATOP) += anatop_regulator.o
 obj-$(CONFIG_DM_REGULATOR_TPS65219) += tps65219_regulator.o
diff --git a/drivers/power/regulator/tps65224_regulator.c 
b/drivers/power/regulator/tps65224_regulator.c
new file mode 100644
index 00..0431556331
--- /dev/null
+++ b/drivers/power/regulator/tps65224_regulator.c
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023 Texas Instruments Incorporated, 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TPS65224_BUCK234_50mV_OFFSET_START_VOLT 120
+#define TPS65224_BUCK234_25mV_OFFSET_START_VOLT  50
+#define TPS65224_BUCK234_50mV_OFFSET_START_VSET 0x1B
+#define TPS65224_BUCK234_25mV_OFFSET_START_VSET 0x00
+
+#define TPS65224_BUCK1_20mV_OFFSET_START_VOLT_1 166
+#define TPS65224_BUCK1_10mV_OFFSET_START_VOLT   110
+#define TPS65224_BUCK1_5mV_OFFSET_START_VOLT 60
+#define TPS65224_BUCK1_20mV_OFFSET_START_VOLT_0  50
+#define TPS65224_BUCK1_20mV_OFFSET_START_VSET_1 0xAB
+#define TPS65224_BUCK1_10mV_OFFSET_START_VSET   0x73
+#define TPS65224_BUCK1_5mV_OFFSET_START_VSET0x0F
+#define TPS65224_BUCK1_20mV_OFFSET_START_VSET_0 0x0A
+
+static const char tps65224_buck_ctrl[TPS65224_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA};
+static const char tps65224_buck_vout[TPS65224_BUCK_NUM] = {0xE, 0x10, 0x12, 
0x14};
+static const char tps65224_ldo_ctrl[TPS65224_BUCK_NUM] = {0x1D, 0x1E, 0x1F};
+static const char tps65224_ldo_vout[TPS65224_BUCK_NUM] = {0x23, 0x24, 0x25};
+
+static int tps65224_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+   int ret;
+   unsigned int adr;
+   struct dm_regulator_uclass_plat *uc_pdata;
+
+   uc_pdata = dev_get_uclass_plat(dev);
+   adr = uc_pdata->ctrl_reg;
+
+   ret = pmic_reg_read(dev->parent, adr);
+   if (ret < 0)
+   return ret;
+
+   if (op == PMIC_OP_GET) {
+   ret &= TPS65224_BUCK_MODE_MASK;
+
+   if (ret)
+   *enable = true;
+   else
+   *enable = false;
+
+   return 0;
+   } else if (op == PMIC_OP_SET) {
+   if (*enable)
+   ret |= TPS65224_BUCK_MODE_MASK;
+   else
+   ret &= ~TPS65224_BUCK_MODE_MASK;
+   ret = pmic_reg_write(dev->parent, adr, ret);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   if (uV >= TPS65224_BUCK234_50mV_OFFSET_START_VOLT)
+   return (uV - TPS65224_BUCK234_50mV_OFFSET_START_VOLT) / 
5 +
+   TPS65224_BUCK234_50mV_OFFSET_START_VSET;
+   else if (uV >= TPS65224_BUCK23

[PATCH v2 1/2] driver: power: add support for TPS65224

2023-11-06 Thread Bhargav Raviprakash
Added support for PMIC TPS65224. Includes driver for pmic,
and disabling Watchdog.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/pmic/Kconfig|   6 ++
 drivers/power/pmic/Makefile   |   1 +
 drivers/power/pmic/tps65224.c | 141 ++
 include/power/tps65224.h  |  57 ++
 4 files changed, 205 insertions(+)
 create mode 100644 drivers/power/pmic/tps65224.c
 create mode 100644 include/power/tps65224.h

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 4a6f0ce093..b06bd31823 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -378,6 +378,12 @@ config PMIC_TPS65941
The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
This driver binds the pmic children.
 
+config PMIC_TPS65224
+   bool "Enable driver for Texas Instruments TPS65224 PMIC"
+   help
+   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
+   This driver binds the pmic children.
+
 config PMIC_TPS65219
bool "Enable driver for Texas Instruments TPS65219 PMIC"
depends on DM_PMIC
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 0b3b3d62d0..cec16e57d3 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
 obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
 obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
 obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
+obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
 obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
 
 ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
new file mode 100644
index 00..33395f6edf
--- /dev/null
+++ b/drivers/power/pmic/tps65224.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023 Texas Instruments Incorporated, 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const struct pmic_child_info pmic_children_info[] = {
+   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
+   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
+   { },
+};
+
+static int tps65224_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
+{
+   if (dm_i2c_write(dev, reg, buff, len)) {
+   pr_err("write error to device: %p register: %#x!\n", dev, reg);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+   if (dm_i2c_read(dev, reg, buff, len)) {
+   pr_err("read error from device: %p register: %#x!\n", dev, reg);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int tps65224_bind(struct udevice *dev)
+{
+   ofnode regulators_node;
+   int children;
+
+   if (dev->driver_data == TPS65224_WD)
+   return 0;
+
+   regulators_node = dev_read_subnode(dev, "regulators");
+   if (!ofnode_valid(regulators_node)) {
+   debug("%s: %s regulators subnode not found!\n", __func__,
+ dev->name);
+   return -ENXIO;
+   }
+
+   debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
+
+   children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+   if (!children)
+   printf("%s: %s - no child found\n", __func__, dev->name);
+
+   /* Probe all the child devices */
+   return dm_scan_fdt_dev(dev);
+}
+
+static int stop_watchdog(struct udevice *wd_i2c_dev)
+{
+   int ret;
+
+   /* Maintain WD long window */
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_MODE_REG);
+   if (ret < 0) {
+   debug("failed to read i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   ret &= ~TPS65224_WD_PWRHOLD_MASK;
+   ret |= TPS65224_WD_PWRHOLD_MASK;
+   ret = dm_i2c_reg_write(wd_i2c_dev, TPS65224_WD_MODE_REG, ret);
+   if (ret) {
+   debug("%s: %s write WD_PWRHOLD fail!\n", __func__, 
wd_i2c_dev->name);
+   return ret;
+   }
+
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_MODE_REG);
+   if (ret < 0) {
+   debug("failed to read back i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   /* Disable WD */
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_THR_CFG);
+   if (ret < 0) {
+   debug("failed to read i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   ret &= ~TPS65224_WD_EN_MASK;
+   ret = dm_i2c_reg_write(wd_i2c_dev, TPS65224_WD_THR_CFG, ret);
+   if (ret) {
+   debug("%s: %s write WD_EN fail!\n", __func__, wd_i2c_dev->name

[PATCH v2 0/2] TPS65224 PMIC Driver

2023-11-06 Thread Bhargav Raviprakash
TPS65224 is a Power Management IC which provides regulators and others
features like GPIOs, RTC, watchdog, ADC, ESMs (Error Signal Monitor),
and PFSM (Pre-configurable Finite State Machine). The SoC and the PMIC
can communicate through the I2C.

Add support for TPS65224 PMIC in U-boot. This includes driver for
PMIC and regulator.

The driver was tested on Ti's custom AM62A EVM using U-boot's
pmic list, regulator list, regulator enable, regulator disable and
regulator value commands. Regulator output voltages were verified.

Logs from running the above commands,
 => pmic list
 | Name| Parent name   | Parent uclass @ seq
 | pmic@48 | i2c@490   | i2c @ 0 | status: 0
 | watchdog@12 | i2c@2000  | i2c @ 1 | status: 0
 => reg list
 | Device  | regulator-name| Parent
 | buck12  | buck12| pmic@48
 | buck3   | buck3 | pmic@48
 | buck4   | buck4 | pmic@48
 | ldo1| ldo1  | pmic@48
 | ldo2| ldo2  | pmic@48
 | ldo3| ldo3  | pmic@48
 => regulator dev buck12
 dev: buck12 @ buck12
 => regulator enable
 => regulator value 150
 => regulator disable

Changes since v1:
 - corrected coyright lines changed to 2023 in all files
 - Added #define macros for some of the magic numbers, constants
   and offsets to improve readability

Bhargav Raviprakash (2):
  driver: power: add support for TPS65224
  driver: power: regulator: add support for TPS65224 regulator

 drivers/power/pmic/Kconfig   |   6 +
 drivers/power/pmic/Makefile  |   1 +
 drivers/power/pmic/tps65224.c| 141 ++
 drivers/power/regulator/Kconfig  |  10 +
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/tps65224_regulator.c | 495 +++
 include/power/tps65224.h |  59 +++
 7 files changed, 713 insertions(+)
 create mode 100644 drivers/power/pmic/tps65224.c
 create mode 100644 drivers/power/regulator/tps65224_regulator.c
 create mode 100644 include/power/tps65224.h

-- 
2.25.1



[PATCH v1 2/2] driver: power: regulator: add support for TPS65224 regulator

2023-10-25 Thread Bhargav Raviprakash
Added support for PMIC TPS65224 regulators. Includes driver for
buck and ldo.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/regulator/Kconfig  |  10 +
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/tps65224_regulator.c | 472 +++
 include/power/tps65224.h |   6 +-
 4 files changed, 487 insertions(+), 2 deletions(-)
 create mode 100644 drivers/power/regulator/tps65224_regulator.c

diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index eb5aa38c1c..cb86025a22 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -408,6 +408,16 @@ config DM_REGULATOR_TPS65941
be configured in multi phase modes & 4 LDOs. The driver implements
get/set api for value and enable.
 
+config DM_REGULATOR_TPS65224
+   bool "Enable driver for TPS65224 PMIC regulators"
+depends on PMIC_TPS65224
+   help
+   This enables implementation of driver-model regulator uclass
+   features for REGULATOR TPS65224 and the family of TPS65224 PMICs.
+   TPS65224 series of PMICs have 4 single phase BUCKs that can also
+   be configured in multi phase modes & 3 LDOs. The driver implements
+   get/set api for value and enable.
+
 config DM_REGULATOR_SCMI
bool "Enable driver for SCMI voltage domain regulators"
depends on DM_REGULATOR
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index d9e0cd5949..d4b9b7233f 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o
 obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o
 obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o
+obj-$(CONFIG_DM_REGULATOR_TPS65224) += tps65224_regulator.o
 obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_ANATOP) += anatop_regulator.o
 obj-$(CONFIG_DM_REGULATOR_TPS65219) += tps65219_regulator.o
diff --git a/drivers/power/regulator/tps65224_regulator.c 
b/drivers/power/regulator/tps65224_regulator.c
new file mode 100644
index 00..2f8c803778
--- /dev/null
+++ b/drivers/power/regulator/tps65224_regulator.c
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023
+ * Texas Instruments Incorporated, 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char tps65224_buck_ctrl[TPS65224_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA};
+static const char tps65224_buck_vout[TPS65224_BUCK_NUM] = {0xE, 0x10, 0x12,
+   0x14};
+static const char tps65224_ldo_ctrl[TPS65224_BUCK_NUM] = {0x1D, 0x1E, 0x1F};
+static const char tps65224_ldo_vout[TPS65224_BUCK_NUM] = {0x23, 0x24, 0x25};
+
+static int tps65224_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+   int ret;
+   unsigned int adr;
+   struct dm_regulator_uclass_plat *uc_pdata;
+
+   uc_pdata = dev_get_uclass_plat(dev);
+   adr = uc_pdata->ctrl_reg;
+
+   ret = pmic_reg_read(dev->parent, adr);
+   if (ret < 0)
+   return ret;
+
+   if (op == PMIC_OP_GET) {
+   ret &= TPS65224_BUCK_MODE_MASK;
+
+   if (ret)
+   *enable = true;
+   else
+   *enable = false;
+
+   return 0;
+   } else if (op == PMIC_OP_SET) {
+   if (*enable)
+   ret |= TPS65224_BUCK_MODE_MASK;
+   else
+   ret &= ~TPS65224_BUCK_MODE_MASK;
+   ret = pmic_reg_write(dev->parent, adr, ret);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int tps65224_buck_volt2val(int idx, int uV)
+{
+   if (uV > TPS65224_BUCK_VOLT_MAX)
+   return -EINVAL;
+
+   if (idx > 0) {
+   if (uV >= 120)
+   return (uV - 120) / 5 + 0x1B;
+   else if (uV >= 50)
+   return (uV - 50) / 25000;
+   else
+   return -EINVAL;
+   }
+
+   if (uV >= 166)
+   return (uV - 166) / 2 + 0xAB;
+   else if (uV >= 110)
+   return (uV - 110) / 1 + 0x73;
+   else if (uV >= 60)
+   return (uV - 60) / 5000 + 0x0F;
+   else if (uV >= 50)
+   return (uV - 50) / 2 + 0x0A;
+   else
+   return -EINVAL;
+}
+
+static int tps65224_buck_val2volt(int idx, int val)
+{
+   if (idx > 0) {
+   if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
+   return -EINVAL;
+   else if (val >= 0x1B)
+ 

[PATCH v1 1/2] driver: power: add support for TPS65224

2023-10-25 Thread Bhargav Raviprakash
Added support for PMIC TPS65224. Includes driver for pmic,
and disabling Watchdog.

Signed-off-by: Bhargav Raviprakash 
---
 drivers/power/pmic/Kconfig|   6 ++
 drivers/power/pmic/Makefile   |   1 +
 drivers/power/pmic/tps65224.c | 141 ++
 include/power/tps65224.h  |  54 +
 4 files changed, 202 insertions(+)
 create mode 100644 drivers/power/pmic/tps65224.c
 create mode 100644 include/power/tps65224.h

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 4a6f0ce093..b06bd31823 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -378,6 +378,12 @@ config PMIC_TPS65941
The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
This driver binds the pmic children.
 
+config PMIC_TPS65224
+   bool "Enable driver for Texas Instruments TPS65224 PMIC"
+   help
+   The TPS65224 is a PMIC containing a bunch of SMPS & LDOs.
+   This driver binds the pmic children.
+
 config PMIC_TPS65219
bool "Enable driver for Texas Instruments TPS65219 PMIC"
depends on DM_PMIC
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 0b3b3d62d0..cec16e57d3 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
 obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
 obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
 obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
+obj-$(CONFIG_PMIC_TPS65224) += tps65224.o
 obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
 
 ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
diff --git a/drivers/power/pmic/tps65224.c b/drivers/power/pmic/tps65224.c
new file mode 100644
index 00..450769de61
--- /dev/null
+++ b/drivers/power/pmic/tps65224.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Texas Instruments Incorporated, 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const struct pmic_child_info pmic_children_info[] = {
+   { .prefix = "ldo", .driver = TPS65224_LDO_DRIVER },
+   { .prefix = "buck", .driver = TPS65224_BUCK_DRIVER },
+   { },
+};
+
+static int tps65224_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
+{
+   if (dm_i2c_write(dev, reg, buff, len)) {
+   pr_err("write error to device: %p register: %#x!\n", dev, reg);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int tps65224_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+   if (dm_i2c_read(dev, reg, buff, len)) {
+   pr_err("read error from device: %p register: %#x!\n", dev, reg);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int tps65224_bind(struct udevice *dev)
+{
+   ofnode regulators_node;
+   int children;
+
+   if (dev->driver_data == TPS65224_WD)
+   return 0;
+
+   regulators_node = dev_read_subnode(dev, "regulators");
+   if (!ofnode_valid(regulators_node)) {
+   debug("%s: %s regulators subnode not found!\n", __func__,
+ dev->name);
+   return -ENXIO;
+   }
+
+   debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
+
+   children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+   if (!children)
+   printf("%s: %s - no child found\n", __func__, dev->name);
+
+   /* Probe all the child devices */
+   return dm_scan_fdt_dev(dev);
+}
+
+static int stop_watchdog(struct udevice *wd_i2c_dev)
+{
+   int ret;
+
+   /* Maintain WD long window */
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_MODE_REG);
+   if (ret < 0) {
+   debug("failed to read i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   ret &= ~TPS65224_WD_PWRHOLD_MASK;
+   ret |= TPS65224_WD_PWRHOLD_MASK;
+   ret = dm_i2c_reg_write(wd_i2c_dev, TPS65224_WD_MODE_REG, ret);
+   if (ret) {
+   debug("%s: %s write WD_PWRHOLD fail!\n", __func__, 
wd_i2c_dev->name);
+   return ret;
+   }
+
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_MODE_REG);
+   if (ret < 0) {
+   debug("failed to read back i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   /* Disable WD */
+   ret = dm_i2c_reg_read(wd_i2c_dev, TPS65224_WD_THR_CFG);
+   if (ret < 0) {
+   debug("failed to read i2c reg (%d)\n", ret);
+   return ret;
+   }
+
+   ret &= ~TPS65224_WD_EN_MASK;
+   ret = dm_i2c_reg_write(wd_i2c_dev, TPS65224_WD_THR_CFG, ret);
+   if (ret) {
+   debug("%s: %s write WD_EN fail!\n", __func__, wd_i2c_dev->name

[PATCH v1 0/2] TPS65224 PMIC driver

2023-10-25 Thread Bhargav Raviprakash
Add support for TPS65224 PMIC in U-boot.
This includes driver for PMIC and regulator.

The driver was tested on Ti's custom AM62A EVM using U-boot's 
pmic list, regulator list, regulator enable, regulator disable and 
regulator value commands. Regulator output voltages were verified.

Logs from running the above commands,
 => pmic list
 | Name | Parent name   | Parent uclass @ seq
 | pmic@48  | i2c@490   | i2c @ 0 | status: 0
 | watchdog@12  | i2c@2000  | i2c @ 1 | status: 0
 => reg list
 | Device  | regulator-name  | Parent
 | buck12  | buck12  | pmic@48
 | buck3   | buck3   | pmic@48
 | buck4   | buck4   | pmic@48
 | ldo1| ldo1| pmic@48
 | ldo2| ldo2| pmic@48
 | ldo3| ldo3| pmic@48
 => regulator dev buck12
 dev: buck12 @ buck12
 => regulator enable
 => regulator value 150
 => regulator disable

Bhargav Raviprakash (2):
  driver: power: add support for TPS65224
  driver: power: regulator: add support for TPS65224 regulator

 drivers/power/pmic/Kconfig   |   6 +
 drivers/power/pmic/Makefile  |   1 +
 drivers/power/pmic/tps65224.c| 141 ++
 drivers/power/regulator/Kconfig  |  10 +
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/tps65224_regulator.c | 472 +++
 include/power/tps65224.h |  56 +++
 7 files changed, 687 insertions(+)
 create mode 100644 drivers/power/pmic/tps65224.c
 create mode 100644 drivers/power/regulator/tps65224_regulator.c
 create mode 100644 include/power/tps65224.h

-- 
2.25.1