diff options
| -rw-r--r-- | drivers/hwmon/amc6821.c | 2 | ||||
| -rw-r--r-- | drivers/hwmon/lm93.c | 4 | ||||
| -rw-r--r-- | drivers/hwmon/lm95241.c | 19 | ||||
| -rw-r--r-- | drivers/hwmon/max6650.c | 2 | ||||
| -rw-r--r-- | drivers/hwmon/w83795.c | 207 |
5 files changed, 192 insertions, 42 deletions
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index fa9708c2d723..4033974d1bb3 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> | 4 | Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> |
| 5 | 5 | ||
| 6 | Based on max6650.c: | 6 | Based on max6650.c: |
| 7 | Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de> | 7 | Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de> |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 6669255aadcf..c9ed14eba5a6 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> | 20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> |
| 21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab | 21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab |
| 22 | 22 | ||
| 23 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | 23 | Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de> |
| 24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH | 24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH |
| 25 | 25 | ||
| 26 | This program is free software; you can redistribute it and/or modify | 26 | This program is free software; you can redistribute it and/or modify |
| @@ -2629,7 +2629,7 @@ static void __exit lm93_exit(void) | |||
| 2629 | } | 2629 | } |
| 2630 | 2630 | ||
| 2631 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " | 2631 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " |
| 2632 | "Hans J. Koch <hjk@linutronix.de"); | 2632 | "Hans J. Koch <hjk@hansjkoch.de>"); |
| 2633 | MODULE_DESCRIPTION("LM93 driver"); | 2633 | MODULE_DESCRIPTION("LM93 driver"); |
| 2634 | MODULE_LICENSE("GPL"); | 2634 | MODULE_LICENSE("GPL"); |
| 2635 | 2635 | ||
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 464340f25496..4546d82f024a 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
| @@ -128,9 +128,12 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr, | |||
| 128 | { | 128 | { |
| 129 | struct i2c_client *client = to_i2c_client(dev); | 129 | struct i2c_client *client = to_i2c_client(dev); |
| 130 | struct lm95241_data *data = i2c_get_clientdata(client); | 130 | struct lm95241_data *data = i2c_get_clientdata(client); |
| 131 | unsigned long val; | ||
| 131 | 132 | ||
| 132 | strict_strtol(buf, 10, &data->interval); | 133 | if (strict_strtoul(buf, 10, &val) < 0) |
| 133 | data->interval = data->interval * HZ / 1000; | 134 | return -EINVAL; |
| 135 | |||
| 136 | data->interval = val * HZ / 1000; | ||
| 134 | 137 | ||
| 135 | return count; | 138 | return count; |
| 136 | } | 139 | } |
| @@ -188,7 +191,9 @@ static ssize_t set_type##flag(struct device *dev, \ | |||
| 188 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 191 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
| 189 | \ | 192 | \ |
| 190 | long val; \ | 193 | long val; \ |
| 191 | strict_strtol(buf, 10, &val); \ | 194 | \ |
| 195 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
| 196 | return -EINVAL; \ | ||
| 192 | \ | 197 | \ |
| 193 | if ((val == 1) || (val == 2)) { \ | 198 | if ((val == 1) || (val == 2)) { \ |
| 194 | \ | 199 | \ |
| @@ -227,7 +232,9 @@ static ssize_t set_min##flag(struct device *dev, \ | |||
| 227 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 232 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
| 228 | \ | 233 | \ |
| 229 | long val; \ | 234 | long val; \ |
| 230 | strict_strtol(buf, 10, &val); \ | 235 | \ |
| 236 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
| 237 | return -EINVAL;\ | ||
| 231 | \ | 238 | \ |
| 232 | mutex_lock(&data->update_lock); \ | 239 | mutex_lock(&data->update_lock); \ |
| 233 | \ | 240 | \ |
| @@ -256,7 +263,9 @@ static ssize_t set_max##flag(struct device *dev, \ | |||
| 256 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 263 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
| 257 | \ | 264 | \ |
| 258 | long val; \ | 265 | long val; \ |
| 259 | strict_strtol(buf, 10, &val); \ | 266 | \ |
| 267 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
| 268 | return -EINVAL; \ | ||
| 260 | \ | 269 | \ |
| 261 | mutex_lock(&data->update_lock); \ | 270 | mutex_lock(&data->update_lock); \ |
| 262 | \ | 271 | \ |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index a0160ee5caef..9a11532ecae8 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware |
| 3 | * monitoring. | 3 | * monitoring. |
| 4 | * | 4 | * |
| 5 | * (C) 2007 by Hans J. Koch <hjk@linutronix.de> | 5 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> |
| 6 | * | 6 | * |
| 7 | * based on code written by John Morris <john.morris@spirentcom.com> | 7 | * based on code written by John Morris <john.morris@spirentcom.com> |
| 8 | * Copyright (c) 2003 Spirent Communications | 8 | * Copyright (c) 2003 Spirent Communications |
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index 1d840aa83782..cdbc7448491e 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
| @@ -165,10 +165,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { | |||
| 165 | 165 | ||
| 166 | #define W83795_REG_VID_CTRL 0x6A | 166 | #define W83795_REG_VID_CTRL 0x6A |
| 167 | 167 | ||
| 168 | #define W83795_REG_ALARM_CTRL 0x40 | ||
| 169 | #define ALARM_CTRL_RTSACS (1 << 7) | ||
| 168 | #define W83795_REG_ALARM(index) (0x41 + (index)) | 170 | #define W83795_REG_ALARM(index) (0x41 + (index)) |
| 171 | #define W83795_REG_CLR_CHASSIS 0x4D | ||
| 169 | #define W83795_REG_BEEP(index) (0x50 + (index)) | 172 | #define W83795_REG_BEEP(index) (0x50 + (index)) |
| 170 | 173 | ||
| 171 | #define W83795_REG_CLR_CHASSIS 0x4D | 174 | #define W83795_REG_OVT_CFG 0x58 |
| 175 | #define OVT_CFG_SEL (1 << 7) | ||
| 172 | 176 | ||
| 173 | 177 | ||
| 174 | #define W83795_REG_FCMS1 0x201 | 178 | #define W83795_REG_FCMS1 0x201 |
| @@ -178,6 +182,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { | |||
| 178 | 182 | ||
| 179 | #define W83795_REG_TSS(index) (0x209 + (index)) | 183 | #define W83795_REG_TSS(index) (0x209 + (index)) |
| 180 | 184 | ||
| 185 | #define TSS_MAP_RESERVED 0xff | ||
| 186 | static const u8 tss_map[4][6] = { | ||
| 187 | { 0, 1, 2, 3, 4, 5}, | ||
| 188 | { 6, 7, 8, 9, 0, 1}, | ||
| 189 | {10, 11, 12, 13, 2, 3}, | ||
| 190 | { 4, 5, 4, 5, TSS_MAP_RESERVED, TSS_MAP_RESERVED}, | ||
| 191 | }; | ||
| 192 | |||
| 181 | #define PWM_OUTPUT 0 | 193 | #define PWM_OUTPUT 0 |
| 182 | #define PWM_FREQ 1 | 194 | #define PWM_FREQ 1 |
| 183 | #define PWM_START 2 | 195 | #define PWM_START 2 |
| @@ -369,6 +381,7 @@ struct w83795_data { | |||
| 369 | u8 setup_pwm[3]; /* Register value */ | 381 | u8 setup_pwm[3]; /* Register value */ |
| 370 | 382 | ||
| 371 | u8 alarms[6]; /* Register value */ | 383 | u8 alarms[6]; /* Register value */ |
| 384 | u8 enable_beep; | ||
| 372 | u8 beeps[6]; /* Register value */ | 385 | u8 beeps[6]; /* Register value */ |
| 373 | 386 | ||
| 374 | char valid; | 387 | char valid; |
| @@ -499,8 +512,11 @@ static void w83795_update_limits(struct i2c_client *client) | |||
| 499 | } | 512 | } |
| 500 | 513 | ||
| 501 | /* Read beep settings */ | 514 | /* Read beep settings */ |
| 502 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) | 515 | if (data->enable_beep) { |
| 503 | data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i)); | 516 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) |
| 517 | data->beeps[i] = | ||
| 518 | w83795_read(client, W83795_REG_BEEP(i)); | ||
| 519 | } | ||
| 504 | 520 | ||
| 505 | data->valid_limits = 1; | 521 | data->valid_limits = 1; |
| 506 | } | 522 | } |
| @@ -577,6 +593,7 @@ static struct w83795_data *w83795_update_device(struct device *dev) | |||
| 577 | struct i2c_client *client = to_i2c_client(dev); | 593 | struct i2c_client *client = to_i2c_client(dev); |
| 578 | struct w83795_data *data = i2c_get_clientdata(client); | 594 | struct w83795_data *data = i2c_get_clientdata(client); |
| 579 | u16 tmp; | 595 | u16 tmp; |
| 596 | u8 intrusion; | ||
| 580 | int i; | 597 | int i; |
| 581 | 598 | ||
| 582 | mutex_lock(&data->update_lock); | 599 | mutex_lock(&data->update_lock); |
| @@ -648,9 +665,24 @@ static struct w83795_data *w83795_update_device(struct device *dev) | |||
| 648 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); | 665 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); |
| 649 | } | 666 | } |
| 650 | 667 | ||
| 651 | /* update alarm */ | 668 | /* Update intrusion and alarms |
| 669 | * It is important to read intrusion first, because reading from | ||
| 670 | * register SMI STS6 clears the interrupt status temporarily. */ | ||
| 671 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); | ||
| 672 | /* Switch to interrupt status for intrusion if needed */ | ||
| 673 | if (tmp & ALARM_CTRL_RTSACS) | ||
| 674 | w83795_write(client, W83795_REG_ALARM_CTRL, | ||
| 675 | tmp & ~ALARM_CTRL_RTSACS); | ||
| 676 | intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); | ||
| 677 | /* Switch to real-time alarms */ | ||
| 678 | w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); | ||
| 652 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) | 679 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) |
| 653 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); | 680 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); |
| 681 | data->alarms[5] |= intrusion; | ||
| 682 | /* Restore original configuration if needed */ | ||
| 683 | if (!(tmp & ALARM_CTRL_RTSACS)) | ||
| 684 | w83795_write(client, W83795_REG_ALARM_CTRL, | ||
| 685 | tmp & ~ALARM_CTRL_RTSACS); | ||
| 654 | 686 | ||
| 655 | data->last_updated = jiffies; | 687 | data->last_updated = jiffies; |
| 656 | data->valid = 1; | 688 | data->valid = 1; |
| @@ -730,6 +762,10 @@ store_chassis_clear(struct device *dev, | |||
| 730 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); | 762 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); |
| 731 | val |= 0x80; | 763 | val |= 0x80; |
| 732 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); | 764 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); |
| 765 | |||
| 766 | /* Clear status and force cache refresh */ | ||
| 767 | w83795_read(client, W83795_REG_ALARM(5)); | ||
| 768 | data->valid = 0; | ||
| 733 | mutex_unlock(&data->update_lock); | 769 | mutex_unlock(&data->update_lock); |
| 734 | return count; | 770 | return count; |
| 735 | } | 771 | } |
| @@ -857,20 +893,20 @@ show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 857 | int index = sensor_attr->index; | 893 | int index = sensor_attr->index; |
| 858 | u8 tmp; | 894 | u8 tmp; |
| 859 | 895 | ||
| 860 | if (1 == (data->pwm_fcms[0] & (1 << index))) { | 896 | /* Speed cruise mode */ |
| 897 | if (data->pwm_fcms[0] & (1 << index)) { | ||
| 861 | tmp = 2; | 898 | tmp = 2; |
| 862 | goto out; | 899 | goto out; |
| 863 | } | 900 | } |
| 901 | /* Thermal cruise or SmartFan IV mode */ | ||
| 864 | for (tmp = 0; tmp < 6; tmp++) { | 902 | for (tmp = 0; tmp < 6; tmp++) { |
| 865 | if (data->pwm_tfmr[tmp] & (1 << index)) { | 903 | if (data->pwm_tfmr[tmp] & (1 << index)) { |
| 866 | tmp = 3; | 904 | tmp = 3; |
| 867 | goto out; | 905 | goto out; |
| 868 | } | 906 | } |
| 869 | } | 907 | } |
| 870 | if (data->pwm_fomc & (1 << index)) | 908 | /* Manual mode */ |
| 871 | tmp = 0; | 909 | tmp = 1; |
| 872 | else | ||
| 873 | tmp = 1; | ||
| 874 | 910 | ||
| 875 | out: | 911 | out: |
| 876 | return sprintf(buf, "%u\n", tmp); | 912 | return sprintf(buf, "%u\n", tmp); |
| @@ -890,23 +926,21 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
| 890 | 926 | ||
| 891 | if (strict_strtoul(buf, 10, &val) < 0) | 927 | if (strict_strtoul(buf, 10, &val) < 0) |
| 892 | return -EINVAL; | 928 | return -EINVAL; |
| 893 | if (val > 2) | 929 | if (val < 1 || val > 2) |
| 894 | return -EINVAL; | 930 | return -EINVAL; |
| 895 | 931 | ||
| 896 | mutex_lock(&data->update_lock); | 932 | mutex_lock(&data->update_lock); |
| 897 | switch (val) { | 933 | switch (val) { |
| 898 | case 0: | ||
| 899 | case 1: | 934 | case 1: |
| 935 | /* Clear speed cruise mode bits */ | ||
| 900 | data->pwm_fcms[0] &= ~(1 << index); | 936 | data->pwm_fcms[0] &= ~(1 << index); |
| 901 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); | 937 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); |
| 938 | /* Clear thermal cruise mode bits */ | ||
| 902 | for (i = 0; i < 6; i++) { | 939 | for (i = 0; i < 6; i++) { |
| 903 | data->pwm_tfmr[i] &= ~(1 << index); | 940 | data->pwm_tfmr[i] &= ~(1 << index); |
| 904 | w83795_write(client, W83795_REG_TFMR(i), | 941 | w83795_write(client, W83795_REG_TFMR(i), |
| 905 | data->pwm_tfmr[i]); | 942 | data->pwm_tfmr[i]); |
| 906 | } | 943 | } |
| 907 | data->pwm_fomc |= 1 << index; | ||
| 908 | data->pwm_fomc ^= val << index; | ||
| 909 | w83795_write(client, W83795_REG_FOMC, data->pwm_fomc); | ||
| 910 | break; | 944 | break; |
| 911 | case 2: | 945 | case 2: |
| 912 | data->pwm_fcms[0] |= (1 << index); | 946 | data->pwm_fcms[0] |= (1 << index); |
| @@ -918,23 +952,60 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
| 918 | } | 952 | } |
| 919 | 953 | ||
| 920 | static ssize_t | 954 | static ssize_t |
| 955 | show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 956 | { | ||
| 957 | struct w83795_data *data = w83795_update_pwm_config(dev); | ||
| 958 | int index = to_sensor_dev_attr_2(attr)->index; | ||
| 959 | unsigned int mode; | ||
| 960 | |||
| 961 | if (data->pwm_fomc & (1 << index)) | ||
| 962 | mode = 0; /* DC */ | ||
| 963 | else | ||
| 964 | mode = 1; /* PWM */ | ||
| 965 | |||
| 966 | return sprintf(buf, "%u\n", mode); | ||
| 967 | } | ||
| 968 | |||
| 969 | /* | ||
| 970 | * Check whether a given temperature source can ever be useful. | ||
| 971 | * Returns the number of selectable temperature channels which are | ||
| 972 | * enabled. | ||
| 973 | */ | ||
| 974 | static int w83795_tss_useful(const struct w83795_data *data, int tsrc) | ||
| 975 | { | ||
| 976 | int useful = 0, i; | ||
| 977 | |||
| 978 | for (i = 0; i < 4; i++) { | ||
| 979 | if (tss_map[i][tsrc] == TSS_MAP_RESERVED) | ||
| 980 | continue; | ||
| 981 | if (tss_map[i][tsrc] < 6) /* Analog */ | ||
| 982 | useful += (data->has_temp >> tss_map[i][tsrc]) & 1; | ||
| 983 | else /* Digital */ | ||
| 984 | useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1; | ||
| 985 | } | ||
| 986 | |||
| 987 | return useful; | ||
| 988 | } | ||
| 989 | |||
| 990 | static ssize_t | ||
| 921 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) | 991 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) |
| 922 | { | 992 | { |
| 923 | struct sensor_device_attribute_2 *sensor_attr = | 993 | struct sensor_device_attribute_2 *sensor_attr = |
| 924 | to_sensor_dev_attr_2(attr); | 994 | to_sensor_dev_attr_2(attr); |
| 925 | struct w83795_data *data = w83795_update_pwm_config(dev); | 995 | struct w83795_data *data = w83795_update_pwm_config(dev); |
| 926 | int index = sensor_attr->index; | 996 | int index = sensor_attr->index; |
| 927 | u8 val = index / 2; | 997 | u8 tmp = data->temp_src[index / 2]; |
| 928 | u8 tmp = data->temp_src[val]; | ||
| 929 | 998 | ||
| 930 | if (index & 1) | 999 | if (index & 1) |
| 931 | val = 4; | 1000 | tmp >>= 4; /* Pick high nibble */ |
| 932 | else | 1001 | else |
| 933 | val = 0; | 1002 | tmp &= 0x0f; /* Pick low nibble */ |
| 934 | tmp >>= val; | ||
| 935 | tmp &= 0x0f; | ||
| 936 | 1003 | ||
| 937 | return sprintf(buf, "%u\n", tmp); | 1004 | /* Look-up the actual temperature channel number */ |
| 1005 | if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED) | ||
| 1006 | return -EINVAL; /* Shouldn't happen */ | ||
| 1007 | |||
| 1008 | return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1); | ||
| 938 | } | 1009 | } |
| 939 | 1010 | ||
| 940 | static ssize_t | 1011 | static ssize_t |
| @@ -946,12 +1017,21 @@ store_temp_src(struct device *dev, struct device_attribute *attr, | |||
| 946 | struct sensor_device_attribute_2 *sensor_attr = | 1017 | struct sensor_device_attribute_2 *sensor_attr = |
| 947 | to_sensor_dev_attr_2(attr); | 1018 | to_sensor_dev_attr_2(attr); |
| 948 | int index = sensor_attr->index; | 1019 | int index = sensor_attr->index; |
| 949 | unsigned long tmp; | 1020 | int tmp; |
| 1021 | unsigned long channel; | ||
| 950 | u8 val = index / 2; | 1022 | u8 val = index / 2; |
| 951 | 1023 | ||
| 952 | if (strict_strtoul(buf, 10, &tmp) < 0) | 1024 | if (strict_strtoul(buf, 10, &channel) < 0 || |
| 1025 | channel < 1 || channel > 14) | ||
| 1026 | return -EINVAL; | ||
| 1027 | |||
| 1028 | /* Check if request can be fulfilled */ | ||
| 1029 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 1030 | if (tss_map[tmp][index] == channel - 1) | ||
| 1031 | break; | ||
| 1032 | } | ||
| 1033 | if (tmp == 4) /* No match */ | ||
| 953 | return -EINVAL; | 1034 | return -EINVAL; |
| 954 | tmp = SENSORS_LIMIT(tmp, 0, 15); | ||
| 955 | 1035 | ||
| 956 | mutex_lock(&data->update_lock); | 1036 | mutex_lock(&data->update_lock); |
| 957 | if (index & 1) { | 1037 | if (index & 1) { |
| @@ -1515,7 +1595,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
| 1515 | 1595 | ||
| 1516 | #define NOT_USED -1 | 1596 | #define NOT_USED -1 |
| 1517 | 1597 | ||
| 1518 | /* Don't change the attribute order, _max and _min are accessed by index | 1598 | /* Don't change the attribute order, _max, _min and _beep are accessed by index |
| 1519 | * somewhere else in the code */ | 1599 | * somewhere else in the code */ |
| 1520 | #define SENSOR_ATTR_IN(index) { \ | 1600 | #define SENSOR_ATTR_IN(index) { \ |
| 1521 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ | 1601 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ |
| @@ -1530,6 +1610,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
| 1530 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1610 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
| 1531 | index + ((index > 14) ? 1 : 0)) } | 1611 | index + ((index > 14) ? 1 : 0)) } |
| 1532 | 1612 | ||
| 1613 | /* Don't change the attribute order, _beep is accessed by index | ||
| 1614 | * somewhere else in the code */ | ||
| 1533 | #define SENSOR_ATTR_FAN(index) { \ | 1615 | #define SENSOR_ATTR_FAN(index) { \ |
| 1534 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ | 1616 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ |
| 1535 | NULL, FAN_INPUT, index - 1), \ | 1617 | NULL, FAN_INPUT, index - 1), \ |
| @@ -1553,9 +1635,13 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
| 1553 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ | 1635 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ |
| 1554 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ | 1636 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ |
| 1555 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ | 1637 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ |
| 1638 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ | ||
| 1639 | show_pwm_mode, NULL, NOT_USED, index - 1), \ | ||
| 1556 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ | 1640 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ |
| 1557 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } | 1641 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } |
| 1558 | 1642 | ||
| 1643 | /* Don't change the attribute order, _beep is accessed by index | ||
| 1644 | * somewhere else in the code */ | ||
| 1559 | #define SENSOR_ATTR_DTS(index) { \ | 1645 | #define SENSOR_ATTR_DTS(index) { \ |
| 1560 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ | 1646 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ |
| 1561 | show_dts_mode, NULL, NOT_USED, index - 7), \ | 1647 | show_dts_mode, NULL, NOT_USED, index - 7), \ |
| @@ -1574,6 +1660,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
| 1574 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1660 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
| 1575 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } | 1661 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } |
| 1576 | 1662 | ||
| 1663 | /* Don't change the attribute order, _beep is accessed by index | ||
| 1664 | * somewhere else in the code */ | ||
| 1577 | #define SENSOR_ATTR_TEMP(index) { \ | 1665 | #define SENSOR_ATTR_TEMP(index) { \ |
| 1578 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ | 1666 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ |
| 1579 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ | 1667 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ |
| @@ -1593,8 +1681,6 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
| 1593 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1681 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
| 1594 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1682 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
| 1595 | index + (index > 4 ? 11 : 17)), \ | 1683 | index + (index > 4 ? 11 : 17)), \ |
| 1596 | SENSOR_ATTR_2(temp##index##_source_sel, S_IWUSR | S_IRUGO, \ | ||
| 1597 | show_temp_src, store_temp_src, NOT_USED, index - 1), \ | ||
| 1598 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ | 1684 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ |
| 1599 | show_temp_pwm_enable, store_temp_pwm_enable, \ | 1685 | show_temp_pwm_enable, store_temp_pwm_enable, \ |
| 1600 | TEMP_PWM_ENABLE, index - 1), \ | 1686 | TEMP_PWM_ENABLE, index - 1), \ |
| @@ -1680,7 +1766,7 @@ static const struct sensor_device_attribute_2 w83795_fan[][4] = { | |||
| 1680 | SENSOR_ATTR_FAN(14), | 1766 | SENSOR_ATTR_FAN(14), |
| 1681 | }; | 1767 | }; |
| 1682 | 1768 | ||
| 1683 | static const struct sensor_device_attribute_2 w83795_temp[][29] = { | 1769 | static const struct sensor_device_attribute_2 w83795_temp[][28] = { |
| 1684 | SENSOR_ATTR_TEMP(1), | 1770 | SENSOR_ATTR_TEMP(1), |
| 1685 | SENSOR_ATTR_TEMP(2), | 1771 | SENSOR_ATTR_TEMP(2), |
| 1686 | SENSOR_ATTR_TEMP(3), | 1772 | SENSOR_ATTR_TEMP(3), |
| @@ -1700,7 +1786,7 @@ static const struct sensor_device_attribute_2 w83795_dts[][8] = { | |||
| 1700 | SENSOR_ATTR_DTS(14), | 1786 | SENSOR_ATTR_DTS(14), |
| 1701 | }; | 1787 | }; |
| 1702 | 1788 | ||
| 1703 | static const struct sensor_device_attribute_2 w83795_pwm[][7] = { | 1789 | static const struct sensor_device_attribute_2 w83795_pwm[][8] = { |
| 1704 | SENSOR_ATTR_PWM(1), | 1790 | SENSOR_ATTR_PWM(1), |
| 1705 | SENSOR_ATTR_PWM(2), | 1791 | SENSOR_ATTR_PWM(2), |
| 1706 | SENSOR_ATTR_PWM(3), | 1792 | SENSOR_ATTR_PWM(3), |
| @@ -1711,13 +1797,24 @@ static const struct sensor_device_attribute_2 w83795_pwm[][7] = { | |||
| 1711 | SENSOR_ATTR_PWM(8), | 1797 | SENSOR_ATTR_PWM(8), |
| 1712 | }; | 1798 | }; |
| 1713 | 1799 | ||
| 1800 | static const struct sensor_device_attribute_2 w83795_tss[6] = { | ||
| 1801 | SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO, | ||
| 1802 | show_temp_src, store_temp_src, NOT_USED, 0), | ||
| 1803 | SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO, | ||
| 1804 | show_temp_src, store_temp_src, NOT_USED, 1), | ||
| 1805 | SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO, | ||
| 1806 | show_temp_src, store_temp_src, NOT_USED, 2), | ||
| 1807 | SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO, | ||
| 1808 | show_temp_src, store_temp_src, NOT_USED, 3), | ||
| 1809 | SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO, | ||
| 1810 | show_temp_src, store_temp_src, NOT_USED, 4), | ||
| 1811 | SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO, | ||
| 1812 | show_temp_src, store_temp_src, NOT_USED, 5), | ||
| 1813 | }; | ||
| 1814 | |||
| 1714 | static const struct sensor_device_attribute_2 sda_single_files[] = { | 1815 | static const struct sensor_device_attribute_2 sda_single_files[] = { |
| 1715 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | 1816 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, |
| 1716 | store_chassis_clear, ALARM_STATUS, 46), | 1817 | store_chassis_clear, ALARM_STATUS, 46), |
| 1717 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
| 1718 | store_beep, BEEP_ENABLE, 46), | ||
| 1719 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
| 1720 | store_beep, BEEP_ENABLE, 47), | ||
| 1721 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1818 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
| 1722 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, | 1819 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, |
| 1723 | store_fanin, FANIN_TOL, NOT_USED), | 1820 | store_fanin, FANIN_TOL, NOT_USED), |
| @@ -1730,6 +1827,13 @@ static const struct sensor_device_attribute_2 sda_single_files[] = { | |||
| 1730 | #endif | 1827 | #endif |
| 1731 | }; | 1828 | }; |
| 1732 | 1829 | ||
| 1830 | static const struct sensor_device_attribute_2 sda_beep_files[] = { | ||
| 1831 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
| 1832 | store_beep, BEEP_ENABLE, 46), | ||
| 1833 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
| 1834 | store_beep, BEEP_ENABLE, 47), | ||
| 1835 | }; | ||
| 1836 | |||
| 1733 | /* | 1837 | /* |
| 1734 | * Driver interface | 1838 | * Driver interface |
| 1735 | */ | 1839 | */ |
| @@ -1859,6 +1963,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
| 1859 | if (!(data->has_in & (1 << i))) | 1963 | if (!(data->has_in & (1 << i))) |
| 1860 | continue; | 1964 | continue; |
| 1861 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { | 1965 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { |
| 1966 | if (j == 4 && !data->enable_beep) | ||
| 1967 | continue; | ||
| 1862 | err = fn(dev, &w83795_in[i][j].dev_attr); | 1968 | err = fn(dev, &w83795_in[i][j].dev_attr); |
| 1863 | if (err) | 1969 | if (err) |
| 1864 | return err; | 1970 | return err; |
| @@ -1869,18 +1975,37 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
| 1869 | if (!(data->has_fan & (1 << i))) | 1975 | if (!(data->has_fan & (1 << i))) |
| 1870 | continue; | 1976 | continue; |
| 1871 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { | 1977 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { |
| 1978 | if (j == 3 && !data->enable_beep) | ||
| 1979 | continue; | ||
| 1872 | err = fn(dev, &w83795_fan[i][j].dev_attr); | 1980 | err = fn(dev, &w83795_fan[i][j].dev_attr); |
| 1873 | if (err) | 1981 | if (err) |
| 1874 | return err; | 1982 | return err; |
| 1875 | } | 1983 | } |
| 1876 | } | 1984 | } |
| 1877 | 1985 | ||
| 1986 | for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) { | ||
| 1987 | j = w83795_tss_useful(data, i); | ||
| 1988 | if (!j) | ||
| 1989 | continue; | ||
| 1990 | err = fn(dev, &w83795_tss[i].dev_attr); | ||
| 1991 | if (err) | ||
| 1992 | return err; | ||
| 1993 | } | ||
| 1994 | |||
| 1878 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { | 1995 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { |
| 1879 | err = fn(dev, &sda_single_files[i].dev_attr); | 1996 | err = fn(dev, &sda_single_files[i].dev_attr); |
| 1880 | if (err) | 1997 | if (err) |
| 1881 | return err; | 1998 | return err; |
| 1882 | } | 1999 | } |
| 1883 | 2000 | ||
| 2001 | if (data->enable_beep) { | ||
| 2002 | for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { | ||
| 2003 | err = fn(dev, &sda_beep_files[i].dev_attr); | ||
| 2004 | if (err) | ||
| 2005 | return err; | ||
| 2006 | } | ||
| 2007 | } | ||
| 2008 | |||
| 1884 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 2009 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
| 1885 | for (i = 0; i < data->has_pwm; i++) { | 2010 | for (i = 0; i < data->has_pwm; i++) { |
| 1886 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { | 2011 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { |
| @@ -1899,6 +2024,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
| 1899 | #else | 2024 | #else |
| 1900 | for (j = 0; j < 8; j++) { | 2025 | for (j = 0; j < 8; j++) { |
| 1901 | #endif | 2026 | #endif |
| 2027 | if (j == 7 && !data->enable_beep) | ||
| 2028 | continue; | ||
| 1902 | err = fn(dev, &w83795_temp[i][j].dev_attr); | 2029 | err = fn(dev, &w83795_temp[i][j].dev_attr); |
| 1903 | if (err) | 2030 | if (err) |
| 1904 | return err; | 2031 | return err; |
| @@ -1910,6 +2037,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
| 1910 | if (!(data->has_dts & (1 << i))) | 2037 | if (!(data->has_dts & (1 << i))) |
| 1911 | continue; | 2038 | continue; |
| 1912 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { | 2039 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { |
| 2040 | if (j == 7 && !data->enable_beep) | ||
| 2041 | continue; | ||
| 1913 | err = fn(dev, &w83795_dts[i][j].dev_attr); | 2042 | err = fn(dev, &w83795_dts[i][j].dev_attr); |
| 1914 | if (err) | 2043 | if (err) |
| 1915 | return err; | 2044 | return err; |
| @@ -2049,6 +2178,18 @@ static int w83795_probe(struct i2c_client *client, | |||
| 2049 | else | 2178 | else |
| 2050 | data->has_pwm = 2; | 2179 | data->has_pwm = 2; |
| 2051 | 2180 | ||
| 2181 | /* Check if BEEP pin is available */ | ||
| 2182 | if (data->chip_type == w83795g) { | ||
| 2183 | /* The W83795G has a dedicated BEEP pin */ | ||
| 2184 | data->enable_beep = 1; | ||
| 2185 | } else { | ||
| 2186 | /* The W83795ADG has a shared pin for OVT# and BEEP, so you | ||
| 2187 | * can't have both */ | ||
| 2188 | tmp = w83795_read(client, W83795_REG_OVT_CFG); | ||
| 2189 | if ((tmp & OVT_CFG_SEL) == 0) | ||
| 2190 | data->enable_beep = 1; | ||
| 2191 | } | ||
| 2192 | |||
| 2052 | err = w83795_handle_files(dev, device_create_file); | 2193 | err = w83795_handle_files(dev, device_create_file); |
| 2053 | if (err) | 2194 | if (err) |
| 2054 | goto exit_remove; | 2195 | goto exit_remove; |
