aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-03-30 15:46:40 -0400
committerJean Delvare <khali@linux-fr.org>2009-03-30 15:46:40 -0400
commit594592dc6f68356a3b7278eb4d260a50a66f0a06 (patch)
tree0bdb535a8e3bcd0f4ea03fdc86842709e9ea4b50 /drivers/hwmon
parent9202add67454c6a6f9508f41e733edce705dc56e (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')
-rw-r--r--drivers/hwmon/ds1621.c48
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. */
87static int ds1621_read_value(struct i2c_client *client, u8 reg) 87static 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
95static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) 97static 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
103static void ds1621_init_client(struct i2c_client *client) 102static 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 }