summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2014-04-22 19:13:17 -0400
committerGuenter Roeck <linux@roeck-us.net>2014-08-04 10:01:37 -0400
commita63ee9d83b960199ae111ff4e2413fbe328d32fe (patch)
tree392bfc7218b33f57d10ab85d11fada20d29acc51
parente47c39b3a8299e2d84d9e3ca5e591bc5055dd1d8 (diff)
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>
-rw-r--r--Documentation/hwmon/tmp4214
-rw-r--r--drivers/hwmon/tmp421.c14
2 files changed, 16 insertions, 2 deletions
diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421
index 0cf07f824741..d0e77143077f 100644
--- a/Documentation/hwmon/tmp421
+++ b/Documentation/hwmon/tmp421
@@ -8,11 +8,11 @@ Supported chips:
8 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html 8 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
9 * Texas Instruments TMP422 9 * Texas Instruments TMP422
10 Prefix: 'tmp422' 10 Prefix: 'tmp422'
11 Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f 11 Addresses scanned: I2C 0x4c, 0x4d, 0x4e and 0x4f
12 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html 12 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
13 * Texas Instruments TMP423 13 * Texas Instruments TMP423
14 Prefix: 'tmp423' 14 Prefix: 'tmp423'
15 Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f 15 Addresses scanned: I2C 0x4c and 0x4d
16 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html 16 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
17 17
18Authors: 18Authors:
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 7bab7a9bedc6..9438c1bd5d59 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -42,6 +42,7 @@ static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
42enum chips { tmp421, tmp422, tmp423 }; 42enum chips { tmp421, tmp422, tmp423 };
43 43
44/* The TMP421 registers */ 44/* The TMP421 registers */
45#define TMP421_STATUS_REG 0x08
45#define TMP421_CONFIG_REG_1 0x09 46#define TMP421_CONFIG_REG_1 0x09
46#define TMP421_CONVERSION_RATE_REG 0x0B 47#define TMP421_CONVERSION_RATE_REG 0x0B
47#define TMP421_MANUFACTURER_ID_REG 0xFE 48#define TMP421_MANUFACTURER_ID_REG 0xFE
@@ -235,6 +236,7 @@ static int tmp421_detect(struct i2c_client *client,
235 enum chips kind; 236 enum chips kind;
236 struct i2c_adapter *adapter = client->adapter; 237 struct i2c_adapter *adapter = client->adapter;
237 const char *names[] = { "TMP421", "TMP422", "TMP423" }; 238 const char *names[] = { "TMP421", "TMP422", "TMP423" };
239 int addr = client->addr;
238 u8 reg; 240 u8 reg;
239 241
240 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 242 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -244,15 +246,27 @@ static int tmp421_detect(struct i2c_client *client,
244 if (reg != TMP421_MANUFACTURER_ID) 246 if (reg != TMP421_MANUFACTURER_ID)
245 return -ENODEV; 247 return -ENODEV;
246 248
249 reg = i2c_smbus_read_byte_data(client, TMP421_CONVERSION_RATE_REG);
250 if (reg & 0xf8)
251 return -ENODEV;
252
253 reg = i2c_smbus_read_byte_data(client, TMP421_STATUS_REG);
254 if (reg & 0x7f)
255 return -ENODEV;
256
247 reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG); 257 reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
248 switch (reg) { 258 switch (reg) {
249 case TMP421_DEVICE_ID: 259 case TMP421_DEVICE_ID:
250 kind = tmp421; 260 kind = tmp421;
251 break; 261 break;
252 case TMP422_DEVICE_ID: 262 case TMP422_DEVICE_ID:
263 if (addr == 0x2a)
264 return -ENODEV;
253 kind = tmp422; 265 kind = tmp422;
254 break; 266 break;
255 case TMP423_DEVICE_ID: 267 case TMP423_DEVICE_ID:
268 if (addr != 0x4c && addr != 0x4d)
269 return -ENODEV;
256 kind = tmp423; 270 kind = tmp423;
257 break; 271 break;
258 default: 272 default: