aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/w83627ehf.c206
1 files changed, 80 insertions, 126 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 1affaf15beda..b6bd5685fd38 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -42,6 +42,7 @@
42#include <linux/i2c.h> 42#include <linux/i2c.h>
43#include <linux/i2c-isa.h> 43#include <linux/i2c-isa.h>
44#include <linux/hwmon.h> 44#include <linux/hwmon.h>
45#include <linux/hwmon-sysfs.h>
45#include <linux/err.h> 46#include <linux/err.h>
46#include <linux/mutex.h> 47#include <linux/mutex.h>
47#include <asm/io.h> 48#include <asm/io.h>
@@ -408,9 +409,12 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
408 409
409#define show_fan_reg(reg) \ 410#define show_fan_reg(reg) \
410static ssize_t \ 411static ssize_t \
411show_##reg(struct device *dev, char *buf, int nr) \ 412show_##reg(struct device *dev, struct device_attribute *attr, \
413 char *buf) \
412{ \ 414{ \
413 struct w83627ehf_data *data = w83627ehf_update_device(dev); \ 415 struct w83627ehf_data *data = w83627ehf_update_device(dev); \
416 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
417 int nr = sensor_attr->index; \
414 return sprintf(buf, "%d\n", \ 418 return sprintf(buf, "%d\n", \
415 fan_from_reg(data->reg[nr], \ 419 fan_from_reg(data->reg[nr], \
416 div_from_reg(data->fan_div[nr]))); \ 420 div_from_reg(data->fan_div[nr]))); \
@@ -419,18 +423,23 @@ show_fan_reg(fan);
419show_fan_reg(fan_min); 423show_fan_reg(fan_min);
420 424
421static ssize_t 425static ssize_t
422show_fan_div(struct device *dev, char *buf, int nr) 426show_fan_div(struct device *dev, struct device_attribute *attr,
427 char *buf)
423{ 428{
424 struct w83627ehf_data *data = w83627ehf_update_device(dev); 429 struct w83627ehf_data *data = w83627ehf_update_device(dev);
425 return sprintf(buf, "%u\n", 430 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
426 div_from_reg(data->fan_div[nr])); 431 int nr = sensor_attr->index;
432 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
427} 433}
428 434
429static ssize_t 435static ssize_t
430store_fan_min(struct device *dev, const char *buf, size_t count, int nr) 436store_fan_min(struct device *dev, struct device_attribute *attr,
437 const char *buf, size_t count)
431{ 438{
432 struct i2c_client *client = to_i2c_client(dev); 439 struct i2c_client *client = to_i2c_client(dev);
433 struct w83627ehf_data *data = i2c_get_clientdata(client); 440 struct w83627ehf_data *data = i2c_get_clientdata(client);
441 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
442 int nr = sensor_attr->index;
434 unsigned int val = simple_strtoul(buf, NULL, 10); 443 unsigned int val = simple_strtoul(buf, NULL, 10);
435 unsigned int reg; 444 unsigned int reg;
436 u8 new_div; 445 u8 new_div;
@@ -488,58 +497,41 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
488 return count; 497 return count;
489} 498}
490 499
491#define sysfs_fan_offset(offset) \ 500static struct sensor_device_attribute sda_fan_input[] = {
492static ssize_t \ 501 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
493show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \ 502 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
494 char *buf) \ 503 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
495{ \ 504 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
496 return show_fan(dev, buf, offset-1); \ 505 SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
497} \ 506};
498static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
499 show_reg_fan_##offset, NULL);
500 507
501#define sysfs_fan_min_offset(offset) \ 508static struct sensor_device_attribute sda_fan_min[] = {
502static ssize_t \ 509 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
503show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ 510 store_fan_min, 0),
504 char *buf) \ 511 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
505{ \ 512 store_fan_min, 1),
506 return show_fan_min(dev, buf, offset-1); \ 513 SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
507} \ 514 store_fan_min, 2),
508static ssize_t \ 515 SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
509store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ 516 store_fan_min, 3),
510 const char *buf, size_t count) \ 517 SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
511{ \ 518 store_fan_min, 4),
512 return store_fan_min(dev, buf, count, offset-1); \ 519};
513} \
514static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
515 show_reg_fan##offset##_min, \
516 store_reg_fan##offset##_min);
517 520
518#define sysfs_fan_div_offset(offset) \ 521static struct sensor_device_attribute sda_fan_div[] = {
519static ssize_t \ 522 SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
520show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \ 523 SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
521 char *buf) \ 524 SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
522{ \ 525 SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
523 return show_fan_div(dev, buf, offset - 1); \ 526 SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
524} \ 527};
525static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ 528
526 show_reg_fan##offset##_div, NULL); 529static void device_create_file_fan(struct device *dev, int i)
527 530{
528sysfs_fan_offset(1); 531 device_create_file(dev, &sda_fan_input[i].dev_attr);
529sysfs_fan_min_offset(1); 532 device_create_file(dev, &sda_fan_div[i].dev_attr);
530sysfs_fan_div_offset(1); 533 device_create_file(dev, &sda_fan_min[i].dev_attr);
531sysfs_fan_offset(2); 534}
532sysfs_fan_min_offset(2);
533sysfs_fan_div_offset(2);
534sysfs_fan_offset(3);
535sysfs_fan_min_offset(3);
536sysfs_fan_div_offset(3);
537sysfs_fan_offset(4);
538sysfs_fan_min_offset(4);
539sysfs_fan_div_offset(4);
540sysfs_fan_offset(5);
541sysfs_fan_min_offset(5);
542sysfs_fan_div_offset(5);
543 535
544#define show_temp1_reg(reg) \ 536#define show_temp1_reg(reg) \
545static ssize_t \ 537static ssize_t \
@@ -572,17 +564,14 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
572store_temp1_reg(OVER, max); 564store_temp1_reg(OVER, max);
573store_temp1_reg(HYST, max_hyst); 565store_temp1_reg(HYST, max_hyst);
574 566
575static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
576static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR,
577 show_temp1_max, store_temp1_max);
578static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR,
579 show_temp1_max_hyst, store_temp1_max_hyst);
580
581#define show_temp_reg(reg) \ 567#define show_temp_reg(reg) \
582static ssize_t \ 568static ssize_t \
583show_##reg (struct device *dev, char *buf, int nr) \ 569show_##reg(struct device *dev, struct device_attribute *attr, \
570 char *buf) \
584{ \ 571{ \
585 struct w83627ehf_data *data = w83627ehf_update_device(dev); \ 572 struct w83627ehf_data *data = w83627ehf_update_device(dev); \
573 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
574 int nr = sensor_attr->index; \
586 return sprintf(buf, "%d\n", \ 575 return sprintf(buf, "%d\n", \
587 LM75_TEMP_FROM_REG(data->reg[nr])); \ 576 LM75_TEMP_FROM_REG(data->reg[nr])); \
588} 577}
@@ -592,10 +581,13 @@ show_temp_reg(temp_max_hyst);
592 581
593#define store_temp_reg(REG, reg) \ 582#define store_temp_reg(REG, reg) \
594static ssize_t \ 583static ssize_t \
595store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ 584store_##reg(struct device *dev, struct device_attribute *attr, \
585 const char *buf, size_t count) \
596{ \ 586{ \
597 struct i2c_client *client = to_i2c_client(dev); \ 587 struct i2c_client *client = to_i2c_client(dev); \
598 struct w83627ehf_data *data = i2c_get_clientdata(client); \ 588 struct w83627ehf_data *data = i2c_get_clientdata(client); \
589 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
590 int nr = sensor_attr->index; \
599 u32 val = simple_strtoul(buf, NULL, 10); \ 591 u32 val = simple_strtoul(buf, NULL, 10); \
600 \ 592 \
601 mutex_lock(&data->update_lock); \ 593 mutex_lock(&data->update_lock); \
@@ -608,39 +600,23 @@ store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
608store_temp_reg(OVER, temp_max); 600store_temp_reg(OVER, temp_max);
609store_temp_reg(HYST, temp_max_hyst); 601store_temp_reg(HYST, temp_max_hyst);
610 602
611#define sysfs_temp_offset(offset) \ 603static struct sensor_device_attribute sda_temp[] = {
612static ssize_t \ 604 SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
613show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \ 605 SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
614 char *buf) \ 606 SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
615{ \ 607 SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
616 return show_temp(dev, buf, offset - 2); \ 608 store_temp1_max, 0),
617} \ 609 SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
618static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ 610 store_temp_max, 0),
619 show_reg_temp##offset, NULL); 611 SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
620 612 store_temp_max, 1),
621#define sysfs_temp_reg_offset(reg, offset) \ 613 SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
622static ssize_t \ 614 store_temp1_max_hyst, 0),
623show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ 615 SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
624 char *buf) \ 616 store_temp_max_hyst, 0),
625{ \ 617 SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
626 return show_temp_##reg(dev, buf, offset - 2); \ 618 store_temp_max_hyst, 1),
627} \ 619};
628static ssize_t \
629store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
630 const char *buf, size_t count) \
631{ \
632 return store_temp_##reg(dev, buf, count, offset - 2); \
633} \
634static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
635 show_reg_temp##offset##_##reg, \
636 store_reg_temp##offset##_##reg);
637
638sysfs_temp_offset(2);
639sysfs_temp_reg_offset(max, 2);
640sysfs_temp_reg_offset(max_hyst, 2);
641sysfs_temp_offset(3);
642sysfs_temp_reg_offset(max, 3);
643sysfs_temp_reg_offset(max_hyst, 3);
644 620
645/* 621/*
646 * Driver and client management 622 * Driver and client management
@@ -674,6 +650,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
674{ 650{
675 struct i2c_client *client; 651 struct i2c_client *client;
676 struct w83627ehf_data *data; 652 struct w83627ehf_data *data;
653 struct device *dev;
677 int i, err = 0; 654 int i, err = 0;
678 655
679 if (!request_region(address + REGION_OFFSET, REGION_LENGTH, 656 if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
@@ -694,6 +671,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
694 client->adapter = adapter; 671 client->adapter = adapter;
695 client->driver = &w83627ehf_driver; 672 client->driver = &w83627ehf_driver;
696 client->flags = 0; 673 client->flags = 0;
674 dev = &client->dev;
697 675
698 strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); 676 strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
699 data->valid = 0; 677 data->valid = 0;
@@ -721,42 +699,18 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
721 data->has_fan |= (1 << 4); 699 data->has_fan |= (1 << 4);
722 700
723 /* Register sysfs hooks */ 701 /* Register sysfs hooks */
724 data->class_dev = hwmon_device_register(&client->dev); 702 data->class_dev = hwmon_device_register(dev);
725 if (IS_ERR(data->class_dev)) { 703 if (IS_ERR(data->class_dev)) {
726 err = PTR_ERR(data->class_dev); 704 err = PTR_ERR(data->class_dev);
727 goto exit_detach; 705 goto exit_detach;
728 } 706 }
729 707
730 device_create_file(&client->dev, &dev_attr_fan1_input); 708 for (i = 0; i < 5; i++) {
731 device_create_file(&client->dev, &dev_attr_fan1_min); 709 if (data->has_fan & (1 << i))
732 device_create_file(&client->dev, &dev_attr_fan1_div); 710 device_create_file_fan(dev, i);
733 device_create_file(&client->dev, &dev_attr_fan2_input);
734 device_create_file(&client->dev, &dev_attr_fan2_min);
735 device_create_file(&client->dev, &dev_attr_fan2_div);
736 device_create_file(&client->dev, &dev_attr_fan3_input);
737 device_create_file(&client->dev, &dev_attr_fan3_min);
738 device_create_file(&client->dev, &dev_attr_fan3_div);
739
740 if (data->has_fan & (1 << 3)) {
741 device_create_file(&client->dev, &dev_attr_fan4_input);
742 device_create_file(&client->dev, &dev_attr_fan4_min);
743 device_create_file(&client->dev, &dev_attr_fan4_div);
744 }
745 if (data->has_fan & (1 << 4)) {
746 device_create_file(&client->dev, &dev_attr_fan5_input);
747 device_create_file(&client->dev, &dev_attr_fan5_min);
748 device_create_file(&client->dev, &dev_attr_fan5_div);
749 } 711 }
750 712 for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
751 device_create_file(&client->dev, &dev_attr_temp1_input); 713 device_create_file(dev, &sda_temp[i].dev_attr);
752 device_create_file(&client->dev, &dev_attr_temp1_max);
753 device_create_file(&client->dev, &dev_attr_temp1_max_hyst);
754 device_create_file(&client->dev, &dev_attr_temp2_input);
755 device_create_file(&client->dev, &dev_attr_temp2_max);
756 device_create_file(&client->dev, &dev_attr_temp2_max_hyst);
757 device_create_file(&client->dev, &dev_attr_temp3_input);
758 device_create_file(&client->dev, &dev_attr_temp3_max);
759 device_create_file(&client->dev, &dev_attr_temp3_max_hyst);
760 714
761 return 0; 715 return 0;
762 716