Skip to content

Commit 4317eca

Browse files
committed
regulator: mp8859: Support status and error readback
The MP8859 can report if it is in regulation and detect over temperature conditions, report this information via the relevant regulator API calls. Tested-by: Markus Reichl <m.reichl@fivetechno.de> Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://msgid.link/r/20240225-regulator-mp8859-v1-6-68ee2c839ded@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent d7217c9 commit 4317eca

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

drivers/regulator/mp8859.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
#define MP8859_DISCHG_EN_MASK 0x10
4040
#define MP8859_MODE_MASK 0x08
4141

42+
#define MP8859_PG_MASK 0x80
43+
#define MP8859_OTP_MASK 0x40
44+
#define MP8859_OTW_MASK 0x20
45+
#define MP8859_CC_CV_MASK 0x10
46+
4247
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
4348
{
4449
int ret;
@@ -112,6 +117,58 @@ static int mp8859_set_mode(struct regulator_dev *rdev, unsigned int mode)
112117
MP8859_MODE_MASK, val);
113118
}
114119

120+
static int mp8859_get_status(struct regulator_dev *rdev)
121+
{
122+
unsigned int val;
123+
int ret;
124+
125+
/* Output status is only meaingful when enabled */
126+
ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val);
127+
if (ret != 0)
128+
return ret;
129+
if (!(val & MP8859_ENABLE_MASK))
130+
return REGULATOR_STATUS_UNDEFINED;
131+
132+
ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &val);
133+
if (ret != 0)
134+
return ret;
135+
136+
if (val & MP8859_PG_MASK)
137+
return REGULATOR_STATUS_ON;
138+
else
139+
return REGULATOR_STATUS_ERROR;
140+
}
141+
142+
static int mp8859_get_error_flags(struct regulator_dev *rdev,
143+
unsigned int *flags)
144+
{
145+
unsigned int status, enabled;
146+
int ret;
147+
148+
*flags = 0;
149+
150+
/* Output status is only meaingful when enabled */
151+
ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &enabled);
152+
if (ret != 0)
153+
return ret;
154+
enabled &= MP8859_ENABLE_MASK;
155+
156+
ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &status);
157+
if (ret != 0)
158+
return ret;
159+
160+
if (enabled && !(status & MP8859_PG_MASK))
161+
status |= REGULATOR_ERROR_FAIL;
162+
if (status & MP8859_OTP_MASK)
163+
status |= REGULATOR_ERROR_OVER_TEMP;
164+
if (status & MP8859_OTW_MASK)
165+
status |= REGULATOR_ERROR_OVER_TEMP_WARN;
166+
if (status & MP8859_CC_CV_MASK)
167+
status |= REGULATOR_ERROR_OVER_CURRENT;
168+
169+
return 0;
170+
}
171+
115172
static const struct linear_range mp8859_dcdc_ranges[] = {
116173
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
117174
};
@@ -169,6 +226,8 @@ static const struct regulator_ops mp8859_ops = {
169226
.set_mode = mp8859_set_mode,
170227
.get_mode = mp8859_get_mode,
171228
.set_active_discharge = regulator_set_active_discharge_regmap,
229+
.get_status = mp8859_get_status,
230+
.get_error_flags = mp8859_get_error_flags,
172231
};
173232

174233
static const struct regulator_desc mp8859_regulators[] = {

0 commit comments

Comments
 (0)