[PATCH v3 05/10] regulator: ab8500: Test dedicated enable bits only
From: Linus Walleij
Date: Mon Sep 14 2026 - 03:55:59 EST
Some regulator control registers have independent enable and low-power
bits. is_enabled() currently tests their combined update mask, so an
off regulator with its low-power bit set is incorrectly reported as
enabled.
Add an optional enable mask and use it for VINTCORE, AB8500 TVOUT,
AB8505 ADC, and AB8505 VAUX5/6. Regulators whose two-bit field encodes
the complete operating state continue to test the full update mask.
References: AB8500 User Manual, UM0836 Rev 3, p. 214;
AB8505 User Manual, DM00046744 Rev 3, pp. 171-172 and 223
Fixes: 65e03ed2d0cd ("regulators: Fixed errors in ab8500 register mapping")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@xxxxxxxxxx>
---
drivers/regulator/ab8500.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 42cb8dfdc7c9..05c6b9c7af0c 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -162,6 +162,7 @@ struct ab8500_shared_mode {
* @update_bank: bank to control on/off
* @update_reg: register to control on/off
* @update_mask: mask to enable/disable and set mode of regulator
+ * @enable_mask: optional mask for an enable bit separate from the mode bit
* @update_val: bits holding the regulator current mode
* @update_val_idle: bits to enable the regulator in idle (low power) mode
* @update_val_normal: bits to enable the regulator in normal (high power) mode
@@ -183,6 +184,7 @@ struct ab8500_regulator_info {
u8 update_bank;
u8 update_reg;
u8 update_mask;
+ u8 enable_mask;
u8 update_val;
u8 update_val_idle;
u8 update_val_normal;
@@ -377,6 +379,7 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
{
int ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 enable_mask;
u8 regval;
if (info == NULL) {
@@ -392,13 +395,15 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
return ret;
}
+ enable_mask = info->enable_mask ? info->enable_mask : info->update_mask;
+
dev_vdbg(rdev_get_dev(rdev),
"%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
" 0x%x\n",
info->desc.name, info->update_bank, info->update_reg,
- info->update_mask, regval);
+ enable_mask, regval);
- if (regval & info->update_mask)
+ if (regval & enable_mask)
return 1;
else
return 0;
@@ -833,6 +838,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x44,
+ .enable_mask = 0x04,
.update_val = 0x44,
.update_val_idle = 0x44,
.update_val_normal = 0x04,
@@ -861,6 +867,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
+ .enable_mask = 0x02,
.update_val = 0x02,
.update_val_idle = 0x82,
.update_val_normal = 0x02,
@@ -1070,6 +1077,7 @@ static struct ab8500_regulator_info
.update_bank = 0x01,
.update_reg = 0x55,
.update_mask = 0x18,
+ .enable_mask = 0x10,
.update_val = 0x10,
.update_val_idle = 0x18,
.update_val_normal = 0x10,
@@ -1092,6 +1100,7 @@ static struct ab8500_regulator_info
.update_bank = 0x01,
.update_reg = 0x56,
.update_mask = 0x18,
+ .enable_mask = 0x10,
.update_val = 0x10,
.update_val_idle = 0x18,
.update_val_normal = 0x10,
@@ -1113,6 +1122,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x44,
+ .enable_mask = 0x04,
.update_val = 0x04,
.update_val_idle = 0x44,
.update_val_normal = 0x04,
@@ -1141,6 +1151,7 @@ static struct ab8500_regulator_info
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
+ .enable_mask = 0x02,
.update_val = 0x02,
.update_val_idle = 0x82,
.update_val_normal = 0x02,
--
2.55.0