diff options
| author | Peng Fan <[email protected]> | 2026-04-18 20:37:34 +0800 |
|---|---|---|
| committer | Peng Fan <[email protected]> | 2026-05-06 10:20:30 +0800 |
| commit | e015bc1b8d3d9974494581eec1321e59ffe2b355 (patch) | |
| tree | 67eeaa676f6900714b9bbfbf074e757cf406df1c | |
| parent | b7b7aa741f9dd37a25cf44f3a2771ec9bfd497dc (diff) | |
power: regulator: pfuze100: support non-independent mode
Some BUCKs could work in single/dual phase mode, not in independent
mode. In single/dual phase mode, registers of both regulators,
must be identically set. So configure mode and value for both BUCKs.
CONF registers are not touched, leave them as default OTP settings.
PFUZE100/200 SW3A/B, could work in single/dual phase mode, so introduce
a new macro by adding a pointer to the SW3B descriptor.
Signed-off-by: Peng Fan <[email protected]>
| -rw-r--r-- | drivers/power/regulator/pfuze100.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/power/regulator/pfuze100.c b/drivers/power/regulator/pfuze100.c index ed69e6e14c3..77c82a00b65 100644 --- a/drivers/power/regulator/pfuze100.c +++ b/drivers/power/regulator/pfuze100.c @@ -33,6 +33,8 @@ struct pfuze100_high_volt_desc { * @voltage: Current voltage for REGULATOR_TYPE_FIXED type regulator. * @high_volt_mask: Low or High Output voltage mode mask * @high_volt_desc: High Output voltage description + * @b: Some regulators could work together to provide one output when working + * in single phase or dual phase mode. */ struct pfuze100_regulator_desc { char *name; @@ -47,6 +49,7 @@ struct pfuze100_regulator_desc { unsigned int voltage; unsigned int high_volt_mask; struct pfuze100_high_volt_desc *high_volt_desc; + struct pfuze100_regulator_desc *b; }; /** @@ -79,6 +82,21 @@ struct pfuze100_regulator_plat { .high_volt_mask = (mask), \ } +#define PFUZE100_SWAB_REG(_name, base, step, min, volt_desc, mask, desc) \ + { \ + .name = #_name, \ + .type = REGULATOR_TYPE_BUCK, \ + .uV_step = (step), \ + .min_uV = (min), \ + .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ + .vsel_mask = 0x3F, \ + .stby_reg = (base) + PFUZE100_STBY_OFFSET, \ + .stby_mask = 0x3F, \ + .high_volt_desc = (volt_desc), \ + .high_volt_mask = (mask), \ + .b = (desc), \ + } + #define PFUZE100_SWB_REG(_name, base, mask, step, voltages) \ { \ .name = #_name, \ @@ -184,6 +202,8 @@ static struct pfuze100_regulator_desc pfuze100_regulators[] = { PFUZE100_SW_REG(sw1c, PFUZE100_SW1CVOL, 25000, 300000, NULL, 0), PFUZE100_SW_REG(sw2, PFUZE100_SW2VOL, 25000, 400000, &high_desc, BIT(6)), PFUZE100_SW_REG(sw3a, PFUZE100_SW3AVOL, 25000, 400000, &high_desc, BIT(6)), + PFUZE100_SWAB_REG(sw3ab, PFUZE100_SW3AVOL, 25000, 400000, &high_desc, BIT(6), + &pfuze100_regulators[5]), PFUZE100_SW_REG(sw3b, PFUZE100_SW3BVOL, 25000, 400000, &high_desc, BIT(6)), PFUZE100_SW_REG(sw4, PFUZE100_SW4VOL, 25000, 400000, &high_desc, BIT(6)), PFUZE100_SWB_REG(swbst, PFUZE100_SWBSTCON1, 0x3, 50000, pfuze100_swbst), @@ -202,6 +222,8 @@ static struct pfuze100_regulator_desc pfuze200_regulators[] = { PFUZE100_SW_REG(sw1ab, PFUZE100_SW1ABVOL, 25000, 300000, NULL, 0), PFUZE100_SW_REG(sw2, PFUZE100_SW2VOL, 25000, 400000, &high_desc, BIT(6)), PFUZE100_SW_REG(sw3a, PFUZE100_SW3AVOL, 25000, 400000, &high_desc, BIT(6)), + PFUZE100_SWAB_REG(sw3ab, PFUZE100_SW3AVOL, 25000, 400000, &high_desc, BIT(6), + &pfuze200_regulators[4]), PFUZE100_SW_REG(sw3b, PFUZE100_SW3BVOL, 25000, 400000, &high_desc, BIT(6)), PFUZE100_SWB_REG(swbst, PFUZE100_SWBSTCON1, 0x3, 50000, pfuze100_swbst), PFUZE100_SNVS_REG(vsnvs, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), @@ -380,6 +402,16 @@ static int pfuze100_regulator_mode(struct udevice *dev, int op, int *opmode) desc->vsel_reg + PFUZE100_MODE_OFFSET, SW_MODE_MASK, *opmode << SW_MODE_SHIFT); + if (val) + return val; + + if (desc->b) { + desc = desc->b; + val = pmic_clrsetbits(dev->parent, + desc->vsel_reg + PFUZE100_MODE_OFFSET, + SW_MODE_MASK, + *opmode << SW_MODE_SHIFT); + } } else if (desc->type == REGULATOR_TYPE_LDO) { val = pmic_clrsetbits(dev->parent, desc->vsel_reg, @@ -458,7 +490,7 @@ static int pfuze100_regulator_enable(struct udevice *dev, int op, bool *enable) static int pfuze100_regulator_val(struct udevice *dev, int op, int *uV) { - int i; + int i, ret; int val, min_uV, uV_step; struct pfuze100_regulator_plat *plat = dev_get_plat(dev); struct pfuze100_regulator_desc *desc = plat->desc; @@ -526,9 +558,18 @@ static int pfuze100_regulator_val(struct udevice *dev, int op, int *uV) uV_step = desc->uV_step; } - return pmic_clrsetbits(dev->parent, desc->vsel_reg, - desc->vsel_mask, - (*uV - min_uV) / uV_step); + ret = pmic_clrsetbits(dev->parent, desc->vsel_reg, + desc->vsel_mask, (*uV - min_uV) / uV_step); + if (ret) + return ret; + + if (desc->b) { + desc = desc->b; + ret = pmic_clrsetbits(dev->parent, desc->vsel_reg, + desc->vsel_mask, (*uV - min_uV) / uV_step); + if (ret) + return ret; + } } return 0; |
