TMP461 does not support 16-bit registers. Use two 8-bit accesses to read and write temperature values and limits for this chip. Fixes: 24333ac26d01 ("hwmon: (tmp401) use smb word operations instead of 2 smb byte operations") Reported-by: David T. Wilson <david.wilson@xxxxxxxx> Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> --- drivers/hwmon/tmp401.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 9dc210b55e69..78d50a9d26d7 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -69,6 +69,14 @@ static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { { 0, 0x11 }, /* offset */ }; +static const u8 TMP461_TEMP_LSB[5][2] = { + { 0x15, 0x10 }, /* temp */ + { 0, 0x14 }, /* low limit (local n/a) */ + { 0, 0x13 }, /* high limit (local n/a) */ + { 0, 0 }, /* therm (crit) limit (n/a) */ + { 0, 0x12 }, /* offset (local n/a) */ +}; + static const u8 TMP432_TEMP_MSB_READ[4][3] = { { 0x00, 0x01, 0x23 }, /* temp */ { 0x06, 0x08, 0x16 }, /* low limit */ @@ -190,6 +198,19 @@ static int tmp401_update_device_reg16(struct i2c_client *client, TMP401_TEMP_MSB_READ[j][i]; if (j == 3) { /* crit is msb only */ val = i2c_smbus_read_byte_data(client, regaddr); + } else if (data->kind == tmp461) { + /* TMP461 does not support 16-bit registers */ + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] = val << 8; + regaddr = TMP461_TEMP_LSB[j][i]; + if (regaddr) { + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] |= val; + } } else { val = i2c_smbus_read_word_swapped(client, regaddr); @@ -343,6 +364,12 @@ static ssize_t temp_store(struct device *dev, : TMP401_TEMP_MSB_WRITE[nr][index]; if (nr == 3) { /* crit is msb only */ i2c_smbus_write_byte_data(client, regaddr, reg >> 8); + } else if (data->kind == tmp461) { + /* TMP461 does not support 16-bit registers */ + i2c_smbus_write_byte_data(client, regaddr, reg >> 8); + regaddr = TMP461_TEMP_LSB[nr][index]; + if (regaddr) + i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); } else { /* Hardware expects big endian data --> use _swapped */ i2c_smbus_write_word_swapped(client, regaddr, reg); -- 2.33.0