diff options
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r-- | drivers/hwmon/lm90.c | 128 |
1 files changed, 83 insertions, 45 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d96e403d59e0..b2d9b3f0946d 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -138,40 +138,6 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | |||
138 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 | 138 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Conversions and various macros | ||
142 | * For local temperatures and limits, critical limits and the hysteresis | ||
143 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. | ||
144 | * For remote temperatures and limits, it uses signed 11-bit values with | ||
145 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. | ||
146 | */ | ||
147 | |||
148 | #define TEMP1_FROM_REG(val) ((val) * 1000) | ||
149 | #define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \ | ||
150 | (val) >= 127000 ? 127 : \ | ||
151 | (val) < 0 ? ((val) - 500) / 1000 : \ | ||
152 | ((val) + 500) / 1000) | ||
153 | #define TEMP2_FROM_REG(val) ((val) / 32 * 125) | ||
154 | #define TEMP2_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ | ||
155 | (val) >= 127875 ? 0x7FE0 : \ | ||
156 | (val) < 0 ? ((val) - 62) / 125 * 32 : \ | ||
157 | ((val) + 62) / 125 * 32) | ||
158 | #define HYST_TO_REG(val) ((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \ | ||
159 | ((val) + 500) / 1000) | ||
160 | |||
161 | /* | ||
162 | * ADT7461 is almost identical to LM90 except that attempts to write | ||
163 | * values that are outside the range 0 < temp < 127 are treated as | ||
164 | * the boundary value. | ||
165 | */ | ||
166 | |||
167 | #define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \ | ||
168 | (val) >= 127000 ? 127 : \ | ||
169 | ((val) + 500) / 1000) | ||
170 | #define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \ | ||
171 | (val) >= 127750 ? 0x7FC0 : \ | ||
172 | ((val) + 125) / 250 * 64) | ||
173 | |||
174 | /* | ||
175 | * Functions declaration | 141 | * Functions declaration |
176 | */ | 142 | */ |
177 | 143 | ||
@@ -241,6 +207,78 @@ struct lm90_data { | |||
241 | }; | 207 | }; |
242 | 208 | ||
243 | /* | 209 | /* |
210 | * Conversions | ||
211 | * For local temperatures and limits, critical limits and the hysteresis | ||
212 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. | ||
213 | * For remote temperatures and limits, it uses signed 11-bit values with | ||
214 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. | ||
215 | */ | ||
216 | |||
217 | static inline int temp1_from_reg(s8 val) | ||
218 | { | ||
219 | return val * 1000; | ||
220 | } | ||
221 | |||
222 | static inline int temp2_from_reg(s16 val) | ||
223 | { | ||
224 | return val / 32 * 125; | ||
225 | } | ||
226 | |||
227 | static s8 temp1_to_reg(long val) | ||
228 | { | ||
229 | if (val <= -128000) | ||
230 | return -128; | ||
231 | if (val >= 127000) | ||
232 | return 127; | ||
233 | if (val < 0) | ||
234 | return (val - 500) / 1000; | ||
235 | return (val + 500) / 1000; | ||
236 | } | ||
237 | |||
238 | static s16 temp2_to_reg(long val) | ||
239 | { | ||
240 | if (val <= -128000) | ||
241 | return 0x8000; | ||
242 | if (val >= 127875) | ||
243 | return 0x7FE0; | ||
244 | if (val < 0) | ||
245 | return (val - 62) / 125 * 32; | ||
246 | return (val + 62) / 125 * 32; | ||
247 | } | ||
248 | |||
249 | static u8 hyst_to_reg(long val) | ||
250 | { | ||
251 | if (val <= 0) | ||
252 | return 0; | ||
253 | if (val >= 30500) | ||
254 | return 31; | ||
255 | return (val + 500) / 1000; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * ADT7461 is almost identical to LM90 except that attempts to write | ||
260 | * values that are outside the range 0 < temp < 127 are treated as | ||
261 | * the boundary value. | ||
262 | */ | ||
263 | static u8 temp1_to_reg_adt7461(long val) | ||
264 | { | ||
265 | if (val <= 0) | ||
266 | return 0; | ||
267 | if (val >= 127000) | ||
268 | return 127; | ||
269 | return (val + 500) / 1000; | ||
270 | } | ||
271 | |||
272 | static u16 temp2_to_reg_adt7461(long val) | ||
273 | { | ||
274 | if (val <= 0) | ||
275 | return 0; | ||
276 | if (val >= 127750) | ||
277 | return 0x7FC0; | ||
278 | return (val + 125) / 250 * 64; | ||
279 | } | ||
280 | |||
281 | /* | ||
244 | * Sysfs stuff | 282 | * Sysfs stuff |
245 | */ | 283 | */ |
246 | 284 | ||
@@ -249,7 +287,7 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | |||
249 | { | 287 | { |
250 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 288 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
251 | struct lm90_data *data = lm90_update_device(dev); | 289 | struct lm90_data *data = lm90_update_device(dev); |
252 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])); | 290 | return sprintf(buf, "%d\n", temp1_from_reg(data->temp8[attr->index])); |
253 | } | 291 | } |
254 | 292 | ||
255 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | 293 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, |
@@ -270,9 +308,9 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
270 | 308 | ||
271 | mutex_lock(&data->update_lock); | 309 | mutex_lock(&data->update_lock); |
272 | if (data->kind == adt7461) | 310 | if (data->kind == adt7461) |
273 | data->temp8[nr] = TEMP1_TO_REG_ADT7461(val); | 311 | data->temp8[nr] = temp1_to_reg_adt7461(val); |
274 | else | 312 | else |
275 | data->temp8[nr] = TEMP1_TO_REG(val); | 313 | data->temp8[nr] = temp1_to_reg(val); |
276 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); | 314 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); |
277 | mutex_unlock(&data->update_lock); | 315 | mutex_unlock(&data->update_lock); |
278 | return count; | 316 | return count; |
@@ -283,7 +321,7 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
283 | { | 321 | { |
284 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 322 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
285 | struct lm90_data *data = lm90_update_device(dev); | 323 | struct lm90_data *data = lm90_update_device(dev); |
286 | return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index])); | 324 | return sprintf(buf, "%d\n", temp2_from_reg(data->temp11[attr->index])); |
287 | } | 325 | } |
288 | 326 | ||
289 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 327 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
@@ -306,11 +344,11 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
306 | 344 | ||
307 | mutex_lock(&data->update_lock); | 345 | mutex_lock(&data->update_lock); |
308 | if (data->kind == adt7461) | 346 | if (data->kind == adt7461) |
309 | data->temp11[nr] = TEMP2_TO_REG_ADT7461(val); | 347 | data->temp11[nr] = temp2_to_reg_adt7461(val); |
310 | else if (data->kind == max6657 || data->kind == max6680) | 348 | else if (data->kind == max6657 || data->kind == max6680) |
311 | data->temp11[nr] = TEMP1_TO_REG(val) << 8; | 349 | data->temp11[nr] = temp1_to_reg(val) << 8; |
312 | else | 350 | else |
313 | data->temp11[nr] = TEMP2_TO_REG(val); | 351 | data->temp11[nr] = temp2_to_reg(val); |
314 | 352 | ||
315 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], | 353 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], |
316 | data->temp11[nr] >> 8); | 354 | data->temp11[nr] >> 8); |
@@ -326,8 +364,8 @@ static ssize_t show_temphyst(struct device *dev, struct device_attribute *devatt | |||
326 | { | 364 | { |
327 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 365 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
328 | struct lm90_data *data = lm90_update_device(dev); | 366 | struct lm90_data *data = lm90_update_device(dev); |
329 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index]) | 367 | return sprintf(buf, "%d\n", temp1_from_reg(data->temp8[attr->index]) |
330 | - TEMP1_FROM_REG(data->temp_hyst)); | 368 | - temp1_from_reg(data->temp_hyst)); |
331 | } | 369 | } |
332 | 370 | ||
333 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | 371 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, |
@@ -339,9 +377,9 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | |||
339 | long hyst; | 377 | long hyst; |
340 | 378 | ||
341 | mutex_lock(&data->update_lock); | 379 | mutex_lock(&data->update_lock); |
342 | hyst = TEMP1_FROM_REG(data->temp8[2]) - val; | 380 | hyst = temp1_from_reg(data->temp8[2]) - val; |
343 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | 381 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, |
344 | HYST_TO_REG(hyst)); | 382 | hyst_to_reg(hyst)); |
345 | mutex_unlock(&data->update_lock); | 383 | mutex_unlock(&data->update_lock); |
346 | return count; | 384 | return count; |
347 | } | 385 | } |