diff options
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 206 |
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) \ |
410 | static ssize_t \ | 411 | static ssize_t \ |
411 | show_##reg(struct device *dev, char *buf, int nr) \ | 412 | show_##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); | |||
419 | show_fan_reg(fan_min); | 423 | show_fan_reg(fan_min); |
420 | 424 | ||
421 | static ssize_t | 425 | static ssize_t |
422 | show_fan_div(struct device *dev, char *buf, int nr) | 426 | show_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 | ||
429 | static ssize_t | 435 | static ssize_t |
430 | store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | 436 | store_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) \ | 500 | static struct sensor_device_attribute sda_fan_input[] = { |
492 | static ssize_t \ | 501 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), |
493 | show_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 | }; |
498 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
499 | show_reg_fan_##offset, NULL); | ||
500 | 507 | ||
501 | #define sysfs_fan_min_offset(offset) \ | 508 | static struct sensor_device_attribute sda_fan_min[] = { |
502 | static ssize_t \ | 509 | SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, |
503 | show_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), |
508 | static ssize_t \ | 515 | SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, |
509 | store_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 | } \ | ||
514 | static 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) \ | 521 | static struct sensor_device_attribute sda_fan_div[] = { |
519 | static ssize_t \ | 522 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), |
520 | show_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 | }; |
525 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ | 528 | |
526 | show_reg_fan##offset##_div, NULL); | 529 | static void device_create_file_fan(struct device *dev, int i) |
527 | 530 | { | |
528 | sysfs_fan_offset(1); | 531 | device_create_file(dev, &sda_fan_input[i].dev_attr); |
529 | sysfs_fan_min_offset(1); | 532 | device_create_file(dev, &sda_fan_div[i].dev_attr); |
530 | sysfs_fan_div_offset(1); | 533 | device_create_file(dev, &sda_fan_min[i].dev_attr); |
531 | sysfs_fan_offset(2); | 534 | } |
532 | sysfs_fan_min_offset(2); | ||
533 | sysfs_fan_div_offset(2); | ||
534 | sysfs_fan_offset(3); | ||
535 | sysfs_fan_min_offset(3); | ||
536 | sysfs_fan_div_offset(3); | ||
537 | sysfs_fan_offset(4); | ||
538 | sysfs_fan_min_offset(4); | ||
539 | sysfs_fan_div_offset(4); | ||
540 | sysfs_fan_offset(5); | ||
541 | sysfs_fan_min_offset(5); | ||
542 | sysfs_fan_div_offset(5); | ||
543 | 535 | ||
544 | #define show_temp1_reg(reg) \ | 536 | #define show_temp1_reg(reg) \ |
545 | static ssize_t \ | 537 | static ssize_t \ |
@@ -572,17 +564,14 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | |||
572 | store_temp1_reg(OVER, max); | 564 | store_temp1_reg(OVER, max); |
573 | store_temp1_reg(HYST, max_hyst); | 565 | store_temp1_reg(HYST, max_hyst); |
574 | 566 | ||
575 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL); | ||
576 | static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR, | ||
577 | show_temp1_max, store_temp1_max); | ||
578 | static 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) \ |
582 | static ssize_t \ | 568 | static ssize_t \ |
583 | show_##reg (struct device *dev, char *buf, int nr) \ | 569 | show_##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) \ |
594 | static ssize_t \ | 583 | static ssize_t \ |
595 | store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 584 | store_##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) \ | |||
608 | store_temp_reg(OVER, temp_max); | 600 | store_temp_reg(OVER, temp_max); |
609 | store_temp_reg(HYST, temp_max_hyst); | 601 | store_temp_reg(HYST, temp_max_hyst); |
610 | 602 | ||
611 | #define sysfs_temp_offset(offset) \ | 603 | static struct sensor_device_attribute sda_temp[] = { |
612 | static ssize_t \ | 604 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), |
613 | show_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, |
618 | static 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, |
622 | static ssize_t \ | 614 | store_temp1_max_hyst, 0), |
623 | show_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 | }; |
628 | static ssize_t \ | ||
629 | store_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 | } \ | ||
634 | static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ | ||
635 | show_reg_temp##offset##_##reg, \ | ||
636 | store_reg_temp##offset##_##reg); | ||
637 | |||
638 | sysfs_temp_offset(2); | ||
639 | sysfs_temp_reg_offset(max, 2); | ||
640 | sysfs_temp_reg_offset(max_hyst, 2); | ||
641 | sysfs_temp_offset(3); | ||
642 | sysfs_temp_reg_offset(max, 3); | ||
643 | sysfs_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 | ||