mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 06:23:42 -04:00
hwmon: (ads7828) Fix external VREF regulator handling
The driver currently has two issues with the external VREF regulator
handling in ads7828_probe():
1. All errors from devm_regulator_get_optional() are ignored, causing the
driver to incorrectly fall back to internal VREF even for transient
errors like -EPROBE_DEFER or genuine failures like -ENOMEM.
2. The external regulator is never enabled. The driver calls
regulator_get_voltage() without first calling regulator_enable(),
so the VREF pin may remain unpowered if the regulator is not
configured as always-on.
Fix both issues by switching to devm_regulator_get_enable_read_voltage(),
which handles regulator get, enable, and voltage read in one call.
Only -ENODEV (no regulator specified in device tree) should trigger the
fallback to internal VREF. All other errors are propagated to the caller.
Fixes: a8ddfea095 ("hwmon: (ads7828) Accept optional parameters from device tree")
Signed-off-by: Qingshuang Fu <fuqingshuang@kylinos.cn>
Link: https://lore.kernel.org/r/20260805061645.1331652-1-fffsqian@163.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
committed by
Guenter Roeck
parent
36c4d73ce0
commit
fddb5ceaf9
@@ -106,12 +106,11 @@ static int ads7828_probe(struct i2c_client *client)
|
||||
struct ads7828_data *data;
|
||||
struct device *hwmon_dev;
|
||||
unsigned int vref_mv = ADS7828_INT_VREF_MV;
|
||||
unsigned int vref_uv;
|
||||
int vref_uv;
|
||||
bool diff_input = false;
|
||||
bool ext_vref = false;
|
||||
unsigned int regval;
|
||||
enum ads7828_chips chip;
|
||||
struct regulator *reg;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
@@ -125,9 +124,11 @@ static int ads7828_probe(struct i2c_client *client)
|
||||
} else if (dev->of_node) {
|
||||
diff_input = of_property_read_bool(dev->of_node,
|
||||
"ti,differential-input");
|
||||
reg = devm_regulator_get_optional(dev, "vref");
|
||||
if (!IS_ERR(reg)) {
|
||||
vref_uv = regulator_get_voltage(reg);
|
||||
vref_uv = devm_regulator_get_enable_read_voltage(dev, "vref");
|
||||
if (vref_uv < 0) {
|
||||
if (vref_uv != -ENODEV)
|
||||
return vref_uv;
|
||||
} else {
|
||||
vref_mv = DIV_ROUND_CLOSEST(vref_uv, 1000);
|
||||
if (vref_mv < ADS7828_EXT_VREF_MV_MIN ||
|
||||
vref_mv > ADS7828_EXT_VREF_MV_MAX)
|
||||
|
||||
Reference in New Issue
Block a user