aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/lm90.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips/lm90.c')
-rw-r--r--drivers/i2c/chips/lm90.c264
1 files changed, 147 insertions, 117 deletions
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
index 42795b43c8b9..ebd99dfbf9c7 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
@@ -76,6 +76,7 @@
76#include <linux/jiffies.h> 76#include <linux/jiffies.h>
77#include <linux/i2c.h> 77#include <linux/i2c.h>
78#include <linux/i2c-sensor.h> 78#include <linux/i2c-sensor.h>
79#include <linux/i2c-sysfs.h>
79 80
80/* 81/*
81 * Addresses to scan 82 * Addresses to scan
@@ -205,9 +206,14 @@ struct lm90_data {
205 int kind; 206 int kind;
206 207
207 /* registers values */ 208 /* registers values */
208 s8 temp_input1, temp_low1, temp_high1; /* local */ 209 s8 temp8[5]; /* 0: local input
209 s16 temp_input2, temp_low2, temp_high2; /* remote, combined */ 210 1: local low limit
210 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 */
211 u8 temp_hyst; 217 u8 temp_hyst;
212 u8 alarms; /* bitvector */ 218 u8 alarms; /* bitvector */
213}; 219};
@@ -216,75 +222,88 @@ struct lm90_data {
216 * Sysfs stuff 222 * Sysfs stuff
217 */ 223 */
218 224
219#define show_temp(value, converter) \ 225static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
220static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 226 char *buf)
221{ \ 227{
222 struct lm90_data *data = lm90_update_device(dev); \ 228 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
223 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;
224} 257}
225show_temp(temp_input1, TEMP1_FROM_REG); 258
226show_temp(temp_input2, TEMP2_FROM_REG); 259static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
227show_temp(temp_low1, TEMP1_FROM_REG); 260 char *buf)
228show_temp(temp_low2, TEMP2_FROM_REG); 261{
229show_temp(temp_high1, TEMP1_FROM_REG); 262 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
230show_temp(temp_high2, TEMP2_FROM_REG); 263 struct lm90_data *data = lm90_update_device(dev);
231show_temp(temp_crit1, TEMP1_FROM_REG); 264 return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index]));
232show_temp(temp_crit2, TEMP1_FROM_REG);
233
234#define set_temp1(value, reg) \
235static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
236 size_t count) \
237{ \
238 struct i2c_client *client = to_i2c_client(dev); \
239 struct lm90_data *data = i2c_get_clientdata(client); \
240 long val = simple_strtol(buf, NULL, 10); \
241 \
242 down(&data->update_lock); \
243 if (data->kind == adt7461) \
244 data->value = TEMP1_TO_REG_ADT7461(val); \
245 else \
246 data->value = TEMP1_TO_REG(val); \
247 i2c_smbus_write_byte_data(client, reg, data->value); \
248 up(&data->update_lock); \
249 return count; \
250} 265}
251#define set_temp2(value, regh, regl) \ 266
252static 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,
253 size_t count) \ 268 const char *buf, size_t count)
254{ \ 269{
255 struct i2c_client *client = to_i2c_client(dev); \ 270 static const u8 reg[4] = {
256 struct lm90_data *data = i2c_get_clientdata(client); \ 271 LM90_REG_W_REMOTE_LOWH,
257 long val = simple_strtol(buf, NULL, 10); \ 272 LM90_REG_W_REMOTE_LOWL,
258 \ 273 LM90_REG_W_REMOTE_HIGHH,
259 down(&data->update_lock); \ 274 LM90_REG_W_REMOTE_HIGHL,
260 if (data->kind == adt7461) \ 275 };
261 data->value = TEMP2_TO_REG_ADT7461(val); \ 276
262 else \ 277 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
263 data->value = TEMP2_TO_REG(val); \ 278 struct i2c_client *client = to_i2c_client(dev);
264 i2c_smbus_write_byte_data(client, regh, data->value >> 8); \ 279 struct lm90_data *data = i2c_get_clientdata(client);
265 i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \ 280 long val = simple_strtol(buf, NULL, 10);
266 up(&data->update_lock); \ 281 int nr = attr->index;
267 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;
268} 294}
269set_temp1(temp_low1, LM90_REG_W_LOCAL_LOW); 295
270set_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,
271set_temp1(temp_high1, LM90_REG_W_LOCAL_HIGH); 297 char *buf)
272set_temp2(temp_high2, LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL); 298{
273set_temp1(temp_crit1, LM90_REG_W_LOCAL_CRIT); 299 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
274set_temp1(temp_crit2, LM90_REG_W_REMOTE_CRIT); 300 struct lm90_data *data = lm90_update_device(dev);
275 301 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])
276#define show_temp_hyst(value, basereg) \ 302 - TEMP1_FROM_REG(data->temp_hyst));
277static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
278{ \
279 struct lm90_data *data = lm90_update_device(dev); \
280 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->basereg) \
281 - TEMP1_FROM_REG(data->temp_hyst)); \
282} 303}
283show_temp_hyst(temp_hyst1, temp_crit1);
284show_temp_hyst(temp_hyst2, temp_crit2);
285 304
286static 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,
287 size_t count) 306 const char *buf, size_t count)
288{ 307{
289 struct i2c_client *client = to_i2c_client(dev); 308 struct i2c_client *client = to_i2c_client(dev);
290 struct lm90_data *data = i2c_get_clientdata(client); 309 struct lm90_data *data = i2c_get_clientdata(client);
@@ -292,36 +311,37 @@ static ssize_t set_temp_hyst1(struct device *dev, struct device_attribute *attr,
292 long hyst; 311 long hyst;
293 312
294 down(&data->update_lock); 313 down(&data->update_lock);
295 hyst = TEMP1_FROM_REG(data->temp_crit1) - val; 314 hyst = TEMP1_FROM_REG(data->temp8[3]) - val;
296 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, 315 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
297 HYST_TO_REG(hyst)); 316 HYST_TO_REG(hyst));
298 up(&data->update_lock); 317 up(&data->update_lock);
299 return count; 318 return count;
300} 319}
301 320
302static 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)
303{ 323{
304 struct lm90_data *data = lm90_update_device(dev); 324 struct lm90_data *data = lm90_update_device(dev);
305 return sprintf(buf, "%d\n", data->alarms); 325 return sprintf(buf, "%d\n", data->alarms);
306} 326}
307 327
308static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); 328static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
309static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); 329static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
310static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_low1, 330static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
311 set_temp_low1); 331 set_temp8, 1);
312static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2, 332static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
313 set_temp_low2); 333 set_temp11, 1);
314static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_high1, 334static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
315 set_temp_high1); 335 set_temp8, 2);
316static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2, 336static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
317 set_temp_high2); 337 set_temp11, 2);
318static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit1, 338static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8,
319 set_temp_crit1); 339 set_temp8, 3);
320static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2, 340static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
321 set_temp_crit2); 341 set_temp8, 4);
322static 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,
323 set_temp_hyst1); 343 set_temphyst, 3);
324static DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_hyst2, NULL); 344static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
325static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 345static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
326 346
327/* 347/*
@@ -480,16 +500,26 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
480 lm90_init_client(new_client); 500 lm90_init_client(new_client);
481 501
482 /* Register sysfs hooks */ 502 /* Register sysfs hooks */
483 device_create_file(&new_client->dev, &dev_attr_temp1_input); 503 device_create_file(&new_client->dev,
484 device_create_file(&new_client->dev, &dev_attr_temp2_input); 504 &sensor_dev_attr_temp1_input.dev_attr);
485 device_create_file(&new_client->dev, &dev_attr_temp1_min); 505 device_create_file(&new_client->dev,
486 device_create_file(&new_client->dev, &dev_attr_temp2_min); 506 &sensor_dev_attr_temp2_input.dev_attr);
487 device_create_file(&new_client->dev, &dev_attr_temp1_max); 507 device_create_file(&new_client->dev,
488 device_create_file(&new_client->dev, &dev_attr_temp2_max); 508 &sensor_dev_attr_temp1_min.dev_attr);
489 device_create_file(&new_client->dev, &dev_attr_temp1_crit); 509 device_create_file(&new_client->dev,
490 device_create_file(&new_client->dev, &dev_attr_temp2_crit); 510 &sensor_dev_attr_temp2_min.dev_attr);
491 device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); 511 device_create_file(&new_client->dev,
492 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);
493 device_create_file(&new_client->dev, &dev_attr_alarms); 523 device_create_file(&new_client->dev, &dev_attr_alarms);
494 524
495 return 0; 525 return 0;
@@ -540,16 +570,16 @@ static struct lm90_data *lm90_update_device(struct device *dev)
540 u8 oldh, newh; 570 u8 oldh, newh;
541 571
542 dev_dbg(&client->dev, "Updating lm90 data.\n"); 572 dev_dbg(&client->dev, "Updating lm90 data.\n");
543 data->temp_input1 = i2c_smbus_read_byte_data(client, 573 data->temp8[0] = i2c_smbus_read_byte_data(client,
544 LM90_REG_R_LOCAL_TEMP); 574 LM90_REG_R_LOCAL_TEMP);
545 data->temp_high1 = i2c_smbus_read_byte_data(client, 575 data->temp8[1] = i2c_smbus_read_byte_data(client,
546 LM90_REG_R_LOCAL_HIGH); 576 LM90_REG_R_LOCAL_LOW);
547 data->temp_low1 = i2c_smbus_read_byte_data(client, 577 data->temp8[2] = i2c_smbus_read_byte_data(client,
548 LM90_REG_R_LOCAL_LOW); 578 LM90_REG_R_LOCAL_HIGH);
549 data->temp_crit1 = i2c_smbus_read_byte_data(client, 579 data->temp8[3] = i2c_smbus_read_byte_data(client,
550 LM90_REG_R_LOCAL_CRIT); 580 LM90_REG_R_LOCAL_CRIT);
551 data->temp_crit2 = i2c_smbus_read_byte_data(client, 581 data->temp8[4] = i2c_smbus_read_byte_data(client,
552 LM90_REG_R_REMOTE_CRIT); 582 LM90_REG_R_REMOTE_CRIT);
553 data->temp_hyst = i2c_smbus_read_byte_data(client, 583 data->temp_hyst = i2c_smbus_read_byte_data(client,
554 LM90_REG_R_TCRIT_HYST); 584 LM90_REG_R_TCRIT_HYST);
555 585
@@ -569,13 +599,13 @@ static struct lm90_data *lm90_update_device(struct device *dev)
569 */ 599 */
570 oldh = i2c_smbus_read_byte_data(client, 600 oldh = i2c_smbus_read_byte_data(client,
571 LM90_REG_R_REMOTE_TEMPH); 601 LM90_REG_R_REMOTE_TEMPH);
572 data->temp_input2 = i2c_smbus_read_byte_data(client, 602 data->temp11[0] = i2c_smbus_read_byte_data(client,
573 LM90_REG_R_REMOTE_TEMPL); 603 LM90_REG_R_REMOTE_TEMPL);
574 newh = i2c_smbus_read_byte_data(client, 604 newh = i2c_smbus_read_byte_data(client,
575 LM90_REG_R_REMOTE_TEMPH); 605 LM90_REG_R_REMOTE_TEMPH);
576 if (newh != oldh) { 606 if (newh != oldh) {
577 data->temp_input2 = i2c_smbus_read_byte_data(client, 607 data->temp11[0] = i2c_smbus_read_byte_data(client,
578 LM90_REG_R_REMOTE_TEMPL); 608 LM90_REG_R_REMOTE_TEMPL);
579#ifdef DEBUG 609#ifdef DEBUG
580 oldh = i2c_smbus_read_byte_data(client, 610 oldh = i2c_smbus_read_byte_data(client,
581 LM90_REG_R_REMOTE_TEMPH); 611 LM90_REG_R_REMOTE_TEMPH);
@@ -585,16 +615,16 @@ static struct lm90_data *lm90_update_device(struct device *dev)
585 "wrong.\n"); 615 "wrong.\n");
586#endif 616#endif
587 } 617 }
588 data->temp_input2 |= (newh << 8); 618 data->temp11[0] |= (newh << 8);
589 619
590 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,
591 LM90_REG_R_REMOTE_HIGHH) << 8) + 625 LM90_REG_R_REMOTE_HIGHH) << 8) +
592 i2c_smbus_read_byte_data(client, 626 i2c_smbus_read_byte_data(client,
593 LM90_REG_R_REMOTE_HIGHL); 627 LM90_REG_R_REMOTE_HIGHL);
594 data->temp_low2 = (i2c_smbus_read_byte_data(client,
595 LM90_REG_R_REMOTE_LOWH) << 8) +
596 i2c_smbus_read_byte_data(client,
597 LM90_REG_R_REMOTE_LOWL);
598 data->alarms = i2c_smbus_read_byte_data(client, 628 data->alarms = i2c_smbus_read_byte_data(client,
599 LM90_REG_R_STATUS); 629 LM90_REG_R_STATUS);
600 630