[PATCH 4/6] power: regulator: s2mps11: declaratively get/set regulator mode
    Kaustabh Chakraborty 
    kauschluss at disroot.org
       
    Fri Oct 17 17:28:19 CEST 2025
    
    
  
The functions s2mps11_{buck,ldo}_mode use the s2mps11_{buck,ldo}_modes
arrays directly in order to extract the mode of a certain register.
This approach does not allow similar devices of other variants (which
may support a different set of modes) to work with the same driver.
Instead of using these arrays hardcoded, extract them from the device's
uclass platform data. Now the responsibility of setting these arrays
properly is done by functions s2mps11_{buck,ldo}_probe, by implementing
a switch-case block which can support modes of multiple variants if and
when added.
Signed-off-by: Kaustabh Chakraborty <kauschluss at disroot.org>
---
 drivers/power/regulator/s2mps11_regulator.c | 132 +++++++++++++---------------
 1 file changed, 59 insertions(+), 73 deletions(-)
diff --git a/drivers/power/regulator/s2mps11_regulator.c b/drivers/power/regulator/s2mps11_regulator.c
index db981df53ae4b6297c63cb8be0f285805307c230..17a0a4d7ce676db7d11aa39e58a68d6f8c3f1a0a 100644
--- a/drivers/power/regulator/s2mps11_regulator.c
+++ b/drivers/power/regulator/s2mps11_regulator.c
@@ -204,10 +204,11 @@ static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
 
 static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
 {
+	struct dm_regulator_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
 	const struct sec_regulator_desc *buck_desc;
 	unsigned int addr, mode;
 	unsigned char val;
-	int num_bucks, buck, ret;
+	int num_bucks, buck, ret, i;
 
 	switch (s2mps11_get_variant(dev)) {
 	case VARIANT_S2MPS11:
@@ -233,42 +234,29 @@ static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
 
 	if (op == PMIC_OP_GET) {
 		val &= buck_desc[buck].mode_mask;
-		switch (val) {
-		case S2MPS11_BUCK_MODE_OFF:
-			*opmode = OP_OFF;
-			break;
-		case S2MPS11_BUCK_MODE_STANDBY:
-			*opmode = OP_STANDBY;
-			break;
-		case S2MPS11_BUCK_MODE_ON:
-			*opmode = OP_ON;
-			break;
-		default:
-			return -EINVAL;
+		for (i = 0; i < uc_pdata->mode_count; i++) {
+			if (uc_pdata->mode[i].register_value != val)
+				continue;
+
+			*opmode = uc_pdata->mode[i].id;
+			return 0;
 		}
-		return 0;
-	}
 
-	switch (*opmode) {
-	case OP_OFF:
-		mode = S2MPS11_BUCK_MODE_OFF;
-		break;
-	case OP_STANDBY:
-		mode = S2MPS11_BUCK_MODE_STANDBY;
-		break;
-	case OP_ON:
-		mode = S2MPS11_BUCK_MODE_ON;
-		break;
-	default:
-		pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
 		return -EINVAL;
 	}
 
-	val &= ~buck_desc[buck].mode_mask;
-	val |= mode;
-	ret = pmic_write(dev->parent, addr, &val, 1);
+	for (i = 0; i < uc_pdata->mode_count; i++) {
+		if (uc_pdata->mode[i].id != *opmode)
+			continue;
 
-	return ret;
+		mode = uc_pdata->mode[i].register_value;
+		val &= ~buck_desc[buck].mode_mask;
+		val |= mode;
+		return pmic_write(dev->parent, addr, &val, 1);
+	}
+
+	pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
+	return -EINVAL;
 }
 
 static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable)
@@ -357,10 +345,17 @@ static int s2mps11_buck_probe(struct udevice *dev)
 	struct dm_regulator_uclass_plat *uc_pdata;
 
 	uc_pdata = dev_get_uclass_plat(dev);
-
 	uc_pdata->type = REGULATOR_TYPE_BUCK;
-	uc_pdata->mode = s2mps11_buck_modes;
-	uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
+
+	switch (s2mps11_get_variant(dev)) {
+	case VARIANT_S2MPS11:
+		uc_pdata->mode = s2mps11_buck_modes;
+		uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
+		break;
+	default:
+		pr_err("Unknown device type\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -434,10 +429,11 @@ static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
 
 static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
 {
+	struct dm_regulator_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
 	const struct sec_regulator_desc *ldo_desc;
 	unsigned int addr, mode;
 	unsigned char val;
-	int num_ldos, ldo, ret;
+	int num_ldos, ldo, ret, i;
 
 	switch (s2mps11_get_variant(dev)) {
 	case VARIANT_S2MPS11:
@@ -463,48 +459,30 @@ static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
 
 	if (op == PMIC_OP_GET) {
 		val &= ldo_desc[ldo].mode_mask;
-		switch (val) {
-		case S2MPS11_LDO_MODE_OFF:
-			*opmode = OP_OFF;
-			break;
-		case S2MPS11_LDO_MODE_STANDBY:
-			*opmode = OP_STANDBY;
-			break;
-		case S2MPS11_LDO_MODE_STANDBY_LPM:
-			*opmode = OP_STANDBY_LPM;
-			break;
-		case S2MPS11_LDO_MODE_ON:
-			*opmode = OP_ON;
-			break;
-		default:
-			return -EINVAL;
+
+		for (i = 0; i < uc_pdata->mode_count; i++) {
+			if (uc_pdata->mode[i].register_value != val)
+				continue;
+
+			*opmode = uc_pdata->mode[i].id;
+			return 0;
 		}
-		return 0;
-	}
 
-	switch (*opmode) {
-	case OP_OFF:
-		mode = S2MPS11_LDO_MODE_OFF;
-		break;
-	case OP_STANDBY:
-		mode = S2MPS11_LDO_MODE_STANDBY;
-		break;
-	case OP_STANDBY_LPM:
-		mode = S2MPS11_LDO_MODE_STANDBY_LPM;
-		break;
-	case OP_ON:
-		mode = S2MPS11_LDO_MODE_ON;
-		break;
-	default:
-		pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
 		return -EINVAL;
 	}
 
-	val &= ~ldo_desc[ldo].mode_mask;
-	val |= mode;
-	ret = pmic_write(dev->parent, addr, &val, 1);
+	for (i = 0; i < uc_pdata->mode_count; i++) {
+		if (uc_pdata->mode[i].id != *opmode)
+			continue;
 
-	return ret;
+		mode = uc_pdata->mode[i].register_value;
+		val &= ~ldo_desc[ldo].mode_mask;
+		val |= mode;
+		return pmic_write(dev->parent, addr, &val, 1);
+	}
+
+	pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
+	return -EINVAL;
 }
 
 static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
@@ -602,8 +580,16 @@ static int s2mps11_ldo_probe(struct udevice *dev)
 
 	uc_pdata = dev_get_uclass_plat(dev);
 	uc_pdata->type = REGULATOR_TYPE_LDO;
-	uc_pdata->mode = s2mps11_ldo_modes;
-	uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
+
+	switch (s2mps11_get_variant(dev)) {
+	case VARIANT_S2MPS11:
+		uc_pdata->mode = s2mps11_ldo_modes;
+		uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
+		break;
+	default:
+		pr_err("Unknown device type\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
-- 
2.51.0
    
    
More information about the U-Boot
mailing list