Browse Source

hwmon: (tmp421) Strengthen detect function

Not all supported chips support the entire I2C address range.
Only accept specific chips at the addresses supported by that chip.
Check for invalid values in conversion rate and status registers.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Guenter Roeck 11 năm trước cách đây
mục cha
commit
a63ee9d83b
2 tập tin đã thay đổi với 16 bổ sung2 xóa
  1. 2 2
      Documentation/hwmon/tmp421
  2. 14 0
      drivers/hwmon/tmp421.c

+ 2 - 2
Documentation/hwmon/tmp421

@@ -8,11 +8,11 @@ Supported chips:
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
   * Texas Instruments TMP422
   * Texas Instruments TMP422
     Prefix: 'tmp422'
     Prefix: 'tmp422'
-    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Addresses scanned: I2C 0x4c, 0x4d, 0x4e and 0x4f
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
   * Texas Instruments TMP423
   * Texas Instruments TMP423
     Prefix: 'tmp423'
     Prefix: 'tmp423'
-    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Addresses scanned: I2C 0x4c and 0x4d
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
 
 
 Authors:
 Authors:

+ 14 - 0
drivers/hwmon/tmp421.c

@@ -42,6 +42,7 @@ static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
 enum chips { tmp421, tmp422, tmp423 };
 enum chips { tmp421, tmp422, tmp423 };
 
 
 /* The TMP421 registers */
 /* The TMP421 registers */
+#define TMP421_STATUS_REG			0x08
 #define TMP421_CONFIG_REG_1			0x09
 #define TMP421_CONFIG_REG_1			0x09
 #define TMP421_CONVERSION_RATE_REG		0x0B
 #define TMP421_CONVERSION_RATE_REG		0x0B
 #define TMP421_MANUFACTURER_ID_REG		0xFE
 #define TMP421_MANUFACTURER_ID_REG		0xFE
@@ -235,6 +236,7 @@ static int tmp421_detect(struct i2c_client *client,
 	enum chips kind;
 	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
 	const char *names[] = { "TMP421", "TMP422", "TMP423" };
 	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+	int addr = client->addr;
 	u8 reg;
 	u8 reg;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -244,15 +246,27 @@ static int tmp421_detect(struct i2c_client *client,
 	if (reg != TMP421_MANUFACTURER_ID)
 	if (reg != TMP421_MANUFACTURER_ID)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	reg = i2c_smbus_read_byte_data(client, TMP421_CONVERSION_RATE_REG);
+	if (reg & 0xf8)
+		return -ENODEV;
+
+	reg = i2c_smbus_read_byte_data(client, TMP421_STATUS_REG);
+	if (reg & 0x7f)
+		return -ENODEV;
+
 	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
 	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
 	switch (reg) {
 	switch (reg) {
 	case TMP421_DEVICE_ID:
 	case TMP421_DEVICE_ID:
 		kind = tmp421;
 		kind = tmp421;
 		break;
 		break;
 	case TMP422_DEVICE_ID:
 	case TMP422_DEVICE_ID:
+		if (addr == 0x2a)
+			return -ENODEV;
 		kind = tmp422;
 		kind = tmp422;
 		break;
 		break;
 	case TMP423_DEVICE_ID:
 	case TMP423_DEVICE_ID:
+		if (addr != 0x4c && addr != 0x4d)
+			return -ENODEV;
 		kind = tmp423;
 		kind = tmp423;
 		break;
 		break;
 	default:
 	default: