aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm63.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lm63.c')
-rw-r--r--drivers/hwmon/lm63.c96
1 files changed, 71 insertions, 25 deletions
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 071f0fc6adec..d69f3cf07122 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm63.c - driver for the National Semiconductor LM63 temperature sensor 2 * lm63.c - driver for the National Semiconductor LM63 temperature sensor
3 * with integrated fan control 3 * with integrated fan control
4 * Copyright (C) 2004-2005 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2004-2006 Jean Delvare <khali@linux-fr.org>
5 * Based on the lm90 driver. 5 * Based on the lm90 driver.
6 * 6 *
7 * The LM63 is a sensor chip made by National Semiconductor. It measures 7 * The LM63 is a sensor chip made by National Semiconductor. It measures
@@ -46,6 +46,7 @@
46#include <linux/hwmon.h> 46#include <linux/hwmon.h>
47#include <linux/err.h> 47#include <linux/err.h>
48#include <linux/mutex.h> 48#include <linux/mutex.h>
49#include <linux/sysfs.h>
49 50
50/* 51/*
51 * Addresses to scan 52 * Addresses to scan
@@ -330,6 +331,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
330 return sprintf(buf, "%u\n", data->alarms); 331 return sprintf(buf, "%u\n", data->alarms);
331} 332}
332 333
334static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr,
335 char *buf)
336{
337 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
338 struct lm63_data *data = lm63_update_device(dev);
339 int bitnr = attr->index;
340
341 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
342}
343
333static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); 344static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
334static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, 345static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
335 set_fan, 1); 346 set_fan, 1);
@@ -350,8 +361,52 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
350static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, 361static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
351 set_temp2_crit_hyst); 362 set_temp2_crit_hyst);
352 363
364/* Individual alarm files */
365static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
366static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
367static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2);
368static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
369static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
370static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
371/* Raw alarm file for compatibility */
353static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 372static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
354 373
374static struct attribute *lm63_attributes[] = {
375 &dev_attr_pwm1.attr,
376 &dev_attr_pwm1_enable.attr,
377 &sensor_dev_attr_temp1_input.dev_attr.attr,
378 &sensor_dev_attr_temp2_input.dev_attr.attr,
379 &sensor_dev_attr_temp2_min.dev_attr.attr,
380 &sensor_dev_attr_temp1_max.dev_attr.attr,
381 &sensor_dev_attr_temp2_max.dev_attr.attr,
382 &sensor_dev_attr_temp2_crit.dev_attr.attr,
383 &dev_attr_temp2_crit_hyst.attr,
384
385 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
386 &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
387 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
388 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
389 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
390 &dev_attr_alarms.attr,
391 NULL
392};
393
394static const struct attribute_group lm63_group = {
395 .attrs = lm63_attributes,
396};
397
398static struct attribute *lm63_attributes_fan1[] = {
399 &sensor_dev_attr_fan1_input.dev_attr.attr,
400 &sensor_dev_attr_fan1_min.dev_attr.attr,
401
402 &sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
403 NULL
404};
405
406static const struct attribute_group lm63_group_fan1 = {
407 .attrs = lm63_attributes_fan1,
408};
409
355/* 410/*
356 * Real code 411 * Real code
357 */ 412 */
@@ -438,37 +493,26 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
438 lm63_init_client(new_client); 493 lm63_init_client(new_client);
439 494
440 /* Register sysfs hooks */ 495 /* Register sysfs hooks */
441 data->class_dev = hwmon_device_register(&new_client->dev); 496 if ((err = sysfs_create_group(&new_client->dev.kobj,
442 if (IS_ERR(data->class_dev)) { 497 &lm63_group)))
443 err = PTR_ERR(data->class_dev);
444 goto exit_detach; 498 goto exit_detach;
499 if (data->config & 0x04) { /* tachometer enabled */
500 if ((err = sysfs_create_group(&new_client->dev.kobj,
501 &lm63_group_fan1)))
502 goto exit_remove_files;
445 } 503 }
446 504
447 if (data->config & 0x04) { /* tachometer enabled */ 505 data->class_dev = hwmon_device_register(&new_client->dev);
448 device_create_file(&new_client->dev, 506 if (IS_ERR(data->class_dev)) {
449 &sensor_dev_attr_fan1_input.dev_attr); 507 err = PTR_ERR(data->class_dev);
450 device_create_file(&new_client->dev, 508 goto exit_remove_files;
451 &sensor_dev_attr_fan1_min.dev_attr);
452 } 509 }
453 device_create_file(&new_client->dev, &dev_attr_pwm1);
454 device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
455 device_create_file(&new_client->dev,
456 &sensor_dev_attr_temp1_input.dev_attr);
457 device_create_file(&new_client->dev,
458 &sensor_dev_attr_temp2_input.dev_attr);
459 device_create_file(&new_client->dev,
460 &sensor_dev_attr_temp2_min.dev_attr);
461 device_create_file(&new_client->dev,
462 &sensor_dev_attr_temp1_max.dev_attr);
463 device_create_file(&new_client->dev,
464 &sensor_dev_attr_temp2_max.dev_attr);
465 device_create_file(&new_client->dev,
466 &sensor_dev_attr_temp2_crit.dev_attr);
467 device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
468 device_create_file(&new_client->dev, &dev_attr_alarms);
469 510
470 return 0; 511 return 0;
471 512
513exit_remove_files:
514 sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
515 sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
472exit_detach: 516exit_detach:
473 i2c_detach_client(new_client); 517 i2c_detach_client(new_client);
474exit_free: 518exit_free:
@@ -518,6 +562,8 @@ static int lm63_detach_client(struct i2c_client *client)
518 int err; 562 int err;
519 563
520 hwmon_device_unregister(data->class_dev); 564 hwmon_device_unregister(data->class_dev);
565 sysfs_remove_group(&client->dev.kobj, &lm63_group);
566 sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
521 567
522 if ((err = i2c_detach_client(client))) 568 if ((err = i2c_detach_client(client)))
523 return err; 569 return err;