diff options
author | Jean Delvare <khali@linux-fr.org> | 2011-11-04 12:00:46 +0100 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2011-11-04 12:00:46 +0100 |
commit | 24d6e2a89a1ff0a035f163a83a2812a3192083b6 (patch) | |
tree | 9cd9206f65ae126d78ab428272ee8da62e41c4a8 /drivers/hwmon/lm73.c | |
parent | 746cdfbf01c0a30d59f6e1b6942d432658d7c7cd (diff) | |
download | kernel-common-24d6e2a89a1ff0a035f163a83a2812a3192083b6.tar.gz kernel-common-24d6e2a89a1ff0a035f163a83a2812a3192083b6.tar.bz2 kernel-common-24d6e2a89a1ff0a035f163a83a2812a3192083b6.zip |
hwmon: (lm73) Make detection less problematic
Word reads can cause trouble with some I2C devices, so do as much
detection as we can using only byte reads, and only use a word read in
the end to confirm the positive match. Also properly handle read
errors.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: Robert Casanova <robertcasanova@nanometrics.ca>
Diffstat (limited to 'drivers/hwmon/lm73.c')
-rw-r--r-- | drivers/hwmon/lm73.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 29b9030d42c3..24be17608fbb 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -150,17 +150,31 @@ static int lm73_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; - u16 id; - u8 ctrl; + int id, ctrl, conf; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; + /* + * Do as much detection as possible with byte reads first, as word + * reads can confuse other devices. + */ + ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL); + if (ctrl < 0 || (ctrl & 0x10)) + return -ENODEV; + + conf = i2c_smbus_read_byte_data(new_client, LM73_REG_CONF); + if (conf < 0 || (conf & 0x0c)) + return -ENODEV; + + id = i2c_smbus_read_byte_data(new_client, LM73_REG_ID); + if (id < 0 || id != (LM73_ID & 0xff)) + return -ENODEV; + /* Check device ID */ id = i2c_smbus_read_word_data(new_client, LM73_REG_ID); - ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL); - if ((id != LM73_ID) || (ctrl & 0x10)) + if (id < 0 || id != LM73_ID) return -ENODEV; strlcpy(info->type, "lm73", I2C_NAME_SIZE); |