diff options
| author | Eugene Shalygin <eugene.shalygin@gmail.com> | 2026-07-11 14:26:44 +0200 |
|---|---|---|
| committer | Guenter Roeck <linux@roeck-us.net> | 2026-08-10 08:59:41 -0700 |
| commit | 71a6c1950fa573e5b27de319e371fa94f6572006 (patch) | |
| tree | 767b39bae4e5cdc9e58744bd5aac684246a722c9 | |
| parent | 90639003c0826393f21c65fbbcafaa18510bbfdb (diff) | |
hwmon: (asus-ec-sensors) detect unconnected physical sensors
When there is no physical sensor connected to the motherboard
socket,reading EC register returns one of the special values
(-62, -60, -40). Test for them and return -ENODATA to hwmon.
Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
Link: https://lore.kernel.org/r/20260711122937.594989-2-eugene.shalygin@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
| -rw-r--r-- | drivers/hwmon/asus-ec-sensors.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index 4c69c7f3ca3f..d386f056dc55 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -185,6 +185,20 @@ enum ec_sensors { #define SENSOR_TEMP_SENSOR_EXTRA_2 BIT(ec_sensor_temp_sensor_extra_2) #define SENSOR_TEMP_SENSOR_EXTRA_3 BIT(ec_sensor_temp_sensor_extra_3) +/* + * The values for temperature sensor readings without physical sensors connected. + * The value varies across generations and is seemingly defined by the EC chip + * used in the given board. + */ +static const s32 temperature_blank_values[] = {-62, -60, -40}; + +static const s32 environment_temp_sensors = + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_T_SENSOR_ALT1 | + SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT | + SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT | + SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | + SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3; + enum board_family { family_unknown, family_amd_400_series, @@ -988,6 +1002,7 @@ static const struct dmi_system_id dmi_table[] = { }; struct ec_sensor { + /* this is ec_sensors enum value */ unsigned int info_index; s32 cached_value; }; @@ -1080,6 +1095,12 @@ get_sensor_info(const struct ec_sensors_data *state, int index) return state->sensors_info + state->sensors[index].info_index; } +static enum ec_sensors +get_ec_sensor_type(const struct ec_sensors_data *state, int index) +{ + return state->sensors[index].info_index; +} + static int find_ec_sensor_index(const struct ec_sensors_data *ec, enum hwmon_sensor_types type, int channel) { @@ -1323,6 +1344,17 @@ static int get_cached_value_or_update(const struct device *dev, return 0; } +static bool is_blank_temperature_value(s32 value) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(temperature_blank_values); ++i) { + if (value == temperature_blank_values[i]) + return true; + } + return false; +} + /* * Now follow the functions that implement the hwmon interface */ @@ -1330,6 +1362,8 @@ static int get_cached_value_or_update(const struct device *dev, static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { + const struct ec_sensor_info *sensor_info; + enum ec_sensors ec_sensor; int ret; s32 value = 0; @@ -1341,12 +1375,19 @@ static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, } ret = get_cached_value_or_update(dev, sidx, state, &value); - if (!ret) { - *val = scale_sensor_value(value, - get_sensor_info(state, sidx)->type); + if (ret) + return ret; + + sensor_info = get_sensor_info(state, sidx); + if (sensor_info->type == hwmon_temp) { + ec_sensor = get_ec_sensor_type(state, sidx); + if ((environment_temp_sensors & BIT(ec_sensor)) && + is_blank_temperature_value(value)) + return -ENODATA; } + *val = scale_sensor_value(value, sensor_info->type); - return ret; + return 0; } static int asus_ec_hwmon_read_string(struct device *dev, |
