diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-04 18:53:16 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-04 18:53:16 +0400 |
commit | 46e85f5f1c2a1d106c1ec0fa2a06280276b8e052 (patch) | |
tree | 6b894b2c2c13fe70f986b03b32c9ca2a6d36a053 /drivers/hwmon/lm73.c | |
parent | b2409fb6a49d1f633a8fc488e48043da7d3fd6a7 (diff) | |
parent | eff7687d473c31cba3876c13e97eebc708eb8582 (diff) | |
download | linux-46e85f5f1c2a1d106c1ec0fa2a06280276b8e052.tar.xz |
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
hwmon: (w83627ehf) Add support for the W83627UHG
hwmon: (w83627ehf) Clean up probe function
hwmon: (w83627ehf) Properly report PECI and AMD-SI sensor types
hwmon: Use i2c_smbus_{read,write}_word_swapped
hwmon: (smsc47b397) Fix checkpatch errors
hwmon: (lm90) Make code more readable
hwmon: (lm90) Fix warnings
hwmon: (ibmaem) Avoid repeated memory allocations
hwmon: (ibmaem) Make instance initializations independent
hwmon: (ibmaem) Fix error paths
hwmon: (lm73) Make detection less problematic
hwmon: Avoid building drivers for powerpc that read/write ISA addresses
Diffstat (limited to 'drivers/hwmon/lm73.c')
-rw-r--r-- | drivers/hwmon/lm73.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 29b9030d42c3..9e64d96620d3 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -34,7 +34,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, #define LM73_REG_CTRL 0x04 #define LM73_REG_ID 0x07 -#define LM73_ID 0x9001 /* or 0x190 after a swab16() */ +#define LM73_ID 0x9001 /* 0x0190, byte-swapped */ #define DRVNAME "lm73" #define LM73_TEMP_MIN (-40) #define LM73_TEMP_MAX 150 @@ -57,7 +57,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, /* Write value */ value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4), (LM73_TEMP_MAX*4)) << 5; - i2c_smbus_write_word_data(client, attr->index, swab16(value)); + i2c_smbus_write_word_swapped(client, attr->index, value); return count; } @@ -68,8 +68,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, struct i2c_client *client = to_i2c_client(dev); /* use integer division instead of equivalent right shift to guarantee arithmetic shift and preserve the sign */ - int temp = ((s16) (swab16(i2c_smbus_read_word_data(client, - attr->index)))*250) / 32; + int temp = ((s16) (i2c_smbus_read_word_swapped(client, + attr->index))*250) / 32; return sprintf(buf, "%d\n", temp); } @@ -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); |