diff options
author | Guenter Roeck <linux@roeck-us.net> | 2016-06-18 22:56:08 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-09-09 00:34:17 -0400 |
commit | eb1c8f4325d59e913d561d1fac8c9bc8154eb274 (patch) | |
tree | 32930b35b5eec2a243132e53d9a48c0dff1446d8 | |
parent | 08b024338166abebcc2216f97693336f7ac0bf42 (diff) |
hwmon: (lm90) Convert to use new hwmon registration API
Reduce driver complexity and size by converting it to
the new hwmon API.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/lm90.c | 811 |
1 files changed, 435 insertions, 376 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 496e771b363f..322ed9272811 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -89,7 +89,6 @@ | |||
89 | #include <linux/slab.h> | 89 | #include <linux/slab.h> |
90 | #include <linux/jiffies.h> | 90 | #include <linux/jiffies.h> |
91 | #include <linux/i2c.h> | 91 | #include <linux/i2c.h> |
92 | #include <linux/hwmon-sysfs.h> | ||
93 | #include <linux/hwmon.h> | 92 | #include <linux/hwmon.h> |
94 | #include <linux/err.h> | 93 | #include <linux/err.h> |
95 | #include <linux/mutex.h> | 94 | #include <linux/mutex.h> |
@@ -326,7 +325,7 @@ static const struct lm90_params lm90_params[] = { | |||
326 | .alert_alarms = 0x7c, | 325 | .alert_alarms = 0x7c, |
327 | .max_convrate = 9, | 326 | .max_convrate = 9, |
328 | .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, | 327 | .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, |
329 | } | 328 | }, |
330 | }; | 329 | }; |
331 | 330 | ||
332 | /* | 331 | /* |
@@ -365,7 +364,10 @@ enum lm90_temp11_reg_index { | |||
365 | 364 | ||
366 | struct lm90_data { | 365 | struct lm90_data { |
367 | struct i2c_client *client; | 366 | struct i2c_client *client; |
368 | const struct attribute_group *groups[6]; | 367 | u32 channel_config[4]; |
368 | struct hwmon_channel_info temp_info; | ||
369 | const struct hwmon_channel_info *info[3]; | ||
370 | struct hwmon_chip_info chip; | ||
369 | struct mutex update_lock; | 371 | struct mutex update_lock; |
370 | bool valid; /* true if register values are valid */ | 372 | bool valid; /* true if register values are valid */ |
371 | unsigned long last_updated; /* in jiffies */ | 373 | unsigned long last_updated; /* in jiffies */ |
@@ -489,11 +491,11 @@ static inline int lm90_select_remote_channel(struct i2c_client *client, | |||
489 | * client->update_lock must be held when calling this function (unless we are | 491 | * client->update_lock must be held when calling this function (unless we are |
490 | * in detection or initialization steps). | 492 | * in detection or initialization steps). |
491 | */ | 493 | */ |
492 | static void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, | 494 | static int lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, |
493 | unsigned int interval) | 495 | unsigned int interval) |
494 | { | 496 | { |
495 | int i; | ||
496 | unsigned int update_interval; | 497 | unsigned int update_interval; |
498 | int i, err; | ||
497 | 499 | ||
498 | /* Shift calculations to avoid rounding errors */ | 500 | /* Shift calculations to avoid rounding errors */ |
499 | interval <<= 6; | 501 | interval <<= 6; |
@@ -504,8 +506,9 @@ static void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, | |||
504 | if (interval >= update_interval * 3 / 4) | 506 | if (interval >= update_interval * 3 / 4) |
505 | break; | 507 | break; |
506 | 508 | ||
507 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); | 509 | err = i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); |
508 | data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); | 510 | data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); |
511 | return err; | ||
509 | } | 512 | } |
510 | 513 | ||
511 | static int lm90_update_limits(struct device *dev) | 514 | static int lm90_update_limits(struct device *dev) |
@@ -604,19 +607,17 @@ static int lm90_update_limits(struct device *dev) | |||
604 | return 0; | 607 | return 0; |
605 | } | 608 | } |
606 | 609 | ||
607 | static struct lm90_data *lm90_update_device(struct device *dev) | 610 | static int lm90_update_device(struct device *dev) |
608 | { | 611 | { |
609 | struct lm90_data *data = dev_get_drvdata(dev); | 612 | struct lm90_data *data = dev_get_drvdata(dev); |
610 | struct i2c_client *client = data->client; | 613 | struct i2c_client *client = data->client; |
611 | unsigned long next_update; | 614 | unsigned long next_update; |
612 | int val = 0; | 615 | int val; |
613 | |||
614 | mutex_lock(&data->update_lock); | ||
615 | 616 | ||
616 | if (!data->valid) { | 617 | if (!data->valid) { |
617 | val = lm90_update_limits(dev); | 618 | val = lm90_update_limits(dev); |
618 | if (val < 0) | 619 | if (val < 0) |
619 | goto error; | 620 | return val; |
620 | } | 621 | } |
621 | 622 | ||
622 | next_update = data->last_updated + | 623 | next_update = data->last_updated + |
@@ -628,53 +629,55 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
628 | 629 | ||
629 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW); | 630 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW); |
630 | if (val < 0) | 631 | if (val < 0) |
631 | goto error; | 632 | return val; |
632 | data->temp8[LOCAL_LOW] = val; | 633 | data->temp8[LOCAL_LOW] = val; |
633 | 634 | ||
634 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH); | 635 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH); |
635 | if (val < 0) | 636 | if (val < 0) |
636 | goto error; | 637 | return val; |
637 | data->temp8[LOCAL_HIGH] = val; | 638 | data->temp8[LOCAL_HIGH] = val; |
638 | 639 | ||
639 | if (data->reg_local_ext) { | 640 | if (data->reg_local_ext) { |
640 | val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP, | 641 | val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP, |
641 | data->reg_local_ext); | 642 | data->reg_local_ext); |
642 | if (val < 0) | 643 | if (val < 0) |
643 | goto error; | 644 | return val; |
644 | data->temp11[LOCAL_TEMP] = val; | 645 | data->temp11[LOCAL_TEMP] = val; |
645 | } else { | 646 | } else { |
646 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP); | 647 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP); |
647 | if (val < 0) | 648 | if (val < 0) |
648 | goto error; | 649 | return val; |
649 | data->temp11[LOCAL_TEMP] = val << 8; | 650 | data->temp11[LOCAL_TEMP] = val << 8; |
650 | } | 651 | } |
651 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, | 652 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
652 | LM90_REG_R_REMOTE_TEMPL); | 653 | LM90_REG_R_REMOTE_TEMPL); |
653 | if (val < 0) | 654 | if (val < 0) |
654 | goto error; | 655 | return val; |
655 | data->temp11[REMOTE_TEMP] = val; | 656 | data->temp11[REMOTE_TEMP] = val; |
656 | 657 | ||
657 | val = lm90_read_reg(client, LM90_REG_R_STATUS); | 658 | val = lm90_read_reg(client, LM90_REG_R_STATUS); |
658 | if (val < 0) | 659 | if (val < 0) |
659 | goto error; | 660 | return val; |
660 | data->alarms = val; /* lower 8 bit of alarms */ | 661 | data->alarms = val; /* lower 8 bit of alarms */ |
661 | 662 | ||
662 | if (data->kind == max6696) { | 663 | if (data->kind == max6696) { |
663 | val = lm90_select_remote_channel(client, data, 1); | 664 | val = lm90_select_remote_channel(client, data, 1); |
664 | if (val < 0) | 665 | if (val < 0) |
665 | goto error; | 666 | return val; |
666 | 667 | ||
667 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, | 668 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
668 | LM90_REG_R_REMOTE_TEMPL); | 669 | LM90_REG_R_REMOTE_TEMPL); |
669 | if (val < 0) | 670 | if (val < 0) { |
670 | goto error; | 671 | lm90_select_remote_channel(client, data, 0); |
672 | return val; | ||
673 | } | ||
671 | data->temp11[REMOTE2_TEMP] = val; | 674 | data->temp11[REMOTE2_TEMP] = val; |
672 | 675 | ||
673 | lm90_select_remote_channel(client, data, 0); | 676 | lm90_select_remote_channel(client, data, 0); |
674 | 677 | ||
675 | val = lm90_read_reg(client, MAX6696_REG_R_STATUS2); | 678 | val = lm90_read_reg(client, MAX6696_REG_R_STATUS2); |
676 | if (val < 0) | 679 | if (val < 0) |
677 | goto error; | 680 | return val; |
678 | data->alarms |= val << 8; | 681 | data->alarms |= val << 8; |
679 | } | 682 | } |
680 | 683 | ||
@@ -686,7 +689,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
686 | !(data->alarms & data->alert_alarms)) { | 689 | !(data->alarms & data->alert_alarms)) { |
687 | val = lm90_read_reg(client, LM90_REG_R_CONFIG1); | 690 | val = lm90_read_reg(client, LM90_REG_R_CONFIG1); |
688 | if (val < 0) | 691 | if (val < 0) |
689 | goto error; | 692 | return val; |
690 | 693 | ||
691 | if (val & 0x80) { | 694 | if (val & 0x80) { |
692 | dev_dbg(&client->dev, "Re-enabling ALERT#\n"); | 695 | dev_dbg(&client->dev, "Re-enabling ALERT#\n"); |
@@ -700,13 +703,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
700 | data->valid = true; | 703 | data->valid = true; |
701 | } | 704 | } |
702 | 705 | ||
703 | error: | 706 | return 0; |
704 | mutex_unlock(&data->update_lock); | ||
705 | |||
706 | if (val < 0) | ||
707 | return ERR_PTR(val); | ||
708 | |||
709 | return data; | ||
710 | } | 707 | } |
711 | 708 | ||
712 | /* | 709 | /* |
@@ -832,52 +829,19 @@ static u16 temp_to_u16_adt7461(struct lm90_data *data, long val) | |||
832 | return (val + 125) / 250 * 64; | 829 | return (val + 125) / 250 * 64; |
833 | } | 830 | } |
834 | 831 | ||
835 | /* | 832 | /* pec used for ADM1032 only */ |
836 | * Sysfs stuff | 833 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, |
837 | */ | 834 | char *buf) |
838 | |||
839 | static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | ||
840 | char *buf) | ||
841 | { | 835 | { |
842 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 836 | struct i2c_client *client = to_i2c_client(dev); |
843 | struct lm90_data *data = lm90_update_device(dev); | ||
844 | int temp; | ||
845 | |||
846 | if (IS_ERR(data)) | ||
847 | return PTR_ERR(data); | ||
848 | |||
849 | if (data->kind == adt7461 || data->kind == tmp451) | ||
850 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | ||
851 | else if (data->kind == max6646) | ||
852 | temp = temp_from_u8(data->temp8[attr->index]); | ||
853 | else | ||
854 | temp = temp_from_s8(data->temp8[attr->index]); | ||
855 | |||
856 | /* +16 degrees offset for temp2 for the LM99 */ | ||
857 | if (data->kind == lm99 && attr->index == 3) | ||
858 | temp += 16000; | ||
859 | 837 | ||
860 | return sprintf(buf, "%d\n", temp); | 838 | return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); |
861 | } | 839 | } |
862 | 840 | ||
863 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | 841 | static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, |
864 | const char *buf, size_t count) | 842 | const char *buf, size_t count) |
865 | { | 843 | { |
866 | static const u8 reg[TEMP8_REG_NUM] = { | 844 | struct i2c_client *client = to_i2c_client(dev); |
867 | LM90_REG_W_LOCAL_LOW, | ||
868 | LM90_REG_W_LOCAL_HIGH, | ||
869 | LM90_REG_W_LOCAL_CRIT, | ||
870 | LM90_REG_W_REMOTE_CRIT, | ||
871 | MAX6659_REG_W_LOCAL_EMERG, | ||
872 | MAX6659_REG_W_REMOTE_EMERG, | ||
873 | LM90_REG_W_REMOTE_CRIT, | ||
874 | MAX6659_REG_W_REMOTE_EMERG, | ||
875 | }; | ||
876 | |||
877 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
878 | struct lm90_data *data = dev_get_drvdata(dev); | ||
879 | struct i2c_client *client = data->client; | ||
880 | int nr = attr->index; | ||
881 | long val; | 845 | long val; |
882 | int err; | 846 | int err; |
883 | 847 | ||
@@ -885,82 +849,61 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
885 | if (err < 0) | 849 | if (err < 0) |
886 | return err; | 850 | return err; |
887 | 851 | ||
888 | /* +16 degrees offset for temp2 for the LM99 */ | 852 | switch (val) { |
889 | if (data->kind == lm99 && attr->index == 3) | 853 | case 0: |
890 | val -= 16000; | 854 | client->flags &= ~I2C_CLIENT_PEC; |
891 | 855 | break; | |
892 | mutex_lock(&data->update_lock); | 856 | case 1: |
893 | if (data->kind == adt7461 || data->kind == tmp451) | 857 | client->flags |= I2C_CLIENT_PEC; |
894 | data->temp8[nr] = temp_to_u8_adt7461(data, val); | 858 | break; |
895 | else if (data->kind == max6646) | 859 | default: |
896 | data->temp8[nr] = temp_to_u8(val); | 860 | return -EINVAL; |
897 | else | 861 | } |
898 | data->temp8[nr] = temp_to_s8(val); | ||
899 | |||
900 | lm90_select_remote_channel(client, data, nr >= 6); | ||
901 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); | ||
902 | lm90_select_remote_channel(client, data, 0); | ||
903 | 862 | ||
904 | mutex_unlock(&data->update_lock); | ||
905 | return count; | 863 | return count; |
906 | } | 864 | } |
907 | 865 | ||
908 | static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | 866 | static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); |
909 | char *buf) | 867 | |
868 | static int lm90_get_temp11(struct lm90_data *data, int index) | ||
910 | { | 869 | { |
911 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | 870 | s16 temp11 = data->temp11[index]; |
912 | struct lm90_data *data = lm90_update_device(dev); | ||
913 | int temp; | 871 | int temp; |
914 | 872 | ||
915 | if (IS_ERR(data)) | ||
916 | return PTR_ERR(data); | ||
917 | |||
918 | if (data->kind == adt7461 || data->kind == tmp451) | 873 | if (data->kind == adt7461 || data->kind == tmp451) |
919 | temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); | 874 | temp = temp_from_u16_adt7461(data, temp11); |
920 | else if (data->kind == max6646) | 875 | else if (data->kind == max6646) |
921 | temp = temp_from_u16(data->temp11[attr->index]); | 876 | temp = temp_from_u16(temp11); |
922 | else | 877 | else |
923 | temp = temp_from_s16(data->temp11[attr->index]); | 878 | temp = temp_from_s16(temp11); |
924 | 879 | ||
925 | /* +16 degrees offset for temp2 for the LM99 */ | 880 | /* +16 degrees offset for temp2 for the LM99 */ |
926 | if (data->kind == lm99 && attr->index <= 2) | 881 | if (data->kind == lm99 && index <= 2) |
927 | temp += 16000; | 882 | temp += 16000; |
928 | 883 | ||
929 | return sprintf(buf, "%d\n", temp); | 884 | return temp; |
930 | } | 885 | } |
931 | 886 | ||
932 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 887 | static int lm90_set_temp11(struct lm90_data *data, int index, long val) |
933 | const char *buf, size_t count) | ||
934 | { | 888 | { |
935 | struct { | 889 | static struct reg { |
936 | u8 high; | 890 | u8 high; |
937 | u8 low; | 891 | u8 low; |
938 | int channel; | 892 | } reg[] = { |
939 | } reg[5] = { | 893 | [REMOTE_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL }, |
940 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 0 }, | 894 | [REMOTE_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL }, |
941 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 0 }, | 895 | [REMOTE_OFFSET] = { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL }, |
942 | { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL, 0 }, | 896 | [REMOTE2_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL }, |
943 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 1 }, | 897 | [REMOTE2_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL } |
944 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 1 } | ||
945 | }; | 898 | }; |
946 | |||
947 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
948 | struct lm90_data *data = dev_get_drvdata(dev); | ||
949 | struct i2c_client *client = data->client; | 899 | struct i2c_client *client = data->client; |
950 | int nr = attr->nr; | 900 | struct reg *regp = ®[index]; |
951 | int index = attr->index; | ||
952 | long val; | ||
953 | int err; | 901 | int err; |
954 | 902 | ||
955 | err = kstrtol(buf, 10, &val); | ||
956 | if (err < 0) | ||
957 | return err; | ||
958 | |||
959 | /* +16 degrees offset for temp2 for the LM99 */ | 903 | /* +16 degrees offset for temp2 for the LM99 */ |
960 | if (data->kind == lm99 && index <= 2) | 904 | if (data->kind == lm99 && index <= 2) |
961 | val -= 16000; | 905 | val -= 16000; |
962 | 906 | ||
963 | mutex_lock(&data->update_lock); | ||
964 | if (data->kind == adt7461 || data->kind == tmp451) | 907 | if (data->kind == adt7461 || data->kind == tmp451) |
965 | data->temp11[index] = temp_to_u16_adt7461(data, val); | 908 | data->temp11[index] = temp_to_u16_adt7461(data, val); |
966 | else if (data->kind == max6646) | 909 | else if (data->kind == max6646) |
@@ -970,317 +913,383 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
970 | else | 913 | else |
971 | data->temp11[index] = temp_to_s8(val) << 8; | 914 | data->temp11[index] = temp_to_s8(val) << 8; |
972 | 915 | ||
973 | lm90_select_remote_channel(client, data, reg[nr].channel); | 916 | lm90_select_remote_channel(client, data, index >= 3); |
974 | i2c_smbus_write_byte_data(client, reg[nr].high, | 917 | err = i2c_smbus_write_byte_data(client, regp->high, |
975 | data->temp11[index] >> 8); | 918 | data->temp11[index] >> 8); |
919 | if (err < 0) | ||
920 | return err; | ||
976 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) | 921 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) |
977 | i2c_smbus_write_byte_data(client, reg[nr].low, | 922 | err = i2c_smbus_write_byte_data(client, regp->low, |
978 | data->temp11[index] & 0xff); | 923 | data->temp11[index] & 0xff); |
979 | lm90_select_remote_channel(client, data, 0); | ||
980 | 924 | ||
981 | mutex_unlock(&data->update_lock); | 925 | lm90_select_remote_channel(client, data, 0); |
982 | return count; | 926 | return err; |
983 | } | 927 | } |
984 | 928 | ||
985 | static ssize_t show_temphyst(struct device *dev, | 929 | static int lm90_get_temp8(struct lm90_data *data, int index) |
986 | struct device_attribute *devattr, | ||
987 | char *buf) | ||
988 | { | 930 | { |
989 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 931 | s8 temp8 = data->temp8[index]; |
990 | struct lm90_data *data = lm90_update_device(dev); | ||
991 | int temp; | 932 | int temp; |
992 | 933 | ||
993 | if (IS_ERR(data)) | ||
994 | return PTR_ERR(data); | ||
995 | |||
996 | if (data->kind == adt7461 || data->kind == tmp451) | 934 | if (data->kind == adt7461 || data->kind == tmp451) |
997 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | 935 | temp = temp_from_u8_adt7461(data, temp8); |
998 | else if (data->kind == max6646) | 936 | else if (data->kind == max6646) |
999 | temp = temp_from_u8(data->temp8[attr->index]); | 937 | temp = temp_from_u8(temp8); |
1000 | else | 938 | else |
1001 | temp = temp_from_s8(data->temp8[attr->index]); | 939 | temp = temp_from_s8(temp8); |
1002 | 940 | ||
1003 | /* +16 degrees offset for temp2 for the LM99 */ | 941 | /* +16 degrees offset for temp2 for the LM99 */ |
1004 | if (data->kind == lm99 && attr->index == 3) | 942 | if (data->kind == lm99 && index == 3) |
1005 | temp += 16000; | 943 | temp += 16000; |
1006 | 944 | ||
1007 | return sprintf(buf, "%d\n", temp - temp_from_s8(data->temp_hyst)); | 945 | return temp; |
1008 | } | 946 | } |
1009 | 947 | ||
1010 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | 948 | static int lm90_set_temp8(struct lm90_data *data, int index, long val) |
1011 | const char *buf, size_t count) | ||
1012 | { | 949 | { |
1013 | struct lm90_data *data = dev_get_drvdata(dev); | 950 | static const u8 reg[TEMP8_REG_NUM] = { |
951 | LM90_REG_W_LOCAL_LOW, | ||
952 | LM90_REG_W_LOCAL_HIGH, | ||
953 | LM90_REG_W_LOCAL_CRIT, | ||
954 | LM90_REG_W_REMOTE_CRIT, | ||
955 | MAX6659_REG_W_LOCAL_EMERG, | ||
956 | MAX6659_REG_W_REMOTE_EMERG, | ||
957 | LM90_REG_W_REMOTE_CRIT, | ||
958 | MAX6659_REG_W_REMOTE_EMERG, | ||
959 | }; | ||
1014 | struct i2c_client *client = data->client; | 960 | struct i2c_client *client = data->client; |
1015 | long val; | ||
1016 | int err; | 961 | int err; |
1017 | int temp; | ||
1018 | 962 | ||
1019 | err = kstrtol(buf, 10, &val); | 963 | /* +16 degrees offset for temp2 for the LM99 */ |
1020 | if (err < 0) | 964 | if (data->kind == lm99 && index == 3) |
1021 | return err; | 965 | val -= 16000; |
1022 | 966 | ||
1023 | mutex_lock(&data->update_lock); | ||
1024 | if (data->kind == adt7461 || data->kind == tmp451) | 967 | if (data->kind == adt7461 || data->kind == tmp451) |
1025 | temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]); | 968 | data->temp8[index] = temp_to_u8_adt7461(data, val); |
1026 | else if (data->kind == max6646) | 969 | else if (data->kind == max6646) |
1027 | temp = temp_from_u8(data->temp8[LOCAL_CRIT]); | 970 | data->temp8[index] = temp_to_u8(val); |
1028 | else | 971 | else |
1029 | temp = temp_from_s8(data->temp8[LOCAL_CRIT]); | 972 | data->temp8[index] = temp_to_s8(val); |
1030 | 973 | ||
1031 | data->temp_hyst = hyst_to_reg(temp - val); | 974 | lm90_select_remote_channel(client, data, index >= 6); |
1032 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | 975 | err = i2c_smbus_write_byte_data(client, reg[index], data->temp8[index]); |
1033 | data->temp_hyst); | 976 | lm90_select_remote_channel(client, data, 0); |
1034 | mutex_unlock(&data->update_lock); | ||
1035 | return count; | ||
1036 | } | ||
1037 | |||
1038 | static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, | ||
1039 | char *buf) | ||
1040 | { | ||
1041 | struct lm90_data *data = lm90_update_device(dev); | ||
1042 | |||
1043 | if (IS_ERR(data)) | ||
1044 | return PTR_ERR(data); | ||
1045 | 977 | ||
1046 | return sprintf(buf, "%d\n", data->alarms); | 978 | return err; |
1047 | } | 979 | } |
1048 | 980 | ||
1049 | static ssize_t show_alarm(struct device *dev, struct device_attribute | 981 | static int lm90_get_temphyst(struct lm90_data *data, int index) |
1050 | *devattr, char *buf) | ||
1051 | { | 982 | { |
1052 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 983 | int temp; |
1053 | struct lm90_data *data = lm90_update_device(dev); | ||
1054 | int bitnr = attr->index; | ||
1055 | |||
1056 | if (IS_ERR(data)) | ||
1057 | return PTR_ERR(data); | ||
1058 | 984 | ||
1059 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | 985 | if (data->kind == adt7461 || data->kind == tmp451) |
1060 | } | 986 | temp = temp_from_u8_adt7461(data, data->temp8[index]); |
987 | else if (data->kind == max6646) | ||
988 | temp = temp_from_u8(data->temp8[index]); | ||
989 | else | ||
990 | temp = temp_from_s8(data->temp8[index]); | ||
1061 | 991 | ||
1062 | static ssize_t show_update_interval(struct device *dev, | 992 | /* +16 degrees offset for temp2 for the LM99 */ |
1063 | struct device_attribute *attr, char *buf) | 993 | if (data->kind == lm99 && index == 3) |
1064 | { | 994 | temp += 16000; |
1065 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1066 | 995 | ||
1067 | return sprintf(buf, "%u\n", data->update_interval); | 996 | return temp - temp_from_s8(data->temp_hyst); |
1068 | } | 997 | } |
1069 | 998 | ||
1070 | static ssize_t set_update_interval(struct device *dev, | 999 | static int lm90_set_temphyst(struct lm90_data *data, long val) |
1071 | struct device_attribute *attr, | ||
1072 | const char *buf, size_t count) | ||
1073 | { | 1000 | { |
1074 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1075 | struct i2c_client *client = data->client; | 1001 | struct i2c_client *client = data->client; |
1076 | unsigned long val; | 1002 | int temp; |
1077 | int err; | 1003 | int err; |
1078 | 1004 | ||
1079 | err = kstrtoul(buf, 10, &val); | 1005 | if (data->kind == adt7461 || data->kind == tmp451) |
1080 | if (err) | 1006 | temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]); |
1081 | return err; | 1007 | else if (data->kind == max6646) |
1082 | 1008 | temp = temp_from_u8(data->temp8[LOCAL_CRIT]); | |
1083 | mutex_lock(&data->update_lock); | 1009 | else |
1084 | lm90_set_convrate(client, data, clamp_val(val, 0, 100000)); | 1010 | temp = temp_from_s8(data->temp8[LOCAL_CRIT]); |
1085 | mutex_unlock(&data->update_lock); | ||
1086 | 1011 | ||
1087 | return count; | 1012 | data->temp_hyst = hyst_to_reg(temp - val); |
1013 | err = i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | ||
1014 | data->temp_hyst); | ||
1015 | return err; | ||
1088 | } | 1016 | } |
1089 | 1017 | ||
1090 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp11, NULL, | 1018 | static const u8 lm90_temp_index[3] = { |
1091 | 0, LOCAL_TEMP); | 1019 | LOCAL_TEMP, REMOTE_TEMP, REMOTE2_TEMP |
1092 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp11, NULL, | ||
1093 | 0, REMOTE_TEMP); | ||
1094 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, | ||
1095 | set_temp8, LOCAL_LOW); | ||
1096 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp11, | ||
1097 | set_temp11, 0, REMOTE_LOW); | ||
1098 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, | ||
1099 | set_temp8, LOCAL_HIGH); | ||
1100 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp11, | ||
1101 | set_temp11, 1, REMOTE_HIGH); | ||
1102 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1103 | set_temp8, LOCAL_CRIT); | ||
1104 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1105 | set_temp8, REMOTE_CRIT); | ||
1106 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | ||
1107 | set_temphyst, LOCAL_CRIT); | ||
1108 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, | ||
1109 | REMOTE_CRIT); | ||
1110 | static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, | ||
1111 | set_temp11, 2, REMOTE_OFFSET); | ||
1112 | |||
1113 | /* Individual alarm files */ | ||
1114 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
1115 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
1116 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); | ||
1117 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
1118 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
1119 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
1120 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
1121 | /* Raw alarm file for compatibility */ | ||
1122 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
1123 | |||
1124 | static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, | ||
1125 | set_update_interval); | ||
1126 | |||
1127 | static struct attribute *lm90_attributes[] = { | ||
1128 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1129 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1130 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
1131 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1132 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
1133 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1134 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
1135 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
1136 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
1137 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
1138 | |||
1139 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
1140 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
1141 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
1142 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
1143 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
1144 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
1145 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
1146 | &dev_attr_alarms.attr, | ||
1147 | &dev_attr_update_interval.attr, | ||
1148 | NULL | ||
1149 | }; | 1020 | }; |
1150 | 1021 | ||
1151 | static const struct attribute_group lm90_group = { | 1022 | static const u8 lm90_temp_min_index[3] = { |
1152 | .attrs = lm90_attributes, | 1023 | LOCAL_LOW, REMOTE_LOW, REMOTE2_LOW |
1153 | }; | 1024 | }; |
1154 | 1025 | ||
1155 | static struct attribute *lm90_temp2_offset_attributes[] = { | 1026 | static const u8 lm90_temp_max_index[3] = { |
1156 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 1027 | LOCAL_HIGH, REMOTE_HIGH, REMOTE2_HIGH |
1157 | NULL | ||
1158 | }; | 1028 | }; |
1159 | 1029 | ||
1160 | static const struct attribute_group lm90_temp2_offset_group = { | 1030 | static const u8 lm90_temp_crit_index[3] = { |
1161 | .attrs = lm90_temp2_offset_attributes, | 1031 | LOCAL_CRIT, REMOTE_CRIT, REMOTE2_CRIT |
1162 | }; | 1032 | }; |
1163 | 1033 | ||
1164 | /* | 1034 | static const u8 lm90_temp_emerg_index[3] = { |
1165 | * Additional attributes for devices with emergency sensors | 1035 | LOCAL_EMERG, REMOTE_EMERG, REMOTE2_EMERG |
1166 | */ | ||
1167 | static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1168 | set_temp8, LOCAL_EMERG); | ||
1169 | static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1170 | set_temp8, REMOTE_EMERG); | ||
1171 | static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO, show_temphyst, | ||
1172 | NULL, LOCAL_EMERG); | ||
1173 | static SENSOR_DEVICE_ATTR(temp2_emergency_hyst, S_IRUGO, show_temphyst, | ||
1174 | NULL, REMOTE_EMERG); | ||
1175 | |||
1176 | static struct attribute *lm90_emergency_attributes[] = { | ||
1177 | &sensor_dev_attr_temp1_emergency.dev_attr.attr, | ||
1178 | &sensor_dev_attr_temp2_emergency.dev_attr.attr, | ||
1179 | &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, | ||
1180 | &sensor_dev_attr_temp2_emergency_hyst.dev_attr.attr, | ||
1181 | NULL | ||
1182 | }; | 1036 | }; |
1183 | 1037 | ||
1184 | static const struct attribute_group lm90_emergency_group = { | 1038 | static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 }; |
1185 | .attrs = lm90_emergency_attributes, | 1039 | static const u8 lm90_max_alarm_bits[3] = { 0, 4, 12 }; |
1186 | }; | 1040 | static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 }; |
1041 | static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 }; | ||
1042 | static const u8 lm90_fault_bits[3] = { 0, 2, 10 }; | ||
1187 | 1043 | ||
1188 | static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 15); | 1044 | static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val) |
1189 | static SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 13); | 1045 | { |
1046 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1047 | int err; | ||
1190 | 1048 | ||
1191 | static struct attribute *lm90_emergency_alarm_attributes[] = { | 1049 | mutex_lock(&data->update_lock); |
1192 | &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, | 1050 | err = lm90_update_device(dev); |
1193 | &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, | 1051 | mutex_unlock(&data->update_lock); |
1194 | NULL | 1052 | if (err) |
1195 | }; | 1053 | return err; |
1196 | 1054 | ||
1197 | static const struct attribute_group lm90_emergency_alarm_group = { | 1055 | switch (attr) { |
1198 | .attrs = lm90_emergency_alarm_attributes, | 1056 | case hwmon_temp_input: |
1199 | }; | 1057 | *val = lm90_get_temp11(data, lm90_temp_index[channel]); |
1058 | break; | ||
1059 | case hwmon_temp_min_alarm: | ||
1060 | *val = (data->alarms >> lm90_min_alarm_bits[channel]) & 1; | ||
1061 | break; | ||
1062 | case hwmon_temp_max_alarm: | ||
1063 | *val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1; | ||
1064 | break; | ||
1065 | case hwmon_temp_crit_alarm: | ||
1066 | *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; | ||
1067 | break; | ||
1068 | case hwmon_temp_emergency_alarm: | ||
1069 | *val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1; | ||
1070 | break; | ||
1071 | case hwmon_temp_fault: | ||
1072 | *val = (data->alarms >> lm90_fault_bits[channel]) & 1; | ||
1073 | break; | ||
1074 | case hwmon_temp_min: | ||
1075 | if (channel == 0) | ||
1076 | *val = lm90_get_temp8(data, | ||
1077 | lm90_temp_min_index[channel]); | ||
1078 | else | ||
1079 | *val = lm90_get_temp11(data, | ||
1080 | lm90_temp_min_index[channel]); | ||
1081 | break; | ||
1082 | case hwmon_temp_max: | ||
1083 | if (channel == 0) | ||
1084 | *val = lm90_get_temp8(data, | ||
1085 | lm90_temp_max_index[channel]); | ||
1086 | else | ||
1087 | *val = lm90_get_temp11(data, | ||
1088 | lm90_temp_max_index[channel]); | ||
1089 | break; | ||
1090 | case hwmon_temp_crit: | ||
1091 | *val = lm90_get_temp8(data, lm90_temp_crit_index[channel]); | ||
1092 | break; | ||
1093 | case hwmon_temp_crit_hyst: | ||
1094 | *val = lm90_get_temphyst(data, lm90_temp_crit_index[channel]); | ||
1095 | break; | ||
1096 | case hwmon_temp_emergency: | ||
1097 | *val = lm90_get_temp8(data, lm90_temp_emerg_index[channel]); | ||
1098 | break; | ||
1099 | case hwmon_temp_emergency_hyst: | ||
1100 | *val = lm90_get_temphyst(data, lm90_temp_emerg_index[channel]); | ||
1101 | break; | ||
1102 | case hwmon_temp_offset: | ||
1103 | *val = lm90_get_temp11(data, REMOTE_OFFSET); | ||
1104 | break; | ||
1105 | default: | ||
1106 | return -EOPNOTSUPP; | ||
1107 | } | ||
1108 | return 0; | ||
1109 | } | ||
1200 | 1110 | ||
1201 | /* | 1111 | static int lm90_temp_write(struct device *dev, u32 attr, int channel, long val) |
1202 | * Additional attributes for devices with 3 temperature sensors | 1112 | { |
1203 | */ | 1113 | struct lm90_data *data = dev_get_drvdata(dev); |
1204 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp11, NULL, | 1114 | int err; |
1205 | 0, REMOTE2_TEMP); | ||
1206 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp11, | ||
1207 | set_temp11, 3, REMOTE2_LOW); | ||
1208 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp11, | ||
1209 | set_temp11, 4, REMOTE2_HIGH); | ||
1210 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1211 | set_temp8, REMOTE2_CRIT); | ||
1212 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temphyst, NULL, | ||
1213 | REMOTE2_CRIT); | ||
1214 | static SENSOR_DEVICE_ATTR(temp3_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1215 | set_temp8, REMOTE2_EMERG); | ||
1216 | static SENSOR_DEVICE_ATTR(temp3_emergency_hyst, S_IRUGO, show_temphyst, | ||
1217 | NULL, REMOTE2_EMERG); | ||
1218 | |||
1219 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
1220 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 10); | ||
1221 | static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
1222 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
1223 | static SENSOR_DEVICE_ATTR(temp3_emergency_alarm, S_IRUGO, show_alarm, NULL, 14); | ||
1224 | |||
1225 | static struct attribute *lm90_temp3_attributes[] = { | ||
1226 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1227 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1228 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1229 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
1230 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
1231 | &sensor_dev_attr_temp3_emergency.dev_attr.attr, | ||
1232 | &sensor_dev_attr_temp3_emergency_hyst.dev_attr.attr, | ||
1233 | |||
1234 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
1235 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
1237 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
1238 | &sensor_dev_attr_temp3_emergency_alarm.dev_attr.attr, | ||
1239 | NULL | ||
1240 | }; | ||
1241 | 1115 | ||
1242 | static const struct attribute_group lm90_temp3_group = { | 1116 | mutex_lock(&data->update_lock); |
1243 | .attrs = lm90_temp3_attributes, | ||
1244 | }; | ||
1245 | 1117 | ||
1246 | /* pec used for ADM1032 only */ | 1118 | err = lm90_update_device(dev); |
1247 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, | 1119 | if (err) |
1248 | char *buf) | 1120 | goto error; |
1121 | |||
1122 | switch (attr) { | ||
1123 | case hwmon_temp_min: | ||
1124 | if (channel == 0) | ||
1125 | err = lm90_set_temp8(data, | ||
1126 | lm90_temp_min_index[channel], | ||
1127 | val); | ||
1128 | else | ||
1129 | err = lm90_set_temp11(data, | ||
1130 | lm90_temp_min_index[channel], | ||
1131 | val); | ||
1132 | break; | ||
1133 | case hwmon_temp_max: | ||
1134 | if (channel == 0) | ||
1135 | err = lm90_set_temp8(data, | ||
1136 | lm90_temp_max_index[channel], | ||
1137 | val); | ||
1138 | else | ||
1139 | err = lm90_set_temp11(data, | ||
1140 | lm90_temp_max_index[channel], | ||
1141 | val); | ||
1142 | break; | ||
1143 | case hwmon_temp_crit: | ||
1144 | err = lm90_set_temp8(data, lm90_temp_crit_index[channel], val); | ||
1145 | break; | ||
1146 | case hwmon_temp_crit_hyst: | ||
1147 | err = lm90_set_temphyst(data, val); | ||
1148 | break; | ||
1149 | case hwmon_temp_emergency: | ||
1150 | err = lm90_set_temp8(data, lm90_temp_emerg_index[channel], val); | ||
1151 | break; | ||
1152 | case hwmon_temp_offset: | ||
1153 | err = lm90_set_temp11(data, REMOTE_OFFSET, val); | ||
1154 | break; | ||
1155 | default: | ||
1156 | err = -EOPNOTSUPP; | ||
1157 | break; | ||
1158 | } | ||
1159 | error: | ||
1160 | mutex_unlock(&data->update_lock); | ||
1161 | |||
1162 | return err; | ||
1163 | } | ||
1164 | |||
1165 | static umode_t lm90_temp_is_visible(const void *data, u32 attr, int channel) | ||
1249 | { | 1166 | { |
1250 | struct i2c_client *client = to_i2c_client(dev); | 1167 | switch (attr) { |
1251 | return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); | 1168 | case hwmon_temp_input: |
1169 | case hwmon_temp_min_alarm: | ||
1170 | case hwmon_temp_max_alarm: | ||
1171 | case hwmon_temp_crit_alarm: | ||
1172 | case hwmon_temp_emergency_alarm: | ||
1173 | case hwmon_temp_emergency_hyst: | ||
1174 | case hwmon_temp_fault: | ||
1175 | return S_IRUGO; | ||
1176 | case hwmon_temp_min: | ||
1177 | case hwmon_temp_max: | ||
1178 | case hwmon_temp_crit: | ||
1179 | case hwmon_temp_emergency: | ||
1180 | case hwmon_temp_offset: | ||
1181 | return S_IRUGO | S_IWUSR; | ||
1182 | case hwmon_temp_crit_hyst: | ||
1183 | if (channel == 0) | ||
1184 | return S_IRUGO | S_IWUSR; | ||
1185 | return S_IRUGO; | ||
1186 | default: | ||
1187 | return 0; | ||
1188 | } | ||
1252 | } | 1189 | } |
1253 | 1190 | ||
1254 | static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, | 1191 | static int lm90_chip_read(struct device *dev, u32 attr, int channel, long *val) |
1255 | const char *buf, size_t count) | ||
1256 | { | 1192 | { |
1257 | struct i2c_client *client = to_i2c_client(dev); | 1193 | struct lm90_data *data = dev_get_drvdata(dev); |
1258 | long val; | ||
1259 | int err; | 1194 | int err; |
1260 | 1195 | ||
1261 | err = kstrtol(buf, 10, &val); | 1196 | mutex_lock(&data->update_lock); |
1262 | if (err < 0) | 1197 | err = lm90_update_device(dev); |
1198 | mutex_unlock(&data->update_lock); | ||
1199 | if (err) | ||
1263 | return err; | 1200 | return err; |
1264 | 1201 | ||
1265 | switch (val) { | 1202 | switch (attr) { |
1266 | case 0: | 1203 | case hwmon_chip_update_interval: |
1267 | client->flags &= ~I2C_CLIENT_PEC; | 1204 | *val = data->update_interval; |
1268 | break; | 1205 | break; |
1269 | case 1: | 1206 | case hwmon_chip_alarms: |
1270 | client->flags |= I2C_CLIENT_PEC; | 1207 | *val = data->alarms; |
1271 | break; | 1208 | break; |
1272 | default: | 1209 | default: |
1273 | return -EINVAL; | 1210 | return -EOPNOTSUPP; |
1274 | } | 1211 | } |
1275 | 1212 | ||
1276 | return count; | 1213 | return 0; |
1277 | } | 1214 | } |
1278 | 1215 | ||
1279 | static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | 1216 | static int lm90_chip_write(struct device *dev, u32 attr, int channel, long val) |
1217 | { | ||
1218 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1219 | struct i2c_client *client = data->client; | ||
1220 | int err; | ||
1280 | 1221 | ||
1281 | /* | 1222 | mutex_lock(&data->update_lock); |
1282 | * Real code | 1223 | |
1283 | */ | 1224 | err = lm90_update_device(dev); |
1225 | if (err) | ||
1226 | goto error; | ||
1227 | |||
1228 | switch (attr) { | ||
1229 | case hwmon_chip_update_interval: | ||
1230 | err = lm90_set_convrate(client, data, | ||
1231 | clamp_val(val, 0, 100000)); | ||
1232 | break; | ||
1233 | default: | ||
1234 | err = -EOPNOTSUPP; | ||
1235 | break; | ||
1236 | } | ||
1237 | error: | ||
1238 | mutex_unlock(&data->update_lock); | ||
1239 | |||
1240 | return err; | ||
1241 | } | ||
1242 | |||
1243 | static umode_t lm90_chip_is_visible(const void *data, u32 attr, int channel) | ||
1244 | { | ||
1245 | switch (attr) { | ||
1246 | case hwmon_chip_update_interval: | ||
1247 | return S_IRUGO | S_IWUSR; | ||
1248 | case hwmon_chip_alarms: | ||
1249 | return S_IRUGO; | ||
1250 | default: | ||
1251 | return 0; | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1255 | static int lm90_read(struct device *dev, enum hwmon_sensor_types type, | ||
1256 | u32 attr, int channel, long *val) | ||
1257 | { | ||
1258 | switch (type) { | ||
1259 | case hwmon_chip: | ||
1260 | return lm90_chip_read(dev, attr, channel, val); | ||
1261 | case hwmon_temp: | ||
1262 | return lm90_temp_read(dev, attr, channel, val); | ||
1263 | default: | ||
1264 | return -EOPNOTSUPP; | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | static int lm90_write(struct device *dev, enum hwmon_sensor_types type, | ||
1269 | u32 attr, int channel, long val) | ||
1270 | { | ||
1271 | switch (type) { | ||
1272 | case hwmon_chip: | ||
1273 | return lm90_chip_write(dev, attr, channel, val); | ||
1274 | case hwmon_temp: | ||
1275 | return lm90_temp_write(dev, attr, channel, val); | ||
1276 | default: | ||
1277 | return -EOPNOTSUPP; | ||
1278 | } | ||
1279 | } | ||
1280 | |||
1281 | static umode_t lm90_is_visible(const void *data, enum hwmon_sensor_types type, | ||
1282 | u32 attr, int channel) | ||
1283 | { | ||
1284 | switch (type) { | ||
1285 | case hwmon_chip: | ||
1286 | return lm90_chip_is_visible(data, attr, channel); | ||
1287 | case hwmon_temp: | ||
1288 | return lm90_temp_is_visible(data, attr, channel); | ||
1289 | default: | ||
1290 | return 0; | ||
1291 | } | ||
1292 | } | ||
1284 | 1293 | ||
1285 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1294 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1286 | static int lm90_detect(struct i2c_client *client, | 1295 | static int lm90_detect(struct i2c_client *client, |
@@ -1617,15 +1626,32 @@ static void lm90_regulator_disable(void *regulator) | |||
1617 | regulator_disable(regulator); | 1626 | regulator_disable(regulator); |
1618 | } | 1627 | } |
1619 | 1628 | ||
1629 | static const u32 lm90_chip_config[] = { | ||
1630 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS, | ||
1631 | 0 | ||
1632 | }; | ||
1633 | |||
1634 | static const struct hwmon_channel_info lm90_chip_info = { | ||
1635 | .type = hwmon_chip, | ||
1636 | .config = lm90_chip_config, | ||
1637 | }; | ||
1638 | |||
1639 | |||
1640 | static const struct hwmon_ops lm90_ops = { | ||
1641 | .is_visible = lm90_is_visible, | ||
1642 | .read = lm90_read, | ||
1643 | .write = lm90_write, | ||
1644 | }; | ||
1645 | |||
1620 | static int lm90_probe(struct i2c_client *client, | 1646 | static int lm90_probe(struct i2c_client *client, |
1621 | const struct i2c_device_id *id) | 1647 | const struct i2c_device_id *id) |
1622 | { | 1648 | { |
1623 | struct device *dev = &client->dev; | 1649 | struct device *dev = &client->dev; |
1624 | struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); | 1650 | struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); |
1625 | struct lm90_data *data; | 1651 | struct hwmon_channel_info *info; |
1626 | struct regulator *regulator; | 1652 | struct regulator *regulator; |
1627 | struct device *hwmon_dev; | 1653 | struct device *hwmon_dev; |
1628 | int groups = 0; | 1654 | struct lm90_data *data; |
1629 | int err; | 1655 | int err; |
1630 | 1656 | ||
1631 | regulator = devm_regulator_get(dev, "vcc"); | 1657 | regulator = devm_regulator_get(dev, "vcc"); |
@@ -1665,6 +1691,49 @@ static int lm90_probe(struct i2c_client *client, | |||
1665 | 1691 | ||
1666 | /* Set chip capabilities */ | 1692 | /* Set chip capabilities */ |
1667 | data->flags = lm90_params[data->kind].flags; | 1693 | data->flags = lm90_params[data->kind].flags; |
1694 | |||
1695 | data->chip.ops = &lm90_ops; | ||
1696 | data->chip.info = data->info; | ||
1697 | |||
1698 | data->info[0] = &lm90_chip_info; | ||
1699 | data->info[1] = &data->temp_info; | ||
1700 | |||
1701 | info = &data->temp_info; | ||
1702 | info->type = hwmon_temp; | ||
1703 | info->config = data->channel_config; | ||
1704 | |||
1705 | data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | | ||
1706 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | | ||
1707 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM; | ||
1708 | data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | | ||
1709 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | | ||
1710 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT; | ||
1711 | |||
1712 | if (data->flags & LM90_HAVE_OFFSET) | ||
1713 | data->channel_config[1] |= HWMON_T_OFFSET; | ||
1714 | |||
1715 | if (data->flags & LM90_HAVE_EMERGENCY) { | ||
1716 | data->channel_config[0] |= HWMON_T_EMERGENCY | | ||
1717 | HWMON_T_EMERGENCY_HYST; | ||
1718 | data->channel_config[1] |= HWMON_T_EMERGENCY | | ||
1719 | HWMON_T_EMERGENCY_HYST; | ||
1720 | } | ||
1721 | |||
1722 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { | ||
1723 | data->channel_config[0] |= HWMON_T_EMERGENCY_ALARM; | ||
1724 | data->channel_config[1] |= HWMON_T_EMERGENCY_ALARM; | ||
1725 | } | ||
1726 | |||
1727 | if (data->flags & LM90_HAVE_TEMP3) { | ||
1728 | data->channel_config[2] = HWMON_T_INPUT | | ||
1729 | HWMON_T_MIN | HWMON_T_MAX | | ||
1730 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | | ||
1731 | HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST | | ||
1732 | HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | | ||
1733 | HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY_ALARM | | ||
1734 | HWMON_T_FAULT; | ||
1735 | } | ||
1736 | |||
1668 | data->reg_local_ext = lm90_params[data->kind].reg_local_ext; | 1737 | data->reg_local_ext = lm90_params[data->kind].reg_local_ext; |
1669 | 1738 | ||
1670 | /* Set maximum conversion rate */ | 1739 | /* Set maximum conversion rate */ |
@@ -1677,21 +1746,10 @@ static int lm90_probe(struct i2c_client *client, | |||
1677 | return err; | 1746 | return err; |
1678 | } | 1747 | } |
1679 | 1748 | ||
1680 | /* Register sysfs hooks */ | 1749 | /* |
1681 | data->groups[groups++] = &lm90_group; | 1750 | * The 'pec' attribute is attached to the i2c device and thus created |
1682 | 1751 | * separately. | |
1683 | if (data->flags & LM90_HAVE_OFFSET) | 1752 | */ |
1684 | data->groups[groups++] = &lm90_temp2_offset_group; | ||
1685 | |||
1686 | if (data->flags & LM90_HAVE_EMERGENCY) | ||
1687 | data->groups[groups++] = &lm90_emergency_group; | ||
1688 | |||
1689 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) | ||
1690 | data->groups[groups++] = &lm90_emergency_alarm_group; | ||
1691 | |||
1692 | if (data->flags & LM90_HAVE_TEMP3) | ||
1693 | data->groups[groups++] = &lm90_temp3_group; | ||
1694 | |||
1695 | if (client->flags & I2C_CLIENT_PEC) { | 1753 | if (client->flags & I2C_CLIENT_PEC) { |
1696 | err = device_create_file(dev, &dev_attr_pec); | 1754 | err = device_create_file(dev, &dev_attr_pec); |
1697 | if (err) | 1755 | if (err) |
@@ -1701,8 +1759,9 @@ static int lm90_probe(struct i2c_client *client, | |||
1701 | return err; | 1759 | return err; |
1702 | } | 1760 | } |
1703 | 1761 | ||
1704 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 1762 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
1705 | data, data->groups); | 1763 | data, &data->chip, |
1764 | NULL); | ||
1706 | if (IS_ERR(hwmon_dev)) | 1765 | if (IS_ERR(hwmon_dev)) |
1707 | return PTR_ERR(hwmon_dev); | 1766 | return PTR_ERR(hwmon_dev); |
1708 | 1767 | ||