Commit 591bfcfc authored by Guenter Roeck's avatar Guenter Roeck

hwmon: (adm1021) Strengthen chip detection for ADM1021, LM84 and MAX1617

On a system with both MAX1617 and JC42 sensors, JC42 sensors can be misdetected
as LM84. Strengthen detection sufficiently enough to avoid this misdetection.
Also improve detection for ADM1021.

Modeled after chip detection code in sensors-detect command.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Tested-by: default avatarJean Delvare <khali@linux-fr.org>
Acked-by: default avatarJean Delvare <khali@linux-fr.org>
parent d683b96b
...@@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client, ...@@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client,
man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
if (man_id < 0 || dev_id < 0)
return -ENODEV;
if (man_id == 0x4d && dev_id == 0x01) if (man_id == 0x4d && dev_id == 0x01)
type_name = "max1617a"; type_name = "max1617a";
else if (man_id == 0x41) { else if (man_id == 0x41) {
if ((dev_id & 0xF0) == 0x30) if ((dev_id & 0xF0) == 0x30)
type_name = "adm1023"; type_name = "adm1023";
else else if ((dev_id & 0xF0) == 0x00)
type_name = "adm1021"; type_name = "adm1021";
else
return -ENODEV;
} else if (man_id == 0x49) } else if (man_id == 0x49)
type_name = "thmc10"; type_name = "thmc10";
else if (man_id == 0x23) else if (man_id == 0x23)
type_name = "gl523sm"; type_name = "gl523sm";
else if (man_id == 0x54) else if (man_id == 0x54)
type_name = "mc1066"; type_name = "mc1066";
/* LM84 Mfr ID in a different place, and it has more unused bits */ else {
else if (conv_rate == 0x00 int lte, rte, lhi, rhi, llo, rlo;
&& (config & 0x7F) == 0x00
&& (status & 0xAB) == 0x00) /* extra checks for LM84 and MAX1617 to avoid misdetections */
type_name = "lm84";
else llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0));
type_name = "max1617"; rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1));
/* fail if any of the additional register reads failed */
if (llo < 0 || rlo < 0)
return -ENODEV;
lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0));
rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1));
lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0));
rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1));
/*
* Fail for negative temperatures and negative high limits.
* This check also catches read errors on the tested registers.
*/
if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0)
return -ENODEV;
/* fail if all registers hold the same value */
if (lte == rte && lte == lhi && lte == rhi && lte == llo
&& lte == rlo)
return -ENODEV;
/*
* LM84 Mfr ID is in a different place,
* and it has more unused bits.
*/
if (conv_rate == 0x00
&& (config & 0x7F) == 0x00
&& (status & 0xAB) == 0x00) {
type_name = "lm84";
} else {
/* fail if low limits are larger than high limits */
if ((s8)llo > lhi || (s8)rlo > rhi)
return -ENODEV;
type_name = "max1617";
}
}
pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n",
type_name, i2c_adapter_id(adapter), client->addr); type_name, i2c_adapter_id(adapter), client->addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment