Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
hwmon: Add MAINTAINERS entry for new ams driver
hwmon: New AMS hardware monitoring driver
hwmon/w83793: Add documentation and maintainer
hwmon: New Winbond W83793 hardware monitoring driver
hwmon: Update Rudolf Marek's e-mail address
hwmon/f71805f: Fix the device address decoding
hwmon/f71805f: Always create all fan inputs
hwmon/f71805f: Add support for the Fintek F71872F/FG chip
hwmon: New PC87427 hardware monitoring driver
hwmon/it87: Remove the SMBus interface support
hwmon/hdaps: Update the list of supported devices
hwmon/hdaps: Move the DMI detection data to .data
hwmon/pc87360: Autodetect the VRM version
hwmon/f71805f: Document the fan control features
hwmon/f71805f: Add support for "speed mode" fan speed control
hwmon/f71805f: Support DC fan speed control mode
hwmon/f71805f: Let the user adjust the PWM base frequency
hwmon/f71805f: Add manual fan speed control
hwmon/f71805f: Store the fan control registers

+4115 -300
-9
Documentation/feature-removal-schedule.txt
··· 151 152 --------------------------- 153 154 - What: I2C interface of the it87 driver 155 - When: January 2007 156 - Why: The ISA interface is faster and should be always available. The I2C 157 - probing is also known to cause trouble in at least one case (see 158 - bug #5889.) 159 - Who: Jean Delvare <khali@linux-fr.org> 160 - 161 - --------------------------- 162 - 163 What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports 164 (temporary transition config option provided until then) 165 The transition config option will also be removed at the same time.
··· 151 152 --------------------------- 153 154 What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports 155 (temporary transition config option provided until then) 156 The transition config option will also be removed at the same time.
+51 -5
Documentation/hwmon/f71805f
··· 6 Prefix: 'f71805f' 7 Addresses scanned: none, address read from Super I/O config space 8 Datasheet: Provided by Fintek on request 9 10 Author: Jean Delvare <khali@linux-fr.org> 11 ··· 17 test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and 18 for providing initial documentation. 19 20 - Thanks to Kris Chen from Fintek for answering technical questions and 21 - providing additional documentation. 22 23 Thanks to Chris Lin from Jetway for providing wiring schematics and 24 answering technical questions. ··· 32 source), 3 fans and 3 temperature sensors. 33 34 This chip also has fan controlling features, using either DC or PWM, in 35 - three different modes (one manual, two automatic). The driver doesn't 36 - support these features yet. 37 38 The driver assumes that no more than one chip is present, which seems 39 reasonable. ··· 49 range is thus from 0 to 2.040 V. Voltage values outside of this range 50 need external resistors. An exception is in0, which is used to monitor 51 the chip's own power source (+3.3V), and is divided internally by a 52 - factor 2. 53 54 The two LSB of the voltage limit registers are not used (always 0), so 55 you can only set the limits in steps of 32 mV (before scaling). ··· 69 in6 VIN6 VCC1.5V 10K - 1.00 1.50 V 70 in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1) 71 in8 VIN8 VSB5V 200K 47K 1.00 0.95 V 72 73 (1) Depends on your hardware setup. 74 (2) Obviously not correct, swapping R1 and R2 would make more sense. 75 76 These values can be used as hints at best, as motherboard manufacturers 77 are free to use a completely different setup. As a matter of fact, the ··· 114 or a thermistor. The driver reports the currently selected mode, but 115 doesn't allow changing it. In theory, the BIOS should have configured 116 everything properly.
··· 6 Prefix: 'f71805f' 7 Addresses scanned: none, address read from Super I/O config space 8 Datasheet: Provided by Fintek on request 9 + * Fintek F71872F/FG 10 + Prefix: 'f71872f' 11 + Addresses scanned: none, address read from Super I/O config space 12 + Datasheet: Provided by Fintek on request 13 14 Author: Jean Delvare <khali@linux-fr.org> 15 ··· 13 test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and 14 for providing initial documentation. 15 16 + Thanks to Kris Chen and Aaron Huang from Fintek for answering technical 17 + questions and providing additional documentation. 18 19 Thanks to Chris Lin from Jetway for providing wiring schematics and 20 answering technical questions. ··· 28 source), 3 fans and 3 temperature sensors. 29 30 This chip also has fan controlling features, using either DC or PWM, in 31 + three different modes (one manual, two automatic). 32 + 33 + The Fintek F71872F/FG Super I/O chip is almost the same, with two 34 + additional internal voltages monitored (VSB and battery). It also features 35 + 6 VID inputs. The VID inputs are not yet supported by this driver. 36 37 The driver assumes that no more than one chip is present, which seems 38 reasonable. ··· 42 range is thus from 0 to 2.040 V. Voltage values outside of this range 43 need external resistors. An exception is in0, which is used to monitor 44 the chip's own power source (+3.3V), and is divided internally by a 45 + factor 2. For the F71872F/FG, in9 (VSB) and in10 (battery) are also 46 + divided internally by a factor 2. 47 48 The two LSB of the voltage limit registers are not used (always 0), so 49 you can only set the limits in steps of 32 mV (before scaling). ··· 61 in6 VIN6 VCC1.5V 10K - 1.00 1.50 V 62 in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1) 63 in8 VIN8 VSB5V 200K 47K 1.00 0.95 V 64 + in10 VSB VSB3.3V int. int. 2.00 1.65 V (3) 65 + in9 VBAT VBATTERY int. int. 2.00 1.50 V (3) 66 67 (1) Depends on your hardware setup. 68 (2) Obviously not correct, swapping R1 and R2 would make more sense. 69 + (3) F71872F/FG only. 70 71 These values can be used as hints at best, as motherboard manufacturers 72 are free to use a completely different setup. As a matter of fact, the ··· 103 or a thermistor. The driver reports the currently selected mode, but 104 doesn't allow changing it. In theory, the BIOS should have configured 105 everything properly. 106 + 107 + 108 + Fan Control 109 + ----------- 110 + 111 + Both PWM (pulse-width modulation) and DC fan speed control methods are 112 + supported. The right one to use depends on external circuitry on the 113 + motherboard, so the driver assumes that the BIOS set the method 114 + properly. The driver will report the method, but won't let you change 115 + it. 116 + 117 + When the PWM method is used, you can select the operating frequency, 118 + from 187.5 kHz (default) to 31 Hz. The best frequency depends on the 119 + fan model. As a rule of thumb, lower frequencies seem to give better 120 + control, but may generate annoying high-pitch noise. Fintek recommends 121 + not going below 1 kHz, as the fan tachometers get confused by lower 122 + frequencies as well. 123 + 124 + When the DC method is used, Fintek recommends not going below 5 V, which 125 + corresponds to a pwm value of 106 for the driver. The driver doesn't 126 + enforce this limit though. 127 + 128 + Three different fan control modes are supported: 129 + 130 + * Manual mode 131 + You ask for a specific PWM duty cycle or DC voltage. 132 + 133 + * Fan speed mode 134 + You ask for a specific fan speed. This mode assumes that pwm1 135 + corresponds to fan1, pwm2 to fan2 and pwm3 to fan3. 136 + 137 + * Temperature mode 138 + You define 3 temperature/fan speed trip points, and the fan speed is 139 + adjusted depending on the measured temperature, using interpolation. 140 + This mode is not yet supported by the driver.
+13 -2
Documentation/hwmon/it87
··· 9 http://www.ite.com.tw/ 10 * IT8712F 11 Prefix: 'it8712' 12 - Addresses scanned: I2C 0x2d 13 - from Super I/O config space (8 I/O ports) 14 Datasheet: Publicly available at the ITE website 15 http://www.ite.com.tw/ 16 * IT8716F ··· 51 Force PWM polarity to active high (DANGEROUS). Some chips are 52 misconfigured by BIOS - PWM values would be inverted. This option tries 53 to fix this. Please contact your BIOS manufacturer and ask him for fix. 54 55 Description 56 -----------
··· 9 http://www.ite.com.tw/ 10 * IT8712F 11 Prefix: 'it8712' 12 + Addresses scanned: from Super I/O config space (8 I/O ports) 13 Datasheet: Publicly available at the ITE website 14 http://www.ite.com.tw/ 15 * IT8716F ··· 52 Force PWM polarity to active high (DANGEROUS). Some chips are 53 misconfigured by BIOS - PWM values would be inverted. This option tries 54 to fix this. Please contact your BIOS manufacturer and ask him for fix. 55 + 56 + 57 + Hardware Interfaces 58 + ------------------- 59 + 60 + All the chips suported by this driver are LPC Super-I/O chips, accessed 61 + through the LPC bus (ISA-like I/O ports). The IT8712F additionally has an 62 + SMBus interface to the hardware monitoring functions. This driver no 63 + longer supports this interface though, as it is slower and less reliable 64 + than the ISA access, and was only available on a small number of 65 + motherboard models. 66 + 67 68 Description 69 -----------
+1 -1
Documentation/hwmon/k8temp
··· 8 Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf 9 10 Author: Rudolf Marek 11 - Contact: Rudolf Marek <r.marek@sh.cvut.cz> 12 13 Description 14 -----------
··· 8 Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf 9 10 Author: Rudolf Marek 11 + Contact: Rudolf Marek <r.marek@assembler.cz> 12 13 Description 14 -----------
+38
Documentation/hwmon/pc87427
···
··· 1 + Kernel driver pc87427 2 + ===================== 3 + 4 + Supported chips: 5 + * National Semiconductor PC87427 6 + Prefix: 'pc87427' 7 + Addresses scanned: none, address read from Super I/O config space 8 + Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/apc_007.html 9 + 10 + Author: Jean Delvare <khali@linux-fr.org> 11 + 12 + Thanks to Amir Habibi at Candelis for setting up a test system, and to 13 + Michael Kress for testing several iterations of this driver. 14 + 15 + 16 + Description 17 + ----------- 18 + 19 + The National Semiconductor Super I/O chip includes complete hardware 20 + monitoring capabilities. It can monitor up to 18 voltages, 8 fans and 21 + 6 temperature sensors. Only the fans are supported at the moment. 22 + 23 + This chip also has fan controlling features, which are not yet supported 24 + by this driver either. 25 + 26 + The driver assumes that no more than one chip is present, which seems 27 + reasonable. 28 + 29 + 30 + Fan Monitoring 31 + -------------- 32 + 33 + Fan rotation speeds are reported as 14-bit values from a gated clock 34 + signal. Speeds down to 83 RPM can be measured. 35 + 36 + An alarm is triggered if the rotation speed drops below a programmable 37 + limit. Another alarm is triggered if the speed is too low to to be measured 38 + (including stalled or missing fan).
+3 -1
Documentation/hwmon/sysfs-interface
··· 208 **************** 209 210 temp[1-*]_type Sensor type selection. 211 - Integers 1 to 4 or thermistor Beta value (typically 3435) 212 RW 213 1: PII/Celeron Diode 214 2: 3904 transistor 215 3: thermal diode 216 4: thermistor (default/unknown Beta) 217 Not all types are supported by all chips 218 219 temp[1-*]_max Temperature max value.
··· 208 **************** 209 210 temp[1-*]_type Sensor type selection. 211 + Integers 1 to 6 or thermistor Beta value (typically 3435) 212 RW 213 1: PII/Celeron Diode 214 2: 3904 transistor 215 3: thermal diode 216 4: thermistor (default/unknown Beta) 217 + 5: AMD AMDSI 218 + 6: Intel PECI 219 Not all types are supported by all chips 220 221 temp[1-*]_max Temperature max value.
+1 -1
Documentation/hwmon/w83627ehf
··· 10 Authors: 11 Jean Delvare <khali@linux-fr.org> 12 Yuan Mu (Winbond) 13 - Rudolf Marek <r.marek@sh.cvut.cz> 14 15 Description 16 -----------
··· 10 Authors: 11 Jean Delvare <khali@linux-fr.org> 12 Yuan Mu (Winbond) 13 + Rudolf Marek <r.marek@assembler.cz> 14 15 Description 16 -----------
+1 -1
Documentation/hwmon/w83791d
··· 18 and Mark Studebaker <mdsxyz123@yahoo.com> 19 w83792d.c: 20 Chunhao Huang <DZShen@Winbond.com.tw>, 21 - Rudolf Marek <r.marek@sh.cvut.cz> 22 23 Additional contributors: 24 Sven Anders <anders@anduras.de>
··· 18 and Mark Studebaker <mdsxyz123@yahoo.com> 19 w83792d.c: 20 Chunhao Huang <DZShen@Winbond.com.tw>, 21 + Rudolf Marek <r.marek@assembler.cz> 22 23 Additional contributors: 24 Sven Anders <anders@anduras.de>
+110
Documentation/hwmon/w83793
···
··· 1 + Kernel driver w83793 2 + ==================== 3 + 4 + Supported chips: 5 + * Winbond W83793G/W83793R 6 + Prefix: 'w83793' 7 + Addresses scanned: I2C 0x2c - 0x2f 8 + Datasheet: Still not published 9 + 10 + Authors: 11 + Yuan Mu (Winbond Electronics) 12 + Rudolf Marek <r.marek@assembler.cz> 13 + 14 + 15 + Module parameters 16 + ----------------- 17 + 18 + * reset int 19 + (default 0) 20 + This parameter is not recommended, it will lose motherboard specific 21 + settings. Use 'reset=1' to reset the chip when loading this module. 22 + 23 + * force_subclients=bus,caddr,saddr1,saddr2 24 + This is used to force the i2c addresses for subclients of 25 + a certain chip. Typical usage is `force_subclients=0,0x2f,0x4a,0x4b' 26 + to force the subclients of chip 0x2f on bus 0 to i2c addresses 27 + 0x4a and 0x4b. 28 + 29 + 30 + Description 31 + ----------- 32 + 33 + This driver implements support for Winbond W83793G/W83793R chips. 34 + 35 + * Exported features 36 + This driver exports 10 voltage sensors, up to 12 fan tachometer inputs, 37 + 6 remote temperatures, up to 8 sets of PWM fan controls, SmartFan 38 + (automatic fan speed control) on all temperature/PWM combinations, 2 39 + sets of 6-pin CPU VID input. 40 + 41 + * Sensor resolutions 42 + If your motherboard maker used the reference design, the resolution of 43 + voltage0-2 is 2mV, resolution of voltage3/4/5 is 16mV, 8mV for voltage6, 44 + 24mV for voltage7/8. Temp1-4 have a 0.25 degree Celsius resolution, 45 + temp5-6 have a 1 degree Celsiis resolution. 46 + 47 + * Temperature sensor types 48 + Temp1-4 have 3 possible types. It can be read from (and written to) 49 + temp[1-4]_type. 50 + - If the value of 0, the related temperature channel stops 51 + monitoring. 52 + - If the value is 3, it starts monitoring using a remote termal diode 53 + (default). 54 + - If the value is 5, it starts monitoring using the temperature sensor 55 + in AMD CPU and get result by AMDSI. 56 + - If the value is 6, it starts monitoring using the temperature sensor 57 + in Intel CPU and get result by PECI. 58 + Temp5-6 can be connected to external thermistors (value of 59 + temp[5-6]_type is 4). They can also be disabled (value is 0). 60 + 61 + * Alarm mechanism 62 + For voltage sensors, an alarm triggers if the measured value is below 63 + the low voltage limit or over the high voltage limit. 64 + For temperature sensors, an alarm triggers if the measured value goes 65 + above the high temperature limit, and wears off only after the measured 66 + value drops below the hysteresis value. 67 + For fan sensors, an alarm triggers if the measured value is below the 68 + low speed limit. 69 + 70 + * SmartFan/PWM control 71 + If you want to set a pwm fan to manual mode, you just need to make sure it 72 + is not controlled by any temp channel, for example, you want to set fan1 73 + to manual mode, you need to check the value of temp[1-6]_fan_map, make 74 + sure bit 0 is cleared in the 6 values. And then set the pwm1 value to 75 + control the fan. 76 + 77 + Each temperature channel can control all the 8 PWM outputs (by setting the 78 + corresponding bit in tempX_fan_map), you can set the temperature channel 79 + mode using temp[1-6]_pwm_enable, 2 is Thermal Cruise mode and 3 80 + is the SmartFanII mode. Temperature channels will try to speed up or 81 + slow down all controlled fans, this means one fan can receive different 82 + PWM value requests from different temperature channels, but the chip 83 + will always pick the safest (max) PWM value for each fan. 84 + 85 + In Thermal Cruise mode, the chip attempts to keep the temperature at a 86 + predefined value, within a tolerance margin. So if tempX_input > 87 + thermal_cruiseX + toleranceX, the chip will increase the PWM value, 88 + if tempX_input < thermal_cruiseX - toleranceX, the chip will decrease 89 + the PWM value. If the temperature is within the tolerance range, the PWM 90 + value is left unchanged. 91 + 92 + SmartFanII works differently, you have to define up to 7 PWM, temperature 93 + trip points, defining a PWM/temperature curve which the chip will follow. 94 + While not fundamentally different from the Thermal Cruise mode, the 95 + implementation is quite different, giving you a finer-grained control. 96 + 97 + * Chassis 98 + If the case open alarm triggers, it will stay in this state unless cleared 99 + by any write to the sysfs file "chassis". 100 + 101 + * VID and VRM 102 + The VRM version is detected automatically, don't modify the it unless you 103 + *do* know the cpu VRM version and it's not properly detected. 104 + 105 + 106 + Notes 107 + ----- 108 + 109 + Only Fan1-5 and PWM1-3 are guaranteed to always exist, other fan inputs and 110 + PWM outputs may or may not exist depending on the chip pin configuration.
+14 -1
MAINTAINERS
··· 277 278 ALI1563 I2C DRIVER 279 P: Rudolf Marek 280 - M: r.marek@sh.cvut.cz 281 L: i2c@lm-sensors.org 282 S: Maintained 283 ··· 294 M: info-linux@geode.amd.com 295 L: info-linux@geode.amd.com 296 W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html 297 S: Supported 298 299 AMSO1100 RNIC DRIVER ··· 3440 W83791D HARDWARE MONITORING DRIVER 3441 P: Charles Spirakis 3442 M: bezaur@gmail.com 3443 L: lm-sensors@lm-sensors.org 3444 S: Maintained 3445
··· 277 278 ALI1563 I2C DRIVER 279 P: Rudolf Marek 280 + M: r.marek@assembler.cz 281 L: i2c@lm-sensors.org 282 S: Maintained 283 ··· 294 M: info-linux@geode.amd.com 295 L: info-linux@geode.amd.com 296 W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html 297 + S: Supported 298 + 299 + AMS (Apple Motion Sensor) DRIVER 300 + P: Stelian Pop 301 + M: stelian@popies.net 302 + P: Michael Hanselmann 303 + M: linux-kernel@hansmi.ch 304 S: Supported 305 306 AMSO1100 RNIC DRIVER ··· 3433 W83791D HARDWARE MONITORING DRIVER 3434 P: Charles Spirakis 3435 M: bezaur@gmail.com 3436 + L: lm-sensors@lm-sensors.org 3437 + S: Maintained 3438 + 3439 + W83793 HARDWARE MONITORING DRIVER 3440 + P: Rudolf Marek 3441 + M: r.marek@assembler.cz 3442 L: lm-sensors@lm-sensors.org 3443 S: Maintained 3444
+54 -2
drivers/hwmon/Kconfig
··· 106 This driver can also be built as a module. If so, the module 107 will be called k8temp. 108 109 config SENSORS_ASB100 110 tristate "Asus ASB100 Bach" 111 depends on HWMON && I2C && EXPERIMENTAL ··· 167 will be called ds1621. 168 169 config SENSORS_F71805F 170 - tristate "Fintek F71805F/FG" 171 depends on HWMON && EXPERIMENTAL 172 help 173 If you say yes here you get support for hardware monitoring 174 - features of the Fintek F71805F/FG chips. 175 176 This driver can also be built as a module. If so, the module 177 will be called f71805f. ··· 379 This driver can also be built as a module. If so, the module 380 will be called pc87360. 381 382 config SENSORS_SIS5595 383 tristate "Silicon Integrated Systems Corp. SiS5595" 384 depends on HWMON && I2C && PCI && EXPERIMENTAL ··· 513 This driver can also be built as a module. If so, the module 514 will be called w83792d. 515 516 config SENSORS_W83L785TS 517 tristate "Winbond W83L785TS-S" 518 depends on HWMON && I2C && EXPERIMENTAL ··· 575 576 This driver also provides an absolute input class device, allowing 577 the laptop to act as a pinball machine-esque joystick. 578 579 Say Y here if you have an applicable laptop and want to experience 580 the awesome power of hdaps.
··· 106 This driver can also be built as a module. If so, the module 107 will be called k8temp. 108 109 + config SENSORS_AMS 110 + tristate "Apple Motion Sensor driver" 111 + depends on HWMON && PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL 112 + help 113 + Support for the motion sensor included in PowerBooks. Includes 114 + implementations for PMU and I2C. 115 + 116 + This driver can also be built as a module. If so, the module 117 + will be called ams. 118 + 119 + config SENSORS_AMS_PMU 120 + bool "PMU variant" 121 + depends on SENSORS_AMS && ADB_PMU 122 + default y 123 + help 124 + PMU variant of motion sensor, found in late 2005 PowerBooks. 125 + 126 + config SENSORS_AMS_I2C 127 + bool "I2C variant" 128 + depends on SENSORS_AMS && I2C 129 + default y 130 + help 131 + I2C variant of motion sensor, found in early 2005 PowerBooks and 132 + iBooks. 133 + 134 config SENSORS_ASB100 135 tristate "Asus ASB100 Bach" 136 depends on HWMON && I2C && EXPERIMENTAL ··· 142 will be called ds1621. 143 144 config SENSORS_F71805F 145 + tristate "Fintek F71805F/FG and F71872F/FG" 146 depends on HWMON && EXPERIMENTAL 147 help 148 If you say yes here you get support for hardware monitoring 149 + features of the Fintek F71805F/FG and F71872F/FG Super-I/O 150 + chips. 151 152 This driver can also be built as a module. If so, the module 153 will be called f71805f. ··· 353 This driver can also be built as a module. If so, the module 354 will be called pc87360. 355 356 + config SENSORS_PC87427 357 + tristate "National Semiconductor PC87427" 358 + depends on HWMON && EXPERIMENTAL 359 + help 360 + If you say yes here you get access to the hardware monitoring 361 + functions of the National Semiconductor PC87427 Super-I/O chip. 362 + The chip has two distinct logical devices, one for fan speed 363 + monitoring and control, and one for voltage and temperature 364 + monitoring. Only fan speed monitoring is supported right now. 365 + 366 + This driver can also be built as a module. If so, the module 367 + will be called pc87427. 368 + 369 config SENSORS_SIS5595 370 tristate "Silicon Integrated Systems Corp. SiS5595" 371 depends on HWMON && I2C && PCI && EXPERIMENTAL ··· 474 This driver can also be built as a module. If so, the module 475 will be called w83792d. 476 477 + config SENSORS_W83793 478 + tristate "Winbond W83793" 479 + depends on HWMON && I2C && EXPERIMENTAL 480 + help 481 + If you say yes here you get support for the Winbond W83793 482 + hardware monitoring chip. 483 + 484 + This driver can also be built as a module. If so, the module 485 + will be called w83793. 486 + 487 config SENSORS_W83L785TS 488 tristate "Winbond W83L785TS-S" 489 depends on HWMON && I2C && EXPERIMENTAL ··· 526 527 This driver also provides an absolute input class device, allowing 528 the laptop to act as a pinball machine-esque joystick. 529 + 530 + If your ThinkPad is not recognized by the driver, please update to latest 531 + BIOS. This is especially the case for some R52 ThinkPads. 532 533 Say Y here if you have an applicable laptop and want to experience 534 the awesome power of hdaps.
+3
drivers/hwmon/Makefile
··· 9 obj-$(CONFIG_SENSORS_ASB100) += asb100.o 10 obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o 11 obj-$(CONFIG_SENSORS_W83792D) += w83792d.o 12 obj-$(CONFIG_SENSORS_W83781D) += w83781d.o 13 obj-$(CONFIG_SENSORS_W83791D) += w83791d.o 14 ··· 19 obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o 20 obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o 21 obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o 22 obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 23 obj-$(CONFIG_SENSORS_DS1621) += ds1621.o 24 obj-$(CONFIG_SENSORS_F71805F) += f71805f.o ··· 43 obj-$(CONFIG_SENSORS_LM92) += lm92.o 44 obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 45 obj-$(CONFIG_SENSORS_PC87360) += pc87360.o 46 obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o 47 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o 48 obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
··· 9 obj-$(CONFIG_SENSORS_ASB100) += asb100.o 10 obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o 11 obj-$(CONFIG_SENSORS_W83792D) += w83792d.o 12 + obj-$(CONFIG_SENSORS_W83793) += w83793.o 13 obj-$(CONFIG_SENSORS_W83781D) += w83781d.o 14 obj-$(CONFIG_SENSORS_W83791D) += w83791d.o 15 ··· 18 obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o 19 obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o 20 obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o 21 + obj-$(CONFIG_SENSORS_AMS) += ams/ 22 obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 23 obj-$(CONFIG_SENSORS_DS1621) += ds1621.o 24 obj-$(CONFIG_SENSORS_F71805F) += f71805f.o ··· 41 obj-$(CONFIG_SENSORS_LM92) += lm92.o 42 obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 43 obj-$(CONFIG_SENSORS_PC87360) += pc87360.o 44 + obj-$(CONFIG_SENSORS_PC87427) += pc87427.o 45 obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o 46 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o 47 obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
+8
drivers/hwmon/ams/Makefile
···
··· 1 + # 2 + # Makefile for Apple Motion Sensor driver 3 + # 4 + 5 + ams-y := ams-core.o ams-input.o 6 + ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o 7 + ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o 8 + obj-$(CONFIG_SENSORS_AMS) += ams.o
+265
drivers/hwmon/ams/ams-core.c
···
··· 1 + /* 2 + * Apple Motion Sensor driver 3 + * 4 + * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 5 + * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch) 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/types.h> 24 + #include <linux/errno.h> 25 + #include <linux/init.h> 26 + #include <linux/module.h> 27 + #include <asm/pmac_pfunc.h> 28 + #include <asm/of_platform.h> 29 + 30 + #include "ams.h" 31 + 32 + /* There is only one motion sensor per machine */ 33 + struct ams ams_info; 34 + 35 + static unsigned int verbose; 36 + module_param(verbose, bool, 0644); 37 + MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output"); 38 + 39 + /* Call with ams_info.lock held! */ 40 + void ams_sensors(s8 *x, s8 *y, s8 *z) 41 + { 42 + u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2; 43 + 44 + if (orient & 0x80) 45 + /* X and Y swapped */ 46 + ams_info.get_xyz(y, x, z); 47 + else 48 + ams_info.get_xyz(x, y, z); 49 + 50 + if (orient & 0x04) 51 + *z = ~(*z); 52 + if (orient & 0x02) 53 + *y = ~(*y); 54 + if (orient & 0x01) 55 + *x = ~(*x); 56 + } 57 + 58 + static ssize_t ams_show_current(struct device *dev, 59 + struct device_attribute *attr, char *buf) 60 + { 61 + s8 x, y, z; 62 + 63 + mutex_lock(&ams_info.lock); 64 + ams_sensors(&x, &y, &z); 65 + mutex_unlock(&ams_info.lock); 66 + 67 + return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z); 68 + } 69 + 70 + static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL); 71 + 72 + static void ams_handle_irq(void *data) 73 + { 74 + enum ams_irq irq = *((enum ams_irq *)data); 75 + 76 + spin_lock(&ams_info.irq_lock); 77 + 78 + ams_info.worker_irqs |= irq; 79 + schedule_work(&ams_info.worker); 80 + 81 + spin_unlock(&ams_info.irq_lock); 82 + } 83 + 84 + static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL; 85 + static struct pmf_irq_client ams_freefall_client = { 86 + .owner = THIS_MODULE, 87 + .handler = ams_handle_irq, 88 + .data = &ams_freefall_irq_data, 89 + }; 90 + 91 + static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK; 92 + static struct pmf_irq_client ams_shock_client = { 93 + .owner = THIS_MODULE, 94 + .handler = ams_handle_irq, 95 + .data = &ams_shock_irq_data, 96 + }; 97 + 98 + /* Once hard disk parking is implemented in the kernel, this function can 99 + * trigger it. 100 + */ 101 + static void ams_worker(struct work_struct *work) 102 + { 103 + mutex_lock(&ams_info.lock); 104 + 105 + if (ams_info.has_device) { 106 + unsigned long flags; 107 + 108 + spin_lock_irqsave(&ams_info.irq_lock, flags); 109 + 110 + if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) { 111 + if (verbose) 112 + printk(KERN_INFO "ams: freefall detected!\n"); 113 + 114 + ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL; 115 + 116 + /* we must call this with interrupts enabled */ 117 + spin_unlock_irqrestore(&ams_info.irq_lock, flags); 118 + ams_info.clear_irq(AMS_IRQ_FREEFALL); 119 + spin_lock_irqsave(&ams_info.irq_lock, flags); 120 + } 121 + 122 + if (ams_info.worker_irqs & AMS_IRQ_SHOCK) { 123 + if (verbose) 124 + printk(KERN_INFO "ams: shock detected!\n"); 125 + 126 + ams_info.worker_irqs &= ~AMS_IRQ_SHOCK; 127 + 128 + /* we must call this with interrupts enabled */ 129 + spin_unlock_irqrestore(&ams_info.irq_lock, flags); 130 + ams_info.clear_irq(AMS_IRQ_SHOCK); 131 + spin_lock_irqsave(&ams_info.irq_lock, flags); 132 + } 133 + 134 + spin_unlock_irqrestore(&ams_info.irq_lock, flags); 135 + } 136 + 137 + mutex_unlock(&ams_info.lock); 138 + } 139 + 140 + /* Call with ams_info.lock held! */ 141 + int ams_sensor_attach(void) 142 + { 143 + int result; 144 + u32 *prop; 145 + 146 + /* Get orientation */ 147 + prop = (u32*)get_property(ams_info.of_node, "orientation", NULL); 148 + if (!prop) 149 + return -ENODEV; 150 + ams_info.orient1 = *prop; 151 + ams_info.orient2 = *(prop + 1); 152 + 153 + /* Register freefall interrupt handler */ 154 + result = pmf_register_irq_client(ams_info.of_node, 155 + "accel-int-1", 156 + &ams_freefall_client); 157 + if (result < 0) 158 + return -ENODEV; 159 + 160 + /* Reset saved irqs */ 161 + ams_info.worker_irqs = 0; 162 + 163 + /* Register shock interrupt handler */ 164 + result = pmf_register_irq_client(ams_info.of_node, 165 + "accel-int-2", 166 + &ams_shock_client); 167 + if (result < 0) 168 + goto release_freefall; 169 + 170 + /* Create device */ 171 + ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL); 172 + if (!ams_info.of_dev) { 173 + result = -ENODEV; 174 + goto release_shock; 175 + } 176 + 177 + /* Create attributes */ 178 + result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current); 179 + if (result) 180 + goto release_of; 181 + 182 + ams_info.vflag = !!(ams_info.get_vendor() & 0x10); 183 + 184 + /* Init input device */ 185 + result = ams_input_init(); 186 + if (result) 187 + goto release_device_file; 188 + 189 + return result; 190 + release_device_file: 191 + device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); 192 + release_of: 193 + of_device_unregister(ams_info.of_dev); 194 + release_shock: 195 + pmf_unregister_irq_client(&ams_shock_client); 196 + release_freefall: 197 + pmf_unregister_irq_client(&ams_freefall_client); 198 + return result; 199 + } 200 + 201 + int __init ams_init(void) 202 + { 203 + struct device_node *np; 204 + 205 + spin_lock_init(&ams_info.irq_lock); 206 + mutex_init(&ams_info.lock); 207 + INIT_WORK(&ams_info.worker, ams_worker); 208 + 209 + #ifdef CONFIG_SENSORS_AMS_I2C 210 + np = of_find_node_by_name(NULL, "accelerometer"); 211 + if (np && device_is_compatible(np, "AAPL,accelerometer_1")) 212 + /* Found I2C motion sensor */ 213 + return ams_i2c_init(np); 214 + #endif 215 + 216 + #ifdef CONFIG_SENSORS_AMS_PMU 217 + np = of_find_node_by_name(NULL, "sms"); 218 + if (np && device_is_compatible(np, "sms")) 219 + /* Found PMU motion sensor */ 220 + return ams_pmu_init(np); 221 + #endif 222 + 223 + printk(KERN_ERR "ams: No motion sensor found.\n"); 224 + 225 + return -ENODEV; 226 + } 227 + 228 + void ams_exit(void) 229 + { 230 + mutex_lock(&ams_info.lock); 231 + 232 + if (ams_info.has_device) { 233 + /* Remove input device */ 234 + ams_input_exit(); 235 + 236 + /* Shut down implementation */ 237 + ams_info.exit(); 238 + 239 + /* Flush interrupt worker 240 + * 241 + * We do this after ams_info.exit(), because an interrupt might 242 + * have arrived before disabling them. 243 + */ 244 + flush_scheduled_work(); 245 + 246 + /* Remove attributes */ 247 + device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); 248 + 249 + /* Remove device */ 250 + of_device_unregister(ams_info.of_dev); 251 + 252 + /* Remove handler */ 253 + pmf_unregister_irq_client(&ams_shock_client); 254 + pmf_unregister_irq_client(&ams_freefall_client); 255 + } 256 + 257 + mutex_unlock(&ams_info.lock); 258 + } 259 + 260 + MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); 261 + MODULE_DESCRIPTION("Apple Motion Sensor driver"); 262 + MODULE_LICENSE("GPL"); 263 + 264 + module_init(ams_init); 265 + module_exit(ams_exit);
+299
drivers/hwmon/ams/ams-i2c.c
···
··· 1 + /* 2 + * Apple Motion Sensor driver (I2C variant) 3 + * 4 + * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 5 + * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch) 6 + * 7 + * Clean room implementation based on the reverse engineered Mac OS X driver by 8 + * Johannes Berg <johannes@sipsolutions.net>, documentation available at 9 + * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification 10 + * 11 + * 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 13 + * the Free Software Foundation; either version 2 of the License, or 14 + * (at your option) any later version. 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/types.h> 19 + #include <linux/errno.h> 20 + #include <linux/init.h> 21 + #include <linux/delay.h> 22 + 23 + #include "ams.h" 24 + 25 + /* AMS registers */ 26 + #define AMS_COMMAND 0x00 /* command register */ 27 + #define AMS_STATUS 0x01 /* status register */ 28 + #define AMS_CTRL1 0x02 /* read control 1 (number of values) */ 29 + #define AMS_CTRL2 0x03 /* read control 2 (offset?) */ 30 + #define AMS_CTRL3 0x04 /* read control 3 (size of each value?) */ 31 + #define AMS_DATA1 0x05 /* read data 1 */ 32 + #define AMS_DATA2 0x06 /* read data 2 */ 33 + #define AMS_DATA3 0x07 /* read data 3 */ 34 + #define AMS_DATA4 0x08 /* read data 4 */ 35 + #define AMS_DATAX 0x20 /* data X */ 36 + #define AMS_DATAY 0x21 /* data Y */ 37 + #define AMS_DATAZ 0x22 /* data Z */ 38 + #define AMS_FREEFALL 0x24 /* freefall int control */ 39 + #define AMS_SHOCK 0x25 /* shock int control */ 40 + #define AMS_SENSLOW 0x26 /* sensitivity low limit */ 41 + #define AMS_SENSHIGH 0x27 /* sensitivity high limit */ 42 + #define AMS_CTRLX 0x28 /* control X */ 43 + #define AMS_CTRLY 0x29 /* control Y */ 44 + #define AMS_CTRLZ 0x2A /* control Z */ 45 + #define AMS_UNKNOWN1 0x2B /* unknown 1 */ 46 + #define AMS_UNKNOWN2 0x2C /* unknown 2 */ 47 + #define AMS_UNKNOWN3 0x2D /* unknown 3 */ 48 + #define AMS_VENDOR 0x2E /* vendor */ 49 + 50 + /* AMS commands - use with the AMS_COMMAND register */ 51 + enum ams_i2c_cmd { 52 + AMS_CMD_NOOP = 0, 53 + AMS_CMD_VERSION, 54 + AMS_CMD_READMEM, 55 + AMS_CMD_WRITEMEM, 56 + AMS_CMD_ERASEMEM, 57 + AMS_CMD_READEE, 58 + AMS_CMD_WRITEEE, 59 + AMS_CMD_RESET, 60 + AMS_CMD_START, 61 + }; 62 + 63 + static int ams_i2c_attach(struct i2c_adapter *adapter); 64 + static int ams_i2c_detach(struct i2c_adapter *adapter); 65 + 66 + static struct i2c_driver ams_i2c_driver = { 67 + .driver = { 68 + .name = "ams", 69 + .owner = THIS_MODULE, 70 + }, 71 + .attach_adapter = ams_i2c_attach, 72 + .detach_adapter = ams_i2c_detach, 73 + }; 74 + 75 + static s32 ams_i2c_read(u8 reg) 76 + { 77 + return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg); 78 + } 79 + 80 + static int ams_i2c_write(u8 reg, u8 value) 81 + { 82 + return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value); 83 + } 84 + 85 + static int ams_i2c_cmd(enum ams_i2c_cmd cmd) 86 + { 87 + s32 result; 88 + int remaining = HZ / 20; 89 + 90 + ams_i2c_write(AMS_COMMAND, cmd); 91 + mdelay(5); 92 + 93 + while (remaining) { 94 + result = ams_i2c_read(AMS_COMMAND); 95 + if (result == 0 || result & 0x80) 96 + return 0; 97 + 98 + remaining = schedule_timeout(remaining); 99 + } 100 + 101 + return -1; 102 + } 103 + 104 + static void ams_i2c_set_irq(enum ams_irq reg, char enable) 105 + { 106 + if (reg & AMS_IRQ_FREEFALL) { 107 + u8 val = ams_i2c_read(AMS_CTRLX); 108 + if (enable) 109 + val |= 0x80; 110 + else 111 + val &= ~0x80; 112 + ams_i2c_write(AMS_CTRLX, val); 113 + } 114 + 115 + if (reg & AMS_IRQ_SHOCK) { 116 + u8 val = ams_i2c_read(AMS_CTRLY); 117 + if (enable) 118 + val |= 0x80; 119 + else 120 + val &= ~0x80; 121 + ams_i2c_write(AMS_CTRLY, val); 122 + } 123 + 124 + if (reg & AMS_IRQ_GLOBAL) { 125 + u8 val = ams_i2c_read(AMS_CTRLZ); 126 + if (enable) 127 + val |= 0x80; 128 + else 129 + val &= ~0x80; 130 + ams_i2c_write(AMS_CTRLZ, val); 131 + } 132 + } 133 + 134 + static void ams_i2c_clear_irq(enum ams_irq reg) 135 + { 136 + if (reg & AMS_IRQ_FREEFALL) 137 + ams_i2c_write(AMS_FREEFALL, 0); 138 + 139 + if (reg & AMS_IRQ_SHOCK) 140 + ams_i2c_write(AMS_SHOCK, 0); 141 + } 142 + 143 + static u8 ams_i2c_get_vendor(void) 144 + { 145 + return ams_i2c_read(AMS_VENDOR); 146 + } 147 + 148 + static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z) 149 + { 150 + *x = ams_i2c_read(AMS_DATAX); 151 + *y = ams_i2c_read(AMS_DATAY); 152 + *z = ams_i2c_read(AMS_DATAZ); 153 + } 154 + 155 + static int ams_i2c_attach(struct i2c_adapter *adapter) 156 + { 157 + unsigned long bus; 158 + int vmaj, vmin; 159 + int result; 160 + 161 + /* There can be only one */ 162 + if (unlikely(ams_info.has_device)) 163 + return -ENODEV; 164 + 165 + if (strncmp(adapter->name, "uni-n", 5)) 166 + return -ENODEV; 167 + 168 + bus = simple_strtoul(adapter->name + 6, NULL, 10); 169 + if (bus != ams_info.i2c_bus) 170 + return -ENODEV; 171 + 172 + ams_info.i2c_client.addr = ams_info.i2c_address; 173 + ams_info.i2c_client.adapter = adapter; 174 + ams_info.i2c_client.driver = &ams_i2c_driver; 175 + strcpy(ams_info.i2c_client.name, "Apple Motion Sensor"); 176 + 177 + if (ams_i2c_cmd(AMS_CMD_RESET)) { 178 + printk(KERN_INFO "ams: Failed to reset the device\n"); 179 + return -ENODEV; 180 + } 181 + 182 + if (ams_i2c_cmd(AMS_CMD_START)) { 183 + printk(KERN_INFO "ams: Failed to start the device\n"); 184 + return -ENODEV; 185 + } 186 + 187 + /* get version/vendor information */ 188 + ams_i2c_write(AMS_CTRL1, 0x02); 189 + ams_i2c_write(AMS_CTRL2, 0x85); 190 + ams_i2c_write(AMS_CTRL3, 0x01); 191 + 192 + ams_i2c_cmd(AMS_CMD_READMEM); 193 + 194 + vmaj = ams_i2c_read(AMS_DATA1); 195 + vmin = ams_i2c_read(AMS_DATA2); 196 + if (vmaj != 1 || vmin != 52) { 197 + printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n", 198 + vmaj, vmin); 199 + return -ENODEV; 200 + } 201 + 202 + ams_i2c_cmd(AMS_CMD_VERSION); 203 + 204 + vmaj = ams_i2c_read(AMS_DATA1); 205 + vmin = ams_i2c_read(AMS_DATA2); 206 + if (vmaj != 0 || vmin != 1) { 207 + printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n", 208 + vmaj, vmin); 209 + return -ENODEV; 210 + } 211 + 212 + /* Disable interrupts */ 213 + ams_i2c_set_irq(AMS_IRQ_ALL, 0); 214 + 215 + result = ams_sensor_attach(); 216 + if (result < 0) 217 + return result; 218 + 219 + /* Set default values */ 220 + ams_i2c_write(AMS_SENSLOW, 0x15); 221 + ams_i2c_write(AMS_SENSHIGH, 0x60); 222 + ams_i2c_write(AMS_CTRLX, 0x08); 223 + ams_i2c_write(AMS_CTRLY, 0x0F); 224 + ams_i2c_write(AMS_CTRLZ, 0x4F); 225 + ams_i2c_write(AMS_UNKNOWN1, 0x14); 226 + 227 + /* Clear interrupts */ 228 + ams_i2c_clear_irq(AMS_IRQ_ALL); 229 + 230 + ams_info.has_device = 1; 231 + 232 + /* Enable interrupts */ 233 + ams_i2c_set_irq(AMS_IRQ_ALL, 1); 234 + 235 + printk(KERN_INFO "ams: Found I2C based motion sensor\n"); 236 + 237 + return 0; 238 + } 239 + 240 + static int ams_i2c_detach(struct i2c_adapter *adapter) 241 + { 242 + if (ams_info.has_device) { 243 + /* Disable interrupts */ 244 + ams_i2c_set_irq(AMS_IRQ_ALL, 0); 245 + 246 + /* Clear interrupts */ 247 + ams_i2c_clear_irq(AMS_IRQ_ALL); 248 + 249 + printk(KERN_INFO "ams: Unloading\n"); 250 + 251 + ams_info.has_device = 0; 252 + } 253 + 254 + return 0; 255 + } 256 + 257 + static void ams_i2c_exit(void) 258 + { 259 + i2c_del_driver(&ams_i2c_driver); 260 + } 261 + 262 + int __init ams_i2c_init(struct device_node *np) 263 + { 264 + char *tmp_bus; 265 + int result; 266 + u32 *prop; 267 + 268 + mutex_lock(&ams_info.lock); 269 + 270 + /* Set implementation stuff */ 271 + ams_info.of_node = np; 272 + ams_info.exit = ams_i2c_exit; 273 + ams_info.get_vendor = ams_i2c_get_vendor; 274 + ams_info.get_xyz = ams_i2c_get_xyz; 275 + ams_info.clear_irq = ams_i2c_clear_irq; 276 + ams_info.bustype = BUS_I2C; 277 + 278 + /* look for bus either using "reg" or by path */ 279 + prop = (u32*)get_property(ams_info.of_node, "reg", NULL); 280 + if (!prop) { 281 + result = -ENODEV; 282 + 283 + goto exit; 284 + } 285 + 286 + tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@"); 287 + if (tmp_bus) 288 + ams_info.i2c_bus = *(tmp_bus + 9) - '0'; 289 + else 290 + ams_info.i2c_bus = ((*prop) >> 8) & 0x0f; 291 + ams_info.i2c_address = ((*prop) & 0xff) >> 1; 292 + 293 + result = i2c_add_driver(&ams_i2c_driver); 294 + 295 + exit: 296 + mutex_unlock(&ams_info.lock); 297 + 298 + return result; 299 + }
+160
drivers/hwmon/ams/ams-input.c
···
··· 1 + /* 2 + * Apple Motion Sensor driver (joystick emulation) 3 + * 4 + * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 5 + * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch) 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + #include <linux/module.h> 14 + 15 + #include <linux/types.h> 16 + #include <linux/errno.h> 17 + #include <linux/init.h> 18 + #include <linux/delay.h> 19 + 20 + #include "ams.h" 21 + 22 + static unsigned int joystick; 23 + module_param(joystick, bool, 0644); 24 + MODULE_PARM_DESC(joystick, "Enable the input class device on module load"); 25 + 26 + static unsigned int invert; 27 + module_param(invert, bool, 0644); 28 + MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); 29 + 30 + static int ams_input_kthread(void *data) 31 + { 32 + s8 x, y, z; 33 + 34 + while (!kthread_should_stop()) { 35 + mutex_lock(&ams_info.lock); 36 + 37 + ams_sensors(&x, &y, &z); 38 + 39 + x -= ams_info.xcalib; 40 + y -= ams_info.ycalib; 41 + z -= ams_info.zcalib; 42 + 43 + input_report_abs(ams_info.idev, ABS_X, invert ? -x : x); 44 + input_report_abs(ams_info.idev, ABS_Y, invert ? -y : y); 45 + input_report_abs(ams_info.idev, ABS_Z, z); 46 + 47 + input_sync(ams_info.idev); 48 + 49 + mutex_unlock(&ams_info.lock); 50 + 51 + msleep(25); 52 + } 53 + 54 + return 0; 55 + } 56 + 57 + static int ams_input_open(struct input_dev *dev) 58 + { 59 + ams_info.kthread = kthread_run(ams_input_kthread, NULL, "kams"); 60 + return IS_ERR(ams_info.kthread) ? PTR_ERR(ams_info.kthread) : 0; 61 + } 62 + 63 + static void ams_input_close(struct input_dev *dev) 64 + { 65 + kthread_stop(ams_info.kthread); 66 + } 67 + 68 + /* Call with ams_info.lock held! */ 69 + static void ams_input_enable(void) 70 + { 71 + s8 x, y, z; 72 + 73 + if (ams_info.idev) 74 + return; 75 + 76 + ams_sensors(&x, &y, &z); 77 + ams_info.xcalib = x; 78 + ams_info.ycalib = y; 79 + ams_info.zcalib = z; 80 + 81 + ams_info.idev = input_allocate_device(); 82 + if (!ams_info.idev) 83 + return; 84 + 85 + ams_info.idev->name = "Apple Motion Sensor"; 86 + ams_info.idev->id.bustype = ams_info.bustype; 87 + ams_info.idev->id.vendor = 0; 88 + ams_info.idev->open = ams_input_open; 89 + ams_info.idev->close = ams_input_close; 90 + ams_info.idev->cdev.dev = &ams_info.of_dev->dev; 91 + 92 + input_set_abs_params(ams_info.idev, ABS_X, -50, 50, 3, 0); 93 + input_set_abs_params(ams_info.idev, ABS_Y, -50, 50, 3, 0); 94 + input_set_abs_params(ams_info.idev, ABS_Z, -50, 50, 3, 0); 95 + 96 + set_bit(EV_ABS, ams_info.idev->evbit); 97 + set_bit(EV_KEY, ams_info.idev->evbit); 98 + set_bit(BTN_TOUCH, ams_info.idev->keybit); 99 + 100 + if (input_register_device(ams_info.idev)) { 101 + input_free_device(ams_info.idev); 102 + ams_info.idev = NULL; 103 + return; 104 + } 105 + } 106 + 107 + /* Call with ams_info.lock held! */ 108 + static void ams_input_disable(void) 109 + { 110 + if (ams_info.idev) { 111 + input_unregister_device(ams_info.idev); 112 + ams_info.idev = NULL; 113 + } 114 + } 115 + 116 + static ssize_t ams_input_show_joystick(struct device *dev, 117 + struct device_attribute *attr, char *buf) 118 + { 119 + return sprintf(buf, "%d\n", joystick); 120 + } 121 + 122 + static ssize_t ams_input_store_joystick(struct device *dev, 123 + struct device_attribute *attr, const char *buf, size_t count) 124 + { 125 + if (sscanf(buf, "%d\n", &joystick) != 1) 126 + return -EINVAL; 127 + 128 + mutex_lock(&ams_info.lock); 129 + 130 + if (joystick) 131 + ams_input_enable(); 132 + else 133 + ams_input_disable(); 134 + 135 + mutex_unlock(&ams_info.lock); 136 + 137 + return count; 138 + } 139 + 140 + static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR, 141 + ams_input_show_joystick, ams_input_store_joystick); 142 + 143 + /* Call with ams_info.lock held! */ 144 + int ams_input_init(void) 145 + { 146 + int result; 147 + 148 + result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick); 149 + 150 + if (!result && joystick) 151 + ams_input_enable(); 152 + return result; 153 + } 154 + 155 + /* Call with ams_info.lock held! */ 156 + void ams_input_exit() 157 + { 158 + ams_input_disable(); 159 + device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); 160 + }
+207
drivers/hwmon/ams/ams-pmu.c
···
··· 1 + /* 2 + * Apple Motion Sensor driver (PMU variant) 3 + * 4 + * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch) 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/types.h> 14 + #include <linux/errno.h> 15 + #include <linux/init.h> 16 + #include <linux/adb.h> 17 + #include <linux/pmu.h> 18 + 19 + #include "ams.h" 20 + 21 + /* Attitude */ 22 + #define AMS_X 0x00 23 + #define AMS_Y 0x01 24 + #define AMS_Z 0x02 25 + 26 + /* Not exactly known, maybe chip vendor */ 27 + #define AMS_VENDOR 0x03 28 + 29 + /* Freefall registers */ 30 + #define AMS_FF_CLEAR 0x04 31 + #define AMS_FF_ENABLE 0x05 32 + #define AMS_FF_LOW_LIMIT 0x06 33 + #define AMS_FF_DEBOUNCE 0x07 34 + 35 + /* Shock registers */ 36 + #define AMS_SHOCK_CLEAR 0x08 37 + #define AMS_SHOCK_ENABLE 0x09 38 + #define AMS_SHOCK_HIGH_LIMIT 0x0a 39 + #define AMS_SHOCK_DEBOUNCE 0x0b 40 + 41 + /* Global interrupt and power control register */ 42 + #define AMS_CONTROL 0x0c 43 + 44 + static u8 ams_pmu_cmd; 45 + 46 + static void ams_pmu_req_complete(struct adb_request *req) 47 + { 48 + complete((struct completion *)req->arg); 49 + } 50 + 51 + /* Only call this function from task context */ 52 + static void ams_pmu_set_register(u8 reg, u8 value) 53 + { 54 + static struct adb_request req; 55 + DECLARE_COMPLETION(req_complete); 56 + 57 + req.arg = &req_complete; 58 + if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value)) 59 + return; 60 + 61 + wait_for_completion(&req_complete); 62 + } 63 + 64 + /* Only call this function from task context */ 65 + static u8 ams_pmu_get_register(u8 reg) 66 + { 67 + static struct adb_request req; 68 + DECLARE_COMPLETION(req_complete); 69 + 70 + req.arg = &req_complete; 71 + if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg)) 72 + return 0; 73 + 74 + wait_for_completion(&req_complete); 75 + 76 + if (req.reply_len > 0) 77 + return req.reply[0]; 78 + else 79 + return 0; 80 + } 81 + 82 + /* Enables or disables the specified interrupts */ 83 + static void ams_pmu_set_irq(enum ams_irq reg, char enable) 84 + { 85 + if (reg & AMS_IRQ_FREEFALL) { 86 + u8 val = ams_pmu_get_register(AMS_FF_ENABLE); 87 + if (enable) 88 + val |= 0x80; 89 + else 90 + val &= ~0x80; 91 + ams_pmu_set_register(AMS_FF_ENABLE, val); 92 + } 93 + 94 + if (reg & AMS_IRQ_SHOCK) { 95 + u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE); 96 + if (enable) 97 + val |= 0x80; 98 + else 99 + val &= ~0x80; 100 + ams_pmu_set_register(AMS_SHOCK_ENABLE, val); 101 + } 102 + 103 + if (reg & AMS_IRQ_GLOBAL) { 104 + u8 val = ams_pmu_get_register(AMS_CONTROL); 105 + if (enable) 106 + val |= 0x80; 107 + else 108 + val &= ~0x80; 109 + ams_pmu_set_register(AMS_CONTROL, val); 110 + } 111 + } 112 + 113 + static void ams_pmu_clear_irq(enum ams_irq reg) 114 + { 115 + if (reg & AMS_IRQ_FREEFALL) 116 + ams_pmu_set_register(AMS_FF_CLEAR, 0x00); 117 + 118 + if (reg & AMS_IRQ_SHOCK) 119 + ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00); 120 + } 121 + 122 + static u8 ams_pmu_get_vendor(void) 123 + { 124 + return ams_pmu_get_register(AMS_VENDOR); 125 + } 126 + 127 + static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z) 128 + { 129 + *x = ams_pmu_get_register(AMS_X); 130 + *y = ams_pmu_get_register(AMS_Y); 131 + *z = ams_pmu_get_register(AMS_Z); 132 + } 133 + 134 + static void ams_pmu_exit(void) 135 + { 136 + /* Disable interrupts */ 137 + ams_pmu_set_irq(AMS_IRQ_ALL, 0); 138 + 139 + /* Clear interrupts */ 140 + ams_pmu_clear_irq(AMS_IRQ_ALL); 141 + 142 + ams_info.has_device = 0; 143 + 144 + printk(KERN_INFO "ams: Unloading\n"); 145 + } 146 + 147 + int __init ams_pmu_init(struct device_node *np) 148 + { 149 + u32 *prop; 150 + int result; 151 + 152 + mutex_lock(&ams_info.lock); 153 + 154 + /* Set implementation stuff */ 155 + ams_info.of_node = np; 156 + ams_info.exit = ams_pmu_exit; 157 + ams_info.get_vendor = ams_pmu_get_vendor; 158 + ams_info.get_xyz = ams_pmu_get_xyz; 159 + ams_info.clear_irq = ams_pmu_clear_irq; 160 + ams_info.bustype = BUS_HOST; 161 + 162 + /* Get PMU command, should be 0x4e, but we can never know */ 163 + prop = (u32*)get_property(ams_info.of_node, "reg", NULL); 164 + if (!prop) { 165 + result = -ENODEV; 166 + goto exit; 167 + } 168 + ams_pmu_cmd = ((*prop) >> 8) & 0xff; 169 + 170 + /* Disable interrupts */ 171 + ams_pmu_set_irq(AMS_IRQ_ALL, 0); 172 + 173 + /* Clear interrupts */ 174 + ams_pmu_clear_irq(AMS_IRQ_ALL); 175 + 176 + result = ams_sensor_attach(); 177 + if (result < 0) 178 + goto exit; 179 + 180 + /* Set default values */ 181 + ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15); 182 + ams_pmu_set_register(AMS_FF_ENABLE, 0x08); 183 + ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14); 184 + 185 + ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60); 186 + ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f); 187 + ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14); 188 + 189 + ams_pmu_set_register(AMS_CONTROL, 0x4f); 190 + 191 + /* Clear interrupts */ 192 + ams_pmu_clear_irq(AMS_IRQ_ALL); 193 + 194 + ams_info.has_device = 1; 195 + 196 + /* Enable interrupts */ 197 + ams_pmu_set_irq(AMS_IRQ_ALL, 1); 198 + 199 + printk(KERN_INFO "ams: Found PMU based motion sensor\n"); 200 + 201 + result = 0; 202 + 203 + exit: 204 + mutex_unlock(&ams_info.lock); 205 + 206 + return result; 207 + }
+72
drivers/hwmon/ams/ams.h
···
··· 1 + #include <linux/i2c.h> 2 + #include <linux/input.h> 3 + #include <linux/kthread.h> 4 + #include <linux/mutex.h> 5 + #include <linux/spinlock.h> 6 + #include <linux/types.h> 7 + #include <asm/of_device.h> 8 + 9 + enum ams_irq { 10 + AMS_IRQ_FREEFALL = 0x01, 11 + AMS_IRQ_SHOCK = 0x02, 12 + AMS_IRQ_GLOBAL = 0x04, 13 + AMS_IRQ_ALL = 14 + AMS_IRQ_FREEFALL | 15 + AMS_IRQ_SHOCK | 16 + AMS_IRQ_GLOBAL, 17 + }; 18 + 19 + struct ams { 20 + /* Locks */ 21 + spinlock_t irq_lock; 22 + struct mutex lock; 23 + 24 + /* General properties */ 25 + struct device_node *of_node; 26 + struct of_device *of_dev; 27 + char has_device; 28 + char vflag; 29 + u32 orient1; 30 + u32 orient2; 31 + 32 + /* Interrupt worker */ 33 + struct work_struct worker; 34 + u8 worker_irqs; 35 + 36 + /* Implementation 37 + * 38 + * Only call these functions with the main lock held. 39 + */ 40 + void (*exit)(void); 41 + 42 + void (*get_xyz)(s8 *x, s8 *y, s8 *z); 43 + u8 (*get_vendor)(void); 44 + 45 + void (*clear_irq)(enum ams_irq reg); 46 + 47 + #ifdef CONFIG_SENSORS_AMS_I2C 48 + /* I2C properties */ 49 + int i2c_bus; 50 + int i2c_address; 51 + struct i2c_client i2c_client; 52 + #endif 53 + 54 + /* Joystick emulation */ 55 + struct task_struct *kthread; 56 + struct input_dev *idev; 57 + __u16 bustype; 58 + 59 + /* calibrated null values */ 60 + int xcalib, ycalib, zcalib; 61 + }; 62 + 63 + extern struct ams ams_info; 64 + 65 + extern void ams_sensors(s8 *x, s8 *y, s8 *z); 66 + extern int ams_sensor_attach(void); 67 + 68 + extern int ams_pmu_init(struct device_node *np); 69 + extern int ams_i2c_init(struct device_node *np); 70 + 71 + extern int ams_input_init(void); 72 + extern void ams_input_exit(void);
+491 -78
drivers/hwmon/f71805f.c
··· 1 /* 2 - * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated 3 - * hardware monitoring features 4 * Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org> 5 * 6 * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates 7 * complete hardware monitoring features: voltage, fan and temperature 8 * sensors, and manual and automatic fan speed control. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by ··· 40 static struct platform_device *pdev; 41 42 #define DRVNAME "f71805f" 43 44 /* 45 * Super-I/O constants and functions ··· 52 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 53 #define SIO_REG_DEVREV 0x22 /* Device revision */ 54 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 55 #define SIO_REG_ENABLE 0x30 /* Logical device enable */ 56 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 57 58 #define SIO_FINTEK_ID 0x1934 59 #define SIO_F71805F_ID 0x0406 60 61 static inline int 62 superio_inb(int base, int reg) ··· 102 * ISA constants 103 */ 104 105 - #define REGION_LENGTH 2 106 - #define ADDR_REG_OFFSET 0 107 - #define DATA_REG_OFFSET 1 108 109 /* 110 * Registers 111 */ 112 113 - /* in nr from 0 to 8 (8-bit values) */ 114 #define F71805F_REG_IN(nr) (0x10 + (nr)) 115 - #define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr)) 116 - #define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr)) 117 /* fan nr from 0 to 2 (12-bit values, two registers) */ 118 #define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) 119 #define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) 120 #define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) 121 /* temp nr from 0 to 2 (8-bit values) */ 122 #define F71805F_REG_TEMP(nr) (0x1B + (nr)) 123 #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) ··· 130 #define F71805F_REG_START 0x00 131 /* status nr from 0 to 2 */ 132 #define F71805F_REG_STATUS(nr) (0x36 + (nr)) 133 134 /* 135 * Data structures and manipulation thereof ··· 155 unsigned long last_limits; /* In jiffies */ 156 157 /* Register values */ 158 - u8 in[9]; 159 - u8 in_high[9]; 160 - u8 in_low[9]; 161 u16 fan[3]; 162 u16 fan_low[3]; 163 - u8 fan_enabled; /* Read once at init time */ 164 u8 temp[3]; 165 u8 temp_high[3]; 166 u8 temp_hyst[3]; 167 u8 temp_mode; 168 unsigned long alarms; 169 }; 170 171 static inline long in_from_reg(u8 reg) ··· 224 if (rpm < 367) 225 return 0xfff; 226 return (1500000 / rpm); 227 } 228 229 static inline long temp_from_reg(u8 reg) ··· 327 /* Limit registers cache is refreshed after 60 seconds */ 328 if (time_after(jiffies, data->last_updated + 60 * HZ) 329 || !data->valid) { 330 - for (nr = 0; nr < 9; nr++) { 331 data->in_high[nr] = f71805f_read8(data, 332 F71805F_REG_IN_HIGH(nr)); 333 data->in_low[nr] = f71805f_read8(data, 334 F71805F_REG_IN_LOW(nr)); 335 } 336 for (nr = 0; nr < 3; nr++) { 337 - if (data->fan_enabled & (1 << nr)) 338 - data->fan_low[nr] = f71805f_read16(data, 339 - F71805F_REG_FAN_LOW(nr)); 340 } 341 for (nr = 0; nr < 3; nr++) { 342 data->temp_high[nr] = f71805f_read8(data, ··· 357 /* Measurement registers cache is refreshed after 1 second */ 358 if (time_after(jiffies, data->last_updated + HZ) 359 || !data->valid) { 360 - for (nr = 0; nr < 9; nr++) { 361 data->in[nr] = f71805f_read8(data, 362 F71805F_REG_IN(nr)); 363 } 364 for (nr = 0; nr < 3; nr++) { 365 - if (data->fan_enabled & (1 << nr)) 366 - data->fan[nr] = f71805f_read16(data, 367 - F71805F_REG_FAN(nr)); 368 } 369 for (nr = 0; nr < 3; nr++) { 370 data->temp[nr] = f71805f_read8(data, ··· 396 char *buf) 397 { 398 struct f71805f_data *data = f71805f_update_device(dev); 399 400 - return sprintf(buf, "%ld\n", in0_from_reg(data->in[0])); 401 } 402 403 static ssize_t show_in0_max(struct device *dev, struct device_attribute 404 *devattr, char *buf) 405 { 406 struct f71805f_data *data = f71805f_update_device(dev); 407 408 - return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0])); 409 } 410 411 static ssize_t show_in0_min(struct device *dev, struct device_attribute 412 *devattr, char *buf) 413 { 414 struct f71805f_data *data = f71805f_update_device(dev); 415 416 - return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0])); 417 } 418 419 static ssize_t set_in0_max(struct device *dev, struct device_attribute 420 *devattr, const char *buf, size_t count) 421 { 422 struct f71805f_data *data = dev_get_drvdata(dev); 423 long val = simple_strtol(buf, NULL, 10); 424 425 mutex_lock(&data->update_lock); 426 - data->in_high[0] = in0_to_reg(val); 427 - f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); 428 mutex_unlock(&data->update_lock); 429 430 return count; ··· 442 *devattr, const char *buf, size_t count) 443 { 444 struct f71805f_data *data = dev_get_drvdata(dev); 445 long val = simple_strtol(buf, NULL, 10); 446 447 mutex_lock(&data->update_lock); 448 - data->in_low[0] = in0_to_reg(val); 449 - f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); 450 mutex_unlock(&data->update_lock); 451 452 return count; ··· 536 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); 537 } 538 539 static ssize_t set_fan_min(struct device *dev, struct device_attribute 540 *devattr, const char *buf, size_t count) 541 { ··· 557 mutex_lock(&data->update_lock); 558 data->fan_low[nr] = fan_to_reg(val); 559 f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); 560 mutex_unlock(&data->update_lock); 561 562 return count; ··· 791 { 792 struct f71805f_data *data = f71805f_update_device(dev); 793 794 - return sprintf(buf, "%lu\n", data->alarms & 0x1ff); 795 } 796 797 static ssize_t show_alarms_fan(struct device *dev, struct device_attribute ··· 828 return sprintf(buf, "%s\n", data->name); 829 } 830 831 - static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); 832 - static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); 833 - static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); 834 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); 835 static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, 836 show_in_max, set_in_max, 1); ··· 873 show_in_max, set_in_max, 8); 874 static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR, 875 show_in_min, set_in_min, 8); 876 877 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); 878 static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, 879 show_fan_min, set_fan_min, 0); 880 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); 881 static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, 882 show_fan_min, set_fan_min, 1); 883 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); 884 static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, 885 show_fan_min, set_fan_min, 2); 886 887 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 888 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, ··· 919 show_temp_hyst, set_temp_hyst, 2); 920 static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2); 921 922 static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 923 static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 924 static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); ··· 949 static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); 950 static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); 951 static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8); 952 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11); 953 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12); 954 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13); ··· 964 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 965 966 static struct attribute *f71805f_attributes[] = { 967 - &dev_attr_in0_input.attr, 968 - &dev_attr_in0_max.attr, 969 - &dev_attr_in0_min.attr, 970 &sensor_dev_attr_in1_input.dev_attr.attr, 971 &sensor_dev_attr_in1_max.dev_attr.attr, 972 &sensor_dev_attr_in1_min.dev_attr.attr, ··· 976 &sensor_dev_attr_in3_input.dev_attr.attr, 977 &sensor_dev_attr_in3_max.dev_attr.attr, 978 &sensor_dev_attr_in3_min.dev_attr.attr, 979 - &sensor_dev_attr_in4_input.dev_attr.attr, 980 - &sensor_dev_attr_in4_max.dev_attr.attr, 981 - &sensor_dev_attr_in4_min.dev_attr.attr, 982 &sensor_dev_attr_in5_input.dev_attr.attr, 983 &sensor_dev_attr_in5_max.dev_attr.attr, 984 &sensor_dev_attr_in5_min.dev_attr.attr, ··· 985 &sensor_dev_attr_in7_input.dev_attr.attr, 986 &sensor_dev_attr_in7_max.dev_attr.attr, 987 &sensor_dev_attr_in7_min.dev_attr.attr, 988 - &sensor_dev_attr_in8_input.dev_attr.attr, 989 - &sensor_dev_attr_in8_max.dev_attr.attr, 990 - &sensor_dev_attr_in8_min.dev_attr.attr, 991 992 &sensor_dev_attr_temp1_input.dev_attr.attr, 993 &sensor_dev_attr_temp1_max.dev_attr.attr, ··· 1026 &sensor_dev_attr_in1_alarm.dev_attr.attr, 1027 &sensor_dev_attr_in2_alarm.dev_attr.attr, 1028 &sensor_dev_attr_in3_alarm.dev_attr.attr, 1029 - &sensor_dev_attr_in4_alarm.dev_attr.attr, 1030 &sensor_dev_attr_in5_alarm.dev_attr.attr, 1031 &sensor_dev_attr_in6_alarm.dev_attr.attr, 1032 &sensor_dev_attr_in7_alarm.dev_attr.attr, 1033 - &sensor_dev_attr_in8_alarm.dev_attr.attr, 1034 &dev_attr_alarms_in.attr, 1035 &sensor_dev_attr_temp1_alarm.dev_attr.attr, 1036 &sensor_dev_attr_temp2_alarm.dev_attr.attr, ··· 1044 .attrs = f71805f_attributes, 1045 }; 1046 1047 - static struct attribute *f71805f_attributes_fan[3][4] = { 1048 { 1049 - &sensor_dev_attr_fan1_input.dev_attr.attr, 1050 - &sensor_dev_attr_fan1_min.dev_attr.attr, 1051 - &sensor_dev_attr_fan1_alarm.dev_attr.attr, 1052 NULL 1053 }, { 1054 - &sensor_dev_attr_fan2_input.dev_attr.attr, 1055 - &sensor_dev_attr_fan2_min.dev_attr.attr, 1056 - &sensor_dev_attr_fan2_alarm.dev_attr.attr, 1057 NULL 1058 }, { 1059 - &sensor_dev_attr_fan3_input.dev_attr.attr, 1060 - &sensor_dev_attr_fan3_min.dev_attr.attr, 1061 - &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1062 NULL 1063 } 1064 }; 1065 1066 - static const struct attribute_group f71805f_group_fan[3] = { 1067 - { .attrs = f71805f_attributes_fan[0] }, 1068 - { .attrs = f71805f_attributes_fan[1] }, 1069 - { .attrs = f71805f_attributes_fan[2] }, 1070 }; 1071 1072 /* ··· 1118 /* Fan monitoring can be disabled. If it is, we won't be polling 1119 the register values, and won't create the related sysfs files. */ 1120 for (i = 0; i < 3; i++) { 1121 - reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); 1122 - if (!(reg & 0x80)) 1123 - data->fan_enabled |= (1 << i); 1124 } 1125 } 1126 1127 static int __devinit f71805f_probe(struct platform_device *pdev) 1128 { 1129 struct f71805f_data *data; 1130 struct resource *res; 1131 int i, err; 1132 1133 if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { 1134 err = -ENOMEM; ··· 1151 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1152 data->addr = res->start; 1153 mutex_init(&data->lock); 1154 - data->name = "f71805f"; 1155 mutex_init(&data->update_lock); 1156 1157 platform_set_drvdata(pdev, data); 1158 1159 /* Initialize the F71805F chip */ 1160 f71805f_init_device(data); ··· 1176 /* Register sysfs interface files */ 1177 if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) 1178 goto exit_free; 1179 - for (i = 0; i < 3; i++) { 1180 - if (!(data->fan_enabled & (1 << i))) 1181 - continue; 1182 if ((err = sysfs_create_group(&pdev->dev.kobj, 1183 - &f71805f_group_fan[i]))) 1184 goto exit_remove_files; 1185 } 1186 1187 data->class_dev = hwmon_device_register(&pdev->dev); ··· 1226 1227 exit_remove_files: 1228 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); 1229 - for (i = 0; i < 3; i++) 1230 - sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]); 1231 exit_free: 1232 platform_set_drvdata(pdev, NULL); 1233 kfree(data); ··· 1244 platform_set_drvdata(pdev, NULL); 1245 hwmon_device_unregister(data->class_dev); 1246 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); 1247 - for (i = 0; i < 3; i++) 1248 - sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]); 1249 kfree(data); 1250 1251 return 0; ··· 1261 .remove = __devexit_p(f71805f_remove), 1262 }; 1263 1264 - static int __init f71805f_device_add(unsigned short address) 1265 { 1266 struct resource res = { 1267 .start = address, ··· 1286 goto exit_device_put; 1287 } 1288 1289 err = platform_device_add(pdev); 1290 if (err) { 1291 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", 1292 err); 1293 - goto exit_device_put; 1294 } 1295 1296 return 0; 1297 1298 exit_device_put: 1299 platform_device_put(pdev); 1300 exit: 1301 return err; 1302 } 1303 1304 - static int __init f71805f_find(int sioaddr, unsigned short *address) 1305 { 1306 int err = -ENODEV; 1307 u16 devid; 1308 1309 superio_enter(sioaddr); 1310 ··· 1332 goto exit; 1333 1334 devid = superio_inw(sioaddr, SIO_REG_DEVID); 1335 - if (devid != SIO_F71805F_ID) { 1336 printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " 1337 "skipping\n"); 1338 goto exit; ··· 1359 "skipping\n"); 1360 goto exit; 1361 } 1362 1363 err = 0; 1364 - printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", 1365 - *address, superio_inb(sioaddr, SIO_REG_DEVREV)); 1366 1367 exit: 1368 superio_exit(sioaddr); ··· 1375 { 1376 int err; 1377 unsigned short address; 1378 1379 - if (f71805f_find(0x2e, &address) 1380 - && f71805f_find(0x4e, &address)) 1381 return -ENODEV; 1382 1383 err = platform_driver_register(&f71805f_driver); ··· 1386 goto exit; 1387 1388 /* Sets global pdev as a side effect */ 1389 - err = f71805f_device_add(address); 1390 if (err) 1391 goto exit_driver; 1392 ··· 1400 1401 static void __exit f71805f_exit(void) 1402 { 1403 platform_device_unregister(pdev); 1404 platform_driver_unregister(&f71805f_driver); 1405 } 1406 1407 MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); 1408 MODULE_LICENSE("GPL"); 1409 - MODULE_DESCRIPTION("F71805F hardware monitoring driver"); 1410 1411 module_init(f71805f_init); 1412 module_exit(f71805f_exit);
··· 1 /* 2 + * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O 3 + * chips integrated hardware monitoring features 4 * Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org> 5 * 6 * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates 7 * complete hardware monitoring features: voltage, fan and temperature 8 * sensors, and manual and automatic fan speed control. 9 + * 10 + * The F71872F/FG is almost the same, with two more voltages monitored, 11 + * and 6 VID inputs. 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by ··· 37 static struct platform_device *pdev; 38 39 #define DRVNAME "f71805f" 40 + enum kinds { f71805f, f71872f }; 41 42 /* 43 * Super-I/O constants and functions ··· 48 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 49 #define SIO_REG_DEVREV 0x22 /* Device revision */ 50 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 51 + #define SIO_REG_FNSEL1 0x29 /* Multi Function Select 1 (F71872F) */ 52 #define SIO_REG_ENABLE 0x30 /* Logical device enable */ 53 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 54 55 #define SIO_FINTEK_ID 0x1934 56 #define SIO_F71805F_ID 0x0406 57 + #define SIO_F71872F_ID 0x0341 58 59 static inline int 60 superio_inb(int base, int reg) ··· 96 * ISA constants 97 */ 98 99 + #define REGION_LENGTH 8 100 + #define ADDR_REG_OFFSET 5 101 + #define DATA_REG_OFFSET 6 102 103 /* 104 * Registers 105 */ 106 107 + /* in nr from 0 to 10 (8-bit values) */ 108 #define F71805F_REG_IN(nr) (0x10 + (nr)) 109 + #define F71805F_REG_IN_HIGH(nr) ((nr) < 10 ? 0x40 + 2 * (nr) : 0x2E) 110 + #define F71805F_REG_IN_LOW(nr) ((nr) < 10 ? 0x41 + 2 * (nr) : 0x2F) 111 /* fan nr from 0 to 2 (12-bit values, two registers) */ 112 #define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) 113 #define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) 114 + #define F71805F_REG_FAN_TARGET(nr) (0x69 + 16 * (nr)) 115 #define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) 116 + #define F71805F_REG_PWM_FREQ(nr) (0x63 + 16 * (nr)) 117 + #define F71805F_REG_PWM_DUTY(nr) (0x6B + 16 * (nr)) 118 /* temp nr from 0 to 2 (8-bit values) */ 119 #define F71805F_REG_TEMP(nr) (0x1B + (nr)) 120 #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) ··· 121 #define F71805F_REG_START 0x00 122 /* status nr from 0 to 2 */ 123 #define F71805F_REG_STATUS(nr) (0x36 + (nr)) 124 + 125 + /* individual register bits */ 126 + #define FAN_CTRL_DC_MODE 0x10 127 + #define FAN_CTRL_LATCH_FULL 0x08 128 + #define FAN_CTRL_MODE_MASK 0x03 129 + #define FAN_CTRL_MODE_SPEED 0x00 130 + #define FAN_CTRL_MODE_TEMPERATURE 0x01 131 + #define FAN_CTRL_MODE_MANUAL 0x02 132 133 /* 134 * Data structures and manipulation thereof ··· 138 unsigned long last_limits; /* In jiffies */ 139 140 /* Register values */ 141 + u8 in[11]; 142 + u8 in_high[11]; 143 + u8 in_low[11]; 144 + u16 has_in; 145 u16 fan[3]; 146 u16 fan_low[3]; 147 + u16 fan_target[3]; 148 + u8 fan_ctrl[3]; 149 + u8 pwm[3]; 150 + u8 pwm_freq[3]; 151 u8 temp[3]; 152 u8 temp_high[3]; 153 u8 temp_hyst[3]; 154 u8 temp_mode; 155 unsigned long alarms; 156 + }; 157 + 158 + struct f71805f_sio_data { 159 + enum kinds kind; 160 + u8 fnsel1; 161 }; 162 163 static inline long in_from_reg(u8 reg) ··· 198 if (rpm < 367) 199 return 0xfff; 200 return (1500000 / rpm); 201 + } 202 + 203 + static inline unsigned long pwm_freq_from_reg(u8 reg) 204 + { 205 + unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL; 206 + 207 + reg &= 0x7f; 208 + if (reg == 0) 209 + reg++; 210 + return clock / (reg << 8); 211 + } 212 + 213 + static inline u8 pwm_freq_to_reg(unsigned long val) 214 + { 215 + if (val >= 187500) /* The highest we can do */ 216 + return 0x80; 217 + if (val >= 1475) /* Use 48 MHz clock */ 218 + return 0x80 | (48000000UL / (val << 8)); 219 + if (val < 31) /* The lowest we can do */ 220 + return 0x7f; 221 + else /* Use 1 MHz clock */ 222 + return 1000000UL / (val << 8); 223 + } 224 + 225 + static inline int pwm_mode_from_reg(u8 reg) 226 + { 227 + return !(reg & FAN_CTRL_DC_MODE); 228 } 229 230 static inline long temp_from_reg(u8 reg) ··· 274 /* Limit registers cache is refreshed after 60 seconds */ 275 if (time_after(jiffies, data->last_updated + 60 * HZ) 276 || !data->valid) { 277 + for (nr = 0; nr < 11; nr++) { 278 + if (!(data->has_in & (1 << nr))) 279 + continue; 280 data->in_high[nr] = f71805f_read8(data, 281 F71805F_REG_IN_HIGH(nr)); 282 data->in_low[nr] = f71805f_read8(data, 283 F71805F_REG_IN_LOW(nr)); 284 } 285 for (nr = 0; nr < 3; nr++) { 286 + data->fan_low[nr] = f71805f_read16(data, 287 + F71805F_REG_FAN_LOW(nr)); 288 + data->fan_target[nr] = f71805f_read16(data, 289 + F71805F_REG_FAN_TARGET(nr)); 290 + data->pwm_freq[nr] = f71805f_read8(data, 291 + F71805F_REG_PWM_FREQ(nr)); 292 } 293 for (nr = 0; nr < 3; nr++) { 294 data->temp_high[nr] = f71805f_read8(data, ··· 299 /* Measurement registers cache is refreshed after 1 second */ 300 if (time_after(jiffies, data->last_updated + HZ) 301 || !data->valid) { 302 + for (nr = 0; nr < 11; nr++) { 303 + if (!(data->has_in & (1 << nr))) 304 + continue; 305 data->in[nr] = f71805f_read8(data, 306 F71805F_REG_IN(nr)); 307 } 308 for (nr = 0; nr < 3; nr++) { 309 + data->fan[nr] = f71805f_read16(data, 310 + F71805F_REG_FAN(nr)); 311 + data->fan_ctrl[nr] = f71805f_read8(data, 312 + F71805F_REG_FAN_CTRL(nr)); 313 + data->pwm[nr] = f71805f_read8(data, 314 + F71805F_REG_PWM_DUTY(nr)); 315 } 316 for (nr = 0; nr < 3; nr++) { 317 data->temp[nr] = f71805f_read8(data, ··· 333 char *buf) 334 { 335 struct f71805f_data *data = f71805f_update_device(dev); 336 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 337 + int nr = attr->index; 338 339 + return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr])); 340 } 341 342 static ssize_t show_in0_max(struct device *dev, struct device_attribute 343 *devattr, char *buf) 344 { 345 struct f71805f_data *data = f71805f_update_device(dev); 346 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 347 + int nr = attr->index; 348 349 + return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr])); 350 } 351 352 static ssize_t show_in0_min(struct device *dev, struct device_attribute 353 *devattr, char *buf) 354 { 355 struct f71805f_data *data = f71805f_update_device(dev); 356 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 357 + int nr = attr->index; 358 359 + return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr])); 360 } 361 362 static ssize_t set_in0_max(struct device *dev, struct device_attribute 363 *devattr, const char *buf, size_t count) 364 { 365 struct f71805f_data *data = dev_get_drvdata(dev); 366 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 367 + int nr = attr->index; 368 long val = simple_strtol(buf, NULL, 10); 369 370 mutex_lock(&data->update_lock); 371 + data->in_high[nr] = in0_to_reg(val); 372 + f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); 373 mutex_unlock(&data->update_lock); 374 375 return count; ··· 371 *devattr, const char *buf, size_t count) 372 { 373 struct f71805f_data *data = dev_get_drvdata(dev); 374 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 375 + int nr = attr->index; 376 long val = simple_strtol(buf, NULL, 10); 377 378 mutex_lock(&data->update_lock); 379 + data->in_low[nr] = in0_to_reg(val); 380 + f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); 381 mutex_unlock(&data->update_lock); 382 383 return count; ··· 463 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); 464 } 465 466 + static ssize_t show_fan_target(struct device *dev, struct device_attribute 467 + *devattr, char *buf) 468 + { 469 + struct f71805f_data *data = f71805f_update_device(dev); 470 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 471 + int nr = attr->index; 472 + 473 + return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr])); 474 + } 475 + 476 static ssize_t set_fan_min(struct device *dev, struct device_attribute 477 *devattr, const char *buf, size_t count) 478 { ··· 474 mutex_lock(&data->update_lock); 475 data->fan_low[nr] = fan_to_reg(val); 476 f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); 477 + mutex_unlock(&data->update_lock); 478 + 479 + return count; 480 + } 481 + 482 + static ssize_t set_fan_target(struct device *dev, struct device_attribute 483 + *devattr, const char *buf, size_t count) 484 + { 485 + struct f71805f_data *data = dev_get_drvdata(dev); 486 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 487 + int nr = attr->index; 488 + long val = simple_strtol(buf, NULL, 10); 489 + 490 + mutex_lock(&data->update_lock); 491 + data->fan_target[nr] = fan_to_reg(val); 492 + f71805f_write16(data, F71805F_REG_FAN_TARGET(nr), 493 + data->fan_target[nr]); 494 + mutex_unlock(&data->update_lock); 495 + 496 + return count; 497 + } 498 + 499 + static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, 500 + char *buf) 501 + { 502 + struct f71805f_data *data = f71805f_update_device(dev); 503 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 504 + int nr = attr->index; 505 + 506 + return sprintf(buf, "%d\n", (int)data->pwm[nr]); 507 + } 508 + 509 + static ssize_t show_pwm_enable(struct device *dev, struct device_attribute 510 + *devattr, char *buf) 511 + { 512 + struct f71805f_data *data = f71805f_update_device(dev); 513 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 514 + int nr = attr->index; 515 + int mode; 516 + 517 + switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) { 518 + case FAN_CTRL_MODE_SPEED: 519 + mode = 3; 520 + break; 521 + case FAN_CTRL_MODE_TEMPERATURE: 522 + mode = 2; 523 + break; 524 + default: /* MANUAL */ 525 + mode = 1; 526 + } 527 + 528 + return sprintf(buf, "%d\n", mode); 529 + } 530 + 531 + static ssize_t show_pwm_freq(struct device *dev, struct device_attribute 532 + *devattr, char *buf) 533 + { 534 + struct f71805f_data *data = f71805f_update_device(dev); 535 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 536 + int nr = attr->index; 537 + 538 + return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr])); 539 + } 540 + 541 + static ssize_t show_pwm_mode(struct device *dev, struct device_attribute 542 + *devattr, char *buf) 543 + { 544 + struct f71805f_data *data = f71805f_update_device(dev); 545 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 546 + int nr = attr->index; 547 + 548 + return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr])); 549 + } 550 + 551 + static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, 552 + const char *buf, size_t count) 553 + { 554 + struct f71805f_data *data = dev_get_drvdata(dev); 555 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 556 + int nr = attr->index; 557 + unsigned long val = simple_strtoul(buf, NULL, 10); 558 + 559 + if (val > 255) 560 + return -EINVAL; 561 + 562 + mutex_lock(&data->update_lock); 563 + data->pwm[nr] = val; 564 + f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]); 565 + mutex_unlock(&data->update_lock); 566 + 567 + return count; 568 + } 569 + 570 + static struct attribute *f71805f_attr_pwm[]; 571 + 572 + static ssize_t set_pwm_enable(struct device *dev, struct device_attribute 573 + *devattr, const char *buf, size_t count) 574 + { 575 + struct f71805f_data *data = dev_get_drvdata(dev); 576 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 577 + int nr = attr->index; 578 + unsigned long val = simple_strtoul(buf, NULL, 10); 579 + u8 reg; 580 + 581 + if (val < 1 || val > 3) 582 + return -EINVAL; 583 + 584 + if (val > 1) { /* Automatic mode, user can't set PWM value */ 585 + if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], 586 + S_IRUGO)) 587 + dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1); 588 + } 589 + 590 + mutex_lock(&data->update_lock); 591 + reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr)) 592 + & ~FAN_CTRL_MODE_MASK; 593 + switch (val) { 594 + case 1: 595 + reg |= FAN_CTRL_MODE_MANUAL; 596 + break; 597 + case 2: 598 + reg |= FAN_CTRL_MODE_TEMPERATURE; 599 + break; 600 + case 3: 601 + reg |= FAN_CTRL_MODE_SPEED; 602 + break; 603 + } 604 + data->fan_ctrl[nr] = reg; 605 + f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg); 606 + mutex_unlock(&data->update_lock); 607 + 608 + if (val == 1) { /* Manual mode, user can set PWM value */ 609 + if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], 610 + S_IRUGO | S_IWUSR)) 611 + dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1); 612 + } 613 + 614 + return count; 615 + } 616 + 617 + static ssize_t set_pwm_freq(struct device *dev, struct device_attribute 618 + *devattr, const char *buf, size_t count) 619 + { 620 + struct f71805f_data *data = dev_get_drvdata(dev); 621 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 622 + int nr = attr->index; 623 + unsigned long val = simple_strtoul(buf, NULL, 10); 624 + 625 + mutex_lock(&data->update_lock); 626 + data->pwm_freq[nr] = pwm_freq_to_reg(val); 627 + f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]); 628 mutex_unlock(&data->update_lock); 629 630 return count; ··· 557 { 558 struct f71805f_data *data = f71805f_update_device(dev); 559 560 + return sprintf(buf, "%lu\n", data->alarms & 0x7ff); 561 } 562 563 static ssize_t show_alarms_fan(struct device *dev, struct device_attribute ··· 594 return sprintf(buf, "%s\n", data->name); 595 } 596 597 + static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0); 598 + static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, 599 + show_in0_max, set_in0_max, 0); 600 + static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, 601 + show_in0_min, set_in0_min, 0); 602 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); 603 static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, 604 show_in_max, set_in_max, 1); ··· 637 show_in_max, set_in_max, 8); 638 static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR, 639 show_in_min, set_in_min, 8); 640 + static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in0, NULL, 9); 641 + static SENSOR_DEVICE_ATTR(in9_max, S_IRUGO | S_IWUSR, 642 + show_in0_max, set_in0_max, 9); 643 + static SENSOR_DEVICE_ATTR(in9_min, S_IRUGO | S_IWUSR, 644 + show_in0_min, set_in0_min, 9); 645 + static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in0, NULL, 10); 646 + static SENSOR_DEVICE_ATTR(in10_max, S_IRUGO | S_IWUSR, 647 + show_in0_max, set_in0_max, 10); 648 + static SENSOR_DEVICE_ATTR(in10_min, S_IRUGO | S_IWUSR, 649 + show_in0_min, set_in0_min, 10); 650 651 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); 652 static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, 653 show_fan_min, set_fan_min, 0); 654 + static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, 655 + show_fan_target, set_fan_target, 0); 656 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); 657 static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, 658 show_fan_min, set_fan_min, 1); 659 + static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR, 660 + show_fan_target, set_fan_target, 1); 661 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); 662 static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, 663 show_fan_min, set_fan_min, 2); 664 + static SENSOR_DEVICE_ATTR(fan3_target, S_IRUGO | S_IWUSR, 665 + show_fan_target, set_fan_target, 2); 666 667 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 668 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, ··· 667 show_temp_hyst, set_temp_hyst, 2); 668 static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2); 669 670 + /* pwm (value) files are created read-only, write permission is 671 + then added or removed dynamically as needed */ 672 + static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0); 673 + static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, 674 + show_pwm_enable, set_pwm_enable, 0); 675 + static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, 676 + show_pwm_freq, set_pwm_freq, 0); 677 + static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); 678 + static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO, show_pwm, set_pwm, 1); 679 + static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, 680 + show_pwm_enable, set_pwm_enable, 1); 681 + static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO | S_IWUSR, 682 + show_pwm_freq, set_pwm_freq, 1); 683 + static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1); 684 + static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO, show_pwm, set_pwm, 2); 685 + static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, 686 + show_pwm_enable, set_pwm_enable, 2); 687 + static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR, 688 + show_pwm_freq, set_pwm_freq, 2); 689 + static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); 690 + 691 static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 692 static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 693 static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); ··· 676 static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); 677 static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); 678 static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8); 679 + static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9); 680 + static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10); 681 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11); 682 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12); 683 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13); ··· 689 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 690 691 static struct attribute *f71805f_attributes[] = { 692 + &sensor_dev_attr_in0_input.dev_attr.attr, 693 + &sensor_dev_attr_in0_max.dev_attr.attr, 694 + &sensor_dev_attr_in0_min.dev_attr.attr, 695 &sensor_dev_attr_in1_input.dev_attr.attr, 696 &sensor_dev_attr_in1_max.dev_attr.attr, 697 &sensor_dev_attr_in1_min.dev_attr.attr, ··· 701 &sensor_dev_attr_in3_input.dev_attr.attr, 702 &sensor_dev_attr_in3_max.dev_attr.attr, 703 &sensor_dev_attr_in3_min.dev_attr.attr, 704 &sensor_dev_attr_in5_input.dev_attr.attr, 705 &sensor_dev_attr_in5_max.dev_attr.attr, 706 &sensor_dev_attr_in5_min.dev_attr.attr, ··· 713 &sensor_dev_attr_in7_input.dev_attr.attr, 714 &sensor_dev_attr_in7_max.dev_attr.attr, 715 &sensor_dev_attr_in7_min.dev_attr.attr, 716 + 717 + &sensor_dev_attr_fan1_input.dev_attr.attr, 718 + &sensor_dev_attr_fan1_min.dev_attr.attr, 719 + &sensor_dev_attr_fan1_alarm.dev_attr.attr, 720 + &sensor_dev_attr_fan1_target.dev_attr.attr, 721 + &sensor_dev_attr_fan2_input.dev_attr.attr, 722 + &sensor_dev_attr_fan2_min.dev_attr.attr, 723 + &sensor_dev_attr_fan2_alarm.dev_attr.attr, 724 + &sensor_dev_attr_fan2_target.dev_attr.attr, 725 + &sensor_dev_attr_fan3_input.dev_attr.attr, 726 + &sensor_dev_attr_fan3_min.dev_attr.attr, 727 + &sensor_dev_attr_fan3_alarm.dev_attr.attr, 728 + &sensor_dev_attr_fan3_target.dev_attr.attr, 729 + 730 + &sensor_dev_attr_pwm1.dev_attr.attr, 731 + &sensor_dev_attr_pwm1_enable.dev_attr.attr, 732 + &sensor_dev_attr_pwm1_mode.dev_attr.attr, 733 + &sensor_dev_attr_pwm2.dev_attr.attr, 734 + &sensor_dev_attr_pwm2_enable.dev_attr.attr, 735 + &sensor_dev_attr_pwm2_mode.dev_attr.attr, 736 + &sensor_dev_attr_pwm3.dev_attr.attr, 737 + &sensor_dev_attr_pwm3_enable.dev_attr.attr, 738 + &sensor_dev_attr_pwm3_mode.dev_attr.attr, 739 740 &sensor_dev_attr_temp1_input.dev_attr.attr, 741 &sensor_dev_attr_temp1_max.dev_attr.attr, ··· 734 &sensor_dev_attr_in1_alarm.dev_attr.attr, 735 &sensor_dev_attr_in2_alarm.dev_attr.attr, 736 &sensor_dev_attr_in3_alarm.dev_attr.attr, 737 &sensor_dev_attr_in5_alarm.dev_attr.attr, 738 &sensor_dev_attr_in6_alarm.dev_attr.attr, 739 &sensor_dev_attr_in7_alarm.dev_attr.attr, 740 &dev_attr_alarms_in.attr, 741 &sensor_dev_attr_temp1_alarm.dev_attr.attr, 742 &sensor_dev_attr_temp2_alarm.dev_attr.attr, ··· 754 .attrs = f71805f_attributes, 755 }; 756 757 + static struct attribute *f71805f_attributes_optin[4][5] = { 758 { 759 + &sensor_dev_attr_in4_input.dev_attr.attr, 760 + &sensor_dev_attr_in4_max.dev_attr.attr, 761 + &sensor_dev_attr_in4_min.dev_attr.attr, 762 + &sensor_dev_attr_in4_alarm.dev_attr.attr, 763 NULL 764 }, { 765 + &sensor_dev_attr_in8_input.dev_attr.attr, 766 + &sensor_dev_attr_in8_max.dev_attr.attr, 767 + &sensor_dev_attr_in8_min.dev_attr.attr, 768 + &sensor_dev_attr_in8_alarm.dev_attr.attr, 769 NULL 770 }, { 771 + &sensor_dev_attr_in9_input.dev_attr.attr, 772 + &sensor_dev_attr_in9_max.dev_attr.attr, 773 + &sensor_dev_attr_in9_min.dev_attr.attr, 774 + &sensor_dev_attr_in9_alarm.dev_attr.attr, 775 + NULL 776 + }, { 777 + &sensor_dev_attr_in10_input.dev_attr.attr, 778 + &sensor_dev_attr_in10_max.dev_attr.attr, 779 + &sensor_dev_attr_in10_min.dev_attr.attr, 780 + &sensor_dev_attr_in10_alarm.dev_attr.attr, 781 NULL 782 } 783 }; 784 785 + static const struct attribute_group f71805f_group_optin[4] = { 786 + { .attrs = f71805f_attributes_optin[0] }, 787 + { .attrs = f71805f_attributes_optin[1] }, 788 + { .attrs = f71805f_attributes_optin[2] }, 789 + { .attrs = f71805f_attributes_optin[3] }, 790 + }; 791 + 792 + /* We don't include pwm_freq files in the arrays above, because they must be 793 + created conditionally (only if pwm_mode is 1 == PWM) */ 794 + static struct attribute *f71805f_attributes_pwm_freq[] = { 795 + &sensor_dev_attr_pwm1_freq.dev_attr.attr, 796 + &sensor_dev_attr_pwm2_freq.dev_attr.attr, 797 + &sensor_dev_attr_pwm3_freq.dev_attr.attr, 798 + NULL 799 + }; 800 + 801 + static const struct attribute_group f71805f_group_pwm_freq = { 802 + .attrs = f71805f_attributes_pwm_freq, 803 + }; 804 + 805 + /* We also need an indexed access to pwmN files to toggle writability */ 806 + static struct attribute *f71805f_attr_pwm[] = { 807 + &sensor_dev_attr_pwm1.dev_attr.attr, 808 + &sensor_dev_attr_pwm2.dev_attr.attr, 809 + &sensor_dev_attr_pwm3.dev_attr.attr, 810 }; 811 812 /* ··· 798 /* Fan monitoring can be disabled. If it is, we won't be polling 799 the register values, and won't create the related sysfs files. */ 800 for (i = 0; i < 3; i++) { 801 + data->fan_ctrl[i] = f71805f_read8(data, 802 + F71805F_REG_FAN_CTRL(i)); 803 + /* Clear latch full bit, else "speed mode" fan speed control 804 + doesn't work */ 805 + if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) { 806 + data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL; 807 + f71805f_write8(data, F71805F_REG_FAN_CTRL(i), 808 + data->fan_ctrl[i]); 809 + } 810 } 811 } 812 813 static int __devinit f71805f_probe(struct platform_device *pdev) 814 { 815 + struct f71805f_sio_data *sio_data = pdev->dev.platform_data; 816 struct f71805f_data *data; 817 struct resource *res; 818 int i, err; 819 + 820 + static const char *names[] = { 821 + "f71805f", 822 + "f71872f", 823 + }; 824 825 if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { 826 err = -ENOMEM; ··· 819 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 820 data->addr = res->start; 821 mutex_init(&data->lock); 822 + data->name = names[sio_data->kind]; 823 mutex_init(&data->update_lock); 824 825 platform_set_drvdata(pdev, data); 826 + 827 + /* Some voltage inputs depend on chip model and configuration */ 828 + switch (sio_data->kind) { 829 + case f71805f: 830 + data->has_in = 0x1ff; 831 + break; 832 + case f71872f: 833 + data->has_in = 0x6ef; 834 + if (sio_data->fnsel1 & 0x01) 835 + data->has_in |= (1 << 4); /* in4 */ 836 + if (sio_data->fnsel1 & 0x02) 837 + data->has_in |= (1 << 8); /* in8 */ 838 + break; 839 + } 840 841 /* Initialize the F71805F chip */ 842 f71805f_init_device(data); ··· 830 /* Register sysfs interface files */ 831 if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) 832 goto exit_free; 833 + if (data->has_in & (1 << 4)) { /* in4 */ 834 if ((err = sysfs_create_group(&pdev->dev.kobj, 835 + &f71805f_group_optin[0]))) 836 goto exit_remove_files; 837 + } 838 + if (data->has_in & (1 << 8)) { /* in8 */ 839 + if ((err = sysfs_create_group(&pdev->dev.kobj, 840 + &f71805f_group_optin[1]))) 841 + goto exit_remove_files; 842 + } 843 + if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */ 844 + if ((err = sysfs_create_group(&pdev->dev.kobj, 845 + &f71805f_group_optin[2]))) 846 + goto exit_remove_files; 847 + } 848 + if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */ 849 + if ((err = sysfs_create_group(&pdev->dev.kobj, 850 + &f71805f_group_optin[3]))) 851 + goto exit_remove_files; 852 + } 853 + for (i = 0; i < 3; i++) { 854 + /* If control mode is PWM, create pwm_freq file */ 855 + if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) { 856 + if ((err = sysfs_create_file(&pdev->dev.kobj, 857 + f71805f_attributes_pwm_freq[i]))) 858 + goto exit_remove_files; 859 + } 860 + /* If PWM is in manual mode, add write permission */ 861 + if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) { 862 + if ((err = sysfs_chmod_file(&pdev->dev.kobj, 863 + f71805f_attr_pwm[i], 864 + S_IRUGO | S_IWUSR))) { 865 + dev_err(&pdev->dev, "chmod +w pwm%d failed\n", 866 + i + 1); 867 + goto exit_remove_files; 868 + } 869 + } 870 } 871 872 data->class_dev = hwmon_device_register(&pdev->dev); ··· 849 850 exit_remove_files: 851 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); 852 + for (i = 0; i < 4; i++) 853 + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); 854 + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); 855 exit_free: 856 platform_set_drvdata(pdev, NULL); 857 kfree(data); ··· 866 platform_set_drvdata(pdev, NULL); 867 hwmon_device_unregister(data->class_dev); 868 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); 869 + for (i = 0; i < 4; i++) 870 + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); 871 + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); 872 kfree(data); 873 874 return 0; ··· 882 .remove = __devexit_p(f71805f_remove), 883 }; 884 885 + static int __init f71805f_device_add(unsigned short address, 886 + const struct f71805f_sio_data *sio_data) 887 { 888 struct resource res = { 889 .start = address, ··· 906 goto exit_device_put; 907 } 908 909 + pdev->dev.platform_data = kmalloc(sizeof(struct f71805f_sio_data), 910 + GFP_KERNEL); 911 + if (!pdev->dev.platform_data) { 912 + err = -ENOMEM; 913 + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); 914 + goto exit_device_put; 915 + } 916 + memcpy(pdev->dev.platform_data, sio_data, 917 + sizeof(struct f71805f_sio_data)); 918 + 919 err = platform_device_add(pdev); 920 if (err) { 921 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", 922 err); 923 + goto exit_kfree_data; 924 } 925 926 return 0; 927 928 + exit_kfree_data: 929 + kfree(pdev->dev.platform_data); 930 + pdev->dev.platform_data = NULL; 931 exit_device_put: 932 platform_device_put(pdev); 933 exit: 934 return err; 935 } 936 937 + static int __init f71805f_find(int sioaddr, unsigned short *address, 938 + struct f71805f_sio_data *sio_data) 939 { 940 int err = -ENODEV; 941 u16 devid; 942 + 943 + static const char *names[] = { 944 + "F71805F/FG", 945 + "F71872F/FG", 946 + }; 947 948 superio_enter(sioaddr); 949 ··· 933 goto exit; 934 935 devid = superio_inw(sioaddr, SIO_REG_DEVID); 936 + switch (devid) { 937 + case SIO_F71805F_ID: 938 + sio_data->kind = f71805f; 939 + break; 940 + case SIO_F71872F_ID: 941 + sio_data->kind = f71872f; 942 + sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1); 943 + break; 944 + default: 945 printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " 946 "skipping\n"); 947 goto exit; ··· 952 "skipping\n"); 953 goto exit; 954 } 955 + *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ 956 957 err = 0; 958 + printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n", 959 + names[sio_data->kind], *address, 960 + superio_inb(sioaddr, SIO_REG_DEVREV)); 961 962 exit: 963 superio_exit(sioaddr); ··· 966 { 967 int err; 968 unsigned short address; 969 + struct f71805f_sio_data sio_data; 970 971 + if (f71805f_find(0x2e, &address, &sio_data) 972 + && f71805f_find(0x4e, &address, &sio_data)) 973 return -ENODEV; 974 975 err = platform_driver_register(&f71805f_driver); ··· 976 goto exit; 977 978 /* Sets global pdev as a side effect */ 979 + err = f71805f_device_add(address, &sio_data); 980 if (err) 981 goto exit_driver; 982 ··· 990 991 static void __exit f71805f_exit(void) 992 { 993 + kfree(pdev->dev.platform_data); 994 + pdev->dev.platform_data = NULL; 995 platform_device_unregister(pdev); 996 + 997 platform_driver_unregister(&f71805f_driver); 998 } 999 1000 MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); 1001 MODULE_LICENSE("GPL"); 1002 + MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver"); 1003 1004 module_init(f71805f_init); 1005 module_exit(f71805f_exit);
+29 -39
drivers/hwmon/hdaps.c
··· 478 /* Module stuff */ 479 480 /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ 481 - static int hdaps_dmi_match(struct dmi_system_id *id) 482 { 483 printk(KERN_INFO "hdaps: %s detected.\n", id->ident); 484 return 1; 485 } 486 487 /* hdaps_dmi_match_invert - found an inverted match. */ 488 - static int hdaps_dmi_match_invert(struct dmi_system_id *id) 489 { 490 hdaps_invert = 1; 491 printk(KERN_INFO "hdaps: inverting axis readings.\n"); 492 return hdaps_dmi_match(id); 493 } 494 495 - #define HDAPS_DMI_MATCH_NORMAL(model) { \ 496 - .ident = "IBM " model, \ 497 .callback = hdaps_dmi_match, \ 498 .matches = { \ 499 - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \ 500 DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 501 } \ 502 } 503 504 - #define HDAPS_DMI_MATCH_INVERT(model) { \ 505 - .ident = "IBM " model, \ 506 .callback = hdaps_dmi_match_invert, \ 507 .matches = { \ 508 - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \ 509 DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 510 } \ 511 } 512 513 - #define HDAPS_DMI_MATCH_LENOVO(model) { \ 514 - .ident = "Lenovo " model, \ 515 - .callback = hdaps_dmi_match_invert, \ 516 - .matches = { \ 517 - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), \ 518 - DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 519 - } \ 520 - } 521 522 static int __init hdaps_init(void) 523 { 524 int ret; 525 - 526 - /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match 527 - "ThinkPad T42p", so the order of the entries matters */ 528 - struct dmi_system_id hdaps_whitelist[] = { 529 - HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), 530 - HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), 531 - HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), 532 - HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), 533 - HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"), 534 - HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), /* R52 (1846AQG) */ 535 - HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), 536 - HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), 537 - HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), 538 - HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), 539 - HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), 540 - HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), 541 - HDAPS_DMI_MATCH_LENOVO("ThinkPad T60"), 542 - HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), 543 - HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), 544 - HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), 545 - HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"), 546 - { .ident = NULL } 547 - }; 548 549 if (!dmi_check_system(hdaps_whitelist)) { 550 printk(KERN_WARNING "hdaps: supported laptop not found!\n");
··· 478 /* Module stuff */ 479 480 /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ 481 + static int __init hdaps_dmi_match(struct dmi_system_id *id) 482 { 483 printk(KERN_INFO "hdaps: %s detected.\n", id->ident); 484 return 1; 485 } 486 487 /* hdaps_dmi_match_invert - found an inverted match. */ 488 + static int __init hdaps_dmi_match_invert(struct dmi_system_id *id) 489 { 490 hdaps_invert = 1; 491 printk(KERN_INFO "hdaps: inverting axis readings.\n"); 492 return hdaps_dmi_match(id); 493 } 494 495 + #define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \ 496 + .ident = vendor " " model, \ 497 .callback = hdaps_dmi_match, \ 498 .matches = { \ 499 + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ 500 DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 501 } \ 502 } 503 504 + #define HDAPS_DMI_MATCH_INVERT(vendor, model) { \ 505 + .ident = vendor " " model, \ 506 .callback = hdaps_dmi_match_invert, \ 507 .matches = { \ 508 + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ 509 DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 510 } \ 511 } 512 513 + /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match 514 + "ThinkPad T42p", so the order of the entries matters. 515 + If your ThinkPad is not recognized, please update to latest 516 + BIOS. This is especially the case for some R52 ThinkPads. */ 517 + static struct dmi_system_id __initdata hdaps_whitelist[] = { 518 + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"), 519 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), 520 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), 521 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), 522 + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), 523 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), 524 + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), 525 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), 526 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), 527 + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), 528 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), 529 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), 530 + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), 531 + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), 532 + { .ident = NULL } 533 + }; 534 535 static int __init hdaps_init(void) 536 { 537 int ret; 538 539 if (!dmi_check_system(hdaps_whitelist)) { 540 printk(KERN_WARNING "hdaps: supported laptop not found!\n");
+2 -2
drivers/hwmon/hwmon-vid.c
··· 1 /* 2 hwmon-vid.c - VID/VRM/VRD voltage conversions 3 4 - Copyright (c) 2004 Rudolf Marek <r.marek@sh.cvut.cz> 5 6 Partly imported from i2c-vid.h of the lm_sensors project 7 Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> ··· 232 EXPORT_SYMBOL(vid_from_reg); 233 EXPORT_SYMBOL(vid_which_vrm); 234 235 - MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>"); 236 237 MODULE_DESCRIPTION("hwmon-vid driver"); 238 MODULE_LICENSE("GPL");
··· 1 /* 2 hwmon-vid.c - VID/VRM/VRD voltage conversions 3 4 + Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> 5 6 Partly imported from i2c-vid.h of the lm_sensors project 7 Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> ··· 232 EXPORT_SYMBOL(vid_from_reg); 233 EXPORT_SYMBOL(vid_which_vrm); 234 235 + MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); 236 237 MODULE_DESCRIPTION("hwmon-vid driver"); 238 MODULE_LICENSE("GPL");
+51 -151
drivers/hwmon/it87.c
··· 3 monitoring. 4 5 Supports: IT8705F Super I/O chip w/LPC interface 6 - IT8712F Super I/O chip w/LPC interface & SMBus 7 IT8716F Super I/O chip w/LPC interface 8 IT8718F Super I/O chip w/LPC interface 9 Sis950 A clone of the IT8705F ··· 41 #include <asm/io.h> 42 43 44 - /* Addresses to scan */ 45 - static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; 46 static unsigned short isa_address; 47 - 48 - /* Insmod parameters */ 49 - I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718); 50 51 #define REG 0x2e /* The register to read/write */ 52 #define DEV 0x07 /* Register: Logical device select */ ··· 158 #define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2) 159 #define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2) 160 161 - #define IT87_REG_I2C_ADDR 0x48 162 - 163 #define IT87_REG_VIN_ENABLE 0x50 164 #define IT87_REG_TEMP_ENABLE 0x51 165 ··· 236 }; 237 238 239 - static int it87_attach_adapter(struct i2c_adapter *adapter); 240 - static int it87_isa_attach_adapter(struct i2c_adapter *adapter); 241 - static int it87_detect(struct i2c_adapter *adapter, int address, int kind); 242 static int it87_detach_client(struct i2c_client *client); 243 244 static int it87_read_value(struct i2c_client *client, u8 reg); 245 - static int it87_write_value(struct i2c_client *client, u8 reg, u8 value); 246 static struct it87_data *it87_update_device(struct device *dev); 247 static int it87_check_pwm(struct i2c_client *client); 248 static void it87_init_client(struct i2c_client *client, struct it87_data *data); 249 250 - 251 - static struct i2c_driver it87_driver = { 252 - .driver = { 253 - .name = "it87", 254 - }, 255 - .id = I2C_DRIVERID_IT87, 256 - .attach_adapter = it87_attach_adapter, 257 - .detach_client = it87_detach_client, 258 - }; 259 260 static struct i2c_driver it87_isa_driver = { 261 .driver = { 262 .owner = THIS_MODULE, 263 .name = "it87-isa", 264 }, 265 - .attach_adapter = it87_isa_attach_adapter, 266 .detach_client = it87_detach_client, 267 }; 268 ··· 833 .attrs = it87_attributes_opt, 834 }; 835 836 - /* This function is called when: 837 - * it87_driver is inserted (when this module is loaded), for each 838 - available adapter 839 - * when a new adapter is inserted (and it87_driver is still present) */ 840 - static int it87_attach_adapter(struct i2c_adapter *adapter) 841 - { 842 - if (!(adapter->class & I2C_CLASS_HWMON)) 843 - return 0; 844 - return i2c_probe(adapter, &addr_data, it87_detect); 845 - } 846 - 847 - static int it87_isa_attach_adapter(struct i2c_adapter *adapter) 848 - { 849 - return it87_detect(adapter, isa_address, -1); 850 - } 851 - 852 /* SuperIO detection - will change isa_address if a chip is found */ 853 static int __init it87_find(unsigned short *address) 854 { ··· 883 } 884 885 /* This function is called by i2c_probe */ 886 - static int it87_detect(struct i2c_adapter *adapter, int address, int kind) 887 { 888 - int i; 889 struct i2c_client *new_client; 890 struct it87_data *data; 891 int err = 0; 892 - const char *name = ""; 893 - int is_isa = i2c_is_isa_adapter(adapter); 894 int enable_pwm_interface; 895 896 - if (!is_isa && 897 - !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 898 - goto ERROR0; 899 - 900 /* Reserve the ISA region */ 901 - if (is_isa) 902 - if (!request_region(address, IT87_EXTENT, 903 - it87_isa_driver.driver.name)) 904 - goto ERROR0; 905 - 906 - /* For now, we presume we have a valid client. We create the 907 - client structure, even though we cannot fill it completely yet. 908 - But it allows us to access it87_{read,write}_value. */ 909 910 if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) { 911 err = -ENOMEM; ··· 904 } 905 906 new_client = &data->client; 907 - if (is_isa) 908 - mutex_init(&data->lock); 909 i2c_set_clientdata(new_client, data); 910 - new_client->addr = address; 911 new_client->adapter = adapter; 912 - new_client->driver = is_isa ? &it87_isa_driver : &it87_driver; 913 - new_client->flags = 0; 914 915 /* Now, we do the remaining detection. */ 916 - 917 - if (kind < 0) { 918 - if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) 919 - || (!is_isa 920 - && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) { 921 - err = -ENODEV; 922 - goto ERROR2; 923 - } 924 } 925 926 /* Determine the chip type. */ 927 - if (kind <= 0) { 928 - i = it87_read_value(new_client, IT87_REG_CHIPID); 929 - if (i == 0x90) { 930 - kind = it87; 931 - if (is_isa) { 932 - switch (chip_type) { 933 - case IT8712F_DEVID: 934 - kind = it8712; 935 - break; 936 - case IT8716F_DEVID: 937 - kind = it8716; 938 - break; 939 - case IT8718F_DEVID: 940 - kind = it8718; 941 - break; 942 - } 943 - } 944 - } 945 - else { 946 - if (kind == 0) 947 - dev_info(&adapter->dev, 948 - "Ignoring 'force' parameter for unknown chip at " 949 - "adapter %d, address 0x%02x\n", 950 - i2c_adapter_id(adapter), address); 951 - err = -ENODEV; 952 - goto ERROR2; 953 - } 954 - } 955 - 956 - if (kind == it87) { 957 - name = "it87"; 958 - } else if (kind == it8712) { 959 name = "it8712"; 960 - } else if (kind == it8716) { 961 name = "it8716"; 962 - } else if (kind == it8718) { 963 name = "it8718"; 964 } 965 966 /* Fill in the remaining client fields and put it into the global list */ 967 strlcpy(new_client->name, name, I2C_NAME_SIZE); 968 - data->type = kind; 969 - data->valid = 0; 970 mutex_init(&data->update_lock); 971 972 /* Tell the I2C layer a new client has arrived */ 973 if ((err = i2c_attach_client(new_client))) 974 goto ERROR2; 975 - 976 - if (!is_isa) 977 - dev_info(&new_client->dev, "The I2C interface to IT87xxF " 978 - "hardware monitoring chips is deprecated. Please " 979 - "report if you still rely on it.\n"); 980 981 /* Check PWM configuration */ 982 enable_pwm_interface = it87_check_pwm(new_client); ··· 1053 ERROR2: 1054 kfree(data); 1055 ERROR1: 1056 - if (is_isa) 1057 - release_region(address, IT87_EXTENT); 1058 ERROR0: 1059 return err; 1060 } ··· 1070 if ((err = i2c_detach_client(client))) 1071 return err; 1072 1073 - if(i2c_is_isa_client(client)) 1074 - release_region(client->addr, IT87_EXTENT); 1075 kfree(data); 1076 1077 return 0; 1078 } 1079 1080 - /* The SMBus locks itself, but ISA access must be locked explicitly! 1081 - We don't want to lock the whole ISA bus, so we lock each client 1082 - separately. 1083 We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 1084 would slow down the IT87 access and should not be necessary. */ 1085 static int it87_read_value(struct i2c_client *client, u8 reg) 1086 { 1087 struct it87_data *data = i2c_get_clientdata(client); 1088 - 1089 int res; 1090 - if (i2c_is_isa_client(client)) { 1091 - mutex_lock(&data->lock); 1092 - outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); 1093 - res = inb_p(client->addr + IT87_DATA_REG_OFFSET); 1094 - mutex_unlock(&data->lock); 1095 - return res; 1096 - } else 1097 - return i2c_smbus_read_byte_data(client, reg); 1098 } 1099 1100 - /* The SMBus locks itself, but ISA access muse be locked explicitly! 1101 - We don't want to lock the whole ISA bus, so we lock each client 1102 - separately. 1103 We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 1104 would slow down the IT87 access and should not be necessary. */ 1105 - static int it87_write_value(struct i2c_client *client, u8 reg, u8 value) 1106 { 1107 struct it87_data *data = i2c_get_clientdata(client); 1108 1109 - if (i2c_is_isa_client(client)) { 1110 - mutex_lock(&data->lock); 1111 - outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); 1112 - outb_p(value, client->addr + IT87_DATA_REG_OFFSET); 1113 - mutex_unlock(&data->lock); 1114 - return 0; 1115 - } else 1116 - return i2c_smbus_write_byte_data(client, reg, value); 1117 } 1118 1119 /* Return 1 if and only if the PWM interface is safe to use */ ··· 1338 { 1339 int res; 1340 1341 - res = i2c_add_driver(&it87_driver); 1342 - if (res) 1343 return res; 1344 - 1345 - if (!it87_find(&isa_address)) { 1346 - res = i2c_isa_add_driver(&it87_isa_driver); 1347 - if (res) { 1348 - i2c_del_driver(&it87_driver); 1349 - return res; 1350 - } 1351 - } 1352 - 1353 - return 0; 1354 } 1355 1356 static void __exit sm_it87_exit(void) 1357 { 1358 - if (isa_address) 1359 - i2c_isa_del_driver(&it87_isa_driver); 1360 - i2c_del_driver(&it87_driver); 1361 } 1362 1363
··· 3 monitoring. 4 5 Supports: IT8705F Super I/O chip w/LPC interface 6 + IT8712F Super I/O chip w/LPC interface 7 IT8716F Super I/O chip w/LPC interface 8 IT8718F Super I/O chip w/LPC interface 9 Sis950 A clone of the IT8705F ··· 41 #include <asm/io.h> 42 43 44 static unsigned short isa_address; 45 + enum chips { it87, it8712, it8716, it8718 }; 46 47 #define REG 0x2e /* The register to read/write */ 48 #define DEV 0x07 /* Register: Logical device select */ ··· 162 #define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2) 163 #define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2) 164 165 #define IT87_REG_VIN_ENABLE 0x50 166 #define IT87_REG_TEMP_ENABLE 0x51 167 ··· 242 }; 243 244 245 + static int it87_detect(struct i2c_adapter *adapter); 246 static int it87_detach_client(struct i2c_client *client); 247 248 static int it87_read_value(struct i2c_client *client, u8 reg); 249 + static void it87_write_value(struct i2c_client *client, u8 reg, u8 value); 250 static struct it87_data *it87_update_device(struct device *dev); 251 static int it87_check_pwm(struct i2c_client *client); 252 static void it87_init_client(struct i2c_client *client, struct it87_data *data); 253 254 255 static struct i2c_driver it87_isa_driver = { 256 .driver = { 257 .owner = THIS_MODULE, 258 .name = "it87-isa", 259 }, 260 + .attach_adapter = it87_detect, 261 .detach_client = it87_detach_client, 262 }; 263 ··· 850 .attrs = it87_attributes_opt, 851 }; 852 853 /* SuperIO detection - will change isa_address if a chip is found */ 854 static int __init it87_find(unsigned short *address) 855 { ··· 916 } 917 918 /* This function is called by i2c_probe */ 919 + static int it87_detect(struct i2c_adapter *adapter) 920 { 921 struct i2c_client *new_client; 922 struct it87_data *data; 923 int err = 0; 924 + const char *name; 925 int enable_pwm_interface; 926 927 /* Reserve the ISA region */ 928 + if (!request_region(isa_address, IT87_EXTENT, 929 + it87_isa_driver.driver.name)){ 930 + err = -EBUSY; 931 + goto ERROR0; 932 + } 933 934 if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) { 935 err = -ENOMEM; ··· 946 } 947 948 new_client = &data->client; 949 + mutex_init(&data->lock); 950 i2c_set_clientdata(new_client, data); 951 + new_client->addr = isa_address; 952 new_client->adapter = adapter; 953 + new_client->driver = &it87_isa_driver; 954 955 /* Now, we do the remaining detection. */ 956 + if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) 957 + || it87_read_value(new_client, IT87_REG_CHIPID) != 0x90) { 958 + err = -ENODEV; 959 + goto ERROR2; 960 } 961 962 /* Determine the chip type. */ 963 + switch (chip_type) { 964 + case IT8712F_DEVID: 965 + data->type = it8712; 966 name = "it8712"; 967 + break; 968 + case IT8716F_DEVID: 969 + data->type = it8716; 970 name = "it8716"; 971 + break; 972 + case IT8718F_DEVID: 973 + data->type = it8718; 974 name = "it8718"; 975 + break; 976 + default: 977 + data->type = it87; 978 + name = "it87"; 979 } 980 981 /* Fill in the remaining client fields and put it into the global list */ 982 strlcpy(new_client->name, name, I2C_NAME_SIZE); 983 mutex_init(&data->update_lock); 984 985 /* Tell the I2C layer a new client has arrived */ 986 if ((err = i2c_attach_client(new_client))) 987 goto ERROR2; 988 989 /* Check PWM configuration */ 990 enable_pwm_interface = it87_check_pwm(new_client); ··· 1129 ERROR2: 1130 kfree(data); 1131 ERROR1: 1132 + release_region(isa_address, IT87_EXTENT); 1133 ERROR0: 1134 return err; 1135 } ··· 1147 if ((err = i2c_detach_client(client))) 1148 return err; 1149 1150 + release_region(client->addr, IT87_EXTENT); 1151 kfree(data); 1152 1153 return 0; 1154 } 1155 1156 + /* ISA access must be locked explicitly! 1157 We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 1158 would slow down the IT87 access and should not be necessary. */ 1159 static int it87_read_value(struct i2c_client *client, u8 reg) 1160 { 1161 struct it87_data *data = i2c_get_clientdata(client); 1162 int res; 1163 + 1164 + mutex_lock(&data->lock); 1165 + outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); 1166 + res = inb_p(client->addr + IT87_DATA_REG_OFFSET); 1167 + mutex_unlock(&data->lock); 1168 + 1169 + return res; 1170 } 1171 1172 + /* ISA access must be locked explicitly! 1173 We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 1174 would slow down the IT87 access and should not be necessary. */ 1175 + static void it87_write_value(struct i2c_client *client, u8 reg, u8 value) 1176 { 1177 struct it87_data *data = i2c_get_clientdata(client); 1178 1179 + mutex_lock(&data->lock); 1180 + outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); 1181 + outb_p(value, client->addr + IT87_DATA_REG_OFFSET); 1182 + mutex_unlock(&data->lock); 1183 } 1184 1185 /* Return 1 if and only if the PWM interface is safe to use */ ··· 1426 { 1427 int res; 1428 1429 + if ((res = it87_find(&isa_address))) 1430 return res; 1431 + return i2c_isa_add_driver(&it87_isa_driver); 1432 } 1433 1434 static void __exit sm_it87_exit(void) 1435 { 1436 + i2c_isa_del_driver(&it87_isa_driver); 1437 } 1438 1439
+2 -2
drivers/hwmon/k8temp.c
··· 1 /* 2 * k8temp.c - Linux kernel module for hardware monitoring 3 * 4 - * Copyright (C) 2006 Rudolf Marek <r.marek@sh.cvut.cz> 5 * 6 * Inspired from the w83785 and amd756 drivers. 7 * ··· 286 pci_unregister_driver(&k8temp_driver); 287 } 288 289 - MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>"); 290 MODULE_DESCRIPTION("AMD K8 core temperature monitor"); 291 MODULE_LICENSE("GPL"); 292
··· 1 /* 2 * k8temp.c - Linux kernel module for hardware monitoring 3 * 4 + * Copyright (C) 2006 Rudolf Marek <r.marek@assembler.cz> 5 * 6 * Inspired from the w83785 and amd756 drivers. 7 * ··· 286 pci_unregister_driver(&k8temp_driver); 287 } 288 289 + MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); 290 MODULE_DESCRIPTION("AMD K8 core temperature monitor"); 291 MODULE_LICENSE("GPL"); 292
+1 -1
drivers/hwmon/pc87360.c
··· 1000 (i&0x02) ? "external" : "internal"); 1001 1002 data->vid_conf = confreg[3]; 1003 - data->vrm = 90; 1004 } 1005 1006 /* Fan clock dividers may be needed before any data is read */
··· 1000 (i&0x02) ? "external" : "internal"); 1001 1002 data->vid_conf = confreg[3]; 1003 + data->vrm = vid_which_vrm(); 1004 } 1005 1006 /* Fan clock dividers may be needed before any data is read */
+627
drivers/hwmon/pc87427.c
···
··· 1 + /* 2 + * pc87427.c - hardware monitoring driver for the 3 + * National Semiconductor PC87427 Super-I/O chip 4 + * Copyright (C) 2006 Jean Delvare <khali@linux-fr.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 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 + * Supports the following chips: 16 + * 17 + * Chip #vin #fan #pwm #temp devid 18 + * PC87427 - 8 - - 0xF2 19 + * 20 + * This driver assumes that no more than one chip is present. 21 + * Only fan inputs are supported so far, although the chip can do much more. 22 + */ 23 + 24 + #include <linux/module.h> 25 + #include <linux/init.h> 26 + #include <linux/slab.h> 27 + #include <linux/jiffies.h> 28 + #include <linux/platform_device.h> 29 + #include <linux/hwmon.h> 30 + #include <linux/hwmon-sysfs.h> 31 + #include <linux/err.h> 32 + #include <linux/mutex.h> 33 + #include <linux/sysfs.h> 34 + #include <asm/io.h> 35 + 36 + static struct platform_device *pdev; 37 + 38 + #define DRVNAME "pc87427" 39 + 40 + /* The lock mutex protects both the I/O accesses (needed because the 41 + device is using banked registers) and the register cache (needed to keep 42 + the data in the registers and the cache in sync at any time). */ 43 + struct pc87427_data { 44 + struct class_device *class_dev; 45 + struct mutex lock; 46 + int address[2]; 47 + const char *name; 48 + 49 + unsigned long last_updated; /* in jiffies */ 50 + u8 fan_enabled; /* bit vector */ 51 + u16 fan[8]; /* register values */ 52 + u16 fan_min[8]; /* register values */ 53 + u8 fan_status[8]; /* register values */ 54 + }; 55 + 56 + /* 57 + * Super-I/O registers and operations 58 + */ 59 + 60 + #define SIOREG_LDSEL 0x07 /* Logical device select */ 61 + #define SIOREG_DEVID 0x20 /* Device ID */ 62 + #define SIOREG_ACT 0x30 /* Device activation */ 63 + #define SIOREG_MAP 0x50 /* I/O or memory mapping */ 64 + #define SIOREG_IOBASE 0x60 /* I/O base address */ 65 + 66 + static const u8 logdev[2] = { 0x09, 0x14 }; 67 + static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" }; 68 + #define LD_FAN 0 69 + #define LD_IN 1 70 + #define LD_TEMP 1 71 + 72 + static inline void superio_outb(int sioaddr, int reg, int val) 73 + { 74 + outb(reg, sioaddr); 75 + outb(val, sioaddr + 1); 76 + } 77 + 78 + static inline int superio_inb(int sioaddr, int reg) 79 + { 80 + outb(reg, sioaddr); 81 + return inb(sioaddr + 1); 82 + } 83 + 84 + static inline void superio_exit(int sioaddr) 85 + { 86 + outb(0x02, sioaddr); 87 + outb(0x02, sioaddr + 1); 88 + } 89 + 90 + /* 91 + * Logical devices 92 + */ 93 + 94 + #define REGION_LENGTH 32 95 + #define PC87427_REG_BANK 0x0f 96 + #define BANK_FM(nr) (nr) 97 + #define BANK_FT(nr) (0x08 + (nr)) 98 + #define BANK_FC(nr) (0x10 + (nr) * 2) 99 + 100 + /* 101 + * I/O access functions 102 + */ 103 + 104 + /* ldi is the logical device index */ 105 + static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg) 106 + { 107 + return inb(data->address[ldi] + reg); 108 + } 109 + 110 + /* Must be called with data->lock held, except during init */ 111 + static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi, 112 + u8 bank, u8 reg) 113 + { 114 + outb(bank, data->address[ldi] + PC87427_REG_BANK); 115 + return inb(data->address[ldi] + reg); 116 + } 117 + 118 + /* Must be called with data->lock held, except during init */ 119 + static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi, 120 + u8 bank, u8 reg, u8 value) 121 + { 122 + outb(bank, data->address[ldi] + PC87427_REG_BANK); 123 + outb(value, data->address[ldi] + reg); 124 + } 125 + 126 + /* 127 + * Fan registers and conversions 128 + */ 129 + 130 + /* fan data registers are 16-bit wide */ 131 + #define PC87427_REG_FAN 0x12 132 + #define PC87427_REG_FAN_MIN 0x14 133 + #define PC87427_REG_FAN_STATUS 0x10 134 + 135 + #define FAN_STATUS_STALL (1 << 3) 136 + #define FAN_STATUS_LOSPD (1 << 1) 137 + #define FAN_STATUS_MONEN (1 << 0) 138 + 139 + /* Dedicated function to read all registers related to a given fan input. 140 + This saves us quite a few locks and bank selections. 141 + Must be called with data->lock held. 142 + nr is from 0 to 7 */ 143 + static void pc87427_readall_fan(struct pc87427_data *data, u8 nr) 144 + { 145 + int iobase = data->address[LD_FAN]; 146 + 147 + outb(BANK_FM(nr), iobase + PC87427_REG_BANK); 148 + data->fan[nr] = inw(iobase + PC87427_REG_FAN); 149 + data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN); 150 + data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS); 151 + /* Clear fan alarm bits */ 152 + outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS); 153 + } 154 + 155 + /* The 2 LSB of fan speed registers are used for something different. 156 + The actual 2 LSB of the measurements are not available. */ 157 + static inline unsigned long fan_from_reg(u16 reg) 158 + { 159 + reg &= 0xfffc; 160 + if (reg == 0x0000 || reg == 0xfffc) 161 + return 0; 162 + return 5400000UL / reg; 163 + } 164 + 165 + /* The 2 LSB of the fan speed limit registers are not significant. */ 166 + static inline u16 fan_to_reg(unsigned long val) 167 + { 168 + if (val < 83UL) 169 + return 0xffff; 170 + if (val >= 1350000UL) 171 + return 0x0004; 172 + return ((1350000UL + val / 2) / val) << 2; 173 + } 174 + 175 + /* 176 + * Data interface 177 + */ 178 + 179 + static struct pc87427_data *pc87427_update_device(struct device *dev) 180 + { 181 + struct pc87427_data *data = dev_get_drvdata(dev); 182 + int i; 183 + 184 + mutex_lock(&data->lock); 185 + if (!time_after(jiffies, data->last_updated + HZ) 186 + && data->last_updated) 187 + goto done; 188 + 189 + /* Fans */ 190 + for (i = 0; i < 8; i++) { 191 + if (!(data->fan_enabled & (1 << i))) 192 + continue; 193 + pc87427_readall_fan(data, i); 194 + } 195 + data->last_updated = jiffies; 196 + 197 + done: 198 + mutex_unlock(&data->lock); 199 + return data; 200 + } 201 + 202 + static ssize_t show_fan_input(struct device *dev, struct device_attribute 203 + *devattr, char *buf) 204 + { 205 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 206 + struct pc87427_data *data = pc87427_update_device(dev); 207 + int nr = attr->index; 208 + 209 + return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr])); 210 + } 211 + 212 + static ssize_t show_fan_min(struct device *dev, struct device_attribute 213 + *devattr, char *buf) 214 + { 215 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 216 + struct pc87427_data *data = pc87427_update_device(dev); 217 + int nr = attr->index; 218 + 219 + return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr])); 220 + } 221 + 222 + static ssize_t show_fan_alarm(struct device *dev, struct device_attribute 223 + *devattr, char *buf) 224 + { 225 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 226 + struct pc87427_data *data = pc87427_update_device(dev); 227 + int nr = attr->index; 228 + 229 + return sprintf(buf, "%d\n", !!(data->fan_status[nr] 230 + & FAN_STATUS_LOSPD)); 231 + } 232 + 233 + static ssize_t show_fan_fault(struct device *dev, struct device_attribute 234 + *devattr, char *buf) 235 + { 236 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 237 + struct pc87427_data *data = pc87427_update_device(dev); 238 + int nr = attr->index; 239 + 240 + return sprintf(buf, "%d\n", !!(data->fan_status[nr] 241 + & FAN_STATUS_STALL)); 242 + } 243 + 244 + static ssize_t set_fan_min(struct device *dev, struct device_attribute 245 + *devattr, const char *buf, size_t count) 246 + { 247 + struct pc87427_data *data = dev_get_drvdata(dev); 248 + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 249 + int nr = attr->index; 250 + unsigned long val = simple_strtoul(buf, NULL, 10); 251 + int iobase = data->address[LD_FAN]; 252 + 253 + mutex_lock(&data->lock); 254 + outb(BANK_FM(nr), iobase + PC87427_REG_BANK); 255 + /* The low speed limit registers are read-only while monitoring 256 + is enabled, so we have to disable monitoring, then change the 257 + limit, and finally enable monitoring again. */ 258 + outb(0, iobase + PC87427_REG_FAN_STATUS); 259 + data->fan_min[nr] = fan_to_reg(val); 260 + outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN); 261 + outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS); 262 + mutex_unlock(&data->lock); 263 + 264 + return count; 265 + } 266 + 267 + static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); 268 + static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); 269 + static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2); 270 + static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3); 271 + static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4); 272 + static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5); 273 + static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6); 274 + static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7); 275 + 276 + static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, 277 + show_fan_min, set_fan_min, 0); 278 + static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, 279 + show_fan_min, set_fan_min, 1); 280 + static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, 281 + show_fan_min, set_fan_min, 2); 282 + static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, 283 + show_fan_min, set_fan_min, 3); 284 + static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, 285 + show_fan_min, set_fan_min, 4); 286 + static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, 287 + show_fan_min, set_fan_min, 5); 288 + static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, 289 + show_fan_min, set_fan_min, 6); 290 + static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, 291 + show_fan_min, set_fan_min, 7); 292 + 293 + static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0); 294 + static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1); 295 + static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2); 296 + static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3); 297 + static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4); 298 + static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5); 299 + static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6); 300 + static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7); 301 + 302 + static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0); 303 + static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1); 304 + static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2); 305 + static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3); 306 + static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4); 307 + static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5); 308 + static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6); 309 + static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7); 310 + 311 + static struct attribute *pc87427_attributes_fan[8][5] = { 312 + { 313 + &sensor_dev_attr_fan1_input.dev_attr.attr, 314 + &sensor_dev_attr_fan1_min.dev_attr.attr, 315 + &sensor_dev_attr_fan1_alarm.dev_attr.attr, 316 + &sensor_dev_attr_fan1_fault.dev_attr.attr, 317 + NULL 318 + }, { 319 + &sensor_dev_attr_fan2_input.dev_attr.attr, 320 + &sensor_dev_attr_fan2_min.dev_attr.attr, 321 + &sensor_dev_attr_fan2_alarm.dev_attr.attr, 322 + &sensor_dev_attr_fan2_fault.dev_attr.attr, 323 + NULL 324 + }, { 325 + &sensor_dev_attr_fan3_input.dev_attr.attr, 326 + &sensor_dev_attr_fan3_min.dev_attr.attr, 327 + &sensor_dev_attr_fan3_alarm.dev_attr.attr, 328 + &sensor_dev_attr_fan3_fault.dev_attr.attr, 329 + NULL 330 + }, { 331 + &sensor_dev_attr_fan4_input.dev_attr.attr, 332 + &sensor_dev_attr_fan4_min.dev_attr.attr, 333 + &sensor_dev_attr_fan4_alarm.dev_attr.attr, 334 + &sensor_dev_attr_fan4_fault.dev_attr.attr, 335 + NULL 336 + }, { 337 + &sensor_dev_attr_fan5_input.dev_attr.attr, 338 + &sensor_dev_attr_fan5_min.dev_attr.attr, 339 + &sensor_dev_attr_fan5_alarm.dev_attr.attr, 340 + &sensor_dev_attr_fan5_fault.dev_attr.attr, 341 + NULL 342 + }, { 343 + &sensor_dev_attr_fan6_input.dev_attr.attr, 344 + &sensor_dev_attr_fan6_min.dev_attr.attr, 345 + &sensor_dev_attr_fan6_alarm.dev_attr.attr, 346 + &sensor_dev_attr_fan6_fault.dev_attr.attr, 347 + NULL 348 + }, { 349 + &sensor_dev_attr_fan7_input.dev_attr.attr, 350 + &sensor_dev_attr_fan7_min.dev_attr.attr, 351 + &sensor_dev_attr_fan7_alarm.dev_attr.attr, 352 + &sensor_dev_attr_fan7_fault.dev_attr.attr, 353 + NULL 354 + }, { 355 + &sensor_dev_attr_fan8_input.dev_attr.attr, 356 + &sensor_dev_attr_fan8_min.dev_attr.attr, 357 + &sensor_dev_attr_fan8_alarm.dev_attr.attr, 358 + &sensor_dev_attr_fan8_fault.dev_attr.attr, 359 + NULL 360 + } 361 + }; 362 + 363 + static const struct attribute_group pc87427_group_fan[8] = { 364 + { .attrs = pc87427_attributes_fan[0] }, 365 + { .attrs = pc87427_attributes_fan[1] }, 366 + { .attrs = pc87427_attributes_fan[2] }, 367 + { .attrs = pc87427_attributes_fan[3] }, 368 + { .attrs = pc87427_attributes_fan[4] }, 369 + { .attrs = pc87427_attributes_fan[5] }, 370 + { .attrs = pc87427_attributes_fan[6] }, 371 + { .attrs = pc87427_attributes_fan[7] }, 372 + }; 373 + 374 + static ssize_t show_name(struct device *dev, struct device_attribute 375 + *devattr, char *buf) 376 + { 377 + struct pc87427_data *data = dev_get_drvdata(dev); 378 + 379 + return sprintf(buf, "%s\n", data->name); 380 + } 381 + static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 382 + 383 + 384 + /* 385 + * Device detection, attach and detach 386 + */ 387 + 388 + static void __devinit pc87427_init_device(struct device *dev) 389 + { 390 + struct pc87427_data *data = dev_get_drvdata(dev); 391 + int i; 392 + u8 reg; 393 + 394 + /* The FMC module should be ready */ 395 + reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK); 396 + if (!(reg & 0x80)) 397 + dev_warn(dev, "FMC module not ready!\n"); 398 + 399 + /* Check which fans are enabled */ 400 + for (i = 0; i < 8; i++) { 401 + reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i), 402 + PC87427_REG_FAN_STATUS); 403 + if (reg & FAN_STATUS_MONEN) 404 + data->fan_enabled |= (1 << i); 405 + } 406 + 407 + if (!data->fan_enabled) { 408 + dev_dbg(dev, "Enabling all fan inputs\n"); 409 + for (i = 0; i < 8; i++) 410 + pc87427_write8_bank(data, LD_FAN, BANK_FM(i), 411 + PC87427_REG_FAN_STATUS, 412 + FAN_STATUS_MONEN); 413 + data->fan_enabled = 0xff; 414 + } 415 + } 416 + 417 + static int __devinit pc87427_probe(struct platform_device *pdev) 418 + { 419 + struct pc87427_data *data; 420 + struct resource *res; 421 + int i, err; 422 + 423 + if (!(data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL))) { 424 + err = -ENOMEM; 425 + printk(KERN_ERR DRVNAME ": Out of memory\n"); 426 + goto exit; 427 + } 428 + 429 + /* This will need to be revisited when we add support for 430 + temperature and voltage monitoring. */ 431 + res = platform_get_resource(pdev, IORESOURCE_IO, 0); 432 + data->address[0] = res->start; 433 + 434 + mutex_init(&data->lock); 435 + data->name = "pc87427"; 436 + platform_set_drvdata(pdev, data); 437 + pc87427_init_device(&pdev->dev); 438 + 439 + /* Register sysfs hooks */ 440 + if ((err = device_create_file(&pdev->dev, &dev_attr_name))) 441 + goto exit_kfree; 442 + for (i = 0; i < 8; i++) { 443 + if (!(data->fan_enabled & (1 << i))) 444 + continue; 445 + if ((err = sysfs_create_group(&pdev->dev.kobj, 446 + &pc87427_group_fan[i]))) 447 + goto exit_remove_files; 448 + } 449 + 450 + data->class_dev = hwmon_device_register(&pdev->dev); 451 + if (IS_ERR(data->class_dev)) { 452 + err = PTR_ERR(data->class_dev); 453 + dev_err(&pdev->dev, "Class registration failed (%d)\n", err); 454 + goto exit_remove_files; 455 + } 456 + 457 + return 0; 458 + 459 + exit_remove_files: 460 + for (i = 0; i < 8; i++) { 461 + if (!(data->fan_enabled & (1 << i))) 462 + continue; 463 + sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); 464 + } 465 + exit_kfree: 466 + platform_set_drvdata(pdev, NULL); 467 + kfree(data); 468 + exit: 469 + return err; 470 + } 471 + 472 + static int __devexit pc87427_remove(struct platform_device *pdev) 473 + { 474 + struct pc87427_data *data = platform_get_drvdata(pdev); 475 + int i; 476 + 477 + platform_set_drvdata(pdev, NULL); 478 + hwmon_device_unregister(data->class_dev); 479 + device_remove_file(&pdev->dev, &dev_attr_name); 480 + for (i = 0; i < 8; i++) { 481 + if (!(data->fan_enabled & (1 << i))) 482 + continue; 483 + sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); 484 + } 485 + kfree(data); 486 + 487 + return 0; 488 + } 489 + 490 + 491 + static struct platform_driver pc87427_driver = { 492 + .driver = { 493 + .owner = THIS_MODULE, 494 + .name = DRVNAME, 495 + }, 496 + .probe = pc87427_probe, 497 + .remove = __devexit_p(pc87427_remove), 498 + }; 499 + 500 + static int __init pc87427_device_add(unsigned short address) 501 + { 502 + struct resource res = { 503 + .start = address, 504 + .end = address + REGION_LENGTH - 1, 505 + .name = logdev_str[0], 506 + .flags = IORESOURCE_IO, 507 + }; 508 + int err; 509 + 510 + pdev = platform_device_alloc(DRVNAME, address); 511 + if (!pdev) { 512 + err = -ENOMEM; 513 + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); 514 + goto exit; 515 + } 516 + 517 + err = platform_device_add_resources(pdev, &res, 1); 518 + if (err) { 519 + printk(KERN_ERR DRVNAME ": Device resource addition failed " 520 + "(%d)\n", err); 521 + goto exit_device_put; 522 + } 523 + 524 + err = platform_device_add(pdev); 525 + if (err) { 526 + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", 527 + err); 528 + goto exit_device_put; 529 + } 530 + 531 + return 0; 532 + 533 + exit_device_put: 534 + platform_device_put(pdev); 535 + exit: 536 + return err; 537 + } 538 + 539 + static int __init pc87427_find(int sioaddr, unsigned short *address) 540 + { 541 + u16 val; 542 + int i, err = 0; 543 + 544 + /* Identify device */ 545 + val = superio_inb(sioaddr, SIOREG_DEVID); 546 + if (val != 0xf2) { /* PC87427 */ 547 + err = -ENODEV; 548 + goto exit; 549 + } 550 + 551 + for (i = 0; i < 2; i++) { 552 + address[i] = 0; 553 + /* Select logical device */ 554 + superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]); 555 + 556 + val = superio_inb(sioaddr, SIOREG_ACT); 557 + if (!(val & 0x01)) { 558 + printk(KERN_INFO DRVNAME ": Logical device 0x%02x " 559 + "not activated\n", logdev[i]); 560 + continue; 561 + } 562 + 563 + val = superio_inb(sioaddr, SIOREG_MAP); 564 + if (val & 0x01) { 565 + printk(KERN_WARNING DRVNAME ": Logical device 0x%02x " 566 + "is memory-mapped, can't use\n", logdev[i]); 567 + continue; 568 + } 569 + 570 + val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) 571 + | superio_inb(sioaddr, SIOREG_IOBASE + 1); 572 + if (!val) { 573 + printk(KERN_INFO DRVNAME ": I/O base address not set " 574 + "for logical device 0x%02x\n", logdev[i]); 575 + continue; 576 + } 577 + address[i] = val; 578 + } 579 + 580 + exit: 581 + superio_exit(sioaddr); 582 + return err; 583 + } 584 + 585 + static int __init pc87427_init(void) 586 + { 587 + int err; 588 + unsigned short address[2]; 589 + 590 + if (pc87427_find(0x2e, address) 591 + && pc87427_find(0x4e, address)) 592 + return -ENODEV; 593 + 594 + /* For now the driver only handles fans so we only care about the 595 + first address. */ 596 + if (!address[0]) 597 + return -ENODEV; 598 + 599 + err = platform_driver_register(&pc87427_driver); 600 + if (err) 601 + goto exit; 602 + 603 + /* Sets global pdev as a side effect */ 604 + err = pc87427_device_add(address[0]); 605 + if (err) 606 + goto exit_driver; 607 + 608 + return 0; 609 + 610 + exit_driver: 611 + platform_driver_unregister(&pc87427_driver); 612 + exit: 613 + return err; 614 + } 615 + 616 + static void __exit pc87427_exit(void) 617 + { 618 + platform_device_unregister(pdev); 619 + platform_driver_unregister(&pc87427_driver); 620 + } 621 + 622 + MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); 623 + MODULE_DESCRIPTION("PC87427 hardware monitoring driver"); 624 + MODULE_LICENSE("GPL"); 625 + 626 + module_init(pc87427_init); 627 + module_exit(pc87427_exit);
+1 -1
drivers/hwmon/w83627ehf.c
··· 3 the Winbond W83627EHF Super-I/O chip 4 Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> 5 Copyright (C) 2006 Yuan Mu (Winbond), 6 - Rudolf Marek <r.marek@sh.cvut.cz> 7 David Hubbard <david.c.hubbard@gmail.com> 8 9 Shamelessly ripped from the w83627hf driver
··· 3 the Winbond W83627EHF Super-I/O chip 4 Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> 5 Copyright (C) 2006 Yuan Mu (Winbond), 6 + Rudolf Marek <r.marek@assembler.cz> 7 David Hubbard <david.c.hubbard@gmail.com> 8 9 Shamelessly ripped from the w83627hf driver
+1 -1
drivers/hwmon/w83792d.c
··· 3 monitoring 4 Copyright (C) 2004, 2005 Winbond Electronics Corp. 5 Chunhao Huang <DZShen@Winbond.com.tw>, 6 - Rudolf Marek <r.marek@sh.cvut.cz> 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
··· 3 monitoring 4 Copyright (C) 2004, 2005 Winbond Electronics Corp. 5 Chunhao Huang <DZShen@Winbond.com.tw>, 6 + Rudolf Marek <r.marek@assembler.cz> 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
+1609
drivers/hwmon/w83793.c
···
··· 1 + /* 2 + w83793.c - Linux kernel driver for hardware monitoring 3 + Copyright (C) 2006 Winbond Electronics Corp. 4 + Yuan Mu 5 + Rudolf Marek <r.marek@assembler.cz> 6 + 7 + This program is free software; you can redistribute it and/or modify 8 + it under the terms of the GNU General Public License as published by 9 + the Free Software Foundation - version 2. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 + 02110-1301 USA. 20 + */ 21 + 22 + /* 23 + Supports following chips: 24 + 25 + Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA 26 + w83793 10 12 8 6 0x7b 0x5ca3 yes no 27 + */ 28 + 29 + #include <linux/module.h> 30 + #include <linux/init.h> 31 + #include <linux/slab.h> 32 + #include <linux/i2c.h> 33 + #include <linux/hwmon.h> 34 + #include <linux/hwmon-vid.h> 35 + #include <linux/hwmon-sysfs.h> 36 + #include <linux/err.h> 37 + #include <linux/mutex.h> 38 + 39 + /* Addresses to scan */ 40 + static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; 41 + 42 + /* Insmod parameters */ 43 + I2C_CLIENT_INSMOD_1(w83793); 44 + I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 45 + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 46 + 47 + static int reset; 48 + module_param(reset, bool, 0); 49 + MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); 50 + 51 + /* 52 + Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved 53 + as ID, Bank Select registers 54 + */ 55 + #define W83793_REG_BANKSEL 0x00 56 + #define W83793_REG_VENDORID 0x0d 57 + #define W83793_REG_CHIPID 0x0e 58 + #define W83793_REG_DEVICEID 0x0f 59 + 60 + #define W83793_REG_CONFIG 0x40 61 + #define W83793_REG_MFC 0x58 62 + #define W83793_REG_FANIN_CTRL 0x5c 63 + #define W83793_REG_FANIN_SEL 0x5d 64 + #define W83793_REG_I2C_ADDR 0x0b 65 + #define W83793_REG_I2C_SUBADDR 0x0c 66 + #define W83793_REG_VID_INA 0x05 67 + #define W83793_REG_VID_INB 0x06 68 + #define W83793_REG_VID_LATCHA 0x07 69 + #define W83793_REG_VID_LATCHB 0x08 70 + #define W83793_REG_VID_CTRL 0x59 71 + 72 + static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f }; 73 + 74 + #define TEMP_READ 0 75 + #define TEMP_CRIT 1 76 + #define TEMP_CRIT_HYST 2 77 + #define TEMP_WARN 3 78 + #define TEMP_WARN_HYST 4 79 + /* only crit and crit_hyst affect real-time alarm status 80 + current crit crit_hyst warn warn_hyst */ 81 + static u16 W83793_REG_TEMP[][5] = { 82 + {0x1c, 0x78, 0x79, 0x7a, 0x7b}, 83 + {0x1d, 0x7c, 0x7d, 0x7e, 0x7f}, 84 + {0x1e, 0x80, 0x81, 0x82, 0x83}, 85 + {0x1f, 0x84, 0x85, 0x86, 0x87}, 86 + {0x20, 0x88, 0x89, 0x8a, 0x8b}, 87 + {0x21, 0x8c, 0x8d, 0x8e, 0x8f}, 88 + }; 89 + 90 + #define W83793_REG_TEMP_LOW_BITS 0x22 91 + 92 + #define W83793_REG_BEEP(index) (0x53 + (index)) 93 + #define W83793_REG_ALARM(index) (0x4b + (index)) 94 + 95 + #define W83793_REG_CLR_CHASSIS 0x4a /* SMI MASK4 */ 96 + #define W83793_REG_IRQ_CTRL 0x50 97 + #define W83793_REG_OVT_CTRL 0x51 98 + #define W83793_REG_OVT_BEEP 0x52 99 + 100 + #define IN_READ 0 101 + #define IN_MAX 1 102 + #define IN_LOW 2 103 + static const u16 W83793_REG_IN[][3] = { 104 + /* Current, High, Low */ 105 + {0x10, 0x60, 0x61}, /* Vcore A */ 106 + {0x11, 0x62, 0x63}, /* Vcore B */ 107 + {0x12, 0x64, 0x65}, /* Vtt */ 108 + {0x14, 0x6a, 0x6b}, /* VSEN1 */ 109 + {0x15, 0x6c, 0x6d}, /* VSEN2 */ 110 + {0x16, 0x6e, 0x6f}, /* +3VSEN */ 111 + {0x17, 0x70, 0x71}, /* +12VSEN */ 112 + {0x18, 0x72, 0x73}, /* 5VDD */ 113 + {0x19, 0x74, 0x75}, /* 5VSB */ 114 + {0x1a, 0x76, 0x77}, /* VBAT */ 115 + }; 116 + 117 + /* Low Bits of Vcore A/B Vtt Read/High/Low */ 118 + static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; 119 + static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; 120 + 121 + #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ 122 + #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ 123 + 124 + #define W83793_REG_PWM_DEFAULT 0xb2 125 + #define W83793_REG_PWM_ENABLE 0x207 126 + #define W83793_REG_PWM_UPTIME 0xc3 /* Unit in 0.1 second */ 127 + #define W83793_REG_PWM_DOWNTIME 0xc4 /* Unit in 0.1 second */ 128 + #define W83793_REG_TEMP_CRITICAL 0xc5 129 + 130 + #define PWM_DUTY 0 131 + #define PWM_START 1 132 + #define PWM_NONSTOP 2 133 + #define W83793_REG_PWM(index, nr) (((nr) == 0 ? 0xb3 : \ 134 + (nr) == 1 ? 0x220 : 0x218) + (index)) 135 + 136 + /* bit field, fan1 is bit0, fan2 is bit1 ... */ 137 + #define W83793_REG_TEMP_FAN_MAP(index) (0x201 + (index)) 138 + #define W83793_REG_TEMP_TOL(index) (0x208 + (index)) 139 + #define W83793_REG_TEMP_CRUISE(index) (0x210 + (index)) 140 + #define W83793_REG_PWM_STOP_TIME(index) (0x228 + (index)) 141 + #define W83793_REG_SF2_TEMP(index, nr) (0x230 + ((index) << 4) + (nr)) 142 + #define W83793_REG_SF2_PWM(index, nr) (0x238 + ((index) << 4) + (nr)) 143 + 144 + static inline unsigned long FAN_FROM_REG(u16 val) 145 + { 146 + if ((val >= 0xfff) || (val == 0)) 147 + return 0; 148 + return (1350000UL / val); 149 + } 150 + 151 + static inline u16 FAN_TO_REG(long rpm) 152 + { 153 + if (rpm <= 0) 154 + return 0x0fff; 155 + return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe); 156 + } 157 + 158 + static inline unsigned long TIME_FROM_REG(u8 reg) 159 + { 160 + return (reg * 100); 161 + } 162 + 163 + static inline u8 TIME_TO_REG(unsigned long val) 164 + { 165 + return SENSORS_LIMIT((val + 50) / 100, 0, 0xff); 166 + } 167 + 168 + static inline long TEMP_FROM_REG(s8 reg) 169 + { 170 + return (reg * 1000); 171 + } 172 + 173 + static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) 174 + { 175 + return SENSORS_LIMIT((val + (val < 0 ? -500 : 500)) / 1000, min, max); 176 + } 177 + 178 + struct w83793_data { 179 + struct i2c_client client; 180 + struct i2c_client *lm75[2]; 181 + struct class_device *class_dev; 182 + struct mutex update_lock; 183 + char valid; /* !=0 if following fields are valid */ 184 + unsigned long last_updated; /* In jiffies */ 185 + unsigned long last_nonvolatile; /* In jiffies, last time we update the 186 + nonvolatile registers */ 187 + 188 + u8 bank; 189 + u8 vrm; 190 + u8 vid[2]; 191 + u8 in[10][3]; /* Register value, read/high/low */ 192 + u8 in_low_bits[3]; /* Additional resolution for VCore A/B Vtt */ 193 + 194 + u16 has_fan; /* Only fan1- fan5 has own pins */ 195 + u16 fan[12]; /* Register value combine */ 196 + u16 fan_min[12]; /* Register value combine */ 197 + 198 + s8 temp[6][5]; /* current, crit, crit_hyst,warn, warn_hyst */ 199 + u8 temp_low_bits; /* Additional resolution TD1-TD4 */ 200 + u8 temp_mode[2]; /* byte 0: Temp D1-D4 mode each has 2 bits 201 + byte 1: Temp R1,R2 mode, each has 1 bit */ 202 + u8 temp_critical; /* If reached all fan will be at full speed */ 203 + u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ 204 + 205 + u8 has_pwm; 206 + u8 pwm_enable; /* Register value, each Temp has 1 bit */ 207 + u8 pwm_uptime; /* Register value */ 208 + u8 pwm_downtime; /* Register value */ 209 + u8 pwm_default; /* All fan default pwm, next poweron valid */ 210 + u8 pwm[8][3]; /* Register value */ 211 + u8 pwm_stop_time[8]; 212 + u8 temp_cruise[6]; 213 + 214 + u8 alarms[5]; /* realtime status registers */ 215 + u8 beeps[5]; 216 + u8 beep_enable; 217 + u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */ 218 + u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */ 219 + u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */ 220 + }; 221 + 222 + static u8 w83793_read_value(struct i2c_client *client, u16 reg); 223 + static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); 224 + static int w83793_attach_adapter(struct i2c_adapter *adapter); 225 + static int w83793_detect(struct i2c_adapter *adapter, int address, int kind); 226 + static int w83793_detach_client(struct i2c_client *client); 227 + static void w83793_init_client(struct i2c_client *client); 228 + static void w83793_update_nonvolatile(struct device *dev); 229 + static struct w83793_data *w83793_update_device(struct device *dev); 230 + 231 + static struct i2c_driver w83793_driver = { 232 + .driver = { 233 + .name = "w83793", 234 + }, 235 + .attach_adapter = w83793_attach_adapter, 236 + .detach_client = w83793_detach_client, 237 + }; 238 + 239 + static ssize_t 240 + show_vrm(struct device *dev, struct device_attribute *attr, char *buf) 241 + { 242 + struct i2c_client *client = to_i2c_client(dev); 243 + struct w83793_data *data = i2c_get_clientdata(client); 244 + 245 + return sprintf(buf, "%d\n", data->vrm); 246 + } 247 + 248 + static ssize_t 249 + show_vid(struct device *dev, struct device_attribute *attr, char *buf) 250 + { 251 + struct w83793_data *data = w83793_update_device(dev); 252 + struct sensor_device_attribute_2 *sensor_attr = 253 + to_sensor_dev_attr_2(attr); 254 + int index = sensor_attr->index; 255 + 256 + return sprintf(buf, "%d\n", vid_from_reg(data->vid[index], data->vrm)); 257 + } 258 + 259 + static ssize_t 260 + store_vrm(struct device *dev, struct device_attribute *attr, 261 + const char *buf, size_t count) 262 + { 263 + struct i2c_client *client = to_i2c_client(dev); 264 + struct w83793_data *data = i2c_get_clientdata(client); 265 + 266 + data->vrm = simple_strtoul(buf, NULL, 10); 267 + return count; 268 + } 269 + 270 + #define ALARM_STATUS 0 271 + #define BEEP_ENABLE 1 272 + static ssize_t 273 + show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf) 274 + { 275 + struct w83793_data *data = w83793_update_device(dev); 276 + struct sensor_device_attribute_2 *sensor_attr = 277 + to_sensor_dev_attr_2(attr); 278 + int nr = sensor_attr->nr; 279 + int index = sensor_attr->index >> 3; 280 + int bit = sensor_attr->index & 0x07; 281 + u8 val; 282 + 283 + if (ALARM_STATUS == nr) { 284 + val = (data->alarms[index] >> (bit)) & 1; 285 + } else { /* BEEP_ENABLE */ 286 + val = (data->beeps[index] >> (bit)) & 1; 287 + } 288 + 289 + return sprintf(buf, "%u\n", val); 290 + } 291 + 292 + static ssize_t 293 + store_beep(struct device *dev, struct device_attribute *attr, 294 + const char *buf, size_t count) 295 + { 296 + struct i2c_client *client = to_i2c_client(dev); 297 + struct w83793_data *data = i2c_get_clientdata(client); 298 + struct sensor_device_attribute_2 *sensor_attr = 299 + to_sensor_dev_attr_2(attr); 300 + int index = sensor_attr->index >> 3; 301 + int shift = sensor_attr->index & 0x07; 302 + u8 beep_bit = 1 << shift; 303 + u8 val; 304 + 305 + val = simple_strtoul(buf, NULL, 10); 306 + if (val != 0 && val != 1) 307 + return -EINVAL; 308 + 309 + mutex_lock(&data->update_lock); 310 + data->beeps[index] = w83793_read_value(client, W83793_REG_BEEP(index)); 311 + data->beeps[index] &= ~beep_bit; 312 + data->beeps[index] |= val << shift; 313 + w83793_write_value(client, W83793_REG_BEEP(index), data->beeps[index]); 314 + mutex_unlock(&data->update_lock); 315 + 316 + return count; 317 + } 318 + 319 + static ssize_t 320 + show_beep_enable(struct device *dev, struct device_attribute *attr, char *buf) 321 + { 322 + struct w83793_data *data = w83793_update_device(dev); 323 + return sprintf(buf, "%u\n", (data->beep_enable >> 1) & 0x01); 324 + } 325 + 326 + static ssize_t 327 + store_beep_enable(struct device *dev, struct device_attribute *attr, 328 + const char *buf, size_t count) 329 + { 330 + struct i2c_client *client = to_i2c_client(dev); 331 + struct w83793_data *data = i2c_get_clientdata(client); 332 + u8 val = simple_strtoul(buf, NULL, 10); 333 + 334 + if (val != 0 && val != 1) 335 + return -EINVAL; 336 + 337 + mutex_lock(&data->update_lock); 338 + data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP) 339 + & 0xfd; 340 + data->beep_enable |= val << 1; 341 + w83793_write_value(client, W83793_REG_OVT_BEEP, data->beep_enable); 342 + mutex_unlock(&data->update_lock); 343 + 344 + return count; 345 + } 346 + 347 + /* Write any value to clear chassis alarm */ 348 + static ssize_t 349 + store_chassis_clear(struct device *dev, 350 + struct device_attribute *attr, const char *buf, 351 + size_t count) 352 + { 353 + struct i2c_client *client = to_i2c_client(dev); 354 + struct w83793_data *data = i2c_get_clientdata(client); 355 + u8 val; 356 + 357 + mutex_lock(&data->update_lock); 358 + val = w83793_read_value(client, W83793_REG_CLR_CHASSIS); 359 + val |= 0x80; 360 + w83793_write_value(client, W83793_REG_CLR_CHASSIS, val); 361 + mutex_unlock(&data->update_lock); 362 + return count; 363 + } 364 + 365 + #define FAN_INPUT 0 366 + #define FAN_MIN 1 367 + static ssize_t 368 + show_fan(struct device *dev, struct device_attribute *attr, char *buf) 369 + { 370 + struct sensor_device_attribute_2 *sensor_attr = 371 + to_sensor_dev_attr_2(attr); 372 + int nr = sensor_attr->nr; 373 + int index = sensor_attr->index; 374 + struct w83793_data *data = w83793_update_device(dev); 375 + u16 val; 376 + 377 + if (FAN_INPUT == nr) { 378 + val = data->fan[index] & 0x0fff; 379 + } else { 380 + val = data->fan_min[index] & 0x0fff; 381 + } 382 + 383 + return sprintf(buf, "%lu\n", FAN_FROM_REG(val)); 384 + } 385 + 386 + static ssize_t 387 + store_fan_min(struct device *dev, struct device_attribute *attr, 388 + const char *buf, size_t count) 389 + { 390 + struct sensor_device_attribute_2 *sensor_attr = 391 + to_sensor_dev_attr_2(attr); 392 + int index = sensor_attr->index; 393 + struct i2c_client *client = to_i2c_client(dev); 394 + struct w83793_data *data = i2c_get_clientdata(client); 395 + u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10)); 396 + 397 + mutex_lock(&data->update_lock); 398 + data->fan_min[index] = val; 399 + w83793_write_value(client, W83793_REG_FAN_MIN(index), 400 + (val >> 8) & 0xff); 401 + w83793_write_value(client, W83793_REG_FAN_MIN(index) + 1, val & 0xff); 402 + mutex_unlock(&data->update_lock); 403 + 404 + return count; 405 + } 406 + 407 + #define PWM_DUTY 0 408 + #define PWM_START 1 409 + #define PWM_NONSTOP 2 410 + #define PWM_STOP_TIME 3 411 + static ssize_t 412 + show_pwm(struct device *dev, struct device_attribute *attr, char *buf) 413 + { 414 + struct sensor_device_attribute_2 *sensor_attr = 415 + to_sensor_dev_attr_2(attr); 416 + struct w83793_data *data = w83793_update_device(dev); 417 + u16 val; 418 + int nr = sensor_attr->nr; 419 + int index = sensor_attr->index; 420 + 421 + if (PWM_STOP_TIME == nr) 422 + val = TIME_FROM_REG(data->pwm_stop_time[index]); 423 + else 424 + val = (data->pwm[index][nr] & 0x3f) << 2; 425 + 426 + return sprintf(buf, "%d\n", val); 427 + } 428 + 429 + static ssize_t 430 + store_pwm(struct device *dev, struct device_attribute *attr, 431 + const char *buf, size_t count) 432 + { 433 + struct i2c_client *client = to_i2c_client(dev); 434 + struct w83793_data *data = i2c_get_clientdata(client); 435 + struct sensor_device_attribute_2 *sensor_attr = 436 + to_sensor_dev_attr_2(attr); 437 + int nr = sensor_attr->nr; 438 + int index = sensor_attr->index; 439 + u8 val; 440 + 441 + mutex_lock(&data->update_lock); 442 + if (PWM_STOP_TIME == nr) { 443 + val = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); 444 + data->pwm_stop_time[index] = val; 445 + w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index), 446 + val); 447 + } else { 448 + val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) 449 + >> 2; 450 + data->pwm[index][nr] = 451 + w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0; 452 + data->pwm[index][nr] |= val; 453 + w83793_write_value(client, W83793_REG_PWM(index, nr), 454 + data->pwm[index][nr]); 455 + } 456 + 457 + mutex_unlock(&data->update_lock); 458 + return count; 459 + } 460 + 461 + static ssize_t 462 + show_temp(struct device *dev, struct device_attribute *attr, char *buf) 463 + { 464 + struct sensor_device_attribute_2 *sensor_attr = 465 + to_sensor_dev_attr_2(attr); 466 + int nr = sensor_attr->nr; 467 + int index = sensor_attr->index; 468 + struct w83793_data *data = w83793_update_device(dev); 469 + long temp = TEMP_FROM_REG(data->temp[index][nr]); 470 + 471 + if (TEMP_READ == nr && index < 4) { /* Only TD1-TD4 have low bits */ 472 + int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250; 473 + temp += temp > 0 ? low : -low; 474 + } 475 + return sprintf(buf, "%ld\n", temp); 476 + } 477 + 478 + static ssize_t 479 + store_temp(struct device *dev, struct device_attribute *attr, 480 + const char *buf, size_t count) 481 + { 482 + struct sensor_device_attribute_2 *sensor_attr = 483 + to_sensor_dev_attr_2(attr); 484 + int nr = sensor_attr->nr; 485 + int index = sensor_attr->index; 486 + struct i2c_client *client = to_i2c_client(dev); 487 + struct w83793_data *data = i2c_get_clientdata(client); 488 + long tmp = simple_strtol(buf, NULL, 10); 489 + 490 + mutex_lock(&data->update_lock); 491 + data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127); 492 + w83793_write_value(client, W83793_REG_TEMP[index][nr], 493 + data->temp[index][nr]); 494 + mutex_unlock(&data->update_lock); 495 + return count; 496 + } 497 + 498 + /* 499 + TD1-TD4 500 + each has 4 mode:(2 bits) 501 + 0: Stop monitor 502 + 1: Use internal temp sensor(default) 503 + 2: Use sensor in AMD CPU and get result by AMDSI 504 + 3: Use sensor in Intel CPU and get result by PECI 505 + 506 + TR1-TR2 507 + each has 2 mode:(1 bit) 508 + 0: Disable temp sensor monitor 509 + 1: To enable temp sensors monitor 510 + */ 511 + 512 + /* 0 disable, 5 AMDSI, 6 PECI */ 513 + static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; 514 + 515 + static ssize_t 516 + show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) 517 + { 518 + struct w83793_data *data = w83793_update_device(dev); 519 + struct sensor_device_attribute_2 *sensor_attr = 520 + to_sensor_dev_attr_2(attr); 521 + int index = sensor_attr->index; 522 + u8 mask = (index < 4) ? 0x03 : 0x01; 523 + u8 shift = (index < 4) ? (2 * index) : (index - 4); 524 + u8 tmp; 525 + index = (index < 4) ? 0 : 1; 526 + 527 + tmp = (data->temp_mode[index] >> shift) & mask; 528 + 529 + /* for the internal sensor, found out if diode or thermistor */ 530 + if (tmp == 1) { 531 + tmp = index == 0 ? 3 : 4; 532 + } else { 533 + tmp = TO_TEMP_MODE[tmp]; 534 + } 535 + 536 + return sprintf(buf, "%d\n", tmp); 537 + } 538 + 539 + static ssize_t 540 + store_temp_mode(struct device *dev, struct device_attribute *attr, 541 + const char *buf, size_t count) 542 + { 543 + struct i2c_client *client = to_i2c_client(dev); 544 + struct w83793_data *data = i2c_get_clientdata(client); 545 + struct sensor_device_attribute_2 *sensor_attr = 546 + to_sensor_dev_attr_2(attr); 547 + int index = sensor_attr->index; 548 + u8 mask = (index < 4) ? 0x03 : 0x01; 549 + u8 shift = (index < 4) ? (2 * index) : (index - 4); 550 + u8 val = simple_strtoul(buf, NULL, 10); 551 + 552 + /* transform the sysfs interface values into table above */ 553 + if ((val == 5 || val == 6) && (index < 4)) { 554 + val -= 3; 555 + } else if ((val == 3 && index < 4) 556 + || (val == 4 && index >= 4) 557 + || val == 0) { 558 + /* transform diode or thermistor into internal enable */ 559 + val = !!val; 560 + } else { 561 + return -EINVAL; 562 + } 563 + 564 + index = (index < 4) ? 0 : 1; 565 + mutex_lock(&data->update_lock); 566 + data->temp_mode[index] = 567 + w83793_read_value(client, W83793_REG_TEMP_MODE[index]); 568 + data->temp_mode[index] &= ~(mask << shift); 569 + data->temp_mode[index] |= val << shift; 570 + w83793_write_value(client, W83793_REG_TEMP_MODE[index], 571 + data->temp_mode[index]); 572 + mutex_unlock(&data->update_lock); 573 + 574 + return count; 575 + } 576 + 577 + #define SETUP_PWM_DEFAULT 0 578 + #define SETUP_PWM_UPTIME 1 /* Unit in 0.1s */ 579 + #define SETUP_PWM_DOWNTIME 2 /* Unit in 0.1s */ 580 + #define SETUP_TEMP_CRITICAL 3 581 + static ssize_t 582 + show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf) 583 + { 584 + struct sensor_device_attribute_2 *sensor_attr = 585 + to_sensor_dev_attr_2(attr); 586 + int nr = sensor_attr->nr; 587 + struct w83793_data *data = w83793_update_device(dev); 588 + u32 val = 0; 589 + 590 + if (SETUP_PWM_DEFAULT == nr) { 591 + val = (data->pwm_default & 0x3f) << 2; 592 + } else if (SETUP_PWM_UPTIME == nr) { 593 + val = TIME_FROM_REG(data->pwm_uptime); 594 + } else if (SETUP_PWM_DOWNTIME == nr) { 595 + val = TIME_FROM_REG(data->pwm_downtime); 596 + } else if (SETUP_TEMP_CRITICAL == nr) { 597 + val = TEMP_FROM_REG(data->temp_critical & 0x7f); 598 + } 599 + 600 + return sprintf(buf, "%d\n", val); 601 + } 602 + 603 + static ssize_t 604 + store_sf_setup(struct device *dev, struct device_attribute *attr, 605 + const char *buf, size_t count) 606 + { 607 + struct sensor_device_attribute_2 *sensor_attr = 608 + to_sensor_dev_attr_2(attr); 609 + int nr = sensor_attr->nr; 610 + struct i2c_client *client = to_i2c_client(dev); 611 + struct w83793_data *data = i2c_get_clientdata(client); 612 + 613 + mutex_lock(&data->update_lock); 614 + if (SETUP_PWM_DEFAULT == nr) { 615 + data->pwm_default = 616 + w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0; 617 + data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL, 618 + 10), 619 + 0, 0xff) >> 2; 620 + w83793_write_value(client, W83793_REG_PWM_DEFAULT, 621 + data->pwm_default); 622 + } else if (SETUP_PWM_UPTIME == nr) { 623 + data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); 624 + data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0; 625 + w83793_write_value(client, W83793_REG_PWM_UPTIME, 626 + data->pwm_uptime); 627 + } else if (SETUP_PWM_DOWNTIME == nr) { 628 + data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); 629 + data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0; 630 + w83793_write_value(client, W83793_REG_PWM_DOWNTIME, 631 + data->pwm_downtime); 632 + } else { /* SETUP_TEMP_CRITICAL */ 633 + data->temp_critical = 634 + w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80; 635 + data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10), 636 + 0, 0x7f); 637 + w83793_write_value(client, W83793_REG_TEMP_CRITICAL, 638 + data->temp_critical); 639 + } 640 + 641 + mutex_unlock(&data->update_lock); 642 + return count; 643 + } 644 + 645 + /* 646 + Temp SmartFan control 647 + TEMP_FAN_MAP 648 + Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1... 649 + It's possible two or more temp channels control the same fan, w83793 650 + always prefers to pick the most critical request and applies it to 651 + the related Fan. 652 + It's possible one fan is not in any mapping of 6 temp channels, this 653 + means the fan is manual mode 654 + 655 + TEMP_PWM_ENABLE 656 + Each temp channel has its own SmartFan mode, and temp channel 657 + control fans that are set by TEMP_FAN_MAP 658 + 0: SmartFanII mode 659 + 1: Thermal Cruise Mode 660 + 661 + TEMP_CRUISE 662 + Target temperature in thermal cruise mode, w83793 will try to turn 663 + fan speed to keep the temperature of target device around this 664 + temperature. 665 + 666 + TEMP_TOLERANCE 667 + If Temp higher or lower than target with this tolerance, w83793 668 + will take actions to speed up or slow down the fan to keep the 669 + temperature within the tolerance range. 670 + */ 671 + 672 + #define TEMP_FAN_MAP 0 673 + #define TEMP_PWM_ENABLE 1 674 + #define TEMP_CRUISE 2 675 + #define TEMP_TOLERANCE 3 676 + static ssize_t 677 + show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf) 678 + { 679 + struct sensor_device_attribute_2 *sensor_attr = 680 + to_sensor_dev_attr_2(attr); 681 + int nr = sensor_attr->nr; 682 + int index = sensor_attr->index; 683 + struct w83793_data *data = w83793_update_device(dev); 684 + u32 val; 685 + 686 + if (TEMP_FAN_MAP == nr) { 687 + val = data->temp_fan_map[index]; 688 + } else if (TEMP_PWM_ENABLE == nr) { 689 + /* +2 to transfrom into 2 and 3 to conform with sysfs intf */ 690 + val = ((data->pwm_enable >> index) & 0x01) + 2; 691 + } else if (TEMP_CRUISE == nr) { 692 + val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f); 693 + } else { /* TEMP_TOLERANCE */ 694 + val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0); 695 + val = TEMP_FROM_REG(val & 0x0f); 696 + } 697 + return sprintf(buf, "%d\n", val); 698 + } 699 + 700 + static ssize_t 701 + store_sf_ctrl(struct device *dev, struct device_attribute *attr, 702 + const char *buf, size_t count) 703 + { 704 + struct sensor_device_attribute_2 *sensor_attr = 705 + to_sensor_dev_attr_2(attr); 706 + int nr = sensor_attr->nr; 707 + int index = sensor_attr->index; 708 + struct i2c_client *client = to_i2c_client(dev); 709 + struct w83793_data *data = i2c_get_clientdata(client); 710 + u32 val; 711 + 712 + mutex_lock(&data->update_lock); 713 + if (TEMP_FAN_MAP == nr) { 714 + val = simple_strtoul(buf, NULL, 10) & 0xff; 715 + w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val); 716 + data->temp_fan_map[index] = val; 717 + } else if (TEMP_PWM_ENABLE == nr) { 718 + val = simple_strtoul(buf, NULL, 10); 719 + if (2 == val || 3 == val) { 720 + data->pwm_enable = 721 + w83793_read_value(client, W83793_REG_PWM_ENABLE); 722 + if (val - 2) 723 + data->pwm_enable |= 1 << index; 724 + else 725 + data->pwm_enable &= ~(1 << index); 726 + w83793_write_value(client, W83793_REG_PWM_ENABLE, 727 + data->pwm_enable); 728 + } else { 729 + mutex_unlock(&data->update_lock); 730 + return -EINVAL; 731 + } 732 + } else if (TEMP_CRUISE == nr) { 733 + data->temp_cruise[index] = 734 + w83793_read_value(client, W83793_REG_TEMP_CRUISE(index)); 735 + val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); 736 + data->temp_cruise[index] &= 0x80; 737 + data->temp_cruise[index] |= val; 738 + 739 + w83793_write_value(client, W83793_REG_TEMP_CRUISE(index), 740 + data->temp_cruise[index]); 741 + } else { /* TEMP_TOLERANCE */ 742 + int i = index >> 1; 743 + u8 shift = (index & 0x01) ? 4 : 0; 744 + data->tolerance[i] = 745 + w83793_read_value(client, W83793_REG_TEMP_TOL(i)); 746 + 747 + val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f); 748 + data->tolerance[i] &= ~(0x0f << shift); 749 + data->tolerance[i] |= val << shift; 750 + w83793_write_value(client, W83793_REG_TEMP_TOL(i), 751 + data->tolerance[i]); 752 + } 753 + 754 + mutex_unlock(&data->update_lock); 755 + return count; 756 + } 757 + 758 + static ssize_t 759 + show_sf2_pwm(struct device *dev, struct device_attribute *attr, char *buf) 760 + { 761 + struct sensor_device_attribute_2 *sensor_attr = 762 + to_sensor_dev_attr_2(attr); 763 + int nr = sensor_attr->nr; 764 + int index = sensor_attr->index; 765 + struct w83793_data *data = w83793_update_device(dev); 766 + 767 + return sprintf(buf, "%d\n", (data->sf2_pwm[index][nr] & 0x3f) << 2); 768 + } 769 + 770 + static ssize_t 771 + store_sf2_pwm(struct device *dev, struct device_attribute *attr, 772 + const char *buf, size_t count) 773 + { 774 + struct i2c_client *client = to_i2c_client(dev); 775 + struct w83793_data *data = i2c_get_clientdata(client); 776 + struct sensor_device_attribute_2 *sensor_attr = 777 + to_sensor_dev_attr_2(attr); 778 + int nr = sensor_attr->nr; 779 + int index = sensor_attr->index; 780 + u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2; 781 + 782 + mutex_lock(&data->update_lock); 783 + data->sf2_pwm[index][nr] = 784 + w83793_read_value(client, W83793_REG_SF2_PWM(index, nr)) & 0xc0; 785 + data->sf2_pwm[index][nr] |= val; 786 + w83793_write_value(client, W83793_REG_SF2_PWM(index, nr), 787 + data->sf2_pwm[index][nr]); 788 + mutex_unlock(&data->update_lock); 789 + return count; 790 + } 791 + 792 + static ssize_t 793 + show_sf2_temp(struct device *dev, struct device_attribute *attr, char *buf) 794 + { 795 + struct sensor_device_attribute_2 *sensor_attr = 796 + to_sensor_dev_attr_2(attr); 797 + int nr = sensor_attr->nr; 798 + int index = sensor_attr->index; 799 + struct w83793_data *data = w83793_update_device(dev); 800 + 801 + return sprintf(buf, "%ld\n", 802 + TEMP_FROM_REG(data->sf2_temp[index][nr] & 0x7f)); 803 + } 804 + 805 + static ssize_t 806 + store_sf2_temp(struct device *dev, struct device_attribute *attr, 807 + const char *buf, size_t count) 808 + { 809 + struct i2c_client *client = to_i2c_client(dev); 810 + struct w83793_data *data = i2c_get_clientdata(client); 811 + struct sensor_device_attribute_2 *sensor_attr = 812 + to_sensor_dev_attr_2(attr); 813 + int nr = sensor_attr->nr; 814 + int index = sensor_attr->index; 815 + u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); 816 + 817 + mutex_lock(&data->update_lock); 818 + data->sf2_temp[index][nr] = 819 + w83793_read_value(client, W83793_REG_SF2_TEMP(index, nr)) & 0x80; 820 + data->sf2_temp[index][nr] |= val; 821 + w83793_write_value(client, W83793_REG_SF2_TEMP(index, nr), 822 + data->sf2_temp[index][nr]); 823 + mutex_unlock(&data->update_lock); 824 + return count; 825 + } 826 + 827 + /* only Vcore A/B and Vtt have additional 2 bits precision */ 828 + static ssize_t 829 + show_in(struct device *dev, struct device_attribute *attr, char *buf) 830 + { 831 + struct sensor_device_attribute_2 *sensor_attr = 832 + to_sensor_dev_attr_2(attr); 833 + int nr = sensor_attr->nr; 834 + int index = sensor_attr->index; 835 + struct w83793_data *data = w83793_update_device(dev); 836 + u16 val = data->in[index][nr]; 837 + 838 + if (index < 3) { 839 + val <<= 2; 840 + val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; 841 + } 842 + return sprintf(buf, "%d\n", val * scale_in[index]); 843 + } 844 + 845 + static ssize_t 846 + store_in(struct device *dev, struct device_attribute *attr, 847 + const char *buf, size_t count) 848 + { 849 + struct sensor_device_attribute_2 *sensor_attr = 850 + to_sensor_dev_attr_2(attr); 851 + int nr = sensor_attr->nr; 852 + int index = sensor_attr->index; 853 + struct i2c_client *client = to_i2c_client(dev); 854 + struct w83793_data *data = i2c_get_clientdata(client); 855 + u32 val; 856 + 857 + val = 858 + (simple_strtoul(buf, NULL, 10) + 859 + scale_in[index] / 2) / scale_in[index]; 860 + mutex_lock(&data->update_lock); 861 + if (index > 2) { 862 + val = SENSORS_LIMIT(val, 0, 255); 863 + } else { 864 + val = SENSORS_LIMIT(val, 0, 0x3FF); 865 + data->in_low_bits[nr] = 866 + w83793_read_value(client, W83793_REG_IN_LOW_BITS[nr]); 867 + data->in_low_bits[nr] &= ~(0x03 << (2 * index)); 868 + data->in_low_bits[nr] |= (val & 0x03) << (2 * index); 869 + w83793_write_value(client, W83793_REG_IN_LOW_BITS[nr], 870 + data->in_low_bits[nr]); 871 + val >>= 2; 872 + } 873 + data->in[index][nr] = val; 874 + w83793_write_value(client, W83793_REG_IN[index][nr], 875 + data->in[index][nr]); 876 + mutex_unlock(&data->update_lock); 877 + return count; 878 + } 879 + 880 + #define NOT_USED -1 881 + 882 + #define SENSOR_ATTR_IN(index) \ 883 + SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ 884 + IN_READ, index), \ 885 + SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in, \ 886 + store_in, IN_MAX, index), \ 887 + SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in, \ 888 + store_in, IN_LOW, index), \ 889 + SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep, \ 890 + NULL, ALARM_STATUS, index + ((index > 2) ? 1 : 0)), \ 891 + SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO, \ 892 + show_alarm_beep, store_beep, BEEP_ENABLE, \ 893 + index + ((index > 2) ? 1 : 0)) 894 + 895 + #define SENSOR_ATTR_FAN(index) \ 896 + SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep, \ 897 + NULL, ALARM_STATUS, index + 17), \ 898 + SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO, \ 899 + show_alarm_beep, store_beep, BEEP_ENABLE, index + 17), \ 900 + SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ 901 + NULL, FAN_INPUT, index - 1), \ 902 + SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO, \ 903 + show_fan, store_fan_min, FAN_MIN, index - 1) 904 + 905 + #define SENSOR_ATTR_PWM(index) \ 906 + SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ 907 + store_pwm, PWM_DUTY, index - 1), \ 908 + SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ 909 + show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ 910 + SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ 911 + show_pwm, store_pwm, PWM_START, index - 1), \ 912 + SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ 913 + show_pwm, store_pwm, PWM_STOP_TIME, index - 1) 914 + 915 + #define SENSOR_ATTR_TEMP(index) \ 916 + SENSOR_ATTR_2(temp##index##_type, S_IRUGO | S_IWUSR, \ 917 + show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ 918 + SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \ 919 + NULL, TEMP_READ, index - 1), \ 920 + SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp, \ 921 + store_temp, TEMP_CRIT, index - 1), \ 922 + SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \ 923 + show_temp, store_temp, TEMP_CRIT_HYST, index - 1), \ 924 + SENSOR_ATTR_2(temp##index##_warn, S_IRUGO | S_IWUSR, show_temp, \ 925 + store_temp, TEMP_WARN, index - 1), \ 926 + SENSOR_ATTR_2(temp##index##_warn_hyst, S_IRUGO | S_IWUSR, \ 927 + show_temp, store_temp, TEMP_WARN_HYST, index - 1), \ 928 + SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \ 929 + show_alarm_beep, NULL, ALARM_STATUS, index + 11), \ 930 + SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ 931 + show_alarm_beep, store_beep, BEEP_ENABLE, index + 11), \ 932 + SENSOR_ATTR_2(temp##index##_auto_channels_pwm, \ 933 + S_IRUGO | S_IWUSR, show_sf_ctrl, store_sf_ctrl, \ 934 + TEMP_FAN_MAP, index - 1), \ 935 + SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ 936 + show_sf_ctrl, store_sf_ctrl, TEMP_PWM_ENABLE, \ 937 + index - 1), \ 938 + SENSOR_ATTR_2(thermal_cruise##index, S_IRUGO | S_IWUSR, \ 939 + show_sf_ctrl, store_sf_ctrl, TEMP_CRUISE, index - 1), \ 940 + SENSOR_ATTR_2(tolerance##index, S_IRUGO | S_IWUSR, show_sf_ctrl,\ 941 + store_sf_ctrl, TEMP_TOLERANCE, index - 1), \ 942 + SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \ 943 + show_sf2_pwm, store_sf2_pwm, 0, index - 1), \ 944 + SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \ 945 + show_sf2_pwm, store_sf2_pwm, 1, index - 1), \ 946 + SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \ 947 + show_sf2_pwm, store_sf2_pwm, 2, index - 1), \ 948 + SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \ 949 + show_sf2_pwm, store_sf2_pwm, 3, index - 1), \ 950 + SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \ 951 + show_sf2_pwm, store_sf2_pwm, 4, index - 1), \ 952 + SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \ 953 + show_sf2_pwm, store_sf2_pwm, 5, index - 1), \ 954 + SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \ 955 + show_sf2_pwm, store_sf2_pwm, 6, index - 1), \ 956 + SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\ 957 + show_sf2_temp, store_sf2_temp, 0, index - 1), \ 958 + SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\ 959 + show_sf2_temp, store_sf2_temp, 1, index - 1), \ 960 + SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\ 961 + show_sf2_temp, store_sf2_temp, 2, index - 1), \ 962 + SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\ 963 + show_sf2_temp, store_sf2_temp, 3, index - 1), \ 964 + SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\ 965 + show_sf2_temp, store_sf2_temp, 4, index - 1), \ 966 + SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\ 967 + show_sf2_temp, store_sf2_temp, 5, index - 1), \ 968 + SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\ 969 + show_sf2_temp, store_sf2_temp, 6, index - 1) 970 + 971 + static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { 972 + SENSOR_ATTR_IN(0), 973 + SENSOR_ATTR_IN(1), 974 + SENSOR_ATTR_IN(2), 975 + SENSOR_ATTR_IN(3), 976 + SENSOR_ATTR_IN(4), 977 + SENSOR_ATTR_IN(5), 978 + SENSOR_ATTR_IN(6), 979 + SENSOR_ATTR_IN(7), 980 + SENSOR_ATTR_IN(8), 981 + SENSOR_ATTR_IN(9), 982 + SENSOR_ATTR_TEMP(1), 983 + SENSOR_ATTR_TEMP(2), 984 + SENSOR_ATTR_TEMP(3), 985 + SENSOR_ATTR_TEMP(4), 986 + SENSOR_ATTR_TEMP(5), 987 + SENSOR_ATTR_TEMP(6), 988 + SENSOR_ATTR_FAN(1), 989 + SENSOR_ATTR_FAN(2), 990 + SENSOR_ATTR_FAN(3), 991 + SENSOR_ATTR_FAN(4), 992 + SENSOR_ATTR_FAN(5), 993 + SENSOR_ATTR_PWM(1), 994 + SENSOR_ATTR_PWM(2), 995 + SENSOR_ATTR_PWM(3), 996 + }; 997 + 998 + /* Fan6-Fan12 */ 999 + static struct sensor_device_attribute_2 w83793_left_fan[] = { 1000 + SENSOR_ATTR_FAN(6), 1001 + SENSOR_ATTR_FAN(7), 1002 + SENSOR_ATTR_FAN(8), 1003 + SENSOR_ATTR_FAN(9), 1004 + SENSOR_ATTR_FAN(10), 1005 + SENSOR_ATTR_FAN(11), 1006 + SENSOR_ATTR_FAN(12), 1007 + }; 1008 + 1009 + /* Pwm4-Pwm8 */ 1010 + static struct sensor_device_attribute_2 w83793_left_pwm[] = { 1011 + SENSOR_ATTR_PWM(4), 1012 + SENSOR_ATTR_PWM(5), 1013 + SENSOR_ATTR_PWM(6), 1014 + SENSOR_ATTR_PWM(7), 1015 + SENSOR_ATTR_PWM(8), 1016 + }; 1017 + 1018 + static struct sensor_device_attribute_2 sda_single_files[] = { 1019 + SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), 1020 + SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), 1021 + SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, 1022 + NOT_USED, NOT_USED), 1023 + SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, 1024 + store_chassis_clear, ALARM_STATUS, 30), 1025 + SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, 1026 + store_beep_enable, NOT_USED, NOT_USED), 1027 + SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup, 1028 + store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED), 1029 + SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup, 1030 + store_sf_setup, SETUP_PWM_UPTIME, NOT_USED), 1031 + SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup, 1032 + store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED), 1033 + SENSOR_ATTR_2(temp_critical, S_IWUSR | S_IRUGO, show_sf_setup, 1034 + store_sf_setup, SETUP_TEMP_CRITICAL, NOT_USED), 1035 + }; 1036 + 1037 + static void w83793_init_client(struct i2c_client *client) 1038 + { 1039 + if (reset) { 1040 + w83793_write_value(client, W83793_REG_CONFIG, 0x80); 1041 + } 1042 + 1043 + /* Start monitoring */ 1044 + w83793_write_value(client, W83793_REG_CONFIG, 1045 + w83793_read_value(client, W83793_REG_CONFIG) | 0x01); 1046 + 1047 + } 1048 + 1049 + static int w83793_attach_adapter(struct i2c_adapter *adapter) 1050 + { 1051 + if (!(adapter->class & I2C_CLASS_HWMON)) 1052 + return 0; 1053 + return i2c_probe(adapter, &addr_data, w83793_detect); 1054 + } 1055 + 1056 + static int w83793_detach_client(struct i2c_client *client) 1057 + { 1058 + struct w83793_data *data = i2c_get_clientdata(client); 1059 + struct device *dev = &client->dev; 1060 + int err, i; 1061 + 1062 + /* main client */ 1063 + if (data) { 1064 + hwmon_device_unregister(data->class_dev); 1065 + 1066 + for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) 1067 + device_remove_file(dev, 1068 + &w83793_sensor_attr_2[i].dev_attr); 1069 + 1070 + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) 1071 + device_remove_file(dev, &sda_single_files[i].dev_attr); 1072 + 1073 + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) 1074 + device_remove_file(dev, &w83793_left_fan[i].dev_attr); 1075 + 1076 + for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) 1077 + device_remove_file(dev, &w83793_left_pwm[i].dev_attr); 1078 + } 1079 + 1080 + if ((err = i2c_detach_client(client))) 1081 + return err; 1082 + 1083 + /* main client */ 1084 + if (data) 1085 + kfree(data); 1086 + /* subclient */ 1087 + else 1088 + kfree(client); 1089 + 1090 + return 0; 1091 + } 1092 + 1093 + static int 1094 + w83793_create_subclient(struct i2c_adapter *adapter, 1095 + struct i2c_client *client, int addr, 1096 + struct i2c_client **sub_cli) 1097 + { 1098 + int err = 0; 1099 + struct i2c_client *sub_client; 1100 + 1101 + (*sub_cli) = sub_client = 1102 + kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 1103 + if (!(sub_client)) { 1104 + return -ENOMEM; 1105 + } 1106 + sub_client->addr = 0x48 + addr; 1107 + i2c_set_clientdata(sub_client, NULL); 1108 + sub_client->adapter = adapter; 1109 + sub_client->driver = &w83793_driver; 1110 + strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE); 1111 + if ((err = i2c_attach_client(sub_client))) { 1112 + dev_err(&client->dev, "subclient registration " 1113 + "at address 0x%x failed\n", sub_client->addr); 1114 + kfree(sub_client); 1115 + } 1116 + return err; 1117 + } 1118 + 1119 + static int 1120 + w83793_detect_subclients(struct i2c_adapter *adapter, int address, 1121 + int kind, struct i2c_client *client) 1122 + { 1123 + int i, id, err; 1124 + u8 tmp; 1125 + struct w83793_data *data = i2c_get_clientdata(client); 1126 + 1127 + id = i2c_adapter_id(adapter); 1128 + if (force_subclients[0] == id && force_subclients[1] == address) { 1129 + for (i = 2; i <= 3; i++) { 1130 + if (force_subclients[i] < 0x48 1131 + || force_subclients[i] > 0x4f) { 1132 + dev_err(&client->dev, 1133 + "invalid subclient " 1134 + "address %d; must be 0x48-0x4f\n", 1135 + force_subclients[i]); 1136 + err = -EINVAL; 1137 + goto ERROR_SC_0; 1138 + } 1139 + } 1140 + w83793_write_value(client, W83793_REG_I2C_SUBADDR, 1141 + (force_subclients[2] & 0x07) | 1142 + ((force_subclients[3] & 0x07) << 4)); 1143 + } 1144 + 1145 + tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); 1146 + if (!(tmp & 0x08)) { 1147 + err = 1148 + w83793_create_subclient(adapter, client, tmp & 0x7, 1149 + &data->lm75[0]); 1150 + if (err < 0) 1151 + goto ERROR_SC_0; 1152 + } 1153 + if (!(tmp & 0x80)) { 1154 + if ((data->lm75[0] != NULL) 1155 + && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) { 1156 + dev_err(&client->dev, 1157 + "duplicate addresses 0x%x, " 1158 + "use force_subclients\n", data->lm75[0]->addr); 1159 + err = -ENODEV; 1160 + goto ERROR_SC_1; 1161 + } 1162 + err = w83793_create_subclient(adapter, client, 1163 + (tmp >> 4) & 0x7, &data->lm75[1]); 1164 + if (err < 0) 1165 + goto ERROR_SC_1; 1166 + } 1167 + 1168 + return 0; 1169 + 1170 + /* Undo inits in case of errors */ 1171 + 1172 + ERROR_SC_1: 1173 + if (data->lm75[0] != NULL) { 1174 + i2c_detach_client(data->lm75[0]); 1175 + kfree(data->lm75[0]); 1176 + } 1177 + ERROR_SC_0: 1178 + return err; 1179 + } 1180 + 1181 + static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) 1182 + { 1183 + int i; 1184 + u8 tmp, val; 1185 + struct i2c_client *client; 1186 + struct device *dev; 1187 + struct w83793_data *data; 1188 + int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; 1189 + int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; 1190 + int err = 0; 1191 + 1192 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1193 + goto exit; 1194 + } 1195 + 1196 + /* OK. For now, we presume we have a valid client. We now create the 1197 + client structure, even though we cannot fill it completely yet. 1198 + But it allows us to access w83793_{read,write}_value. */ 1199 + 1200 + if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) { 1201 + err = -ENOMEM; 1202 + goto exit; 1203 + } 1204 + 1205 + client = &data->client; 1206 + dev = &client->dev; 1207 + i2c_set_clientdata(client, data); 1208 + client->addr = address; 1209 + client->adapter = adapter; 1210 + client->driver = &w83793_driver; 1211 + 1212 + data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); 1213 + 1214 + /* Now, we do the remaining detection. */ 1215 + if (kind < 0) { 1216 + tmp = data->bank & 0x80 ? 0x5c : 0xa3; 1217 + /* Check Winbond vendor ID */ 1218 + if (tmp != i2c_smbus_read_byte_data(client, 1219 + W83793_REG_VENDORID)) { 1220 + pr_debug("w83793: Detection failed at check " 1221 + "vendor id\n"); 1222 + err = -ENODEV; 1223 + goto free_mem; 1224 + } 1225 + 1226 + /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR 1227 + should match */ 1228 + if ((data->bank & 0x07) == 0 1229 + && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != 1230 + (address << 1)) { 1231 + pr_debug("w83793: Detection failed at check " 1232 + "i2c addr\n"); 1233 + err = -ENODEV; 1234 + goto free_mem; 1235 + } 1236 + 1237 + } 1238 + 1239 + /* We have either had a force parameter, or we have already detected the 1240 + Winbond. Determine the chip type now */ 1241 + 1242 + if (kind <= 0) { 1243 + if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) { 1244 + kind = w83793; 1245 + } else { 1246 + if (kind == 0) 1247 + dev_warn(&adapter->dev, "w83793: Ignoring " 1248 + "'force' parameter for unknown chip " 1249 + "at address 0x%02x\n", address); 1250 + err = -ENODEV; 1251 + goto free_mem; 1252 + } 1253 + } 1254 + 1255 + /* Fill in the remaining client fields and put into the global list */ 1256 + strlcpy(client->name, "w83793", I2C_NAME_SIZE); 1257 + 1258 + mutex_init(&data->update_lock); 1259 + 1260 + /* Tell the I2C layer a new client has arrived */ 1261 + if ((err = i2c_attach_client(client))) 1262 + goto free_mem; 1263 + 1264 + if ((err = w83793_detect_subclients(adapter, address, kind, client))) 1265 + goto detach_client; 1266 + 1267 + /* Initialize the chip */ 1268 + w83793_init_client(client); 1269 + 1270 + data->vrm = vid_which_vrm(); 1271 + /* 1272 + Only fan 1-5 has their own input pins, 1273 + Pwm 1-3 has their own pins 1274 + */ 1275 + data->has_fan = 0x1f; 1276 + data->has_pwm = 0x07; 1277 + tmp = w83793_read_value(client, W83793_REG_MFC); 1278 + val = w83793_read_value(client, W83793_REG_FANIN_CTRL); 1279 + 1280 + /* check the function of pins 49-56 */ 1281 + if (!(tmp & 0x80)) { 1282 + data->has_pwm |= 0x18; /* pwm 4,5 */ 1283 + if (val & 0x01) { /* fan 6 */ 1284 + data->has_fan |= 0x20; 1285 + data->has_pwm |= 0x20; 1286 + } 1287 + if (val & 0x02) { /* fan 7 */ 1288 + data->has_fan |= 0x40; 1289 + data->has_pwm |= 0x40; 1290 + } 1291 + if (!(tmp & 0x40) && (val & 0x04)) { /* fan 8 */ 1292 + data->has_fan |= 0x80; 1293 + data->has_pwm |= 0x80; 1294 + } 1295 + } 1296 + 1297 + if (0x08 == (tmp & 0x0c)) { 1298 + if (val & 0x08) /* fan 9 */ 1299 + data->has_fan |= 0x100; 1300 + if (val & 0x10) /* fan 10 */ 1301 + data->has_fan |= 0x200; 1302 + } 1303 + 1304 + if (0x20 == (tmp & 0x30)) { 1305 + if (val & 0x20) /* fan 11 */ 1306 + data->has_fan |= 0x400; 1307 + if (val & 0x40) /* fan 12 */ 1308 + data->has_fan |= 0x800; 1309 + } 1310 + 1311 + if ((tmp & 0x01) && (val & 0x04)) { /* fan 8, second location */ 1312 + data->has_fan |= 0x80; 1313 + data->has_pwm |= 0x80; 1314 + } 1315 + 1316 + /* Register sysfs hooks */ 1317 + for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { 1318 + err = device_create_file(dev, 1319 + &w83793_sensor_attr_2[i].dev_attr); 1320 + if (err) 1321 + goto exit_remove; 1322 + } 1323 + 1324 + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { 1325 + err = device_create_file(dev, &sda_single_files[i].dev_attr); 1326 + if (err) 1327 + goto exit_remove; 1328 + 1329 + } 1330 + 1331 + for (i = 5; i < 12; i++) { 1332 + int j; 1333 + if (!(data->has_fan & (1 << i))) 1334 + continue; 1335 + for (j = 0; j < files_fan; j++) { 1336 + err = device_create_file(dev, 1337 + &w83793_left_fan[(i - 5) * files_fan 1338 + + j].dev_attr); 1339 + if (err) 1340 + goto exit_remove; 1341 + } 1342 + } 1343 + 1344 + for (i = 3; i < 8; i++) { 1345 + int j; 1346 + if (!(data->has_pwm & (1 << i))) 1347 + continue; 1348 + for (j = 0; j < files_pwm; j++) { 1349 + err = device_create_file(dev, 1350 + &w83793_left_pwm[(i - 3) * files_pwm 1351 + + j].dev_attr); 1352 + if (err) 1353 + goto exit_remove; 1354 + } 1355 + } 1356 + 1357 + data->class_dev = hwmon_device_register(dev); 1358 + if (IS_ERR(data->class_dev)) { 1359 + err = PTR_ERR(data->class_dev); 1360 + goto exit_remove; 1361 + } 1362 + 1363 + return 0; 1364 + 1365 + /* Unregister sysfs hooks */ 1366 + 1367 + exit_remove: 1368 + for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) 1369 + device_remove_file(dev, &w83793_sensor_attr_2[i].dev_attr); 1370 + 1371 + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) 1372 + device_remove_file(dev, &sda_single_files[i].dev_attr); 1373 + 1374 + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) 1375 + device_remove_file(dev, &w83793_left_fan[i].dev_attr); 1376 + 1377 + for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) 1378 + device_remove_file(dev, &w83793_left_pwm[i].dev_attr); 1379 + 1380 + if (data->lm75[0] != NULL) { 1381 + i2c_detach_client(data->lm75[0]); 1382 + kfree(data->lm75[0]); 1383 + } 1384 + if (data->lm75[1] != NULL) { 1385 + i2c_detach_client(data->lm75[1]); 1386 + kfree(data->lm75[1]); 1387 + } 1388 + detach_client: 1389 + i2c_detach_client(client); 1390 + free_mem: 1391 + kfree(data); 1392 + exit: 1393 + return err; 1394 + } 1395 + 1396 + static void w83793_update_nonvolatile(struct device *dev) 1397 + { 1398 + struct i2c_client *client = to_i2c_client(dev); 1399 + struct w83793_data *data = i2c_get_clientdata(client); 1400 + int i, j; 1401 + /* 1402 + They are somewhat "stable" registers, and to update them everytime 1403 + takes so much time, it's just not worthy. Update them in a long 1404 + interval to avoid exception. 1405 + */ 1406 + if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300) 1407 + || !data->valid)) 1408 + return; 1409 + /* update voltage limits */ 1410 + for (i = 1; i < 3; i++) { 1411 + for (j = 0; j < ARRAY_SIZE(data->in); j++) { 1412 + data->in[j][i] = 1413 + w83793_read_value(client, W83793_REG_IN[j][i]); 1414 + } 1415 + data->in_low_bits[i] = 1416 + w83793_read_value(client, W83793_REG_IN_LOW_BITS[i]); 1417 + } 1418 + 1419 + for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { 1420 + /* Update the Fan measured value and limits */ 1421 + if (!(data->has_fan & (1 << i))) { 1422 + continue; 1423 + } 1424 + data->fan_min[i] = 1425 + w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8; 1426 + data->fan_min[i] |= 1427 + w83793_read_value(client, W83793_REG_FAN_MIN(i) + 1); 1428 + } 1429 + 1430 + for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { 1431 + data->temp_fan_map[i] = 1432 + w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); 1433 + for (j = 1; j < 5; j++) { 1434 + data->temp[i][j] = 1435 + w83793_read_value(client, W83793_REG_TEMP[i][j]); 1436 + } 1437 + data->temp_cruise[i] = 1438 + w83793_read_value(client, W83793_REG_TEMP_CRUISE(i)); 1439 + for (j = 0; j < 7; j++) { 1440 + data->sf2_pwm[i][j] = 1441 + w83793_read_value(client, W83793_REG_SF2_PWM(i, j)); 1442 + data->sf2_temp[i][j] = 1443 + w83793_read_value(client, 1444 + W83793_REG_SF2_TEMP(i, j)); 1445 + } 1446 + } 1447 + 1448 + for (i = 0; i < ARRAY_SIZE(data->temp_mode); i++) 1449 + data->temp_mode[i] = 1450 + w83793_read_value(client, W83793_REG_TEMP_MODE[i]); 1451 + 1452 + for (i = 0; i < ARRAY_SIZE(data->tolerance); i++) { 1453 + data->tolerance[i] = 1454 + w83793_read_value(client, W83793_REG_TEMP_TOL(i)); 1455 + } 1456 + 1457 + for (i = 0; i < ARRAY_SIZE(data->pwm); i++) { 1458 + if (!(data->has_pwm & (1 << i))) 1459 + continue; 1460 + data->pwm[i][PWM_NONSTOP] = 1461 + w83793_read_value(client, W83793_REG_PWM(i, PWM_NONSTOP)); 1462 + data->pwm[i][PWM_START] = 1463 + w83793_read_value(client, W83793_REG_PWM(i, PWM_START)); 1464 + data->pwm_stop_time[i] = 1465 + w83793_read_value(client, W83793_REG_PWM_STOP_TIME(i)); 1466 + } 1467 + 1468 + data->pwm_default = w83793_read_value(client, W83793_REG_PWM_DEFAULT); 1469 + data->pwm_enable = w83793_read_value(client, W83793_REG_PWM_ENABLE); 1470 + data->pwm_uptime = w83793_read_value(client, W83793_REG_PWM_UPTIME); 1471 + data->pwm_downtime = w83793_read_value(client, W83793_REG_PWM_DOWNTIME); 1472 + data->temp_critical = 1473 + w83793_read_value(client, W83793_REG_TEMP_CRITICAL); 1474 + data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP); 1475 + 1476 + for (i = 0; i < ARRAY_SIZE(data->beeps); i++) { 1477 + data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i)); 1478 + } 1479 + 1480 + data->last_nonvolatile = jiffies; 1481 + } 1482 + 1483 + static struct w83793_data *w83793_update_device(struct device *dev) 1484 + { 1485 + struct i2c_client *client = to_i2c_client(dev); 1486 + struct w83793_data *data = i2c_get_clientdata(client); 1487 + int i; 1488 + 1489 + mutex_lock(&data->update_lock); 1490 + 1491 + if (!(time_after(jiffies, data->last_updated + HZ * 2) 1492 + || !data->valid)) 1493 + goto END; 1494 + 1495 + /* Update the voltages measured value and limits */ 1496 + for (i = 0; i < ARRAY_SIZE(data->in); i++) 1497 + data->in[i][IN_READ] = 1498 + w83793_read_value(client, W83793_REG_IN[i][IN_READ]); 1499 + 1500 + data->in_low_bits[IN_READ] = 1501 + w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]); 1502 + 1503 + for (i = 0; i < ARRAY_SIZE(data->fan); i++) { 1504 + if (!(data->has_fan & (1 << i))) { 1505 + continue; 1506 + } 1507 + data->fan[i] = 1508 + w83793_read_value(client, W83793_REG_FAN(i)) << 8; 1509 + data->fan[i] |= 1510 + w83793_read_value(client, W83793_REG_FAN(i) + 1); 1511 + } 1512 + 1513 + for (i = 0; i < ARRAY_SIZE(data->temp); i++) 1514 + data->temp[i][TEMP_READ] = 1515 + w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); 1516 + 1517 + data->temp_low_bits = 1518 + w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); 1519 + 1520 + for (i = 0; i < ARRAY_SIZE(data->pwm); i++) { 1521 + if (data->has_pwm & (1 << i)) 1522 + data->pwm[i][PWM_DUTY] = 1523 + w83793_read_value(client, 1524 + W83793_REG_PWM(i, PWM_DUTY)); 1525 + } 1526 + 1527 + for (i = 0; i < ARRAY_SIZE(data->alarms); i++) 1528 + data->alarms[i] = 1529 + w83793_read_value(client, W83793_REG_ALARM(i)); 1530 + data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); 1531 + data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); 1532 + w83793_update_nonvolatile(dev); 1533 + data->last_updated = jiffies; 1534 + data->valid = 1; 1535 + 1536 + END: 1537 + mutex_unlock(&data->update_lock); 1538 + return data; 1539 + } 1540 + 1541 + /* Ignore the possibility that somebody change bank outside the driver 1542 + Must be called with data->update_lock held, except during initialization */ 1543 + static u8 w83793_read_value(struct i2c_client *client, u16 reg) 1544 + { 1545 + struct w83793_data *data = i2c_get_clientdata(client); 1546 + u8 res = 0xff; 1547 + u8 new_bank = reg >> 8; 1548 + 1549 + new_bank |= data->bank & 0xfc; 1550 + if (data->bank != new_bank) { 1551 + if (i2c_smbus_write_byte_data 1552 + (client, W83793_REG_BANKSEL, new_bank) >= 0) 1553 + data->bank = new_bank; 1554 + else { 1555 + dev_err(&client->dev, 1556 + "set bank to %d failed, fall back " 1557 + "to bank %d, read reg 0x%x error\n", 1558 + new_bank, data->bank, reg); 1559 + res = 0x0; /* read 0x0 from the chip */ 1560 + goto END; 1561 + } 1562 + } 1563 + res = i2c_smbus_read_byte_data(client, reg & 0xff); 1564 + END: 1565 + return res; 1566 + } 1567 + 1568 + /* Must be called with data->update_lock held, except during initialization */ 1569 + static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value) 1570 + { 1571 + struct w83793_data *data = i2c_get_clientdata(client); 1572 + int res; 1573 + u8 new_bank = reg >> 8; 1574 + 1575 + new_bank |= data->bank & 0xfc; 1576 + if (data->bank != new_bank) { 1577 + if ((res = i2c_smbus_write_byte_data 1578 + (client, W83793_REG_BANKSEL, new_bank)) >= 0) 1579 + data->bank = new_bank; 1580 + else { 1581 + dev_err(&client->dev, 1582 + "set bank to %d failed, fall back " 1583 + "to bank %d, write reg 0x%x error\n", 1584 + new_bank, data->bank, reg); 1585 + goto END; 1586 + } 1587 + } 1588 + 1589 + res = i2c_smbus_write_byte_data(client, reg & 0xff, value); 1590 + END: 1591 + return res; 1592 + } 1593 + 1594 + static int __init sensors_w83793_init(void) 1595 + { 1596 + return i2c_add_driver(&w83793_driver); 1597 + } 1598 + 1599 + static void __exit sensors_w83793_exit(void) 1600 + { 1601 + i2c_del_driver(&w83793_driver); 1602 + } 1603 + 1604 + MODULE_AUTHOR("Yuan Mu"); 1605 + MODULE_DESCRIPTION("w83793 driver"); 1606 + MODULE_LICENSE("GPL"); 1607 + 1608 + module_init(sensors_w83793_init); 1609 + module_exit(sensors_w83793_exit);
+1 -1
drivers/i2c/busses/i2c-ali1563.c
··· 2 * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge 3 * 4 * Copyright (C) 2004 Patrick Mochel 5 - * 2005 Rudolf Marek <r.marek@sh.cvut.cz> 6 * 7 * The 1563 southbridge is deceptively similar to the 1533, with a 8 * few notable exceptions. One of those happens to be the fact they
··· 2 * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge 3 * 4 * Copyright (C) 2004 Patrick Mochel 5 + * 2005 Rudolf Marek <r.marek@assembler.cz> 6 * 7 * The 1563 southbridge is deceptively similar to the 1533, with a 8 * few notable exceptions. One of those happens to be the fact they
-1
include/linux/i2c-id.h
··· 142 #define I2C_DRIVERID_MTP008 1023 143 #define I2C_DRIVERID_DS1621 1024 144 #define I2C_DRIVERID_ADM1024 1025 145 - #define I2C_DRIVERID_IT87 1026 146 #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */ 147 #define I2C_DRIVERID_FSCPOS 1028 148 #define I2C_DRIVERID_FSCSCY 1029
··· 142 #define I2C_DRIVERID_MTP008 1023 143 #define I2C_DRIVERID_DS1621 1024 144 #define I2C_DRIVERID_ADM1024 1025 145 #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */ 146 #define I2C_DRIVERID_FSCPOS 1028 147 #define I2C_DRIVERID_FSCSCY 1029