diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/osl.c | 9 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 34 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 2 | ||||
-rw-r--r-- | drivers/hwmon/adm1031.c | 68 | ||||
-rw-r--r-- | drivers/hwmon/applesmc.c | 186 | ||||
-rw-r--r-- | drivers/hwmon/asus_atk0110.c | 7 | ||||
-rw-r--r-- | drivers/hwmon/dme1737.c | 328 | ||||
-rw-r--r-- | drivers/hwmon/emc1403.c | 344 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 170 | ||||
-rw-r--r-- | drivers/hwmon/lm63.c | 16 | ||||
-rw-r--r-- | drivers/hwmon/lm75.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/lm90.c | 3 | ||||
-rw-r--r-- | drivers/hwmon/ltc4245.c | 18 | ||||
-rw-r--r-- | drivers/hwmon/tmp102.c | 321 | ||||
-rw-r--r-- | drivers/hwmon/tmp401.c | 255 |
15 files changed, 1456 insertions, 307 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4bc1c4178f50..78418ce4fc78 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -1207,6 +1207,15 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, | |||
1207 | EXPORT_SYMBOL(acpi_check_mem_region); | 1207 | EXPORT_SYMBOL(acpi_check_mem_region); |
1208 | 1208 | ||
1209 | /* | 1209 | /* |
1210 | * Let drivers know whether the resource checks are effective | ||
1211 | */ | ||
1212 | int acpi_resources_are_enforced(void) | ||
1213 | { | ||
1214 | return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT; | ||
1215 | } | ||
1216 | EXPORT_SYMBOL(acpi_resources_are_enforced); | ||
1217 | |||
1218 | /* | ||
1210 | * Acquire a spinlock. | 1219 | * Acquire a spinlock. |
1211 | * | 1220 | * |
1212 | * handle is a pointer to the spinlock_t. | 1221 | * handle is a pointer to the spinlock_t. |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6a9ac754ca5d..e19cf8eb6ccf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -447,13 +447,14 @@ config SENSORS_IT87 | |||
447 | will be called it87. | 447 | will be called it87. |
448 | 448 | ||
449 | config SENSORS_LM63 | 449 | config SENSORS_LM63 |
450 | tristate "National Semiconductor LM63" | 450 | tristate "National Semiconductor LM63 and LM64" |
451 | depends on I2C | 451 | depends on I2C |
452 | help | 452 | help |
453 | If you say yes here you get support for the National Semiconductor | 453 | If you say yes here you get support for the National |
454 | LM63 remote diode digital temperature sensor with integrated fan | 454 | Semiconductor LM63 and LM64 remote diode digital temperature |
455 | control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro) | 455 | sensors with integrated fan control. Such chips are found |
456 | motherboard, among others. | 456 | on the Tyan S4882 (Thunder K8QS Pro) motherboard, among |
457 | others. | ||
457 | 458 | ||
458 | This driver can also be built as a module. If so, the module | 459 | This driver can also be built as a module. If so, the module |
459 | will be called lm63. | 460 | will be called lm63. |
@@ -492,7 +493,8 @@ config SENSORS_LM75 | |||
492 | - NXP's LM75A | 493 | - NXP's LM75A |
493 | - ST Microelectronics STDS75 | 494 | - ST Microelectronics STDS75 |
494 | - TelCom (now Microchip) TCN75 | 495 | - TelCom (now Microchip) TCN75 |
495 | - Texas Instruments TMP100, TMP101, TMP75, TMP175, TMP275 | 496 | - Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175, |
497 | TMP275 | ||
496 | 498 | ||
497 | This driver supports driver model based binding through board | 499 | This driver supports driver model based binding through board |
498 | specific I2C device tables. | 500 | specific I2C device tables. |
@@ -749,6 +751,16 @@ config SENSORS_DME1737 | |||
749 | This driver can also be built as a module. If so, the module | 751 | This driver can also be built as a module. If so, the module |
750 | will be called dme1737. | 752 | will be called dme1737. |
751 | 753 | ||
754 | config SENSORS_EMC1403 | ||
755 | tristate "SMSC EMC1403 thermal sensor" | ||
756 | depends on I2C | ||
757 | help | ||
758 | If you say yes here you get support for the SMSC EMC1403 | ||
759 | temperature monitoring chip. | ||
760 | |||
761 | Threshold values can be configured using sysfs. | ||
762 | Data from the different diodes are accessible via sysfs. | ||
763 | |||
752 | config SENSORS_SMSC47M1 | 764 | config SENSORS_SMSC47M1 |
753 | tristate "SMSC LPC47M10x and compatibles" | 765 | tristate "SMSC LPC47M10x and compatibles" |
754 | help | 766 | help |
@@ -831,6 +843,16 @@ config SENSORS_THMC50 | |||
831 | This driver can also be built as a module. If so, the module | 843 | This driver can also be built as a module. If so, the module |
832 | will be called thmc50. | 844 | will be called thmc50. |
833 | 845 | ||
846 | config SENSORS_TMP102 | ||
847 | tristate "Texas Instruments TMP102" | ||
848 | depends on I2C && EXPERIMENTAL | ||
849 | help | ||
850 | If you say yes here you get support for Texas Instruments TMP102 | ||
851 | sensor chips. | ||
852 | |||
853 | This driver can also be built as a module. If so, the module | ||
854 | will be called tmp102. | ||
855 | |||
834 | config SENSORS_TMP401 | 856 | config SENSORS_TMP401 |
835 | tristate "Texas Instruments TMP401 and compatibles" | 857 | tristate "Texas Instruments TMP401 and compatibles" |
836 | depends on I2C && EXPERIMENTAL | 858 | depends on I2C && EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 86920fb34118..2138ceb1a713 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | |||
41 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | 41 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o |
42 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | 42 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o |
43 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 43 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
44 | obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o | ||
44 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 45 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
45 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o | 46 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o |
46 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o | 47 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o |
@@ -90,6 +91,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | |||
90 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 91 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
91 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o | 92 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o |
92 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 93 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
94 | obj-$(CONFIG_SENSORS_TMP102) += tmp102.o | ||
93 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o | 95 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o |
94 | obj-$(CONFIG_SENSORS_TMP421) += tmp421.o | 96 | obj-$(CONFIG_SENSORS_TMP421) += tmp421.o |
95 | obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o | 97 | obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 1644b92e7cc4..15c1a9616af3 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #define ADM1031_REG_FAN_DIV(nr) (0x20 + (nr)) | 36 | #define ADM1031_REG_FAN_DIV(nr) (0x20 + (nr)) |
37 | #define ADM1031_REG_PWM (0x22) | 37 | #define ADM1031_REG_PWM (0x22) |
38 | #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) | 38 | #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) |
39 | #define ADM1031_REG_FAN_FILTER (0x23) | ||
39 | 40 | ||
40 | #define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr)) | 41 | #define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr)) |
41 | #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) | 42 | #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) |
@@ -61,6 +62,9 @@ | |||
61 | #define ADM1031_CONF2_TACH2_ENABLE 0x08 | 62 | #define ADM1031_CONF2_TACH2_ENABLE 0x08 |
62 | #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) | 63 | #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) |
63 | 64 | ||
65 | #define ADM1031_UPDATE_RATE_MASK 0x1c | ||
66 | #define ADM1031_UPDATE_RATE_SHIFT 2 | ||
67 | |||
64 | /* Addresses to scan */ | 68 | /* Addresses to scan */ |
65 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 69 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
66 | 70 | ||
@@ -75,6 +79,7 @@ struct adm1031_data { | |||
75 | int chip_type; | 79 | int chip_type; |
76 | char valid; /* !=0 if following fields are valid */ | 80 | char valid; /* !=0 if following fields are valid */ |
77 | unsigned long last_updated; /* In jiffies */ | 81 | unsigned long last_updated; /* In jiffies */ |
82 | unsigned int update_rate; /* In milliseconds */ | ||
78 | /* The chan_select_table contains the possible configurations for | 83 | /* The chan_select_table contains the possible configurations for |
79 | * auto fan control. | 84 | * auto fan control. |
80 | */ | 85 | */ |
@@ -738,6 +743,57 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12); | |||
738 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); | 743 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); |
739 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); | 744 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); |
740 | 745 | ||
746 | /* Update Rate */ | ||
747 | static const unsigned int update_rates[] = { | ||
748 | 16000, 8000, 4000, 2000, 1000, 500, 250, 125, | ||
749 | }; | ||
750 | |||
751 | static ssize_t show_update_rate(struct device *dev, | ||
752 | struct device_attribute *attr, char *buf) | ||
753 | { | ||
754 | struct i2c_client *client = to_i2c_client(dev); | ||
755 | struct adm1031_data *data = i2c_get_clientdata(client); | ||
756 | |||
757 | return sprintf(buf, "%u\n", data->update_rate); | ||
758 | } | ||
759 | |||
760 | static ssize_t set_update_rate(struct device *dev, | ||
761 | struct device_attribute *attr, | ||
762 | const char *buf, size_t count) | ||
763 | { | ||
764 | struct i2c_client *client = to_i2c_client(dev); | ||
765 | struct adm1031_data *data = i2c_get_clientdata(client); | ||
766 | unsigned long val; | ||
767 | int i, err; | ||
768 | u8 reg; | ||
769 | |||
770 | err = strict_strtoul(buf, 10, &val); | ||
771 | if (err) | ||
772 | return err; | ||
773 | |||
774 | /* find the nearest update rate from the table */ | ||
775 | for (i = 0; i < ARRAY_SIZE(update_rates) - 1; i++) { | ||
776 | if (val >= update_rates[i]) | ||
777 | break; | ||
778 | } | ||
779 | /* if not found, we point to the last entry (lowest update rate) */ | ||
780 | |||
781 | /* set the new update rate while preserving other settings */ | ||
782 | reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); | ||
783 | reg &= ~ADM1031_UPDATE_RATE_MASK; | ||
784 | reg |= i << ADM1031_UPDATE_RATE_SHIFT; | ||
785 | adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg); | ||
786 | |||
787 | mutex_lock(&data->update_lock); | ||
788 | data->update_rate = update_rates[i]; | ||
789 | mutex_unlock(&data->update_lock); | ||
790 | |||
791 | return count; | ||
792 | } | ||
793 | |||
794 | static DEVICE_ATTR(update_rate, S_IRUGO | S_IWUSR, show_update_rate, | ||
795 | set_update_rate); | ||
796 | |||
741 | static struct attribute *adm1031_attributes[] = { | 797 | static struct attribute *adm1031_attributes[] = { |
742 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 798 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
743 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 799 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
@@ -774,6 +830,7 @@ static struct attribute *adm1031_attributes[] = { | |||
774 | 830 | ||
775 | &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr, | 831 | &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr, |
776 | 832 | ||
833 | &dev_attr_update_rate.attr, | ||
777 | &dev_attr_alarms.attr, | 834 | &dev_attr_alarms.attr, |
778 | 835 | ||
779 | NULL | 836 | NULL |
@@ -900,6 +957,7 @@ static void adm1031_init_client(struct i2c_client *client) | |||
900 | { | 957 | { |
901 | unsigned int read_val; | 958 | unsigned int read_val; |
902 | unsigned int mask; | 959 | unsigned int mask; |
960 | int i; | ||
903 | struct adm1031_data *data = i2c_get_clientdata(client); | 961 | struct adm1031_data *data = i2c_get_clientdata(client); |
904 | 962 | ||
905 | mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE); | 963 | mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE); |
@@ -919,18 +977,24 @@ static void adm1031_init_client(struct i2c_client *client) | |||
919 | ADM1031_CONF1_MONITOR_ENABLE); | 977 | ADM1031_CONF1_MONITOR_ENABLE); |
920 | } | 978 | } |
921 | 979 | ||
980 | /* Read the chip's update rate */ | ||
981 | mask = ADM1031_UPDATE_RATE_MASK; | ||
982 | read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); | ||
983 | i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT; | ||
984 | data->update_rate = update_rates[i]; | ||
922 | } | 985 | } |
923 | 986 | ||
924 | static struct adm1031_data *adm1031_update_device(struct device *dev) | 987 | static struct adm1031_data *adm1031_update_device(struct device *dev) |
925 | { | 988 | { |
926 | struct i2c_client *client = to_i2c_client(dev); | 989 | struct i2c_client *client = to_i2c_client(dev); |
927 | struct adm1031_data *data = i2c_get_clientdata(client); | 990 | struct adm1031_data *data = i2c_get_clientdata(client); |
991 | unsigned long next_update; | ||
928 | int chan; | 992 | int chan; |
929 | 993 | ||
930 | mutex_lock(&data->update_lock); | 994 | mutex_lock(&data->update_lock); |
931 | 995 | ||
932 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 996 | next_update = data->last_updated + msecs_to_jiffies(data->update_rate); |
933 | || !data->valid) { | 997 | if (time_after(jiffies, next_update) || !data->valid) { |
934 | 998 | ||
935 | dev_dbg(&client->dev, "Starting adm1031 update\n"); | 999 | dev_dbg(&client->dev, "Starting adm1031 update\n"); |
936 | for (chan = 0; | 1000 | for (chan = 0; |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f085c18d2905..b6598aa557a0 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -148,6 +148,20 @@ static const char *temperature_sensors_sets[][41] = { | |||
148 | /* Set 18: MacBook Pro 2,2 */ | 148 | /* Set 18: MacBook Pro 2,2 */ |
149 | { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", | 149 | { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", |
150 | "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, | 150 | "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, |
151 | /* Set 19: Macbook Pro 5,3 */ | ||
152 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", | ||
153 | "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H", | ||
154 | "Tm0P", "Ts0P", "Ts0S", NULL }, | ||
155 | /* Set 20: MacBook Pro 5,4 */ | ||
156 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D", | ||
157 | "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL }, | ||
158 | /* Set 21: MacBook Pro 6,2 */ | ||
159 | { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D", | ||
160 | "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P", | ||
161 | "Ts0P", "Ts0S", NULL }, | ||
162 | /* Set 22: MacBook Pro 7,1 */ | ||
163 | { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S", | ||
164 | "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL }, | ||
151 | }; | 165 | }; |
152 | 166 | ||
153 | /* List of keys used to read/write fan speeds */ | 167 | /* List of keys used to read/write fan speeds */ |
@@ -646,6 +660,17 @@ out: | |||
646 | return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); | 660 | return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); |
647 | } | 661 | } |
648 | 662 | ||
663 | /* Displays sensor key as label */ | ||
664 | static ssize_t applesmc_show_sensor_label(struct device *dev, | ||
665 | struct device_attribute *devattr, char *sysfsbuf) | ||
666 | { | ||
667 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
668 | const char *key = | ||
669 | temperature_sensors_sets[applesmc_temperature_set][attr->index]; | ||
670 | |||
671 | return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); | ||
672 | } | ||
673 | |||
649 | /* Displays degree Celsius * 1000 */ | 674 | /* Displays degree Celsius * 1000 */ |
650 | static ssize_t applesmc_show_temperature(struct device *dev, | 675 | static ssize_t applesmc_show_temperature(struct device *dev, |
651 | struct device_attribute *devattr, char *sysfsbuf) | 676 | struct device_attribute *devattr, char *sysfsbuf) |
@@ -1113,6 +1138,86 @@ static const struct attribute_group fan_attribute_groups[] = { | |||
1113 | /* | 1138 | /* |
1114 | * Temperature sensors sysfs entries. | 1139 | * Temperature sensors sysfs entries. |
1115 | */ | 1140 | */ |
1141 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, | ||
1142 | applesmc_show_sensor_label, NULL, 0); | ||
1143 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, | ||
1144 | applesmc_show_sensor_label, NULL, 1); | ||
1145 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, | ||
1146 | applesmc_show_sensor_label, NULL, 2); | ||
1147 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, | ||
1148 | applesmc_show_sensor_label, NULL, 3); | ||
1149 | static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, | ||
1150 | applesmc_show_sensor_label, NULL, 4); | ||
1151 | static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, | ||
1152 | applesmc_show_sensor_label, NULL, 5); | ||
1153 | static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, | ||
1154 | applesmc_show_sensor_label, NULL, 6); | ||
1155 | static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, | ||
1156 | applesmc_show_sensor_label, NULL, 7); | ||
1157 | static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, | ||
1158 | applesmc_show_sensor_label, NULL, 8); | ||
1159 | static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, | ||
1160 | applesmc_show_sensor_label, NULL, 9); | ||
1161 | static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, | ||
1162 | applesmc_show_sensor_label, NULL, 10); | ||
1163 | static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, | ||
1164 | applesmc_show_sensor_label, NULL, 11); | ||
1165 | static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, | ||
1166 | applesmc_show_sensor_label, NULL, 12); | ||
1167 | static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, | ||
1168 | applesmc_show_sensor_label, NULL, 13); | ||
1169 | static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, | ||
1170 | applesmc_show_sensor_label, NULL, 14); | ||
1171 | static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO, | ||
1172 | applesmc_show_sensor_label, NULL, 15); | ||
1173 | static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO, | ||
1174 | applesmc_show_sensor_label, NULL, 16); | ||
1175 | static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO, | ||
1176 | applesmc_show_sensor_label, NULL, 17); | ||
1177 | static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO, | ||
1178 | applesmc_show_sensor_label, NULL, 18); | ||
1179 | static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO, | ||
1180 | applesmc_show_sensor_label, NULL, 19); | ||
1181 | static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO, | ||
1182 | applesmc_show_sensor_label, NULL, 20); | ||
1183 | static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO, | ||
1184 | applesmc_show_sensor_label, NULL, 21); | ||
1185 | static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO, | ||
1186 | applesmc_show_sensor_label, NULL, 22); | ||
1187 | static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO, | ||
1188 | applesmc_show_sensor_label, NULL, 23); | ||
1189 | static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO, | ||
1190 | applesmc_show_sensor_label, NULL, 24); | ||
1191 | static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO, | ||
1192 | applesmc_show_sensor_label, NULL, 25); | ||
1193 | static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO, | ||
1194 | applesmc_show_sensor_label, NULL, 26); | ||
1195 | static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO, | ||
1196 | applesmc_show_sensor_label, NULL, 27); | ||
1197 | static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO, | ||
1198 | applesmc_show_sensor_label, NULL, 28); | ||
1199 | static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO, | ||
1200 | applesmc_show_sensor_label, NULL, 29); | ||
1201 | static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO, | ||
1202 | applesmc_show_sensor_label, NULL, 30); | ||
1203 | static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO, | ||
1204 | applesmc_show_sensor_label, NULL, 31); | ||
1205 | static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO, | ||
1206 | applesmc_show_sensor_label, NULL, 32); | ||
1207 | static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO, | ||
1208 | applesmc_show_sensor_label, NULL, 33); | ||
1209 | static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO, | ||
1210 | applesmc_show_sensor_label, NULL, 34); | ||
1211 | static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO, | ||
1212 | applesmc_show_sensor_label, NULL, 35); | ||
1213 | static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO, | ||
1214 | applesmc_show_sensor_label, NULL, 36); | ||
1215 | static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO, | ||
1216 | applesmc_show_sensor_label, NULL, 37); | ||
1217 | static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO, | ||
1218 | applesmc_show_sensor_label, NULL, 38); | ||
1219 | static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO, | ||
1220 | applesmc_show_sensor_label, NULL, 39); | ||
1116 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | 1221 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, |
1117 | applesmc_show_temperature, NULL, 0); | 1222 | applesmc_show_temperature, NULL, 0); |
1118 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, | 1223 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, |
@@ -1194,6 +1299,50 @@ static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO, | |||
1194 | static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, | 1299 | static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, |
1195 | applesmc_show_temperature, NULL, 39); | 1300 | applesmc_show_temperature, NULL, 39); |
1196 | 1301 | ||
1302 | static struct attribute *label_attributes[] = { | ||
1303 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
1304 | &sensor_dev_attr_temp2_label.dev_attr.attr, | ||
1305 | &sensor_dev_attr_temp3_label.dev_attr.attr, | ||
1306 | &sensor_dev_attr_temp4_label.dev_attr.attr, | ||
1307 | &sensor_dev_attr_temp5_label.dev_attr.attr, | ||
1308 | &sensor_dev_attr_temp6_label.dev_attr.attr, | ||
1309 | &sensor_dev_attr_temp7_label.dev_attr.attr, | ||
1310 | &sensor_dev_attr_temp8_label.dev_attr.attr, | ||
1311 | &sensor_dev_attr_temp9_label.dev_attr.attr, | ||
1312 | &sensor_dev_attr_temp10_label.dev_attr.attr, | ||
1313 | &sensor_dev_attr_temp11_label.dev_attr.attr, | ||
1314 | &sensor_dev_attr_temp12_label.dev_attr.attr, | ||
1315 | &sensor_dev_attr_temp13_label.dev_attr.attr, | ||
1316 | &sensor_dev_attr_temp14_label.dev_attr.attr, | ||
1317 | &sensor_dev_attr_temp15_label.dev_attr.attr, | ||
1318 | &sensor_dev_attr_temp16_label.dev_attr.attr, | ||
1319 | &sensor_dev_attr_temp17_label.dev_attr.attr, | ||
1320 | &sensor_dev_attr_temp18_label.dev_attr.attr, | ||
1321 | &sensor_dev_attr_temp19_label.dev_attr.attr, | ||
1322 | &sensor_dev_attr_temp20_label.dev_attr.attr, | ||
1323 | &sensor_dev_attr_temp21_label.dev_attr.attr, | ||
1324 | &sensor_dev_attr_temp22_label.dev_attr.attr, | ||
1325 | &sensor_dev_attr_temp23_label.dev_attr.attr, | ||
1326 | &sensor_dev_attr_temp24_label.dev_attr.attr, | ||
1327 | &sensor_dev_attr_temp25_label.dev_attr.attr, | ||
1328 | &sensor_dev_attr_temp26_label.dev_attr.attr, | ||
1329 | &sensor_dev_attr_temp27_label.dev_attr.attr, | ||
1330 | &sensor_dev_attr_temp28_label.dev_attr.attr, | ||
1331 | &sensor_dev_attr_temp29_label.dev_attr.attr, | ||
1332 | &sensor_dev_attr_temp30_label.dev_attr.attr, | ||
1333 | &sensor_dev_attr_temp31_label.dev_attr.attr, | ||
1334 | &sensor_dev_attr_temp32_label.dev_attr.attr, | ||
1335 | &sensor_dev_attr_temp33_label.dev_attr.attr, | ||
1336 | &sensor_dev_attr_temp34_label.dev_attr.attr, | ||
1337 | &sensor_dev_attr_temp35_label.dev_attr.attr, | ||
1338 | &sensor_dev_attr_temp36_label.dev_attr.attr, | ||
1339 | &sensor_dev_attr_temp37_label.dev_attr.attr, | ||
1340 | &sensor_dev_attr_temp38_label.dev_attr.attr, | ||
1341 | &sensor_dev_attr_temp39_label.dev_attr.attr, | ||
1342 | &sensor_dev_attr_temp40_label.dev_attr.attr, | ||
1343 | NULL | ||
1344 | }; | ||
1345 | |||
1197 | static struct attribute *temperature_attributes[] = { | 1346 | static struct attribute *temperature_attributes[] = { |
1198 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 1347 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1199 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 1348 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
@@ -1241,6 +1390,10 @@ static struct attribute *temperature_attributes[] = { | |||
1241 | static const struct attribute_group temperature_attributes_group = | 1390 | static const struct attribute_group temperature_attributes_group = |
1242 | { .attrs = temperature_attributes }; | 1391 | { .attrs = temperature_attributes }; |
1243 | 1392 | ||
1393 | static const struct attribute_group label_attributes_group = { | ||
1394 | .attrs = label_attributes | ||
1395 | }; | ||
1396 | |||
1244 | /* Module stuff */ | 1397 | /* Module stuff */ |
1245 | 1398 | ||
1246 | /* | 1399 | /* |
@@ -1363,6 +1516,14 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1363 | { .accelerometer = 0, .light = 0, .temperature_set = 17 }, | 1516 | { .accelerometer = 0, .light = 0, .temperature_set = 17 }, |
1364 | /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ | 1517 | /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ |
1365 | { .accelerometer = 1, .light = 1, .temperature_set = 18 }, | 1518 | { .accelerometer = 1, .light = 1, .temperature_set = 18 }, |
1519 | /* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */ | ||
1520 | { .accelerometer = 1, .light = 1, .temperature_set = 19 }, | ||
1521 | /* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */ | ||
1522 | { .accelerometer = 1, .light = 1, .temperature_set = 20 }, | ||
1523 | /* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */ | ||
1524 | { .accelerometer = 1, .light = 1, .temperature_set = 21 }, | ||
1525 | /* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */ | ||
1526 | { .accelerometer = 1, .light = 1, .temperature_set = 22 }, | ||
1366 | }; | 1527 | }; |
1367 | 1528 | ||
1368 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1529 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
@@ -1376,6 +1537,22 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1376 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1537 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1377 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | 1538 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, |
1378 | &applesmc_dmi_data[7]}, | 1539 | &applesmc_dmi_data[7]}, |
1540 | { applesmc_dmi_match, "Apple MacBook Pro 7", { | ||
1541 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1542 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") }, | ||
1543 | &applesmc_dmi_data[22]}, | ||
1544 | { applesmc_dmi_match, "Apple MacBook Pro 5,4", { | ||
1545 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1546 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") }, | ||
1547 | &applesmc_dmi_data[20]}, | ||
1548 | { applesmc_dmi_match, "Apple MacBook Pro 5,3", { | ||
1549 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1550 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") }, | ||
1551 | &applesmc_dmi_data[19]}, | ||
1552 | { applesmc_dmi_match, "Apple MacBook Pro 6", { | ||
1553 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1554 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") }, | ||
1555 | &applesmc_dmi_data[21]}, | ||
1379 | { applesmc_dmi_match, "Apple MacBook Pro 5", { | 1556 | { applesmc_dmi_match, "Apple MacBook Pro 5", { |
1380 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1557 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1381 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, | 1558 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, |
@@ -1518,7 +1695,8 @@ static int __init applesmc_init(void) | |||
1518 | for (i = 0; | 1695 | for (i = 0; |
1519 | temperature_sensors_sets[applesmc_temperature_set][i] != NULL; | 1696 | temperature_sensors_sets[applesmc_temperature_set][i] != NULL; |
1520 | i++) { | 1697 | i++) { |
1521 | if (temperature_attributes[i] == NULL) { | 1698 | if (temperature_attributes[i] == NULL || |
1699 | label_attributes[i] == NULL) { | ||
1522 | printk(KERN_ERR "applesmc: More temperature sensors " | 1700 | printk(KERN_ERR "applesmc: More temperature sensors " |
1523 | "in temperature_sensors_sets (at least %i)" | 1701 | "in temperature_sensors_sets (at least %i)" |
1524 | "than available sysfs files in " | 1702 | "than available sysfs files in " |
@@ -1530,6 +1708,10 @@ static int __init applesmc_init(void) | |||
1530 | temperature_attributes[i]); | 1708 | temperature_attributes[i]); |
1531 | if (ret) | 1709 | if (ret) |
1532 | goto out_temperature; | 1710 | goto out_temperature; |
1711 | ret = sysfs_create_file(&pdev->dev.kobj, | ||
1712 | label_attributes[i]); | ||
1713 | if (ret) | ||
1714 | goto out_temperature; | ||
1533 | } | 1715 | } |
1534 | 1716 | ||
1535 | if (applesmc_accelerometer) { | 1717 | if (applesmc_accelerometer) { |
@@ -1580,6 +1762,7 @@ out_accelerometer: | |||
1580 | if (applesmc_accelerometer) | 1762 | if (applesmc_accelerometer) |
1581 | applesmc_release_accelerometer(); | 1763 | applesmc_release_accelerometer(); |
1582 | out_temperature: | 1764 | out_temperature: |
1765 | sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); | ||
1583 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); | 1766 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); |
1584 | out_fans: | 1767 | out_fans: |
1585 | while (fans_handled) | 1768 | while (fans_handled) |
@@ -1609,6 +1792,7 @@ static void __exit applesmc_exit(void) | |||
1609 | } | 1792 | } |
1610 | if (applesmc_accelerometer) | 1793 | if (applesmc_accelerometer) |
1611 | applesmc_release_accelerometer(); | 1794 | applesmc_release_accelerometer(); |
1795 | sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); | ||
1612 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); | 1796 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); |
1613 | while (fans_handled) | 1797 | while (fans_handled) |
1614 | sysfs_remove_group(&pdev->dev.kobj, | 1798 | sysfs_remove_group(&pdev->dev.kobj, |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 16c420240724..653db1bda934 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -1411,6 +1411,13 @@ static int __init atk0110_init(void) | |||
1411 | { | 1411 | { |
1412 | int ret; | 1412 | int ret; |
1413 | 1413 | ||
1414 | /* Make sure it's safe to access the device through ACPI */ | ||
1415 | if (!acpi_resources_are_enforced()) { | ||
1416 | pr_err("atk: Resources not safely usable due to " | ||
1417 | "acpi_enforce_resources kernel parameter\n"); | ||
1418 | return -EBUSY; | ||
1419 | } | ||
1420 | |||
1414 | ret = acpi_bus_register_driver(&atk_driver); | 1421 | ret = acpi_bus_register_driver(&atk_driver); |
1415 | if (ret) | 1422 | if (ret) |
1416 | pr_info("atk: acpi_bus_register_driver failed: %d\n", ret); | 1423 | pr_info("atk: acpi_bus_register_driver failed: %d\n", ret); |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 823dd28a902c..980c17d5eeae 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -1,12 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027, |
3 | * SCH5027 Super-I/O chips integrated hardware monitoring features. | 3 | * and SCH5127 Super-I/O chips integrated hardware monitoring |
4 | * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com> | 4 | * features. |
5 | * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger <juergh@gmail.com> | ||
5 | * | 6 | * |
6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access | 7 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
7 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus | 8 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus |
8 | * if a SCH311x chip is found. Both types of chips have very similar hardware | 9 | * if a SCH311x or SCH5127 chip is found. Both types of chips have very |
9 | * monitoring capabilities but differ in the way they can be accessed. | 10 | * similar hardware monitoring capabilities but differ in the way they can be |
11 | * accessed. | ||
10 | * | 12 | * |
11 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
@@ -57,7 +59,7 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | |||
57 | /* Addresses to scan */ | 59 | /* Addresses to scan */ |
58 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 60 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
59 | 61 | ||
60 | enum chips { dme1737, sch5027, sch311x }; | 62 | enum chips { dme1737, sch5027, sch311x, sch5127 }; |
61 | 63 | ||
62 | /* --------------------------------------------------------------------- | 64 | /* --------------------------------------------------------------------- |
63 | * Registers | 65 | * Registers |
@@ -164,10 +166,29 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
164 | #define DME1737_VERSTEP_MASK 0xf8 | 166 | #define DME1737_VERSTEP_MASK 0xf8 |
165 | #define SCH311X_DEVICE 0x8c | 167 | #define SCH311X_DEVICE 0x8c |
166 | #define SCH5027_VERSTEP 0x69 | 168 | #define SCH5027_VERSTEP 0x69 |
169 | #define SCH5127_DEVICE 0x8e | ||
170 | |||
171 | /* Device ID values (global configuration register index 0x20) */ | ||
172 | #define DME1737_ID_1 0x77 | ||
173 | #define DME1737_ID_2 0x78 | ||
174 | #define SCH3112_ID 0x7c | ||
175 | #define SCH3114_ID 0x7d | ||
176 | #define SCH3116_ID 0x7f | ||
177 | #define SCH5027_ID 0x89 | ||
178 | #define SCH5127_ID 0x86 | ||
167 | 179 | ||
168 | /* Length of ISA address segment */ | 180 | /* Length of ISA address segment */ |
169 | #define DME1737_EXTENT 2 | 181 | #define DME1737_EXTENT 2 |
170 | 182 | ||
183 | /* chip-dependent features */ | ||
184 | #define HAS_TEMP_OFFSET (1 << 0) /* bit 0 */ | ||
185 | #define HAS_VID (1 << 1) /* bit 1 */ | ||
186 | #define HAS_ZONE3 (1 << 2) /* bit 2 */ | ||
187 | #define HAS_ZONE_HYST (1 << 3) /* bit 3 */ | ||
188 | #define HAS_PWM_MIN (1 << 4) /* bit 4 */ | ||
189 | #define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ | ||
190 | #define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ | ||
191 | |||
171 | /* --------------------------------------------------------------------- | 192 | /* --------------------------------------------------------------------- |
172 | * Data structures and manipulation thereof | 193 | * Data structures and manipulation thereof |
173 | * --------------------------------------------------------------------- */ | 194 | * --------------------------------------------------------------------- */ |
@@ -187,8 +208,7 @@ struct dme1737_data { | |||
187 | 208 | ||
188 | u8 vid; | 209 | u8 vid; |
189 | u8 pwm_rr_en; | 210 | u8 pwm_rr_en; |
190 | u8 has_pwm; | 211 | u32 has_features; |
191 | u8 has_fan; | ||
192 | 212 | ||
193 | /* Register values */ | 213 | /* Register values */ |
194 | u16 in[7]; | 214 | u16 in[7]; |
@@ -224,8 +244,11 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | |||
224 | 3300}; | 244 | 3300}; |
225 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, | 245 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, |
226 | 3300}; | 246 | 3300}; |
247 | static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, | ||
248 | 3300}; | ||
227 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ | 249 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ |
228 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | 250 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ |
251 | (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ | ||
229 | IN_NOMINAL_DME1737) | 252 | IN_NOMINAL_DME1737) |
230 | 253 | ||
231 | /* Voltage input | 254 | /* Voltage input |
@@ -568,7 +591,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
568 | 591 | ||
569 | /* Sample register contents every 1 sec */ | 592 | /* Sample register contents every 1 sec */ |
570 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | 593 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { |
571 | if (data->type == dme1737) { | 594 | if (data->has_features & HAS_VID) { |
572 | data->vid = dme1737_read(data, DME1737_REG_VID) & | 595 | data->vid = dme1737_read(data, DME1737_REG_VID) & |
573 | 0x3f; | 596 | 0x3f; |
574 | } | 597 | } |
@@ -599,7 +622,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
599 | DME1737_REG_TEMP_MIN(ix)); | 622 | DME1737_REG_TEMP_MIN(ix)); |
600 | data->temp_max[ix] = dme1737_read(data, | 623 | data->temp_max[ix] = dme1737_read(data, |
601 | DME1737_REG_TEMP_MAX(ix)); | 624 | DME1737_REG_TEMP_MAX(ix)); |
602 | if (data->type != sch5027) { | 625 | if (data->has_features & HAS_TEMP_OFFSET) { |
603 | data->temp_offset[ix] = dme1737_read(data, | 626 | data->temp_offset[ix] = dme1737_read(data, |
604 | DME1737_REG_TEMP_OFFSET(ix)); | 627 | DME1737_REG_TEMP_OFFSET(ix)); |
605 | } | 628 | } |
@@ -626,7 +649,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
626 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { | 649 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { |
627 | /* Skip reading registers if optional fans are not | 650 | /* Skip reading registers if optional fans are not |
628 | * present */ | 651 | * present */ |
629 | if (!(data->has_fan & (1 << ix))) { | 652 | if (!(data->has_features & HAS_FAN(ix))) { |
630 | continue; | 653 | continue; |
631 | } | 654 | } |
632 | data->fan[ix] = dme1737_read(data, | 655 | data->fan[ix] = dme1737_read(data, |
@@ -650,7 +673,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
650 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { | 673 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { |
651 | /* Skip reading registers if optional PWMs are not | 674 | /* Skip reading registers if optional PWMs are not |
652 | * present */ | 675 | * present */ |
653 | if (!(data->has_pwm & (1 << ix))) { | 676 | if (!(data->has_features & HAS_PWM(ix))) { |
654 | continue; | 677 | continue; |
655 | } | 678 | } |
656 | data->pwm[ix] = dme1737_read(data, | 679 | data->pwm[ix] = dme1737_read(data, |
@@ -672,12 +695,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
672 | 695 | ||
673 | /* Thermal zone registers */ | 696 | /* Thermal zone registers */ |
674 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | 697 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { |
675 | data->zone_low[ix] = dme1737_read(data, | 698 | /* Skip reading registers if zone3 is not present */ |
676 | DME1737_REG_ZONE_LOW(ix)); | 699 | if ((ix == 2) && !(data->has_features & HAS_ZONE3)) { |
677 | data->zone_abs[ix] = dme1737_read(data, | 700 | continue; |
678 | DME1737_REG_ZONE_ABS(ix)); | 701 | } |
702 | /* sch5127 zone2 registers are special */ | ||
703 | if ((ix == 1) && (data->type == sch5127)) { | ||
704 | data->zone_low[1] = dme1737_read(data, | ||
705 | DME1737_REG_ZONE_LOW(2)); | ||
706 | data->zone_abs[1] = dme1737_read(data, | ||
707 | DME1737_REG_ZONE_ABS(2)); | ||
708 | } else { | ||
709 | data->zone_low[ix] = dme1737_read(data, | ||
710 | DME1737_REG_ZONE_LOW(ix)); | ||
711 | data->zone_abs[ix] = dme1737_read(data, | ||
712 | DME1737_REG_ZONE_ABS(ix)); | ||
713 | } | ||
679 | } | 714 | } |
680 | if (data->type != sch5027) { | 715 | if (data->has_features & HAS_ZONE_HYST) { |
681 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | 716 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { |
682 | data->zone_hyst[ix] = dme1737_read(data, | 717 | data->zone_hyst[ix] = dme1737_read(data, |
683 | DME1737_REG_ZONE_HYST(ix)); | 718 | DME1737_REG_ZONE_HYST(ix)); |
@@ -1594,10 +1629,6 @@ static struct attribute *dme1737_attr[] ={ | |||
1594 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1629 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
1595 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1630 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
1596 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, | 1631 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, |
1597 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
1598 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
1599 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1600 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
1601 | NULL | 1632 | NULL |
1602 | }; | 1633 | }; |
1603 | 1634 | ||
@@ -1605,27 +1636,23 @@ static const struct attribute_group dme1737_group = { | |||
1605 | .attrs = dme1737_attr, | 1636 | .attrs = dme1737_attr, |
1606 | }; | 1637 | }; |
1607 | 1638 | ||
1608 | /* The following struct holds misc attributes, which are not available in all | 1639 | /* The following struct holds temp offset attributes, which are not available |
1609 | * chips. Their creation depends on the chip type which is determined during | 1640 | * in all chips. The following chips support them: |
1610 | * module load. */ | 1641 | * DME1737, SCH311x */ |
1611 | static struct attribute *dme1737_misc_attr[] = { | 1642 | static struct attribute *dme1737_temp_offset_attr[] = { |
1612 | /* Temperatures */ | ||
1613 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | 1643 | &sensor_dev_attr_temp1_offset.dev_attr.attr, |
1614 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 1644 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
1615 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 1645 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
1616 | /* Zones */ | ||
1617 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
1618 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
1619 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
1620 | NULL | 1646 | NULL |
1621 | }; | 1647 | }; |
1622 | 1648 | ||
1623 | static const struct attribute_group dme1737_misc_group = { | 1649 | static const struct attribute_group dme1737_temp_offset_group = { |
1624 | .attrs = dme1737_misc_attr, | 1650 | .attrs = dme1737_temp_offset_attr, |
1625 | }; | 1651 | }; |
1626 | 1652 | ||
1627 | /* The following struct holds VID-related attributes. Their creation | 1653 | /* The following struct holds VID related attributes, which are not available |
1628 | depends on the chip type which is determined during module load. */ | 1654 | * in all chips. The following chips support them: |
1655 | * DME1737 */ | ||
1629 | static struct attribute *dme1737_vid_attr[] = { | 1656 | static struct attribute *dme1737_vid_attr[] = { |
1630 | &dev_attr_vrm.attr, | 1657 | &dev_attr_vrm.attr, |
1631 | &dev_attr_cpu0_vid.attr, | 1658 | &dev_attr_cpu0_vid.attr, |
@@ -1636,6 +1663,36 @@ static const struct attribute_group dme1737_vid_group = { | |||
1636 | .attrs = dme1737_vid_attr, | 1663 | .attrs = dme1737_vid_attr, |
1637 | }; | 1664 | }; |
1638 | 1665 | ||
1666 | /* The following struct holds temp zone 3 related attributes, which are not | ||
1667 | * available in all chips. The following chips support them: | ||
1668 | * DME1737, SCH311x, SCH5027 */ | ||
1669 | static struct attribute *dme1737_zone3_attr[] = { | ||
1670 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
1671 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
1672 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1673 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
1674 | NULL | ||
1675 | }; | ||
1676 | |||
1677 | static const struct attribute_group dme1737_zone3_group = { | ||
1678 | .attrs = dme1737_zone3_attr, | ||
1679 | }; | ||
1680 | |||
1681 | |||
1682 | /* The following struct holds temp zone hysteresis related attributes, which | ||
1683 | * are not available in all chips. The following chips support them: | ||
1684 | * DME1737, SCH311x */ | ||
1685 | static struct attribute *dme1737_zone_hyst_attr[] = { | ||
1686 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
1687 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
1688 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
1689 | NULL | ||
1690 | }; | ||
1691 | |||
1692 | static const struct attribute_group dme1737_zone_hyst_group = { | ||
1693 | .attrs = dme1737_zone_hyst_attr, | ||
1694 | }; | ||
1695 | |||
1639 | /* The following structs hold the PWM attributes, some of which are optional. | 1696 | /* The following structs hold the PWM attributes, some of which are optional. |
1640 | * Their creation depends on the chip configuration which is determined during | 1697 | * Their creation depends on the chip configuration which is determined during |
1641 | * module load. */ | 1698 | * module load. */ |
@@ -1691,10 +1748,10 @@ static const struct attribute_group dme1737_pwm_group[] = { | |||
1691 | { .attrs = dme1737_pwm6_attr }, | 1748 | { .attrs = dme1737_pwm6_attr }, |
1692 | }; | 1749 | }; |
1693 | 1750 | ||
1694 | /* The following struct holds misc PWM attributes, which are not available in | 1751 | /* The following struct holds auto PWM min attributes, which are not available |
1695 | * all chips. Their creation depends on the chip type which is determined | 1752 | * in all chips. Their creation depends on the chip type which is determined |
1696 | * during module load. */ | 1753 | * during module load. */ |
1697 | static struct attribute *dme1737_pwm_misc_attr[] = { | 1754 | static struct attribute *dme1737_auto_pwm_min_attr[] = { |
1698 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | 1755 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, |
1699 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | 1756 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, |
1700 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | 1757 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, |
@@ -1764,14 +1821,25 @@ static struct attribute *dme1737_zone_chmod_attr[] = { | |||
1764 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | 1821 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
1765 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1822 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
1766 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1823 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
1824 | NULL | ||
1825 | }; | ||
1826 | |||
1827 | static const struct attribute_group dme1737_zone_chmod_group = { | ||
1828 | .attrs = dme1737_zone_chmod_attr, | ||
1829 | }; | ||
1830 | |||
1831 | |||
1832 | /* The permissions of the following zone 3 attributes are changed to read- | ||
1833 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | ||
1834 | static struct attribute *dme1737_zone3_chmod_attr[] = { | ||
1767 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | 1835 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
1768 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | 1836 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
1769 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | 1837 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, |
1770 | NULL | 1838 | NULL |
1771 | }; | 1839 | }; |
1772 | 1840 | ||
1773 | static const struct attribute_group dme1737_zone_chmod_group = { | 1841 | static const struct attribute_group dme1737_zone3_chmod_group = { |
1774 | .attrs = dme1737_zone_chmod_attr, | 1842 | .attrs = dme1737_zone3_chmod_attr, |
1775 | }; | 1843 | }; |
1776 | 1844 | ||
1777 | /* The permissions of the following PWM attributes are changed to read- | 1845 | /* The permissions of the following PWM attributes are changed to read- |
@@ -1887,30 +1955,35 @@ static void dme1737_remove_files(struct device *dev) | |||
1887 | int ix; | 1955 | int ix; |
1888 | 1956 | ||
1889 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 1957 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1890 | if (data->has_fan & (1 << ix)) { | 1958 | if (data->has_features & HAS_FAN(ix)) { |
1891 | sysfs_remove_group(&dev->kobj, | 1959 | sysfs_remove_group(&dev->kobj, |
1892 | &dme1737_fan_group[ix]); | 1960 | &dme1737_fan_group[ix]); |
1893 | } | 1961 | } |
1894 | } | 1962 | } |
1895 | 1963 | ||
1896 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 1964 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1897 | if (data->has_pwm & (1 << ix)) { | 1965 | if (data->has_features & HAS_PWM(ix)) { |
1898 | sysfs_remove_group(&dev->kobj, | 1966 | sysfs_remove_group(&dev->kobj, |
1899 | &dme1737_pwm_group[ix]); | 1967 | &dme1737_pwm_group[ix]); |
1900 | if (data->type != sch5027 && ix < 3) { | 1968 | if ((data->has_features & HAS_PWM_MIN) && ix < 3) { |
1901 | sysfs_remove_file(&dev->kobj, | 1969 | sysfs_remove_file(&dev->kobj, |
1902 | dme1737_pwm_misc_attr[ix]); | 1970 | dme1737_auto_pwm_min_attr[ix]); |
1903 | } | 1971 | } |
1904 | } | 1972 | } |
1905 | } | 1973 | } |
1906 | 1974 | ||
1907 | if (data->type != sch5027) { | 1975 | if (data->has_features & HAS_TEMP_OFFSET) { |
1908 | sysfs_remove_group(&dev->kobj, &dme1737_misc_group); | 1976 | sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group); |
1909 | } | 1977 | } |
1910 | if (data->type == dme1737) { | 1978 | if (data->has_features & HAS_VID) { |
1911 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); | 1979 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); |
1912 | } | 1980 | } |
1913 | 1981 | if (data->has_features & HAS_ZONE3) { | |
1982 | sysfs_remove_group(&dev->kobj, &dme1737_zone3_group); | ||
1983 | } | ||
1984 | if (data->has_features & HAS_ZONE_HYST) { | ||
1985 | sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); | ||
1986 | } | ||
1914 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 1987 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
1915 | 1988 | ||
1916 | if (!data->client) { | 1989 | if (!data->client) { |
@@ -1934,23 +2007,31 @@ static int dme1737_create_files(struct device *dev) | |||
1934 | goto exit_remove; | 2007 | goto exit_remove; |
1935 | } | 2008 | } |
1936 | 2009 | ||
1937 | /* Create misc sysfs attributes */ | 2010 | /* Create chip-dependent sysfs attributes */ |
1938 | if ((data->type != sch5027) && | 2011 | if ((data->has_features & HAS_TEMP_OFFSET) && |
1939 | (err = sysfs_create_group(&dev->kobj, | 2012 | (err = sysfs_create_group(&dev->kobj, |
1940 | &dme1737_misc_group))) { | 2013 | &dme1737_temp_offset_group))) { |
1941 | goto exit_remove; | 2014 | goto exit_remove; |
1942 | } | 2015 | } |
1943 | 2016 | if ((data->has_features & HAS_VID) && | |
1944 | /* Create VID-related sysfs attributes */ | ||
1945 | if ((data->type == dme1737) && | ||
1946 | (err = sysfs_create_group(&dev->kobj, | 2017 | (err = sysfs_create_group(&dev->kobj, |
1947 | &dme1737_vid_group))) { | 2018 | &dme1737_vid_group))) { |
1948 | goto exit_remove; | 2019 | goto exit_remove; |
1949 | } | 2020 | } |
2021 | if ((data->has_features & HAS_ZONE3) && | ||
2022 | (err = sysfs_create_group(&dev->kobj, | ||
2023 | &dme1737_zone3_group))) { | ||
2024 | goto exit_remove; | ||
2025 | } | ||
2026 | if ((data->has_features & HAS_ZONE_HYST) && | ||
2027 | (err = sysfs_create_group(&dev->kobj, | ||
2028 | &dme1737_zone_hyst_group))) { | ||
2029 | goto exit_remove; | ||
2030 | } | ||
1950 | 2031 | ||
1951 | /* Create fan sysfs attributes */ | 2032 | /* Create fan sysfs attributes */ |
1952 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2033 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1953 | if (data->has_fan & (1 << ix)) { | 2034 | if (data->has_features & HAS_FAN(ix)) { |
1954 | if ((err = sysfs_create_group(&dev->kobj, | 2035 | if ((err = sysfs_create_group(&dev->kobj, |
1955 | &dme1737_fan_group[ix]))) { | 2036 | &dme1737_fan_group[ix]))) { |
1956 | goto exit_remove; | 2037 | goto exit_remove; |
@@ -1960,14 +2041,14 @@ static int dme1737_create_files(struct device *dev) | |||
1960 | 2041 | ||
1961 | /* Create PWM sysfs attributes */ | 2042 | /* Create PWM sysfs attributes */ |
1962 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 2043 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1963 | if (data->has_pwm & (1 << ix)) { | 2044 | if (data->has_features & HAS_PWM(ix)) { |
1964 | if ((err = sysfs_create_group(&dev->kobj, | 2045 | if ((err = sysfs_create_group(&dev->kobj, |
1965 | &dme1737_pwm_group[ix]))) { | 2046 | &dme1737_pwm_group[ix]))) { |
1966 | goto exit_remove; | 2047 | goto exit_remove; |
1967 | } | 2048 | } |
1968 | if (data->type != sch5027 && ix < 3 && | 2049 | if ((data->has_features & HAS_PWM_MIN) && ix < 3 && |
1969 | (err = sysfs_create_file(&dev->kobj, | 2050 | (err = sysfs_create_file(&dev->kobj, |
1970 | dme1737_pwm_misc_attr[ix]))) { | 2051 | dme1737_auto_pwm_min_attr[ix]))) { |
1971 | goto exit_remove; | 2052 | goto exit_remove; |
1972 | } | 2053 | } |
1973 | } | 2054 | } |
@@ -1983,21 +2064,30 @@ static int dme1737_create_files(struct device *dev) | |||
1983 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, | 2064 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
1984 | S_IRUGO | S_IWUSR); | 2065 | S_IRUGO | S_IWUSR); |
1985 | 2066 | ||
1986 | /* Change permissions of misc sysfs attributes */ | 2067 | /* Change permissions of chip-dependent sysfs attributes */ |
1987 | if (data->type != sch5027) { | 2068 | if (data->has_features & HAS_TEMP_OFFSET) { |
1988 | dme1737_chmod_group(dev, &dme1737_misc_group, | 2069 | dme1737_chmod_group(dev, &dme1737_temp_offset_group, |
2070 | S_IRUGO | S_IWUSR); | ||
2071 | } | ||
2072 | if (data->has_features & HAS_ZONE3) { | ||
2073 | dme1737_chmod_group(dev, &dme1737_zone3_chmod_group, | ||
2074 | S_IRUGO | S_IWUSR); | ||
2075 | } | ||
2076 | if (data->has_features & HAS_ZONE_HYST) { | ||
2077 | dme1737_chmod_group(dev, &dme1737_zone_hyst_group, | ||
1989 | S_IRUGO | S_IWUSR); | 2078 | S_IRUGO | S_IWUSR); |
1990 | } | 2079 | } |
1991 | 2080 | ||
1992 | /* Change permissions of PWM sysfs attributes */ | 2081 | /* Change permissions of PWM sysfs attributes */ |
1993 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { | 2082 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { |
1994 | if (data->has_pwm & (1 << ix)) { | 2083 | if (data->has_features & HAS_PWM(ix)) { |
1995 | dme1737_chmod_group(dev, | 2084 | dme1737_chmod_group(dev, |
1996 | &dme1737_pwm_chmod_group[ix], | 2085 | &dme1737_pwm_chmod_group[ix], |
1997 | S_IRUGO | S_IWUSR); | 2086 | S_IRUGO | S_IWUSR); |
1998 | if (data->type != sch5027 && ix < 3) { | 2087 | if ((data->has_features & HAS_PWM_MIN) && |
2088 | ix < 3) { | ||
1999 | dme1737_chmod_file(dev, | 2089 | dme1737_chmod_file(dev, |
2000 | dme1737_pwm_misc_attr[ix], | 2090 | dme1737_auto_pwm_min_attr[ix], |
2001 | S_IRUGO | S_IWUSR); | 2091 | S_IRUGO | S_IWUSR); |
2002 | } | 2092 | } |
2003 | } | 2093 | } |
@@ -2005,7 +2095,7 @@ static int dme1737_create_files(struct device *dev) | |||
2005 | 2095 | ||
2006 | /* Change permissions of pwm[1-3] if in manual mode */ | 2096 | /* Change permissions of pwm[1-3] if in manual mode */ |
2007 | for (ix = 0; ix < 3; ix++) { | 2097 | for (ix = 0; ix < 3; ix++) { |
2008 | if ((data->has_pwm & (1 << ix)) && | 2098 | if ((data->has_features & HAS_PWM(ix)) && |
2009 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | 2099 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
2010 | dme1737_chmod_file(dev, | 2100 | dme1737_chmod_file(dev, |
2011 | dme1737_pwm_chmod_attr[ix], | 2101 | dme1737_pwm_chmod_attr[ix], |
@@ -2052,20 +2142,20 @@ static int dme1737_init_device(struct device *dev) | |||
2052 | return -EFAULT; | 2142 | return -EFAULT; |
2053 | } | 2143 | } |
2054 | 2144 | ||
2055 | /* Determine which optional fan and pwm features are enabled/present */ | 2145 | /* Determine which optional fan and pwm features are enabled (only |
2146 | * valid for I2C devices) */ | ||
2056 | if (client) { /* I2C chip */ | 2147 | if (client) { /* I2C chip */ |
2057 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); | 2148 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); |
2058 | /* Check if optional fan3 input is enabled */ | 2149 | /* Check if optional fan3 input is enabled */ |
2059 | if (data->config2 & 0x04) { | 2150 | if (data->config2 & 0x04) { |
2060 | data->has_fan |= (1 << 2); | 2151 | data->has_features |= HAS_FAN(2); |
2061 | } | 2152 | } |
2062 | 2153 | ||
2063 | /* Fan4 and pwm3 are only available if the client's I2C address | 2154 | /* Fan4 and pwm3 are only available if the client's I2C address |
2064 | * is the default 0x2e. Otherwise the I/Os associated with | 2155 | * is the default 0x2e. Otherwise the I/Os associated with |
2065 | * these functions are used for addr enable/select. */ | 2156 | * these functions are used for addr enable/select. */ |
2066 | if (client->addr == 0x2e) { | 2157 | if (client->addr == 0x2e) { |
2067 | data->has_fan |= (1 << 3); | 2158 | data->has_features |= HAS_FAN(3) | HAS_PWM(2); |
2068 | data->has_pwm |= (1 << 2); | ||
2069 | } | 2159 | } |
2070 | 2160 | ||
2071 | /* Determine which of the optional fan[5-6] and pwm[5-6] | 2161 | /* Determine which of the optional fan[5-6] and pwm[5-6] |
@@ -2077,26 +2167,40 @@ static int dme1737_init_device(struct device *dev) | |||
2077 | dev_warn(dev, "Failed to query Super-IO for optional " | 2167 | dev_warn(dev, "Failed to query Super-IO for optional " |
2078 | "features.\n"); | 2168 | "features.\n"); |
2079 | } | 2169 | } |
2080 | } else { /* ISA chip */ | ||
2081 | /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6] | ||
2082 | * don't exist in the ISA chip. */ | ||
2083 | data->has_fan |= (1 << 2); | ||
2084 | data->has_pwm |= (1 << 2); | ||
2085 | } | 2170 | } |
2086 | 2171 | ||
2087 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | 2172 | /* Fan[1-2] and pwm[1-2] are present in all chips */ |
2088 | data->has_fan |= 0x03; | 2173 | data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1); |
2089 | data->has_pwm |= 0x03; | 2174 | |
2175 | /* Chip-dependent features */ | ||
2176 | switch (data->type) { | ||
2177 | case dme1737: | ||
2178 | data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 | | ||
2179 | HAS_ZONE_HYST | HAS_PWM_MIN; | ||
2180 | break; | ||
2181 | case sch311x: | ||
2182 | data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 | | ||
2183 | HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2); | ||
2184 | break; | ||
2185 | case sch5027: | ||
2186 | data->has_features |= HAS_ZONE3; | ||
2187 | break; | ||
2188 | case sch5127: | ||
2189 | data->has_features |= HAS_FAN(2) | HAS_PWM(2); | ||
2190 | break; | ||
2191 | default: | ||
2192 | break; | ||
2193 | } | ||
2090 | 2194 | ||
2091 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | 2195 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " |
2092 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | 2196 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", |
2093 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | 2197 | (data->has_features & HAS_PWM(2)) ? "yes" : "no", |
2094 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | 2198 | (data->has_features & HAS_PWM(4)) ? "yes" : "no", |
2095 | (data->has_pwm & (1 << 5)) ? "yes" : "no", | 2199 | (data->has_features & HAS_PWM(5)) ? "yes" : "no", |
2096 | (data->has_fan & (1 << 2)) ? "yes" : "no", | 2200 | (data->has_features & HAS_FAN(2)) ? "yes" : "no", |
2097 | (data->has_fan & (1 << 3)) ? "yes" : "no", | 2201 | (data->has_features & HAS_FAN(3)) ? "yes" : "no", |
2098 | (data->has_fan & (1 << 4)) ? "yes" : "no", | 2202 | (data->has_features & HAS_FAN(4)) ? "yes" : "no", |
2099 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | 2203 | (data->has_features & HAS_FAN(5)) ? "yes" : "no"); |
2100 | 2204 | ||
2101 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); | 2205 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); |
2102 | /* Inform if fan-to-pwm mapping differs from the default */ | 2206 | /* Inform if fan-to-pwm mapping differs from the default */ |
@@ -2122,7 +2226,7 @@ static int dme1737_init_device(struct device *dev) | |||
2122 | for (ix = 0; ix < 3; ix++) { | 2226 | for (ix = 0; ix < 3; ix++) { |
2123 | data->pwm_config[ix] = dme1737_read(data, | 2227 | data->pwm_config[ix] = dme1737_read(data, |
2124 | DME1737_REG_PWM_CONFIG(ix)); | 2228 | DME1737_REG_PWM_CONFIG(ix)); |
2125 | if ((data->has_pwm & (1 << ix)) && | 2229 | if ((data->has_features & HAS_PWM(ix)) && |
2126 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 2230 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
2127 | dev_info(dev, "Switching pwm%d to " | 2231 | dev_info(dev, "Switching pwm%d to " |
2128 | "manual mode.\n", ix + 1); | 2232 | "manual mode.\n", ix + 1); |
@@ -2142,7 +2246,7 @@ static int dme1737_init_device(struct device *dev) | |||
2142 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | 2246 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ |
2143 | 2247 | ||
2144 | /* Set VRM */ | 2248 | /* Set VRM */ |
2145 | if (data->type == dme1737) { | 2249 | if (data->has_features & HAS_VID) { |
2146 | data->vrm = vid_which_vrm(); | 2250 | data->vrm = vid_which_vrm(); |
2147 | } | 2251 | } |
2148 | 2252 | ||
@@ -2163,10 +2267,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2163 | dme1737_sio_enter(sio_cip); | 2267 | dme1737_sio_enter(sio_cip); |
2164 | 2268 | ||
2165 | /* Check device ID | 2269 | /* Check device ID |
2166 | * The DME1737 can return either 0x78 or 0x77 as its device ID. | 2270 | * We currently know about two kinds of DME1737 and SCH5027. */ |
2167 | * The SCH5027 returns 0x89 as its device ID. */ | ||
2168 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2271 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
2169 | if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { | 2272 | if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 || |
2273 | reg == SCH5027_ID)) { | ||
2170 | err = -ENODEV; | 2274 | err = -ENODEV; |
2171 | goto exit; | 2275 | goto exit; |
2172 | } | 2276 | } |
@@ -2185,16 +2289,16 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2185 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | 2289 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set |
2186 | * to '10' if the respective feature is enabled. */ | 2290 | * to '10' if the respective feature is enabled. */ |
2187 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | 2291 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ |
2188 | data->has_fan |= (1 << 5); | 2292 | data->has_features |= HAS_FAN(5); |
2189 | } | 2293 | } |
2190 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | 2294 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ |
2191 | data->has_pwm |= (1 << 5); | 2295 | data->has_features |= HAS_PWM(5); |
2192 | } | 2296 | } |
2193 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | 2297 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ |
2194 | data->has_fan |= (1 << 4); | 2298 | data->has_features |= HAS_FAN(4); |
2195 | } | 2299 | } |
2196 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | 2300 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ |
2197 | data->has_pwm |= (1 << 4); | 2301 | data->has_features |= HAS_PWM(4); |
2198 | } | 2302 | } |
2199 | 2303 | ||
2200 | exit: | 2304 | exit: |
@@ -2222,7 +2326,6 @@ static int dme1737_i2c_detect(struct i2c_client *client, | |||
2222 | if (company == DME1737_COMPANY_SMSC && | 2326 | if (company == DME1737_COMPANY_SMSC && |
2223 | verstep == SCH5027_VERSTEP) { | 2327 | verstep == SCH5027_VERSTEP) { |
2224 | name = "sch5027"; | 2328 | name = "sch5027"; |
2225 | |||
2226 | } else if (company == DME1737_COMPANY_SMSC && | 2329 | } else if (company == DME1737_COMPANY_SMSC && |
2227 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { | 2330 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
2228 | name = "dme1737"; | 2331 | name = "dme1737"; |
@@ -2329,10 +2432,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) | |||
2329 | dme1737_sio_enter(sio_cip); | 2432 | dme1737_sio_enter(sio_cip); |
2330 | 2433 | ||
2331 | /* Check device ID | 2434 | /* Check device ID |
2332 | * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and | 2435 | * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */ |
2333 | * SCH3116 (0x7f). */ | ||
2334 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2436 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
2335 | if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { | 2437 | if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID || |
2438 | reg == SCH5127_ID)) { | ||
2336 | err = -ENODEV; | 2439 | err = -ENODEV; |
2337 | goto exit; | 2440 | goto exit; |
2338 | } | 2441 | } |
@@ -2424,23 +2527,42 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2424 | platform_set_drvdata(pdev, data); | 2527 | platform_set_drvdata(pdev, data); |
2425 | 2528 | ||
2426 | /* Skip chip detection if module is loaded with force_id parameter */ | 2529 | /* Skip chip detection if module is loaded with force_id parameter */ |
2427 | if (!force_id) { | 2530 | switch (force_id) { |
2531 | case SCH3112_ID: | ||
2532 | case SCH3114_ID: | ||
2533 | case SCH3116_ID: | ||
2534 | data->type = sch311x; | ||
2535 | break; | ||
2536 | case SCH5127_ID: | ||
2537 | data->type = sch5127; | ||
2538 | break; | ||
2539 | default: | ||
2428 | company = dme1737_read(data, DME1737_REG_COMPANY); | 2540 | company = dme1737_read(data, DME1737_REG_COMPANY); |
2429 | device = dme1737_read(data, DME1737_REG_DEVICE); | 2541 | device = dme1737_read(data, DME1737_REG_DEVICE); |
2430 | 2542 | ||
2431 | if (!((company == DME1737_COMPANY_SMSC) && | 2543 | if ((company == DME1737_COMPANY_SMSC) && |
2432 | (device == SCH311X_DEVICE))) { | 2544 | (device == SCH311X_DEVICE)) { |
2545 | data->type = sch311x; | ||
2546 | } else if ((company == DME1737_COMPANY_SMSC) && | ||
2547 | (device == SCH5127_DEVICE)) { | ||
2548 | data->type = sch5127; | ||
2549 | } else { | ||
2433 | err = -ENODEV; | 2550 | err = -ENODEV; |
2434 | goto exit_kfree; | 2551 | goto exit_kfree; |
2435 | } | 2552 | } |
2436 | } | 2553 | } |
2437 | data->type = sch311x; | ||
2438 | 2554 | ||
2439 | /* Fill in the remaining client fields and initialize the mutex */ | 2555 | if (data->type == sch5127) { |
2440 | data->name = "sch311x"; | 2556 | data->name = "sch5127"; |
2557 | } else { | ||
2558 | data->name = "sch311x"; | ||
2559 | } | ||
2560 | |||
2561 | /* Initialize the mutex */ | ||
2441 | mutex_init(&data->update_lock); | 2562 | mutex_init(&data->update_lock); |
2442 | 2563 | ||
2443 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); | 2564 | dev_info(dev, "Found a %s chip at 0x%04x\n", |
2565 | data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); | ||
2444 | 2566 | ||
2445 | /* Initialize the chip */ | 2567 | /* Initialize the chip */ |
2446 | if ((err = dme1737_init_device(dev))) { | 2568 | if ((err = dme1737_init_device(dev))) { |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c new file mode 100644 index 000000000000..0e4b5642638d --- /dev/null +++ b/drivers/hwmon/emc1403.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * emc1403.c - SMSC Thermal Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
21 | * | ||
22 | * TODO | ||
23 | * - cache alarm and critical limit registers | ||
24 | * - add emc1404 support | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/hwmon.h> | ||
32 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/sysfs.h> | ||
35 | #include <linux/mutex.h> | ||
36 | |||
37 | #define THERMAL_PID_REG 0xfd | ||
38 | #define THERMAL_SMSC_ID_REG 0xfe | ||
39 | #define THERMAL_REVISION_REG 0xff | ||
40 | |||
41 | struct thermal_data { | ||
42 | struct device *hwmon_dev; | ||
43 | struct mutex mutex; | ||
44 | /* Cache the hyst value so we don't keep re-reading it. In theory | ||
45 | we could cache it forever as nobody else should be writing it. */ | ||
46 | u8 cached_hyst; | ||
47 | unsigned long hyst_valid; | ||
48 | }; | ||
49 | |||
50 | static ssize_t show_temp(struct device *dev, | ||
51 | struct device_attribute *attr, char *buf) | ||
52 | { | ||
53 | struct i2c_client *client = to_i2c_client(dev); | ||
54 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
55 | int retval = i2c_smbus_read_byte_data(client, sda->index); | ||
56 | |||
57 | if (retval < 0) | ||
58 | return retval; | ||
59 | return sprintf(buf, "%d000\n", retval); | ||
60 | } | ||
61 | |||
62 | static ssize_t show_bit(struct device *dev, | ||
63 | struct device_attribute *attr, char *buf) | ||
64 | { | ||
65 | struct i2c_client *client = to_i2c_client(dev); | ||
66 | struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); | ||
67 | int retval = i2c_smbus_read_byte_data(client, sda->nr); | ||
68 | |||
69 | if (retval < 0) | ||
70 | return retval; | ||
71 | retval &= sda->index; | ||
72 | return sprintf(buf, "%d\n", retval ? 1 : 0); | ||
73 | } | ||
74 | |||
75 | static ssize_t store_temp(struct device *dev, | ||
76 | struct device_attribute *attr, const char *buf, size_t count) | ||
77 | { | ||
78 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
79 | struct i2c_client *client = to_i2c_client(dev); | ||
80 | unsigned long val; | ||
81 | int retval; | ||
82 | |||
83 | if (strict_strtoul(buf, 10, &val)) | ||
84 | return -EINVAL; | ||
85 | retval = i2c_smbus_write_byte_data(client, sda->index, | ||
86 | DIV_ROUND_CLOSEST(val, 1000)); | ||
87 | if (retval < 0) | ||
88 | return retval; | ||
89 | return count; | ||
90 | } | ||
91 | |||
92 | static ssize_t show_hyst(struct device *dev, | ||
93 | struct device_attribute *attr, char *buf) | ||
94 | { | ||
95 | struct i2c_client *client = to_i2c_client(dev); | ||
96 | struct thermal_data *data = i2c_get_clientdata(client); | ||
97 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
98 | int retval; | ||
99 | int hyst; | ||
100 | |||
101 | retval = i2c_smbus_read_byte_data(client, sda->index); | ||
102 | if (retval < 0) | ||
103 | return retval; | ||
104 | |||
105 | if (time_after(jiffies, data->hyst_valid)) { | ||
106 | hyst = i2c_smbus_read_byte_data(client, 0x21); | ||
107 | if (hyst < 0) | ||
108 | return retval; | ||
109 | data->cached_hyst = hyst; | ||
110 | data->hyst_valid = jiffies + HZ; | ||
111 | } | ||
112 | return sprintf(buf, "%d000\n", retval - data->cached_hyst); | ||
113 | } | ||
114 | |||
115 | static ssize_t store_hyst(struct device *dev, | ||
116 | struct device_attribute *attr, const char *buf, size_t count) | ||
117 | { | ||
118 | struct i2c_client *client = to_i2c_client(dev); | ||
119 | struct thermal_data *data = i2c_get_clientdata(client); | ||
120 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
121 | int retval; | ||
122 | int hyst; | ||
123 | unsigned long val; | ||
124 | |||
125 | if (strict_strtoul(buf, 10, &val)) | ||
126 | return -EINVAL; | ||
127 | |||
128 | mutex_lock(&data->mutex); | ||
129 | retval = i2c_smbus_read_byte_data(client, sda->index); | ||
130 | if (retval < 0) | ||
131 | goto fail; | ||
132 | |||
133 | hyst = val - retval * 1000; | ||
134 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); | ||
135 | if (hyst < 0 || hyst > 255) { | ||
136 | retval = -ERANGE; | ||
137 | goto fail; | ||
138 | } | ||
139 | |||
140 | retval = i2c_smbus_write_byte_data(client, 0x21, hyst); | ||
141 | if (retval == 0) { | ||
142 | retval = count; | ||
143 | data->cached_hyst = hyst; | ||
144 | data->hyst_valid = jiffies + HZ; | ||
145 | } | ||
146 | fail: | ||
147 | mutex_unlock(&data->mutex); | ||
148 | return retval; | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * Sensors. We pass the actual i2c register to the methods. | ||
153 | */ | ||
154 | |||
155 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, | ||
156 | show_temp, store_temp, 0x06); | ||
157 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, | ||
158 | show_temp, store_temp, 0x05); | ||
159 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, | ||
160 | show_temp, store_temp, 0x20); | ||
161 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0x00); | ||
162 | static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, | ||
163 | show_bit, NULL, 0x36, 0x01); | ||
164 | static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, | ||
165 | show_bit, NULL, 0x35, 0x01); | ||
166 | static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, | ||
167 | show_bit, NULL, 0x37, 0x01); | ||
168 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR, | ||
169 | show_hyst, store_hyst, 0x20); | ||
170 | |||
171 | static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, | ||
172 | show_temp, store_temp, 0x08); | ||
173 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, | ||
174 | show_temp, store_temp, 0x07); | ||
175 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, | ||
176 | show_temp, store_temp, 0x19); | ||
177 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0x01); | ||
178 | static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, | ||
179 | show_bit, NULL, 0x36, 0x02); | ||
180 | static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, | ||
181 | show_bit, NULL, 0x35, 0x02); | ||
182 | static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, | ||
183 | show_bit, NULL, 0x37, 0x02); | ||
184 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO | S_IWUSR, | ||
185 | show_hyst, store_hyst, 0x19); | ||
186 | |||
187 | static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, | ||
188 | show_temp, store_temp, 0x16); | ||
189 | static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, | ||
190 | show_temp, store_temp, 0x15); | ||
191 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO | S_IWUSR, | ||
192 | show_temp, store_temp, 0x1A); | ||
193 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 0x23); | ||
194 | static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, | ||
195 | show_bit, NULL, 0x36, 0x04); | ||
196 | static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, | ||
197 | show_bit, NULL, 0x35, 0x04); | ||
198 | static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, | ||
199 | show_bit, NULL, 0x37, 0x04); | ||
200 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR, | ||
201 | show_hyst, store_hyst, 0x1A); | ||
202 | |||
203 | static struct attribute *mid_att_thermal[] = { | ||
204 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
205 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
206 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
207 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
208 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
209 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
210 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
211 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
212 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
213 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
214 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
215 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
216 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
217 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
218 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
219 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
220 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
221 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
222 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
223 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
224 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
225 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
226 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
227 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
228 | NULL | ||
229 | }; | ||
230 | |||
231 | static const struct attribute_group m_thermal_gr = { | ||
232 | .attrs = mid_att_thermal | ||
233 | }; | ||
234 | |||
235 | static int emc1403_detect(struct i2c_client *client, | ||
236 | struct i2c_board_info *info) | ||
237 | { | ||
238 | int id; | ||
239 | /* Check if thermal chip is SMSC and EMC1403 */ | ||
240 | |||
241 | id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG); | ||
242 | if (id != 0x5d) | ||
243 | return -ENODEV; | ||
244 | |||
245 | /* Note: 0x25 is the 1404 which is very similar and this | ||
246 | driver could be extended */ | ||
247 | id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); | ||
248 | if (id != 0x21) | ||
249 | return -ENODEV; | ||
250 | |||
251 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); | ||
252 | if (id != 0x01) | ||
253 | return -ENODEV; | ||
254 | |||
255 | strlcpy(info->type, "emc1403", I2C_NAME_SIZE); | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int emc1403_probe(struct i2c_client *client, | ||
260 | const struct i2c_device_id *id) | ||
261 | { | ||
262 | int res; | ||
263 | struct thermal_data *data; | ||
264 | |||
265 | data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL); | ||
266 | if (data == NULL) { | ||
267 | dev_warn(&client->dev, "out of memory"); | ||
268 | return -ENOMEM; | ||
269 | } | ||
270 | |||
271 | i2c_set_clientdata(client, data); | ||
272 | mutex_init(&data->mutex); | ||
273 | data->hyst_valid = jiffies - 1; /* Expired */ | ||
274 | |||
275 | res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); | ||
276 | if (res) { | ||
277 | dev_warn(&client->dev, "create group failed\n"); | ||
278 | hwmon_device_unregister(data->hwmon_dev); | ||
279 | goto thermal_error1; | ||
280 | } | ||
281 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
282 | if (IS_ERR(data->hwmon_dev)) { | ||
283 | res = PTR_ERR(data->hwmon_dev); | ||
284 | dev_warn(&client->dev, "register hwmon dev failed\n"); | ||
285 | goto thermal_error2; | ||
286 | } | ||
287 | dev_info(&client->dev, "EMC1403 Thermal chip found\n"); | ||
288 | return res; | ||
289 | |||
290 | thermal_error2: | ||
291 | sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); | ||
292 | thermal_error1: | ||
293 | kfree(data); | ||
294 | return res; | ||
295 | } | ||
296 | |||
297 | static int emc1403_remove(struct i2c_client *client) | ||
298 | { | ||
299 | struct thermal_data *data = i2c_get_clientdata(client); | ||
300 | |||
301 | hwmon_device_unregister(data->hwmon_dev); | ||
302 | sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); | ||
303 | kfree(data); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static const unsigned short emc1403_address_list[] = { | ||
308 | 0x18, 0x2a, 0x4c, 0x4d, I2C_CLIENT_END | ||
309 | }; | ||
310 | |||
311 | static const struct i2c_device_id emc1403_idtable[] = { | ||
312 | { "emc1403", 0 }, | ||
313 | { } | ||
314 | }; | ||
315 | MODULE_DEVICE_TABLE(i2c, emc1403_idtable); | ||
316 | |||
317 | static struct i2c_driver sensor_emc1403 = { | ||
318 | .class = I2C_CLASS_HWMON, | ||
319 | .driver = { | ||
320 | .name = "emc1403", | ||
321 | }, | ||
322 | .detect = emc1403_detect, | ||
323 | .probe = emc1403_probe, | ||
324 | .remove = emc1403_remove, | ||
325 | .id_table = emc1403_idtable, | ||
326 | .address_list = emc1403_address_list, | ||
327 | }; | ||
328 | |||
329 | static int __init sensor_emc1403_init(void) | ||
330 | { | ||
331 | return i2c_add_driver(&sensor_emc1403); | ||
332 | } | ||
333 | |||
334 | static void __exit sensor_emc1403_exit(void) | ||
335 | { | ||
336 | i2c_del_driver(&sensor_emc1403); | ||
337 | } | ||
338 | |||
339 | module_init(sensor_emc1403_init); | ||
340 | module_exit(sensor_emc1403_exit); | ||
341 | |||
342 | MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com"); | ||
343 | MODULE_DESCRIPTION("emc1403 Thermal Driver"); | ||
344 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index a95fa4256caa..537841ef44b9 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -856,21 +856,19 @@ static inline int superio_inb(int base, int reg) | |||
856 | static int superio_inw(int base, int reg) | 856 | static int superio_inw(int base, int reg) |
857 | { | 857 | { |
858 | int val; | 858 | int val; |
859 | outb(reg++, base); | 859 | val = superio_inb(base, reg) << 8; |
860 | val = inb(base + 1) << 8; | 860 | val |= superio_inb(base, reg + 1); |
861 | outb(reg, base); | ||
862 | val |= inb(base + 1); | ||
863 | return val; | 861 | return val; |
864 | } | 862 | } |
865 | 863 | ||
866 | static inline void superio_enter(int base) | 864 | static inline void superio_enter(int base) |
867 | { | 865 | { |
868 | /* according to the datasheet the key must be send twice! */ | 866 | /* according to the datasheet the key must be send twice! */ |
869 | outb( SIO_UNLOCK_KEY, base); | 867 | outb(SIO_UNLOCK_KEY, base); |
870 | outb( SIO_UNLOCK_KEY, base); | 868 | outb(SIO_UNLOCK_KEY, base); |
871 | } | 869 | } |
872 | 870 | ||
873 | static inline void superio_select( int base, int ld) | 871 | static inline void superio_select(int base, int ld) |
874 | { | 872 | { |
875 | outb(SIO_REG_LDSEL, base); | 873 | outb(SIO_REG_LDSEL, base); |
876 | outb(ld, base + 1); | 874 | outb(ld, base + 1); |
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) | |||
905 | { | 903 | { |
906 | u16 val; | 904 | u16 val; |
907 | 905 | ||
908 | outb(reg++, data->addr + ADDR_REG_OFFSET); | 906 | val = f71882fg_read8(data, reg) << 8; |
909 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | 907 | val |= f71882fg_read8(data, reg + 1); |
910 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
911 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
912 | 908 | ||
913 | return val; | 909 | return val; |
914 | } | 910 | } |
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) | |||
921 | 917 | ||
922 | static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) | 918 | static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) |
923 | { | 919 | { |
924 | outb(reg++, data->addr + ADDR_REG_OFFSET); | 920 | f71882fg_write8(data, reg, val >> 8); |
925 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | 921 | f71882fg_write8(data, reg + 1, val & 0xff); |
926 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
927 | outb(val & 255, data->addr + DATA_REG_OFFSET); | ||
928 | } | 922 | } |
929 | 923 | ||
930 | static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) | 924 | static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) |
@@ -945,7 +939,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
945 | mutex_lock(&data->update_lock); | 939 | mutex_lock(&data->update_lock); |
946 | 940 | ||
947 | /* Update once every 60 seconds */ | 941 | /* Update once every 60 seconds */ |
948 | if ( time_after(jiffies, data->last_limits + 60 * HZ ) || | 942 | if (time_after(jiffies, data->last_limits + 60 * HZ) || |
949 | !data->valid) { | 943 | !data->valid) { |
950 | if (data->type == f71882fg || data->type == f71889fg) { | 944 | if (data->type == f71882fg || data->type == f71889fg) { |
951 | data->in1_max = | 945 | data->in1_max = |
@@ -1127,8 +1121,12 @@ static ssize_t store_fan_full_speed(struct device *dev, | |||
1127 | const char *buf, size_t count) | 1121 | const char *buf, size_t count) |
1128 | { | 1122 | { |
1129 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1123 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1130 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1124 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1131 | long val = simple_strtol(buf, NULL, 10); | 1125 | long val; |
1126 | |||
1127 | err = strict_strtol(buf, 10, &val); | ||
1128 | if (err) | ||
1129 | return err; | ||
1132 | 1130 | ||
1133 | val = SENSORS_LIMIT(val, 23, 1500000); | 1131 | val = SENSORS_LIMIT(val, 23, 1500000); |
1134 | val = fan_to_reg(val); | 1132 | val = fan_to_reg(val); |
@@ -1157,8 +1155,12 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute | |||
1157 | *devattr, const char *buf, size_t count) | 1155 | *devattr, const char *buf, size_t count) |
1158 | { | 1156 | { |
1159 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1157 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1160 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1158 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1161 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1159 | unsigned long val; |
1160 | |||
1161 | err = strict_strtoul(buf, 10, &val); | ||
1162 | if (err) | ||
1163 | return err; | ||
1162 | 1164 | ||
1163 | mutex_lock(&data->update_lock); | 1165 | mutex_lock(&data->update_lock); |
1164 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); | 1166 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); |
@@ -1206,7 +1208,14 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute | |||
1206 | *devattr, const char *buf, size_t count) | 1208 | *devattr, const char *buf, size_t count) |
1207 | { | 1209 | { |
1208 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1210 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1209 | long val = simple_strtol(buf, NULL, 10) / 8; | 1211 | int err; |
1212 | long val; | ||
1213 | |||
1214 | err = strict_strtol(buf, 10, &val); | ||
1215 | if (err) | ||
1216 | return err; | ||
1217 | |||
1218 | val /= 8; | ||
1210 | val = SENSORS_LIMIT(val, 0, 255); | 1219 | val = SENSORS_LIMIT(val, 0, 255); |
1211 | 1220 | ||
1212 | mutex_lock(&data->update_lock); | 1221 | mutex_lock(&data->update_lock); |
@@ -1233,8 +1242,12 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute | |||
1233 | *devattr, const char *buf, size_t count) | 1242 | *devattr, const char *buf, size_t count) |
1234 | { | 1243 | { |
1235 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1244 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1236 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1245 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1237 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1246 | unsigned long val; |
1247 | |||
1248 | err = strict_strtoul(buf, 10, &val); | ||
1249 | if (err) | ||
1250 | return err; | ||
1238 | 1251 | ||
1239 | mutex_lock(&data->update_lock); | 1252 | mutex_lock(&data->update_lock); |
1240 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); | 1253 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); |
@@ -1299,8 +1312,14 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute | |||
1299 | *devattr, const char *buf, size_t count) | 1312 | *devattr, const char *buf, size_t count) |
1300 | { | 1313 | { |
1301 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1314 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1302 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1315 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1303 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1316 | long val; |
1317 | |||
1318 | err = strict_strtol(buf, 10, &val); | ||
1319 | if (err) | ||
1320 | return err; | ||
1321 | |||
1322 | val /= 1000; | ||
1304 | val = SENSORS_LIMIT(val, 0, 255); | 1323 | val = SENSORS_LIMIT(val, 0, 255); |
1305 | 1324 | ||
1306 | mutex_lock(&data->update_lock); | 1325 | mutex_lock(&data->update_lock); |
@@ -1333,10 +1352,16 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | |||
1333 | *devattr, const char *buf, size_t count) | 1352 | *devattr, const char *buf, size_t count) |
1334 | { | 1353 | { |
1335 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1354 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1336 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1355 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1337 | long val = simple_strtol(buf, NULL, 10) / 1000; | ||
1338 | ssize_t ret = count; | 1356 | ssize_t ret = count; |
1339 | u8 reg; | 1357 | u8 reg; |
1358 | long val; | ||
1359 | |||
1360 | err = strict_strtol(buf, 10, &val); | ||
1361 | if (err) | ||
1362 | return err; | ||
1363 | |||
1364 | val /= 1000; | ||
1340 | 1365 | ||
1341 | mutex_lock(&data->update_lock); | 1366 | mutex_lock(&data->update_lock); |
1342 | 1367 | ||
@@ -1372,8 +1397,14 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute | |||
1372 | *devattr, const char *buf, size_t count) | 1397 | *devattr, const char *buf, size_t count) |
1373 | { | 1398 | { |
1374 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1399 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1375 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1400 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1376 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1401 | long val; |
1402 | |||
1403 | err = strict_strtol(buf, 10, &val); | ||
1404 | if (err) | ||
1405 | return err; | ||
1406 | |||
1407 | val /= 1000; | ||
1377 | val = SENSORS_LIMIT(val, 0, 255); | 1408 | val = SENSORS_LIMIT(val, 0, 255); |
1378 | 1409 | ||
1379 | mutex_lock(&data->update_lock); | 1410 | mutex_lock(&data->update_lock); |
@@ -1427,8 +1458,12 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute | |||
1427 | *devattr, const char *buf, size_t count) | 1458 | *devattr, const char *buf, size_t count) |
1428 | { | 1459 | { |
1429 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1460 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1430 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1461 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1431 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1462 | unsigned long val; |
1463 | |||
1464 | err = strict_strtoul(buf, 10, &val); | ||
1465 | if (err) | ||
1466 | return err; | ||
1432 | 1467 | ||
1433 | mutex_lock(&data->update_lock); | 1468 | mutex_lock(&data->update_lock); |
1434 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); | 1469 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); |
@@ -1490,8 +1525,13 @@ static ssize_t store_pwm(struct device *dev, | |||
1490 | size_t count) | 1525 | size_t count) |
1491 | { | 1526 | { |
1492 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1527 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1493 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1528 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1494 | long val = simple_strtol(buf, NULL, 10); | 1529 | long val; |
1530 | |||
1531 | err = strict_strtol(buf, 10, &val); | ||
1532 | if (err) | ||
1533 | return err; | ||
1534 | |||
1495 | val = SENSORS_LIMIT(val, 0, 255); | 1535 | val = SENSORS_LIMIT(val, 0, 255); |
1496 | 1536 | ||
1497 | mutex_lock(&data->update_lock); | 1537 | mutex_lock(&data->update_lock); |
@@ -1551,8 +1591,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute | |||
1551 | *devattr, const char *buf, size_t count) | 1591 | *devattr, const char *buf, size_t count) |
1552 | { | 1592 | { |
1553 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1593 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1554 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1594 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1555 | long val = simple_strtol(buf, NULL, 10); | 1595 | long val; |
1596 | |||
1597 | err = strict_strtol(buf, 10, &val); | ||
1598 | if (err) | ||
1599 | return err; | ||
1556 | 1600 | ||
1557 | /* Special case for F8000 pwm channel 3 which only does auto mode */ | 1601 | /* Special case for F8000 pwm channel 3 which only does auto mode */ |
1558 | if (data->type == f8000 && nr == 2 && val != 2) | 1602 | if (data->type == f8000 && nr == 2 && val != 2) |
@@ -1626,9 +1670,14 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev, | |||
1626 | const char *buf, size_t count) | 1670 | const char *buf, size_t count) |
1627 | { | 1671 | { |
1628 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1672 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1629 | int pwm = to_sensor_dev_attr_2(devattr)->index; | 1673 | int err, pwm = to_sensor_dev_attr_2(devattr)->index; |
1630 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1674 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1631 | long val = simple_strtol(buf, NULL, 10); | 1675 | long val; |
1676 | |||
1677 | err = strict_strtol(buf, 10, &val); | ||
1678 | if (err) | ||
1679 | return err; | ||
1680 | |||
1632 | val = SENSORS_LIMIT(val, 0, 255); | 1681 | val = SENSORS_LIMIT(val, 0, 255); |
1633 | 1682 | ||
1634 | mutex_lock(&data->update_lock); | 1683 | mutex_lock(&data->update_lock); |
@@ -1674,10 +1723,16 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, | |||
1674 | const char *buf, size_t count) | 1723 | const char *buf, size_t count) |
1675 | { | 1724 | { |
1676 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1725 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1677 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1726 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1678 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1727 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1679 | long val = simple_strtol(buf, NULL, 10) / 1000; | ||
1680 | u8 reg; | 1728 | u8 reg; |
1729 | long val; | ||
1730 | |||
1731 | err = strict_strtol(buf, 10, &val); | ||
1732 | if (err) | ||
1733 | return err; | ||
1734 | |||
1735 | val /= 1000; | ||
1681 | 1736 | ||
1682 | mutex_lock(&data->update_lock); | 1737 | mutex_lock(&data->update_lock); |
1683 | data->pwm_auto_point_temp[nr][point] = | 1738 | data->pwm_auto_point_temp[nr][point] = |
@@ -1716,8 +1771,12 @@ static ssize_t store_pwm_interpolate(struct device *dev, | |||
1716 | const char *buf, size_t count) | 1771 | const char *buf, size_t count) |
1717 | { | 1772 | { |
1718 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1773 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1719 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1774 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1720 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1775 | unsigned long val; |
1776 | |||
1777 | err = strict_strtoul(buf, 10, &val); | ||
1778 | if (err) | ||
1779 | return err; | ||
1721 | 1780 | ||
1722 | mutex_lock(&data->update_lock); | 1781 | mutex_lock(&data->update_lock); |
1723 | data->pwm_auto_point_mapping[nr] = | 1782 | data->pwm_auto_point_mapping[nr] = |
@@ -1752,8 +1811,12 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, | |||
1752 | const char *buf, size_t count) | 1811 | const char *buf, size_t count) |
1753 | { | 1812 | { |
1754 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1813 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1755 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1814 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1756 | long val = simple_strtol(buf, NULL, 10); | 1815 | long val; |
1816 | |||
1817 | err = strict_strtol(buf, 10, &val); | ||
1818 | if (err) | ||
1819 | return err; | ||
1757 | 1820 | ||
1758 | switch (val) { | 1821 | switch (val) { |
1759 | case 1: | 1822 | case 1: |
@@ -1798,9 +1861,15 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, | |||
1798 | const char *buf, size_t count) | 1861 | const char *buf, size_t count) |
1799 | { | 1862 | { |
1800 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1863 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1801 | int pwm = to_sensor_dev_attr_2(devattr)->index; | 1864 | int err, pwm = to_sensor_dev_attr_2(devattr)->index; |
1802 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1865 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1803 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1866 | long val; |
1867 | |||
1868 | err = strict_strtol(buf, 10, &val); | ||
1869 | if (err) | ||
1870 | return err; | ||
1871 | |||
1872 | val /= 1000; | ||
1804 | 1873 | ||
1805 | if (data->type == f71889fg) | 1874 | if (data->type == f71889fg) |
1806 | val = SENSORS_LIMIT(val, -128, 127); | 1875 | val = SENSORS_LIMIT(val, -128, 127); |
@@ -2109,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2109 | int err = -ENODEV; | 2178 | int err = -ENODEV; |
2110 | u16 devid; | 2179 | u16 devid; |
2111 | 2180 | ||
2181 | /* Don't step on other drivers' I/O space by accident */ | ||
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | ||
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2112 | superio_enter(sioaddr); | 2188 | superio_enter(sioaddr); |
2113 | 2189 | ||
2114 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
@@ -2151,8 +2227,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2151 | } | 2227 | } |
2152 | 2228 | ||
2153 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2154 | if (*address == 0) | 2230 | if (*address == 0) { |
2155 | { | ||
2156 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2157 | goto exit; | 2232 | goto exit; |
2158 | } | 2233 | } |
@@ -2164,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2164 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2165 | exit: | 2240 | exit: |
2166 | superio_exit(sioaddr); | 2241 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2167 | return err; | 2243 | return err; |
2168 | } | 2244 | } |
2169 | 2245 | ||
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index bf81aff7051d..776aeb3019d2 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -53,7 +53,7 @@ | |||
53 | * Address is fully defined internally and cannot be changed. | 53 | * Address is fully defined internally and cannot be changed. |
54 | */ | 54 | */ |
55 | 55 | ||
56 | static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; | 56 | static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * The LM63 registers | 59 | * The LM63 registers |
@@ -131,12 +131,15 @@ static struct lm63_data *lm63_update_device(struct device *dev); | |||
131 | static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); | 131 | static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); |
132 | static void lm63_init_client(struct i2c_client *client); | 132 | static void lm63_init_client(struct i2c_client *client); |
133 | 133 | ||
134 | enum chips { lm63, lm64 }; | ||
135 | |||
134 | /* | 136 | /* |
135 | * Driver data (common to all clients) | 137 | * Driver data (common to all clients) |
136 | */ | 138 | */ |
137 | 139 | ||
138 | static const struct i2c_device_id lm63_id[] = { | 140 | static const struct i2c_device_id lm63_id[] = { |
139 | { "lm63", 0 }, | 141 | { "lm63", lm63 }, |
142 | { "lm64", lm64 }, | ||
140 | { } | 143 | { } |
141 | }; | 144 | }; |
142 | MODULE_DEVICE_TABLE(i2c, lm63_id); | 145 | MODULE_DEVICE_TABLE(i2c, lm63_id); |
@@ -422,6 +425,7 @@ static int lm63_detect(struct i2c_client *new_client, | |||
422 | struct i2c_adapter *adapter = new_client->adapter; | 425 | struct i2c_adapter *adapter = new_client->adapter; |
423 | u8 man_id, chip_id, reg_config1, reg_config2; | 426 | u8 man_id, chip_id, reg_config1, reg_config2; |
424 | u8 reg_alert_status, reg_alert_mask; | 427 | u8 reg_alert_status, reg_alert_mask; |
428 | int address = new_client->addr; | ||
425 | 429 | ||
426 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 430 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
427 | return -ENODEV; | 431 | return -ENODEV; |
@@ -439,7 +443,6 @@ static int lm63_detect(struct i2c_client *new_client, | |||
439 | LM63_REG_ALERT_MASK); | 443 | LM63_REG_ALERT_MASK); |
440 | 444 | ||
441 | if (man_id != 0x01 /* National Semiconductor */ | 445 | if (man_id != 0x01 /* National Semiconductor */ |
442 | || chip_id != 0x41 /* LM63 */ | ||
443 | || (reg_config1 & 0x18) != 0x00 | 446 | || (reg_config1 & 0x18) != 0x00 |
444 | || (reg_config2 & 0xF8) != 0x00 | 447 | || (reg_config2 & 0xF8) != 0x00 |
445 | || (reg_alert_status & 0x20) != 0x00 | 448 | || (reg_alert_status & 0x20) != 0x00 |
@@ -450,7 +453,12 @@ static int lm63_detect(struct i2c_client *new_client, | |||
450 | return -ENODEV; | 453 | return -ENODEV; |
451 | } | 454 | } |
452 | 455 | ||
453 | strlcpy(info->type, "lm63", I2C_NAME_SIZE); | 456 | if (chip_id == 0x41 && address == 0x4c) |
457 | strlcpy(info->type, "lm63", I2C_NAME_SIZE); | ||
458 | else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e)) | ||
459 | strlcpy(info->type, "lm64", I2C_NAME_SIZE); | ||
460 | else | ||
461 | return -ENODEV; | ||
454 | 462 | ||
455 | return 0; | 463 | return 0; |
456 | } | 464 | } |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 8ae2cfe2d827..56463428a419 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -46,6 +46,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ | |||
46 | tcn75, | 46 | tcn75, |
47 | tmp100, | 47 | tmp100, |
48 | tmp101, | 48 | tmp101, |
49 | tmp105, | ||
49 | tmp175, | 50 | tmp175, |
50 | tmp275, | 51 | tmp275, |
51 | tmp75, | 52 | tmp75, |
@@ -220,6 +221,7 @@ static const struct i2c_device_id lm75_ids[] = { | |||
220 | { "tcn75", tcn75, }, | 221 | { "tcn75", tcn75, }, |
221 | { "tmp100", tmp100, }, | 222 | { "tmp100", tmp100, }, |
222 | { "tmp101", tmp101, }, | 223 | { "tmp101", tmp101, }, |
224 | { "tmp105", tmp105, }, | ||
223 | { "tmp175", tmp175, }, | 225 | { "tmp175", tmp175, }, |
224 | { "tmp275", tmp275, }, | 226 | { "tmp275", tmp275, }, |
225 | { "tmp75", tmp75, }, | 227 | { "tmp75", tmp75, }, |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 7cc2708871ab..760ef72eea56 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -982,7 +982,8 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
982 | 982 | ||
983 | mutex_lock(&data->update_lock); | 983 | mutex_lock(&data->update_lock); |
984 | 984 | ||
985 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 985 | if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) |
986 | || !data->valid) { | ||
986 | u8 h, l; | 987 | u8 h, l; |
987 | 988 | ||
988 | dev_dbg(&client->dev, "Updating lm90 data.\n"); | 989 | dev_dbg(&client->dev, "Updating lm90 data.\n"); |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 65c232a9d0c5..21d201befc2c 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
@@ -45,9 +45,7 @@ enum ltc4245_cmd { | |||
45 | LTC4245_VEEIN = 0x19, | 45 | LTC4245_VEEIN = 0x19, |
46 | LTC4245_VEESENSE = 0x1a, | 46 | LTC4245_VEESENSE = 0x1a, |
47 | LTC4245_VEEOUT = 0x1b, | 47 | LTC4245_VEEOUT = 0x1b, |
48 | LTC4245_GPIOADC1 = 0x1c, | 48 | LTC4245_GPIOADC = 0x1c, |
49 | LTC4245_GPIOADC2 = 0x1d, | ||
50 | LTC4245_GPIOADC3 = 0x1e, | ||
51 | }; | 49 | }; |
52 | 50 | ||
53 | struct ltc4245_data { | 51 | struct ltc4245_data { |
@@ -61,7 +59,7 @@ struct ltc4245_data { | |||
61 | u8 cregs[0x08]; | 59 | u8 cregs[0x08]; |
62 | 60 | ||
63 | /* Voltage registers */ | 61 | /* Voltage registers */ |
64 | u8 vregs[0x0f]; | 62 | u8 vregs[0x0d]; |
65 | }; | 63 | }; |
66 | 64 | ||
67 | static struct ltc4245_data *ltc4245_update_device(struct device *dev) | 65 | static struct ltc4245_data *ltc4245_update_device(struct device *dev) |
@@ -86,7 +84,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev) | |||
86 | data->cregs[i] = val; | 84 | data->cregs[i] = val; |
87 | } | 85 | } |
88 | 86 | ||
89 | /* Read voltage registers -- 0x10 to 0x1f */ | 87 | /* Read voltage registers -- 0x10 to 0x1c */ |
90 | for (i = 0; i < ARRAY_SIZE(data->vregs); i++) { | 88 | for (i = 0; i < ARRAY_SIZE(data->vregs); i++) { |
91 | val = i2c_smbus_read_byte_data(client, i+0x10); | 89 | val = i2c_smbus_read_byte_data(client, i+0x10); |
92 | if (unlikely(val < 0)) | 90 | if (unlikely(val < 0)) |
@@ -128,9 +126,7 @@ static int ltc4245_get_voltage(struct device *dev, u8 reg) | |||
128 | case LTC4245_VEEOUT: | 126 | case LTC4245_VEEOUT: |
129 | voltage = regval * -55; | 127 | voltage = regval * -55; |
130 | break; | 128 | break; |
131 | case LTC4245_GPIOADC1: | 129 | case LTC4245_GPIOADC: |
132 | case LTC4245_GPIOADC2: | ||
133 | case LTC4245_GPIOADC3: | ||
134 | voltage = regval * 10; | 130 | voltage = regval * 10; |
135 | break; | 131 | break; |
136 | default: | 132 | default: |
@@ -297,9 +293,7 @@ LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2); | |||
297 | LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); | 293 | LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); |
298 | 294 | ||
299 | /* GPIO voltages */ | 295 | /* GPIO voltages */ |
300 | LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC1); | 296 | LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC); |
301 | LTC4245_VOLTAGE(in10_input, LTC4245_GPIOADC2); | ||
302 | LTC4245_VOLTAGE(in11_input, LTC4245_GPIOADC3); | ||
303 | 297 | ||
304 | /* Power Consumption (virtual) */ | 298 | /* Power Consumption (virtual) */ |
305 | LTC4245_POWER(power1_input, LTC4245_12VSENSE); | 299 | LTC4245_POWER(power1_input, LTC4245_12VSENSE); |
@@ -342,8 +336,6 @@ static struct attribute *ltc4245_attributes[] = { | |||
342 | &sensor_dev_attr_in8_min_alarm.dev_attr.attr, | 336 | &sensor_dev_attr_in8_min_alarm.dev_attr.attr, |
343 | 337 | ||
344 | &sensor_dev_attr_in9_input.dev_attr.attr, | 338 | &sensor_dev_attr_in9_input.dev_attr.attr, |
345 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
346 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
347 | 339 | ||
348 | &sensor_dev_attr_power1_input.dev_attr.attr, | 340 | &sensor_dev_attr_power1_input.dev_attr.attr, |
349 | &sensor_dev_attr_power2_input.dev_attr.attr, | 341 | &sensor_dev_attr_power2_input.dev_attr.attr, |
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c new file mode 100644 index 000000000000..8013895a1faf --- /dev/null +++ b/drivers/hwmon/tmp102.c | |||
@@ -0,0 +1,321 @@ | |||
1 | /* Texas Instruments TMP102 SMBus temperature sensor driver | ||
2 | * | ||
3 | * Copyright (C) 2010 Steven King <sfking@fdwdc.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/hwmon.h> | ||
25 | #include <linux/hwmon-sysfs.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <linux/device.h> | ||
29 | |||
30 | #define DRIVER_NAME "tmp102" | ||
31 | |||
32 | #define TMP102_TEMP_REG 0x00 | ||
33 | #define TMP102_CONF_REG 0x01 | ||
34 | /* note: these bit definitions are byte swapped */ | ||
35 | #define TMP102_CONF_SD 0x0100 | ||
36 | #define TMP102_CONF_TM 0x0200 | ||
37 | #define TMP102_CONF_POL 0x0400 | ||
38 | #define TMP102_CONF_F0 0x0800 | ||
39 | #define TMP102_CONF_F1 0x1000 | ||
40 | #define TMP102_CONF_R0 0x2000 | ||
41 | #define TMP102_CONF_R1 0x4000 | ||
42 | #define TMP102_CONF_OS 0x8000 | ||
43 | #define TMP102_CONF_EM 0x0010 | ||
44 | #define TMP102_CONF_AL 0x0020 | ||
45 | #define TMP102_CONF_CR0 0x0040 | ||
46 | #define TMP102_CONF_CR1 0x0080 | ||
47 | #define TMP102_TLOW_REG 0x02 | ||
48 | #define TMP102_THIGH_REG 0x03 | ||
49 | |||
50 | struct tmp102 { | ||
51 | struct device *hwmon_dev; | ||
52 | struct mutex lock; | ||
53 | u16 config_orig; | ||
54 | unsigned long last_update; | ||
55 | int temp[3]; | ||
56 | }; | ||
57 | |||
58 | /* SMBus specifies low byte first, but the TMP102 returns high byte first, | ||
59 | * so we have to swab16 the values */ | ||
60 | static inline int tmp102_read_reg(struct i2c_client *client, u8 reg) | ||
61 | { | ||
62 | int result = i2c_smbus_read_word_data(client, reg); | ||
63 | return result < 0 ? result : swab16(result); | ||
64 | } | ||
65 | |||
66 | static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) | ||
67 | { | ||
68 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
69 | } | ||
70 | |||
71 | /* convert left adjusted 13-bit TMP102 register value to milliCelsius */ | ||
72 | static inline int tmp102_reg_to_mC(s16 val) | ||
73 | { | ||
74 | return ((val & ~0x01) * 1000) / 128; | ||
75 | } | ||
76 | |||
77 | /* convert milliCelsius to left adjusted 13-bit TMP102 register value */ | ||
78 | static inline u16 tmp102_mC_to_reg(int val) | ||
79 | { | ||
80 | return (val * 128) / 1000; | ||
81 | } | ||
82 | |||
83 | static const u8 tmp102_reg[] = { | ||
84 | TMP102_TEMP_REG, | ||
85 | TMP102_TLOW_REG, | ||
86 | TMP102_THIGH_REG, | ||
87 | }; | ||
88 | |||
89 | static struct tmp102 *tmp102_update_device(struct i2c_client *client) | ||
90 | { | ||
91 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | ||
92 | |||
93 | mutex_lock(&tmp102->lock); | ||
94 | if (time_after(jiffies, tmp102->last_update + HZ / 3)) { | ||
95 | int i; | ||
96 | for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { | ||
97 | int status = tmp102_read_reg(client, tmp102_reg[i]); | ||
98 | if (status > -1) | ||
99 | tmp102->temp[i] = tmp102_reg_to_mC(status); | ||
100 | } | ||
101 | tmp102->last_update = jiffies; | ||
102 | } | ||
103 | mutex_unlock(&tmp102->lock); | ||
104 | return tmp102; | ||
105 | } | ||
106 | |||
107 | static ssize_t tmp102_show_temp(struct device *dev, | ||
108 | struct device_attribute *attr, | ||
109 | char *buf) | ||
110 | { | ||
111 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
112 | struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev)); | ||
113 | |||
114 | return sprintf(buf, "%d\n", tmp102->temp[sda->index]); | ||
115 | } | ||
116 | |||
117 | static ssize_t tmp102_set_temp(struct device *dev, | ||
118 | struct device_attribute *attr, | ||
119 | const char *buf, size_t count) | ||
120 | { | ||
121 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
122 | struct i2c_client *client = to_i2c_client(dev); | ||
123 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | ||
124 | long val; | ||
125 | int status; | ||
126 | |||
127 | if (strict_strtol(buf, 10, &val) < 0) | ||
128 | return -EINVAL; | ||
129 | val = SENSORS_LIMIT(val, -256000, 255000); | ||
130 | |||
131 | mutex_lock(&tmp102->lock); | ||
132 | tmp102->temp[sda->index] = val; | ||
133 | status = tmp102_write_reg(client, tmp102_reg[sda->index], | ||
134 | tmp102_mC_to_reg(val)); | ||
135 | mutex_unlock(&tmp102->lock); | ||
136 | return status ? : count; | ||
137 | } | ||
138 | |||
139 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp102_show_temp, NULL , 0); | ||
140 | |||
141 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, | ||
142 | tmp102_set_temp, 1); | ||
143 | |||
144 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, | ||
145 | tmp102_set_temp, 2); | ||
146 | |||
147 | static struct attribute *tmp102_attributes[] = { | ||
148 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
149 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
150 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
151 | NULL | ||
152 | }; | ||
153 | |||
154 | static const struct attribute_group tmp102_attr_group = { | ||
155 | .attrs = tmp102_attributes, | ||
156 | }; | ||
157 | |||
158 | #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) | ||
159 | #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) | ||
160 | |||
161 | static int __devinit tmp102_probe(struct i2c_client *client, | ||
162 | const struct i2c_device_id *id) | ||
163 | { | ||
164 | struct tmp102 *tmp102; | ||
165 | int status; | ||
166 | |||
167 | if (!i2c_check_functionality(client->adapter, | ||
168 | I2C_FUNC_SMBUS_WORD_DATA)) { | ||
169 | dev_err(&client->dev, "adapter doesnt support SMBus word " | ||
170 | "transactions\n"); | ||
171 | return -ENODEV; | ||
172 | } | ||
173 | |||
174 | tmp102 = kzalloc(sizeof(*tmp102), GFP_KERNEL); | ||
175 | if (!tmp102) { | ||
176 | dev_dbg(&client->dev, "kzalloc failed\n"); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | i2c_set_clientdata(client, tmp102); | ||
180 | |||
181 | status = tmp102_read_reg(client, TMP102_CONF_REG); | ||
182 | if (status < 0) { | ||
183 | dev_err(&client->dev, "error reading config register\n"); | ||
184 | goto fail_free; | ||
185 | } | ||
186 | tmp102->config_orig = status; | ||
187 | status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); | ||
188 | if (status < 0) { | ||
189 | dev_err(&client->dev, "error writing config register\n"); | ||
190 | goto fail_restore_config; | ||
191 | } | ||
192 | status = tmp102_read_reg(client, TMP102_CONF_REG); | ||
193 | if (status < 0) { | ||
194 | dev_err(&client->dev, "error reading config register\n"); | ||
195 | goto fail_restore_config; | ||
196 | } | ||
197 | status &= ~TMP102_CONFIG_RD_ONLY; | ||
198 | if (status != TMP102_CONFIG) { | ||
199 | dev_err(&client->dev, "config settings did not stick\n"); | ||
200 | status = -ENODEV; | ||
201 | goto fail_restore_config; | ||
202 | } | ||
203 | tmp102->last_update = jiffies - HZ; | ||
204 | mutex_init(&tmp102->lock); | ||
205 | |||
206 | status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); | ||
207 | if (status) { | ||
208 | dev_dbg(&client->dev, "could not create sysfs files\n"); | ||
209 | goto fail_restore_config; | ||
210 | } | ||
211 | tmp102->hwmon_dev = hwmon_device_register(&client->dev); | ||
212 | if (IS_ERR(tmp102->hwmon_dev)) { | ||
213 | dev_dbg(&client->dev, "unable to register hwmon device\n"); | ||
214 | status = PTR_ERR(tmp102->hwmon_dev); | ||
215 | goto fail_remove_sysfs; | ||
216 | } | ||
217 | |||
218 | dev_info(&client->dev, "initialized\n"); | ||
219 | |||
220 | return 0; | ||
221 | |||
222 | fail_remove_sysfs: | ||
223 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | ||
224 | fail_restore_config: | ||
225 | tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); | ||
226 | fail_free: | ||
227 | i2c_set_clientdata(client, NULL); | ||
228 | kfree(tmp102); | ||
229 | |||
230 | return status; | ||
231 | } | ||
232 | |||
233 | static int __devexit tmp102_remove(struct i2c_client *client) | ||
234 | { | ||
235 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | ||
236 | |||
237 | hwmon_device_unregister(tmp102->hwmon_dev); | ||
238 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | ||
239 | |||
240 | /* Stop monitoring if device was stopped originally */ | ||
241 | if (tmp102->config_orig & TMP102_CONF_SD) { | ||
242 | int config; | ||
243 | |||
244 | config = tmp102_read_reg(client, TMP102_CONF_REG); | ||
245 | if (config >= 0) | ||
246 | tmp102_write_reg(client, TMP102_CONF_REG, | ||
247 | config | TMP102_CONF_SD); | ||
248 | } | ||
249 | |||
250 | i2c_set_clientdata(client, NULL); | ||
251 | kfree(tmp102); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | #ifdef CONFIG_PM | ||
257 | static int tmp102_suspend(struct device *dev) | ||
258 | { | ||
259 | struct i2c_client *client = to_i2c_client(dev); | ||
260 | int config; | ||
261 | |||
262 | config = tmp102_read_reg(client, TMP102_CONF_REG); | ||
263 | if (config < 0) | ||
264 | return config; | ||
265 | |||
266 | config |= TMP102_CONF_SD; | ||
267 | return tmp102_write_reg(client, TMP102_CONF_REG, config); | ||
268 | } | ||
269 | |||
270 | static int tmp102_resume(struct device *dev) | ||
271 | { | ||
272 | struct i2c_client *client = to_i2c_client(dev); | ||
273 | int config; | ||
274 | |||
275 | config = tmp102_read_reg(client, TMP102_CONF_REG); | ||
276 | if (config < 0) | ||
277 | return config; | ||
278 | |||
279 | config &= ~TMP102_CONF_SD; | ||
280 | return tmp102_write_reg(client, TMP102_CONF_REG, config); | ||
281 | } | ||
282 | |||
283 | static const struct dev_pm_ops tmp102_dev_pm_ops = { | ||
284 | .suspend = tmp102_suspend, | ||
285 | .resume = tmp102_resume, | ||
286 | }; | ||
287 | |||
288 | #define TMP102_DEV_PM_OPS (&tmp102_dev_pm_ops) | ||
289 | #else | ||
290 | #define TMP102_DEV_PM_OPS NULL | ||
291 | #endif /* CONFIG_PM */ | ||
292 | |||
293 | static const struct i2c_device_id tmp102_id[] = { | ||
294 | { "tmp102", 0 }, | ||
295 | { } | ||
296 | }; | ||
297 | MODULE_DEVICE_TABLE(i2c, tmp102_id); | ||
298 | |||
299 | static struct i2c_driver tmp102_driver = { | ||
300 | .driver.name = DRIVER_NAME, | ||
301 | .driver.pm = TMP102_DEV_PM_OPS, | ||
302 | .probe = tmp102_probe, | ||
303 | .remove = __devexit_p(tmp102_remove), | ||
304 | .id_table = tmp102_id, | ||
305 | }; | ||
306 | |||
307 | static int __init tmp102_init(void) | ||
308 | { | ||
309 | return i2c_add_driver(&tmp102_driver); | ||
310 | } | ||
311 | module_init(tmp102_init); | ||
312 | |||
313 | static void __exit tmp102_exit(void) | ||
314 | { | ||
315 | i2c_del_driver(&tmp102_driver); | ||
316 | } | ||
317 | module_exit(tmp102_exit); | ||
318 | |||
319 | MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); | ||
320 | MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); | ||
321 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index d14a1af9f550..ad8d535235c5 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c | |||
@@ -92,17 +92,6 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; | |||
92 | #define TMP411_DEVICE_ID 0x12 | 92 | #define TMP411_DEVICE_ID 0x12 |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * Functions declarations | ||
96 | */ | ||
97 | |||
98 | static int tmp401_probe(struct i2c_client *client, | ||
99 | const struct i2c_device_id *id); | ||
100 | static int tmp401_detect(struct i2c_client *client, | ||
101 | struct i2c_board_info *info); | ||
102 | static int tmp401_remove(struct i2c_client *client); | ||
103 | static struct tmp401_data *tmp401_update_device(struct device *dev); | ||
104 | |||
105 | /* | ||
106 | * Driver data (common to all clients) | 95 | * Driver data (common to all clients) |
107 | */ | 96 | */ |
108 | 97 | ||
@@ -113,18 +102,6 @@ static const struct i2c_device_id tmp401_id[] = { | |||
113 | }; | 102 | }; |
114 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | 103 | MODULE_DEVICE_TABLE(i2c, tmp401_id); |
115 | 104 | ||
116 | static struct i2c_driver tmp401_driver = { | ||
117 | .class = I2C_CLASS_HWMON, | ||
118 | .driver = { | ||
119 | .name = "tmp401", | ||
120 | }, | ||
121 | .probe = tmp401_probe, | ||
122 | .remove = tmp401_remove, | ||
123 | .id_table = tmp401_id, | ||
124 | .detect = tmp401_detect, | ||
125 | .address_list = normal_i2c, | ||
126 | }; | ||
127 | |||
128 | /* | 105 | /* |
129 | * Client data (each client gets its own) | 106 | * Client data (each client gets its own) |
130 | */ | 107 | */ |
@@ -194,6 +171,71 @@ static u8 tmp401_crit_temp_to_register(long temp, u8 config) | |||
194 | return (temp + 500) / 1000; | 171 | return (temp + 500) / 1000; |
195 | } | 172 | } |
196 | 173 | ||
174 | static struct tmp401_data *tmp401_update_device_reg16( | ||
175 | struct i2c_client *client, struct tmp401_data *data) | ||
176 | { | ||
177 | int i; | ||
178 | |||
179 | for (i = 0; i < 2; i++) { | ||
180 | /* | ||
181 | * High byte must be read first immediately followed | ||
182 | * by the low byte | ||
183 | */ | ||
184 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
185 | TMP401_TEMP_MSB[i]) << 8; | ||
186 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
187 | TMP401_TEMP_LSB[i]); | ||
188 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
189 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
190 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
191 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
192 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
193 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
194 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
195 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
196 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
197 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
198 | |||
199 | if (data->kind == tmp411) { | ||
200 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
201 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
202 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
203 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
204 | |||
205 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
206 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
207 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
208 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
209 | } | ||
210 | } | ||
211 | return data; | ||
212 | } | ||
213 | |||
214 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
215 | { | ||
216 | struct i2c_client *client = to_i2c_client(dev); | ||
217 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
218 | |||
219 | mutex_lock(&data->update_lock); | ||
220 | |||
221 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
222 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
223 | data->config = i2c_smbus_read_byte_data(client, | ||
224 | TMP401_CONFIG_READ); | ||
225 | tmp401_update_device_reg16(client, data); | ||
226 | |||
227 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
228 | TMP401_TEMP_CRIT_HYST); | ||
229 | |||
230 | data->last_updated = jiffies; | ||
231 | data->valid = 1; | ||
232 | } | ||
233 | |||
234 | mutex_unlock(&data->update_lock); | ||
235 | |||
236 | return data; | ||
237 | } | ||
238 | |||
197 | static ssize_t show_temp_value(struct device *dev, | 239 | static ssize_t show_temp_value(struct device *dev, |
198 | struct device_attribute *devattr, char *buf) | 240 | struct device_attribute *devattr, char *buf) |
199 | { | 241 | { |
@@ -420,30 +462,36 @@ static ssize_t reset_temp_history(struct device *dev, | |||
420 | } | 462 | } |
421 | 463 | ||
422 | static struct sensor_device_attribute tmp401_attr[] = { | 464 | static struct sensor_device_attribute tmp401_attr[] = { |
423 | SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), | 465 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0), |
424 | SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0), | 466 | SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, |
425 | SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0), | 467 | store_temp_min, 0), |
426 | SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0), | 468 | SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, |
427 | SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst, | 469 | store_temp_max, 0), |
470 | SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, | ||
471 | store_temp_crit, 0), | ||
472 | SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_crit_hyst, | ||
428 | store_temp_crit_hyst, 0), | 473 | store_temp_crit_hyst, 0), |
429 | SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL, | 474 | SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL, |
430 | TMP401_STATUS_LOCAL_LOW), | 475 | TMP401_STATUS_LOCAL_LOW), |
431 | SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL, | 476 | SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL, |
432 | TMP401_STATUS_LOCAL_HIGH), | 477 | TMP401_STATUS_LOCAL_HIGH), |
433 | SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL, | 478 | SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL, |
434 | TMP401_STATUS_LOCAL_CRIT), | 479 | TMP401_STATUS_LOCAL_CRIT), |
435 | SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1), | 480 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1), |
436 | SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1), | 481 | SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, |
437 | SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1), | 482 | store_temp_min, 1), |
438 | SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1), | 483 | SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, |
439 | SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1), | 484 | store_temp_max, 1), |
440 | SENSOR_ATTR(temp2_fault, 0444, show_status, NULL, | 485 | SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, |
486 | store_temp_crit, 1), | ||
487 | SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), | ||
488 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_status, NULL, | ||
441 | TMP401_STATUS_REMOTE_OPEN), | 489 | TMP401_STATUS_REMOTE_OPEN), |
442 | SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL, | 490 | SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL, |
443 | TMP401_STATUS_REMOTE_LOW), | 491 | TMP401_STATUS_REMOTE_LOW), |
444 | SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL, | 492 | SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL, |
445 | TMP401_STATUS_REMOTE_HIGH), | 493 | TMP401_STATUS_REMOTE_HIGH), |
446 | SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL, | 494 | SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL, |
447 | TMP401_STATUS_REMOTE_CRIT), | 495 | TMP401_STATUS_REMOTE_CRIT), |
448 | }; | 496 | }; |
449 | 497 | ||
@@ -455,11 +503,11 @@ static struct sensor_device_attribute tmp401_attr[] = { | |||
455 | * and remote channels. | 503 | * and remote channels. |
456 | */ | 504 | */ |
457 | static struct sensor_device_attribute tmp411_attr[] = { | 505 | static struct sensor_device_attribute tmp411_attr[] = { |
458 | SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0), | 506 | SENSOR_ATTR(temp1_highest, S_IRUGO, show_temp_highest, NULL, 0), |
459 | SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0), | 507 | SENSOR_ATTR(temp1_lowest, S_IRUGO, show_temp_lowest, NULL, 0), |
460 | SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1), | 508 | SENSOR_ATTR(temp2_highest, S_IRUGO, show_temp_highest, NULL, 1), |
461 | SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1), | 509 | SENSOR_ATTR(temp2_lowest, S_IRUGO, show_temp_lowest, NULL, 1), |
462 | SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0), | 510 | SENSOR_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, 0), |
463 | }; | 511 | }; |
464 | 512 | ||
465 | /* | 513 | /* |
@@ -529,6 +577,27 @@ static int tmp401_detect(struct i2c_client *client, | |||
529 | return 0; | 577 | return 0; |
530 | } | 578 | } |
531 | 579 | ||
580 | static int tmp401_remove(struct i2c_client *client) | ||
581 | { | ||
582 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
583 | int i; | ||
584 | |||
585 | if (data->hwmon_dev) | ||
586 | hwmon_device_unregister(data->hwmon_dev); | ||
587 | |||
588 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | ||
589 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | ||
590 | |||
591 | if (data->kind == tmp411) { | ||
592 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
593 | device_remove_file(&client->dev, | ||
594 | &tmp411_attr[i].dev_attr); | ||
595 | } | ||
596 | |||
597 | kfree(data); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
532 | static int tmp401_probe(struct i2c_client *client, | 601 | static int tmp401_probe(struct i2c_client *client, |
533 | const struct i2c_device_id *id) | 602 | const struct i2c_device_id *id) |
534 | { | 603 | { |
@@ -581,91 +650,17 @@ exit_remove: | |||
581 | return err; | 650 | return err; |
582 | } | 651 | } |
583 | 652 | ||
584 | static int tmp401_remove(struct i2c_client *client) | 653 | static struct i2c_driver tmp401_driver = { |
585 | { | 654 | .class = I2C_CLASS_HWMON, |
586 | struct tmp401_data *data = i2c_get_clientdata(client); | 655 | .driver = { |
587 | int i; | 656 | .name = "tmp401", |
588 | 657 | }, | |
589 | if (data->hwmon_dev) | 658 | .probe = tmp401_probe, |
590 | hwmon_device_unregister(data->hwmon_dev); | 659 | .remove = tmp401_remove, |
591 | 660 | .id_table = tmp401_id, | |
592 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | 661 | .detect = tmp401_detect, |
593 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | 662 | .address_list = normal_i2c, |
594 | 663 | }; | |
595 | if (data->kind == tmp411) { | ||
596 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
597 | device_remove_file(&client->dev, | ||
598 | &tmp411_attr[i].dev_attr); | ||
599 | } | ||
600 | |||
601 | kfree(data); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static struct tmp401_data *tmp401_update_device_reg16( | ||
606 | struct i2c_client *client, struct tmp401_data *data) | ||
607 | { | ||
608 | int i; | ||
609 | |||
610 | for (i = 0; i < 2; i++) { | ||
611 | /* | ||
612 | * High byte must be read first immediately followed | ||
613 | * by the low byte | ||
614 | */ | ||
615 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
616 | TMP401_TEMP_MSB[i]) << 8; | ||
617 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
618 | TMP401_TEMP_LSB[i]); | ||
619 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
620 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
621 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
622 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
623 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
624 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
625 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
626 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
627 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
628 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
629 | |||
630 | if (data->kind == tmp411) { | ||
631 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
632 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
633 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
634 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
635 | |||
636 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
637 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
638 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
639 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
640 | } | ||
641 | } | ||
642 | return data; | ||
643 | } | ||
644 | |||
645 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
646 | { | ||
647 | struct i2c_client *client = to_i2c_client(dev); | ||
648 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
649 | |||
650 | mutex_lock(&data->update_lock); | ||
651 | |||
652 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
653 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
654 | data->config = i2c_smbus_read_byte_data(client, | ||
655 | TMP401_CONFIG_READ); | ||
656 | tmp401_update_device_reg16(client, data); | ||
657 | |||
658 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
659 | TMP401_TEMP_CRIT_HYST); | ||
660 | |||
661 | data->last_updated = jiffies; | ||
662 | data->valid = 1; | ||
663 | } | ||
664 | |||
665 | mutex_unlock(&data->update_lock); | ||
666 | |||
667 | return data; | ||
668 | } | ||
669 | 664 | ||
670 | static int __init tmp401_init(void) | 665 | static int __init tmp401_init(void) |
671 | { | 666 | { |