diff options
| author | Jean Delvare <khali@linux-fr.org> | 2009-03-30 15:46:40 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@linux-fr.org> | 2009-03-30 15:46:40 -0400 |
| commit | 594592dc6f68356a3b7278eb4d260a50a66f0a06 (patch) | |
| tree | 0bdb535a8e3bcd0f4ea03fdc86842709e9ea4b50 | |
| parent | 9202add67454c6a6f9508f41e733edce705dc56e (diff) | |
hwmon: (ds1621) Clean up register access
Fix a few oddities in how the ds1621 driver accesses the registers:
* We don't need a wrapper to access the configuration register.
* Check for error before calling swab16. Error checking isn't
complete yet, but that's a start.
* Device-specific read functions should never be called during
detection, as by definition we don't know what device we are talking
to at that point.
* Likewise, don't assume that register reads succeed during detection.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Aurelien Jarno <aurelien@aurel32.net>
| -rw-r--r-- | drivers/hwmon/ds1621.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index e688798e115f..fe160c54b959 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
| @@ -81,28 +81,27 @@ struct ds1621_data { | |||
| 81 | u8 conf; /* Register encoding, combined */ | 81 | u8 conf; /* Register encoding, combined */ |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | /* All registers are word-sized, except for the configuration register. | 84 | /* Temperature registers are word-sized. |
| 85 | DS1621 uses a high-byte first convention, which is exactly opposite to | 85 | DS1621 uses a high-byte first convention, which is exactly opposite to |
| 86 | the SMBus standard. */ | 86 | the SMBus standard. */ |
| 87 | static int ds1621_read_value(struct i2c_client *client, u8 reg) | 87 | static int ds1621_read_temp(struct i2c_client *client, u8 reg) |
| 88 | { | 88 | { |
| 89 | if (reg == DS1621_REG_CONF) | 89 | int ret; |
| 90 | return i2c_smbus_read_byte_data(client, reg); | 90 | |
| 91 | else | 91 | ret = i2c_smbus_read_word_data(client, reg); |
| 92 | return swab16(i2c_smbus_read_word_data(client, reg)); | 92 | if (ret < 0) |
| 93 | return ret; | ||
| 94 | return swab16(ret); | ||
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) | 97 | static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value) |
| 96 | { | 98 | { |
| 97 | if (reg == DS1621_REG_CONF) | 99 | return i2c_smbus_write_word_data(client, reg, swab16(value)); |
| 98 | return i2c_smbus_write_byte_data(client, reg, value); | ||
| 99 | else | ||
| 100 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | ||
| 101 | } | 100 | } |
| 102 | 101 | ||
| 103 | static void ds1621_init_client(struct i2c_client *client) | 102 | static void ds1621_init_client(struct i2c_client *client) |
| 104 | { | 103 | { |
| 105 | int reg = ds1621_read_value(client, DS1621_REG_CONF); | 104 | int reg = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); |
| 106 | /* switch to continuous conversion mode */ | 105 | /* switch to continuous conversion mode */ |
| 107 | reg &= ~ DS1621_REG_CONFIG_1SHOT; | 106 | reg &= ~ DS1621_REG_CONFIG_1SHOT; |
| 108 | 107 | ||
| @@ -112,7 +111,7 @@ static void ds1621_init_client(struct i2c_client *client) | |||
| 112 | else if (polarity == 1) | 111 | else if (polarity == 1) |
| 113 | reg |= DS1621_REG_CONFIG_POLARITY; | 112 | reg |= DS1621_REG_CONFIG_POLARITY; |
| 114 | 113 | ||
| 115 | ds1621_write_value(client, DS1621_REG_CONF, reg); | 114 | i2c_smbus_write_byte_data(client, DS1621_REG_CONF, reg); |
| 116 | 115 | ||
| 117 | /* start conversion */ | 116 | /* start conversion */ |
| 118 | i2c_smbus_write_byte(client, DS1621_COM_START); | 117 | i2c_smbus_write_byte(client, DS1621_COM_START); |
| @@ -132,11 +131,11 @@ static struct ds1621_data *ds1621_update_client(struct device *dev) | |||
| 132 | 131 | ||
| 133 | dev_dbg(&client->dev, "Starting ds1621 update\n"); | 132 | dev_dbg(&client->dev, "Starting ds1621 update\n"); |
| 134 | 133 | ||
| 135 | data->conf = ds1621_read_value(client, DS1621_REG_CONF); | 134 | data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); |
| 136 | 135 | ||
| 137 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) | 136 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) |
| 138 | data->temp[i] = ds1621_read_value(client, | 137 | data->temp[i] = ds1621_read_temp(client, |
| 139 | DS1621_REG_TEMP[i]); | 138 | DS1621_REG_TEMP[i]); |
| 140 | 139 | ||
| 141 | /* reset alarms if necessary */ | 140 | /* reset alarms if necessary */ |
| 142 | new_conf = data->conf; | 141 | new_conf = data->conf; |
| @@ -145,8 +144,8 @@ static struct ds1621_data *ds1621_update_client(struct device *dev) | |||
| 145 | if (data->temp[0] < data->temp[2]) /* input < max */ | 144 | if (data->temp[0] < data->temp[2]) /* input < max */ |
| 146 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; | 145 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; |
| 147 | if (data->conf != new_conf) | 146 | if (data->conf != new_conf) |
| 148 | ds1621_write_value(client, DS1621_REG_CONF, | 147 | i2c_smbus_write_byte_data(client, DS1621_REG_CONF, |
| 149 | new_conf); | 148 | new_conf); |
| 150 | 149 | ||
| 151 | data->last_updated = jiffies; | 150 | data->last_updated = jiffies; |
| 152 | data->valid = 1; | 151 | data->valid = 1; |
| @@ -176,8 +175,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
| 176 | 175 | ||
| 177 | mutex_lock(&data->update_lock); | 176 | mutex_lock(&data->update_lock); |
| 178 | data->temp[attr->index] = val; | 177 | data->temp[attr->index] = val; |
| 179 | ds1621_write_value(client, DS1621_REG_TEMP[attr->index], | 178 | ds1621_write_temp(client, DS1621_REG_TEMP[attr->index], |
| 180 | data->temp[attr->index]); | 179 | data->temp[attr->index]); |
| 181 | mutex_unlock(&data->update_lock); | 180 | mutex_unlock(&data->update_lock); |
| 182 | return count; | 181 | return count; |
| 183 | } | 182 | } |
| @@ -239,13 +238,14 @@ static int ds1621_detect(struct i2c_client *client, int kind, | |||
| 239 | /* The NVB bit should be low if no EEPROM write has been | 238 | /* The NVB bit should be low if no EEPROM write has been |
| 240 | requested during the latest 10ms, which is highly | 239 | requested during the latest 10ms, which is highly |
| 241 | improbable in our case. */ | 240 | improbable in our case. */ |
| 242 | conf = ds1621_read_value(client, DS1621_REG_CONF); | 241 | conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); |
| 243 | if (conf & DS1621_REG_CONFIG_NVB) | 242 | if (conf < 0 || conf & DS1621_REG_CONFIG_NVB) |
| 244 | return -ENODEV; | 243 | return -ENODEV; |
| 245 | /* The 7 lowest bits of a temperature should always be 0. */ | 244 | /* The 7 lowest bits of a temperature should always be 0. */ |
| 246 | for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) { | 245 | for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) { |
| 247 | temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); | 246 | temp = i2c_smbus_read_word_data(client, |
| 248 | if (temp & 0x007f) | 247 | DS1621_REG_TEMP[i]); |
| 248 | if (temp < 0 || (temp & 0x7f00)) | ||
| 249 | return -ENODEV; | 249 | return -ENODEV; |
| 250 | } | 250 | } |
| 251 | } | 251 | } |
