]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
hwmon: (lm75) Fix AS6200 and TMP112 setup and alarm handling
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Sat, 2 May 2026 17:32:06 +0000 (19:32 +0200)
committerGuenter Roeck <linux@roeck-us.net>
Thu, 7 May 2026 23:29:05 +0000 (16:29 -0700)
The initialization of the AS6200 has two shortcomings

- The device-add-commit states "Conversion mode: continuous" but the
  the lm75_params structure uses set_mask = 0x94c0. This activates
  single shot mode (bit 15). According to the datasheet "The device
  features a single shot measurement mode if the device is in sleep
  mode (SM=1)". This is quite contradictionary.
- It is the only device that activates polarity active-high (bit 10)

All this is paired with a undefined clear mask bug in function
lm75_write_config() that was introduced with a later refactoring
commit.

[as6200] = {
.config_reg_16bits = true,
.set_mask = 0x94C0,
        -> .clr_mask not defined here
.default_resolution = 12,
...
static inline int lm75_write_config(struct lm75_data *data, u16 set_mask,
    u16 clr_mask)
{
return regmap_update_bits(data->regmap, LM75_REG_CONF,
  clr_mask | LM75_SHUTDOWN, set_mask);
}

regmap_update_bits() requires clr_mask to be a superset of set_mask.
So basically all sensors with "wrong" masks like the AS6200 are not
initialized as intended.

Fix that by

- Change the set_mask to 0xc010 to reflect the current active-low
  setup properly and to drive the sensor in continous mode. This
  takes into account that the config register is little endian and
  the first byte sent to the chip is the LSB.
- Adapt the alarm handling so it can report the alarm correctly
  even if it is high active. This is done by comparing config register
  bit 5 and 10 (translated to 2 and 13).

This commit does not introduce any ABI breakage as the mutliple bugs
effectly drive the AS6200 in standard active-low mode.

Fixes: 4b6358e1fe46 ("hwmon: (lm75) Add AMS AS6200 temperature sensor")
Suggested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://lore.kernel.org/r/20260502173207.3567876-2-markus.stockhausen@gmx.de
[groeck: Update set_mask for as6200 further: As modeled, the upper bits
 contain the conversion rate, so the config register needs to be set to
 0xc010 instead of 0x10c0 to reflect 8 samples/s and 4 consecutive faults.
 Fix the same problem for TMP112.]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/lm75.c

index f1a1e5b888f64ebbe6f32db38d626512404cd381..a1bf4e9813ed8ef4a929b9c636a775c2a6c1da26 100644 (file)
@@ -137,7 +137,7 @@ static const struct lm75_params device_params[] = {
        },
        [as6200] = {
                .config_reg_16bits = true,
-               .set_mask = 0x94C0,     /* 8 sample/s, 4 CF, positive polarity */
+               .set_mask = 0xC010,     /* 8 sample/s, 4 CF */
                .default_resolution = 12,
                .default_sample_time = 125,
                .num_sample_times = 4,
@@ -286,8 +286,8 @@ static const struct lm75_params device_params[] = {
        },
        [tmp112] = {
                .config_reg_16bits = true,
-               .set_mask = 0x60C0,     /* 12-bit mode, 8 samples / second */
-               .clr_mask = 1 << 15,    /* no one-shot mode*/
+               .set_mask = 0xC060,     /* 12-bit mode, 8 samples / second */
+               .clr_mask = 1 << 7,     /* no one-shot mode*/
                .default_resolution = 12,
                .default_sample_time = 125,
                .num_sample_times = 4,
@@ -416,7 +416,7 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
                        switch (data->kind) {
                        case as6200:
                        case tmp112:
-                               *val = (regval >> 13) & 0x1;
+                               *val = !!(regval & BIT(13)) == !!(regval & BIT(2));
                                break;
                        default:
                                return -EINVAL;