diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-16 21:50:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-16 21:50:49 -0400 |
commit | fdb8a291227338fe54a2a790dae457726e5c237b (patch) | |
tree | 736649a170086db26d2310cb842819bb7e854e98 | |
parent | 1cc3880a3c99f1be73f9024bd9db6248ffdcec70 (diff) | |
parent | d6a442df63b2f0043c0b4fc05504ac4ded96ae80 (diff) |
Merge tag 'hwmon-for-linus-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon updates from Guenter Roeck:
- major rework of it87 driver: cleanup, added support for additional
attributes, added support for two chips in the system, added support
for IT8728E
- fam17h_power driver now reports accumulated power consumption
- new driver for MAX31722/MAX31723 temperature sensors
- minor fixes to sch5636 and ads7828 drivers
* tag 'hwmon-for-linus-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (35 commits)
hwmon: (sch5636) trivial fix of spelling mistake on revision
hwmon: (it87) Add support for IT8628E
hwmon: (it87) Fix pwm_temp_map for system with 6 pwm channels
hwmon: (it87) Support automatic pwm control on newer chips
hwmon: (it87) Enhance validation for fan4 and fan5
hwmon: (it87) Support disabling fan control for all pwm control and chips
hwmon: (it87) Formatting cleanup
hwmon: (it87) Use defines for array sizes and sensor counts
hwmon: (it87) Use BIT macro
hwmon: (it87) Add support for VIN7 to VIN10 on IT8620E
hwmon: (it87) Simplify reading voltage registers
hwmon: (it87) Support up to 6 temperature sensors on IT8620E
hwmon: (it87) Convert to use new hwmon API
hwmon: (it87) Use single group and is_visible for miscellaneous attributes
hwmon: (it87) Use is_visible for pwm attributes
hwmon: (it87) Use is_visible for fan attributes
hwmon: (it87) Use is_visible for temperature sensors
hwmon: (it87) Use is_visible for voltage sensors
hwmon: (it87) Rearrange code to avoid forward declarations
hwmon: (it87) Add support for second Super-IO chip
...
-rw-r--r-- | Documentation/devicetree/bindings/hwmon/ltc2978.txt | 1 | ||||
-rw-r--r-- | Documentation/hwmon/fam15h_power | 65 | ||||
-rw-r--r-- | Documentation/hwmon/it87 | 15 | ||||
-rw-r--r-- | Documentation/hwmon/max31722 | 34 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 15 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/ads7828.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/fam15h_power.c | 215 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 2261 | ||||
-rw-r--r-- | drivers/hwmon/max31722.c | 165 | ||||
-rw-r--r-- | drivers/hwmon/sch5636.c | 2 |
11 files changed, 1784 insertions, 1000 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/ltc2978.txt b/Documentation/devicetree/bindings/hwmon/ltc2978.txt index a7afbf60bb9c..bf2a47bbdc58 100644 --- a/Documentation/devicetree/bindings/hwmon/ltc2978.txt +++ b/Documentation/devicetree/bindings/hwmon/ltc2978.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | * "lltc,ltc3886" | 13 | * "lltc,ltc3886" |
14 | * "lltc,ltc3887" | 14 | * "lltc,ltc3887" |
15 | * "lltc,ltm2987" | 15 | * "lltc,ltm2987" |
16 | * "lltc,ltm4675" | ||
16 | * "lltc,ltm4676" | 17 | * "lltc,ltm4676" |
17 | - reg: I2C slave address | 18 | - reg: I2C slave address |
18 | 19 | ||
diff --git a/Documentation/hwmon/fam15h_power b/Documentation/hwmon/fam15h_power index e2b1b69eebea..fb594c281c46 100644 --- a/Documentation/hwmon/fam15h_power +++ b/Documentation/hwmon/fam15h_power | |||
@@ -10,14 +10,22 @@ Supported chips: | |||
10 | Datasheets: | 10 | Datasheets: |
11 | BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors | 11 | BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors |
12 | BIOS and Kernel Developer's Guide (BKDG) For AMD Family 16h Processors | 12 | BIOS and Kernel Developer's Guide (BKDG) For AMD Family 16h Processors |
13 | AMD64 Architecture Programmer's Manual Volume 2: System Programming | ||
13 | 14 | ||
14 | Author: Andreas Herrmann <herrmann.der.user@googlemail.com> | 15 | Author: Andreas Herrmann <herrmann.der.user@googlemail.com> |
15 | 16 | ||
16 | Description | 17 | Description |
17 | ----------- | 18 | ----------- |
18 | 19 | ||
20 | 1) Processor TDP (Thermal design power) | ||
21 | |||
22 | Given a fixed frequency and voltage, the power consumption of a | ||
23 | processor varies based on the workload being executed. Derated power | ||
24 | is the power consumed when running a specific application. Thermal | ||
25 | design power (TDP) is an example of derated power. | ||
26 | |||
19 | This driver permits reading of registers providing power information | 27 | This driver permits reading of registers providing power information |
20 | of AMD Family 15h and 16h processors. | 28 | of AMD Family 15h and 16h processors via TDP algorithm. |
21 | 29 | ||
22 | For AMD Family 15h and 16h processors the following power values can | 30 | For AMD Family 15h and 16h processors the following power values can |
23 | be calculated using different processor northbridge function | 31 | be calculated using different processor northbridge function |
@@ -37,3 +45,58 @@ This driver provides ProcessorPwrWatts and CurrPwrWatts: | |||
37 | On multi-node processors the calculated value is for the entire | 45 | On multi-node processors the calculated value is for the entire |
38 | package and not for a single node. Thus the driver creates sysfs | 46 | package and not for a single node. Thus the driver creates sysfs |
39 | attributes only for internal node0 of a multi-node processor. | 47 | attributes only for internal node0 of a multi-node processor. |
48 | |||
49 | 2) Accumulated Power Mechanism | ||
50 | |||
51 | This driver also introduces an algorithm that should be used to | ||
52 | calculate the average power consumed by a processor during a | ||
53 | measurement interval Tm. The feature of accumulated power mechanism is | ||
54 | indicated by CPUID Fn8000_0007_EDX[12]. | ||
55 | |||
56 | * Tsample: compute unit power accumulator sample period | ||
57 | * Tref: the PTSC counter period | ||
58 | * PTSC: performance timestamp counter | ||
59 | * N: the ratio of compute unit power accumulator sample period to the | ||
60 | PTSC period | ||
61 | * Jmax: max compute unit accumulated power which is indicated by | ||
62 | MaxCpuSwPwrAcc MSR C001007b | ||
63 | * Jx/Jy: compute unit accumulated power which is indicated by | ||
64 | CpuSwPwrAcc MSR C001007a | ||
65 | * Tx/Ty: the value of performance timestamp counter which is indicated | ||
66 | by CU_PTSC MSR C0010280 | ||
67 | * PwrCPUave: CPU average power | ||
68 | |||
69 | i. Determine the ratio of Tsample to Tref by executing CPUID Fn8000_0007. | ||
70 | N = value of CPUID Fn8000_0007_ECX[CpuPwrSampleTimeRatio[15:0]]. | ||
71 | |||
72 | ii. Read the full range of the cumulative energy value from the new | ||
73 | MSR MaxCpuSwPwrAcc. | ||
74 | Jmax = value returned. | ||
75 | iii. At time x, SW reads CpuSwPwrAcc MSR and samples the PTSC. | ||
76 | Jx = value read from CpuSwPwrAcc and Tx = value read from | ||
77 | PTSC. | ||
78 | |||
79 | iv. At time y, SW reads CpuSwPwrAcc MSR and samples the PTSC. | ||
80 | Jy = value read from CpuSwPwrAcc and Ty = value read from | ||
81 | PTSC. | ||
82 | |||
83 | v. Calculate the average power consumption for a compute unit over | ||
84 | time period (y-x). Unit of result is uWatt. | ||
85 | if (Jy < Jx) // Rollover has occurred | ||
86 | Jdelta = (Jy + Jmax) - Jx | ||
87 | else | ||
88 | Jdelta = Jy - Jx | ||
89 | PwrCPUave = N * Jdelta * 1000 / (Ty - Tx) | ||
90 | |||
91 | This driver provides PwrCPUave and interval(default is 10 millisecond | ||
92 | and maximum is 1 second): | ||
93 | * power1_average (PwrCPUave) | ||
94 | * power1_average_interval (Interval) | ||
95 | |||
96 | The power1_average_interval can be updated at /etc/sensors3.conf file | ||
97 | as below: | ||
98 | |||
99 | chip "fam15h_power-*" | ||
100 | set power1_average_interval 0.01 | ||
101 | |||
102 | Then save it with "sensors -s". | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 733296d65449..fff6f6bf55bc 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -9,6 +9,9 @@ Supported chips: | |||
9 | * IT8620E | 9 | * IT8620E |
10 | Prefix: 'it8620' | 10 | Prefix: 'it8620' |
11 | Addresses scanned: from Super I/O config space (8 I/O ports) | 11 | Addresses scanned: from Super I/O config space (8 I/O ports) |
12 | * IT8628E | ||
13 | Prefix: 'it8628' | ||
14 | Addresses scanned: from Super I/O config space (8 I/O ports) | ||
12 | Datasheet: Not publicly available | 15 | Datasheet: Not publicly available |
13 | * IT8705F | 16 | * IT8705F |
14 | Prefix: 'it87' | 17 | Prefix: 'it87' |
@@ -114,8 +117,8 @@ motherboard models. | |||
114 | Description | 117 | Description |
115 | ----------- | 118 | ----------- |
116 | 119 | ||
117 | This driver implements support for the IT8603E, IT8620E, IT8623E, IT8705F, | 120 | This driver implements support for the IT8603E, IT8620E, IT8623E, IT8628E, |
118 | IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, | 121 | IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, |
119 | IT8758E, IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, and | 122 | IT8758E, IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, and |
120 | SiS950 chips. | 123 | SiS950 chips. |
121 | 124 | ||
@@ -158,8 +161,8 @@ The IT8603E/IT8623E is a custom design, hardware monitoring part is similar to | |||
158 | IT8728F. It only supports 3 fans, 16-bit fan mode, and the full speed mode | 161 | IT8728F. It only supports 3 fans, 16-bit fan mode, and the full speed mode |
159 | of the fan is not supported (value 0 of pwmX_enable). | 162 | of the fan is not supported (value 0 of pwmX_enable). |
160 | 163 | ||
161 | The IT8620E is another custom design, hardware monitoring part is similar to | 164 | The IT8620E and IT8628E are custom designs, hardware monitoring part is similar |
162 | IT8728F. It only supports 16-bit fan mode. | 165 | to IT8728F. It only supports 16-bit fan mode. Both chips support up to 6 fans. |
163 | 166 | ||
164 | The IT8790E supports up to 3 fans. 16-bit fan mode is always enabled. | 167 | The IT8790E supports up to 3 fans. 16-bit fan mode is always enabled. |
165 | 168 | ||
@@ -187,8 +190,8 @@ of 0.016 volt. IT8603E, IT8721F/IT8758E and IT8728F can measure between 0 and | |||
187 | 2.8 volts with a resolution of 0.0109 volt. The battery voltage in8 does not | 190 | 2.8 volts with a resolution of 0.0109 volt. The battery voltage in8 does not |
188 | have limit registers. | 191 | have limit registers. |
189 | 192 | ||
190 | On the IT8603E, IT8721F/IT8758E, IT8732F, IT8781F, IT8782F, and IT8783E/F, some | 193 | On the IT8603E, IT8620E, IT8628E, IT8721F/IT8758E, IT8732F, IT8781F, IT8782F, |
191 | voltage inputs are internal and scaled inside the chip: | 194 | and IT8783E/F, some voltage inputs are internal and scaled inside the chip: |
192 | * in3 (optional) | 195 | * in3 (optional) |
193 | * in7 (optional for IT8781F, IT8782F, and IT8783E/F) | 196 | * in7 (optional for IT8781F, IT8782F, and IT8783E/F) |
194 | * in8 (always) | 197 | * in8 (always) |
diff --git a/Documentation/hwmon/max31722 b/Documentation/hwmon/max31722 new file mode 100644 index 000000000000..090da84538c8 --- /dev/null +++ b/Documentation/hwmon/max31722 | |||
@@ -0,0 +1,34 @@ | |||
1 | Kernel driver max31722 | ||
2 | ====================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Maxim Integrated MAX31722 | ||
6 | Prefix: 'max31722' | ||
7 | ACPI ID: MAX31722 | ||
8 | Addresses scanned: - | ||
9 | Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31722-MAX31723.pdf | ||
10 | * Maxim Integrated MAX31723 | ||
11 | Prefix: 'max31723' | ||
12 | ACPI ID: MAX31723 | ||
13 | Addresses scanned: - | ||
14 | Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31722-MAX31723.pdf | ||
15 | |||
16 | Author: Tiberiu Breana <tiberiu.a.breana@intel.com> | ||
17 | |||
18 | Description | ||
19 | ----------- | ||
20 | |||
21 | This driver adds support for the Maxim Integrated MAX31722/MAX31723 thermometers | ||
22 | and thermostats running over an SPI interface. | ||
23 | |||
24 | Usage Notes | ||
25 | ----------- | ||
26 | |||
27 | This driver uses ACPI to auto-detect devices. See ACPI IDs in the above section. | ||
28 | |||
29 | Sysfs entries | ||
30 | ------------- | ||
31 | |||
32 | The following attribute is supported: | ||
33 | |||
34 | temp1_input Measured temperature. Read-only. | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5c2d13a687aa..ff940075bb90 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -288,7 +288,7 @@ config SENSORS_K10TEMP | |||
288 | 288 | ||
289 | config SENSORS_FAM15H_POWER | 289 | config SENSORS_FAM15H_POWER |
290 | tristate "AMD Family 15h processor power" | 290 | tristate "AMD Family 15h processor power" |
291 | depends on X86 && PCI | 291 | depends on X86 && PCI && CPU_SUP_AMD |
292 | help | 292 | help |
293 | If you say yes here you get support for processor power | 293 | If you say yes here you get support for processor power |
294 | information of your AMD family 15h CPU. | 294 | information of your AMD family 15h CPU. |
@@ -621,7 +621,8 @@ config SENSORS_IT87 | |||
621 | If you say yes here you get support for ITE IT8705F, IT8712F, IT8716F, | 621 | If you say yes here you get support for ITE IT8705F, IT8712F, IT8716F, |
622 | IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, IT8758E, | 622 | IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, IT8758E, |
623 | IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, | 623 | IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, |
624 | IT8603E, IT8620E, and IT8623E sensor chips, and the SiS950 clone. | 624 | IT8603E, IT8620E, IT8623E, and IT8628E sensor chips, and the SiS950 |
625 | clone. | ||
625 | 626 | ||
626 | This driver can also be built as a module. If so, the module | 627 | This driver can also be built as a module. If so, the module |
627 | will be called it87. | 628 | will be called it87. |
@@ -821,6 +822,16 @@ config SENSORS_MAX197 | |||
821 | This driver can also be built as a module. If so, the module | 822 | This driver can also be built as a module. If so, the module |
822 | will be called max197. | 823 | will be called max197. |
823 | 824 | ||
825 | config SENSORS_MAX31722 | ||
826 | tristate "MAX31722 temperature sensor" | ||
827 | depends on SPI | ||
828 | help | ||
829 | Support for the Maxim Integrated MAX31722/MAX31723 digital | ||
830 | thermometers/thermostats operating over an SPI interface. | ||
831 | |||
832 | This driver can also be built as a module. If so, the module | ||
833 | will be called max31722. | ||
834 | |||
824 | config SENSORS_MAX6639 | 835 | config SENSORS_MAX6639 |
825 | tristate "Maxim MAX6639 sensor chip" | 836 | tristate "Maxim MAX6639 sensor chip" |
826 | depends on I2C | 837 | depends on I2C |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 58cc3acba7e7..2ef5b7c4c54f 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -112,6 +112,7 @@ obj-$(CONFIG_SENSORS_MAX16065) += max16065.o | |||
112 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 112 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
113 | obj-$(CONFIG_SENSORS_MAX1668) += max1668.o | 113 | obj-$(CONFIG_SENSORS_MAX1668) += max1668.o |
114 | obj-$(CONFIG_SENSORS_MAX197) += max197.o | 114 | obj-$(CONFIG_SENSORS_MAX197) += max197.o |
115 | obj-$(CONFIG_SENSORS_MAX31722) += max31722.o | ||
115 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o | 116 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o |
116 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o | 117 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o |
117 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 118 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 6c99ee7bafa3..ee396ff167d9 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c | |||
@@ -120,6 +120,7 @@ static int ads7828_probe(struct i2c_client *client, | |||
120 | unsigned int vref_mv = ADS7828_INT_VREF_MV; | 120 | unsigned int vref_mv = ADS7828_INT_VREF_MV; |
121 | bool diff_input = false; | 121 | bool diff_input = false; |
122 | bool ext_vref = false; | 122 | bool ext_vref = false; |
123 | unsigned int regval; | ||
123 | 124 | ||
124 | data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL); | 125 | data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL); |
125 | if (!data) | 126 | if (!data) |
@@ -154,6 +155,15 @@ static int ads7828_probe(struct i2c_client *client, | |||
154 | if (!diff_input) | 155 | if (!diff_input) |
155 | data->cmd_byte |= ADS7828_CMD_SD_SE; | 156 | data->cmd_byte |= ADS7828_CMD_SD_SE; |
156 | 157 | ||
158 | /* | ||
159 | * Datasheet specifies internal reference voltage is disabled by | ||
160 | * default. The internal reference voltage needs to be enabled and | ||
161 | * voltage needs to settle before getting valid ADC data. So perform a | ||
162 | * dummy read to enable the internal reference voltage. | ||
163 | */ | ||
164 | if (!ext_vref) | ||
165 | regmap_read(data->regmap, data->cmd_byte, ®val); | ||
166 | |||
157 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 167 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
158 | data, | 168 | data, |
159 | ads7828_groups); | 169 | ads7828_groups); |
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 4f695d8fcafa..eb97a9241d17 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fam15h_power.c - AMD Family 15h processor power monitoring | 2 | * fam15h_power.c - AMD Family 15h processor power monitoring |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Advanced Micro Devices, Inc. | 4 | * Copyright (c) 2011-2016 Advanced Micro Devices, Inc. |
5 | * Author: Andreas Herrmann <herrmann.der.user@googlemail.com> | 5 | * Author: Andreas Herrmann <herrmann.der.user@googlemail.com> |
6 | * | 6 | * |
7 | * | 7 | * |
@@ -25,6 +25,10 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
28 | #include <linux/cpu.h> | ||
29 | #include <linux/cpumask.h> | ||
30 | #include <linux/time.h> | ||
31 | #include <linux/sched.h> | ||
28 | #include <asm/processor.h> | 32 | #include <asm/processor.h> |
29 | #include <asm/msr.h> | 33 | #include <asm/msr.h> |
30 | 34 | ||
@@ -44,8 +48,14 @@ MODULE_LICENSE("GPL"); | |||
44 | 48 | ||
45 | #define FAM15H_MIN_NUM_ATTRS 2 | 49 | #define FAM15H_MIN_NUM_ATTRS 2 |
46 | #define FAM15H_NUM_GROUPS 2 | 50 | #define FAM15H_NUM_GROUPS 2 |
51 | #define MAX_CUS 8 | ||
47 | 52 | ||
53 | /* set maximum interval as 1 second */ | ||
54 | #define MAX_INTERVAL 1000 | ||
55 | |||
56 | #define MSR_F15H_CU_PWR_ACCUMULATOR 0xc001007a | ||
48 | #define MSR_F15H_CU_MAX_PWR_ACCUMULATOR 0xc001007b | 57 | #define MSR_F15H_CU_MAX_PWR_ACCUMULATOR 0xc001007b |
58 | #define MSR_F15H_PTSC 0xc0010280 | ||
49 | 59 | ||
50 | #define PCI_DEVICE_ID_AMD_15H_M70H_NB_F4 0x15b4 | 60 | #define PCI_DEVICE_ID_AMD_15H_M70H_NB_F4 0x15b4 |
51 | 61 | ||
@@ -59,8 +69,20 @@ struct fam15h_power_data { | |||
59 | struct attribute_group group; | 69 | struct attribute_group group; |
60 | /* maximum accumulated power of a compute unit */ | 70 | /* maximum accumulated power of a compute unit */ |
61 | u64 max_cu_acc_power; | 71 | u64 max_cu_acc_power; |
72 | /* accumulated power of the compute units */ | ||
73 | u64 cu_acc_power[MAX_CUS]; | ||
74 | /* performance timestamp counter */ | ||
75 | u64 cpu_sw_pwr_ptsc[MAX_CUS]; | ||
76 | /* online/offline status of current compute unit */ | ||
77 | int cu_on[MAX_CUS]; | ||
78 | unsigned long power_period; | ||
62 | }; | 79 | }; |
63 | 80 | ||
81 | static bool is_carrizo_or_later(void) | ||
82 | { | ||
83 | return boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model >= 0x60; | ||
84 | } | ||
85 | |||
64 | static ssize_t show_power(struct device *dev, | 86 | static ssize_t show_power(struct device *dev, |
65 | struct device_attribute *attr, char *buf) | 87 | struct device_attribute *attr, char *buf) |
66 | { | 88 | { |
@@ -77,7 +99,7 @@ static ssize_t show_power(struct device *dev, | |||
77 | * On Carrizo and later platforms, TdpRunAvgAccCap bit field | 99 | * On Carrizo and later platforms, TdpRunAvgAccCap bit field |
78 | * is extended to 4:31 from 4:25. | 100 | * is extended to 4:31 from 4:25. |
79 | */ | 101 | */ |
80 | if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model >= 0x60) { | 102 | if (is_carrizo_or_later()) { |
81 | running_avg_capture = val >> 4; | 103 | running_avg_capture = val >> 4; |
82 | running_avg_capture = sign_extend32(running_avg_capture, 27); | 104 | running_avg_capture = sign_extend32(running_avg_capture, 27); |
83 | } else { | 105 | } else { |
@@ -94,7 +116,7 @@ static ssize_t show_power(struct device *dev, | |||
94 | * On Carrizo and later platforms, ApmTdpLimit bit field | 116 | * On Carrizo and later platforms, ApmTdpLimit bit field |
95 | * is extended to 16:31 from 16:28. | 117 | * is extended to 16:31 from 16:28. |
96 | */ | 118 | */ |
97 | if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model >= 0x60) | 119 | if (is_carrizo_or_later()) |
98 | tdp_limit = val >> 16; | 120 | tdp_limit = val >> 16; |
99 | else | 121 | else |
100 | tdp_limit = (val >> 16) & 0x1fff; | 122 | tdp_limit = (val >> 16) & 0x1fff; |
@@ -125,6 +147,167 @@ static ssize_t show_power_crit(struct device *dev, | |||
125 | } | 147 | } |
126 | static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL); | 148 | static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL); |
127 | 149 | ||
150 | static void do_read_registers_on_cu(void *_data) | ||
151 | { | ||
152 | struct fam15h_power_data *data = _data; | ||
153 | int cpu, cu; | ||
154 | |||
155 | cpu = smp_processor_id(); | ||
156 | |||
157 | /* | ||
158 | * With the new x86 topology modelling, cpu core id actually | ||
159 | * is compute unit id. | ||
160 | */ | ||
161 | cu = cpu_data(cpu).cpu_core_id; | ||
162 | |||
163 | rdmsrl_safe(MSR_F15H_CU_PWR_ACCUMULATOR, &data->cu_acc_power[cu]); | ||
164 | rdmsrl_safe(MSR_F15H_PTSC, &data->cpu_sw_pwr_ptsc[cu]); | ||
165 | |||
166 | data->cu_on[cu] = 1; | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * This function is only able to be called when CPUID | ||
171 | * Fn8000_0007:EDX[12] is set. | ||
172 | */ | ||
173 | static int read_registers(struct fam15h_power_data *data) | ||
174 | { | ||
175 | int this_cpu, ret, cpu; | ||
176 | int core, this_core; | ||
177 | cpumask_var_t mask; | ||
178 | |||
179 | ret = zalloc_cpumask_var(&mask, GFP_KERNEL); | ||
180 | if (!ret) | ||
181 | return -ENOMEM; | ||
182 | |||
183 | memset(data->cu_on, 0, sizeof(int) * MAX_CUS); | ||
184 | |||
185 | get_online_cpus(); | ||
186 | this_cpu = smp_processor_id(); | ||
187 | |||
188 | /* | ||
189 | * Choose the first online core of each compute unit, and then | ||
190 | * read their MSR value of power and ptsc in a single IPI, | ||
191 | * because the MSR value of CPU core represent the compute | ||
192 | * unit's. | ||
193 | */ | ||
194 | core = -1; | ||
195 | |||
196 | for_each_online_cpu(cpu) { | ||
197 | this_core = topology_core_id(cpu); | ||
198 | |||
199 | if (this_core == core) | ||
200 | continue; | ||
201 | |||
202 | core = this_core; | ||
203 | |||
204 | /* get any CPU on this compute unit */ | ||
205 | cpumask_set_cpu(cpumask_any(topology_sibling_cpumask(cpu)), mask); | ||
206 | } | ||
207 | |||
208 | if (cpumask_test_cpu(this_cpu, mask)) | ||
209 | do_read_registers_on_cu(data); | ||
210 | |||
211 | smp_call_function_many(mask, do_read_registers_on_cu, data, true); | ||
212 | put_online_cpus(); | ||
213 | |||
214 | free_cpumask_var(mask); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static ssize_t acc_show_power(struct device *dev, | ||
220 | struct device_attribute *attr, | ||
221 | char *buf) | ||
222 | { | ||
223 | struct fam15h_power_data *data = dev_get_drvdata(dev); | ||
224 | u64 prev_cu_acc_power[MAX_CUS], prev_ptsc[MAX_CUS], | ||
225 | jdelta[MAX_CUS]; | ||
226 | u64 tdelta, avg_acc; | ||
227 | int cu, cu_num, ret; | ||
228 | signed long leftover; | ||
229 | |||
230 | /* | ||
231 | * With the new x86 topology modelling, x86_max_cores is the | ||
232 | * compute unit number. | ||
233 | */ | ||
234 | cu_num = boot_cpu_data.x86_max_cores; | ||
235 | |||
236 | ret = read_registers(data); | ||
237 | if (ret) | ||
238 | return 0; | ||
239 | |||
240 | for (cu = 0; cu < cu_num; cu++) { | ||
241 | prev_cu_acc_power[cu] = data->cu_acc_power[cu]; | ||
242 | prev_ptsc[cu] = data->cpu_sw_pwr_ptsc[cu]; | ||
243 | } | ||
244 | |||
245 | leftover = schedule_timeout_interruptible(msecs_to_jiffies(data->power_period)); | ||
246 | if (leftover) | ||
247 | return 0; | ||
248 | |||
249 | ret = read_registers(data); | ||
250 | if (ret) | ||
251 | return 0; | ||
252 | |||
253 | for (cu = 0, avg_acc = 0; cu < cu_num; cu++) { | ||
254 | /* check if current compute unit is online */ | ||
255 | if (data->cu_on[cu] == 0) | ||
256 | continue; | ||
257 | |||
258 | if (data->cu_acc_power[cu] < prev_cu_acc_power[cu]) { | ||
259 | jdelta[cu] = data->max_cu_acc_power + data->cu_acc_power[cu]; | ||
260 | jdelta[cu] -= prev_cu_acc_power[cu]; | ||
261 | } else { | ||
262 | jdelta[cu] = data->cu_acc_power[cu] - prev_cu_acc_power[cu]; | ||
263 | } | ||
264 | tdelta = data->cpu_sw_pwr_ptsc[cu] - prev_ptsc[cu]; | ||
265 | jdelta[cu] *= data->cpu_pwr_sample_ratio * 1000; | ||
266 | do_div(jdelta[cu], tdelta); | ||
267 | |||
268 | /* the unit is microWatt */ | ||
269 | avg_acc += jdelta[cu]; | ||
270 | } | ||
271 | |||
272 | return sprintf(buf, "%llu\n", (unsigned long long)avg_acc); | ||
273 | } | ||
274 | static DEVICE_ATTR(power1_average, S_IRUGO, acc_show_power, NULL); | ||
275 | |||
276 | static ssize_t acc_show_power_period(struct device *dev, | ||
277 | struct device_attribute *attr, | ||
278 | char *buf) | ||
279 | { | ||
280 | struct fam15h_power_data *data = dev_get_drvdata(dev); | ||
281 | |||
282 | return sprintf(buf, "%lu\n", data->power_period); | ||
283 | } | ||
284 | |||
285 | static ssize_t acc_set_power_period(struct device *dev, | ||
286 | struct device_attribute *attr, | ||
287 | const char *buf, size_t count) | ||
288 | { | ||
289 | struct fam15h_power_data *data = dev_get_drvdata(dev); | ||
290 | unsigned long temp; | ||
291 | int ret; | ||
292 | |||
293 | ret = kstrtoul(buf, 10, &temp); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | if (temp > MAX_INTERVAL) | ||
298 | return -EINVAL; | ||
299 | |||
300 | /* the interval value should be greater than 0 */ | ||
301 | if (temp <= 0) | ||
302 | return -EINVAL; | ||
303 | |||
304 | data->power_period = temp; | ||
305 | |||
306 | return count; | ||
307 | } | ||
308 | static DEVICE_ATTR(power1_average_interval, S_IRUGO | S_IWUSR, | ||
309 | acc_show_power_period, acc_set_power_period); | ||
310 | |||
128 | static int fam15h_power_init_attrs(struct pci_dev *pdev, | 311 | static int fam15h_power_init_attrs(struct pci_dev *pdev, |
129 | struct fam15h_power_data *data) | 312 | struct fam15h_power_data *data) |
130 | { | 313 | { |
@@ -137,6 +320,10 @@ static int fam15h_power_init_attrs(struct pci_dev *pdev, | |||
137 | (c->x86_model >= 0x60 && c->x86_model <= 0x7f))) | 320 | (c->x86_model >= 0x60 && c->x86_model <= 0x7f))) |
138 | n += 1; | 321 | n += 1; |
139 | 322 | ||
323 | /* check if processor supports accumulated power */ | ||
324 | if (boot_cpu_has(X86_FEATURE_ACC_POWER)) | ||
325 | n += 2; | ||
326 | |||
140 | fam15h_power_attrs = devm_kcalloc(&pdev->dev, n, | 327 | fam15h_power_attrs = devm_kcalloc(&pdev->dev, n, |
141 | sizeof(*fam15h_power_attrs), | 328 | sizeof(*fam15h_power_attrs), |
142 | GFP_KERNEL); | 329 | GFP_KERNEL); |
@@ -151,6 +338,11 @@ static int fam15h_power_init_attrs(struct pci_dev *pdev, | |||
151 | (c->x86_model >= 0x60 && c->x86_model <= 0x7f))) | 338 | (c->x86_model >= 0x60 && c->x86_model <= 0x7f))) |
152 | fam15h_power_attrs[n++] = &dev_attr_power1_input.attr; | 339 | fam15h_power_attrs[n++] = &dev_attr_power1_input.attr; |
153 | 340 | ||
341 | if (boot_cpu_has(X86_FEATURE_ACC_POWER)) { | ||
342 | fam15h_power_attrs[n++] = &dev_attr_power1_average.attr; | ||
343 | fam15h_power_attrs[n++] = &dev_attr_power1_average_interval.attr; | ||
344 | } | ||
345 | |||
154 | data->group.attrs = fam15h_power_attrs; | 346 | data->group.attrs = fam15h_power_attrs; |
155 | 347 | ||
156 | return 0; | 348 | return 0; |
@@ -216,7 +408,7 @@ static int fam15h_power_resume(struct pci_dev *pdev) | |||
216 | static int fam15h_power_init_data(struct pci_dev *f4, | 408 | static int fam15h_power_init_data(struct pci_dev *f4, |
217 | struct fam15h_power_data *data) | 409 | struct fam15h_power_data *data) |
218 | { | 410 | { |
219 | u32 val, eax, ebx, ecx, edx; | 411 | u32 val; |
220 | u64 tmp; | 412 | u64 tmp; |
221 | int ret; | 413 | int ret; |
222 | 414 | ||
@@ -243,10 +435,9 @@ static int fam15h_power_init_data(struct pci_dev *f4, | |||
243 | if (ret) | 435 | if (ret) |
244 | return ret; | 436 | return ret; |
245 | 437 | ||
246 | cpuid(0x80000007, &eax, &ebx, &ecx, &edx); | ||
247 | 438 | ||
248 | /* CPUID Fn8000_0007:EDX[12] indicates to support accumulated power */ | 439 | /* CPUID Fn8000_0007:EDX[12] indicates to support accumulated power */ |
249 | if (!(edx & BIT(12))) | 440 | if (!boot_cpu_has(X86_FEATURE_ACC_POWER)) |
250 | return 0; | 441 | return 0; |
251 | 442 | ||
252 | /* | 443 | /* |
@@ -254,7 +445,7 @@ static int fam15h_power_init_data(struct pci_dev *f4, | |||
254 | * sample period to the PTSC counter period by executing CPUID | 445 | * sample period to the PTSC counter period by executing CPUID |
255 | * Fn8000_0007:ECX | 446 | * Fn8000_0007:ECX |
256 | */ | 447 | */ |
257 | data->cpu_pwr_sample_ratio = ecx; | 448 | data->cpu_pwr_sample_ratio = cpuid_ecx(0x80000007); |
258 | 449 | ||
259 | if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &tmp)) { | 450 | if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &tmp)) { |
260 | pr_err("Failed to read max compute unit power accumulator MSR\n"); | 451 | pr_err("Failed to read max compute unit power accumulator MSR\n"); |
@@ -263,7 +454,15 @@ static int fam15h_power_init_data(struct pci_dev *f4, | |||
263 | 454 | ||
264 | data->max_cu_acc_power = tmp; | 455 | data->max_cu_acc_power = tmp; |
265 | 456 | ||
266 | return 0; | 457 | /* |
458 | * Milliseconds are a reasonable interval for the measurement. | ||
459 | * But it shouldn't set too long here, because several seconds | ||
460 | * would cause the read function to hang. So set default | ||
461 | * interval as 10 ms. | ||
462 | */ | ||
463 | data->power_period = 10; | ||
464 | |||
465 | return read_registers(data); | ||
267 | } | 466 | } |
268 | 467 | ||
269 | static int fam15h_power_probe(struct pci_dev *pdev, | 468 | static int fam15h_power_probe(struct pci_dev *pdev, |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 1896e26df634..730d84028260 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * Supports: IT8603E Super I/O chip w/LPC interface | 13 | * Supports: IT8603E Super I/O chip w/LPC interface |
14 | * IT8620E Super I/O chip w/LPC interface | 14 | * IT8620E Super I/O chip w/LPC interface |
15 | * IT8623E Super I/O chip w/LPC interface | 15 | * IT8623E Super I/O chip w/LPC interface |
16 | * IT8628E Super I/O chip w/LPC interface | ||
16 | * IT8705F Super I/O chip w/LPC interface | 17 | * IT8705F Super I/O chip w/LPC interface |
17 | * IT8712F Super I/O chip w/LPC interface | 18 | * IT8712F Super I/O chip w/LPC interface |
18 | * IT8716F Super I/O chip w/LPC interface | 19 | * IT8716F Super I/O chip w/LPC interface |
@@ -44,14 +45,11 @@ | |||
44 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 45 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
45 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 46 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
46 | * GNU General Public License for more details. | 47 | * GNU General Public License for more details. |
47 | * | ||
48 | * You should have received a copy of the GNU General Public License | ||
49 | * along with this program; if not, write to the Free Software | ||
50 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
51 | */ | 48 | */ |
52 | 49 | ||
53 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 50 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
54 | 51 | ||
52 | #include <linux/bitops.h> | ||
55 | #include <linux/module.h> | 53 | #include <linux/module.h> |
56 | #include <linux/init.h> | 54 | #include <linux/init.h> |
57 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
@@ -72,17 +70,18 @@ | |||
72 | 70 | ||
73 | enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, | 71 | enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, |
74 | it8771, it8772, it8781, it8782, it8783, it8786, it8790, it8603, | 72 | it8771, it8772, it8781, it8782, it8783, it8786, it8790, it8603, |
75 | it8620 }; | 73 | it8620, it8628 }; |
76 | 74 | ||
77 | static unsigned short force_id; | 75 | static unsigned short force_id; |
78 | module_param(force_id, ushort, 0); | 76 | module_param(force_id, ushort, 0); |
79 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 77 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
80 | 78 | ||
81 | static struct platform_device *pdev; | 79 | static struct platform_device *it87_pdev[2]; |
80 | |||
81 | #define REG_2E 0x2e /* The register to read/write */ | ||
82 | #define REG_4E 0x4e /* Secondary register to read/write */ | ||
82 | 83 | ||
83 | #define REG 0x2e /* The register to read/write */ | ||
84 | #define DEV 0x07 /* Register: Logical device select */ | 84 | #define DEV 0x07 /* Register: Logical device select */ |
85 | #define VAL 0x2f /* The value to read/write */ | ||
86 | #define PME 0x04 /* The device with the fan registers in it */ | 85 | #define PME 0x04 /* The device with the fan registers in it */ |
87 | 86 | ||
88 | /* The device with the IT8718F/IT8720F VID value in it */ | 87 | /* The device with the IT8718F/IT8720F VID value in it */ |
@@ -91,54 +90,55 @@ static struct platform_device *pdev; | |||
91 | #define DEVID 0x20 /* Register: Device ID */ | 90 | #define DEVID 0x20 /* Register: Device ID */ |
92 | #define DEVREV 0x22 /* Register: Device Revision */ | 91 | #define DEVREV 0x22 /* Register: Device Revision */ |
93 | 92 | ||
94 | static inline int superio_inb(int reg) | 93 | static inline int superio_inb(int ioreg, int reg) |
95 | { | 94 | { |
96 | outb(reg, REG); | 95 | outb(reg, ioreg); |
97 | return inb(VAL); | 96 | return inb(ioreg + 1); |
98 | } | 97 | } |
99 | 98 | ||
100 | static inline void superio_outb(int reg, int val) | 99 | static inline void superio_outb(int ioreg, int reg, int val) |
101 | { | 100 | { |
102 | outb(reg, REG); | 101 | outb(reg, ioreg); |
103 | outb(val, VAL); | 102 | outb(val, ioreg + 1); |
104 | } | 103 | } |
105 | 104 | ||
106 | static int superio_inw(int reg) | 105 | static int superio_inw(int ioreg, int reg) |
107 | { | 106 | { |
108 | int val; | 107 | int val; |
109 | outb(reg++, REG); | 108 | |
110 | val = inb(VAL) << 8; | 109 | outb(reg++, ioreg); |
111 | outb(reg, REG); | 110 | val = inb(ioreg + 1) << 8; |
112 | val |= inb(VAL); | 111 | outb(reg, ioreg); |
112 | val |= inb(ioreg + 1); | ||
113 | return val; | 113 | return val; |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline void superio_select(int ldn) | 116 | static inline void superio_select(int ioreg, int ldn) |
117 | { | 117 | { |
118 | outb(DEV, REG); | 118 | outb(DEV, ioreg); |
119 | outb(ldn, VAL); | 119 | outb(ldn, ioreg + 1); |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline int superio_enter(void) | 122 | static inline int superio_enter(int ioreg) |
123 | { | 123 | { |
124 | /* | 124 | /* |
125 | * Try to reserve REG and REG + 1 for exclusive access. | 125 | * Try to reserve ioreg and ioreg + 1 for exclusive access. |
126 | */ | 126 | */ |
127 | if (!request_muxed_region(REG, 2, DRVNAME)) | 127 | if (!request_muxed_region(ioreg, 2, DRVNAME)) |
128 | return -EBUSY; | 128 | return -EBUSY; |
129 | 129 | ||
130 | outb(0x87, REG); | 130 | outb(0x87, ioreg); |
131 | outb(0x01, REG); | 131 | outb(0x01, ioreg); |
132 | outb(0x55, REG); | 132 | outb(0x55, ioreg); |
133 | outb(0x55, REG); | 133 | outb(ioreg == REG_4E ? 0xaa : 0x55, ioreg); |
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | static inline void superio_exit(void) | 137 | static inline void superio_exit(int ioreg) |
138 | { | 138 | { |
139 | outb(0x02, REG); | 139 | outb(0x02, ioreg); |
140 | outb(0x02, VAL); | 140 | outb(0x02, ioreg + 1); |
141 | release_region(REG, 2); | 141 | release_region(ioreg, 2); |
142 | } | 142 | } |
143 | 143 | ||
144 | /* Logical device 4 registers */ | 144 | /* Logical device 4 registers */ |
@@ -161,6 +161,7 @@ static inline void superio_exit(void) | |||
161 | #define IT8603E_DEVID 0x8603 | 161 | #define IT8603E_DEVID 0x8603 |
162 | #define IT8620E_DEVID 0x8620 | 162 | #define IT8620E_DEVID 0x8620 |
163 | #define IT8623E_DEVID 0x8623 | 163 | #define IT8623E_DEVID 0x8623 |
164 | #define IT8628E_DEVID 0x8628 | ||
164 | #define IT87_ACT_REG 0x30 | 165 | #define IT87_ACT_REG 0x30 |
165 | #define IT87_BASE_REG 0x60 | 166 | #define IT87_BASE_REG 0x60 |
166 | 167 | ||
@@ -168,6 +169,7 @@ static inline void superio_exit(void) | |||
168 | #define IT87_SIO_GPIO1_REG 0x25 | 169 | #define IT87_SIO_GPIO1_REG 0x25 |
169 | #define IT87_SIO_GPIO2_REG 0x26 | 170 | #define IT87_SIO_GPIO2_REG 0x26 |
170 | #define IT87_SIO_GPIO3_REG 0x27 | 171 | #define IT87_SIO_GPIO3_REG 0x27 |
172 | #define IT87_SIO_GPIO4_REG 0x28 | ||
171 | #define IT87_SIO_GPIO5_REG 0x29 | 173 | #define IT87_SIO_GPIO5_REG 0x29 |
172 | #define IT87_SIO_PINX1_REG 0x2a /* Pin selection */ | 174 | #define IT87_SIO_PINX1_REG 0x2a /* Pin selection */ |
173 | #define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ | 175 | #define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ |
@@ -217,7 +219,12 @@ static bool fix_pwm_polarity; | |||
217 | #define IT87_REG_FAN_DIV 0x0b | 219 | #define IT87_REG_FAN_DIV 0x0b |
218 | #define IT87_REG_FAN_16BIT 0x0c | 220 | #define IT87_REG_FAN_16BIT 0x0c |
219 | 221 | ||
220 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ | 222 | /* |
223 | * Monitors: | ||
224 | * - up to 13 voltage (0 to 7, battery, avcc, 10 to 12) | ||
225 | * - up to 6 temp (1 to 6) | ||
226 | * - up to 6 fan (1 to 6) | ||
227 | */ | ||
221 | 228 | ||
222 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c }; | 229 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c }; |
223 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e }; | 230 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e }; |
@@ -227,10 +234,12 @@ static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; | |||
227 | 234 | ||
228 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 235 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
229 | #define IT87_REG_FAN_CTL 0x14 | 236 | #define IT87_REG_FAN_CTL 0x14 |
230 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 237 | static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf }; |
231 | #define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) | 238 | static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab }; |
239 | |||
240 | static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, | ||
241 | 0x27, 0x28, 0x2f, 0x2c, 0x2d, 0x2e }; | ||
232 | 242 | ||
233 | #define IT87_REG_VIN(nr) (0x20 + (nr)) | ||
234 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) | 243 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) |
235 | 244 | ||
236 | #define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2) | 245 | #define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2) |
@@ -245,30 +254,48 @@ static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; | |||
245 | 254 | ||
246 | #define IT87_REG_CHIPID 0x58 | 255 | #define IT87_REG_CHIPID 0x58 |
247 | 256 | ||
248 | #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i)) | 257 | static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 }; |
249 | #define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i)) | 258 | |
259 | #define IT87_REG_AUTO_TEMP(nr, i) (IT87_REG_AUTO_BASE[nr] + (i)) | ||
260 | #define IT87_REG_AUTO_PWM(nr, i) (IT87_REG_AUTO_BASE[nr] + 5 + (i)) | ||
261 | |||
262 | #define IT87_REG_TEMP456_ENABLE 0x77 | ||
263 | |||
264 | #define NUM_VIN ARRAY_SIZE(IT87_REG_VIN) | ||
265 | #define NUM_VIN_LIMIT 8 | ||
266 | #define NUM_TEMP 6 | ||
267 | #define NUM_TEMP_OFFSET ARRAY_SIZE(IT87_REG_TEMP_OFFSET) | ||
268 | #define NUM_TEMP_LIMIT 3 | ||
269 | #define NUM_FAN ARRAY_SIZE(IT87_REG_FAN) | ||
270 | #define NUM_FAN_DIV 3 | ||
271 | #define NUM_PWM ARRAY_SIZE(IT87_REG_PWM) | ||
272 | #define NUM_AUTO_PWM ARRAY_SIZE(IT87_REG_PWM) | ||
250 | 273 | ||
251 | struct it87_devices { | 274 | struct it87_devices { |
252 | const char *name; | 275 | const char *name; |
253 | const char * const suffix; | 276 | const char * const suffix; |
254 | u16 features; | 277 | u32 features; |
255 | u8 peci_mask; | 278 | u8 peci_mask; |
256 | u8 old_peci_mask; | 279 | u8 old_peci_mask; |
257 | }; | 280 | }; |
258 | 281 | ||
259 | #define FEAT_12MV_ADC (1 << 0) | 282 | #define FEAT_12MV_ADC BIT(0) |
260 | #define FEAT_NEWER_AUTOPWM (1 << 1) | 283 | #define FEAT_NEWER_AUTOPWM BIT(1) |
261 | #define FEAT_OLD_AUTOPWM (1 << 2) | 284 | #define FEAT_OLD_AUTOPWM BIT(2) |
262 | #define FEAT_16BIT_FANS (1 << 3) | 285 | #define FEAT_16BIT_FANS BIT(3) |
263 | #define FEAT_TEMP_OFFSET (1 << 4) | 286 | #define FEAT_TEMP_OFFSET BIT(4) |
264 | #define FEAT_TEMP_PECI (1 << 5) | 287 | #define FEAT_TEMP_PECI BIT(5) |
265 | #define FEAT_TEMP_OLD_PECI (1 << 6) | 288 | #define FEAT_TEMP_OLD_PECI BIT(6) |
266 | #define FEAT_FAN16_CONFIG (1 << 7) /* Need to enable 16-bit fans */ | 289 | #define FEAT_FAN16_CONFIG BIT(7) /* Need to enable 16-bit fans */ |
267 | #define FEAT_FIVE_FANS (1 << 8) /* Supports five fans */ | 290 | #define FEAT_FIVE_FANS BIT(8) /* Supports five fans */ |
268 | #define FEAT_VID (1 << 9) /* Set if chip supports VID */ | 291 | #define FEAT_VID BIT(9) /* Set if chip supports VID */ |
269 | #define FEAT_IN7_INTERNAL (1 << 10) /* Set if in7 is internal */ | 292 | #define FEAT_IN7_INTERNAL BIT(10) /* Set if in7 is internal */ |
270 | #define FEAT_SIX_FANS (1 << 11) /* Supports six fans */ | 293 | #define FEAT_SIX_FANS BIT(11) /* Supports six fans */ |
271 | #define FEAT_10_9MV_ADC (1 << 12) | 294 | #define FEAT_10_9MV_ADC BIT(12) |
295 | #define FEAT_AVCC3 BIT(13) /* Chip supports in9/AVCC3 */ | ||
296 | #define FEAT_SIX_PWM BIT(14) /* Chip supports 6 pwm chn */ | ||
297 | #define FEAT_PWM_FREQ2 BIT(15) /* Separate pwm freq 2 */ | ||
298 | #define FEAT_SIX_TEMP BIT(16) /* Up to 6 temp sensors */ | ||
272 | 299 | ||
273 | static const struct it87_devices it87_devices[] = { | 300 | static const struct it87_devices it87_devices[] = { |
274 | [it87] = { | 301 | [it87] = { |
@@ -286,20 +313,22 @@ static const struct it87_devices it87_devices[] = { | |||
286 | .name = "it8716", | 313 | .name = "it8716", |
287 | .suffix = "F", | 314 | .suffix = "F", |
288 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | 315 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID |
289 | | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | 316 | | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2, |
290 | }, | 317 | }, |
291 | [it8718] = { | 318 | [it8718] = { |
292 | .name = "it8718", | 319 | .name = "it8718", |
293 | .suffix = "F", | 320 | .suffix = "F", |
294 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | 321 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID |
295 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | 322 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS |
323 | | FEAT_PWM_FREQ2, | ||
296 | .old_peci_mask = 0x4, | 324 | .old_peci_mask = 0x4, |
297 | }, | 325 | }, |
298 | [it8720] = { | 326 | [it8720] = { |
299 | .name = "it8720", | 327 | .name = "it8720", |
300 | .suffix = "F", | 328 | .suffix = "F", |
301 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | 329 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID |
302 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, | 330 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS |
331 | | FEAT_PWM_FREQ2, | ||
303 | .old_peci_mask = 0x4, | 332 | .old_peci_mask = 0x4, |
304 | }, | 333 | }, |
305 | [it8721] = { | 334 | [it8721] = { |
@@ -307,7 +336,8 @@ static const struct it87_devices it87_devices[] = { | |||
307 | .suffix = "F", | 336 | .suffix = "F", |
308 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 337 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
309 | | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI | 338 | | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI |
310 | | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL, | 339 | | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL |
340 | | FEAT_PWM_FREQ2, | ||
311 | .peci_mask = 0x05, | 341 | .peci_mask = 0x05, |
312 | .old_peci_mask = 0x02, /* Actually reports PCH */ | 342 | .old_peci_mask = 0x02, /* Actually reports PCH */ |
313 | }, | 343 | }, |
@@ -316,7 +346,7 @@ static const struct it87_devices it87_devices[] = { | |||
316 | .suffix = "F", | 346 | .suffix = "F", |
317 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 347 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
318 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS | 348 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS |
319 | | FEAT_IN7_INTERNAL, | 349 | | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2, |
320 | .peci_mask = 0x07, | 350 | .peci_mask = 0x07, |
321 | }, | 351 | }, |
322 | [it8732] = { | 352 | [it8732] = { |
@@ -332,7 +362,8 @@ static const struct it87_devices it87_devices[] = { | |||
332 | .name = "it8771", | 362 | .name = "it8771", |
333 | .suffix = "E", | 363 | .suffix = "E", |
334 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 364 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
335 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | 365 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL |
366 | | FEAT_PWM_FREQ2, | ||
336 | /* PECI: guesswork */ | 367 | /* PECI: guesswork */ |
337 | /* 12mV ADC (OHM) */ | 368 | /* 12mV ADC (OHM) */ |
338 | /* 16 bit fans (OHM) */ | 369 | /* 16 bit fans (OHM) */ |
@@ -343,7 +374,8 @@ static const struct it87_devices it87_devices[] = { | |||
343 | .name = "it8772", | 374 | .name = "it8772", |
344 | .suffix = "E", | 375 | .suffix = "E", |
345 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 376 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
346 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | 377 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL |
378 | | FEAT_PWM_FREQ2, | ||
347 | /* PECI (coreboot) */ | 379 | /* PECI (coreboot) */ |
348 | /* 12mV ADC (HWSensors4, OHM) */ | 380 | /* 12mV ADC (HWSensors4, OHM) */ |
349 | /* 16 bit fans (HWSensors4, OHM) */ | 381 | /* 16 bit fans (HWSensors4, OHM) */ |
@@ -354,42 +386,45 @@ static const struct it87_devices it87_devices[] = { | |||
354 | .name = "it8781", | 386 | .name = "it8781", |
355 | .suffix = "F", | 387 | .suffix = "F", |
356 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | 388 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET |
357 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | 389 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, |
358 | .old_peci_mask = 0x4, | 390 | .old_peci_mask = 0x4, |
359 | }, | 391 | }, |
360 | [it8782] = { | 392 | [it8782] = { |
361 | .name = "it8782", | 393 | .name = "it8782", |
362 | .suffix = "F", | 394 | .suffix = "F", |
363 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | 395 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET |
364 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | 396 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, |
365 | .old_peci_mask = 0x4, | 397 | .old_peci_mask = 0x4, |
366 | }, | 398 | }, |
367 | [it8783] = { | 399 | [it8783] = { |
368 | .name = "it8783", | 400 | .name = "it8783", |
369 | .suffix = "E/F", | 401 | .suffix = "E/F", |
370 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | 402 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET |
371 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, | 403 | | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, |
372 | .old_peci_mask = 0x4, | 404 | .old_peci_mask = 0x4, |
373 | }, | 405 | }, |
374 | [it8786] = { | 406 | [it8786] = { |
375 | .name = "it8786", | 407 | .name = "it8786", |
376 | .suffix = "E", | 408 | .suffix = "E", |
377 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 409 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
378 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | 410 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL |
411 | | FEAT_PWM_FREQ2, | ||
379 | .peci_mask = 0x07, | 412 | .peci_mask = 0x07, |
380 | }, | 413 | }, |
381 | [it8790] = { | 414 | [it8790] = { |
382 | .name = "it8790", | 415 | .name = "it8790", |
383 | .suffix = "E", | 416 | .suffix = "E", |
384 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 417 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
385 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | 418 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL |
419 | | FEAT_PWM_FREQ2, | ||
386 | .peci_mask = 0x07, | 420 | .peci_mask = 0x07, |
387 | }, | 421 | }, |
388 | [it8603] = { | 422 | [it8603] = { |
389 | .name = "it8603", | 423 | .name = "it8603", |
390 | .suffix = "E", | 424 | .suffix = "E", |
391 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 425 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
392 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL, | 426 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL |
427 | | FEAT_AVCC3 | FEAT_PWM_FREQ2, | ||
393 | .peci_mask = 0x07, | 428 | .peci_mask = 0x07, |
394 | }, | 429 | }, |
395 | [it8620] = { | 430 | [it8620] = { |
@@ -397,7 +432,17 @@ static const struct it87_devices it87_devices[] = { | |||
397 | .suffix = "E", | 432 | .suffix = "E", |
398 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | 433 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS |
399 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS | 434 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS |
400 | | FEAT_IN7_INTERNAL, | 435 | | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 |
436 | | FEAT_SIX_TEMP, | ||
437 | .peci_mask = 0x07, | ||
438 | }, | ||
439 | [it8628] = { | ||
440 | .name = "it8628", | ||
441 | .suffix = "E", | ||
442 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | ||
443 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS | ||
444 | | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 | ||
445 | | FEAT_SIX_TEMP, | ||
401 | .peci_mask = 0x07, | 446 | .peci_mask = 0x07, |
402 | }, | 447 | }, |
403 | }; | 448 | }; |
@@ -409,16 +454,20 @@ static const struct it87_devices it87_devices[] = { | |||
409 | #define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM) | 454 | #define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM) |
410 | #define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET) | 455 | #define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET) |
411 | #define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \ | 456 | #define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \ |
412 | ((data)->peci_mask & (1 << nr))) | 457 | ((data)->peci_mask & BIT(nr))) |
413 | #define has_temp_old_peci(data, nr) \ | 458 | #define has_temp_old_peci(data, nr) \ |
414 | (((data)->features & FEAT_TEMP_OLD_PECI) && \ | 459 | (((data)->features & FEAT_TEMP_OLD_PECI) && \ |
415 | ((data)->old_peci_mask & (1 << nr))) | 460 | ((data)->old_peci_mask & BIT(nr))) |
416 | #define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) | 461 | #define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) |
417 | #define has_five_fans(data) ((data)->features & (FEAT_FIVE_FANS | \ | 462 | #define has_five_fans(data) ((data)->features & (FEAT_FIVE_FANS | \ |
418 | FEAT_SIX_FANS)) | 463 | FEAT_SIX_FANS)) |
419 | #define has_vid(data) ((data)->features & FEAT_VID) | 464 | #define has_vid(data) ((data)->features & FEAT_VID) |
420 | #define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL) | 465 | #define has_in7_internal(data) ((data)->features & FEAT_IN7_INTERNAL) |
421 | #define has_six_fans(data) ((data)->features & FEAT_SIX_FANS) | 466 | #define has_six_fans(data) ((data)->features & FEAT_SIX_FANS) |
467 | #define has_avcc3(data) ((data)->features & FEAT_AVCC3) | ||
468 | #define has_six_pwm(data) ((data)->features & FEAT_SIX_PWM) | ||
469 | #define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2) | ||
470 | #define has_six_temp(data) ((data)->features & FEAT_SIX_TEMP) | ||
422 | 471 | ||
423 | struct it87_sio_data { | 472 | struct it87_sio_data { |
424 | enum chips type; | 473 | enum chips type; |
@@ -440,7 +489,7 @@ struct it87_sio_data { | |||
440 | * The structure is dynamically allocated. | 489 | * The structure is dynamically allocated. |
441 | */ | 490 | */ |
442 | struct it87_data { | 491 | struct it87_data { |
443 | struct device *hwmon_dev; | 492 | const struct attribute_group *groups[7]; |
444 | enum chips type; | 493 | enum chips type; |
445 | u16 features; | 494 | u16 features; |
446 | u8 peci_mask; | 495 | u8 peci_mask; |
@@ -453,17 +502,21 @@ struct it87_data { | |||
453 | unsigned long last_updated; /* In jiffies */ | 502 | unsigned long last_updated; /* In jiffies */ |
454 | 503 | ||
455 | u16 in_scaled; /* Internal voltage sensors are scaled */ | 504 | u16 in_scaled; /* Internal voltage sensors are scaled */ |
456 | u8 in[10][3]; /* [nr][0]=in, [1]=min, [2]=max */ | 505 | u16 in_internal; /* Bitfield, internal sensors (for labels) */ |
506 | u16 has_in; /* Bitfield, voltage sensors enabled */ | ||
507 | u8 in[NUM_VIN][3]; /* [nr][0]=in, [1]=min, [2]=max */ | ||
457 | u8 has_fan; /* Bitfield, fans enabled */ | 508 | u8 has_fan; /* Bitfield, fans enabled */ |
458 | u16 fan[6][2]; /* Register values, [nr][0]=fan, [1]=min */ | 509 | u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */ |
459 | u8 has_temp; /* Bitfield, temp sensors enabled */ | 510 | u8 has_temp; /* Bitfield, temp sensors enabled */ |
460 | s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ | 511 | s8 temp[NUM_TEMP][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ |
461 | u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ | 512 | u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ |
462 | u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */ | 513 | u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */ |
463 | u8 fan_div[3]; /* Register encoding, shifted right */ | 514 | u8 fan_div[NUM_FAN_DIV];/* Register encoding, shifted right */ |
515 | bool has_vid; /* True if VID supported */ | ||
464 | u8 vid; /* Register encoding, combined */ | 516 | u8 vid; /* Register encoding, combined */ |
465 | u8 vrm; | 517 | u8 vrm; |
466 | u32 alarms; /* Register encoding, combined */ | 518 | u32 alarms; /* Register encoding, combined */ |
519 | bool has_beep; /* true if beep supported */ | ||
467 | u8 beeps; /* Register encoding */ | 520 | u8 beeps; /* Register encoding */ |
468 | u8 fan_main_ctrl; /* Register value */ | 521 | u8 fan_main_ctrl; /* Register value */ |
469 | u8 fan_ctl; /* Register value */ | 522 | u8 fan_ctl; /* Register value */ |
@@ -478,13 +531,14 @@ struct it87_data { | |||
478 | * is no longer needed, but it is still done to keep the driver | 531 | * is no longer needed, but it is still done to keep the driver |
479 | * simple. | 532 | * simple. |
480 | */ | 533 | */ |
481 | u8 pwm_ctrl[3]; /* Register value */ | 534 | u8 has_pwm; /* Bitfield, pwm control enabled */ |
482 | u8 pwm_duty[3]; /* Manual PWM value set by user */ | 535 | u8 pwm_ctrl[NUM_PWM]; /* Register value */ |
483 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ | 536 | u8 pwm_duty[NUM_PWM]; /* Manual PWM value set by user */ |
537 | u8 pwm_temp_map[NUM_PWM];/* PWM to temp. chan. mapping (bits 1-0) */ | ||
484 | 538 | ||
485 | /* Automatic fan speed control registers */ | 539 | /* Automatic fan speed control registers */ |
486 | u8 auto_pwm[3][4]; /* [nr][3] is hard-coded */ | 540 | u8 auto_pwm[NUM_AUTO_PWM][4]; /* [nr][3] is hard-coded */ |
487 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ | 541 | s8 auto_temp[NUM_AUTO_PWM][5]; /* [nr][0] is point1_temp_hyst */ |
488 | }; | 542 | }; |
489 | 543 | ||
490 | static int adc_lsb(const struct it87_data *data, int nr) | 544 | static int adc_lsb(const struct it87_data *data, int nr) |
@@ -497,7 +551,7 @@ static int adc_lsb(const struct it87_data *data, int nr) | |||
497 | lsb = 109; | 551 | lsb = 109; |
498 | else | 552 | else |
499 | lsb = 160; | 553 | lsb = 160; |
500 | if (data->in_scaled & (1 << nr)) | 554 | if (data->in_scaled & BIT(nr)) |
501 | lsb <<= 1; | 555 | lsb <<= 1; |
502 | return lsb; | 556 | return lsb; |
503 | } | 557 | } |
@@ -554,15 +608,16 @@ static int pwm_from_reg(const struct it87_data *data, u8 reg) | |||
554 | return (reg & 0x7f) << 1; | 608 | return (reg & 0x7f) << 1; |
555 | } | 609 | } |
556 | 610 | ||
557 | |||
558 | static int DIV_TO_REG(int val) | 611 | static int DIV_TO_REG(int val) |
559 | { | 612 | { |
560 | int answer = 0; | 613 | int answer = 0; |
614 | |||
561 | while (answer < 7 && (val >>= 1)) | 615 | while (answer < 7 && (val >>= 1)) |
562 | answer++; | 616 | answer++; |
563 | return answer; | 617 | return answer; |
564 | } | 618 | } |
565 | #define DIV_FROM_REG(val) (1 << (val)) | 619 | |
620 | #define DIV_FROM_REG(val) BIT(val) | ||
566 | 621 | ||
567 | /* | 622 | /* |
568 | * PWM base frequencies. The frequency has to be divided by either 128 or 256, | 623 | * PWM base frequencies. The frequency has to be divided by either 128 or 256, |
@@ -585,32 +640,204 @@ static const unsigned int pwm_freq[8] = { | |||
585 | 750000, | 640 | 750000, |
586 | }; | 641 | }; |
587 | 642 | ||
588 | static int it87_probe(struct platform_device *pdev); | 643 | /* |
589 | static int it87_remove(struct platform_device *pdev); | 644 | * Must be called with data->update_lock held, except during initialization. |
645 | * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | ||
646 | * would slow down the IT87 access and should not be necessary. | ||
647 | */ | ||
648 | static int it87_read_value(struct it87_data *data, u8 reg) | ||
649 | { | ||
650 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); | ||
651 | return inb_p(data->addr + IT87_DATA_REG_OFFSET); | ||
652 | } | ||
590 | 653 | ||
591 | static int it87_read_value(struct it87_data *data, u8 reg); | 654 | /* |
592 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value); | 655 | * Must be called with data->update_lock held, except during initialization. |
593 | static struct it87_data *it87_update_device(struct device *dev); | 656 | * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
594 | static int it87_check_pwm(struct device *dev); | 657 | * would slow down the IT87 access and should not be necessary. |
595 | static void it87_init_device(struct platform_device *pdev); | 658 | */ |
659 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value) | ||
660 | { | ||
661 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); | ||
662 | outb_p(value, data->addr + IT87_DATA_REG_OFFSET); | ||
663 | } | ||
596 | 664 | ||
665 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | ||
666 | { | ||
667 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM[nr]); | ||
668 | if (has_newer_autopwm(data)) { | ||
669 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
670 | data->pwm_duty[nr] = it87_read_value(data, | ||
671 | IT87_REG_PWM_DUTY[nr]); | ||
672 | } else { | ||
673 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | ||
674 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
675 | else /* Manual mode */ | ||
676 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | ||
677 | } | ||
597 | 678 | ||
598 | static struct platform_driver it87_driver = { | 679 | if (has_old_autopwm(data)) { |
599 | .driver = { | 680 | int i; |
600 | .name = DRVNAME, | 681 | |
601 | }, | 682 | for (i = 0; i < 5 ; i++) |
602 | .probe = it87_probe, | 683 | data->auto_temp[nr][i] = it87_read_value(data, |
603 | .remove = it87_remove, | 684 | IT87_REG_AUTO_TEMP(nr, i)); |
604 | }; | 685 | for (i = 0; i < 3 ; i++) |
686 | data->auto_pwm[nr][i] = it87_read_value(data, | ||
687 | IT87_REG_AUTO_PWM(nr, i)); | ||
688 | } else if (has_newer_autopwm(data)) { | ||
689 | int i; | ||
690 | |||
691 | /* | ||
692 | * 0: temperature hysteresis (base + 5) | ||
693 | * 1: fan off temperature (base + 0) | ||
694 | * 2: fan start temperature (base + 1) | ||
695 | * 3: fan max temperature (base + 2) | ||
696 | */ | ||
697 | data->auto_temp[nr][0] = | ||
698 | it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 5)); | ||
699 | |||
700 | for (i = 0; i < 3 ; i++) | ||
701 | data->auto_temp[nr][i + 1] = | ||
702 | it87_read_value(data, | ||
703 | IT87_REG_AUTO_TEMP(nr, i)); | ||
704 | /* | ||
705 | * 0: start pwm value (base + 3) | ||
706 | * 1: pwm slope (base + 4, 1/8th pwm) | ||
707 | */ | ||
708 | data->auto_pwm[nr][0] = | ||
709 | it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 3)); | ||
710 | data->auto_pwm[nr][1] = | ||
711 | it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 4)); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | static struct it87_data *it87_update_device(struct device *dev) | ||
716 | { | ||
717 | struct it87_data *data = dev_get_drvdata(dev); | ||
718 | int i; | ||
719 | |||
720 | mutex_lock(&data->update_lock); | ||
721 | |||
722 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || | ||
723 | !data->valid) { | ||
724 | if (update_vbat) { | ||
725 | /* | ||
726 | * Cleared after each update, so reenable. Value | ||
727 | * returned by this read will be previous value | ||
728 | */ | ||
729 | it87_write_value(data, IT87_REG_CONFIG, | ||
730 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); | ||
731 | } | ||
732 | for (i = 0; i < NUM_VIN; i++) { | ||
733 | if (!(data->has_in & BIT(i))) | ||
734 | continue; | ||
735 | |||
736 | data->in[i][0] = | ||
737 | it87_read_value(data, IT87_REG_VIN[i]); | ||
738 | |||
739 | /* VBAT and AVCC don't have limit registers */ | ||
740 | if (i >= NUM_VIN_LIMIT) | ||
741 | continue; | ||
742 | |||
743 | data->in[i][1] = | ||
744 | it87_read_value(data, IT87_REG_VIN_MIN(i)); | ||
745 | data->in[i][2] = | ||
746 | it87_read_value(data, IT87_REG_VIN_MAX(i)); | ||
747 | } | ||
748 | |||
749 | for (i = 0; i < NUM_FAN; i++) { | ||
750 | /* Skip disabled fans */ | ||
751 | if (!(data->has_fan & BIT(i))) | ||
752 | continue; | ||
753 | |||
754 | data->fan[i][1] = | ||
755 | it87_read_value(data, IT87_REG_FAN_MIN[i]); | ||
756 | data->fan[i][0] = it87_read_value(data, | ||
757 | IT87_REG_FAN[i]); | ||
758 | /* Add high byte if in 16-bit mode */ | ||
759 | if (has_16bit_fans(data)) { | ||
760 | data->fan[i][0] |= it87_read_value(data, | ||
761 | IT87_REG_FANX[i]) << 8; | ||
762 | data->fan[i][1] |= it87_read_value(data, | ||
763 | IT87_REG_FANX_MIN[i]) << 8; | ||
764 | } | ||
765 | } | ||
766 | for (i = 0; i < NUM_TEMP; i++) { | ||
767 | if (!(data->has_temp & BIT(i))) | ||
768 | continue; | ||
769 | data->temp[i][0] = | ||
770 | it87_read_value(data, IT87_REG_TEMP(i)); | ||
771 | |||
772 | if (has_temp_offset(data) && i < NUM_TEMP_OFFSET) | ||
773 | data->temp[i][3] = | ||
774 | it87_read_value(data, | ||
775 | IT87_REG_TEMP_OFFSET[i]); | ||
776 | |||
777 | if (i >= NUM_TEMP_LIMIT) | ||
778 | continue; | ||
779 | |||
780 | data->temp[i][1] = | ||
781 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); | ||
782 | data->temp[i][2] = | ||
783 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); | ||
784 | } | ||
785 | |||
786 | /* Newer chips don't have clock dividers */ | ||
787 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { | ||
788 | i = it87_read_value(data, IT87_REG_FAN_DIV); | ||
789 | data->fan_div[0] = i & 0x07; | ||
790 | data->fan_div[1] = (i >> 3) & 0x07; | ||
791 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | ||
792 | } | ||
793 | |||
794 | data->alarms = | ||
795 | it87_read_value(data, IT87_REG_ALARM1) | | ||
796 | (it87_read_value(data, IT87_REG_ALARM2) << 8) | | ||
797 | (it87_read_value(data, IT87_REG_ALARM3) << 16); | ||
798 | data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE); | ||
799 | |||
800 | data->fan_main_ctrl = it87_read_value(data, | ||
801 | IT87_REG_FAN_MAIN_CTRL); | ||
802 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | ||
803 | for (i = 0; i < NUM_PWM; i++) { | ||
804 | if (!(data->has_pwm & BIT(i))) | ||
805 | continue; | ||
806 | it87_update_pwm_ctrl(data, i); | ||
807 | } | ||
808 | |||
809 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | ||
810 | data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); | ||
811 | /* | ||
812 | * The IT8705F does not have VID capability. | ||
813 | * The IT8718F and later don't use IT87_REG_VID for the | ||
814 | * same purpose. | ||
815 | */ | ||
816 | if (data->type == it8712 || data->type == it8716) { | ||
817 | data->vid = it87_read_value(data, IT87_REG_VID); | ||
818 | /* | ||
819 | * The older IT8712F revisions had only 5 VID pins, | ||
820 | * but we assume it is always safe to read 6 bits. | ||
821 | */ | ||
822 | data->vid &= 0x3f; | ||
823 | } | ||
824 | data->last_updated = jiffies; | ||
825 | data->valid = 1; | ||
826 | } | ||
827 | |||
828 | mutex_unlock(&data->update_lock); | ||
829 | |||
830 | return data; | ||
831 | } | ||
605 | 832 | ||
606 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 833 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
607 | char *buf) | 834 | char *buf) |
608 | { | 835 | { |
609 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | 836 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
610 | int nr = sattr->nr; | 837 | struct it87_data *data = it87_update_device(dev); |
611 | int index = sattr->index; | 838 | int index = sattr->index; |
839 | int nr = sattr->nr; | ||
612 | 840 | ||
613 | struct it87_data *data = it87_update_device(dev); | ||
614 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr][index])); | 841 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr][index])); |
615 | } | 842 | } |
616 | 843 | ||
@@ -618,10 +845,9 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, | |||
618 | const char *buf, size_t count) | 845 | const char *buf, size_t count) |
619 | { | 846 | { |
620 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | 847 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
621 | int nr = sattr->nr; | ||
622 | int index = sattr->index; | ||
623 | |||
624 | struct it87_data *data = dev_get_drvdata(dev); | 848 | struct it87_data *data = dev_get_drvdata(dev); |
849 | int index = sattr->index; | ||
850 | int nr = sattr->nr; | ||
625 | unsigned long val; | 851 | unsigned long val; |
626 | 852 | ||
627 | if (kstrtoul(buf, 10, &val) < 0) | 853 | if (kstrtoul(buf, 10, &val) < 0) |
@@ -687,8 +913,11 @@ static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in, | |||
687 | 913 | ||
688 | static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0); | 914 | static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0); |
689 | static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0); | 915 | static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0); |
916 | static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 10, 0); | ||
917 | static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in, NULL, 11, 0); | ||
918 | static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in, NULL, 12, 0); | ||
690 | 919 | ||
691 | /* 3 temperatures */ | 920 | /* Up to 6 temperatures */ |
692 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | 921 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, |
693 | char *buf) | 922 | char *buf) |
694 | { | 923 | { |
@@ -761,6 +990,9 @@ static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | |||
761 | 2, 2); | 990 | 2, 2); |
762 | static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp, | 991 | static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp, |
763 | set_temp, 2, 3); | 992 | set_temp, 2, 3); |
993 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0); | ||
994 | static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0); | ||
995 | static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0); | ||
764 | 996 | ||
765 | static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, | 997 | static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, |
766 | char *buf) | 998 | char *buf) |
@@ -771,8 +1003,8 @@ static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, | |||
771 | u8 reg = data->sensor; /* In case value is updated while used */ | 1003 | u8 reg = data->sensor; /* In case value is updated while used */ |
772 | u8 extra = data->extra; | 1004 | u8 extra = data->extra; |
773 | 1005 | ||
774 | if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1)) | 1006 | if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1)) || |
775 | || (has_temp_old_peci(data, nr) && (extra & 0x80))) | 1007 | (has_temp_old_peci(data, nr) && (extra & 0x80))) |
776 | return sprintf(buf, "6\n"); /* Intel PECI */ | 1008 | return sprintf(buf, "6\n"); /* Intel PECI */ |
777 | if (reg & (1 << nr)) | 1009 | if (reg & (1 << nr)) |
778 | return sprintf(buf, "3\n"); /* thermal diode */ | 1010 | return sprintf(buf, "3\n"); /* thermal diode */ |
@@ -837,18 +1069,19 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type, | |||
837 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, | 1069 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, |
838 | set_temp_type, 2); | 1070 | set_temp_type, 2); |
839 | 1071 | ||
840 | /* 3 Fans */ | 1072 | /* 6 Fans */ |
841 | 1073 | ||
842 | static int pwm_mode(const struct it87_data *data, int nr) | 1074 | static int pwm_mode(const struct it87_data *data, int nr) |
843 | { | 1075 | { |
844 | int ctrl = data->fan_main_ctrl & (1 << nr); | 1076 | if (data->type != it8603 && nr < 3 && !(data->fan_main_ctrl & BIT(nr))) |
845 | 1077 | return 0; /* Full speed */ | |
846 | if (ctrl == 0 && data->type != it8603) /* Full speed */ | 1078 | if (data->pwm_ctrl[nr] & 0x80) |
847 | return 0; | 1079 | return 2; /* Automatic mode */ |
848 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | 1080 | if ((data->type == it8603 || nr >= 3) && |
849 | return 2; | 1081 | data->pwm_duty[nr] == pwm_to_reg(data, 0xff)) |
850 | else /* Manual mode */ | 1082 | return 0; /* Full speed */ |
851 | return 1; | 1083 | |
1084 | return 1; /* Manual mode */ | ||
852 | } | 1085 | } |
853 | 1086 | ||
854 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | 1087 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
@@ -868,39 +1101,49 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | |||
868 | } | 1101 | } |
869 | 1102 | ||
870 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | 1103 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, |
871 | char *buf) | 1104 | char *buf) |
872 | { | 1105 | { |
873 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1106 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1107 | struct it87_data *data = it87_update_device(dev); | ||
874 | int nr = sensor_attr->index; | 1108 | int nr = sensor_attr->index; |
875 | 1109 | ||
876 | struct it87_data *data = it87_update_device(dev); | 1110 | return sprintf(buf, "%lu\n", DIV_FROM_REG(data->fan_div[nr])); |
877 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); | ||
878 | } | 1111 | } |
1112 | |||
879 | static ssize_t show_pwm_enable(struct device *dev, | 1113 | static ssize_t show_pwm_enable(struct device *dev, |
880 | struct device_attribute *attr, char *buf) | 1114 | struct device_attribute *attr, char *buf) |
881 | { | 1115 | { |
882 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1116 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1117 | struct it87_data *data = it87_update_device(dev); | ||
883 | int nr = sensor_attr->index; | 1118 | int nr = sensor_attr->index; |
884 | 1119 | ||
885 | struct it87_data *data = it87_update_device(dev); | ||
886 | return sprintf(buf, "%d\n", pwm_mode(data, nr)); | 1120 | return sprintf(buf, "%d\n", pwm_mode(data, nr)); |
887 | } | 1121 | } |
1122 | |||
888 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | 1123 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, |
889 | char *buf) | 1124 | char *buf) |
890 | { | 1125 | { |
891 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1126 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1127 | struct it87_data *data = it87_update_device(dev); | ||
892 | int nr = sensor_attr->index; | 1128 | int nr = sensor_attr->index; |
893 | 1129 | ||
894 | struct it87_data *data = it87_update_device(dev); | ||
895 | return sprintf(buf, "%d\n", | 1130 | return sprintf(buf, "%d\n", |
896 | pwm_from_reg(data, data->pwm_duty[nr])); | 1131 | pwm_from_reg(data, data->pwm_duty[nr])); |
897 | } | 1132 | } |
1133 | |||
898 | static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, | 1134 | static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, |
899 | char *buf) | 1135 | char *buf) |
900 | { | 1136 | { |
1137 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
901 | struct it87_data *data = it87_update_device(dev); | 1138 | struct it87_data *data = it87_update_device(dev); |
902 | int index = (data->fan_ctl >> 4) & 0x07; | 1139 | int nr = sensor_attr->index; |
903 | unsigned int freq; | 1140 | unsigned int freq; |
1141 | int index; | ||
1142 | |||
1143 | if (has_pwm_freq2(data) && nr == 1) | ||
1144 | index = (data->extra >> 4) & 0x07; | ||
1145 | else | ||
1146 | index = (data->fan_ctl >> 4) & 0x07; | ||
904 | 1147 | ||
905 | freq = pwm_freq[index] / (has_newer_autopwm(data) ? 256 : 128); | 1148 | freq = pwm_freq[index] / (has_newer_autopwm(data) ? 256 : 128); |
906 | 1149 | ||
@@ -953,12 +1196,11 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
953 | } | 1196 | } |
954 | 1197 | ||
955 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | 1198 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, |
956 | const char *buf, size_t count) | 1199 | const char *buf, size_t count) |
957 | { | 1200 | { |
958 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1201 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
959 | int nr = sensor_attr->index; | ||
960 | |||
961 | struct it87_data *data = dev_get_drvdata(dev); | 1202 | struct it87_data *data = dev_get_drvdata(dev); |
1203 | int nr = sensor_attr->index; | ||
962 | unsigned long val; | 1204 | unsigned long val; |
963 | int min; | 1205 | int min; |
964 | u8 old; | 1206 | u8 old; |
@@ -1013,6 +1255,11 @@ static int check_trip_points(struct device *dev, int nr) | |||
1013 | if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1]) | 1255 | if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1]) |
1014 | err = -EINVAL; | 1256 | err = -EINVAL; |
1015 | } | 1257 | } |
1258 | } else if (has_newer_autopwm(data)) { | ||
1259 | for (i = 1; i < 3; i++) { | ||
1260 | if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1]) | ||
1261 | err = -EINVAL; | ||
1262 | } | ||
1016 | } | 1263 | } |
1017 | 1264 | ||
1018 | if (err) { | 1265 | if (err) { |
@@ -1023,13 +1270,12 @@ static int check_trip_points(struct device *dev, int nr) | |||
1023 | return err; | 1270 | return err; |
1024 | } | 1271 | } |
1025 | 1272 | ||
1026 | static ssize_t set_pwm_enable(struct device *dev, | 1273 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, |
1027 | struct device_attribute *attr, const char *buf, size_t count) | 1274 | const char *buf, size_t count) |
1028 | { | 1275 | { |
1029 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1276 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1030 | int nr = sensor_attr->index; | ||
1031 | |||
1032 | struct it87_data *data = dev_get_drvdata(dev); | 1277 | struct it87_data *data = dev_get_drvdata(dev); |
1278 | int nr = sensor_attr->index; | ||
1033 | long val; | 1279 | long val; |
1034 | 1280 | ||
1035 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 2) | 1281 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 2) |
@@ -1041,21 +1287,30 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
1041 | return -EINVAL; | 1287 | return -EINVAL; |
1042 | } | 1288 | } |
1043 | 1289 | ||
1044 | /* IT8603E does not have on/off mode */ | ||
1045 | if (val == 0 && data->type == it8603) | ||
1046 | return -EINVAL; | ||
1047 | |||
1048 | mutex_lock(&data->update_lock); | 1290 | mutex_lock(&data->update_lock); |
1049 | 1291 | ||
1050 | if (val == 0) { | 1292 | if (val == 0) { |
1051 | int tmp; | 1293 | if (nr < 3 && data->type != it8603) { |
1052 | /* make sure the fan is on when in on/off mode */ | 1294 | int tmp; |
1053 | tmp = it87_read_value(data, IT87_REG_FAN_CTL); | 1295 | /* make sure the fan is on when in on/off mode */ |
1054 | it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr)); | 1296 | tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
1055 | /* set on/off mode */ | 1297 | it87_write_value(data, IT87_REG_FAN_CTL, tmp | BIT(nr)); |
1056 | data->fan_main_ctrl &= ~(1 << nr); | 1298 | /* set on/off mode */ |
1057 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, | 1299 | data->fan_main_ctrl &= ~BIT(nr); |
1058 | data->fan_main_ctrl); | 1300 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, |
1301 | data->fan_main_ctrl); | ||
1302 | } else { | ||
1303 | /* No on/off mode, set maximum pwm value */ | ||
1304 | data->pwm_duty[nr] = pwm_to_reg(data, 0xff); | ||
1305 | it87_write_value(data, IT87_REG_PWM_DUTY[nr], | ||
1306 | data->pwm_duty[nr]); | ||
1307 | /* and set manual mode */ | ||
1308 | data->pwm_ctrl[nr] = has_newer_autopwm(data) ? | ||
1309 | data->pwm_temp_map[nr] : | ||
1310 | data->pwm_duty[nr]; | ||
1311 | it87_write_value(data, IT87_REG_PWM[nr], | ||
1312 | data->pwm_ctrl[nr]); | ||
1313 | } | ||
1059 | } else { | 1314 | } else { |
1060 | if (val == 1) /* Manual mode */ | 1315 | if (val == 1) /* Manual mode */ |
1061 | data->pwm_ctrl[nr] = has_newer_autopwm(data) ? | 1316 | data->pwm_ctrl[nr] = has_newer_autopwm(data) ? |
@@ -1063,11 +1318,11 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
1063 | data->pwm_duty[nr]; | 1318 | data->pwm_duty[nr]; |
1064 | else /* Automatic mode */ | 1319 | else /* Automatic mode */ |
1065 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | 1320 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; |
1066 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 1321 | it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]); |
1067 | 1322 | ||
1068 | if (data->type != it8603) { | 1323 | if (data->type != it8603 && nr < 3) { |
1069 | /* set SmartGuardian mode */ | 1324 | /* set SmartGuardian mode */ |
1070 | data->fan_main_ctrl |= (1 << nr); | 1325 | data->fan_main_ctrl |= BIT(nr); |
1071 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, | 1326 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, |
1072 | data->fan_main_ctrl); | 1327 | data->fan_main_ctrl); |
1073 | } | 1328 | } |
@@ -1076,13 +1331,13 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
1076 | mutex_unlock(&data->update_lock); | 1331 | mutex_unlock(&data->update_lock); |
1077 | return count; | 1332 | return count; |
1078 | } | 1333 | } |
1334 | |||
1079 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | 1335 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
1080 | const char *buf, size_t count) | 1336 | const char *buf, size_t count) |
1081 | { | 1337 | { |
1082 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1338 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1083 | int nr = sensor_attr->index; | ||
1084 | |||
1085 | struct it87_data *data = dev_get_drvdata(dev); | 1339 | struct it87_data *data = dev_get_drvdata(dev); |
1340 | int nr = sensor_attr->index; | ||
1086 | long val; | 1341 | long val; |
1087 | 1342 | ||
1088 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) | 1343 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) |
@@ -1099,7 +1354,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1099 | return -EBUSY; | 1354 | return -EBUSY; |
1100 | } | 1355 | } |
1101 | data->pwm_duty[nr] = pwm_to_reg(data, val); | 1356 | data->pwm_duty[nr] = pwm_to_reg(data, val); |
1102 | it87_write_value(data, IT87_REG_PWM_DUTY(nr), | 1357 | it87_write_value(data, IT87_REG_PWM_DUTY[nr], |
1103 | data->pwm_duty[nr]); | 1358 | data->pwm_duty[nr]); |
1104 | } else { | 1359 | } else { |
1105 | data->pwm_duty[nr] = pwm_to_reg(data, val); | 1360 | data->pwm_duty[nr] = pwm_to_reg(data, val); |
@@ -1109,17 +1364,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1109 | */ | 1364 | */ |
1110 | if (!(data->pwm_ctrl[nr] & 0x80)) { | 1365 | if (!(data->pwm_ctrl[nr] & 0x80)) { |
1111 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 1366 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; |
1112 | it87_write_value(data, IT87_REG_PWM(nr), | 1367 | it87_write_value(data, IT87_REG_PWM[nr], |
1113 | data->pwm_ctrl[nr]); | 1368 | data->pwm_ctrl[nr]); |
1114 | } | 1369 | } |
1115 | } | 1370 | } |
1116 | mutex_unlock(&data->update_lock); | 1371 | mutex_unlock(&data->update_lock); |
1117 | return count; | 1372 | return count; |
1118 | } | 1373 | } |
1119 | static ssize_t set_pwm_freq(struct device *dev, | 1374 | |
1120 | struct device_attribute *attr, const char *buf, size_t count) | 1375 | static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr, |
1376 | const char *buf, size_t count) | ||
1121 | { | 1377 | { |
1378 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
1122 | struct it87_data *data = dev_get_drvdata(dev); | 1379 | struct it87_data *data = dev_get_drvdata(dev); |
1380 | int nr = sensor_attr->index; | ||
1123 | unsigned long val; | 1381 | unsigned long val; |
1124 | int i; | 1382 | int i; |
1125 | 1383 | ||
@@ -1131,63 +1389,66 @@ static ssize_t set_pwm_freq(struct device *dev, | |||
1131 | 1389 | ||
1132 | /* Search for the nearest available frequency */ | 1390 | /* Search for the nearest available frequency */ |
1133 | for (i = 0; i < 7; i++) { | 1391 | for (i = 0; i < 7; i++) { |
1134 | if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2) | 1392 | if (val > (pwm_freq[i] + pwm_freq[i + 1]) / 2) |
1135 | break; | 1393 | break; |
1136 | } | 1394 | } |
1137 | 1395 | ||
1138 | mutex_lock(&data->update_lock); | 1396 | mutex_lock(&data->update_lock); |
1139 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f; | 1397 | if (nr == 0) { |
1140 | data->fan_ctl |= i << 4; | 1398 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f; |
1141 | it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl); | 1399 | data->fan_ctl |= i << 4; |
1400 | it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl); | ||
1401 | } else { | ||
1402 | data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x8f; | ||
1403 | data->extra |= i << 4; | ||
1404 | it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra); | ||
1405 | } | ||
1142 | mutex_unlock(&data->update_lock); | 1406 | mutex_unlock(&data->update_lock); |
1143 | 1407 | ||
1144 | return count; | 1408 | return count; |
1145 | } | 1409 | } |
1410 | |||
1146 | static ssize_t show_pwm_temp_map(struct device *dev, | 1411 | static ssize_t show_pwm_temp_map(struct device *dev, |
1147 | struct device_attribute *attr, char *buf) | 1412 | struct device_attribute *attr, char *buf) |
1148 | { | 1413 | { |
1149 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1414 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1150 | int nr = sensor_attr->index; | ||
1151 | |||
1152 | struct it87_data *data = it87_update_device(dev); | 1415 | struct it87_data *data = it87_update_device(dev); |
1416 | int nr = sensor_attr->index; | ||
1153 | int map; | 1417 | int map; |
1154 | 1418 | ||
1155 | if (data->pwm_temp_map[nr] < 3) | 1419 | map = data->pwm_temp_map[nr]; |
1156 | map = 1 << data->pwm_temp_map[nr]; | 1420 | if (map >= 3) |
1157 | else | 1421 | map = 0; /* Should never happen */ |
1158 | map = 0; /* Should never happen */ | 1422 | if (nr >= 3) /* pwm channels 3..6 map to temp4..6 */ |
1159 | return sprintf(buf, "%d\n", map); | 1423 | map += 3; |
1424 | |||
1425 | return sprintf(buf, "%d\n", (int)BIT(map)); | ||
1160 | } | 1426 | } |
1427 | |||
1161 | static ssize_t set_pwm_temp_map(struct device *dev, | 1428 | static ssize_t set_pwm_temp_map(struct device *dev, |
1162 | struct device_attribute *attr, const char *buf, size_t count) | 1429 | struct device_attribute *attr, const char *buf, |
1430 | size_t count) | ||
1163 | { | 1431 | { |
1164 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1432 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
1165 | int nr = sensor_attr->index; | ||
1166 | |||
1167 | struct it87_data *data = dev_get_drvdata(dev); | 1433 | struct it87_data *data = dev_get_drvdata(dev); |
1434 | int nr = sensor_attr->index; | ||
1168 | long val; | 1435 | long val; |
1169 | u8 reg; | 1436 | u8 reg; |
1170 | 1437 | ||
1171 | /* | ||
1172 | * This check can go away if we ever support automatic fan speed | ||
1173 | * control on newer chips. | ||
1174 | */ | ||
1175 | if (!has_old_autopwm(data)) { | ||
1176 | dev_notice(dev, "Mapping change disabled for safety reasons\n"); | ||
1177 | return -EINVAL; | ||
1178 | } | ||
1179 | |||
1180 | if (kstrtol(buf, 10, &val) < 0) | 1438 | if (kstrtol(buf, 10, &val) < 0) |
1181 | return -EINVAL; | 1439 | return -EINVAL; |
1182 | 1440 | ||
1441 | if (nr >= 3) | ||
1442 | val -= 3; | ||
1443 | |||
1183 | switch (val) { | 1444 | switch (val) { |
1184 | case (1 << 0): | 1445 | case BIT(0): |
1185 | reg = 0x00; | 1446 | reg = 0x00; |
1186 | break; | 1447 | break; |
1187 | case (1 << 1): | 1448 | case BIT(1): |
1188 | reg = 0x01; | 1449 | reg = 0x01; |
1189 | break; | 1450 | break; |
1190 | case (1 << 2): | 1451 | case BIT(2): |
1191 | reg = 0x02; | 1452 | reg = 0x02; |
1192 | break; | 1453 | break; |
1193 | default: | 1454 | default: |
@@ -1202,14 +1463,14 @@ static ssize_t set_pwm_temp_map(struct device *dev, | |||
1202 | */ | 1463 | */ |
1203 | if (data->pwm_ctrl[nr] & 0x80) { | 1464 | if (data->pwm_ctrl[nr] & 0x80) { |
1204 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | 1465 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; |
1205 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 1466 | it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]); |
1206 | } | 1467 | } |
1207 | mutex_unlock(&data->update_lock); | 1468 | mutex_unlock(&data->update_lock); |
1208 | return count; | 1469 | return count; |
1209 | } | 1470 | } |
1210 | 1471 | ||
1211 | static ssize_t show_auto_pwm(struct device *dev, | 1472 | static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr, |
1212 | struct device_attribute *attr, char *buf) | 1473 | char *buf) |
1213 | { | 1474 | { |
1214 | struct it87_data *data = it87_update_device(dev); | 1475 | struct it87_data *data = it87_update_device(dev); |
1215 | struct sensor_device_attribute_2 *sensor_attr = | 1476 | struct sensor_device_attribute_2 *sensor_attr = |
@@ -1221,14 +1482,15 @@ static ssize_t show_auto_pwm(struct device *dev, | |||
1221 | pwm_from_reg(data, data->auto_pwm[nr][point])); | 1482 | pwm_from_reg(data, data->auto_pwm[nr][point])); |
1222 | } | 1483 | } |
1223 | 1484 | ||
1224 | static ssize_t set_auto_pwm(struct device *dev, | 1485 | static ssize_t set_auto_pwm(struct device *dev, struct device_attribute *attr, |
1225 | struct device_attribute *attr, const char *buf, size_t count) | 1486 | const char *buf, size_t count) |
1226 | { | 1487 | { |
1227 | struct it87_data *data = dev_get_drvdata(dev); | 1488 | struct it87_data *data = dev_get_drvdata(dev); |
1228 | struct sensor_device_attribute_2 *sensor_attr = | 1489 | struct sensor_device_attribute_2 *sensor_attr = |
1229 | to_sensor_dev_attr_2(attr); | 1490 | to_sensor_dev_attr_2(attr); |
1230 | int nr = sensor_attr->nr; | 1491 | int nr = sensor_attr->nr; |
1231 | int point = sensor_attr->index; | 1492 | int point = sensor_attr->index; |
1493 | int regaddr; | ||
1232 | long val; | 1494 | long val; |
1233 | 1495 | ||
1234 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) | 1496 | if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) |
@@ -1236,26 +1498,65 @@ static ssize_t set_auto_pwm(struct device *dev, | |||
1236 | 1498 | ||
1237 | mutex_lock(&data->update_lock); | 1499 | mutex_lock(&data->update_lock); |
1238 | data->auto_pwm[nr][point] = pwm_to_reg(data, val); | 1500 | data->auto_pwm[nr][point] = pwm_to_reg(data, val); |
1239 | it87_write_value(data, IT87_REG_AUTO_PWM(nr, point), | 1501 | if (has_newer_autopwm(data)) |
1240 | data->auto_pwm[nr][point]); | 1502 | regaddr = IT87_REG_AUTO_TEMP(nr, 3); |
1503 | else | ||
1504 | regaddr = IT87_REG_AUTO_PWM(nr, point); | ||
1505 | it87_write_value(data, regaddr, data->auto_pwm[nr][point]); | ||
1241 | mutex_unlock(&data->update_lock); | 1506 | mutex_unlock(&data->update_lock); |
1242 | return count; | 1507 | return count; |
1243 | } | 1508 | } |
1244 | 1509 | ||
1245 | static ssize_t show_auto_temp(struct device *dev, | 1510 | static ssize_t show_auto_pwm_slope(struct device *dev, |
1246 | struct device_attribute *attr, char *buf) | 1511 | struct device_attribute *attr, char *buf) |
1512 | { | ||
1513 | struct it87_data *data = it87_update_device(dev); | ||
1514 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
1515 | int nr = sensor_attr->index; | ||
1516 | |||
1517 | return sprintf(buf, "%d\n", data->auto_pwm[nr][1] & 0x7f); | ||
1518 | } | ||
1519 | |||
1520 | static ssize_t set_auto_pwm_slope(struct device *dev, | ||
1521 | struct device_attribute *attr, | ||
1522 | const char *buf, size_t count) | ||
1523 | { | ||
1524 | struct it87_data *data = dev_get_drvdata(dev); | ||
1525 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
1526 | int nr = sensor_attr->index; | ||
1527 | unsigned long val; | ||
1528 | |||
1529 | if (kstrtoul(buf, 10, &val) < 0 || val > 127) | ||
1530 | return -EINVAL; | ||
1531 | |||
1532 | mutex_lock(&data->update_lock); | ||
1533 | data->auto_pwm[nr][1] = (data->auto_pwm[nr][1] & 0x80) | val; | ||
1534 | it87_write_value(data, IT87_REG_AUTO_TEMP(nr, 4), | ||
1535 | data->auto_pwm[nr][1]); | ||
1536 | mutex_unlock(&data->update_lock); | ||
1537 | return count; | ||
1538 | } | ||
1539 | |||
1540 | static ssize_t show_auto_temp(struct device *dev, struct device_attribute *attr, | ||
1541 | char *buf) | ||
1247 | { | 1542 | { |
1248 | struct it87_data *data = it87_update_device(dev); | 1543 | struct it87_data *data = it87_update_device(dev); |
1249 | struct sensor_device_attribute_2 *sensor_attr = | 1544 | struct sensor_device_attribute_2 *sensor_attr = |
1250 | to_sensor_dev_attr_2(attr); | 1545 | to_sensor_dev_attr_2(attr); |
1251 | int nr = sensor_attr->nr; | 1546 | int nr = sensor_attr->nr; |
1252 | int point = sensor_attr->index; | 1547 | int point = sensor_attr->index; |
1548 | int reg; | ||
1549 | |||
1550 | if (has_old_autopwm(data) || point) | ||
1551 | reg = data->auto_temp[nr][point]; | ||
1552 | else | ||
1553 | reg = data->auto_temp[nr][1] - (data->auto_temp[nr][0] & 0x1f); | ||
1253 | 1554 | ||
1254 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->auto_temp[nr][point])); | 1555 | return sprintf(buf, "%d\n", TEMP_FROM_REG(reg)); |
1255 | } | 1556 | } |
1256 | 1557 | ||
1257 | static ssize_t set_auto_temp(struct device *dev, | 1558 | static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr, |
1258 | struct device_attribute *attr, const char *buf, size_t count) | 1559 | const char *buf, size_t count) |
1259 | { | 1560 | { |
1260 | struct it87_data *data = dev_get_drvdata(dev); | 1561 | struct it87_data *data = dev_get_drvdata(dev); |
1261 | struct sensor_device_attribute_2 *sensor_attr = | 1562 | struct sensor_device_attribute_2 *sensor_attr = |
@@ -1263,14 +1564,24 @@ static ssize_t set_auto_temp(struct device *dev, | |||
1263 | int nr = sensor_attr->nr; | 1564 | int nr = sensor_attr->nr; |
1264 | int point = sensor_attr->index; | 1565 | int point = sensor_attr->index; |
1265 | long val; | 1566 | long val; |
1567 | int reg; | ||
1266 | 1568 | ||
1267 | if (kstrtol(buf, 10, &val) < 0 || val < -128000 || val > 127000) | 1569 | if (kstrtol(buf, 10, &val) < 0 || val < -128000 || val > 127000) |
1268 | return -EINVAL; | 1570 | return -EINVAL; |
1269 | 1571 | ||
1270 | mutex_lock(&data->update_lock); | 1572 | mutex_lock(&data->update_lock); |
1271 | data->auto_temp[nr][point] = TEMP_TO_REG(val); | 1573 | if (has_newer_autopwm(data) && !point) { |
1272 | it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point), | 1574 | reg = data->auto_temp[nr][1] - TEMP_TO_REG(val); |
1273 | data->auto_temp[nr][point]); | 1575 | reg = clamp_val(reg, 0, 0x1f) | (data->auto_temp[nr][0] & 0xe0); |
1576 | data->auto_temp[nr][0] = reg; | ||
1577 | it87_write_value(data, IT87_REG_AUTO_TEMP(nr, 5), reg); | ||
1578 | } else { | ||
1579 | reg = TEMP_TO_REG(val); | ||
1580 | data->auto_temp[nr][point] = reg; | ||
1581 | if (has_newer_autopwm(data)) | ||
1582 | point--; | ||
1583 | it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point), reg); | ||
1584 | } | ||
1274 | mutex_unlock(&data->update_lock); | 1585 | mutex_unlock(&data->update_lock); |
1275 | return count; | 1586 | return count; |
1276 | } | 1587 | } |
@@ -1308,8 +1619,9 @@ static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | |||
1308 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | 1619 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, |
1309 | show_pwm_enable, set_pwm_enable, 0); | 1620 | show_pwm_enable, set_pwm_enable, 0); |
1310 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); | 1621 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); |
1311 | static DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); | 1622 | static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq, |
1312 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR, | 1623 | set_pwm_freq, 0); |
1624 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO, | ||
1313 | show_pwm_temp_map, set_pwm_temp_map, 0); | 1625 | show_pwm_temp_map, set_pwm_temp_map, 0); |
1314 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, | 1626 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1315 | show_auto_pwm, set_auto_pwm, 0, 0); | 1627 | show_auto_pwm, set_auto_pwm, 0, 0); |
@@ -1329,12 +1641,16 @@ static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, | |||
1329 | show_auto_temp, set_auto_temp, 0, 3); | 1641 | show_auto_temp, set_auto_temp, 0, 3); |
1330 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, | 1642 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, |
1331 | show_auto_temp, set_auto_temp, 0, 4); | 1643 | show_auto_temp, set_auto_temp, 0, 4); |
1644 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, S_IRUGO | S_IWUSR, | ||
1645 | show_auto_pwm, set_auto_pwm, 0, 0); | ||
1646 | static SENSOR_DEVICE_ATTR(pwm1_auto_slope, S_IRUGO | S_IWUSR, | ||
1647 | show_auto_pwm_slope, set_auto_pwm_slope, 0); | ||
1332 | 1648 | ||
1333 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, | 1649 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, |
1334 | show_pwm_enable, set_pwm_enable, 1); | 1650 | show_pwm_enable, set_pwm_enable, 1); |
1335 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1); | 1651 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1); |
1336 | static DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, NULL); | 1652 | static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1); |
1337 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR, | 1653 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO, |
1338 | show_pwm_temp_map, set_pwm_temp_map, 1); | 1654 | show_pwm_temp_map, set_pwm_temp_map, 1); |
1339 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, | 1655 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1340 | show_auto_pwm, set_auto_pwm, 1, 0); | 1656 | show_auto_pwm, set_auto_pwm, 1, 0); |
@@ -1354,12 +1670,16 @@ static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR, | |||
1354 | show_auto_temp, set_auto_temp, 1, 3); | 1670 | show_auto_temp, set_auto_temp, 1, 3); |
1355 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR, | 1671 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR, |
1356 | show_auto_temp, set_auto_temp, 1, 4); | 1672 | show_auto_temp, set_auto_temp, 1, 4); |
1673 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, S_IRUGO | S_IWUSR, | ||
1674 | show_auto_pwm, set_auto_pwm, 1, 0); | ||
1675 | static SENSOR_DEVICE_ATTR(pwm2_auto_slope, S_IRUGO | S_IWUSR, | ||
1676 | show_auto_pwm_slope, set_auto_pwm_slope, 1); | ||
1357 | 1677 | ||
1358 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, | 1678 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, |
1359 | show_pwm_enable, set_pwm_enable, 2); | 1679 | show_pwm_enable, set_pwm_enable, 2); |
1360 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2); | 1680 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2); |
1361 | static DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL); | 1681 | static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2); |
1362 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR, | 1682 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO, |
1363 | show_pwm_temp_map, set_pwm_temp_map, 2); | 1683 | show_pwm_temp_map, set_pwm_temp_map, 2); |
1364 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, | 1684 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1365 | show_auto_pwm, set_auto_pwm, 2, 0); | 1685 | show_auto_pwm, set_auto_pwm, 2, 0); |
@@ -1379,30 +1699,94 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR, | |||
1379 | show_auto_temp, set_auto_temp, 2, 3); | 1699 | show_auto_temp, set_auto_temp, 2, 3); |
1380 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR, | 1700 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR, |
1381 | show_auto_temp, set_auto_temp, 2, 4); | 1701 | show_auto_temp, set_auto_temp, 2, 4); |
1702 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, S_IRUGO | S_IWUSR, | ||
1703 | show_auto_pwm, set_auto_pwm, 2, 0); | ||
1704 | static SENSOR_DEVICE_ATTR(pwm3_auto_slope, S_IRUGO | S_IWUSR, | ||
1705 | show_auto_pwm_slope, set_auto_pwm_slope, 2); | ||
1706 | |||
1707 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR, | ||
1708 | show_pwm_enable, set_pwm_enable, 3); | ||
1709 | static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3); | ||
1710 | static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3); | ||
1711 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO, | ||
1712 | show_pwm_temp_map, set_pwm_temp_map, 3); | ||
1713 | static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1714 | show_auto_temp, set_auto_temp, 2, 1); | ||
1715 | static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, | ||
1716 | show_auto_temp, set_auto_temp, 2, 0); | ||
1717 | static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1718 | show_auto_temp, set_auto_temp, 2, 2); | ||
1719 | static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1720 | show_auto_temp, set_auto_temp, 2, 3); | ||
1721 | static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, S_IRUGO | S_IWUSR, | ||
1722 | show_auto_pwm, set_auto_pwm, 3, 0); | ||
1723 | static SENSOR_DEVICE_ATTR(pwm4_auto_slope, S_IRUGO | S_IWUSR, | ||
1724 | show_auto_pwm_slope, set_auto_pwm_slope, 3); | ||
1725 | |||
1726 | static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR, | ||
1727 | show_pwm_enable, set_pwm_enable, 4); | ||
1728 | static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4); | ||
1729 | static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4); | ||
1730 | static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO, | ||
1731 | show_pwm_temp_map, set_pwm_temp_map, 4); | ||
1732 | static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1733 | show_auto_temp, set_auto_temp, 2, 1); | ||
1734 | static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, | ||
1735 | show_auto_temp, set_auto_temp, 2, 0); | ||
1736 | static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1737 | show_auto_temp, set_auto_temp, 2, 2); | ||
1738 | static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1739 | show_auto_temp, set_auto_temp, 2, 3); | ||
1740 | static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, S_IRUGO | S_IWUSR, | ||
1741 | show_auto_pwm, set_auto_pwm, 4, 0); | ||
1742 | static SENSOR_DEVICE_ATTR(pwm5_auto_slope, S_IRUGO | S_IWUSR, | ||
1743 | show_auto_pwm_slope, set_auto_pwm_slope, 4); | ||
1744 | |||
1745 | static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR, | ||
1746 | show_pwm_enable, set_pwm_enable, 5); | ||
1747 | static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5); | ||
1748 | static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5); | ||
1749 | static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO, | ||
1750 | show_pwm_temp_map, set_pwm_temp_map, 5); | ||
1751 | static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1752 | show_auto_temp, set_auto_temp, 2, 1); | ||
1753 | static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, | ||
1754 | show_auto_temp, set_auto_temp, 2, 0); | ||
1755 | static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1756 | show_auto_temp, set_auto_temp, 2, 2); | ||
1757 | static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1758 | show_auto_temp, set_auto_temp, 2, 3); | ||
1759 | static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, S_IRUGO | S_IWUSR, | ||
1760 | show_auto_pwm, set_auto_pwm, 5, 0); | ||
1761 | static SENSOR_DEVICE_ATTR(pwm6_auto_slope, S_IRUGO | S_IWUSR, | ||
1762 | show_auto_pwm_slope, set_auto_pwm_slope, 5); | ||
1382 | 1763 | ||
1383 | /* Alarms */ | 1764 | /* Alarms */ |
1384 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | 1765 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, |
1385 | char *buf) | 1766 | char *buf) |
1386 | { | 1767 | { |
1387 | struct it87_data *data = it87_update_device(dev); | 1768 | struct it87_data *data = it87_update_device(dev); |
1769 | |||
1388 | return sprintf(buf, "%u\n", data->alarms); | 1770 | return sprintf(buf, "%u\n", data->alarms); |
1389 | } | 1771 | } |
1390 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 1772 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
1391 | 1773 | ||
1392 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 1774 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
1393 | char *buf) | 1775 | char *buf) |
1394 | { | 1776 | { |
1395 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
1396 | struct it87_data *data = it87_update_device(dev); | 1777 | struct it87_data *data = it87_update_device(dev); |
1778 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
1779 | |||
1397 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | 1780 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); |
1398 | } | 1781 | } |
1399 | 1782 | ||
1400 | static ssize_t clear_intrusion(struct device *dev, struct device_attribute | 1783 | static ssize_t clear_intrusion(struct device *dev, |
1401 | *attr, const char *buf, size_t count) | 1784 | struct device_attribute *attr, const char *buf, |
1785 | size_t count) | ||
1402 | { | 1786 | { |
1403 | struct it87_data *data = dev_get_drvdata(dev); | 1787 | struct it87_data *data = dev_get_drvdata(dev); |
1404 | long val; | ||
1405 | int config; | 1788 | int config; |
1789 | long val; | ||
1406 | 1790 | ||
1407 | if (kstrtol(buf, 10, &val) < 0 || val != 0) | 1791 | if (kstrtol(buf, 10, &val) < 0 || val != 0) |
1408 | return -EINVAL; | 1792 | return -EINVAL; |
@@ -1412,7 +1796,7 @@ static ssize_t clear_intrusion(struct device *dev, struct device_attribute | |||
1412 | if (config < 0) { | 1796 | if (config < 0) { |
1413 | count = config; | 1797 | count = config; |
1414 | } else { | 1798 | } else { |
1415 | config |= 1 << 5; | 1799 | config |= BIT(5); |
1416 | it87_write_value(data, IT87_REG_CONFIG, config); | 1800 | it87_write_value(data, IT87_REG_CONFIG, config); |
1417 | /* Invalidate cache to force re-read */ | 1801 | /* Invalidate cache to force re-read */ |
1418 | data->valid = 0; | 1802 | data->valid = 0; |
@@ -1443,29 +1827,30 @@ static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, | |||
1443 | show_alarm, clear_intrusion, 4); | 1827 | show_alarm, clear_intrusion, 4); |
1444 | 1828 | ||
1445 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | 1829 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, |
1446 | char *buf) | 1830 | char *buf) |
1447 | { | 1831 | { |
1448 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
1449 | struct it87_data *data = it87_update_device(dev); | 1832 | struct it87_data *data = it87_update_device(dev); |
1833 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
1834 | |||
1450 | return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1); | 1835 | return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1); |
1451 | } | 1836 | } |
1837 | |||
1452 | static ssize_t set_beep(struct device *dev, struct device_attribute *attr, | 1838 | static ssize_t set_beep(struct device *dev, struct device_attribute *attr, |
1453 | const char *buf, size_t count) | 1839 | const char *buf, size_t count) |
1454 | { | 1840 | { |
1455 | int bitnr = to_sensor_dev_attr(attr)->index; | 1841 | int bitnr = to_sensor_dev_attr(attr)->index; |
1456 | struct it87_data *data = dev_get_drvdata(dev); | 1842 | struct it87_data *data = dev_get_drvdata(dev); |
1457 | long val; | 1843 | long val; |
1458 | 1844 | ||
1459 | if (kstrtol(buf, 10, &val) < 0 | 1845 | if (kstrtol(buf, 10, &val) < 0 || (val != 0 && val != 1)) |
1460 | || (val != 0 && val != 1)) | ||
1461 | return -EINVAL; | 1846 | return -EINVAL; |
1462 | 1847 | ||
1463 | mutex_lock(&data->update_lock); | 1848 | mutex_lock(&data->update_lock); |
1464 | data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE); | 1849 | data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE); |
1465 | if (val) | 1850 | if (val) |
1466 | data->beeps |= (1 << bitnr); | 1851 | data->beeps |= BIT(bitnr); |
1467 | else | 1852 | else |
1468 | data->beeps &= ~(1 << bitnr); | 1853 | data->beeps &= ~BIT(bitnr); |
1469 | it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps); | 1854 | it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps); |
1470 | mutex_unlock(&data->update_lock); | 1855 | mutex_unlock(&data->update_lock); |
1471 | return count; | 1856 | return count; |
@@ -1493,13 +1878,15 @@ static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2); | |||
1493 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2); | 1878 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2); |
1494 | 1879 | ||
1495 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, | 1880 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, |
1496 | char *buf) | 1881 | char *buf) |
1497 | { | 1882 | { |
1498 | struct it87_data *data = dev_get_drvdata(dev); | 1883 | struct it87_data *data = dev_get_drvdata(dev); |
1884 | |||
1499 | return sprintf(buf, "%u\n", data->vrm); | 1885 | return sprintf(buf, "%u\n", data->vrm); |
1500 | } | 1886 | } |
1887 | |||
1501 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, | 1888 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, |
1502 | const char *buf, size_t count) | 1889 | const char *buf, size_t count) |
1503 | { | 1890 | { |
1504 | struct it87_data *data = dev_get_drvdata(dev); | 1891 | struct it87_data *data = dev_get_drvdata(dev); |
1505 | unsigned long val; | 1892 | unsigned long val; |
@@ -1514,15 +1901,16 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, | |||
1514 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | 1901 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); |
1515 | 1902 | ||
1516 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, | 1903 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, |
1517 | char *buf) | 1904 | char *buf) |
1518 | { | 1905 | { |
1519 | struct it87_data *data = it87_update_device(dev); | 1906 | struct it87_data *data = it87_update_device(dev); |
1520 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); | 1907 | |
1908 | return sprintf(buf, "%ld\n", (long)vid_from_reg(data->vid, data->vrm)); | ||
1521 | } | 1909 | } |
1522 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 1910 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
1523 | 1911 | ||
1524 | static ssize_t show_label(struct device *dev, struct device_attribute *attr, | 1912 | static ssize_t show_label(struct device *dev, struct device_attribute *attr, |
1525 | char *buf) | 1913 | char *buf) |
1526 | { | 1914 | { |
1527 | static const char * const labels[] = { | 1915 | static const char * const labels[] = { |
1528 | "+5V", | 1916 | "+5V", |
@@ -1548,227 +1936,348 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr, | |||
1548 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); | 1936 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); |
1549 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); | 1937 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); |
1550 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2); | 1938 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2); |
1551 | /* special AVCC3 IT8603E in9 */ | 1939 | /* AVCC3 */ |
1552 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 0); | 1940 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 0); |
1553 | 1941 | ||
1554 | static ssize_t show_name(struct device *dev, struct device_attribute | 1942 | static umode_t it87_in_is_visible(struct kobject *kobj, |
1555 | *devattr, char *buf) | 1943 | struct attribute *attr, int index) |
1556 | { | 1944 | { |
1945 | struct device *dev = container_of(kobj, struct device, kobj); | ||
1557 | struct it87_data *data = dev_get_drvdata(dev); | 1946 | struct it87_data *data = dev_get_drvdata(dev); |
1558 | return sprintf(buf, "%s\n", data->name); | 1947 | int i = index / 5; /* voltage index */ |
1948 | int a = index % 5; /* attribute index */ | ||
1949 | |||
1950 | if (index >= 40) { /* in8 and higher only have input attributes */ | ||
1951 | i = index - 40 + 8; | ||
1952 | a = 0; | ||
1953 | } | ||
1954 | |||
1955 | if (!(data->has_in & BIT(i))) | ||
1956 | return 0; | ||
1957 | |||
1958 | if (a == 4 && !data->has_beep) | ||
1959 | return 0; | ||
1960 | |||
1961 | return attr->mode; | ||
1559 | } | 1962 | } |
1560 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
1561 | 1963 | ||
1562 | static struct attribute *it87_attributes_in[10][5] = { | 1964 | static struct attribute *it87_attributes_in[] = { |
1563 | { | ||
1564 | &sensor_dev_attr_in0_input.dev_attr.attr, | 1965 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1565 | &sensor_dev_attr_in0_min.dev_attr.attr, | 1966 | &sensor_dev_attr_in0_min.dev_attr.attr, |
1566 | &sensor_dev_attr_in0_max.dev_attr.attr, | 1967 | &sensor_dev_attr_in0_max.dev_attr.attr, |
1567 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | 1968 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
1568 | NULL | 1969 | &sensor_dev_attr_in0_beep.dev_attr.attr, /* 4 */ |
1569 | }, { | 1970 | |
1570 | &sensor_dev_attr_in1_input.dev_attr.attr, | 1971 | &sensor_dev_attr_in1_input.dev_attr.attr, |
1571 | &sensor_dev_attr_in1_min.dev_attr.attr, | 1972 | &sensor_dev_attr_in1_min.dev_attr.attr, |
1572 | &sensor_dev_attr_in1_max.dev_attr.attr, | 1973 | &sensor_dev_attr_in1_max.dev_attr.attr, |
1573 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 1974 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
1574 | NULL | 1975 | &sensor_dev_attr_in1_beep.dev_attr.attr, /* 9 */ |
1575 | }, { | 1976 | |
1576 | &sensor_dev_attr_in2_input.dev_attr.attr, | 1977 | &sensor_dev_attr_in2_input.dev_attr.attr, |
1577 | &sensor_dev_attr_in2_min.dev_attr.attr, | 1978 | &sensor_dev_attr_in2_min.dev_attr.attr, |
1578 | &sensor_dev_attr_in2_max.dev_attr.attr, | 1979 | &sensor_dev_attr_in2_max.dev_attr.attr, |
1579 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | 1980 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
1580 | NULL | 1981 | &sensor_dev_attr_in2_beep.dev_attr.attr, /* 14 */ |
1581 | }, { | 1982 | |
1582 | &sensor_dev_attr_in3_input.dev_attr.attr, | 1983 | &sensor_dev_attr_in3_input.dev_attr.attr, |
1583 | &sensor_dev_attr_in3_min.dev_attr.attr, | 1984 | &sensor_dev_attr_in3_min.dev_attr.attr, |
1584 | &sensor_dev_attr_in3_max.dev_attr.attr, | 1985 | &sensor_dev_attr_in3_max.dev_attr.attr, |
1585 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | 1986 | &sensor_dev_attr_in3_alarm.dev_attr.attr, |
1586 | NULL | 1987 | &sensor_dev_attr_in3_beep.dev_attr.attr, /* 19 */ |
1587 | }, { | 1988 | |
1588 | &sensor_dev_attr_in4_input.dev_attr.attr, | 1989 | &sensor_dev_attr_in4_input.dev_attr.attr, |
1589 | &sensor_dev_attr_in4_min.dev_attr.attr, | 1990 | &sensor_dev_attr_in4_min.dev_attr.attr, |
1590 | &sensor_dev_attr_in4_max.dev_attr.attr, | 1991 | &sensor_dev_attr_in4_max.dev_attr.attr, |
1591 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | 1992 | &sensor_dev_attr_in4_alarm.dev_attr.attr, |
1592 | NULL | 1993 | &sensor_dev_attr_in4_beep.dev_attr.attr, /* 24 */ |
1593 | }, { | 1994 | |
1594 | &sensor_dev_attr_in5_input.dev_attr.attr, | 1995 | &sensor_dev_attr_in5_input.dev_attr.attr, |
1595 | &sensor_dev_attr_in5_min.dev_attr.attr, | 1996 | &sensor_dev_attr_in5_min.dev_attr.attr, |
1596 | &sensor_dev_attr_in5_max.dev_attr.attr, | 1997 | &sensor_dev_attr_in5_max.dev_attr.attr, |
1597 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | 1998 | &sensor_dev_attr_in5_alarm.dev_attr.attr, |
1598 | NULL | 1999 | &sensor_dev_attr_in5_beep.dev_attr.attr, /* 29 */ |
1599 | }, { | 2000 | |
1600 | &sensor_dev_attr_in6_input.dev_attr.attr, | 2001 | &sensor_dev_attr_in6_input.dev_attr.attr, |
1601 | &sensor_dev_attr_in6_min.dev_attr.attr, | 2002 | &sensor_dev_attr_in6_min.dev_attr.attr, |
1602 | &sensor_dev_attr_in6_max.dev_attr.attr, | 2003 | &sensor_dev_attr_in6_max.dev_attr.attr, |
1603 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | 2004 | &sensor_dev_attr_in6_alarm.dev_attr.attr, |
1604 | NULL | 2005 | &sensor_dev_attr_in6_beep.dev_attr.attr, /* 34 */ |
1605 | }, { | 2006 | |
1606 | &sensor_dev_attr_in7_input.dev_attr.attr, | 2007 | &sensor_dev_attr_in7_input.dev_attr.attr, |
1607 | &sensor_dev_attr_in7_min.dev_attr.attr, | 2008 | &sensor_dev_attr_in7_min.dev_attr.attr, |
1608 | &sensor_dev_attr_in7_max.dev_attr.attr, | 2009 | &sensor_dev_attr_in7_max.dev_attr.attr, |
1609 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | 2010 | &sensor_dev_attr_in7_alarm.dev_attr.attr, |
1610 | NULL | 2011 | &sensor_dev_attr_in7_beep.dev_attr.attr, /* 39 */ |
1611 | }, { | 2012 | |
1612 | &sensor_dev_attr_in8_input.dev_attr.attr, | 2013 | &sensor_dev_attr_in8_input.dev_attr.attr, /* 40 */ |
1613 | NULL | 2014 | &sensor_dev_attr_in9_input.dev_attr.attr, /* 41 */ |
1614 | }, { | 2015 | &sensor_dev_attr_in10_input.dev_attr.attr, /* 41 */ |
1615 | &sensor_dev_attr_in9_input.dev_attr.attr, | 2016 | &sensor_dev_attr_in11_input.dev_attr.attr, /* 41 */ |
1616 | NULL | 2017 | &sensor_dev_attr_in12_input.dev_attr.attr, /* 41 */ |
1617 | } }; | ||
1618 | |||
1619 | static const struct attribute_group it87_group_in[10] = { | ||
1620 | { .attrs = it87_attributes_in[0] }, | ||
1621 | { .attrs = it87_attributes_in[1] }, | ||
1622 | { .attrs = it87_attributes_in[2] }, | ||
1623 | { .attrs = it87_attributes_in[3] }, | ||
1624 | { .attrs = it87_attributes_in[4] }, | ||
1625 | { .attrs = it87_attributes_in[5] }, | ||
1626 | { .attrs = it87_attributes_in[6] }, | ||
1627 | { .attrs = it87_attributes_in[7] }, | ||
1628 | { .attrs = it87_attributes_in[8] }, | ||
1629 | { .attrs = it87_attributes_in[9] }, | ||
1630 | }; | 2018 | }; |
1631 | 2019 | ||
1632 | static struct attribute *it87_attributes_temp[3][6] = { | 2020 | static const struct attribute_group it87_group_in = { |
2021 | .attrs = it87_attributes_in, | ||
2022 | .is_visible = it87_in_is_visible, | ||
2023 | }; | ||
2024 | |||
2025 | static umode_t it87_temp_is_visible(struct kobject *kobj, | ||
2026 | struct attribute *attr, int index) | ||
1633 | { | 2027 | { |
2028 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2029 | struct it87_data *data = dev_get_drvdata(dev); | ||
2030 | int i = index / 7; /* temperature index */ | ||
2031 | int a = index % 7; /* attribute index */ | ||
2032 | |||
2033 | if (index >= 21) { | ||
2034 | i = index - 21 + 3; | ||
2035 | a = 0; | ||
2036 | } | ||
2037 | |||
2038 | if (!(data->has_temp & BIT(i))) | ||
2039 | return 0; | ||
2040 | |||
2041 | if (a == 5 && !has_temp_offset(data)) | ||
2042 | return 0; | ||
2043 | |||
2044 | if (a == 6 && !data->has_beep) | ||
2045 | return 0; | ||
2046 | |||
2047 | return attr->mode; | ||
2048 | } | ||
2049 | |||
2050 | static struct attribute *it87_attributes_temp[] = { | ||
1634 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 2051 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1635 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 2052 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
1636 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 2053 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
1637 | &sensor_dev_attr_temp1_type.dev_attr.attr, | 2054 | &sensor_dev_attr_temp1_type.dev_attr.attr, |
1638 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | 2055 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, |
1639 | NULL | 2056 | &sensor_dev_attr_temp1_offset.dev_attr.attr, /* 5 */ |
1640 | } , { | 2057 | &sensor_dev_attr_temp1_beep.dev_attr.attr, /* 6 */ |
1641 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 2058 | |
2059 | &sensor_dev_attr_temp2_input.dev_attr.attr, /* 7 */ | ||
1642 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 2060 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
1643 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 2061 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
1644 | &sensor_dev_attr_temp2_type.dev_attr.attr, | 2062 | &sensor_dev_attr_temp2_type.dev_attr.attr, |
1645 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 2063 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
1646 | NULL | 2064 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
1647 | } , { | 2065 | &sensor_dev_attr_temp2_beep.dev_attr.attr, |
1648 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 2066 | |
2067 | &sensor_dev_attr_temp3_input.dev_attr.attr, /* 14 */ | ||
1649 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 2068 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
1650 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 2069 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
1651 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 2070 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
1652 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 2071 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
1653 | NULL | 2072 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
1654 | } }; | 2073 | &sensor_dev_attr_temp3_beep.dev_attr.attr, |
1655 | 2074 | ||
1656 | static const struct attribute_group it87_group_temp[3] = { | 2075 | &sensor_dev_attr_temp4_input.dev_attr.attr, /* 21 */ |
1657 | { .attrs = it87_attributes_temp[0] }, | 2076 | &sensor_dev_attr_temp5_input.dev_attr.attr, |
1658 | { .attrs = it87_attributes_temp[1] }, | 2077 | &sensor_dev_attr_temp6_input.dev_attr.attr, |
1659 | { .attrs = it87_attributes_temp[2] }, | 2078 | NULL |
1660 | }; | 2079 | }; |
1661 | 2080 | ||
1662 | static struct attribute *it87_attributes_temp_offset[] = { | 2081 | static const struct attribute_group it87_group_temp = { |
1663 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | 2082 | .attrs = it87_attributes_temp, |
1664 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 2083 | .is_visible = it87_temp_is_visible, |
1665 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
1666 | }; | 2084 | }; |
1667 | 2085 | ||
2086 | static umode_t it87_is_visible(struct kobject *kobj, | ||
2087 | struct attribute *attr, int index) | ||
2088 | { | ||
2089 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2090 | struct it87_data *data = dev_get_drvdata(dev); | ||
2091 | |||
2092 | if ((index == 2 || index == 3) && !data->has_vid) | ||
2093 | return 0; | ||
2094 | |||
2095 | if (index > 3 && !(data->in_internal & BIT(index - 4))) | ||
2096 | return 0; | ||
2097 | |||
2098 | return attr->mode; | ||
2099 | } | ||
2100 | |||
1668 | static struct attribute *it87_attributes[] = { | 2101 | static struct attribute *it87_attributes[] = { |
1669 | &dev_attr_alarms.attr, | 2102 | &dev_attr_alarms.attr, |
1670 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, | 2103 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, |
1671 | &dev_attr_name.attr, | 2104 | &dev_attr_vrm.attr, /* 2 */ |
2105 | &dev_attr_cpu0_vid.attr, /* 3 */ | ||
2106 | &sensor_dev_attr_in3_label.dev_attr.attr, /* 4 .. 7 */ | ||
2107 | &sensor_dev_attr_in7_label.dev_attr.attr, | ||
2108 | &sensor_dev_attr_in8_label.dev_attr.attr, | ||
2109 | &sensor_dev_attr_in9_label.dev_attr.attr, | ||
1672 | NULL | 2110 | NULL |
1673 | }; | 2111 | }; |
1674 | 2112 | ||
1675 | static const struct attribute_group it87_group = { | 2113 | static const struct attribute_group it87_group = { |
1676 | .attrs = it87_attributes, | 2114 | .attrs = it87_attributes, |
2115 | .is_visible = it87_is_visible, | ||
1677 | }; | 2116 | }; |
1678 | 2117 | ||
1679 | static struct attribute *it87_attributes_in_beep[] = { | 2118 | static umode_t it87_fan_is_visible(struct kobject *kobj, |
1680 | &sensor_dev_attr_in0_beep.dev_attr.attr, | 2119 | struct attribute *attr, int index) |
1681 | &sensor_dev_attr_in1_beep.dev_attr.attr, | 2120 | { |
1682 | &sensor_dev_attr_in2_beep.dev_attr.attr, | 2121 | struct device *dev = container_of(kobj, struct device, kobj); |
1683 | &sensor_dev_attr_in3_beep.dev_attr.attr, | 2122 | struct it87_data *data = dev_get_drvdata(dev); |
1684 | &sensor_dev_attr_in4_beep.dev_attr.attr, | 2123 | int i = index / 5; /* fan index */ |
1685 | &sensor_dev_attr_in5_beep.dev_attr.attr, | 2124 | int a = index % 5; /* attribute index */ |
1686 | &sensor_dev_attr_in6_beep.dev_attr.attr, | ||
1687 | &sensor_dev_attr_in7_beep.dev_attr.attr, | ||
1688 | NULL, | ||
1689 | NULL, | ||
1690 | }; | ||
1691 | 2125 | ||
1692 | static struct attribute *it87_attributes_temp_beep[] = { | 2126 | if (index >= 15) { /* fan 4..6 don't have divisor attributes */ |
1693 | &sensor_dev_attr_temp1_beep.dev_attr.attr, | 2127 | i = (index - 15) / 4 + 3; |
1694 | &sensor_dev_attr_temp2_beep.dev_attr.attr, | 2128 | a = (index - 15) % 4; |
1695 | &sensor_dev_attr_temp3_beep.dev_attr.attr, | 2129 | } |
1696 | }; | ||
1697 | 2130 | ||
1698 | static struct attribute *it87_attributes_fan[6][3+1] = { { | 2131 | if (!(data->has_fan & BIT(i))) |
2132 | return 0; | ||
2133 | |||
2134 | if (a == 3) { /* beep */ | ||
2135 | if (!data->has_beep) | ||
2136 | return 0; | ||
2137 | /* first fan beep attribute is writable */ | ||
2138 | if (i == __ffs(data->has_fan)) | ||
2139 | return attr->mode | S_IWUSR; | ||
2140 | } | ||
2141 | |||
2142 | if (a == 4 && has_16bit_fans(data)) /* divisor */ | ||
2143 | return 0; | ||
2144 | |||
2145 | return attr->mode; | ||
2146 | } | ||
2147 | |||
2148 | static struct attribute *it87_attributes_fan[] = { | ||
1699 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 2149 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1700 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 2150 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1701 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | 2151 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
1702 | NULL | 2152 | &sensor_dev_attr_fan1_beep.dev_attr.attr, /* 3 */ |
1703 | }, { | 2153 | &sensor_dev_attr_fan1_div.dev_attr.attr, /* 4 */ |
2154 | |||
1704 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 2155 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1705 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 2156 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1706 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | 2157 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
1707 | NULL | 2158 | &sensor_dev_attr_fan2_beep.dev_attr.attr, |
1708 | }, { | 2159 | &sensor_dev_attr_fan2_div.dev_attr.attr, /* 9 */ |
2160 | |||
1709 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 2161 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1710 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 2162 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1711 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | 2163 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
1712 | NULL | 2164 | &sensor_dev_attr_fan3_beep.dev_attr.attr, |
1713 | }, { | 2165 | &sensor_dev_attr_fan3_div.dev_attr.attr, /* 14 */ |
1714 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 2166 | |
2167 | &sensor_dev_attr_fan4_input.dev_attr.attr, /* 15 */ | ||
1715 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 2168 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1716 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | 2169 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1717 | NULL | 2170 | &sensor_dev_attr_fan4_beep.dev_attr.attr, |
1718 | }, { | 2171 | |
1719 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 2172 | &sensor_dev_attr_fan5_input.dev_attr.attr, /* 19 */ |
1720 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 2173 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1721 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | 2174 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, |
1722 | NULL | 2175 | &sensor_dev_attr_fan5_beep.dev_attr.attr, |
1723 | }, { | 2176 | |
1724 | &sensor_dev_attr_fan6_input.dev_attr.attr, | 2177 | &sensor_dev_attr_fan6_input.dev_attr.attr, /* 23 */ |
1725 | &sensor_dev_attr_fan6_min.dev_attr.attr, | 2178 | &sensor_dev_attr_fan6_min.dev_attr.attr, |
1726 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | 2179 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, |
2180 | &sensor_dev_attr_fan6_beep.dev_attr.attr, | ||
1727 | NULL | 2181 | NULL |
1728 | } }; | ||
1729 | |||
1730 | static const struct attribute_group it87_group_fan[6] = { | ||
1731 | { .attrs = it87_attributes_fan[0] }, | ||
1732 | { .attrs = it87_attributes_fan[1] }, | ||
1733 | { .attrs = it87_attributes_fan[2] }, | ||
1734 | { .attrs = it87_attributes_fan[3] }, | ||
1735 | { .attrs = it87_attributes_fan[4] }, | ||
1736 | { .attrs = it87_attributes_fan[5] }, | ||
1737 | }; | 2182 | }; |
1738 | 2183 | ||
1739 | static const struct attribute *it87_attributes_fan_div[] = { | 2184 | static const struct attribute_group it87_group_fan = { |
1740 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 2185 | .attrs = it87_attributes_fan, |
1741 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 2186 | .is_visible = it87_fan_is_visible, |
1742 | &sensor_dev_attr_fan3_div.dev_attr.attr, | ||
1743 | }; | 2187 | }; |
1744 | 2188 | ||
1745 | static struct attribute *it87_attributes_pwm[3][4+1] = { { | 2189 | static umode_t it87_pwm_is_visible(struct kobject *kobj, |
2190 | struct attribute *attr, int index) | ||
2191 | { | ||
2192 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2193 | struct it87_data *data = dev_get_drvdata(dev); | ||
2194 | int i = index / 4; /* pwm index */ | ||
2195 | int a = index % 4; /* attribute index */ | ||
2196 | |||
2197 | if (!(data->has_pwm & BIT(i))) | ||
2198 | return 0; | ||
2199 | |||
2200 | /* pwmX_auto_channels_temp is only writable if auto pwm is supported */ | ||
2201 | if (a == 3 && (has_old_autopwm(data) || has_newer_autopwm(data))) | ||
2202 | return attr->mode | S_IWUSR; | ||
2203 | |||
2204 | /* pwm2_freq is writable if there are two pwm frequency selects */ | ||
2205 | if (has_pwm_freq2(data) && i == 1 && a == 2) | ||
2206 | return attr->mode | S_IWUSR; | ||
2207 | |||
2208 | return attr->mode; | ||
2209 | } | ||
2210 | |||
2211 | static struct attribute *it87_attributes_pwm[] = { | ||
1746 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 2212 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1747 | &sensor_dev_attr_pwm1.dev_attr.attr, | 2213 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1748 | &dev_attr_pwm1_freq.attr, | 2214 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
1749 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | 2215 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, |
1750 | NULL | 2216 | |
1751 | }, { | ||
1752 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | 2217 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
1753 | &sensor_dev_attr_pwm2.dev_attr.attr, | 2218 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1754 | &dev_attr_pwm2_freq.attr, | 2219 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
1755 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | 2220 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, |
1756 | NULL | 2221 | |
1757 | }, { | ||
1758 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | 2222 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
1759 | &sensor_dev_attr_pwm3.dev_attr.attr, | 2223 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1760 | &dev_attr_pwm3_freq.attr, | 2224 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
1761 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | 2225 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, |
2226 | |||
2227 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
2228 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
2229 | &sensor_dev_attr_pwm4_freq.dev_attr.attr, | ||
2230 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | ||
2231 | |||
2232 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, | ||
2233 | &sensor_dev_attr_pwm5.dev_attr.attr, | ||
2234 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, | ||
2235 | &sensor_dev_attr_pwm5_auto_channels_temp.dev_attr.attr, | ||
2236 | |||
2237 | &sensor_dev_attr_pwm6_enable.dev_attr.attr, | ||
2238 | &sensor_dev_attr_pwm6.dev_attr.attr, | ||
2239 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, | ||
2240 | &sensor_dev_attr_pwm6_auto_channels_temp.dev_attr.attr, | ||
2241 | |||
1762 | NULL | 2242 | NULL |
1763 | } }; | 2243 | }; |
1764 | 2244 | ||
1765 | static const struct attribute_group it87_group_pwm[3] = { | 2245 | static const struct attribute_group it87_group_pwm = { |
1766 | { .attrs = it87_attributes_pwm[0] }, | 2246 | .attrs = it87_attributes_pwm, |
1767 | { .attrs = it87_attributes_pwm[1] }, | 2247 | .is_visible = it87_pwm_is_visible, |
1768 | { .attrs = it87_attributes_pwm[2] }, | ||
1769 | }; | 2248 | }; |
1770 | 2249 | ||
1771 | static struct attribute *it87_attributes_autopwm[3][9+1] = { { | 2250 | static umode_t it87_auto_pwm_is_visible(struct kobject *kobj, |
2251 | struct attribute *attr, int index) | ||
2252 | { | ||
2253 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2254 | struct it87_data *data = dev_get_drvdata(dev); | ||
2255 | int i = index / 11; /* pwm index */ | ||
2256 | int a = index % 11; /* attribute index */ | ||
2257 | |||
2258 | if (index >= 33) { /* pwm 4..6 */ | ||
2259 | i = (index - 33) / 6 + 3; | ||
2260 | a = (index - 33) % 6 + 4; | ||
2261 | } | ||
2262 | |||
2263 | if (!(data->has_pwm & BIT(i))) | ||
2264 | return 0; | ||
2265 | |||
2266 | if (has_newer_autopwm(data)) { | ||
2267 | if (a < 4) /* no auto point pwm */ | ||
2268 | return 0; | ||
2269 | if (a == 8) /* no auto_point4 */ | ||
2270 | return 0; | ||
2271 | } | ||
2272 | if (has_old_autopwm(data)) { | ||
2273 | if (a >= 9) /* no pwm_auto_start, pwm_auto_slope */ | ||
2274 | return 0; | ||
2275 | } | ||
2276 | |||
2277 | return attr->mode; | ||
2278 | } | ||
2279 | |||
2280 | static struct attribute *it87_attributes_auto_pwm[] = { | ||
1772 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | 2281 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, |
1773 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | 2282 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, |
1774 | &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, | 2283 | &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, |
@@ -1778,9 +2287,10 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { { | |||
1778 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | 2287 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, |
1779 | &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, | 2288 | &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, |
1780 | &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, | 2289 | &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, |
1781 | NULL | 2290 | &sensor_dev_attr_pwm1_auto_start.dev_attr.attr, |
1782 | }, { | 2291 | &sensor_dev_attr_pwm1_auto_slope.dev_attr.attr, |
1783 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | 2292 | |
2293 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, /* 11 */ | ||
1784 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | 2294 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, |
1785 | &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr, | 2295 | &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr, |
1786 | &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr, | 2296 | &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr, |
@@ -1789,9 +2299,10 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { { | |||
1789 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, | 2299 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, |
1790 | &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr, | 2300 | &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr, |
1791 | &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr, | 2301 | &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr, |
1792 | NULL | 2302 | &sensor_dev_attr_pwm2_auto_start.dev_attr.attr, |
1793 | }, { | 2303 | &sensor_dev_attr_pwm2_auto_slope.dev_attr.attr, |
1794 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | 2304 | |
2305 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, /* 22 */ | ||
1795 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | 2306 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, |
1796 | &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr, | 2307 | &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr, |
1797 | &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr, | 2308 | &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr, |
@@ -1800,61 +2311,53 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { { | |||
1800 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, | 2311 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, |
1801 | &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr, | 2312 | &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr, |
1802 | &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr, | 2313 | &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr, |
1803 | NULL | 2314 | &sensor_dev_attr_pwm3_auto_start.dev_attr.attr, |
1804 | } }; | 2315 | &sensor_dev_attr_pwm3_auto_slope.dev_attr.attr, |
1805 | 2316 | ||
1806 | static const struct attribute_group it87_group_autopwm[3] = { | 2317 | &sensor_dev_attr_pwm4_auto_point1_temp.dev_attr.attr, /* 33 */ |
1807 | { .attrs = it87_attributes_autopwm[0] }, | 2318 | &sensor_dev_attr_pwm4_auto_point1_temp_hyst.dev_attr.attr, |
1808 | { .attrs = it87_attributes_autopwm[1] }, | 2319 | &sensor_dev_attr_pwm4_auto_point2_temp.dev_attr.attr, |
1809 | { .attrs = it87_attributes_autopwm[2] }, | 2320 | &sensor_dev_attr_pwm4_auto_point3_temp.dev_attr.attr, |
1810 | }; | 2321 | &sensor_dev_attr_pwm4_auto_start.dev_attr.attr, |
2322 | &sensor_dev_attr_pwm4_auto_slope.dev_attr.attr, | ||
2323 | |||
2324 | &sensor_dev_attr_pwm5_auto_point1_temp.dev_attr.attr, | ||
2325 | &sensor_dev_attr_pwm5_auto_point1_temp_hyst.dev_attr.attr, | ||
2326 | &sensor_dev_attr_pwm5_auto_point2_temp.dev_attr.attr, | ||
2327 | &sensor_dev_attr_pwm5_auto_point3_temp.dev_attr.attr, | ||
2328 | &sensor_dev_attr_pwm5_auto_start.dev_attr.attr, | ||
2329 | &sensor_dev_attr_pwm5_auto_slope.dev_attr.attr, | ||
2330 | |||
2331 | &sensor_dev_attr_pwm6_auto_point1_temp.dev_attr.attr, | ||
2332 | &sensor_dev_attr_pwm6_auto_point1_temp_hyst.dev_attr.attr, | ||
2333 | &sensor_dev_attr_pwm6_auto_point2_temp.dev_attr.attr, | ||
2334 | &sensor_dev_attr_pwm6_auto_point3_temp.dev_attr.attr, | ||
2335 | &sensor_dev_attr_pwm6_auto_start.dev_attr.attr, | ||
2336 | &sensor_dev_attr_pwm6_auto_slope.dev_attr.attr, | ||
1811 | 2337 | ||
1812 | static struct attribute *it87_attributes_fan_beep[] = { | 2338 | NULL, |
1813 | &sensor_dev_attr_fan1_beep.dev_attr.attr, | ||
1814 | &sensor_dev_attr_fan2_beep.dev_attr.attr, | ||
1815 | &sensor_dev_attr_fan3_beep.dev_attr.attr, | ||
1816 | &sensor_dev_attr_fan4_beep.dev_attr.attr, | ||
1817 | &sensor_dev_attr_fan5_beep.dev_attr.attr, | ||
1818 | &sensor_dev_attr_fan6_beep.dev_attr.attr, | ||
1819 | }; | ||
1820 | |||
1821 | static struct attribute *it87_attributes_vid[] = { | ||
1822 | &dev_attr_vrm.attr, | ||
1823 | &dev_attr_cpu0_vid.attr, | ||
1824 | NULL | ||
1825 | }; | ||
1826 | |||
1827 | static const struct attribute_group it87_group_vid = { | ||
1828 | .attrs = it87_attributes_vid, | ||
1829 | }; | ||
1830 | |||
1831 | static struct attribute *it87_attributes_label[] = { | ||
1832 | &sensor_dev_attr_in3_label.dev_attr.attr, | ||
1833 | &sensor_dev_attr_in7_label.dev_attr.attr, | ||
1834 | &sensor_dev_attr_in8_label.dev_attr.attr, | ||
1835 | &sensor_dev_attr_in9_label.dev_attr.attr, | ||
1836 | NULL | ||
1837 | }; | 2339 | }; |
1838 | 2340 | ||
1839 | static const struct attribute_group it87_group_label = { | 2341 | static const struct attribute_group it87_group_auto_pwm = { |
1840 | .attrs = it87_attributes_label, | 2342 | .attrs = it87_attributes_auto_pwm, |
2343 | .is_visible = it87_auto_pwm_is_visible, | ||
1841 | }; | 2344 | }; |
1842 | 2345 | ||
1843 | /* SuperIO detection - will change isa_address if a chip is found */ | 2346 | /* SuperIO detection - will change isa_address if a chip is found */ |
1844 | static int __init it87_find(unsigned short *address, | 2347 | static int __init it87_find(int sioaddr, unsigned short *address, |
1845 | struct it87_sio_data *sio_data) | 2348 | struct it87_sio_data *sio_data) |
1846 | { | 2349 | { |
1847 | int err; | 2350 | int err; |
1848 | u16 chip_type; | 2351 | u16 chip_type; |
1849 | const char *board_vendor, *board_name; | 2352 | const char *board_vendor, *board_name; |
1850 | const struct it87_devices *config; | 2353 | const struct it87_devices *config; |
1851 | 2354 | ||
1852 | err = superio_enter(); | 2355 | err = superio_enter(sioaddr); |
1853 | if (err) | 2356 | if (err) |
1854 | return err; | 2357 | return err; |
1855 | 2358 | ||
1856 | err = -ENODEV; | 2359 | err = -ENODEV; |
1857 | chip_type = force_id ? force_id : superio_inw(DEVID); | 2360 | chip_type = force_id ? force_id : superio_inw(sioaddr, DEVID); |
1858 | 2361 | ||
1859 | switch (chip_type) { | 2362 | switch (chip_type) { |
1860 | case IT8705F_DEVID: | 2363 | case IT8705F_DEVID: |
@@ -1910,6 +2413,9 @@ static int __init it87_find(unsigned short *address, | |||
1910 | case IT8620E_DEVID: | 2413 | case IT8620E_DEVID: |
1911 | sio_data->type = it8620; | 2414 | sio_data->type = it8620; |
1912 | break; | 2415 | break; |
2416 | case IT8628E_DEVID: | ||
2417 | sio_data->type = it8628; | ||
2418 | break; | ||
1913 | case 0xffff: /* No device at all */ | 2419 | case 0xffff: /* No device at all */ |
1914 | goto exit; | 2420 | goto exit; |
1915 | default: | 2421 | default: |
@@ -1917,20 +2423,20 @@ static int __init it87_find(unsigned short *address, | |||
1917 | goto exit; | 2423 | goto exit; |
1918 | } | 2424 | } |
1919 | 2425 | ||
1920 | superio_select(PME); | 2426 | superio_select(sioaddr, PME); |
1921 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { | 2427 | if (!(superio_inb(sioaddr, IT87_ACT_REG) & 0x01)) { |
1922 | pr_info("Device not activated, skipping\n"); | 2428 | pr_info("Device not activated, skipping\n"); |
1923 | goto exit; | 2429 | goto exit; |
1924 | } | 2430 | } |
1925 | 2431 | ||
1926 | *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1); | 2432 | *address = superio_inw(sioaddr, IT87_BASE_REG) & ~(IT87_EXTENT - 1); |
1927 | if (*address == 0) { | 2433 | if (*address == 0) { |
1928 | pr_info("Base address not set, skipping\n"); | 2434 | pr_info("Base address not set, skipping\n"); |
1929 | goto exit; | 2435 | goto exit; |
1930 | } | 2436 | } |
1931 | 2437 | ||
1932 | err = 0; | 2438 | err = 0; |
1933 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | 2439 | sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f; |
1934 | pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, | 2440 | pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, |
1935 | it87_devices[sio_data->type].suffix, | 2441 | it87_devices[sio_data->type].suffix, |
1936 | *address, sio_data->revision); | 2442 | *address, sio_data->revision); |
@@ -1939,14 +2445,19 @@ static int __init it87_find(unsigned short *address, | |||
1939 | 2445 | ||
1940 | /* in7 (VSB or VCCH5V) is always internal on some chips */ | 2446 | /* in7 (VSB or VCCH5V) is always internal on some chips */ |
1941 | if (has_in7_internal(config)) | 2447 | if (has_in7_internal(config)) |
1942 | sio_data->internal |= (1 << 1); | 2448 | sio_data->internal |= BIT(1); |
1943 | 2449 | ||
1944 | /* in8 (Vbat) is always internal */ | 2450 | /* in8 (Vbat) is always internal */ |
1945 | sio_data->internal |= (1 << 2); | 2451 | sio_data->internal |= BIT(2); |
1946 | 2452 | ||
1947 | /* Only the IT8603E has in9 */ | 2453 | /* in9 (AVCC3), always internal if supported */ |
1948 | if (sio_data->type != it8603) | 2454 | if (has_avcc3(config)) |
1949 | sio_data->skip_in |= (1 << 9); | 2455 | sio_data->internal |= BIT(3); /* in9 is AVCC */ |
2456 | else | ||
2457 | sio_data->skip_in |= BIT(9); | ||
2458 | |||
2459 | if (!has_six_pwm(config)) | ||
2460 | sio_data->skip_pwm |= BIT(3) | BIT(4) | BIT(5); | ||
1950 | 2461 | ||
1951 | if (!has_vid(config)) | 2462 | if (!has_vid(config)) |
1952 | sio_data->skip_vid = 1; | 2463 | sio_data->skip_vid = 1; |
@@ -1954,45 +2465,46 @@ static int __init it87_find(unsigned short *address, | |||
1954 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ | 2465 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ |
1955 | if (sio_data->type == it87) { | 2466 | if (sio_data->type == it87) { |
1956 | /* The IT8705F has a different LD number for GPIO */ | 2467 | /* The IT8705F has a different LD number for GPIO */ |
1957 | superio_select(5); | 2468 | superio_select(sioaddr, 5); |
1958 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 2469 | sio_data->beep_pin = superio_inb(sioaddr, |
2470 | IT87_SIO_BEEP_PIN_REG) & 0x3f; | ||
1959 | } else if (sio_data->type == it8783) { | 2471 | } else if (sio_data->type == it8783) { |
1960 | int reg25, reg27, reg2a, reg2c, regef; | 2472 | int reg25, reg27, reg2a, reg2c, regef; |
1961 | 2473 | ||
1962 | superio_select(GPIO); | 2474 | superio_select(sioaddr, GPIO); |
1963 | 2475 | ||
1964 | reg25 = superio_inb(IT87_SIO_GPIO1_REG); | 2476 | reg25 = superio_inb(sioaddr, IT87_SIO_GPIO1_REG); |
1965 | reg27 = superio_inb(IT87_SIO_GPIO3_REG); | 2477 | reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); |
1966 | reg2a = superio_inb(IT87_SIO_PINX1_REG); | 2478 | reg2a = superio_inb(sioaddr, IT87_SIO_PINX1_REG); |
1967 | reg2c = superio_inb(IT87_SIO_PINX2_REG); | 2479 | reg2c = superio_inb(sioaddr, IT87_SIO_PINX2_REG); |
1968 | regef = superio_inb(IT87_SIO_SPI_REG); | 2480 | regef = superio_inb(sioaddr, IT87_SIO_SPI_REG); |
1969 | 2481 | ||
1970 | /* Check if fan3 is there or not */ | 2482 | /* Check if fan3 is there or not */ |
1971 | if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2))) | 2483 | if ((reg27 & BIT(0)) || !(reg2c & BIT(2))) |
1972 | sio_data->skip_fan |= (1 << 2); | 2484 | sio_data->skip_fan |= BIT(2); |
1973 | if ((reg25 & (1 << 4)) | 2485 | if ((reg25 & BIT(4)) || |
1974 | || (!(reg2a & (1 << 1)) && (regef & (1 << 0)))) | 2486 | (!(reg2a & BIT(1)) && (regef & BIT(0)))) |
1975 | sio_data->skip_pwm |= (1 << 2); | 2487 | sio_data->skip_pwm |= BIT(2); |
1976 | 2488 | ||
1977 | /* Check if fan2 is there or not */ | 2489 | /* Check if fan2 is there or not */ |
1978 | if (reg27 & (1 << 7)) | 2490 | if (reg27 & BIT(7)) |
1979 | sio_data->skip_fan |= (1 << 1); | 2491 | sio_data->skip_fan |= BIT(1); |
1980 | if (reg27 & (1 << 3)) | 2492 | if (reg27 & BIT(3)) |
1981 | sio_data->skip_pwm |= (1 << 1); | 2493 | sio_data->skip_pwm |= BIT(1); |
1982 | 2494 | ||
1983 | /* VIN5 */ | 2495 | /* VIN5 */ |
1984 | if ((reg27 & (1 << 0)) || (reg2c & (1 << 2))) | 2496 | if ((reg27 & BIT(0)) || (reg2c & BIT(2))) |
1985 | sio_data->skip_in |= (1 << 5); /* No VIN5 */ | 2497 | sio_data->skip_in |= BIT(5); /* No VIN5 */ |
1986 | 2498 | ||
1987 | /* VIN6 */ | 2499 | /* VIN6 */ |
1988 | if (reg27 & (1 << 1)) | 2500 | if (reg27 & BIT(1)) |
1989 | sio_data->skip_in |= (1 << 6); /* No VIN6 */ | 2501 | sio_data->skip_in |= BIT(6); /* No VIN6 */ |
1990 | 2502 | ||
1991 | /* | 2503 | /* |
1992 | * VIN7 | 2504 | * VIN7 |
1993 | * Does not depend on bit 2 of Reg2C, contrary to datasheet. | 2505 | * Does not depend on bit 2 of Reg2C, contrary to datasheet. |
1994 | */ | 2506 | */ |
1995 | if (reg27 & (1 << 2)) { | 2507 | if (reg27 & BIT(2)) { |
1996 | /* | 2508 | /* |
1997 | * The data sheet is a bit unclear regarding the | 2509 | * The data sheet is a bit unclear regarding the |
1998 | * internal voltage divider for VCCH5V. It says | 2510 | * internal voltage divider for VCCH5V. It says |
@@ -2006,81 +2518,121 @@ static int __init it87_find(unsigned short *address, | |||
2006 | * not the case, and ask the user to report if the | 2518 | * not the case, and ask the user to report if the |
2007 | * resulting voltage is sane. | 2519 | * resulting voltage is sane. |
2008 | */ | 2520 | */ |
2009 | if (!(reg2c & (1 << 1))) { | 2521 | if (!(reg2c & BIT(1))) { |
2010 | reg2c |= (1 << 1); | 2522 | reg2c |= BIT(1); |
2011 | superio_outb(IT87_SIO_PINX2_REG, reg2c); | 2523 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, |
2524 | reg2c); | ||
2012 | pr_notice("Routing internal VCCH5V to in7.\n"); | 2525 | pr_notice("Routing internal VCCH5V to in7.\n"); |
2013 | } | 2526 | } |
2014 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); | 2527 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); |
2015 | pr_notice("Please report if it displays a reasonable voltage.\n"); | 2528 | pr_notice("Please report if it displays a reasonable voltage.\n"); |
2016 | } | 2529 | } |
2017 | 2530 | ||
2018 | if (reg2c & (1 << 0)) | 2531 | if (reg2c & BIT(0)) |
2019 | sio_data->internal |= (1 << 0); | 2532 | sio_data->internal |= BIT(0); |
2020 | if (reg2c & (1 << 1)) | 2533 | if (reg2c & BIT(1)) |
2021 | sio_data->internal |= (1 << 1); | 2534 | sio_data->internal |= BIT(1); |
2022 | 2535 | ||
2023 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 2536 | sio_data->beep_pin = superio_inb(sioaddr, |
2537 | IT87_SIO_BEEP_PIN_REG) & 0x3f; | ||
2024 | } else if (sio_data->type == it8603) { | 2538 | } else if (sio_data->type == it8603) { |
2025 | int reg27, reg29; | 2539 | int reg27, reg29; |
2026 | 2540 | ||
2027 | superio_select(GPIO); | 2541 | superio_select(sioaddr, GPIO); |
2028 | 2542 | ||
2029 | reg27 = superio_inb(IT87_SIO_GPIO3_REG); | 2543 | reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); |
2030 | 2544 | ||
2031 | /* Check if fan3 is there or not */ | 2545 | /* Check if fan3 is there or not */ |
2032 | if (reg27 & (1 << 6)) | 2546 | if (reg27 & BIT(6)) |
2033 | sio_data->skip_pwm |= (1 << 2); | 2547 | sio_data->skip_pwm |= BIT(2); |
2034 | if (reg27 & (1 << 7)) | 2548 | if (reg27 & BIT(7)) |
2035 | sio_data->skip_fan |= (1 << 2); | 2549 | sio_data->skip_fan |= BIT(2); |
2036 | 2550 | ||
2037 | /* Check if fan2 is there or not */ | 2551 | /* Check if fan2 is there or not */ |
2038 | reg29 = superio_inb(IT87_SIO_GPIO5_REG); | 2552 | reg29 = superio_inb(sioaddr, IT87_SIO_GPIO5_REG); |
2039 | if (reg29 & (1 << 1)) | 2553 | if (reg29 & BIT(1)) |
2040 | sio_data->skip_pwm |= (1 << 1); | 2554 | sio_data->skip_pwm |= BIT(1); |
2041 | if (reg29 & (1 << 2)) | 2555 | if (reg29 & BIT(2)) |
2042 | sio_data->skip_fan |= (1 << 1); | 2556 | sio_data->skip_fan |= BIT(1); |
2043 | 2557 | ||
2044 | sio_data->skip_in |= (1 << 5); /* No VIN5 */ | 2558 | sio_data->skip_in |= BIT(5); /* No VIN5 */ |
2045 | sio_data->skip_in |= (1 << 6); /* No VIN6 */ | 2559 | sio_data->skip_in |= BIT(6); /* No VIN6 */ |
2046 | 2560 | ||
2047 | sio_data->internal |= (1 << 3); /* in9 is AVCC */ | 2561 | sio_data->beep_pin = superio_inb(sioaddr, |
2048 | 2562 | IT87_SIO_BEEP_PIN_REG) & 0x3f; | |
2049 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 2563 | } else if (sio_data->type == it8620 || sio_data->type == it8628) { |
2050 | } else if (sio_data->type == it8620) { | ||
2051 | int reg; | 2564 | int reg; |
2052 | 2565 | ||
2053 | superio_select(GPIO); | 2566 | superio_select(sioaddr, GPIO); |
2567 | |||
2568 | /* Check for pwm5 */ | ||
2569 | reg = superio_inb(sioaddr, IT87_SIO_GPIO1_REG); | ||
2570 | if (reg & BIT(6)) | ||
2571 | sio_data->skip_pwm |= BIT(4); | ||
2054 | 2572 | ||
2055 | /* Check for fan4, fan5 */ | 2573 | /* Check for fan4, fan5 */ |
2056 | reg = superio_inb(IT87_SIO_GPIO2_REG); | 2574 | reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG); |
2057 | if (!(reg & (1 << 5))) | 2575 | if (!(reg & BIT(5))) |
2058 | sio_data->skip_fan |= (1 << 3); | 2576 | sio_data->skip_fan |= BIT(3); |
2059 | if (!(reg & (1 << 4))) | 2577 | if (!(reg & BIT(4))) |
2060 | sio_data->skip_fan |= (1 << 4); | 2578 | sio_data->skip_fan |= BIT(4); |
2061 | 2579 | ||
2062 | /* Check for pwm3, fan3 */ | 2580 | /* Check for pwm3, fan3 */ |
2063 | reg = superio_inb(IT87_SIO_GPIO3_REG); | 2581 | reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); |
2064 | if (reg & (1 << 6)) | 2582 | if (reg & BIT(6)) |
2065 | sio_data->skip_pwm |= (1 << 2); | 2583 | sio_data->skip_pwm |= BIT(2); |
2066 | if (reg & (1 << 7)) | 2584 | if (reg & BIT(7)) |
2067 | sio_data->skip_fan |= (1 << 2); | 2585 | sio_data->skip_fan |= BIT(2); |
2586 | |||
2587 | /* Check for pwm4 */ | ||
2588 | reg = superio_inb(sioaddr, IT87_SIO_GPIO4_REG); | ||
2589 | if (!(reg & BIT(2))) | ||
2590 | sio_data->skip_pwm |= BIT(3); | ||
2068 | 2591 | ||
2069 | /* Check for pwm2, fan2 */ | 2592 | /* Check for pwm2, fan2 */ |
2070 | reg = superio_inb(IT87_SIO_GPIO5_REG); | 2593 | reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG); |
2071 | if (reg & (1 << 1)) | 2594 | if (reg & BIT(1)) |
2072 | sio_data->skip_pwm |= (1 << 1); | 2595 | sio_data->skip_pwm |= BIT(1); |
2073 | if (reg & (1 << 2)) | 2596 | if (reg & BIT(2)) |
2074 | sio_data->skip_fan |= (1 << 1); | 2597 | sio_data->skip_fan |= BIT(1); |
2598 | /* Check for pwm6, fan6 */ | ||
2599 | if (!(reg & BIT(7))) { | ||
2600 | sio_data->skip_pwm |= BIT(5); | ||
2601 | sio_data->skip_fan |= BIT(5); | ||
2602 | } | ||
2075 | 2603 | ||
2076 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 2604 | sio_data->beep_pin = superio_inb(sioaddr, |
2605 | IT87_SIO_BEEP_PIN_REG) & 0x3f; | ||
2077 | } else { | 2606 | } else { |
2078 | int reg; | 2607 | int reg; |
2079 | bool uart6; | 2608 | bool uart6; |
2080 | 2609 | ||
2081 | superio_select(GPIO); | 2610 | superio_select(sioaddr, GPIO); |
2611 | |||
2612 | /* Check for fan4, fan5 */ | ||
2613 | if (has_five_fans(config)) { | ||
2614 | reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG); | ||
2615 | switch (sio_data->type) { | ||
2616 | case it8718: | ||
2617 | if (reg & BIT(5)) | ||
2618 | sio_data->skip_fan |= BIT(3); | ||
2619 | if (reg & BIT(4)) | ||
2620 | sio_data->skip_fan |= BIT(4); | ||
2621 | break; | ||
2622 | case it8720: | ||
2623 | case it8721: | ||
2624 | case it8728: | ||
2625 | if (!(reg & BIT(5))) | ||
2626 | sio_data->skip_fan |= BIT(3); | ||
2627 | if (!(reg & BIT(4))) | ||
2628 | sio_data->skip_fan |= BIT(4); | ||
2629 | break; | ||
2630 | default: | ||
2631 | break; | ||
2632 | } | ||
2633 | } | ||
2082 | 2634 | ||
2083 | reg = superio_inb(IT87_SIO_GPIO3_REG); | 2635 | reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); |
2084 | if (!sio_data->skip_vid) { | 2636 | if (!sio_data->skip_vid) { |
2085 | /* We need at least 4 VID pins */ | 2637 | /* We need at least 4 VID pins */ |
2086 | if (reg & 0x0f) { | 2638 | if (reg & 0x0f) { |
@@ -2090,25 +2642,26 @@ static int __init it87_find(unsigned short *address, | |||
2090 | } | 2642 | } |
2091 | 2643 | ||
2092 | /* Check if fan3 is there or not */ | 2644 | /* Check if fan3 is there or not */ |
2093 | if (reg & (1 << 6)) | 2645 | if (reg & BIT(6)) |
2094 | sio_data->skip_pwm |= (1 << 2); | 2646 | sio_data->skip_pwm |= BIT(2); |
2095 | if (reg & (1 << 7)) | 2647 | if (reg & BIT(7)) |
2096 | sio_data->skip_fan |= (1 << 2); | 2648 | sio_data->skip_fan |= BIT(2); |
2097 | 2649 | ||
2098 | /* Check if fan2 is there or not */ | 2650 | /* Check if fan2 is there or not */ |
2099 | reg = superio_inb(IT87_SIO_GPIO5_REG); | 2651 | reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG); |
2100 | if (reg & (1 << 1)) | 2652 | if (reg & BIT(1)) |
2101 | sio_data->skip_pwm |= (1 << 1); | 2653 | sio_data->skip_pwm |= BIT(1); |
2102 | if (reg & (1 << 2)) | 2654 | if (reg & BIT(2)) |
2103 | sio_data->skip_fan |= (1 << 1); | 2655 | sio_data->skip_fan |= BIT(1); |
2104 | 2656 | ||
2105 | if ((sio_data->type == it8718 || sio_data->type == it8720) | 2657 | if ((sio_data->type == it8718 || sio_data->type == it8720) && |
2106 | && !(sio_data->skip_vid)) | 2658 | !(sio_data->skip_vid)) |
2107 | sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); | 2659 | sio_data->vid_value = superio_inb(sioaddr, |
2660 | IT87_SIO_VID_REG); | ||
2108 | 2661 | ||
2109 | reg = superio_inb(IT87_SIO_PINX2_REG); | 2662 | reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG); |
2110 | 2663 | ||
2111 | uart6 = sio_data->type == it8782 && (reg & (1 << 2)); | 2664 | uart6 = sio_data->type == it8782 && (reg & BIT(2)); |
2112 | 2665 | ||
2113 | /* | 2666 | /* |
2114 | * The IT8720F has no VIN7 pin, so VCCH should always be | 2667 | * The IT8720F has no VIN7 pin, so VCCH should always be |
@@ -2124,15 +2677,15 @@ static int __init it87_find(unsigned short *address, | |||
2124 | * If UART6 is enabled, re-route VIN7 to the internal divider | 2677 | * If UART6 is enabled, re-route VIN7 to the internal divider |
2125 | * if that is not already the case. | 2678 | * if that is not already the case. |
2126 | */ | 2679 | */ |
2127 | if ((sio_data->type == it8720 || uart6) && !(reg & (1 << 1))) { | 2680 | if ((sio_data->type == it8720 || uart6) && !(reg & BIT(1))) { |
2128 | reg |= (1 << 1); | 2681 | reg |= BIT(1); |
2129 | superio_outb(IT87_SIO_PINX2_REG, reg); | 2682 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg); |
2130 | pr_notice("Routing internal VCCH to in7\n"); | 2683 | pr_notice("Routing internal VCCH to in7\n"); |
2131 | } | 2684 | } |
2132 | if (reg & (1 << 0)) | 2685 | if (reg & BIT(0)) |
2133 | sio_data->internal |= (1 << 0); | 2686 | sio_data->internal |= BIT(0); |
2134 | if (reg & (1 << 1)) | 2687 | if (reg & BIT(1)) |
2135 | sio_data->internal |= (1 << 1); | 2688 | sio_data->internal |= BIT(1); |
2136 | 2689 | ||
2137 | /* | 2690 | /* |
2138 | * On IT8782F, UART6 pins overlap with VIN5, VIN6, and VIN7. | 2691 | * On IT8782F, UART6 pins overlap with VIN5, VIN6, and VIN7. |
@@ -2144,11 +2697,12 @@ static int __init it87_find(unsigned short *address, | |||
2144 | * temperature source here, skip_temp is preliminary. | 2697 | * temperature source here, skip_temp is preliminary. |
2145 | */ | 2698 | */ |
2146 | if (uart6) { | 2699 | if (uart6) { |
2147 | sio_data->skip_in |= (1 << 5) | (1 << 6); | 2700 | sio_data->skip_in |= BIT(5) | BIT(6); |
2148 | sio_data->skip_temp |= (1 << 2); | 2701 | sio_data->skip_temp |= BIT(2); |
2149 | } | 2702 | } |
2150 | 2703 | ||
2151 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 2704 | sio_data->beep_pin = superio_inb(sioaddr, |
2705 | IT87_SIO_BEEP_PIN_REG) & 0x3f; | ||
2152 | } | 2706 | } |
2153 | if (sio_data->beep_pin) | 2707 | if (sio_data->beep_pin) |
2154 | pr_info("Beeping is supported\n"); | 2708 | pr_info("Beeping is supported\n"); |
@@ -2157,8 +2711,8 @@ static int __init it87_find(unsigned short *address, | |||
2157 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | 2711 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); |
2158 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | 2712 | board_name = dmi_get_system_info(DMI_BOARD_NAME); |
2159 | if (board_vendor && board_name) { | 2713 | if (board_vendor && board_name) { |
2160 | if (strcmp(board_vendor, "nVIDIA") == 0 | 2714 | if (strcmp(board_vendor, "nVIDIA") == 0 && |
2161 | && strcmp(board_name, "FN68PT") == 0) { | 2715 | strcmp(board_name, "FN68PT") == 0) { |
2162 | /* | 2716 | /* |
2163 | * On the Shuttle SN68PT, FAN_CTL2 is apparently not | 2717 | * On the Shuttle SN68PT, FAN_CTL2 is apparently not |
2164 | * connected to a fan, but to something else. One user | 2718 | * connected to a fan, but to something else. One user |
@@ -2168,373 +2722,15 @@ static int __init it87_find(unsigned short *address, | |||
2168 | * the same board is ever used in other systems. | 2722 | * the same board is ever used in other systems. |
2169 | */ | 2723 | */ |
2170 | pr_info("Disabling pwm2 due to hardware constraints\n"); | 2724 | pr_info("Disabling pwm2 due to hardware constraints\n"); |
2171 | sio_data->skip_pwm = (1 << 1); | 2725 | sio_data->skip_pwm = BIT(1); |
2172 | } | 2726 | } |
2173 | } | 2727 | } |
2174 | 2728 | ||
2175 | exit: | 2729 | exit: |
2176 | superio_exit(); | 2730 | superio_exit(sioaddr); |
2177 | return err; | 2731 | return err; |
2178 | } | 2732 | } |
2179 | 2733 | ||
2180 | static void it87_remove_files(struct device *dev) | ||
2181 | { | ||
2182 | struct it87_data *data = platform_get_drvdata(pdev); | ||
2183 | struct it87_sio_data *sio_data = dev_get_platdata(dev); | ||
2184 | int i; | ||
2185 | |||
2186 | sysfs_remove_group(&dev->kobj, &it87_group); | ||
2187 | for (i = 0; i < 10; i++) { | ||
2188 | if (sio_data->skip_in & (1 << i)) | ||
2189 | continue; | ||
2190 | sysfs_remove_group(&dev->kobj, &it87_group_in[i]); | ||
2191 | if (it87_attributes_in_beep[i]) | ||
2192 | sysfs_remove_file(&dev->kobj, | ||
2193 | it87_attributes_in_beep[i]); | ||
2194 | } | ||
2195 | for (i = 0; i < 3; i++) { | ||
2196 | if (!(data->has_temp & (1 << i))) | ||
2197 | continue; | ||
2198 | sysfs_remove_group(&dev->kobj, &it87_group_temp[i]); | ||
2199 | if (has_temp_offset(data)) | ||
2200 | sysfs_remove_file(&dev->kobj, | ||
2201 | it87_attributes_temp_offset[i]); | ||
2202 | if (sio_data->beep_pin) | ||
2203 | sysfs_remove_file(&dev->kobj, | ||
2204 | it87_attributes_temp_beep[i]); | ||
2205 | } | ||
2206 | for (i = 0; i < 6; i++) { | ||
2207 | if (!(data->has_fan & (1 << i))) | ||
2208 | continue; | ||
2209 | sysfs_remove_group(&dev->kobj, &it87_group_fan[i]); | ||
2210 | if (sio_data->beep_pin) | ||
2211 | sysfs_remove_file(&dev->kobj, | ||
2212 | it87_attributes_fan_beep[i]); | ||
2213 | if (i < 3 && !has_16bit_fans(data)) | ||
2214 | sysfs_remove_file(&dev->kobj, | ||
2215 | it87_attributes_fan_div[i]); | ||
2216 | } | ||
2217 | for (i = 0; i < 3; i++) { | ||
2218 | if (sio_data->skip_pwm & (1 << i)) | ||
2219 | continue; | ||
2220 | sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]); | ||
2221 | if (has_old_autopwm(data)) | ||
2222 | sysfs_remove_group(&dev->kobj, | ||
2223 | &it87_group_autopwm[i]); | ||
2224 | } | ||
2225 | if (!sio_data->skip_vid) | ||
2226 | sysfs_remove_group(&dev->kobj, &it87_group_vid); | ||
2227 | sysfs_remove_group(&dev->kobj, &it87_group_label); | ||
2228 | } | ||
2229 | |||
2230 | static int it87_probe(struct platform_device *pdev) | ||
2231 | { | ||
2232 | struct it87_data *data; | ||
2233 | struct resource *res; | ||
2234 | struct device *dev = &pdev->dev; | ||
2235 | struct it87_sio_data *sio_data = dev_get_platdata(dev); | ||
2236 | int err = 0, i; | ||
2237 | int enable_pwm_interface; | ||
2238 | int fan_beep_need_rw; | ||
2239 | |||
2240 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
2241 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, | ||
2242 | DRVNAME)) { | ||
2243 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
2244 | (unsigned long)res->start, | ||
2245 | (unsigned long)(res->start + IT87_EC_EXTENT - 1)); | ||
2246 | return -EBUSY; | ||
2247 | } | ||
2248 | |||
2249 | data = devm_kzalloc(&pdev->dev, sizeof(struct it87_data), GFP_KERNEL); | ||
2250 | if (!data) | ||
2251 | return -ENOMEM; | ||
2252 | |||
2253 | data->addr = res->start; | ||
2254 | data->type = sio_data->type; | ||
2255 | data->features = it87_devices[sio_data->type].features; | ||
2256 | data->peci_mask = it87_devices[sio_data->type].peci_mask; | ||
2257 | data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask; | ||
2258 | data->name = it87_devices[sio_data->type].name; | ||
2259 | /* | ||
2260 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
2261 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
2262 | * These are the first revisions with 16-bit tachometer support. | ||
2263 | */ | ||
2264 | switch (data->type) { | ||
2265 | case it87: | ||
2266 | if (sio_data->revision >= 0x03) { | ||
2267 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
2268 | data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS; | ||
2269 | } | ||
2270 | break; | ||
2271 | case it8712: | ||
2272 | if (sio_data->revision >= 0x08) { | ||
2273 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
2274 | data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS | | ||
2275 | FEAT_FIVE_FANS; | ||
2276 | } | ||
2277 | break; | ||
2278 | default: | ||
2279 | break; | ||
2280 | } | ||
2281 | |||
2282 | /* Now, we do the remaining detection. */ | ||
2283 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) | ||
2284 | || it87_read_value(data, IT87_REG_CHIPID) != 0x90) | ||
2285 | return -ENODEV; | ||
2286 | |||
2287 | platform_set_drvdata(pdev, data); | ||
2288 | |||
2289 | mutex_init(&data->update_lock); | ||
2290 | |||
2291 | /* Check PWM configuration */ | ||
2292 | enable_pwm_interface = it87_check_pwm(dev); | ||
2293 | |||
2294 | /* Starting with IT8721F, we handle scaling of internal voltages */ | ||
2295 | if (has_12mv_adc(data)) { | ||
2296 | if (sio_data->internal & (1 << 0)) | ||
2297 | data->in_scaled |= (1 << 3); /* in3 is AVCC */ | ||
2298 | if (sio_data->internal & (1 << 1)) | ||
2299 | data->in_scaled |= (1 << 7); /* in7 is VSB */ | ||
2300 | if (sio_data->internal & (1 << 2)) | ||
2301 | data->in_scaled |= (1 << 8); /* in8 is Vbat */ | ||
2302 | if (sio_data->internal & (1 << 3)) | ||
2303 | data->in_scaled |= (1 << 9); /* in9 is AVCC */ | ||
2304 | } else if (sio_data->type == it8781 || sio_data->type == it8782 || | ||
2305 | sio_data->type == it8783) { | ||
2306 | if (sio_data->internal & (1 << 0)) | ||
2307 | data->in_scaled |= (1 << 3); /* in3 is VCC5V */ | ||
2308 | if (sio_data->internal & (1 << 1)) | ||
2309 | data->in_scaled |= (1 << 7); /* in7 is VCCH5V */ | ||
2310 | } | ||
2311 | |||
2312 | data->has_temp = 0x07; | ||
2313 | if (sio_data->skip_temp & (1 << 2)) { | ||
2314 | if (sio_data->type == it8782 | ||
2315 | && !(it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x80)) | ||
2316 | data->has_temp &= ~(1 << 2); | ||
2317 | } | ||
2318 | |||
2319 | /* Initialize the IT87 chip */ | ||
2320 | it87_init_device(pdev); | ||
2321 | |||
2322 | /* Register sysfs hooks */ | ||
2323 | err = sysfs_create_group(&dev->kobj, &it87_group); | ||
2324 | if (err) | ||
2325 | return err; | ||
2326 | |||
2327 | for (i = 0; i < 10; i++) { | ||
2328 | if (sio_data->skip_in & (1 << i)) | ||
2329 | continue; | ||
2330 | err = sysfs_create_group(&dev->kobj, &it87_group_in[i]); | ||
2331 | if (err) | ||
2332 | goto error; | ||
2333 | if (sio_data->beep_pin && it87_attributes_in_beep[i]) { | ||
2334 | err = sysfs_create_file(&dev->kobj, | ||
2335 | it87_attributes_in_beep[i]); | ||
2336 | if (err) | ||
2337 | goto error; | ||
2338 | } | ||
2339 | } | ||
2340 | |||
2341 | for (i = 0; i < 3; i++) { | ||
2342 | if (!(data->has_temp & (1 << i))) | ||
2343 | continue; | ||
2344 | err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]); | ||
2345 | if (err) | ||
2346 | goto error; | ||
2347 | if (has_temp_offset(data)) { | ||
2348 | err = sysfs_create_file(&dev->kobj, | ||
2349 | it87_attributes_temp_offset[i]); | ||
2350 | if (err) | ||
2351 | goto error; | ||
2352 | } | ||
2353 | if (sio_data->beep_pin) { | ||
2354 | err = sysfs_create_file(&dev->kobj, | ||
2355 | it87_attributes_temp_beep[i]); | ||
2356 | if (err) | ||
2357 | goto error; | ||
2358 | } | ||
2359 | } | ||
2360 | |||
2361 | /* Do not create fan files for disabled fans */ | ||
2362 | fan_beep_need_rw = 1; | ||
2363 | for (i = 0; i < 6; i++) { | ||
2364 | if (!(data->has_fan & (1 << i))) | ||
2365 | continue; | ||
2366 | err = sysfs_create_group(&dev->kobj, &it87_group_fan[i]); | ||
2367 | if (err) | ||
2368 | goto error; | ||
2369 | |||
2370 | if (i < 3 && !has_16bit_fans(data)) { | ||
2371 | err = sysfs_create_file(&dev->kobj, | ||
2372 | it87_attributes_fan_div[i]); | ||
2373 | if (err) | ||
2374 | goto error; | ||
2375 | } | ||
2376 | |||
2377 | if (sio_data->beep_pin) { | ||
2378 | err = sysfs_create_file(&dev->kobj, | ||
2379 | it87_attributes_fan_beep[i]); | ||
2380 | if (err) | ||
2381 | goto error; | ||
2382 | if (!fan_beep_need_rw) | ||
2383 | continue; | ||
2384 | |||
2385 | /* | ||
2386 | * As we have a single beep enable bit for all fans, | ||
2387 | * only the first enabled fan has a writable attribute | ||
2388 | * for it. | ||
2389 | */ | ||
2390 | if (sysfs_chmod_file(&dev->kobj, | ||
2391 | it87_attributes_fan_beep[i], | ||
2392 | S_IRUGO | S_IWUSR)) | ||
2393 | dev_dbg(dev, "chmod +w fan%d_beep failed\n", | ||
2394 | i + 1); | ||
2395 | fan_beep_need_rw = 0; | ||
2396 | } | ||
2397 | } | ||
2398 | |||
2399 | if (enable_pwm_interface) { | ||
2400 | for (i = 0; i < 3; i++) { | ||
2401 | if (sio_data->skip_pwm & (1 << i)) | ||
2402 | continue; | ||
2403 | err = sysfs_create_group(&dev->kobj, | ||
2404 | &it87_group_pwm[i]); | ||
2405 | if (err) | ||
2406 | goto error; | ||
2407 | |||
2408 | if (!has_old_autopwm(data)) | ||
2409 | continue; | ||
2410 | err = sysfs_create_group(&dev->kobj, | ||
2411 | &it87_group_autopwm[i]); | ||
2412 | if (err) | ||
2413 | goto error; | ||
2414 | } | ||
2415 | } | ||
2416 | |||
2417 | if (!sio_data->skip_vid) { | ||
2418 | data->vrm = vid_which_vrm(); | ||
2419 | /* VID reading from Super-I/O config space if available */ | ||
2420 | data->vid = sio_data->vid_value; | ||
2421 | err = sysfs_create_group(&dev->kobj, &it87_group_vid); | ||
2422 | if (err) | ||
2423 | goto error; | ||
2424 | } | ||
2425 | |||
2426 | /* Export labels for internal sensors */ | ||
2427 | for (i = 0; i < 4; i++) { | ||
2428 | if (!(sio_data->internal & (1 << i))) | ||
2429 | continue; | ||
2430 | err = sysfs_create_file(&dev->kobj, | ||
2431 | it87_attributes_label[i]); | ||
2432 | if (err) | ||
2433 | goto error; | ||
2434 | } | ||
2435 | |||
2436 | data->hwmon_dev = hwmon_device_register(dev); | ||
2437 | if (IS_ERR(data->hwmon_dev)) { | ||
2438 | err = PTR_ERR(data->hwmon_dev); | ||
2439 | goto error; | ||
2440 | } | ||
2441 | |||
2442 | return 0; | ||
2443 | |||
2444 | error: | ||
2445 | it87_remove_files(dev); | ||
2446 | return err; | ||
2447 | } | ||
2448 | |||
2449 | static int it87_remove(struct platform_device *pdev) | ||
2450 | { | ||
2451 | struct it87_data *data = platform_get_drvdata(pdev); | ||
2452 | |||
2453 | hwmon_device_unregister(data->hwmon_dev); | ||
2454 | it87_remove_files(&pdev->dev); | ||
2455 | |||
2456 | return 0; | ||
2457 | } | ||
2458 | |||
2459 | /* | ||
2460 | * Must be called with data->update_lock held, except during initialization. | ||
2461 | * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | ||
2462 | * would slow down the IT87 access and should not be necessary. | ||
2463 | */ | ||
2464 | static int it87_read_value(struct it87_data *data, u8 reg) | ||
2465 | { | ||
2466 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); | ||
2467 | return inb_p(data->addr + IT87_DATA_REG_OFFSET); | ||
2468 | } | ||
2469 | |||
2470 | /* | ||
2471 | * Must be called with data->update_lock held, except during initialization. | ||
2472 | * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | ||
2473 | * would slow down the IT87 access and should not be necessary. | ||
2474 | */ | ||
2475 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value) | ||
2476 | { | ||
2477 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); | ||
2478 | outb_p(value, data->addr + IT87_DATA_REG_OFFSET); | ||
2479 | } | ||
2480 | |||
2481 | /* Return 1 if and only if the PWM interface is safe to use */ | ||
2482 | static int it87_check_pwm(struct device *dev) | ||
2483 | { | ||
2484 | struct it87_data *data = dev_get_drvdata(dev); | ||
2485 | /* | ||
2486 | * Some BIOSes fail to correctly configure the IT87 fans. All fans off | ||
2487 | * and polarity set to active low is sign that this is the case so we | ||
2488 | * disable pwm control to protect the user. | ||
2489 | */ | ||
2490 | int tmp = it87_read_value(data, IT87_REG_FAN_CTL); | ||
2491 | if ((tmp & 0x87) == 0) { | ||
2492 | if (fix_pwm_polarity) { | ||
2493 | /* | ||
2494 | * The user asks us to attempt a chip reconfiguration. | ||
2495 | * This means switching to active high polarity and | ||
2496 | * inverting all fan speed values. | ||
2497 | */ | ||
2498 | int i; | ||
2499 | u8 pwm[3]; | ||
2500 | |||
2501 | for (i = 0; i < 3; i++) | ||
2502 | pwm[i] = it87_read_value(data, | ||
2503 | IT87_REG_PWM(i)); | ||
2504 | |||
2505 | /* | ||
2506 | * If any fan is in automatic pwm mode, the polarity | ||
2507 | * might be correct, as suspicious as it seems, so we | ||
2508 | * better don't change anything (but still disable the | ||
2509 | * PWM interface). | ||
2510 | */ | ||
2511 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { | ||
2512 | dev_info(dev, | ||
2513 | "Reconfiguring PWM to active high polarity\n"); | ||
2514 | it87_write_value(data, IT87_REG_FAN_CTL, | ||
2515 | tmp | 0x87); | ||
2516 | for (i = 0; i < 3; i++) | ||
2517 | it87_write_value(data, | ||
2518 | IT87_REG_PWM(i), | ||
2519 | 0x7f & ~pwm[i]); | ||
2520 | return 1; | ||
2521 | } | ||
2522 | |||
2523 | dev_info(dev, | ||
2524 | "PWM configuration is too broken to be fixed\n"); | ||
2525 | } | ||
2526 | |||
2527 | dev_info(dev, | ||
2528 | "Detected broken BIOS defaults, disabling PWM interface\n"); | ||
2529 | return 0; | ||
2530 | } else if (fix_pwm_polarity) { | ||
2531 | dev_info(dev, | ||
2532 | "PWM configuration looks sane, won't touch\n"); | ||
2533 | } | ||
2534 | |||
2535 | return 1; | ||
2536 | } | ||
2537 | |||
2538 | /* Called when we have found a new IT87. */ | 2734 | /* Called when we have found a new IT87. */ |
2539 | static void it87_init_device(struct platform_device *pdev) | 2735 | static void it87_init_device(struct platform_device *pdev) |
2540 | { | 2736 | { |
@@ -2556,7 +2752,7 @@ static void it87_init_device(struct platform_device *pdev) | |||
2556 | * these have separate registers for the temperature mapping and the | 2752 | * these have separate registers for the temperature mapping and the |
2557 | * manual duty cycle. | 2753 | * manual duty cycle. |
2558 | */ | 2754 | */ |
2559 | for (i = 0; i < 3; i++) { | 2755 | for (i = 0; i < NUM_AUTO_PWM; i++) { |
2560 | data->pwm_temp_map[i] = i; | 2756 | data->pwm_temp_map[i] = i; |
2561 | data->pwm_duty[i] = 0x7f; /* Full speed */ | 2757 | data->pwm_duty[i] = 0x7f; /* Full speed */ |
2562 | data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */ | 2758 | data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */ |
@@ -2569,12 +2765,12 @@ static void it87_init_device(struct platform_device *pdev) | |||
2569 | * means -1 degree C, which surprisingly doesn't trigger an alarm, | 2765 | * means -1 degree C, which surprisingly doesn't trigger an alarm, |
2570 | * but is still confusing, so change to 127 degrees C. | 2766 | * but is still confusing, so change to 127 degrees C. |
2571 | */ | 2767 | */ |
2572 | for (i = 0; i < 8; i++) { | 2768 | for (i = 0; i < NUM_VIN_LIMIT; i++) { |
2573 | tmp = it87_read_value(data, IT87_REG_VIN_MIN(i)); | 2769 | tmp = it87_read_value(data, IT87_REG_VIN_MIN(i)); |
2574 | if (tmp == 0xff) | 2770 | if (tmp == 0xff) |
2575 | it87_write_value(data, IT87_REG_VIN_MIN(i), 0); | 2771 | it87_write_value(data, IT87_REG_VIN_MIN(i), 0); |
2576 | } | 2772 | } |
2577 | for (i = 0; i < 3; i++) { | 2773 | for (i = 0; i < NUM_TEMP_LIMIT; i++) { |
2578 | tmp = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); | 2774 | tmp = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); |
2579 | if (tmp == 0xff) | 2775 | if (tmp == 0xff) |
2580 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); | 2776 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); |
@@ -2619,158 +2815,245 @@ static void it87_init_device(struct platform_device *pdev) | |||
2619 | 2815 | ||
2620 | /* Check for additional fans */ | 2816 | /* Check for additional fans */ |
2621 | if (has_five_fans(data)) { | 2817 | if (has_five_fans(data)) { |
2622 | if (tmp & (1 << 4)) | 2818 | if (tmp & BIT(4)) |
2623 | data->has_fan |= (1 << 3); /* fan4 enabled */ | 2819 | data->has_fan |= BIT(3); /* fan4 enabled */ |
2624 | if (tmp & (1 << 5)) | 2820 | if (tmp & BIT(5)) |
2625 | data->has_fan |= (1 << 4); /* fan5 enabled */ | 2821 | data->has_fan |= BIT(4); /* fan5 enabled */ |
2626 | if (has_six_fans(data) && (tmp & (1 << 2))) | 2822 | if (has_six_fans(data) && (tmp & BIT(2))) |
2627 | data->has_fan |= (1 << 5); /* fan6 enabled */ | 2823 | data->has_fan |= BIT(5); /* fan6 enabled */ |
2628 | } | 2824 | } |
2629 | 2825 | ||
2630 | /* Fan input pins may be used for alternative functions */ | 2826 | /* Fan input pins may be used for alternative functions */ |
2631 | data->has_fan &= ~sio_data->skip_fan; | 2827 | data->has_fan &= ~sio_data->skip_fan; |
2632 | 2828 | ||
2829 | /* Check if pwm5, pwm6 are enabled */ | ||
2830 | if (has_six_pwm(data)) { | ||
2831 | /* The following code may be IT8620E specific */ | ||
2832 | tmp = it87_read_value(data, IT87_REG_FAN_DIV); | ||
2833 | if ((tmp & 0xc0) == 0xc0) | ||
2834 | sio_data->skip_pwm |= BIT(4); | ||
2835 | if (!(tmp & BIT(3))) | ||
2836 | sio_data->skip_pwm |= BIT(5); | ||
2837 | } | ||
2838 | |||
2633 | /* Start monitoring */ | 2839 | /* Start monitoring */ |
2634 | it87_write_value(data, IT87_REG_CONFIG, | 2840 | it87_write_value(data, IT87_REG_CONFIG, |
2635 | (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) | 2841 | (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) |
2636 | | (update_vbat ? 0x41 : 0x01)); | 2842 | | (update_vbat ? 0x41 : 0x01)); |
2637 | } | 2843 | } |
2638 | 2844 | ||
2639 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2845 | /* Return 1 if and only if the PWM interface is safe to use */ |
2846 | static int it87_check_pwm(struct device *dev) | ||
2640 | { | 2847 | { |
2641 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); | 2848 | struct it87_data *data = dev_get_drvdata(dev); |
2642 | if (has_newer_autopwm(data)) { | 2849 | /* |
2643 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | 2850 | * Some BIOSes fail to correctly configure the IT87 fans. All fans off |
2644 | data->pwm_duty[nr] = it87_read_value(data, | 2851 | * and polarity set to active low is sign that this is the case so we |
2645 | IT87_REG_PWM_DUTY(nr)); | 2852 | * disable pwm control to protect the user. |
2646 | } else { | 2853 | */ |
2647 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | 2854 | int tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
2648 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
2649 | else /* Manual mode */ | ||
2650 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | ||
2651 | } | ||
2652 | 2855 | ||
2653 | if (has_old_autopwm(data)) { | 2856 | if ((tmp & 0x87) == 0) { |
2654 | int i; | 2857 | if (fix_pwm_polarity) { |
2858 | /* | ||
2859 | * The user asks us to attempt a chip reconfiguration. | ||
2860 | * This means switching to active high polarity and | ||
2861 | * inverting all fan speed values. | ||
2862 | */ | ||
2863 | int i; | ||
2864 | u8 pwm[3]; | ||
2655 | 2865 | ||
2656 | for (i = 0; i < 5 ; i++) | 2866 | for (i = 0; i < ARRAY_SIZE(pwm); i++) |
2657 | data->auto_temp[nr][i] = it87_read_value(data, | 2867 | pwm[i] = it87_read_value(data, |
2658 | IT87_REG_AUTO_TEMP(nr, i)); | 2868 | IT87_REG_PWM[i]); |
2659 | for (i = 0; i < 3 ; i++) | 2869 | |
2660 | data->auto_pwm[nr][i] = it87_read_value(data, | 2870 | /* |
2661 | IT87_REG_AUTO_PWM(nr, i)); | 2871 | * If any fan is in automatic pwm mode, the polarity |
2872 | * might be correct, as suspicious as it seems, so we | ||
2873 | * better don't change anything (but still disable the | ||
2874 | * PWM interface). | ||
2875 | */ | ||
2876 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { | ||
2877 | dev_info(dev, | ||
2878 | "Reconfiguring PWM to active high polarity\n"); | ||
2879 | it87_write_value(data, IT87_REG_FAN_CTL, | ||
2880 | tmp | 0x87); | ||
2881 | for (i = 0; i < 3; i++) | ||
2882 | it87_write_value(data, | ||
2883 | IT87_REG_PWM[i], | ||
2884 | 0x7f & ~pwm[i]); | ||
2885 | return 1; | ||
2886 | } | ||
2887 | |||
2888 | dev_info(dev, | ||
2889 | "PWM configuration is too broken to be fixed\n"); | ||
2890 | } | ||
2891 | |||
2892 | dev_info(dev, | ||
2893 | "Detected broken BIOS defaults, disabling PWM interface\n"); | ||
2894 | return 0; | ||
2895 | } else if (fix_pwm_polarity) { | ||
2896 | dev_info(dev, | ||
2897 | "PWM configuration looks sane, won't touch\n"); | ||
2662 | } | 2898 | } |
2899 | |||
2900 | return 1; | ||
2663 | } | 2901 | } |
2664 | 2902 | ||
2665 | static struct it87_data *it87_update_device(struct device *dev) | 2903 | static int it87_probe(struct platform_device *pdev) |
2666 | { | 2904 | { |
2667 | struct it87_data *data = dev_get_drvdata(dev); | 2905 | struct it87_data *data; |
2668 | int i; | 2906 | struct resource *res; |
2907 | struct device *dev = &pdev->dev; | ||
2908 | struct it87_sio_data *sio_data = dev_get_platdata(dev); | ||
2909 | int enable_pwm_interface; | ||
2910 | struct device *hwmon_dev; | ||
2669 | 2911 | ||
2670 | mutex_lock(&data->update_lock); | 2912 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
2913 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, | ||
2914 | DRVNAME)) { | ||
2915 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
2916 | (unsigned long)res->start, | ||
2917 | (unsigned long)(res->start + IT87_EC_EXTENT - 1)); | ||
2918 | return -EBUSY; | ||
2919 | } | ||
2671 | 2920 | ||
2672 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 2921 | data = devm_kzalloc(&pdev->dev, sizeof(struct it87_data), GFP_KERNEL); |
2673 | || !data->valid) { | 2922 | if (!data) |
2674 | if (update_vbat) { | 2923 | return -ENOMEM; |
2675 | /* | 2924 | |
2676 | * Cleared after each update, so reenable. Value | 2925 | data->addr = res->start; |
2677 | * returned by this read will be previous value | 2926 | data->type = sio_data->type; |
2678 | */ | 2927 | data->features = it87_devices[sio_data->type].features; |
2679 | it87_write_value(data, IT87_REG_CONFIG, | 2928 | data->peci_mask = it87_devices[sio_data->type].peci_mask; |
2680 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); | 2929 | data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask; |
2930 | /* | ||
2931 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
2932 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
2933 | * These are the first revisions with 16-bit tachometer support. | ||
2934 | */ | ||
2935 | switch (data->type) { | ||
2936 | case it87: | ||
2937 | if (sio_data->revision >= 0x03) { | ||
2938 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
2939 | data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS; | ||
2681 | } | 2940 | } |
2682 | for (i = 0; i <= 7; i++) { | 2941 | break; |
2683 | data->in[i][0] = | 2942 | case it8712: |
2684 | it87_read_value(data, IT87_REG_VIN(i)); | 2943 | if (sio_data->revision >= 0x08) { |
2685 | data->in[i][1] = | 2944 | data->features &= ~FEAT_OLD_AUTOPWM; |
2686 | it87_read_value(data, IT87_REG_VIN_MIN(i)); | 2945 | data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS | |
2687 | data->in[i][2] = | 2946 | FEAT_FIVE_FANS; |
2688 | it87_read_value(data, IT87_REG_VIN_MAX(i)); | ||
2689 | } | 2947 | } |
2690 | /* in8 (battery) has no limit registers */ | 2948 | break; |
2691 | data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8)); | 2949 | default: |
2692 | if (data->type == it8603) | 2950 | break; |
2693 | data->in[9][0] = it87_read_value(data, 0x2f); | 2951 | } |
2694 | 2952 | ||
2695 | for (i = 0; i < 6; i++) { | 2953 | /* Now, we do the remaining detection. */ |
2696 | /* Skip disabled fans */ | 2954 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) || |
2697 | if (!(data->has_fan & (1 << i))) | 2955 | it87_read_value(data, IT87_REG_CHIPID) != 0x90) |
2698 | continue; | 2956 | return -ENODEV; |
2699 | 2957 | ||
2700 | data->fan[i][1] = | 2958 | platform_set_drvdata(pdev, data); |
2701 | it87_read_value(data, IT87_REG_FAN_MIN[i]); | ||
2702 | data->fan[i][0] = it87_read_value(data, | ||
2703 | IT87_REG_FAN[i]); | ||
2704 | /* Add high byte if in 16-bit mode */ | ||
2705 | if (has_16bit_fans(data)) { | ||
2706 | data->fan[i][0] |= it87_read_value(data, | ||
2707 | IT87_REG_FANX[i]) << 8; | ||
2708 | data->fan[i][1] |= it87_read_value(data, | ||
2709 | IT87_REG_FANX_MIN[i]) << 8; | ||
2710 | } | ||
2711 | } | ||
2712 | for (i = 0; i < 3; i++) { | ||
2713 | if (!(data->has_temp & (1 << i))) | ||
2714 | continue; | ||
2715 | data->temp[i][0] = | ||
2716 | it87_read_value(data, IT87_REG_TEMP(i)); | ||
2717 | data->temp[i][1] = | ||
2718 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); | ||
2719 | data->temp[i][2] = | ||
2720 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); | ||
2721 | if (has_temp_offset(data)) | ||
2722 | data->temp[i][3] = | ||
2723 | it87_read_value(data, | ||
2724 | IT87_REG_TEMP_OFFSET[i]); | ||
2725 | } | ||
2726 | 2959 | ||
2727 | /* Newer chips don't have clock dividers */ | 2960 | mutex_init(&data->update_lock); |
2728 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { | ||
2729 | i = it87_read_value(data, IT87_REG_FAN_DIV); | ||
2730 | data->fan_div[0] = i & 0x07; | ||
2731 | data->fan_div[1] = (i >> 3) & 0x07; | ||
2732 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | ||
2733 | } | ||
2734 | 2961 | ||
2735 | data->alarms = | 2962 | /* Check PWM configuration */ |
2736 | it87_read_value(data, IT87_REG_ALARM1) | | 2963 | enable_pwm_interface = it87_check_pwm(dev); |
2737 | (it87_read_value(data, IT87_REG_ALARM2) << 8) | | ||
2738 | (it87_read_value(data, IT87_REG_ALARM3) << 16); | ||
2739 | data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE); | ||
2740 | 2964 | ||
2741 | data->fan_main_ctrl = it87_read_value(data, | 2965 | /* Starting with IT8721F, we handle scaling of internal voltages */ |
2742 | IT87_REG_FAN_MAIN_CTRL); | 2966 | if (has_12mv_adc(data)) { |
2743 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | 2967 | if (sio_data->internal & BIT(0)) |
2744 | for (i = 0; i < 3; i++) | 2968 | data->in_scaled |= BIT(3); /* in3 is AVCC */ |
2745 | it87_update_pwm_ctrl(data, i); | 2969 | if (sio_data->internal & BIT(1)) |
2970 | data->in_scaled |= BIT(7); /* in7 is VSB */ | ||
2971 | if (sio_data->internal & BIT(2)) | ||
2972 | data->in_scaled |= BIT(8); /* in8 is Vbat */ | ||
2973 | if (sio_data->internal & BIT(3)) | ||
2974 | data->in_scaled |= BIT(9); /* in9 is AVCC */ | ||
2975 | } else if (sio_data->type == it8781 || sio_data->type == it8782 || | ||
2976 | sio_data->type == it8783) { | ||
2977 | if (sio_data->internal & BIT(0)) | ||
2978 | data->in_scaled |= BIT(3); /* in3 is VCC5V */ | ||
2979 | if (sio_data->internal & BIT(1)) | ||
2980 | data->in_scaled |= BIT(7); /* in7 is VCCH5V */ | ||
2981 | } | ||
2746 | 2982 | ||
2747 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 2983 | data->has_temp = 0x07; |
2748 | data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); | 2984 | if (sio_data->skip_temp & BIT(2)) { |
2749 | /* | 2985 | if (sio_data->type == it8782 && |
2750 | * The IT8705F does not have VID capability. | 2986 | !(it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x80)) |
2751 | * The IT8718F and later don't use IT87_REG_VID for the | 2987 | data->has_temp &= ~BIT(2); |
2752 | * same purpose. | ||
2753 | */ | ||
2754 | if (data->type == it8712 || data->type == it8716) { | ||
2755 | data->vid = it87_read_value(data, IT87_REG_VID); | ||
2756 | /* | ||
2757 | * The older IT8712F revisions had only 5 VID pins, | ||
2758 | * but we assume it is always safe to read 6 bits. | ||
2759 | */ | ||
2760 | data->vid &= 0x3f; | ||
2761 | } | ||
2762 | data->last_updated = jiffies; | ||
2763 | data->valid = 1; | ||
2764 | } | 2988 | } |
2765 | 2989 | ||
2766 | mutex_unlock(&data->update_lock); | 2990 | data->in_internal = sio_data->internal; |
2991 | data->has_in = 0x3ff & ~sio_data->skip_in; | ||
2992 | |||
2993 | if (has_six_temp(data)) { | ||
2994 | u8 reg = it87_read_value(data, IT87_REG_TEMP456_ENABLE); | ||
2995 | |||
2996 | /* Check for additional temperature sensors */ | ||
2997 | if ((reg & 0x03) >= 0x02) | ||
2998 | data->has_temp |= BIT(3); | ||
2999 | if (((reg >> 2) & 0x03) >= 0x02) | ||
3000 | data->has_temp |= BIT(4); | ||
3001 | if (((reg >> 4) & 0x03) >= 0x02) | ||
3002 | data->has_temp |= BIT(5); | ||
3003 | |||
3004 | /* Check for additional voltage sensors */ | ||
3005 | if ((reg & 0x03) == 0x01) | ||
3006 | data->has_in |= BIT(10); | ||
3007 | if (((reg >> 2) & 0x03) == 0x01) | ||
3008 | data->has_in |= BIT(11); | ||
3009 | if (((reg >> 4) & 0x03) == 0x01) | ||
3010 | data->has_in |= BIT(12); | ||
3011 | } | ||
2767 | 3012 | ||
2768 | return data; | 3013 | data->has_beep = !!sio_data->beep_pin; |
3014 | |||
3015 | /* Initialize the IT87 chip */ | ||
3016 | it87_init_device(pdev); | ||
3017 | |||
3018 | if (!sio_data->skip_vid) { | ||
3019 | data->has_vid = true; | ||
3020 | data->vrm = vid_which_vrm(); | ||
3021 | /* VID reading from Super-I/O config space if available */ | ||
3022 | data->vid = sio_data->vid_value; | ||
3023 | } | ||
3024 | |||
3025 | /* Prepare for sysfs hooks */ | ||
3026 | data->groups[0] = &it87_group; | ||
3027 | data->groups[1] = &it87_group_in; | ||
3028 | data->groups[2] = &it87_group_temp; | ||
3029 | data->groups[3] = &it87_group_fan; | ||
3030 | |||
3031 | if (enable_pwm_interface) { | ||
3032 | data->has_pwm = BIT(ARRAY_SIZE(IT87_REG_PWM)) - 1; | ||
3033 | data->has_pwm &= ~sio_data->skip_pwm; | ||
3034 | |||
3035 | data->groups[4] = &it87_group_pwm; | ||
3036 | if (has_old_autopwm(data) || has_newer_autopwm(data)) | ||
3037 | data->groups[5] = &it87_group_auto_pwm; | ||
3038 | } | ||
3039 | |||
3040 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, | ||
3041 | it87_devices[sio_data->type].name, | ||
3042 | data, data->groups); | ||
3043 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
2769 | } | 3044 | } |
2770 | 3045 | ||
2771 | static int __init it87_device_add(unsigned short address, | 3046 | static struct platform_driver it87_driver = { |
3047 | .driver = { | ||
3048 | .name = DRVNAME, | ||
3049 | }, | ||
3050 | .probe = it87_probe, | ||
3051 | }; | ||
3052 | |||
3053 | static int __init it87_device_add(int index, unsigned short address, | ||
2772 | const struct it87_sio_data *sio_data) | 3054 | const struct it87_sio_data *sio_data) |
2773 | { | 3055 | { |
3056 | struct platform_device *pdev; | ||
2774 | struct resource res = { | 3057 | struct resource res = { |
2775 | .start = address + IT87_EC_OFFSET, | 3058 | .start = address + IT87_EC_OFFSET, |
2776 | .end = address + IT87_EC_OFFSET + IT87_EC_EXTENT - 1, | 3059 | .end = address + IT87_EC_OFFSET + IT87_EC_EXTENT - 1, |
@@ -2781,14 +3064,11 @@ static int __init it87_device_add(unsigned short address, | |||
2781 | 3064 | ||
2782 | err = acpi_check_resource_conflict(&res); | 3065 | err = acpi_check_resource_conflict(&res); |
2783 | if (err) | 3066 | if (err) |
2784 | goto exit; | 3067 | return err; |
2785 | 3068 | ||
2786 | pdev = platform_device_alloc(DRVNAME, address); | 3069 | pdev = platform_device_alloc(DRVNAME, address); |
2787 | if (!pdev) { | 3070 | if (!pdev) |
2788 | err = -ENOMEM; | 3071 | return -ENOMEM; |
2789 | pr_err("Device allocation failed\n"); | ||
2790 | goto exit; | ||
2791 | } | ||
2792 | 3072 | ||
2793 | err = platform_device_add_resources(pdev, &res, 1); | 3073 | err = platform_device_add_resources(pdev, &res, 1); |
2794 | if (err) { | 3074 | if (err) { |
@@ -2809,44 +3089,61 @@ static int __init it87_device_add(unsigned short address, | |||
2809 | goto exit_device_put; | 3089 | goto exit_device_put; |
2810 | } | 3090 | } |
2811 | 3091 | ||
3092 | it87_pdev[index] = pdev; | ||
2812 | return 0; | 3093 | return 0; |
2813 | 3094 | ||
2814 | exit_device_put: | 3095 | exit_device_put: |
2815 | platform_device_put(pdev); | 3096 | platform_device_put(pdev); |
2816 | exit: | ||
2817 | return err; | 3097 | return err; |
2818 | } | 3098 | } |
2819 | 3099 | ||
2820 | static int __init sm_it87_init(void) | 3100 | static int __init sm_it87_init(void) |
2821 | { | 3101 | { |
2822 | int err; | 3102 | int sioaddr[2] = { REG_2E, REG_4E }; |
2823 | unsigned short isa_address = 0; | ||
2824 | struct it87_sio_data sio_data; | 3103 | struct it87_sio_data sio_data; |
3104 | unsigned short isa_address; | ||
3105 | bool found = false; | ||
3106 | int i, err; | ||
2825 | 3107 | ||
2826 | memset(&sio_data, 0, sizeof(struct it87_sio_data)); | ||
2827 | err = it87_find(&isa_address, &sio_data); | ||
2828 | if (err) | ||
2829 | return err; | ||
2830 | err = platform_driver_register(&it87_driver); | 3108 | err = platform_driver_register(&it87_driver); |
2831 | if (err) | 3109 | if (err) |
2832 | return err; | 3110 | return err; |
2833 | 3111 | ||
2834 | err = it87_device_add(isa_address, &sio_data); | 3112 | for (i = 0; i < ARRAY_SIZE(sioaddr); i++) { |
2835 | if (err) { | 3113 | memset(&sio_data, 0, sizeof(struct it87_sio_data)); |
2836 | platform_driver_unregister(&it87_driver); | 3114 | isa_address = 0; |
2837 | return err; | 3115 | err = it87_find(sioaddr[i], &isa_address, &sio_data); |
3116 | if (err || isa_address == 0) | ||
3117 | continue; | ||
3118 | |||
3119 | err = it87_device_add(i, isa_address, &sio_data); | ||
3120 | if (err) | ||
3121 | goto exit_dev_unregister; | ||
3122 | found = true; | ||
2838 | } | 3123 | } |
2839 | 3124 | ||
3125 | if (!found) { | ||
3126 | err = -ENODEV; | ||
3127 | goto exit_unregister; | ||
3128 | } | ||
2840 | return 0; | 3129 | return 0; |
3130 | |||
3131 | exit_dev_unregister: | ||
3132 | /* NULL check handled by platform_device_unregister */ | ||
3133 | platform_device_unregister(it87_pdev[0]); | ||
3134 | exit_unregister: | ||
3135 | platform_driver_unregister(&it87_driver); | ||
3136 | return err; | ||
2841 | } | 3137 | } |
2842 | 3138 | ||
2843 | static void __exit sm_it87_exit(void) | 3139 | static void __exit sm_it87_exit(void) |
2844 | { | 3140 | { |
2845 | platform_device_unregister(pdev); | 3141 | /* NULL check handled by platform_device_unregister */ |
3142 | platform_device_unregister(it87_pdev[1]); | ||
3143 | platform_device_unregister(it87_pdev[0]); | ||
2846 | platform_driver_unregister(&it87_driver); | 3144 | platform_driver_unregister(&it87_driver); |
2847 | } | 3145 | } |
2848 | 3146 | ||
2849 | |||
2850 | MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>"); | 3147 | MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>"); |
2851 | MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver"); | 3148 | MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver"); |
2852 | module_param(update_vbat, bool, 0); | 3149 | module_param(update_vbat, bool, 0); |
diff --git a/drivers/hwmon/max31722.c b/drivers/hwmon/max31722.c new file mode 100644 index 000000000000..30a100e70a0d --- /dev/null +++ b/drivers/hwmon/max31722.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * max31722 - hwmon driver for Maxim Integrated MAX31722/MAX31723 SPI | ||
3 | * digital thermometer and thermostats. | ||
4 | * | ||
5 | * Copyright (c) 2016, Intel Corporation. | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of version 2 of | ||
8 | * the GNU General Public License. See the file COPYING in the main | ||
9 | * directory of this archive for more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/acpi.h> | ||
13 | #include <linux/hwmon.h> | ||
14 | #include <linux/hwmon-sysfs.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/spi/spi.h> | ||
18 | |||
19 | #define MAX31722_REG_CFG 0x00 | ||
20 | #define MAX31722_REG_TEMP_LSB 0x01 | ||
21 | |||
22 | #define MAX31722_MODE_CONTINUOUS 0x00 | ||
23 | #define MAX31722_MODE_STANDBY 0x01 | ||
24 | #define MAX31722_MODE_MASK 0xFE | ||
25 | #define MAX31722_RESOLUTION_12BIT 0x06 | ||
26 | #define MAX31722_WRITE_MASK 0x80 | ||
27 | |||
28 | struct max31722_data { | ||
29 | struct device *hwmon_dev; | ||
30 | struct spi_device *spi_device; | ||
31 | u8 mode; | ||
32 | }; | ||
33 | |||
34 | static int max31722_set_mode(struct max31722_data *data, u8 mode) | ||
35 | { | ||
36 | int ret; | ||
37 | struct spi_device *spi = data->spi_device; | ||
38 | u8 buf[2] = { | ||
39 | MAX31722_REG_CFG | MAX31722_WRITE_MASK, | ||
40 | (data->mode & MAX31722_MODE_MASK) | mode | ||
41 | }; | ||
42 | |||
43 | ret = spi_write(spi, &buf, sizeof(buf)); | ||
44 | if (ret < 0) { | ||
45 | dev_err(&spi->dev, "failed to set sensor mode.\n"); | ||
46 | return ret; | ||
47 | } | ||
48 | data->mode = (data->mode & MAX31722_MODE_MASK) | mode; | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static ssize_t max31722_show_temp(struct device *dev, | ||
54 | struct device_attribute *attr, | ||
55 | char *buf) | ||
56 | { | ||
57 | ssize_t ret; | ||
58 | struct max31722_data *data = dev_get_drvdata(dev); | ||
59 | |||
60 | ret = spi_w8r16(data->spi_device, MAX31722_REG_TEMP_LSB); | ||
61 | if (ret < 0) | ||
62 | return ret; | ||
63 | /* Keep 12 bits and multiply by the scale of 62.5 millidegrees/bit. */ | ||
64 | return sprintf(buf, "%d\n", (s16)le16_to_cpu(ret) * 125 / 32); | ||
65 | } | ||
66 | |||
67 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
68 | max31722_show_temp, NULL, 0); | ||
69 | |||
70 | static struct attribute *max31722_attrs[] = { | ||
71 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
72 | NULL, | ||
73 | }; | ||
74 | |||
75 | ATTRIBUTE_GROUPS(max31722); | ||
76 | |||
77 | static int max31722_probe(struct spi_device *spi) | ||
78 | { | ||
79 | int ret; | ||
80 | struct max31722_data *data; | ||
81 | |||
82 | data = devm_kzalloc(&spi->dev, sizeof(*data), GFP_KERNEL); | ||
83 | if (!data) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | spi_set_drvdata(spi, data); | ||
87 | data->spi_device = spi; | ||
88 | /* | ||
89 | * Set SD bit to 0 so we can have continuous measurements. | ||
90 | * Set resolution to 12 bits for maximum precision. | ||
91 | */ | ||
92 | data->mode = MAX31722_MODE_CONTINUOUS | MAX31722_RESOLUTION_12BIT; | ||
93 | ret = max31722_set_mode(data, MAX31722_MODE_CONTINUOUS); | ||
94 | if (ret < 0) | ||
95 | return ret; | ||
96 | |||
97 | data->hwmon_dev = hwmon_device_register_with_groups(&spi->dev, | ||
98 | spi->modalias, | ||
99 | data, | ||
100 | max31722_groups); | ||
101 | if (IS_ERR(data->hwmon_dev)) { | ||
102 | max31722_set_mode(data, MAX31722_MODE_STANDBY); | ||
103 | return PTR_ERR(data->hwmon_dev); | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int max31722_remove(struct spi_device *spi) | ||
110 | { | ||
111 | struct max31722_data *data = spi_get_drvdata(spi); | ||
112 | |||
113 | hwmon_device_unregister(data->hwmon_dev); | ||
114 | |||
115 | return max31722_set_mode(data, MAX31722_MODE_STANDBY); | ||
116 | } | ||
117 | |||
118 | static int __maybe_unused max31722_suspend(struct device *dev) | ||
119 | { | ||
120 | struct spi_device *spi_device = to_spi_device(dev); | ||
121 | struct max31722_data *data = spi_get_drvdata(spi_device); | ||
122 | |||
123 | return max31722_set_mode(data, MAX31722_MODE_STANDBY); | ||
124 | } | ||
125 | |||
126 | static int __maybe_unused max31722_resume(struct device *dev) | ||
127 | { | ||
128 | struct spi_device *spi_device = to_spi_device(dev); | ||
129 | struct max31722_data *data = spi_get_drvdata(spi_device); | ||
130 | |||
131 | return max31722_set_mode(data, MAX31722_MODE_CONTINUOUS); | ||
132 | } | ||
133 | |||
134 | static SIMPLE_DEV_PM_OPS(max31722_pm_ops, max31722_suspend, max31722_resume); | ||
135 | |||
136 | static const struct spi_device_id max31722_spi_id[] = { | ||
137 | {"max31722", 0}, | ||
138 | {"max31723", 0}, | ||
139 | {} | ||
140 | }; | ||
141 | |||
142 | static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = { | ||
143 | {"MAX31722", 0}, | ||
144 | {"MAX31723", 0}, | ||
145 | {} | ||
146 | }; | ||
147 | |||
148 | MODULE_DEVICE_TABLE(spi, max31722_spi_id); | ||
149 | |||
150 | static struct spi_driver max31722_driver = { | ||
151 | .driver = { | ||
152 | .name = "max31722", | ||
153 | .pm = &max31722_pm_ops, | ||
154 | .acpi_match_table = ACPI_PTR(max31722_acpi_id), | ||
155 | }, | ||
156 | .probe = max31722_probe, | ||
157 | .remove = max31722_remove, | ||
158 | .id_table = max31722_spi_id, | ||
159 | }; | ||
160 | |||
161 | module_spi_driver(max31722_driver); | ||
162 | |||
163 | MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); | ||
164 | MODULE_DESCRIPTION("max31722 sensor driver"); | ||
165 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 131a2815dbda..d24d7b6047f2 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c | |||
@@ -449,7 +449,7 @@ static int sch5636_probe(struct platform_device *pdev) | |||
449 | } | 449 | } |
450 | revision[i] = val; | 450 | revision[i] = val; |
451 | } | 451 | } |
452 | pr_info("Found %s chip at %#hx, revison: %d.%02d\n", DEVNAME, | 452 | pr_info("Found %s chip at %#hx, revision: %d.%02d\n", DEVNAME, |
453 | data->addr, revision[0], revision[1]); | 453 | data->addr, revision[0], revision[1]); |
454 | 454 | ||
455 | /* Read all temp + fan ctrl registers to determine which are active */ | 455 | /* Read all temp + fan ctrl registers to determine which are active */ |