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 /drivers/hwmon/ds1621.c | |
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>
Diffstat (limited to 'drivers/hwmon/ds1621.c')
-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 | } |