Commit 5cfaf338 authored by Jean Delvare's avatar Jean Delvare

hwmon: (lm85) Don't bind to Winbond/Nuvoton WPCD377I

The Winbond/Nuvoton WPCD377I is the reduced version of a Super-I/O
which emulates the National Semiconductor LM96000 hardware monitoring
chips, but without the hardware monitoring part. Instead of plain
disabling the emulation, the vendor left the emulated chip visible,
but all monitored values are always zero. This is rather confusing for
the users. So detect this case and refuse to bind to such fake chips.

This fixes lm-sensors ticket #2182:
http://www.lm-sensors.org/ticket/2182Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent afc31875
...@@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, ...@@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
#define LM85_VERSTEP_GENERIC2 0x70 #define LM85_VERSTEP_GENERIC2 0x70
#define LM85_VERSTEP_LM85C 0x60 #define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62 #define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_LM96000_1 0x68
#define LM85_VERSTEP_LM96000_2 0x69
#define LM85_VERSTEP_ADM1027 0x60 #define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62 #define LM85_VERSTEP_ADT7463 0x62
#define LM85_VERSTEP_ADT7463C 0x6A #define LM85_VERSTEP_ADT7463C 0x6A
...@@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client) ...@@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client)
dev_warn(&client->dev, "Device is not ready\n"); dev_warn(&client->dev, "Device is not ready\n");
} }
static int lm85_is_fake(struct i2c_client *client)
{
/*
* Differenciate between real LM96000 and Winbond WPCD377I. The latter
* emulate the former except that it has no hardware monitoring function
* so the readings are always 0.
*/
int i;
u8 in_temp, fan;
for (i = 0; i < 8; i++) {
in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
fan = i2c_smbus_read_byte_data(client, 0x28 + i);
if (in_temp != 0x00 || fan != 0xff)
return 0;
}
return 1;
}
/* Return 0 if detection is successful, -ENODEV otherwise */ /* Return 0 if detection is successful, -ENODEV otherwise */
static int lm85_detect(struct i2c_client *client, int kind, static int lm85_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info) struct i2c_board_info *info)
...@@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind, ...@@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind,
case LM85_VERSTEP_LM85B: case LM85_VERSTEP_LM85B:
kind = lm85b; kind = lm85b;
break; break;
case LM85_VERSTEP_LM96000_1:
case LM85_VERSTEP_LM96000_2:
/* Check for Winbond WPCD377I */
if (lm85_is_fake(client)) {
dev_dbg(&adapter->dev,
"Found Winbond WPCD377I, "
"ignoring\n");
return -ENODEV;
}
break;
} }
} else if (company == LM85_COMPANY_ANALOG_DEV) { } else if (company == LM85_COMPANY_ANALOG_DEV) {
switch (verstep) { switch (verstep) {
......
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