aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNate Case <ncase@xes-inc.com>2008-10-17 11:51:10 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-10-17 11:51:10 -0400
commit23b2d4778ad33ee6bfe60439fb73c16580f204f2 (patch)
tree9122f72ca2c06558b6e1f176e277393c85dda52d /drivers
parentcea50fe2fdea36174aa24b58c69c4eb9770e7c49 (diff)
hwmon: (lm90) Support ADT7461 in extended mode
Support ADT7461 in extended temperature range mode, which will change the range of readings from 0..127 to -64..191 degC. Adjust the register conversion functions accordingly. Signed-off-by: Nate Case <ncase@xes-inc.com> Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Martyn Welch <martyn.welch@gefanuc.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig7
-rw-r--r--drivers/hwmon/lm90.c120
2 files changed, 95 insertions, 32 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ebacc0af40fe..96701e099e81 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -510,11 +510,8 @@ config SENSORS_LM90
510 depends on I2C 510 depends on I2C
511 help 511 help
512 If you say yes here you get support for National Semiconductor LM90, 512 If you say yes here you get support for National Semiconductor LM90,
513 LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657, 513 LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim
514 MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips. 514 MAX6657, MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips.
515
516 The Analog Devices ADT7461 sensor chip is also supported, but only
517 if found in ADM1032 compatibility mode.
518 515
519 This driver can also be built as a module. If so, the module 516 This driver can also be built as a module. If so, the module
520 will be called lm90. 517 will be called lm90.
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index b2d9b3f0946d..fe5d860fc838 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -37,11 +37,10 @@
37 * chips. The MAX6680 and MAX6681 only differ in the pinout so they can 37 * chips. The MAX6680 and MAX6681 only differ in the pinout so they can
38 * be treated identically. 38 * be treated identically.
39 * 39 *
40 * This driver also supports the ADT7461 chip from Analog Devices but 40 * This driver also supports the ADT7461 chip from Analog Devices.
41 * only in its "compatability mode". If an ADT7461 chip is found but 41 * It's supported in both compatibility and extended mode. It is mostly
42 * is configured in non-compatible mode (where its temperature 42 * compatible with LM90 except for a data format difference for the
43 * register values are decoded differently) it is ignored by this 43 * temperature value registers.
44 * driver.
45 * 44 *
46 * Since the LM90 was the first chipset supported by this driver, most 45 * Since the LM90 was the first chipset supported by this driver, most
47 * comments will refer to this chipset, but are actually general and 46 * comments will refer to this chipset, but are actually general and
@@ -138,6 +137,11 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
138#define MAX6657_REG_R_LOCAL_TEMPL 0x11 137#define MAX6657_REG_R_LOCAL_TEMPL 0x11
139 138
140/* 139/*
140 * Device flags
141 */
142#define LM90_FLAG_ADT7461_EXT 0x01 /* ADT7461 extended mode */
143
144/*
141 * Functions declaration 145 * Functions declaration
142 */ 146 */
143 147
@@ -191,6 +195,7 @@ struct lm90_data {
191 char valid; /* zero until following fields are valid */ 195 char valid; /* zero until following fields are valid */
192 unsigned long last_updated; /* in jiffies */ 196 unsigned long last_updated; /* in jiffies */
193 int kind; 197 int kind;
198 int flags;
194 199
195 /* registers values */ 200 /* registers values */
196 s8 temp8[4]; /* 0: local low limit 201 s8 temp8[4]; /* 0: local low limit
@@ -256,26 +261,61 @@ static u8 hyst_to_reg(long val)
256} 261}
257 262
258/* 263/*
259 * ADT7461 is almost identical to LM90 except that attempts to write 264 * ADT7461 in compatibility mode is almost identical to LM90 except that
260 * values that are outside the range 0 < temp < 127 are treated as 265 * attempts to write values that are outside the range 0 < temp < 127 are
261 * the boundary value. 266 * treated as the boundary value.
267 *
268 * ADT7461 in "extended mode" operation uses unsigned integers offset by
269 * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC.
262 */ 270 */
263static u8 temp1_to_reg_adt7461(long val) 271static inline int temp1_from_reg_adt7461(struct lm90_data *data, u8 val)
264{ 272{
265 if (val <= 0) 273 if (data->flags & LM90_FLAG_ADT7461_EXT)
266 return 0; 274 return (val - 64) * 1000;
267 if (val >= 127000) 275 else
268 return 127; 276 return temp1_from_reg(val);
269 return (val + 500) / 1000;
270} 277}
271 278
272static u16 temp2_to_reg_adt7461(long val) 279static inline int temp2_from_reg_adt7461(struct lm90_data *data, u16 val)
273{ 280{
274 if (val <= 0) 281 if (data->flags & LM90_FLAG_ADT7461_EXT)
275 return 0; 282 return (val - 0x4000) / 64 * 250;
276 if (val >= 127750) 283 else
277 return 0x7FC0; 284 return temp2_from_reg(val);
278 return (val + 125) / 250 * 64; 285}
286
287static u8 temp1_to_reg_adt7461(struct lm90_data *data, long val)
288{
289 if (data->flags & LM90_FLAG_ADT7461_EXT) {
290 if (val <= -64000)
291 return 0;
292 if (val >= 191000)
293 return 0xFF;
294 return (val + 500 + 64000) / 1000;
295 } else {
296 if (val <= 0)
297 return 0;
298 if (val >= 127000)
299 return 127;
300 return (val + 500) / 1000;
301 }
302}
303
304static u16 temp2_to_reg_adt7461(struct lm90_data *data, long val)
305{
306 if (data->flags & LM90_FLAG_ADT7461_EXT) {
307 if (val <= -64000)
308 return 0;
309 if (val >= 191750)
310 return 0xFFC0;
311 return (val + 64000 + 125) / 250 * 64;
312 } else {
313 if (val <= 0)
314 return 0;
315 if (val >= 127750)
316 return 0x7FC0;
317 return (val + 125) / 250 * 64;
318 }
279} 319}
280 320
281/* 321/*
@@ -287,7 +327,14 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
287{ 327{
288 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 328 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
289 struct lm90_data *data = lm90_update_device(dev); 329 struct lm90_data *data = lm90_update_device(dev);
290 return sprintf(buf, "%d\n", temp1_from_reg(data->temp8[attr->index])); 330 int temp;
331
332 if (data->kind == adt7461)
333 temp = temp1_from_reg_adt7461(data, data->temp8[attr->index]);
334 else
335 temp = temp1_from_reg(data->temp8[attr->index]);
336
337 return sprintf(buf, "%d\n", temp);
291} 338}
292 339
293static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, 340static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
@@ -308,7 +355,7 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
308 355
309 mutex_lock(&data->update_lock); 356 mutex_lock(&data->update_lock);
310 if (data->kind == adt7461) 357 if (data->kind == adt7461)
311 data->temp8[nr] = temp1_to_reg_adt7461(val); 358 data->temp8[nr] = temp1_to_reg_adt7461(data, val);
312 else 359 else
313 data->temp8[nr] = temp1_to_reg(val); 360 data->temp8[nr] = temp1_to_reg(val);
314 i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); 361 i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]);
@@ -321,7 +368,14 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
321{ 368{
322 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 369 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
323 struct lm90_data *data = lm90_update_device(dev); 370 struct lm90_data *data = lm90_update_device(dev);
324 return sprintf(buf, "%d\n", temp2_from_reg(data->temp11[attr->index])); 371 int temp;
372
373 if (data->kind == adt7461)
374 temp = temp2_from_reg_adt7461(data, data->temp11[attr->index]);
375 else
376 temp = temp2_from_reg(data->temp11[attr->index]);
377
378 return sprintf(buf, "%d\n", temp);
325} 379}
326 380
327static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, 381static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -344,7 +398,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
344 398
345 mutex_lock(&data->update_lock); 399 mutex_lock(&data->update_lock);
346 if (data->kind == adt7461) 400 if (data->kind == adt7461)
347 data->temp11[nr] = temp2_to_reg_adt7461(val); 401 data->temp11[nr] = temp2_to_reg_adt7461(data, val);
348 else if (data->kind == max6657 || data->kind == max6680) 402 else if (data->kind == max6657 || data->kind == max6680)
349 data->temp11[nr] = temp1_to_reg(val) << 8; 403 data->temp11[nr] = temp1_to_reg(val) << 8;
350 else 404 else
@@ -364,8 +418,14 @@ static ssize_t show_temphyst(struct device *dev, struct device_attribute *devatt
364{ 418{
365 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 419 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
366 struct lm90_data *data = lm90_update_device(dev); 420 struct lm90_data *data = lm90_update_device(dev);
367 return sprintf(buf, "%d\n", temp1_from_reg(data->temp8[attr->index]) 421 int temp;
368 - temp1_from_reg(data->temp_hyst)); 422
423 if (data->kind == adt7461)
424 temp = temp1_from_reg_adt7461(data, data->temp8[attr->index]);
425 else
426 temp = temp1_from_reg(data->temp8[attr->index]);
427
428 return sprintf(buf, "%d\n", temp - temp1_from_reg(data->temp_hyst));
369} 429}
370 430
371static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, 431static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
@@ -598,7 +658,7 @@ static int lm90_detect(struct i2c_client *new_client, int kind,
598 kind = adm1032; 658 kind = adm1032;
599 } else 659 } else
600 if (chip_id == 0x51 /* ADT7461 */ 660 if (chip_id == 0x51 /* ADT7461 */
601 && (reg_config1 & 0x1F) == 0x00 /* check compat mode */ 661 && (reg_config1 & 0x1B) == 0x00
602 && reg_convrate <= 0x0A) { 662 && reg_convrate <= 0x0A) {
603 kind = adt7461; 663 kind = adt7461;
604 } 664 }
@@ -737,6 +797,12 @@ static void lm90_init_client(struct i2c_client *client)
737 } 797 }
738 config_orig = config; 798 config_orig = config;
739 799
800 /* Check Temperature Range Select */
801 if (data->kind == adt7461) {
802 if (config & 0x04)
803 data->flags |= LM90_FLAG_ADT7461_EXT;
804 }
805
740 /* 806 /*
741 * Put MAX6680/MAX8881 into extended resolution (bit 0x10, 807 * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
742 * 0.125 degree resolution) and range (0x08, extend range 808 * 0.125 degree resolution) and range (0x08, extend range