aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/lm90.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-22 13:42:54 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-22 13:42:54 -0400
commit4e93d3e8859c834ee18dfd33051d24df8669d0c0 (patch)
tree13f5b39730857257b5040471618e9bcce30ed9cc /drivers/i2c/chips/lm90.c
parenta0cd30fd26a398c0c6e50c6760610d4529f17a84 (diff)
parent0087e5ef577d0d6e664be7ab4be513b6a482e7ec (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6
Diffstat (limited to 'drivers/i2c/chips/lm90.c')
-rw-r--r--drivers/i2c/chips/lm90.c273
1 files changed, 151 insertions, 122 deletions
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
index 9b127a07f56b..a67dcadf7cb0 100644
--- a/drivers/i2c/chips/lm90.c
+++ b/drivers/i2c/chips/lm90.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware 2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring 3 * monitoring
4 * Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * Based on the lm83 driver. The LM90 is a sensor chip made by National 6 * Based on the lm83 driver. The LM90 is a sensor chip made by National
7 * Semiconductor. It reports up to two temperatures (its own plus up to 7 * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -19,7 +19,7 @@
19 * Complete datasheets can be obtained from National's website at: 19 * Complete datasheets can be obtained from National's website at:
20 * http://www.national.com/pf/LM/LM89.html 20 * http://www.national.com/pf/LM/LM89.html
21 * http://www.national.com/pf/LM/LM99.html 21 * http://www.national.com/pf/LM/LM99.html
22 * Note that there is no way to differenciate between both chips. 22 * Note that there is no way to differentiate between both chips.
23 * 23 *
24 * This driver also supports the LM86, another sensor chip made by 24 * This driver also supports the LM86, another sensor chip made by
25 * National Semiconductor. It is exactly similar to the LM90 except it 25 * National Semiconductor. It is exactly similar to the LM90 except it
@@ -39,7 +39,7 @@
39 * chips made by Maxim. These chips are similar to the LM86. Complete 39 * chips made by Maxim. These chips are similar to the LM86. Complete
40 * datasheet can be obtained at Maxim's website at: 40 * datasheet can be obtained at Maxim's website at:
41 * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 41 * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
42 * Note that there is no easy way to differenciate between the three 42 * Note that there is no easy way to differentiate between the three
43 * variants. The extra address and features of the MAX6659 are not 43 * variants. The extra address and features of the MAX6659 are not
44 * supported by this driver. 44 * supported by this driver.
45 * 45 *
@@ -70,13 +70,13 @@
70 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 70 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
71 */ 71 */
72 72
73#include <linux/config.h>
74#include <linux/module.h> 73#include <linux/module.h>
75#include <linux/init.h> 74#include <linux/init.h>
76#include <linux/slab.h> 75#include <linux/slab.h>
77#include <linux/jiffies.h> 76#include <linux/jiffies.h>
78#include <linux/i2c.h> 77#include <linux/i2c.h>
79#include <linux/i2c-sensor.h> 78#include <linux/i2c-sensor.h>
79#include <linux/hwmon-sysfs.h>
80 80
81/* 81/*
82 * Addresses to scan 82 * Addresses to scan
@@ -139,9 +139,9 @@ SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
139/* 139/*
140 * Conversions and various macros 140 * Conversions and various macros
141 * For local temperatures and limits, critical limits and the hysteresis 141 * For local temperatures and limits, critical limits and the hysteresis
142 * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celcius. 142 * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
143 * For remote temperatures and limits, it uses signed 11-bit values with 143 * For remote temperatures and limits, it uses signed 11-bit values with
144 * LSB = 0.125 degree Celcius, left-justified in 16-bit registers. 144 * LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
145 */ 145 */
146 146
147#define TEMP1_FROM_REG(val) ((val) * 1000) 147#define TEMP1_FROM_REG(val) ((val) * 1000)
@@ -206,9 +206,14 @@ struct lm90_data {
206 int kind; 206 int kind;
207 207
208 /* registers values */ 208 /* registers values */
209 s8 temp_input1, temp_low1, temp_high1; /* local */ 209 s8 temp8[5]; /* 0: local input
210 s16 temp_input2, temp_low2, temp_high2; /* remote, combined */ 210 1: local low limit
211 s8 temp_crit1, temp_crit2; 211 2: local high limit
212 3: local critical limit
213 4: remote critical limit */
214 s16 temp11[3]; /* 0: remote input
215 1: remote low limit
216 2: remote high limit */
212 u8 temp_hyst; 217 u8 temp_hyst;
213 u8 alarms; /* bitvector */ 218 u8 alarms; /* bitvector */
214}; 219};
@@ -217,75 +222,88 @@ struct lm90_data {
217 * Sysfs stuff 222 * Sysfs stuff
218 */ 223 */
219 224
220#define show_temp(value, converter) \ 225static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
221static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 226 char *buf)
222{ \ 227{
223 struct lm90_data *data = lm90_update_device(dev); \ 228 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
224 return sprintf(buf, "%d\n", converter(data->value)); \ 229 struct lm90_data *data = lm90_update_device(dev);
230 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index]));
231}
232
233static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
234 const char *buf, size_t count)
235{
236 static const u8 reg[4] = {
237 LM90_REG_W_LOCAL_LOW,
238 LM90_REG_W_LOCAL_HIGH,
239 LM90_REG_W_LOCAL_CRIT,
240 LM90_REG_W_REMOTE_CRIT,
241 };
242
243 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
244 struct i2c_client *client = to_i2c_client(dev);
245 struct lm90_data *data = i2c_get_clientdata(client);
246 long val = simple_strtol(buf, NULL, 10);
247 int nr = attr->index;
248
249 down(&data->update_lock);
250 if (data->kind == adt7461)
251 data->temp8[nr] = TEMP1_TO_REG_ADT7461(val);
252 else
253 data->temp8[nr] = TEMP1_TO_REG(val);
254 i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]);
255 up(&data->update_lock);
256 return count;
225} 257}
226show_temp(temp_input1, TEMP1_FROM_REG); 258
227show_temp(temp_input2, TEMP2_FROM_REG); 259static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
228show_temp(temp_low1, TEMP1_FROM_REG); 260 char *buf)
229show_temp(temp_low2, TEMP2_FROM_REG); 261{
230show_temp(temp_high1, TEMP1_FROM_REG); 262 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
231show_temp(temp_high2, TEMP2_FROM_REG); 263 struct lm90_data *data = lm90_update_device(dev);
232show_temp(temp_crit1, TEMP1_FROM_REG); 264 return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index]));
233show_temp(temp_crit2, TEMP1_FROM_REG);
234
235#define set_temp1(value, reg) \
236static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
237 size_t count) \
238{ \
239 struct i2c_client *client = to_i2c_client(dev); \
240 struct lm90_data *data = i2c_get_clientdata(client); \
241 long val = simple_strtol(buf, NULL, 10); \
242 \
243 down(&data->update_lock); \
244 if (data->kind == adt7461) \
245 data->value = TEMP1_TO_REG_ADT7461(val); \
246 else \
247 data->value = TEMP1_TO_REG(val); \
248 i2c_smbus_write_byte_data(client, reg, data->value); \
249 up(&data->update_lock); \
250 return count; \
251} 265}
252#define set_temp2(value, regh, regl) \ 266
253static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \ 267static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
254 size_t count) \ 268 const char *buf, size_t count)
255{ \ 269{
256 struct i2c_client *client = to_i2c_client(dev); \ 270 static const u8 reg[4] = {
257 struct lm90_data *data = i2c_get_clientdata(client); \ 271 LM90_REG_W_REMOTE_LOWH,
258 long val = simple_strtol(buf, NULL, 10); \ 272 LM90_REG_W_REMOTE_LOWL,
259 \ 273 LM90_REG_W_REMOTE_HIGHH,
260 down(&data->update_lock); \ 274 LM90_REG_W_REMOTE_HIGHL,
261 if (data->kind == adt7461) \ 275 };
262 data->value = TEMP2_TO_REG_ADT7461(val); \ 276
263 else \ 277 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
264 data->value = TEMP2_TO_REG(val); \ 278 struct i2c_client *client = to_i2c_client(dev);
265 i2c_smbus_write_byte_data(client, regh, data->value >> 8); \ 279 struct lm90_data *data = i2c_get_clientdata(client);
266 i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \ 280 long val = simple_strtol(buf, NULL, 10);
267 up(&data->update_lock); \ 281 int nr = attr->index;
268 return count; \ 282
283 down(&data->update_lock);
284 if (data->kind == adt7461)
285 data->temp11[nr] = TEMP2_TO_REG_ADT7461(val);
286 else
287 data->temp11[nr] = TEMP2_TO_REG(val);
288 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
289 data->temp11[nr] >> 8);
290 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
291 data->temp11[nr] & 0xff);
292 up(&data->update_lock);
293 return count;
269} 294}
270set_temp1(temp_low1, LM90_REG_W_LOCAL_LOW); 295
271set_temp2(temp_low2, LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL); 296static ssize_t show_temphyst(struct device *dev, struct device_attribute *devattr,
272set_temp1(temp_high1, LM90_REG_W_LOCAL_HIGH); 297 char *buf)
273set_temp2(temp_high2, LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL); 298{
274set_temp1(temp_crit1, LM90_REG_W_LOCAL_CRIT); 299 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
275set_temp1(temp_crit2, LM90_REG_W_REMOTE_CRIT); 300 struct lm90_data *data = lm90_update_device(dev);
276 301 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])
277#define show_temp_hyst(value, basereg) \ 302 - TEMP1_FROM_REG(data->temp_hyst));
278static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
279{ \
280 struct lm90_data *data = lm90_update_device(dev); \
281 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->basereg) \
282 - TEMP1_FROM_REG(data->temp_hyst)); \
283} 303}
284show_temp_hyst(temp_hyst1, temp_crit1);
285show_temp_hyst(temp_hyst2, temp_crit2);
286 304
287static ssize_t set_temp_hyst1(struct device *dev, struct device_attribute *attr, const char *buf, 305static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
288 size_t count) 306 const char *buf, size_t count)
289{ 307{
290 struct i2c_client *client = to_i2c_client(dev); 308 struct i2c_client *client = to_i2c_client(dev);
291 struct lm90_data *data = i2c_get_clientdata(client); 309 struct lm90_data *data = i2c_get_clientdata(client);
@@ -293,36 +311,37 @@ static ssize_t set_temp_hyst1(struct device *dev, struct device_attribute *attr,
293 long hyst; 311 long hyst;
294 312
295 down(&data->update_lock); 313 down(&data->update_lock);
296 hyst = TEMP1_FROM_REG(data->temp_crit1) - val; 314 hyst = TEMP1_FROM_REG(data->temp8[3]) - val;
297 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, 315 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
298 HYST_TO_REG(hyst)); 316 HYST_TO_REG(hyst));
299 up(&data->update_lock); 317 up(&data->update_lock);
300 return count; 318 return count;
301} 319}
302 320
303static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) 321static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
322 char *buf)
304{ 323{
305 struct lm90_data *data = lm90_update_device(dev); 324 struct lm90_data *data = lm90_update_device(dev);
306 return sprintf(buf, "%d\n", data->alarms); 325 return sprintf(buf, "%d\n", data->alarms);
307} 326}
308 327
309static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); 328static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
310static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); 329static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
311static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_low1, 330static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
312 set_temp_low1); 331 set_temp8, 1);
313static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2, 332static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
314 set_temp_low2); 333 set_temp11, 1);
315static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_high1, 334static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
316 set_temp_high1); 335 set_temp8, 2);
317static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2, 336static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
318 set_temp_high2); 337 set_temp11, 2);
319static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit1, 338static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8,
320 set_temp_crit1); 339 set_temp8, 3);
321static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2, 340static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
322 set_temp_crit2); 341 set_temp8, 4);
323static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst1, 342static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
324 set_temp_hyst1); 343 set_temphyst, 3);
325static DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_hyst2, NULL); 344static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
326static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 345static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
327 346
328/* 347/*
@@ -481,16 +500,26 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
481 lm90_init_client(new_client); 500 lm90_init_client(new_client);
482 501
483 /* Register sysfs hooks */ 502 /* Register sysfs hooks */
484 device_create_file(&new_client->dev, &dev_attr_temp1_input); 503 device_create_file(&new_client->dev,
485 device_create_file(&new_client->dev, &dev_attr_temp2_input); 504 &sensor_dev_attr_temp1_input.dev_attr);
486 device_create_file(&new_client->dev, &dev_attr_temp1_min); 505 device_create_file(&new_client->dev,
487 device_create_file(&new_client->dev, &dev_attr_temp2_min); 506 &sensor_dev_attr_temp2_input.dev_attr);
488 device_create_file(&new_client->dev, &dev_attr_temp1_max); 507 device_create_file(&new_client->dev,
489 device_create_file(&new_client->dev, &dev_attr_temp2_max); 508 &sensor_dev_attr_temp1_min.dev_attr);
490 device_create_file(&new_client->dev, &dev_attr_temp1_crit); 509 device_create_file(&new_client->dev,
491 device_create_file(&new_client->dev, &dev_attr_temp2_crit); 510 &sensor_dev_attr_temp2_min.dev_attr);
492 device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); 511 device_create_file(&new_client->dev,
493 device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst); 512 &sensor_dev_attr_temp1_max.dev_attr);
513 device_create_file(&new_client->dev,
514 &sensor_dev_attr_temp2_max.dev_attr);
515 device_create_file(&new_client->dev,
516 &sensor_dev_attr_temp1_crit.dev_attr);
517 device_create_file(&new_client->dev,
518 &sensor_dev_attr_temp2_crit.dev_attr);
519 device_create_file(&new_client->dev,
520 &sensor_dev_attr_temp1_crit_hyst.dev_attr);
521 device_create_file(&new_client->dev,
522 &sensor_dev_attr_temp2_crit_hyst.dev_attr);
494 device_create_file(&new_client->dev, &dev_attr_alarms); 523 device_create_file(&new_client->dev, &dev_attr_alarms);
495 524
496 return 0; 525 return 0;
@@ -541,16 +570,16 @@ static struct lm90_data *lm90_update_device(struct device *dev)
541 u8 oldh, newh; 570 u8 oldh, newh;
542 571
543 dev_dbg(&client->dev, "Updating lm90 data.\n"); 572 dev_dbg(&client->dev, "Updating lm90 data.\n");
544 data->temp_input1 = i2c_smbus_read_byte_data(client, 573 data->temp8[0] = i2c_smbus_read_byte_data(client,
545 LM90_REG_R_LOCAL_TEMP); 574 LM90_REG_R_LOCAL_TEMP);
546 data->temp_high1 = i2c_smbus_read_byte_data(client, 575 data->temp8[1] = i2c_smbus_read_byte_data(client,
547 LM90_REG_R_LOCAL_HIGH); 576 LM90_REG_R_LOCAL_LOW);
548 data->temp_low1 = i2c_smbus_read_byte_data(client, 577 data->temp8[2] = i2c_smbus_read_byte_data(client,
549 LM90_REG_R_LOCAL_LOW); 578 LM90_REG_R_LOCAL_HIGH);
550 data->temp_crit1 = i2c_smbus_read_byte_data(client, 579 data->temp8[3] = i2c_smbus_read_byte_data(client,
551 LM90_REG_R_LOCAL_CRIT); 580 LM90_REG_R_LOCAL_CRIT);
552 data->temp_crit2 = i2c_smbus_read_byte_data(client, 581 data->temp8[4] = i2c_smbus_read_byte_data(client,
553 LM90_REG_R_REMOTE_CRIT); 582 LM90_REG_R_REMOTE_CRIT);
554 data->temp_hyst = i2c_smbus_read_byte_data(client, 583 data->temp_hyst = i2c_smbus_read_byte_data(client,
555 LM90_REG_R_TCRIT_HYST); 584 LM90_REG_R_TCRIT_HYST);
556 585
@@ -570,13 +599,13 @@ static struct lm90_data *lm90_update_device(struct device *dev)
570 */ 599 */
571 oldh = i2c_smbus_read_byte_data(client, 600 oldh = i2c_smbus_read_byte_data(client,
572 LM90_REG_R_REMOTE_TEMPH); 601 LM90_REG_R_REMOTE_TEMPH);
573 data->temp_input2 = i2c_smbus_read_byte_data(client, 602 data->temp11[0] = i2c_smbus_read_byte_data(client,
574 LM90_REG_R_REMOTE_TEMPL); 603 LM90_REG_R_REMOTE_TEMPL);
575 newh = i2c_smbus_read_byte_data(client, 604 newh = i2c_smbus_read_byte_data(client,
576 LM90_REG_R_REMOTE_TEMPH); 605 LM90_REG_R_REMOTE_TEMPH);
577 if (newh != oldh) { 606 if (newh != oldh) {
578 data->temp_input2 = i2c_smbus_read_byte_data(client, 607 data->temp11[0] = i2c_smbus_read_byte_data(client,
579 LM90_REG_R_REMOTE_TEMPL); 608 LM90_REG_R_REMOTE_TEMPL);
580#ifdef DEBUG 609#ifdef DEBUG
581 oldh = i2c_smbus_read_byte_data(client, 610 oldh = i2c_smbus_read_byte_data(client,
582 LM90_REG_R_REMOTE_TEMPH); 611 LM90_REG_R_REMOTE_TEMPH);
@@ -586,16 +615,16 @@ static struct lm90_data *lm90_update_device(struct device *dev)
586 "wrong.\n"); 615 "wrong.\n");
587#endif 616#endif
588 } 617 }
589 data->temp_input2 |= (newh << 8); 618 data->temp11[0] |= (newh << 8);
590 619
591 data->temp_high2 = (i2c_smbus_read_byte_data(client, 620 data->temp11[1] = (i2c_smbus_read_byte_data(client,
621 LM90_REG_R_REMOTE_LOWH) << 8) +
622 i2c_smbus_read_byte_data(client,
623 LM90_REG_R_REMOTE_LOWL);
624 data->temp11[2] = (i2c_smbus_read_byte_data(client,
592 LM90_REG_R_REMOTE_HIGHH) << 8) + 625 LM90_REG_R_REMOTE_HIGHH) << 8) +
593 i2c_smbus_read_byte_data(client, 626 i2c_smbus_read_byte_data(client,
594 LM90_REG_R_REMOTE_HIGHL); 627 LM90_REG_R_REMOTE_HIGHL);
595 data->temp_low2 = (i2c_smbus_read_byte_data(client,
596 LM90_REG_R_REMOTE_LOWH) << 8) +
597 i2c_smbus_read_byte_data(client,
598 LM90_REG_R_REMOTE_LOWL);
599 data->alarms = i2c_smbus_read_byte_data(client, 628 data->alarms = i2c_smbus_read_byte_data(client,
600 LM90_REG_R_STATUS); 629 LM90_REG_R_STATUS);
601 630