hwmon: (tmp421) Strengthen detect function
authorGuenter Roeck <linux@roeck-us.net>
Tue, 22 Apr 2014 23:13:17 +0000 (16:13 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 4 Aug 2014 14:01:37 +0000 (07:01 -0700)
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>
Documentation/hwmon/tmp421
drivers/hwmon/tmp421.c

index 0cf07f824741d3cda08625623ba157647a0ffe84..d0e77143077f65a08b0f72c68065dc5f0f4b21b7 100644 (file)
@@ -8,11 +8,11 @@ Supported chips:
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
   * Texas Instruments 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
   * Texas Instruments 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
 
 Authors:
index 7bab7a9bedc6699f7a59d9926b913505116e02f6..9438c1bd5d59ea161168e00f6af4cd595d6af979 100644 (file)
@@ -42,6 +42,7 @@ static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
 enum chips { tmp421, tmp422, tmp423 };
 
 /* The TMP421 registers */
+#define TMP421_STATUS_REG                      0x08
 #define TMP421_CONFIG_REG_1                    0x09
 #define TMP421_CONVERSION_RATE_REG             0x0B
 #define TMP421_MANUFACTURER_ID_REG             0xFE
@@ -235,6 +236,7 @@ static int tmp421_detect(struct i2c_client *client,
        enum chips kind;
        struct i2c_adapter *adapter = client->adapter;
        const char *names[] = { "TMP421", "TMP422", "TMP423" };
+       int addr = client->addr;
        u8 reg;
 
        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)
                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);
        switch (reg) {
        case TMP421_DEVICE_ID:
                kind = tmp421;
                break;
        case TMP422_DEVICE_ID:
+               if (addr == 0x2a)
+                       return -ENODEV;
                kind = tmp422;
                break;
        case TMP423_DEVICE_ID:
+               if (addr != 0x4c && addr != 0x4d)
+                       return -ENODEV;
                kind = tmp423;
                break;
        default: