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