diff options
75 files changed, 6818 insertions, 1846 deletions
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 870cda9416e9..170bf862437b 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp | |||
@@ -4,7 +4,7 @@ Kernel driver coretemp | |||
4 | Supported chips: | 4 | Supported chips: |
5 | * All Intel Core family | 5 | * All Intel Core family |
6 | Prefix: 'coretemp' | 6 | Prefix: 'coretemp' |
7 | CPUID: family 0x6, models 0xe, 0xf | 7 | CPUID: family 0x6, models 0xe, 0xf, 0x16 |
8 | Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual | 8 | Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual |
9 | Volume 3A: System Programming Guide | 9 | Volume 3A: System Programming Guide |
10 | 10 | ||
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 index 1a0f3d64ab80..8f446070e64a 100644 --- a/Documentation/hwmon/dme1737 +++ b/Documentation/hwmon/dme1737 | |||
@@ -6,6 +6,10 @@ Supported chips: | |||
6 | Prefix: 'dme1737' | 6 | Prefix: 'dme1737' |
7 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | 7 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e |
8 | Datasheet: Provided by SMSC upon request and under NDA | 8 | Datasheet: Provided by SMSC upon request and under NDA |
9 | * SMSC SCH3112, SCH3114, SCH3116 | ||
10 | Prefix: 'sch311x' | ||
11 | Addresses scanned: none, address read from Super-I/O config space | ||
12 | Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf | ||
9 | 13 | ||
10 | Authors: | 14 | Authors: |
11 | Juerg Haefliger <juergh@gmail.com> | 15 | Juerg Haefliger <juergh@gmail.com> |
@@ -27,16 +31,25 @@ Description | |||
27 | ----------- | 31 | ----------- |
28 | 32 | ||
29 | This driver implements support for the hardware monitoring capabilities of the | 33 | This driver implements support for the hardware monitoring capabilities of the |
30 | SMSC DME1737 and Asus A8000 (which are the same) Super-I/O chips. This chip | 34 | SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O |
31 | features monitoring of 3 temp sensors temp[1-3] (2 remote diodes and 1 | 35 | chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote |
32 | internal), 7 voltages in[0-6] (6 external and 1 internal) and 6 fan speeds | 36 | diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up |
33 | fan[1-6]. Additionally, the chip implements 5 PWM outputs pwm[1-3,5-6] for | 37 | to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM |
34 | controlling fan speeds both manually and automatically. | 38 | outputs pwm[1-3,5-6] for controlling fan speeds both manually and |
35 | 39 | automatically. | |
36 | Fan[3-6] and pwm[3,5-6] are optional features and their availability is | 40 | |
37 | dependent on the configuration of the chip. The driver will detect which | 41 | For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6] |
38 | features are present during initialization and create the sysfs attributes | 42 | and pwm[3,5-6] are optional features and their availability depends on the |
39 | accordingly. | 43 | configuration of the chip. The driver will detect which features are present |
44 | during initialization and create the sysfs attributes accordingly. | ||
45 | |||
46 | For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and | ||
47 | pwm[5-6] don't exist. | ||
48 | |||
49 | The hardware monitoring features of the DME1737 and A8000 are only accessible | ||
50 | via SMBus, while the SCH311x only provides access via the ISA bus. The driver | ||
51 | will therefore register itself as an I2C client driver if it detects a DME1737 | ||
52 | or A8000 and as a platform driver if it detects a SCH311x chip. | ||
40 | 53 | ||
41 | 54 | ||
42 | Voltage Monitoring | 55 | Voltage Monitoring |
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f index 94e0d2cbd3d2..f0d55976740a 100644 --- a/Documentation/hwmon/f71805f +++ b/Documentation/hwmon/f71805f | |||
@@ -6,6 +6,10 @@ Supported chips: | |||
6 | Prefix: 'f71805f' | 6 | Prefix: 'f71805f' |
7 | Addresses scanned: none, address read from Super I/O config space | 7 | Addresses scanned: none, address read from Super I/O config space |
8 | Datasheet: Available from the Fintek website | 8 | Datasheet: Available from the Fintek website |
9 | * Fintek F71806F/FG | ||
10 | Prefix: 'f71872f' | ||
11 | Addresses scanned: none, address read from Super I/O config space | ||
12 | Datasheet: Available from the Fintek website | ||
9 | * Fintek F71872F/FG | 13 | * Fintek F71872F/FG |
10 | Prefix: 'f71872f' | 14 | Prefix: 'f71872f' |
11 | Addresses scanned: none, address read from Super I/O config space | 15 | Addresses scanned: none, address read from Super I/O config space |
@@ -38,6 +42,9 @@ The Fintek F71872F/FG Super I/O chip is almost the same, with two | |||
38 | additional internal voltages monitored (VSB and battery). It also features | 42 | additional internal voltages monitored (VSB and battery). It also features |
39 | 6 VID inputs. The VID inputs are not yet supported by this driver. | 43 | 6 VID inputs. The VID inputs are not yet supported by this driver. |
40 | 44 | ||
45 | The Fintek F71806F/FG Super-I/O chip is essentially the same as the | ||
46 | F71872F/FG, and is undistinguishable therefrom. | ||
47 | |||
41 | The driver assumes that no more than one chip is present, which seems | 48 | The driver assumes that no more than one chip is present, which seems |
42 | reasonable. | 49 | reasonable. |
43 | 50 | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 81ecc7e41c50..5b704a40256b 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -90,7 +90,8 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you | |||
90 | can't have both on a given board. | 90 | can't have both on a given board. |
91 | 91 | ||
92 | The IT8716F, IT8718F and later IT8712F revisions have support for | 92 | The IT8716F, IT8718F and later IT8712F revisions have support for |
93 | 2 additional fans. They are not yet supported by the driver. | 93 | 2 additional fans. They are supported by the driver for the IT8716F and |
94 | IT8718F but not for the IT8712F | ||
94 | 95 | ||
95 | The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional | 96 | The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional |
96 | 16-bit tachometer counters for fans 1 to 3. This is better (no more fan | 97 | 16-bit tachometer counters for fans 1 to 3. This is better (no more fan |
diff --git a/Documentation/hwmon/lm78 b/Documentation/hwmon/lm78 index fd5dc7a19f0e..dfc318a60fd4 100644 --- a/Documentation/hwmon/lm78 +++ b/Documentation/hwmon/lm78 | |||
@@ -56,16 +56,6 @@ should work with. This is hardcoded by the mainboard and/or processor itself. | |||
56 | It is a value in volts. When it is unconnected, you will often find the | 56 | It is a value in volts. When it is unconnected, you will often find the |
57 | value 3.50 V here. | 57 | value 3.50 V here. |
58 | 58 | ||
59 | In addition to the alarms described above, there are a couple of additional | ||
60 | ones. There is a BTI alarm, which gets triggered when an external chip has | ||
61 | crossed its limits. Usually, this is connected to all LM75 chips; if at | ||
62 | least one crosses its limits, this bit gets set. The CHAS alarm triggers | ||
63 | if your computer case is open. The FIFO alarms should never trigger; it | ||
64 | indicates an internal error. The SMI_IN alarm indicates some other chip | ||
65 | has triggered an SMI interrupt. As we do not use SMI interrupts at all, | ||
66 | this condition usually indicates there is a problem with some other | ||
67 | device. | ||
68 | |||
69 | If an alarm triggers, it will remain triggered until the hardware register | 59 | If an alarm triggers, it will remain triggered until the hardware register |
70 | is read at least once. This means that the cause for the alarm may | 60 | is read at least once. This means that the cause for the alarm may |
71 | already have disappeared! Note that in the current implementation, all | 61 | already have disappeared! Note that in the current implementation, all |
diff --git a/Documentation/hwmon/lm93 b/Documentation/hwmon/lm93 index 4e4a1dc1d2da..ac711f357faf 100644 --- a/Documentation/hwmon/lm93 +++ b/Documentation/hwmon/lm93 | |||
@@ -7,7 +7,7 @@ Supported chips: | |||
7 | Addresses scanned: I2C 0x2c-0x2e | 7 | Addresses scanned: I2C 0x2c-0x2e |
8 | Datasheet: http://www.national.com/ds.cgi/LM/LM93.pdf | 8 | Datasheet: http://www.national.com/ds.cgi/LM/LM93.pdf |
9 | 9 | ||
10 | Author: | 10 | Authors: |
11 | Mark M. Hoffman <mhoffman@lightlink.com> | 11 | Mark M. Hoffman <mhoffman@lightlink.com> |
12 | Ported to 2.6 by Eric J. Bowersox <ericb@aspsys.com> | 12 | Ported to 2.6 by Eric J. Bowersox <ericb@aspsys.com> |
13 | Adapted to 2.6.20 by Carsten Emde <ce@osadl.org> | 13 | Adapted to 2.6.20 by Carsten Emde <ce@osadl.org> |
@@ -16,7 +16,6 @@ Author: | |||
16 | Module Parameters | 16 | Module Parameters |
17 | ----------------- | 17 | ----------------- |
18 | 18 | ||
19 | (specific to LM93) | ||
20 | * init: integer | 19 | * init: integer |
21 | Set to non-zero to force some initializations (default is 0). | 20 | Set to non-zero to force some initializations (default is 0). |
22 | * disable_block: integer | 21 | * disable_block: integer |
@@ -37,30 +36,13 @@ Module Parameters | |||
37 | I.e. this parameter controls the VID pin input thresholds; if your VID | 36 | I.e. this parameter controls the VID pin input thresholds; if your VID |
38 | inputs are not working, try changing this. The default value is "0". | 37 | inputs are not working, try changing this. The default value is "0". |
39 | 38 | ||
40 | (common among sensor drivers) | ||
41 | * force: short array (min = 1, max = 48) | ||
42 | List of adapter,address pairs to assume to be present. Autodetection | ||
43 | of the target device will still be attempted. Use one of the more | ||
44 | specific force directives below if this doesn't detect the device. | ||
45 | * force_lm93: short array (min = 1, max = 48) | ||
46 | List of adapter,address pairs which are unquestionably assumed to contain | ||
47 | a 'lm93' chip | ||
48 | * ignore: short array (min = 1, max = 48) | ||
49 | List of adapter,address pairs not to scan | ||
50 | * ignore_range: short array (min = 1, max = 48) | ||
51 | List of adapter,start-addr,end-addr triples not to scan | ||
52 | * probe: short array (min = 1, max = 48) | ||
53 | List of adapter,address pairs to scan additionally | ||
54 | * probe_range: short array (min = 1, max = 48) | ||
55 | List of adapter,start-addr,end-addr triples to scan additionally | ||
56 | |||
57 | 39 | ||
58 | Hardware Description | 40 | Hardware Description |
59 | -------------------- | 41 | -------------------- |
60 | 42 | ||
61 | (from the datasheet) | 43 | (from the datasheet) |
62 | 44 | ||
63 | The LM93, hardware monitor, has a two wire digital interface compatible with | 45 | The LM93 hardware monitor has a two wire digital interface compatible with |
64 | SMBus 2.0. Using an 8-bit ADC, the LM93 measures the temperature of two remote | 46 | SMBus 2.0. Using an 8-bit ADC, the LM93 measures the temperature of two remote |
65 | diode connected transistors as well as its own die and 16 power supply | 47 | diode connected transistors as well as its own die and 16 power supply |
66 | voltages. To set fan speed, the LM93 has two PWM outputs that are each | 48 | voltages. To set fan speed, the LM93 has two PWM outputs that are each |
@@ -69,18 +51,12 @@ table based. The LM93 includes a digital filter that can be invoked to smooth | |||
69 | temperature readings for better control of fan speed. The LM93 has four | 51 | temperature readings for better control of fan speed. The LM93 has four |
70 | tachometer inputs to measure fan speed. Limit and status registers for all | 52 | tachometer inputs to measure fan speed. Limit and status registers for all |
71 | measured values are included. The LM93 builds upon the functionality of | 53 | measured values are included. The LM93 builds upon the functionality of |
72 | previous motherboard management ASICs and uses some of the LM85 s features | 54 | previous motherboard management ASICs and uses some of the LM85's features |
73 | (i.e. smart tachometer mode). It also adds measurement and control support | 55 | (i.e. smart tachometer mode). It also adds measurement and control support |
74 | for dynamic Vccp monitoring and PROCHOT. It is designed to monitor a dual | 56 | for dynamic Vccp monitoring and PROCHOT. It is designed to monitor a dual |
75 | processor Xeon class motherboard with a minimum of external components. | 57 | processor Xeon class motherboard with a minimum of external components. |
76 | 58 | ||
77 | 59 | ||
78 | Driver Description | ||
79 | ------------------ | ||
80 | |||
81 | This driver implements support for the National Semiconductor LM93. | ||
82 | |||
83 | |||
84 | User Interface | 60 | User Interface |
85 | -------------- | 61 | -------------- |
86 | 62 | ||
@@ -101,7 +77,7 @@ These intervals can be found in the sysfs files prochot1_interval and | |||
101 | prochot2_interval. The values in these files specify the intervals for | 77 | prochot2_interval. The values in these files specify the intervals for |
102 | #P1_PROCHOT and #P2_PROCHOT, respectively. Selecting a value not in this | 78 | #P1_PROCHOT and #P2_PROCHOT, respectively. Selecting a value not in this |
103 | list will cause the driver to use the next largest interval. The available | 79 | list will cause the driver to use the next largest interval. The available |
104 | intervals are: | 80 | intervals are (in seconds): |
105 | 81 | ||
106 | #PROCHOT intervals: 0.73, 1.46, 2.9, 5.8, 11.7, 23.3, 46.6, 93.2, 186, 372 | 82 | #PROCHOT intervals: 0.73, 1.46, 2.9, 5.8, 11.7, 23.3, 46.6, 93.2, 186, 372 |
107 | 83 | ||
@@ -111,12 +87,12 @@ assert #P2_PROCHOT, and vice-versa. This mode is enabled by writing a | |||
111 | non-zero integer to the sysfs file prochot_short. | 87 | non-zero integer to the sysfs file prochot_short. |
112 | 88 | ||
113 | The LM93 can also override the #PROCHOT pins by driving a PWM signal onto | 89 | The LM93 can also override the #PROCHOT pins by driving a PWM signal onto |
114 | one or both of them. When overridden, the signal has a period of 3.56 mS, | 90 | one or both of them. When overridden, the signal has a period of 3.56 ms, |
115 | a minimum pulse width of 5 clocks (at 22.5kHz => 6.25% duty cycle), and | 91 | a minimum pulse width of 5 clocks (at 22.5kHz => 6.25% duty cycle), and |
116 | a maximum pulse width of 80 clocks (at 22.5kHz => 99.88% duty cycle). | 92 | a maximum pulse width of 80 clocks (at 22.5kHz => 99.88% duty cycle). |
117 | 93 | ||
118 | The sysfs files prochot1_override and prochot2_override contain boolean | 94 | The sysfs files prochot1_override and prochot2_override contain boolean |
119 | intgers which enable or disable the override function for #P1_PROCHOT and | 95 | integers which enable or disable the override function for #P1_PROCHOT and |
120 | #P2_PROCHOT, respectively. The sysfs file prochot_override_duty_cycle | 96 | #P2_PROCHOT, respectively. The sysfs file prochot_override_duty_cycle |
121 | contains a value controlling the duty cycle for the PWM signal used when | 97 | contains a value controlling the duty cycle for the PWM signal used when |
122 | the override function is enabled. This value ranges from 0 to 15, with 0 | 98 | the override function is enabled. This value ranges from 0 to 15, with 0 |
@@ -166,7 +142,7 @@ frequency values are constrained by the hardware. Selecting a value which is | |||
166 | not available will cause the driver to use the next largest value. Also note | 142 | not available will cause the driver to use the next largest value. Also note |
167 | that this parameter has implications for the Smart Tach Mode (see above). | 143 | that this parameter has implications for the Smart Tach Mode (see above). |
168 | 144 | ||
169 | PWM Output Frequencies: 12, 36, 48, 60, 72, 84, 96, 22500 (h/w default) | 145 | PWM Output Frequencies (in Hz): 12, 36, 48, 60, 72, 84, 96, 22500 (default) |
170 | 146 | ||
171 | Automatic PWM: | 147 | Automatic PWM: |
172 | 148 | ||
@@ -178,7 +154,7 @@ individual control sources to which the PWM output is bound. | |||
178 | The eight control sources are: temp1-temp4 (aka "zones" in the datasheet), | 154 | The eight control sources are: temp1-temp4 (aka "zones" in the datasheet), |
179 | #PROCHOT 1 & 2, and #VRDHOT 1 & 2. The bindings are expressed as a bitmask | 155 | #PROCHOT 1 & 2, and #VRDHOT 1 & 2. The bindings are expressed as a bitmask |
180 | in the sysfs files pwm<n>_auto_channels, where a "1" enables the binding, and | 156 | in the sysfs files pwm<n>_auto_channels, where a "1" enables the binding, and |
181 | a "0" disables it. The h/w default is 0x0f (all temperatures bound). | 157 | a "0" disables it. The h/w default is 0x0f (all temperatures bound). |
182 | 158 | ||
183 | 0x01 - Temp 1 | 159 | 0x01 - Temp 1 |
184 | 0x02 - Temp 2 | 160 | 0x02 - Temp 2 |
@@ -324,89 +300,3 @@ LM93 Unique sysfs Files | |||
324 | 300 | ||
325 | gpio input state of 8 GPIO pins; read-only | 301 | gpio input state of 8 GPIO pins; read-only |
326 | 302 | ||
327 | |||
328 | Sample Configuration File | ||
329 | ------------------------- | ||
330 | |||
331 | Here is a sample LM93 chip config for sensors.conf: | ||
332 | |||
333 | ---------- cut here ---------- | ||
334 | chip "lm93-*" | ||
335 | |||
336 | # VOLTAGE INPUTS | ||
337 | |||
338 | # labels and scaling based on datasheet recommendations | ||
339 | label in1 "+12V1" | ||
340 | compute in1 @ * 12.945, @ / 12.945 | ||
341 | set in1_min 12 * 0.90 | ||
342 | set in1_max 12 * 1.10 | ||
343 | |||
344 | label in2 "+12V2" | ||
345 | compute in2 @ * 12.945, @ / 12.945 | ||
346 | set in2_min 12 * 0.90 | ||
347 | set in2_max 12 * 1.10 | ||
348 | |||
349 | label in3 "+12V3" | ||
350 | compute in3 @ * 12.945, @ / 12.945 | ||
351 | set in3_min 12 * 0.90 | ||
352 | set in3_max 12 * 1.10 | ||
353 | |||
354 | label in4 "FSB_Vtt" | ||
355 | |||
356 | label in5 "3GIO" | ||
357 | |||
358 | label in6 "ICH_Core" | ||
359 | |||
360 | label in7 "Vccp1" | ||
361 | |||
362 | label in8 "Vccp2" | ||
363 | |||
364 | label in9 "+3.3V" | ||
365 | set in9_min 3.3 * 0.90 | ||
366 | set in9_max 3.3 * 1.10 | ||
367 | |||
368 | label in10 "+5V" | ||
369 | set in10_min 5.0 * 0.90 | ||
370 | set in10_max 5.0 * 1.10 | ||
371 | |||
372 | label in11 "SCSI_Core" | ||
373 | |||
374 | label in12 "Mem_Core" | ||
375 | |||
376 | label in13 "Mem_Vtt" | ||
377 | |||
378 | label in14 "Gbit_Core" | ||
379 | |||
380 | # Assuming R1/R2 = 4.1143, and 3.3V reference | ||
381 | # -12V = (4.1143 + 1) * (@ - 3.3) + 3.3 | ||
382 | label in15 "-12V" | ||
383 | compute in15 @ * 5.1143 - 13.57719, (@ + 13.57719) / 5.1143 | ||
384 | set in15_min -12 * 0.90 | ||
385 | set in15_max -12 * 1.10 | ||
386 | |||
387 | label in16 "+3.3VSB" | ||
388 | set in16_min 3.3 * 0.90 | ||
389 | set in16_max 3.3 * 1.10 | ||
390 | |||
391 | # TEMPERATURE INPUTS | ||
392 | |||
393 | label temp1 "CPU1" | ||
394 | label temp2 "CPU2" | ||
395 | label temp3 "LM93" | ||
396 | |||
397 | # TACHOMETER INPUTS | ||
398 | |||
399 | label fan1 "Fan1" | ||
400 | set fan1_min 3000 | ||
401 | label fan2 "Fan2" | ||
402 | set fan2_min 3000 | ||
403 | label fan3 "Fan3" | ||
404 | set fan3_min 3000 | ||
405 | label fan4 "Fan4" | ||
406 | set fan4_min 3000 | ||
407 | |||
408 | # PWM OUTPUTS | ||
409 | |||
410 | label pwm1 "CPU1" | ||
411 | label pwm2 "CPU2" | ||
412 | |||
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index b3a9e1b9dbda..a17b692d2679 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
@@ -67,6 +67,10 @@ between readings to be caught and alarmed. The exact definition of an | |||
67 | alarm (for example, whether a threshold must be met or must be exceeded | 67 | alarm (for example, whether a threshold must be met or must be exceeded |
68 | to cause an alarm) is chip-dependent. | 68 | to cause an alarm) is chip-dependent. |
69 | 69 | ||
70 | When setting values of hwmon sysfs attributes, the string representation of | ||
71 | the desired value must be written, note that strings which are not a number | ||
72 | are interpreted as 0! For more on how written strings are interpreted see the | ||
73 | "sysfs attribute writes interpretation" section at the end of this file. | ||
70 | 74 | ||
71 | ------------------------------------------------------------------------- | 75 | ------------------------------------------------------------------------- |
72 | 76 | ||
@@ -78,8 +82,21 @@ RW read/write value | |||
78 | Read/write values may be read-only for some chips, depending on the | 82 | Read/write values may be read-only for some chips, depending on the |
79 | hardware implementation. | 83 | hardware implementation. |
80 | 84 | ||
81 | All entries are optional, and should only be created in a given driver | 85 | All entries (except name) are optional, and should only be created in a |
82 | if the chip has the feature. | 86 | given driver if the chip has the feature. |
87 | |||
88 | |||
89 | ******** | ||
90 | * Name * | ||
91 | ******** | ||
92 | |||
93 | name The chip name. | ||
94 | This should be a short, lowercase string, not containing | ||
95 | spaces nor dashes, representing the chip name. This is | ||
96 | the only mandatory attribute. | ||
97 | I2C devices get this attribute created automatically. | ||
98 | RO | ||
99 | |||
83 | 100 | ||
84 | ************ | 101 | ************ |
85 | * Voltages * | 102 | * Voltages * |
@@ -104,18 +121,17 @@ in[0-*]_input Voltage input value. | |||
104 | by the chip driver, and must be done by the application. | 121 | by the chip driver, and must be done by the application. |
105 | However, some drivers (notably lm87 and via686a) | 122 | However, some drivers (notably lm87 and via686a) |
106 | do scale, because of internal resistors built into a chip. | 123 | do scale, because of internal resistors built into a chip. |
107 | These drivers will output the actual voltage. | 124 | These drivers will output the actual voltage. Rule of |
108 | 125 | thumb: drivers should report the voltage values at the | |
109 | Typical usage: | 126 | "pins" of the chip. |
110 | in0_* CPU #1 voltage (not scaled) | 127 | |
111 | in1_* CPU #2 voltage (not scaled) | 128 | in[0-*]_label Suggested voltage channel label. |
112 | in2_* 3.3V nominal (not scaled) | 129 | Text string |
113 | in3_* 5.0V nominal (scaled) | 130 | Should only be created if the driver has hints about what |
114 | in4_* 12.0V nominal (scaled) | 131 | this voltage channel is being used for, and user-space |
115 | in5_* -12.0V nominal (scaled) | 132 | doesn't. In all other cases, the label is provided by |
116 | in6_* -5.0V nominal (scaled) | 133 | user-space. |
117 | in7_* varies | 134 | RO |
118 | in8_* varies | ||
119 | 135 | ||
120 | cpu[0-*]_vid CPU core reference voltage. | 136 | cpu[0-*]_vid CPU core reference voltage. |
121 | Unit: millivolt | 137 | Unit: millivolt |
@@ -159,6 +175,13 @@ fan[1-*]_target | |||
159 | Only makes sense if the chip supports closed-loop fan speed | 175 | Only makes sense if the chip supports closed-loop fan speed |
160 | control based on the measured fan speed. | 176 | control based on the measured fan speed. |
161 | 177 | ||
178 | fan[1-*]_label Suggested fan channel label. | ||
179 | Text string | ||
180 | Should only be created if the driver has hints about what | ||
181 | this fan channel is being used for, and user-space doesn't. | ||
182 | In all other cases, the label is provided by user-space. | ||
183 | RO | ||
184 | |||
162 | Also see the Alarms section for status flags associated with fans. | 185 | Also see the Alarms section for status flags associated with fans. |
163 | 186 | ||
164 | 187 | ||
@@ -219,12 +242,12 @@ temp[1-*]_auto_point[1-*]_temp_hyst | |||
219 | **************** | 242 | **************** |
220 | 243 | ||
221 | temp[1-*]_type Sensor type selection. | 244 | temp[1-*]_type Sensor type selection. |
222 | Integers 1 to 6 or thermistor Beta value (typically 3435) | 245 | Integers 1 to 6 |
223 | RW | 246 | RW |
224 | 1: PII/Celeron Diode | 247 | 1: PII/Celeron Diode |
225 | 2: 3904 transistor | 248 | 2: 3904 transistor |
226 | 3: thermal diode | 249 | 3: thermal diode |
227 | 4: thermistor (default/unknown Beta) | 250 | 4: thermistor |
228 | 5: AMD AMDSI | 251 | 5: AMD AMDSI |
229 | 6: Intel PECI | 252 | 6: Intel PECI |
230 | Not all types are supported by all chips | 253 | Not all types are supported by all chips |
@@ -260,18 +283,19 @@ temp[1-*]_crit_hyst | |||
260 | from the critical value. | 283 | from the critical value. |
261 | RW | 284 | RW |
262 | 285 | ||
263 | temp[1-4]_offset | 286 | temp[1-*]_offset |
264 | Temperature offset which is added to the temperature reading | 287 | Temperature offset which is added to the temperature reading |
265 | by the chip. | 288 | by the chip. |
266 | Unit: millidegree Celsius | 289 | Unit: millidegree Celsius |
267 | Read/Write value. | 290 | Read/Write value. |
268 | 291 | ||
269 | If there are multiple temperature sensors, temp1_* is | 292 | temp[1-*]_label Suggested temperature channel label. |
270 | generally the sensor inside the chip itself, | 293 | Text string |
271 | reported as "motherboard temperature". temp2_* to | 294 | Should only be created if the driver has hints about what |
272 | temp4_* are generally sensors external to the chip | 295 | this temperature channel is being used for, and user-space |
273 | itself, for example the thermal diode inside the CPU or | 296 | doesn't. In all other cases, the label is provided by |
274 | a thermistor nearby. | 297 | user-space. |
298 | RO | ||
275 | 299 | ||
276 | Some chips measure temperature using external thermistors and an ADC, and | 300 | Some chips measure temperature using external thermistors and an ADC, and |
277 | report the temperature measurement as a voltage. Converting this voltage | 301 | report the temperature measurement as a voltage. Converting this voltage |
@@ -393,14 +417,53 @@ beep_mask Bitmask for beep. | |||
393 | RW | 417 | RW |
394 | 418 | ||
395 | 419 | ||
396 | ********* | 420 | sysfs attribute writes interpretation |
397 | * Other * | 421 | ------------------------------------- |
398 | ********* | 422 | |
399 | 423 | hwmon sysfs attributes always contain numbers, so the first thing to do is to | |
400 | eeprom Raw EEPROM data in binary form. | 424 | convert the input to a number, there are 2 ways todo this depending whether |
401 | RO | 425 | the number can be negative or not: |
402 | 426 | unsigned long u = simple_strtoul(buf, NULL, 10); | |
403 | pec Enable or disable PEC (SMBus only) | 427 | long s = simple_strtol(buf, NULL, 10); |
404 | 0: disable | 428 | |
405 | 1: enable | 429 | With buf being the buffer with the user input being passed by the kernel. |
406 | RW | 430 | Notice that we do not use the second argument of strto[u]l, and thus cannot |
431 | tell when 0 is returned, if this was really 0 or is caused by invalid input. | ||
432 | This is done deliberately as checking this everywhere would add a lot of | ||
433 | code to the kernel. | ||
434 | |||
435 | Notice that it is important to always store the converted value in an | ||
436 | unsigned long or long, so that no wrap around can happen before any further | ||
437 | checking. | ||
438 | |||
439 | After the input string is converted to an (unsigned) long, the value should be | ||
440 | checked if its acceptable. Be careful with further conversions on the value | ||
441 | before checking it for validity, as these conversions could still cause a wrap | ||
442 | around before the check. For example do not multiply the result, and only | ||
443 | add/subtract if it has been divided before the add/subtract. | ||
444 | |||
445 | What to do if a value is found to be invalid, depends on the type of the | ||
446 | sysfs attribute that is being set. If it is a continuous setting like a | ||
447 | tempX_max or inX_max attribute, then the value should be clamped to its | ||
448 | limits using SENSORS_LIMIT(value, min_limit, max_limit). If it is not | ||
449 | continuous like for example a tempX_type, then when an invalid value is | ||
450 | written, -EINVAL should be returned. | ||
451 | |||
452 | Example1, temp1_max, register is a signed 8 bit value (-128 - 127 degrees): | ||
453 | |||
454 | long v = simple_strtol(buf, NULL, 10) / 1000; | ||
455 | v = SENSORS_LIMIT(v, -128, 127); | ||
456 | /* write v to register */ | ||
457 | |||
458 | Example2, fan divider setting, valid values 2, 4 and 8: | ||
459 | |||
460 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
461 | |||
462 | switch (v) { | ||
463 | case 2: v = 1; break; | ||
464 | case 4: v = 2; break; | ||
465 | case 8: v = 3; break; | ||
466 | default: | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | /* write v to register */ | ||
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index db9881df88a5..f153b2f6d62c 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d | |||
@@ -75,46 +75,64 @@ Voltage sensors (also known as IN sensors) report their values in millivolts. | |||
75 | An alarm is triggered if the voltage has crossed a programmable minimum | 75 | An alarm is triggered if the voltage has crossed a programmable minimum |
76 | or maximum limit. | 76 | or maximum limit. |
77 | 77 | ||
78 | The bit ordering for the alarm "realtime status register" and the | 78 | The w83791d has a global bit used to enable beeping from the speaker when an |
79 | "beep enable registers" are different. | 79 | alarm is triggered as well as a bitmask to enable or disable the beep for |
80 | 80 | specific alarms. You need both the global beep enable bit and the | |
81 | in0 (VCORE) : alarms: 0x000001 beep_enable: 0x000001 | 81 | corresponding beep bit to be on for a triggered alarm to sound a beep. |
82 | in1 (VINR0) : alarms: 0x000002 beep_enable: 0x002000 <== mismatch | 82 | |
83 | in2 (+3.3VIN): alarms: 0x000004 beep_enable: 0x000004 | 83 | The sysfs interface to the gloabal enable is via the sysfs beep_enable file. |
84 | in3 (5VDD) : alarms: 0x000008 beep_enable: 0x000008 | 84 | This file is used for both legacy and new code. |
85 | in4 (+12VIN) : alarms: 0x000100 beep_enable: 0x000100 | 85 | |
86 | in5 (-12VIN) : alarms: 0x000200 beep_enable: 0x000200 | 86 | The sysfs interface to the beep bitmask has migrated from the original legacy |
87 | in6 (-5VIN) : alarms: 0x000400 beep_enable: 0x000400 | 87 | method of a single sysfs beep_mask file to a newer method using multiple |
88 | in7 (VSB) : alarms: 0x080000 beep_enable: 0x010000 <== mismatch | 88 | *_beep files as described in .../Documentation/hwmon/sysfs-interface. |
89 | in8 (VBAT) : alarms: 0x100000 beep_enable: 0x020000 <== mismatch | 89 | |
90 | in9 (VINR1) : alarms: 0x004000 beep_enable: 0x004000 | 90 | A similar change has occured for the bitmap corresponding to the alarms. The |
91 | temp1 : alarms: 0x000010 beep_enable: 0x000010 | 91 | original legacy method used a single sysfs alarms file containing a bitmap |
92 | temp2 : alarms: 0x000020 beep_enable: 0x000020 | 92 | of triggered alarms. The newer method uses multiple sysfs *_alarm files |
93 | temp3 : alarms: 0x002000 beep_enable: 0x000002 <== mismatch | 93 | (again following the pattern described in sysfs-interface). |
94 | fan1 : alarms: 0x000040 beep_enable: 0x000040 | 94 | |
95 | fan2 : alarms: 0x000080 beep_enable: 0x000080 | 95 | Since both methods read and write the underlying hardware, they can be used |
96 | fan3 : alarms: 0x000800 beep_enable: 0x000800 | 96 | interchangeably and changes in one will automatically be reflected by |
97 | fan4 : alarms: 0x200000 beep_enable: 0x200000 | 97 | the other. If you use the legacy bitmask method, your user-space code is |
98 | fan5 : alarms: 0x400000 beep_enable: 0x400000 | 98 | responsible for handling the fact that the alarms and beep_mask bitmaps |
99 | tart1 : alarms: 0x010000 beep_enable: 0x040000 <== mismatch | 99 | are not the same (see the table below). |
100 | tart2 : alarms: 0x020000 beep_enable: 0x080000 <== mismatch | 100 | |
101 | tart3 : alarms: 0x040000 beep_enable: 0x100000 <== mismatch | 101 | NOTE: All new code should be written to use the newer sysfs-interface |
102 | case_open : alarms: 0x001000 beep_enable: 0x001000 | 102 | specification as that avoids bitmap problems and is the preferred interface |
103 | user_enable : alarms: -------- beep_enable: 0x800000 | 103 | going forward. |
104 | 104 | ||
105 | *** NOTE: It is the responsibility of user-space code to handle the fact | 105 | The driver reads the hardware chip values at most once every three seconds. |
106 | that the beep enable and alarm bits are in different positions when using that | 106 | User mode code requesting values more often will receive cached values. |
107 | feature of the chip. | 107 | |
108 | 108 | Alarms bitmap vs. beep_mask bitmask | |
109 | When an alarm goes off, you can be warned by a beeping signal through your | 109 | ------------------------------------ |
110 | computer speaker. It is possible to enable all beeping globally, or only | 110 | For legacy code using the alarms and beep_mask files: |
111 | the beeping for some alarms. | 111 | |
112 | 112 | in0 (VCORE) : alarms: 0x000001 beep_mask: 0x000001 | |
113 | The driver only reads the chip values each 3 seconds; reading them more | 113 | in1 (VINR0) : alarms: 0x000002 beep_mask: 0x002000 <== mismatch |
114 | often will do no harm, but will return 'old' values. | 114 | in2 (+3.3VIN): alarms: 0x000004 beep_mask: 0x000004 |
115 | in3 (5VDD) : alarms: 0x000008 beep_mask: 0x000008 | ||
116 | in4 (+12VIN) : alarms: 0x000100 beep_mask: 0x000100 | ||
117 | in5 (-12VIN) : alarms: 0x000200 beep_mask: 0x000200 | ||
118 | in6 (-5VIN) : alarms: 0x000400 beep_mask: 0x000400 | ||
119 | in7 (VSB) : alarms: 0x080000 beep_mask: 0x010000 <== mismatch | ||
120 | in8 (VBAT) : alarms: 0x100000 beep_mask: 0x020000 <== mismatch | ||
121 | in9 (VINR1) : alarms: 0x004000 beep_mask: 0x004000 | ||
122 | temp1 : alarms: 0x000010 beep_mask: 0x000010 | ||
123 | temp2 : alarms: 0x000020 beep_mask: 0x000020 | ||
124 | temp3 : alarms: 0x002000 beep_mask: 0x000002 <== mismatch | ||
125 | fan1 : alarms: 0x000040 beep_mask: 0x000040 | ||
126 | fan2 : alarms: 0x000080 beep_mask: 0x000080 | ||
127 | fan3 : alarms: 0x000800 beep_mask: 0x000800 | ||
128 | fan4 : alarms: 0x200000 beep_mask: 0x200000 | ||
129 | fan5 : alarms: 0x400000 beep_mask: 0x400000 | ||
130 | tart1 : alarms: 0x010000 beep_mask: 0x040000 <== mismatch | ||
131 | tart2 : alarms: 0x020000 beep_mask: 0x080000 <== mismatch | ||
132 | tart3 : alarms: 0x040000 beep_mask: 0x100000 <== mismatch | ||
133 | case_open : alarms: 0x001000 beep_mask: 0x001000 | ||
134 | global_enable: alarms: -------- beep_mask: 0x800000 (modified via beep_enable) | ||
115 | 135 | ||
116 | W83791D TODO: | 136 | W83791D TODO: |
117 | --------------- | 137 | --------------- |
118 | Provide a patch for per-file alarms and beep enables as defined in the hwmon | ||
119 | documentation (Documentation/hwmon/sysfs-interface) | ||
120 | Provide a patch for smart-fan control (still need appropriate motherboard/fans) | 138 | Provide a patch for smart-fan control (still need appropriate motherboard/fans) |
diff --git a/MAINTAINERS b/MAINTAINERS index 0fdb8a50b921..012fa837845d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1660,7 +1660,8 @@ P: Mark M. Hoffman | |||
1660 | M: mhoffman@lightlink.com | 1660 | M: mhoffman@lightlink.com |
1661 | L: lm-sensors@lm-sensors.org | 1661 | L: lm-sensors@lm-sensors.org |
1662 | W: http://www.lm-sensors.org/ | 1662 | W: http://www.lm-sensors.org/ |
1663 | T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git | 1663 | T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing |
1664 | T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release | ||
1664 | S: Maintained | 1665 | S: Maintained |
1665 | 1666 | ||
1666 | HARDWARE RANDOM NUMBER GENERATOR CORE | 1667 | HARDWARE RANDOM NUMBER GENERATOR CORE |
@@ -4177,7 +4178,7 @@ W83791D HARDWARE MONITORING DRIVER | |||
4177 | P: Charles Spirakis | 4178 | P: Charles Spirakis |
4178 | M: bezaur@gmail.com | 4179 | M: bezaur@gmail.com |
4179 | L: lm-sensors@lm-sensors.org | 4180 | L: lm-sensors@lm-sensors.org |
4180 | S: Maintained | 4181 | S: Odd Fixes |
4181 | 4182 | ||
4182 | W83793 HARDWARE MONITORING DRIVER | 4183 | W83793 HARDWARE MONITORING DRIVER |
4183 | P: Rudolf Marek | 4184 | P: Rudolf Marek |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 192953b29b28..e47f88170806 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -30,7 +30,7 @@ config HWMON_VID | |||
30 | 30 | ||
31 | config SENSORS_ABITUGURU | 31 | config SENSORS_ABITUGURU |
32 | tristate "Abit uGuru (rev 1 & 2)" | 32 | tristate "Abit uGuru (rev 1 & 2)" |
33 | depends on EXPERIMENTAL | 33 | depends on X86 && EXPERIMENTAL |
34 | help | 34 | help |
35 | If you say yes here you get support for the sensor part of the first | 35 | If you say yes here you get support for the sensor part of the first |
36 | and second revision of the Abit uGuru chip. The voltage and frequency | 36 | and second revision of the Abit uGuru chip. The voltage and frequency |
@@ -45,7 +45,7 @@ config SENSORS_ABITUGURU | |||
45 | 45 | ||
46 | config SENSORS_ABITUGURU3 | 46 | config SENSORS_ABITUGURU3 |
47 | tristate "Abit uGuru (rev 3)" | 47 | tristate "Abit uGuru (rev 3)" |
48 | depends on HWMON && EXPERIMENTAL | 48 | depends on X86 && EXPERIMENTAL |
49 | help | 49 | help |
50 | If you say yes here you get support for the sensor part of the | 50 | If you say yes here you get support for the sensor part of the |
51 | third revision of the Abit uGuru chip. Only reading the sensors | 51 | third revision of the Abit uGuru chip. Only reading the sensors |
@@ -133,6 +133,16 @@ config SENSORS_ADM9240 | |||
133 | This driver can also be built as a module. If so, the module | 133 | This driver can also be built as a module. If so, the module |
134 | will be called adm9240. | 134 | will be called adm9240. |
135 | 135 | ||
136 | config SENSORS_ADT7470 | ||
137 | tristate "Analog Devices ADT7470" | ||
138 | depends on I2C && EXPERIMENTAL | ||
139 | help | ||
140 | If you say yes here you get support for the Analog Devices | ||
141 | ADT7470 temperature monitoring chips. | ||
142 | |||
143 | This driver can also be built as a module. If so, the module | ||
144 | will be called adt7470. | ||
145 | |||
136 | config SENSORS_K8TEMP | 146 | config SENSORS_K8TEMP |
137 | tristate "AMD Athlon64/FX or Opteron temperature sensor" | 147 | tristate "AMD Athlon64/FX or Opteron temperature sensor" |
138 | depends on X86 && PCI && EXPERIMENTAL | 148 | depends on X86 && PCI && EXPERIMENTAL |
@@ -172,7 +182,7 @@ config SENSORS_AMS_I2C | |||
172 | 182 | ||
173 | config SENSORS_ASB100 | 183 | config SENSORS_ASB100 |
174 | tristate "Asus ASB100 Bach" | 184 | tristate "Asus ASB100 Bach" |
175 | depends on I2C && EXPERIMENTAL | 185 | depends on X86 && I2C && EXPERIMENTAL |
176 | select HWMON_VID | 186 | select HWMON_VID |
177 | help | 187 | help |
178 | If you say yes here you get support for the ASB100 Bach sensor | 188 | If you say yes here you get support for the ASB100 Bach sensor |
@@ -206,19 +216,39 @@ config SENSORS_DS1621 | |||
206 | will be called ds1621. | 216 | will be called ds1621. |
207 | 217 | ||
208 | config SENSORS_F71805F | 218 | config SENSORS_F71805F |
209 | tristate "Fintek F71805F/FG and F71872F/FG" | 219 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" |
210 | depends on EXPERIMENTAL | 220 | depends on EXPERIMENTAL |
211 | help | 221 | help |
212 | If you say yes here you get support for hardware monitoring | 222 | If you say yes here you get support for hardware monitoring |
213 | features of the Fintek F71805F/FG and F71872F/FG Super-I/O | 223 | features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG |
214 | chips. | 224 | Super-I/O chips. |
215 | 225 | ||
216 | This driver can also be built as a module. If so, the module | 226 | This driver can also be built as a module. If so, the module |
217 | will be called f71805f. | 227 | will be called f71805f. |
218 | 228 | ||
229 | config SENSORS_F71882FG | ||
230 | tristate "Fintek F71882FG and F71883FG" | ||
231 | depends on EXPERIMENTAL | ||
232 | help | ||
233 | If you say yes here you get support for hardware monitoring | ||
234 | features of the Fintek F71882FG and F71883FG Super-I/O chips. | ||
235 | |||
236 | This driver can also be built as a module. If so, the module | ||
237 | will be called f71882fg. | ||
238 | |||
239 | config SENSORS_F75375S | ||
240 | tristate "Fintek F75375S/SP and F75373"; | ||
241 | depends on I2C && EXPERIMENTAL | ||
242 | help | ||
243 | If you say yes here you get support for hardware monitoring | ||
244 | features of the Fintek F75375S/SP and F75373 | ||
245 | |||
246 | This driver can also be built as a module. If so, the module | ||
247 | will be called f75375s. | ||
248 | |||
219 | config SENSORS_FSCHER | 249 | config SENSORS_FSCHER |
220 | tristate "FSC Hermes" | 250 | tristate "FSC Hermes" |
221 | depends on I2C | 251 | depends on X86 && I2C |
222 | help | 252 | help |
223 | If you say yes here you get support for Fujitsu Siemens | 253 | If you say yes here you get support for Fujitsu Siemens |
224 | Computers Hermes sensor chips. | 254 | Computers Hermes sensor chips. |
@@ -228,7 +258,7 @@ config SENSORS_FSCHER | |||
228 | 258 | ||
229 | config SENSORS_FSCPOS | 259 | config SENSORS_FSCPOS |
230 | tristate "FSC Poseidon" | 260 | tristate "FSC Poseidon" |
231 | depends on I2C | 261 | depends on X86 && I2C |
232 | help | 262 | help |
233 | If you say yes here you get support for Fujitsu Siemens | 263 | If you say yes here you get support for Fujitsu Siemens |
234 | Computers Poseidon sensor chips. | 264 | Computers Poseidon sensor chips. |
@@ -236,6 +266,20 @@ config SENSORS_FSCPOS | |||
236 | This driver can also be built as a module. If so, the module | 266 | This driver can also be built as a module. If so, the module |
237 | will be called fscpos. | 267 | will be called fscpos. |
238 | 268 | ||
269 | config SENSORS_FSCHMD | ||
270 | tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles" | ||
271 | depends on X86 && I2C && EXPERIMENTAL | ||
272 | help | ||
273 | If you say yes here you get support for various Fujitsu Siemens | ||
274 | Computers sensor chips. | ||
275 | |||
276 | This is a new merged driver for FSC sensor chips which is intended | ||
277 | as a replacment for the fscpos, fscscy and fscher drivers and adds | ||
278 | support for several other FCS sensor chips. | ||
279 | |||
280 | This driver can also be built as a module. If so, the module | ||
281 | will be called fschmd. | ||
282 | |||
239 | config SENSORS_GL518SM | 283 | config SENSORS_GL518SM |
240 | tristate "Genesys Logic GL518SM" | 284 | tristate "Genesys Logic GL518SM" |
241 | depends on I2C | 285 | depends on I2C |
@@ -265,6 +309,19 @@ config SENSORS_CORETEMP | |||
265 | sensor inside your CPU. Supported all are all known variants | 309 | sensor inside your CPU. Supported all are all known variants |
266 | of Intel Core family. | 310 | of Intel Core family. |
267 | 311 | ||
312 | config SENSORS_IBMPEX | ||
313 | tristate "IBM PowerExecutive temperature/power sensors" | ||
314 | select IPMI_SI | ||
315 | depends on IPMI_HANDLER | ||
316 | help | ||
317 | If you say yes here you get support for the temperature and | ||
318 | power sensors in various IBM System X servers that support | ||
319 | PowerExecutive. So far this includes the x3550, x3650, x3655, | ||
320 | x3755, and certain HS20 blades. | ||
321 | |||
322 | This driver can also be built as a module. If so, the module | ||
323 | will be called ibmpex. | ||
324 | |||
268 | config SENSORS_IT87 | 325 | config SENSORS_IT87 |
269 | tristate "ITE IT87xx and compatibles" | 326 | tristate "ITE IT87xx and compatibles" |
270 | select HWMON_VID | 327 | select HWMON_VID |
@@ -401,7 +458,7 @@ config SENSORS_LM92 | |||
401 | 458 | ||
402 | config SENSORS_LM93 | 459 | config SENSORS_LM93 |
403 | tristate "National Semiconductor LM93 and compatibles" | 460 | tristate "National Semiconductor LM93 and compatibles" |
404 | depends on HWMON && I2C | 461 | depends on I2C |
405 | select HWMON_VID | 462 | select HWMON_VID |
406 | help | 463 | help |
407 | If you say yes here you get support for National Semiconductor LM93 | 464 | If you say yes here you get support for National Semiconductor LM93 |
@@ -466,13 +523,13 @@ config SENSORS_SIS5595 | |||
466 | will be called sis5595. | 523 | will be called sis5595. |
467 | 524 | ||
468 | config SENSORS_DME1737 | 525 | config SENSORS_DME1737 |
469 | tristate "SMSC DME1737 and compatibles" | 526 | tristate "SMSC DME1737, SCH311x and compatibles" |
470 | depends on I2C && EXPERIMENTAL | 527 | depends on I2C && EXPERIMENTAL |
471 | select HWMON_VID | 528 | select HWMON_VID |
472 | help | 529 | help |
473 | If you say yes here you get support for the hardware monitoring | 530 | If you say yes here you get support for the hardware monitoring |
474 | and fan control features of the SMSC DME1737 (and compatibles | 531 | and fan control features of the SMSC DME1737 (and compatibles |
475 | like the Asus A8000) Super-I/O chip. | 532 | like the Asus A8000) and SCH311x Super-I/O chips. |
476 | 533 | ||
477 | This driver can also be built as a module. If so, the module | 534 | This driver can also be built as a module. If so, the module |
478 | will be called dme1737. | 535 | will be called dme1737. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d04f90031ebf..6da3eef94306 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | |||
22 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | 22 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o |
23 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 23 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
24 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 24 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
25 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o | ||
25 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | 26 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o |
26 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 27 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
27 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 28 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
@@ -29,11 +30,15 @@ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | |||
29 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | 30 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o |
30 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 31 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
31 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 32 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
33 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o | ||
34 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o | ||
32 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 35 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
36 | obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o | ||
33 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 37 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
34 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 38 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
35 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 39 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
36 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 40 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
41 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | ||
37 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 42 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
38 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 43 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
39 | obj-$(CONFIG_SENSORS_LM63) += lm63.o | 44 | obj-$(CONFIG_SENSORS_LM63) += lm63.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 2317f4bb9c92..4dbdb81ea3b1 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -176,7 +176,7 @@ MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" | |||
176 | The structure is dynamically allocated, at the same time when a new | 176 | The structure is dynamically allocated, at the same time when a new |
177 | abituguru device is allocated. */ | 177 | abituguru device is allocated. */ |
178 | struct abituguru_data { | 178 | struct abituguru_data { |
179 | struct class_device *class_dev; /* hwmon registered device */ | 179 | struct device *hwmon_dev; /* hwmon registered device */ |
180 | struct mutex update_lock; /* protect access to data and uGuru */ | 180 | struct mutex update_lock; /* protect access to data and uGuru */ |
181 | unsigned long last_updated; /* In jiffies */ | 181 | unsigned long last_updated; /* In jiffies */ |
182 | unsigned short addr; /* uguru base address */ | 182 | unsigned short addr; /* uguru base address */ |
@@ -1287,11 +1287,11 @@ static int __devinit abituguru_probe(struct platform_device *pdev) | |||
1287 | &abituguru_sysfs_attr[i].dev_attr)) | 1287 | &abituguru_sysfs_attr[i].dev_attr)) |
1288 | goto abituguru_probe_error; | 1288 | goto abituguru_probe_error; |
1289 | 1289 | ||
1290 | data->class_dev = hwmon_device_register(&pdev->dev); | 1290 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1291 | if (!IS_ERR(data->class_dev)) | 1291 | if (!IS_ERR(data->hwmon_dev)) |
1292 | return 0; /* success */ | 1292 | return 0; /* success */ |
1293 | 1293 | ||
1294 | res = PTR_ERR(data->class_dev); | 1294 | res = PTR_ERR(data->hwmon_dev); |
1295 | abituguru_probe_error: | 1295 | abituguru_probe_error: |
1296 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1296 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
1297 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1297 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
@@ -1308,7 +1308,7 @@ static int __devexit abituguru_remove(struct platform_device *pdev) | |||
1308 | int i; | 1308 | int i; |
1309 | struct abituguru_data *data = platform_get_drvdata(pdev); | 1309 | struct abituguru_data *data = platform_get_drvdata(pdev); |
1310 | 1310 | ||
1311 | hwmon_device_unregister(data->class_dev); | 1311 | hwmon_device_unregister(data->hwmon_dev); |
1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index cdd8b6dea16d..cb2331bfd9d5 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -124,7 +124,7 @@ struct abituguru3_motherboard_info { | |||
124 | The structure is dynamically allocated, at the same time when a new | 124 | The structure is dynamically allocated, at the same time when a new |
125 | abituguru3 device is allocated. */ | 125 | abituguru3 device is allocated. */ |
126 | struct abituguru3_data { | 126 | struct abituguru3_data { |
127 | struct class_device *class_dev; /* hwmon registered device */ | 127 | struct device *hwmon_dev; /* hwmon registered device */ |
128 | struct mutex update_lock; /* protect access to data and uGuru */ | 128 | struct mutex update_lock; /* protect access to data and uGuru */ |
129 | unsigned short addr; /* uguru base address */ | 129 | unsigned short addr; /* uguru base address */ |
130 | char valid; /* !=0 if following fields are valid */ | 130 | char valid; /* !=0 if following fields are valid */ |
@@ -933,9 +933,9 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) | |||
933 | &abituguru3_sysfs_attr[i].dev_attr)) | 933 | &abituguru3_sysfs_attr[i].dev_attr)) |
934 | goto abituguru3_probe_error; | 934 | goto abituguru3_probe_error; |
935 | 935 | ||
936 | data->class_dev = hwmon_device_register(&pdev->dev); | 936 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
937 | if (IS_ERR(data->class_dev)) { | 937 | if (IS_ERR(data->hwmon_dev)) { |
938 | res = PTR_ERR(data->class_dev); | 938 | res = PTR_ERR(data->hwmon_dev); |
939 | goto abituguru3_probe_error; | 939 | goto abituguru3_probe_error; |
940 | } | 940 | } |
941 | 941 | ||
@@ -957,7 +957,7 @@ static int __devexit abituguru3_remove(struct platform_device *pdev) | |||
957 | struct abituguru3_data *data = platform_get_drvdata(pdev); | 957 | struct abituguru3_data *data = platform_get_drvdata(pdev); |
958 | 958 | ||
959 | platform_set_drvdata(pdev, NULL); | 959 | platform_set_drvdata(pdev, NULL); |
960 | hwmon_device_unregister(data->class_dev); | 960 | hwmon_device_unregister(data->hwmon_dev); |
961 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 961 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
962 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 962 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
963 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | 963 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) |
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index cc8b624a1e51..fcd7fe78f3f9 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c | |||
@@ -47,7 +47,7 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN, | |||
47 | 47 | ||
48 | struct ad7418_data { | 48 | struct ad7418_data { |
49 | struct i2c_client client; | 49 | struct i2c_client client; |
50 | struct class_device *class_dev; | 50 | struct device *hwmon_dev; |
51 | struct attribute_group attrs; | 51 | struct attribute_group attrs; |
52 | enum chips type; | 52 | enum chips type; |
53 | struct mutex lock; | 53 | struct mutex lock; |
@@ -172,7 +172,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | |||
172 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 172 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
173 | struct i2c_client *client = to_i2c_client(dev); | 173 | struct i2c_client *client = to_i2c_client(dev); |
174 | struct ad7418_data *data = i2c_get_clientdata(client); | 174 | struct ad7418_data *data = i2c_get_clientdata(client); |
175 | int temp = simple_strtol(buf, NULL, 10); | 175 | long temp = simple_strtol(buf, NULL, 10); |
176 | 176 | ||
177 | mutex_lock(&data->lock); | 177 | mutex_lock(&data->lock); |
178 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); | 178 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); |
@@ -326,9 +326,9 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) | |||
326 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) | 326 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) |
327 | goto exit_detach; | 327 | goto exit_detach; |
328 | 328 | ||
329 | data->class_dev = hwmon_device_register(&client->dev); | 329 | data->hwmon_dev = hwmon_device_register(&client->dev); |
330 | if (IS_ERR(data->class_dev)) { | 330 | if (IS_ERR(data->hwmon_dev)) { |
331 | err = PTR_ERR(data->class_dev); | 331 | err = PTR_ERR(data->hwmon_dev); |
332 | goto exit_remove; | 332 | goto exit_remove; |
333 | } | 333 | } |
334 | 334 | ||
@@ -347,7 +347,7 @@ exit: | |||
347 | static int ad7418_detach_client(struct i2c_client *client) | 347 | static int ad7418_detach_client(struct i2c_client *client) |
348 | { | 348 | { |
349 | struct ad7418_data *data = i2c_get_clientdata(client); | 349 | struct ad7418_data *data = i2c_get_clientdata(client); |
350 | hwmon_device_unregister(data->class_dev); | 350 | hwmon_device_unregister(data->hwmon_dev); |
351 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 351 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
352 | i2c_detach_client(client); | 352 | i2c_detach_client(client); |
353 | kfree(data); | 353 | kfree(data); |
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index c466329b2ef4..ebdc6d7db231 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | adm1021.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | adm1021.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and | 4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and |
5 | Philip Edelbrock <phil@netroedge.com> | 5 | Philip Edelbrock <phil@netroedge.com> |
6 | 6 | ||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/hwmon.h> | 27 | #include <linux/hwmon.h> |
28 | #include <linux/hwmon-sysfs.h> | ||
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
30 | 31 | ||
@@ -32,93 +33,77 @@ | |||
32 | /* Addresses to scan */ | 33 | /* Addresses to scan */ |
33 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, | 34 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, |
34 | 0x29, 0x2a, 0x2b, | 35 | 0x29, 0x2a, 0x2b, |
35 | 0x4c, 0x4d, 0x4e, | 36 | 0x4c, 0x4d, 0x4e, |
36 | I2C_CLIENT_END }; | 37 | I2C_CLIENT_END }; |
37 | 38 | ||
38 | /* Insmod parameters */ | 39 | /* Insmod parameters */ |
39 | I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066); | 40 | I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, |
41 | mc1066); | ||
40 | 42 | ||
41 | /* adm1021 constants specified below */ | 43 | /* adm1021 constants specified below */ |
42 | 44 | ||
43 | /* The adm1021 registers */ | 45 | /* The adm1021 registers */ |
44 | /* Read-only */ | 46 | /* Read-only */ |
45 | #define ADM1021_REG_TEMP 0x00 | 47 | /* For nr in 0-1 */ |
46 | #define ADM1021_REG_REMOTE_TEMP 0x01 | 48 | #define ADM1021_REG_TEMP(nr) (nr) |
47 | #define ADM1021_REG_STATUS 0x02 | 49 | #define ADM1021_REG_STATUS 0x02 |
48 | #define ADM1021_REG_MAN_ID 0x0FE /* 0x41 = AMD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/ | 50 | /* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */ |
49 | #define ADM1021_REG_DEV_ID 0x0FF /* ADM1021 = 0x0X, ADM1023 = 0x3X */ | 51 | #define ADM1021_REG_MAN_ID 0xFE |
50 | #define ADM1021_REG_DIE_CODE 0x0FF /* MAX1617A */ | 52 | /* ADM1021 = 0x0X, ADM1023 = 0x3X */ |
53 | #define ADM1021_REG_DEV_ID 0xFF | ||
51 | /* These use different addresses for reading/writing */ | 54 | /* These use different addresses for reading/writing */ |
52 | #define ADM1021_REG_CONFIG_R 0x03 | 55 | #define ADM1021_REG_CONFIG_R 0x03 |
53 | #define ADM1021_REG_CONFIG_W 0x09 | 56 | #define ADM1021_REG_CONFIG_W 0x09 |
54 | #define ADM1021_REG_CONV_RATE_R 0x04 | 57 | #define ADM1021_REG_CONV_RATE_R 0x04 |
55 | #define ADM1021_REG_CONV_RATE_W 0x0A | 58 | #define ADM1021_REG_CONV_RATE_W 0x0A |
56 | /* These are for the ADM1023's additional precision on the remote temp sensor */ | 59 | /* These are for the ADM1023's additional precision on the remote temp sensor */ |
57 | #define ADM1021_REG_REM_TEMP_PREC 0x010 | 60 | #define ADM1023_REG_REM_TEMP_PREC 0x10 |
58 | #define ADM1021_REG_REM_OFFSET 0x011 | 61 | #define ADM1023_REG_REM_OFFSET 0x11 |
59 | #define ADM1021_REG_REM_OFFSET_PREC 0x012 | 62 | #define ADM1023_REG_REM_OFFSET_PREC 0x12 |
60 | #define ADM1021_REG_REM_TOS_PREC 0x013 | 63 | #define ADM1023_REG_REM_TOS_PREC 0x13 |
61 | #define ADM1021_REG_REM_THYST_PREC 0x014 | 64 | #define ADM1023_REG_REM_THYST_PREC 0x14 |
62 | /* limits */ | 65 | /* limits */ |
63 | #define ADM1021_REG_TOS_R 0x05 | 66 | /* For nr in 0-1 */ |
64 | #define ADM1021_REG_TOS_W 0x0B | 67 | #define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr)) |
65 | #define ADM1021_REG_REMOTE_TOS_R 0x07 | 68 | #define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr)) |
66 | #define ADM1021_REG_REMOTE_TOS_W 0x0D | 69 | #define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr)) |
67 | #define ADM1021_REG_THYST_R 0x06 | 70 | #define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr)) |
68 | #define ADM1021_REG_THYST_W 0x0C | ||
69 | #define ADM1021_REG_REMOTE_THYST_R 0x08 | ||
70 | #define ADM1021_REG_REMOTE_THYST_W 0x0E | ||
71 | /* write-only */ | 71 | /* write-only */ |
72 | #define ADM1021_REG_ONESHOT 0x0F | 72 | #define ADM1021_REG_ONESHOT 0x0F |
73 | 73 | ||
74 | |||
75 | /* Conversions. Rounding and limit checking is only done on the TO_REG | ||
76 | variants. Note that you should be a bit careful with which arguments | ||
77 | these macros are called: arguments may be evaluated more than once. | ||
78 | Fixing this is just not worth it. */ | ||
79 | /* Conversions note: 1021 uses normal integer signed-byte format*/ | ||
80 | #define TEMP_FROM_REG(val) (val > 127 ? (val-256)*1000 : val*1000) | ||
81 | #define TEMP_TO_REG(val) (SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255)) | ||
82 | |||
83 | /* Initial values */ | 74 | /* Initial values */ |
84 | 75 | ||
85 | /* Note: Even though I left the low and high limits named os and hyst, | 76 | /* Note: Even though I left the low and high limits named os and hyst, |
86 | they don't quite work like a thermostat the way the LM75 does. I.e., | 77 | they don't quite work like a thermostat the way the LM75 does. I.e., |
87 | a lower temp than THYST actually triggers an alarm instead of | 78 | a lower temp than THYST actually triggers an alarm instead of |
88 | clearing it. Weird, ey? --Phil */ | 79 | clearing it. Weird, ey? --Phil */ |
89 | 80 | ||
90 | /* Each client has this additional data */ | 81 | /* Each client has this additional data */ |
91 | struct adm1021_data { | 82 | struct adm1021_data { |
92 | struct i2c_client client; | 83 | struct i2c_client client; |
93 | struct class_device *class_dev; | 84 | struct device *hwmon_dev; |
94 | enum chips type; | 85 | enum chips type; |
95 | 86 | ||
96 | struct mutex update_lock; | 87 | struct mutex update_lock; |
97 | char valid; /* !=0 if following fields are valid */ | 88 | char valid; /* !=0 if following fields are valid */ |
98 | unsigned long last_updated; /* In jiffies */ | 89 | unsigned long last_updated; /* In jiffies */ |
99 | 90 | ||
100 | u8 temp_max; /* Register values */ | 91 | s8 temp_max[2]; /* Register values */ |
101 | u8 temp_hyst; | 92 | s8 temp_min[2]; |
102 | u8 temp_input; | 93 | s8 temp[2]; |
103 | u8 remote_temp_max; | 94 | u8 alarms; |
104 | u8 remote_temp_hyst; | 95 | /* Special values for ADM1023 only */ |
105 | u8 remote_temp_input; | 96 | u8 remote_temp_prec; |
106 | u8 alarms; | 97 | u8 remote_temp_os_prec; |
107 | /* Special values for ADM1023 only */ | 98 | u8 remote_temp_hyst_prec; |
108 | u8 remote_temp_prec; | 99 | u8 remote_temp_offset; |
109 | u8 remote_temp_os_prec; | 100 | u8 remote_temp_offset_prec; |
110 | u8 remote_temp_hyst_prec; | ||
111 | u8 remote_temp_offset; | ||
112 | u8 remote_temp_offset_prec; | ||
113 | }; | 101 | }; |
114 | 102 | ||
115 | static int adm1021_attach_adapter(struct i2c_adapter *adapter); | 103 | static int adm1021_attach_adapter(struct i2c_adapter *adapter); |
116 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); | 104 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); |
117 | static void adm1021_init_client(struct i2c_client *client); | 105 | static void adm1021_init_client(struct i2c_client *client); |
118 | static int adm1021_detach_client(struct i2c_client *client); | 106 | static int adm1021_detach_client(struct i2c_client *client); |
119 | static int adm1021_read_value(struct i2c_client *client, u8 reg); | ||
120 | static int adm1021_write_value(struct i2c_client *client, u8 reg, | ||
121 | u16 value); | ||
122 | static struct adm1021_data *adm1021_update_device(struct device *dev); | 107 | static struct adm1021_data *adm1021_update_device(struct device *dev); |
123 | 108 | ||
124 | /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ | 109 | /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ |
@@ -135,53 +120,104 @@ static struct i2c_driver adm1021_driver = { | |||
135 | .detach_client = adm1021_detach_client, | 120 | .detach_client = adm1021_detach_client, |
136 | }; | 121 | }; |
137 | 122 | ||
138 | #define show(value) \ | 123 | static ssize_t show_temp(struct device *dev, |
139 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 124 | struct device_attribute *devattr, char *buf) |
140 | { \ | 125 | { |
141 | struct adm1021_data *data = adm1021_update_device(dev); \ | 126 | int index = to_sensor_dev_attr(devattr)->index; |
142 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ | 127 | struct adm1021_data *data = adm1021_update_device(dev); |
128 | |||
129 | return sprintf(buf, "%d\n", 1000 * data->temp[index]); | ||
143 | } | 130 | } |
144 | show(temp_max); | 131 | |
145 | show(temp_hyst); | 132 | static ssize_t show_temp_max(struct device *dev, |
146 | show(temp_input); | 133 | struct device_attribute *devattr, char *buf) |
147 | show(remote_temp_max); | 134 | { |
148 | show(remote_temp_hyst); | 135 | int index = to_sensor_dev_attr(devattr)->index; |
149 | show(remote_temp_input); | 136 | struct adm1021_data *data = adm1021_update_device(dev); |
150 | 137 | ||
151 | #define show2(value) \ | 138 | return sprintf(buf, "%d\n", 1000 * data->temp_max[index]); |
152 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
153 | { \ | ||
154 | struct adm1021_data *data = adm1021_update_device(dev); \ | ||
155 | return sprintf(buf, "%d\n", data->value); \ | ||
156 | } | 139 | } |
157 | show2(alarms); | 140 | |
158 | 141 | static ssize_t show_temp_min(struct device *dev, | |
159 | #define set(value, reg) \ | 142 | struct device_attribute *devattr, char *buf) |
160 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | 143 | { |
161 | { \ | 144 | int index = to_sensor_dev_attr(devattr)->index; |
162 | struct i2c_client *client = to_i2c_client(dev); \ | 145 | struct adm1021_data *data = adm1021_update_device(dev); |
163 | struct adm1021_data *data = i2c_get_clientdata(client); \ | 146 | |
164 | int temp = simple_strtoul(buf, NULL, 10); \ | 147 | return sprintf(buf, "%d\n", 1000 * data->temp_min[index]); |
165 | \ | 148 | } |
166 | mutex_lock(&data->update_lock); \ | 149 | |
167 | data->value = TEMP_TO_REG(temp); \ | 150 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
168 | adm1021_write_value(client, reg, data->value); \ | 151 | char *buf) |
169 | mutex_unlock(&data->update_lock); \ | 152 | { |
170 | return count; \ | 153 | int index = to_sensor_dev_attr(attr)->index; |
154 | struct adm1021_data *data = adm1021_update_device(dev); | ||
155 | return sprintf(buf, "%u\n", (data->alarms >> index) & 1); | ||
156 | } | ||
157 | |||
158 | static ssize_t show_alarms(struct device *dev, | ||
159 | struct device_attribute *attr, | ||
160 | char *buf) | ||
161 | { | ||
162 | struct adm1021_data *data = adm1021_update_device(dev); | ||
163 | return sprintf(buf, "%u\n", data->alarms); | ||
171 | } | 164 | } |
172 | set(temp_max, ADM1021_REG_TOS_W); | ||
173 | set(temp_hyst, ADM1021_REG_THYST_W); | ||
174 | set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W); | ||
175 | set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W); | ||
176 | |||
177 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); | ||
178 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); | ||
179 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); | ||
180 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max); | ||
181 | static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst); | ||
182 | static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL); | ||
183 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
184 | 165 | ||
166 | static ssize_t set_temp_max(struct device *dev, | ||
167 | struct device_attribute *devattr, | ||
168 | const char *buf, size_t count) | ||
169 | { | ||
170 | int index = to_sensor_dev_attr(devattr)->index; | ||
171 | struct i2c_client *client = to_i2c_client(dev); | ||
172 | struct adm1021_data *data = i2c_get_clientdata(client); | ||
173 | long temp = simple_strtol(buf, NULL, 10) / 1000; | ||
174 | |||
175 | mutex_lock(&data->update_lock); | ||
176 | data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); | ||
177 | if (!read_only) | ||
178 | i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index), | ||
179 | data->temp_max[index]); | ||
180 | mutex_unlock(&data->update_lock); | ||
181 | |||
182 | return count; | ||
183 | } | ||
184 | |||
185 | static ssize_t set_temp_min(struct device *dev, | ||
186 | struct device_attribute *devattr, | ||
187 | const char *buf, size_t count) | ||
188 | { | ||
189 | int index = to_sensor_dev_attr(devattr)->index; | ||
190 | struct i2c_client *client = to_i2c_client(dev); | ||
191 | struct adm1021_data *data = i2c_get_clientdata(client); | ||
192 | long temp = simple_strtol(buf, NULL, 10) / 1000; | ||
193 | |||
194 | mutex_lock(&data->update_lock); | ||
195 | data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); | ||
196 | if (!read_only) | ||
197 | i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index), | ||
198 | data->temp_min[index]); | ||
199 | mutex_unlock(&data->update_lock); | ||
200 | |||
201 | return count; | ||
202 | } | ||
203 | |||
204 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
205 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
206 | set_temp_max, 0); | ||
207 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
208 | set_temp_min, 0); | ||
209 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
210 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
211 | set_temp_max, 1); | ||
212 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
213 | set_temp_min, 1); | ||
214 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
215 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
216 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
217 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
218 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); | ||
219 | |||
220 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
185 | 221 | ||
186 | static int adm1021_attach_adapter(struct i2c_adapter *adapter) | 222 | static int adm1021_attach_adapter(struct i2c_adapter *adapter) |
187 | { | 223 | { |
@@ -191,12 +227,17 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) | |||
191 | } | 227 | } |
192 | 228 | ||
193 | static struct attribute *adm1021_attributes[] = { | 229 | static struct attribute *adm1021_attributes[] = { |
194 | &dev_attr_temp1_max.attr, | 230 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
195 | &dev_attr_temp1_min.attr, | 231 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
196 | &dev_attr_temp1_input.attr, | 232 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
197 | &dev_attr_temp2_max.attr, | 233 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
198 | &dev_attr_temp2_min.attr, | 234 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
199 | &dev_attr_temp2_input.attr, | 235 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
236 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
237 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
238 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
239 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
240 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
200 | &dev_attr_alarms.attr, | 241 | &dev_attr_alarms.attr, |
201 | NULL | 242 | NULL |
202 | }; | 243 | }; |
@@ -208,35 +249,44 @@ static const struct attribute_group adm1021_group = { | |||
208 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | 249 | static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) |
209 | { | 250 | { |
210 | int i; | 251 | int i; |
211 | struct i2c_client *new_client; | 252 | struct i2c_client *client; |
212 | struct adm1021_data *data; | 253 | struct adm1021_data *data; |
213 | int err = 0; | 254 | int err = 0; |
214 | const char *type_name = ""; | 255 | const char *type_name = ""; |
256 | int conv_rate, status, config; | ||
215 | 257 | ||
216 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 258 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
259 | pr_debug("adm1021: detect failed, " | ||
260 | "smbus byte data not supported!\n"); | ||
217 | goto error0; | 261 | goto error0; |
262 | } | ||
218 | 263 | ||
219 | /* OK. For now, we presume we have a valid client. We now create the | 264 | /* OK. For now, we presume we have a valid client. We now create the |
220 | client structure, even though we cannot fill it completely yet. | 265 | client structure, even though we cannot fill it completely yet. |
221 | But it allows us to access adm1021_{read,write}_value. */ | 266 | But it allows us to access adm1021 register values. */ |
222 | 267 | ||
223 | if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { | 268 | if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { |
269 | pr_debug("adm1021: detect failed, kzalloc failed!\n"); | ||
224 | err = -ENOMEM; | 270 | err = -ENOMEM; |
225 | goto error0; | 271 | goto error0; |
226 | } | 272 | } |
227 | 273 | ||
228 | new_client = &data->client; | 274 | client = &data->client; |
229 | i2c_set_clientdata(new_client, data); | 275 | i2c_set_clientdata(client, data); |
230 | new_client->addr = address; | 276 | client->addr = address; |
231 | new_client->adapter = adapter; | 277 | client->adapter = adapter; |
232 | new_client->driver = &adm1021_driver; | 278 | client->driver = &adm1021_driver; |
233 | new_client->flags = 0; | 279 | status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS); |
280 | conv_rate = i2c_smbus_read_byte_data(client, | ||
281 | ADM1021_REG_CONV_RATE_R); | ||
282 | config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R); | ||
234 | 283 | ||
235 | /* Now, we do the remaining detection. */ | 284 | /* Now, we do the remaining detection. */ |
236 | if (kind < 0) { | 285 | if (kind < 0) { |
237 | if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00 | 286 | if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00 |
238 | || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00 | 287 | || (conv_rate & 0xF8) != 0x00) { |
239 | || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) { | 288 | pr_debug("adm1021: detect failed, " |
289 | "chip not detected!\n"); | ||
240 | err = -ENODEV; | 290 | err = -ENODEV; |
241 | goto error1; | 291 | goto error1; |
242 | } | 292 | } |
@@ -244,9 +294,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
244 | 294 | ||
245 | /* Determine the chip type. */ | 295 | /* Determine the chip type. */ |
246 | if (kind <= 0) { | 296 | if (kind <= 0) { |
247 | i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID); | 297 | i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); |
248 | if (i == 0x41) | 298 | if (i == 0x41) |
249 | if ((adm1021_read_value(new_client, ADM1021_REG_DEV_ID) & 0x0F0) == 0x030) | 299 | if ((i2c_smbus_read_byte_data(client, |
300 | ADM1021_REG_DEV_ID) & 0xF0) == 0x30) | ||
250 | kind = adm1023; | 301 | kind = adm1023; |
251 | else | 302 | else |
252 | kind = adm1021; | 303 | kind = adm1021; |
@@ -255,15 +306,16 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
255 | else if (i == 0x23) | 306 | else if (i == 0x23) |
256 | kind = gl523sm; | 307 | kind = gl523sm; |
257 | else if ((i == 0x4d) && | 308 | else if ((i == 0x4d) && |
258 | (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01)) | 309 | (i2c_smbus_read_byte_data(client, |
310 | ADM1021_REG_DEV_ID) == 0x01)) | ||
259 | kind = max1617a; | 311 | kind = max1617a; |
260 | else if (i == 0x54) | 312 | else if (i == 0x54) |
261 | kind = mc1066; | 313 | kind = mc1066; |
262 | /* LM84 Mfr ID in a different place, and it has more unused bits */ | 314 | /* LM84 Mfr ID in a different place, and it has more unused bits */ |
263 | else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00 | 315 | else if (conv_rate == 0x00 |
264 | && (kind == 0 /* skip extra detection */ | 316 | && (kind == 0 /* skip extra detection */ |
265 | || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00 | 317 | || ((config & 0x7F) == 0x00 |
266 | && (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00))) | 318 | && (status & 0xAB) == 0x00))) |
267 | kind = lm84; | 319 | kind = lm84; |
268 | else | 320 | else |
269 | kind = max1617; | 321 | kind = max1617; |
@@ -286,37 +338,38 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) | |||
286 | } else if (kind == mc1066) { | 338 | } else if (kind == mc1066) { |
287 | type_name = "mc1066"; | 339 | type_name = "mc1066"; |
288 | } | 340 | } |
341 | pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", | ||
342 | type_name, i2c_adapter_id(adapter), address); | ||
289 | 343 | ||
290 | /* Fill in the remaining client fields and put it into the global list */ | 344 | /* Fill in the remaining client fields */ |
291 | strlcpy(new_client->name, type_name, I2C_NAME_SIZE); | 345 | strlcpy(client->name, type_name, I2C_NAME_SIZE); |
292 | data->type = kind; | 346 | data->type = kind; |
293 | data->valid = 0; | ||
294 | mutex_init(&data->update_lock); | 347 | mutex_init(&data->update_lock); |
295 | 348 | ||
296 | /* Tell the I2C layer a new client has arrived */ | 349 | /* Tell the I2C layer a new client has arrived */ |
297 | if ((err = i2c_attach_client(new_client))) | 350 | if ((err = i2c_attach_client(client))) |
298 | goto error1; | 351 | goto error1; |
299 | 352 | ||
300 | /* Initialize the ADM1021 chip */ | 353 | /* Initialize the ADM1021 chip */ |
301 | if (kind != lm84) | 354 | if (kind != lm84 && !read_only) |
302 | adm1021_init_client(new_client); | 355 | adm1021_init_client(client); |
303 | 356 | ||
304 | /* Register sysfs hooks */ | 357 | /* Register sysfs hooks */ |
305 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1021_group))) | 358 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group))) |
306 | goto error2; | 359 | goto error2; |
307 | 360 | ||
308 | data->class_dev = hwmon_device_register(&new_client->dev); | 361 | data->hwmon_dev = hwmon_device_register(&client->dev); |
309 | if (IS_ERR(data->class_dev)) { | 362 | if (IS_ERR(data->hwmon_dev)) { |
310 | err = PTR_ERR(data->class_dev); | 363 | err = PTR_ERR(data->hwmon_dev); |
311 | goto error3; | 364 | goto error3; |
312 | } | 365 | } |
313 | 366 | ||
314 | return 0; | 367 | return 0; |
315 | 368 | ||
316 | error3: | 369 | error3: |
317 | sysfs_remove_group(&new_client->dev.kobj, &adm1021_group); | 370 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); |
318 | error2: | 371 | error2: |
319 | i2c_detach_client(new_client); | 372 | i2c_detach_client(client); |
320 | error1: | 373 | error1: |
321 | kfree(data); | 374 | kfree(data); |
322 | error0: | 375 | error0: |
@@ -326,10 +379,10 @@ error0: | |||
326 | static void adm1021_init_client(struct i2c_client *client) | 379 | static void adm1021_init_client(struct i2c_client *client) |
327 | { | 380 | { |
328 | /* Enable ADC and disable suspend mode */ | 381 | /* Enable ADC and disable suspend mode */ |
329 | adm1021_write_value(client, ADM1021_REG_CONFIG_W, | 382 | i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W, |
330 | adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF); | 383 | i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF); |
331 | /* Set Conversion rate to 1/sec (this can be tinkered with) */ | 384 | /* Set Conversion rate to 1/sec (this can be tinkered with) */ |
332 | adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04); | 385 | i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04); |
333 | } | 386 | } |
334 | 387 | ||
335 | static int adm1021_detach_client(struct i2c_client *client) | 388 | static int adm1021_detach_client(struct i2c_client *client) |
@@ -337,7 +390,7 @@ static int adm1021_detach_client(struct i2c_client *client) | |||
337 | struct adm1021_data *data = i2c_get_clientdata(client); | 390 | struct adm1021_data *data = i2c_get_clientdata(client); |
338 | int err; | 391 | int err; |
339 | 392 | ||
340 | hwmon_device_unregister(data->class_dev); | 393 | hwmon_device_unregister(data->hwmon_dev); |
341 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); | 394 | sysfs_remove_group(&client->dev.kobj, &adm1021_group); |
342 | 395 | ||
343 | if ((err = i2c_detach_client(client))) | 396 | if ((err = i2c_detach_client(client))) |
@@ -347,19 +400,6 @@ static int adm1021_detach_client(struct i2c_client *client) | |||
347 | return 0; | 400 | return 0; |
348 | } | 401 | } |
349 | 402 | ||
350 | /* All registers are byte-sized */ | ||
351 | static int adm1021_read_value(struct i2c_client *client, u8 reg) | ||
352 | { | ||
353 | return i2c_smbus_read_byte_data(client, reg); | ||
354 | } | ||
355 | |||
356 | static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value) | ||
357 | { | ||
358 | if (!read_only) | ||
359 | return i2c_smbus_write_byte_data(client, reg, value); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static struct adm1021_data *adm1021_update_device(struct device *dev) | 403 | static struct adm1021_data *adm1021_update_device(struct device *dev) |
364 | { | 404 | { |
365 | struct i2c_client *client = to_i2c_client(dev); | 405 | struct i2c_client *client = to_i2c_client(dev); |
@@ -369,21 +409,36 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) | |||
369 | 409 | ||
370 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 410 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
371 | || !data->valid) { | 411 | || !data->valid) { |
412 | int i; | ||
413 | |||
372 | dev_dbg(&client->dev, "Starting adm1021 update\n"); | 414 | dev_dbg(&client->dev, "Starting adm1021 update\n"); |
373 | 415 | ||
374 | data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP); | 416 | for (i = 0; i < 2; i++) { |
375 | data->temp_max = adm1021_read_value(client, ADM1021_REG_TOS_R); | 417 | data->temp[i] = i2c_smbus_read_byte_data(client, |
376 | data->temp_hyst = adm1021_read_value(client, ADM1021_REG_THYST_R); | 418 | ADM1021_REG_TEMP(i)); |
377 | data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP); | 419 | data->temp_max[i] = i2c_smbus_read_byte_data(client, |
378 | data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R); | 420 | ADM1021_REG_TOS_R(i)); |
379 | data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R); | 421 | data->temp_min[i] = i2c_smbus_read_byte_data(client, |
380 | data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c; | 422 | ADM1021_REG_THYST_R(i)); |
423 | } | ||
424 | data->alarms = i2c_smbus_read_byte_data(client, | ||
425 | ADM1021_REG_STATUS) & 0x7c; | ||
381 | if (data->type == adm1023) { | 426 | if (data->type == adm1023) { |
382 | data->remote_temp_prec = adm1021_read_value(client, ADM1021_REG_REM_TEMP_PREC); | 427 | data->remote_temp_prec = |
383 | data->remote_temp_os_prec = adm1021_read_value(client, ADM1021_REG_REM_TOS_PREC); | 428 | i2c_smbus_read_byte_data(client, |
384 | data->remote_temp_hyst_prec = adm1021_read_value(client, ADM1021_REG_REM_THYST_PREC); | 429 | ADM1023_REG_REM_TEMP_PREC); |
385 | data->remote_temp_offset = adm1021_read_value(client, ADM1021_REG_REM_OFFSET); | 430 | data->remote_temp_os_prec = |
386 | data->remote_temp_offset_prec = adm1021_read_value(client, ADM1021_REG_REM_OFFSET_PREC); | 431 | i2c_smbus_read_byte_data(client, |
432 | ADM1023_REG_REM_TOS_PREC); | ||
433 | data->remote_temp_hyst_prec = | ||
434 | i2c_smbus_read_byte_data(client, | ||
435 | ADM1023_REG_REM_THYST_PREC); | ||
436 | data->remote_temp_offset = | ||
437 | i2c_smbus_read_byte_data(client, | ||
438 | ADM1023_REG_REM_OFFSET); | ||
439 | data->remote_temp_offset_prec = | ||
440 | i2c_smbus_read_byte_data(client, | ||
441 | ADM1023_REG_REM_OFFSET_PREC); | ||
387 | } | 442 | } |
388 | data->last_updated = jiffies; | 443 | data->last_updated = jiffies; |
389 | data->valid = 1; | 444 | data->valid = 1; |
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 8c562885b54b..041ecb0bdf48 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c | |||
@@ -133,7 +133,7 @@ static struct i2c_driver adm1025_driver = { | |||
133 | 133 | ||
134 | struct adm1025_data { | 134 | struct adm1025_data { |
135 | struct i2c_client client; | 135 | struct i2c_client client; |
136 | struct class_device *class_dev; | 136 | struct device *hwmon_dev; |
137 | struct mutex update_lock; | 137 | struct mutex update_lock; |
138 | char valid; /* zero until following fields are valid */ | 138 | char valid; /* zero until following fields are valid */ |
139 | unsigned long last_updated; /* in jiffies */ | 139 | unsigned long last_updated; /* in jiffies */ |
@@ -292,7 +292,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
292 | 292 | ||
293 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 293 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
294 | { | 294 | { |
295 | struct adm1025_data *data = adm1025_update_device(dev); | 295 | struct adm1025_data *data = dev_get_drvdata(dev); |
296 | return sprintf(buf, "%u\n", data->vrm); | 296 | return sprintf(buf, "%u\n", data->vrm); |
297 | } | 297 | } |
298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -472,9 +472,9 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) | |||
472 | goto exit_remove; | 472 | goto exit_remove; |
473 | } | 473 | } |
474 | 474 | ||
475 | data->class_dev = hwmon_device_register(&new_client->dev); | 475 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
476 | if (IS_ERR(data->class_dev)) { | 476 | if (IS_ERR(data->hwmon_dev)) { |
477 | err = PTR_ERR(data->class_dev); | 477 | err = PTR_ERR(data->hwmon_dev); |
478 | goto exit_remove; | 478 | goto exit_remove; |
479 | } | 479 | } |
480 | 480 | ||
@@ -538,7 +538,7 @@ static int adm1025_detach_client(struct i2c_client *client) | |||
538 | struct adm1025_data *data = i2c_get_clientdata(client); | 538 | struct adm1025_data *data = i2c_get_clientdata(client); |
539 | int err; | 539 | int err; |
540 | 540 | ||
541 | hwmon_device_unregister(data->class_dev); | 541 | hwmon_device_unregister(data->hwmon_dev); |
542 | sysfs_remove_group(&client->dev.kobj, &adm1025_group); | 542 | sysfs_remove_group(&client->dev.kobj, &adm1025_group); |
543 | sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt); | 543 | sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt); |
544 | 544 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index ba80cd3258c6..aa875ca50d9b 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -260,7 +260,7 @@ struct pwm_data { | |||
260 | 260 | ||
261 | struct adm1026_data { | 261 | struct adm1026_data { |
262 | struct i2c_client client; | 262 | struct i2c_client client; |
263 | struct class_device *class_dev; | 263 | struct device *hwmon_dev; |
264 | enum chips type; | 264 | enum chips type; |
265 | 265 | ||
266 | struct mutex update_lock; | 266 | struct mutex update_lock; |
@@ -1221,7 +1221,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
1221 | 1221 | ||
1222 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 1222 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1223 | { | 1223 | { |
1224 | struct adm1026_data *data = adm1026_update_device(dev); | 1224 | struct adm1026_data *data = dev_get_drvdata(dev); |
1225 | return sprintf(buf,"%d\n", data->vrm); | 1225 | return sprintf(buf,"%d\n", data->vrm); |
1226 | } | 1226 | } |
1227 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, | 1227 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, |
@@ -1676,9 +1676,9 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1676 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) | 1676 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) |
1677 | goto exitdetach; | 1677 | goto exitdetach; |
1678 | 1678 | ||
1679 | data->class_dev = hwmon_device_register(&new_client->dev); | 1679 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
1680 | if (IS_ERR(data->class_dev)) { | 1680 | if (IS_ERR(data->hwmon_dev)) { |
1681 | err = PTR_ERR(data->class_dev); | 1681 | err = PTR_ERR(data->hwmon_dev); |
1682 | goto exitremove; | 1682 | goto exitremove; |
1683 | } | 1683 | } |
1684 | 1684 | ||
@@ -1698,7 +1698,7 @@ exit: | |||
1698 | static int adm1026_detach_client(struct i2c_client *client) | 1698 | static int adm1026_detach_client(struct i2c_client *client) |
1699 | { | 1699 | { |
1700 | struct adm1026_data *data = i2c_get_clientdata(client); | 1700 | struct adm1026_data *data = i2c_get_clientdata(client); |
1701 | hwmon_device_unregister(data->class_dev); | 1701 | hwmon_device_unregister(data->hwmon_dev); |
1702 | sysfs_remove_group(&client->dev.kobj, &adm1026_group); | 1702 | sysfs_remove_group(&client->dev.kobj, &adm1026_group); |
1703 | i2c_detach_client(client); | 1703 | i2c_detach_client(client); |
1704 | kfree(data); | 1704 | kfree(data); |
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 73ce31b31511..0bc897dffa27 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c | |||
@@ -141,7 +141,7 @@ static struct i2c_driver adm1029_driver = { | |||
141 | 141 | ||
142 | struct adm1029_data { | 142 | struct adm1029_data { |
143 | struct i2c_client client; | 143 | struct i2c_client client; |
144 | struct class_device *class_dev; | 144 | struct device *hwmon_dev; |
145 | struct mutex update_lock; | 145 | struct mutex update_lock; |
146 | char valid; /* zero until following fields are valid */ | 146 | char valid; /* zero until following fields are valid */ |
147 | unsigned long last_updated; /* in jiffies */ | 147 | unsigned long last_updated; /* in jiffies */ |
@@ -391,9 +391,9 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind) | |||
391 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) | 391 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) |
392 | goto exit_detach; | 392 | goto exit_detach; |
393 | 393 | ||
394 | data->class_dev = hwmon_device_register(&client->dev); | 394 | data->hwmon_dev = hwmon_device_register(&client->dev); |
395 | if (IS_ERR(data->class_dev)) { | 395 | if (IS_ERR(data->hwmon_dev)) { |
396 | err = PTR_ERR(data->class_dev); | 396 | err = PTR_ERR(data->hwmon_dev); |
397 | goto exit_remove_files; | 397 | goto exit_remove_files; |
398 | } | 398 | } |
399 | 399 | ||
@@ -431,7 +431,7 @@ static int adm1029_detach_client(struct i2c_client *client) | |||
431 | struct adm1029_data *data = i2c_get_clientdata(client); | 431 | struct adm1029_data *data = i2c_get_clientdata(client); |
432 | int err; | 432 | int err; |
433 | 433 | ||
434 | hwmon_device_unregister(data->class_dev); | 434 | hwmon_device_unregister(data->hwmon_dev); |
435 | sysfs_remove_group(&client->dev.kobj, &adm1029_group); | 435 | sysfs_remove_group(&client->dev.kobj, &adm1029_group); |
436 | 436 | ||
437 | if ((err = i2c_detach_client(client))) | 437 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 122683fc91d0..37cfc101da5e 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -70,7 +70,7 @@ typedef u8 auto_chan_table_t[8][2]; | |||
70 | /* Each client has this additional data */ | 70 | /* Each client has this additional data */ |
71 | struct adm1031_data { | 71 | struct adm1031_data { |
72 | struct i2c_client client; | 72 | struct i2c_client client; |
73 | struct class_device *class_dev; | 73 | struct device *hwmon_dev; |
74 | struct mutex update_lock; | 74 | struct mutex update_lock; |
75 | int chip_type; | 75 | int chip_type; |
76 | char valid; /* !=0 if following fields are valid */ | 76 | char valid; /* !=0 if following fields are valid */ |
@@ -853,9 +853,9 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) | |||
853 | goto exit_remove; | 853 | goto exit_remove; |
854 | } | 854 | } |
855 | 855 | ||
856 | data->class_dev = hwmon_device_register(&new_client->dev); | 856 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
857 | if (IS_ERR(data->class_dev)) { | 857 | if (IS_ERR(data->hwmon_dev)) { |
858 | err = PTR_ERR(data->class_dev); | 858 | err = PTR_ERR(data->hwmon_dev); |
859 | goto exit_remove; | 859 | goto exit_remove; |
860 | } | 860 | } |
861 | 861 | ||
@@ -877,7 +877,7 @@ static int adm1031_detach_client(struct i2c_client *client) | |||
877 | struct adm1031_data *data = i2c_get_clientdata(client); | 877 | struct adm1031_data *data = i2c_get_clientdata(client); |
878 | int ret; | 878 | int ret; |
879 | 879 | ||
880 | hwmon_device_unregister(data->class_dev); | 880 | hwmon_device_unregister(data->hwmon_dev); |
881 | sysfs_remove_group(&client->dev.kobj, &adm1031_group); | 881 | sysfs_remove_group(&client->dev.kobj, &adm1031_group); |
882 | sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); | 882 | sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); |
883 | if ((ret = i2c_detach_client(client)) != 0) { | 883 | if ((ret = i2c_detach_client(client)) != 0) { |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index aad594adf0c7..c17d0b6b3283 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -150,7 +150,7 @@ static struct i2c_driver adm9240_driver = { | |||
150 | struct adm9240_data { | 150 | struct adm9240_data { |
151 | enum chips type; | 151 | enum chips type; |
152 | struct i2c_client client; | 152 | struct i2c_client client; |
153 | struct class_device *class_dev; | 153 | struct device *hwmon_dev; |
154 | struct mutex update_lock; | 154 | struct mutex update_lock; |
155 | char valid; | 155 | char valid; |
156 | unsigned long last_updated_measure; | 156 | unsigned long last_updated_measure; |
@@ -590,9 +590,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
590 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) | 590 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) |
591 | goto exit_detach; | 591 | goto exit_detach; |
592 | 592 | ||
593 | data->class_dev = hwmon_device_register(&new_client->dev); | 593 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
594 | if (IS_ERR(data->class_dev)) { | 594 | if (IS_ERR(data->hwmon_dev)) { |
595 | err = PTR_ERR(data->class_dev); | 595 | err = PTR_ERR(data->hwmon_dev); |
596 | goto exit_remove; | 596 | goto exit_remove; |
597 | } | 597 | } |
598 | 598 | ||
@@ -620,7 +620,7 @@ static int adm9240_detach_client(struct i2c_client *client) | |||
620 | struct adm9240_data *data = i2c_get_clientdata(client); | 620 | struct adm9240_data *data = i2c_get_clientdata(client); |
621 | int err; | 621 | int err; |
622 | 622 | ||
623 | hwmon_device_unregister(data->class_dev); | 623 | hwmon_device_unregister(data->hwmon_dev); |
624 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); | 624 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); |
625 | 625 | ||
626 | if ((err = i2c_detach_client(client))) | 626 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c new file mode 100644 index 000000000000..9810aaa0489d --- /dev/null +++ b/drivers/hwmon/adt7470.c | |||
@@ -0,0 +1,1050 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the Analog Devices ADT7470 | ||
3 | * Copyright (C) 2007 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/log2.h> | ||
31 | |||
32 | /* Addresses to scan */ | ||
33 | static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | ||
34 | |||
35 | /* Insmod parameters */ | ||
36 | I2C_CLIENT_INSMOD_1(adt7470); | ||
37 | |||
38 | /* ADT7470 registers */ | ||
39 | #define ADT7470_REG_BASE_ADDR 0x20 | ||
40 | #define ADT7470_REG_TEMP_BASE_ADDR 0x20 | ||
41 | #define ADT7470_REG_TEMP_MAX_ADDR 0x29 | ||
42 | #define ADT7470_REG_FAN_BASE_ADDR 0x2A | ||
43 | #define ADT7470_REG_FAN_MAX_ADDR 0x31 | ||
44 | #define ADT7470_REG_PWM_BASE_ADDR 0x32 | ||
45 | #define ADT7470_REG_PWM_MAX_ADDR 0x35 | ||
46 | #define ADT7470_REG_PWM_MAX_BASE_ADDR 0x38 | ||
47 | #define ADT7470_REG_PWM_MAX_MAX_ADDR 0x3B | ||
48 | #define ADT7470_REG_CFG 0x40 | ||
49 | #define ADT7470_FSPD_MASK 0x04 | ||
50 | #define ADT7470_REG_ALARM1 0x41 | ||
51 | #define ADT7470_REG_ALARM2 0x42 | ||
52 | #define ADT7470_REG_TEMP_LIMITS_BASE_ADDR 0x44 | ||
53 | #define ADT7470_REG_TEMP_LIMITS_MAX_ADDR 0x57 | ||
54 | #define ADT7470_REG_FAN_MIN_BASE_ADDR 0x58 | ||
55 | #define ADT7470_REG_FAN_MIN_MAX_ADDR 0x5F | ||
56 | #define ADT7470_REG_FAN_MAX_BASE_ADDR 0x60 | ||
57 | #define ADT7470_REG_FAN_MAX_MAX_ADDR 0x67 | ||
58 | #define ADT7470_REG_PWM_CFG_BASE_ADDR 0x68 | ||
59 | #define ADT7470_REG_PWM12_CFG 0x68 | ||
60 | #define ADT7470_PWM2_AUTO_MASK 0x40 | ||
61 | #define ADT7470_PWM1_AUTO_MASK 0x80 | ||
62 | #define ADT7470_REG_PWM34_CFG 0x69 | ||
63 | #define ADT7470_PWM3_AUTO_MASK 0x40 | ||
64 | #define ADT7470_PWM4_AUTO_MASK 0x80 | ||
65 | #define ADT7470_REG_PWM_MIN_BASE_ADDR 0x6A | ||
66 | #define ADT7470_REG_PWM_MIN_MAX_ADDR 0x6D | ||
67 | #define ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR 0x6E | ||
68 | #define ADT7470_REG_PWM_TEMP_MIN_MAX_ADDR 0x71 | ||
69 | #define ADT7470_REG_ACOUSTICS12 0x75 | ||
70 | #define ADT7470_REG_ACOUSTICS34 0x76 | ||
71 | #define ADT7470_REG_DEVICE 0x3D | ||
72 | #define ADT7470_REG_VENDOR 0x3E | ||
73 | #define ADT7470_REG_REVISION 0x3F | ||
74 | #define ADT7470_REG_ALARM1_MASK 0x72 | ||
75 | #define ADT7470_REG_ALARM2_MASK 0x73 | ||
76 | #define ADT7470_REG_PWM_AUTO_TEMP_BASE_ADDR 0x7C | ||
77 | #define ADT7470_REG_PWM_AUTO_TEMP_MAX_ADDR 0x7D | ||
78 | #define ADT7470_REG_MAX_ADDR 0x81 | ||
79 | |||
80 | #define ADT7470_TEMP_COUNT 10 | ||
81 | #define ADT7470_TEMP_REG(x) (ADT7470_REG_TEMP_BASE_ADDR + (x)) | ||
82 | #define ADT7470_TEMP_MIN_REG(x) (ADT7470_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2)) | ||
83 | #define ADT7470_TEMP_MAX_REG(x) (ADT7470_REG_TEMP_LIMITS_BASE_ADDR + \ | ||
84 | ((x) * 2) + 1) | ||
85 | |||
86 | #define ADT7470_FAN_COUNT 4 | ||
87 | #define ADT7470_REG_FAN(x) (ADT7470_REG_FAN_BASE_ADDR + ((x) * 2)) | ||
88 | #define ADT7470_REG_FAN_MIN(x) (ADT7470_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) | ||
89 | #define ADT7470_REG_FAN_MAX(x) (ADT7470_REG_FAN_MAX_BASE_ADDR + ((x) * 2)) | ||
90 | |||
91 | #define ADT7470_PWM_COUNT 4 | ||
92 | #define ADT7470_REG_PWM(x) (ADT7470_REG_PWM_BASE_ADDR + (x)) | ||
93 | #define ADT7470_REG_PWM_MAX(x) (ADT7470_REG_PWM_MAX_BASE_ADDR + (x)) | ||
94 | #define ADT7470_REG_PWM_MIN(x) (ADT7470_REG_PWM_MIN_BASE_ADDR + (x)) | ||
95 | #define ADT7470_REG_PWM_TMIN(x) (ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) | ||
96 | #define ADT7470_REG_PWM_CFG(x) (ADT7470_REG_PWM_CFG_BASE_ADDR + ((x) / 2)) | ||
97 | #define ADT7470_REG_PWM_AUTO_TEMP(x) (ADT7470_REG_PWM_AUTO_TEMP_BASE_ADDR + \ | ||
98 | ((x) / 2)) | ||
99 | |||
100 | #define ADT7470_VENDOR 0x41 | ||
101 | #define ADT7470_DEVICE 0x70 | ||
102 | /* datasheet only mentions a revision 2 */ | ||
103 | #define ADT7470_REVISION 0x02 | ||
104 | |||
105 | /* "all temps" according to hwmon sysfs interface spec */ | ||
106 | #define ADT7470_PWM_ALL_TEMPS 0x3FF | ||
107 | |||
108 | /* How often do we reread sensors values? (In jiffies) */ | ||
109 | #define SENSOR_REFRESH_INTERVAL (5 * HZ) | ||
110 | |||
111 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
112 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
113 | |||
114 | /* sleep 1s while gathering temperature data */ | ||
115 | #define TEMP_COLLECTION_TIME 1000 | ||
116 | |||
117 | #define power_of_2(x) (((x) & ((x) - 1)) == 0) | ||
118 | |||
119 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | ||
120 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | ||
121 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | ||
122 | #define FAN_PERIOD_INVALID 65535 | ||
123 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | ||
124 | |||
125 | struct adt7470_data { | ||
126 | struct i2c_client client; | ||
127 | struct device *hwmon_dev; | ||
128 | struct attribute_group attrs; | ||
129 | struct mutex lock; | ||
130 | char sensors_valid; | ||
131 | char limits_valid; | ||
132 | unsigned long sensors_last_updated; /* In jiffies */ | ||
133 | unsigned long limits_last_updated; /* In jiffies */ | ||
134 | |||
135 | s8 temp[ADT7470_TEMP_COUNT]; | ||
136 | s8 temp_min[ADT7470_TEMP_COUNT]; | ||
137 | s8 temp_max[ADT7470_TEMP_COUNT]; | ||
138 | u16 fan[ADT7470_FAN_COUNT]; | ||
139 | u16 fan_min[ADT7470_FAN_COUNT]; | ||
140 | u16 fan_max[ADT7470_FAN_COUNT]; | ||
141 | u16 alarms, alarms_mask; | ||
142 | u8 force_pwm_max; | ||
143 | u8 pwm[ADT7470_PWM_COUNT]; | ||
144 | u8 pwm_max[ADT7470_PWM_COUNT]; | ||
145 | u8 pwm_automatic[ADT7470_PWM_COUNT]; | ||
146 | u8 pwm_min[ADT7470_PWM_COUNT]; | ||
147 | s8 pwm_tmin[ADT7470_PWM_COUNT]; | ||
148 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; | ||
149 | }; | ||
150 | |||
151 | static int adt7470_attach_adapter(struct i2c_adapter *adapter); | ||
152 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind); | ||
153 | static int adt7470_detach_client(struct i2c_client *client); | ||
154 | |||
155 | static struct i2c_driver adt7470_driver = { | ||
156 | .driver = { | ||
157 | .name = "adt7470", | ||
158 | }, | ||
159 | .attach_adapter = adt7470_attach_adapter, | ||
160 | .detach_client = adt7470_detach_client, | ||
161 | }; | ||
162 | |||
163 | /* | ||
164 | * 16-bit registers on the ADT7470 are low-byte first. The data sheet says | ||
165 | * that the low byte must be read before the high byte. | ||
166 | */ | ||
167 | static inline int adt7470_read_word_data(struct i2c_client *client, u8 reg) | ||
168 | { | ||
169 | u16 foo; | ||
170 | foo = i2c_smbus_read_byte_data(client, reg); | ||
171 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); | ||
172 | return foo; | ||
173 | } | ||
174 | |||
175 | static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg, | ||
176 | u16 value) | ||
177 | { | ||
178 | return i2c_smbus_write_byte_data(client, reg, value & 0xFF) | ||
179 | && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); | ||
180 | } | ||
181 | |||
182 | static void adt7470_init_client(struct i2c_client *client) | ||
183 | { | ||
184 | int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
185 | |||
186 | if (reg < 0) { | ||
187 | dev_err(&client->dev, "cannot read configuration register\n"); | ||
188 | } else { | ||
189 | /* start monitoring (and do a self-test) */ | ||
190 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static struct adt7470_data *adt7470_update_device(struct device *dev) | ||
195 | { | ||
196 | struct i2c_client *client = to_i2c_client(dev); | ||
197 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
198 | unsigned long local_jiffies = jiffies; | ||
199 | u8 cfg; | ||
200 | int i; | ||
201 | |||
202 | mutex_lock(&data->lock); | ||
203 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
204 | SENSOR_REFRESH_INTERVAL) | ||
205 | && data->sensors_valid) | ||
206 | goto no_sensor_update; | ||
207 | |||
208 | /* start reading temperature sensors */ | ||
209 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
210 | cfg |= 0x80; | ||
211 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | ||
212 | |||
213 | /* | ||
214 | * Delay is 200ms * number of tmp05 sensors. Too bad | ||
215 | * there's no way to figure out how many are connected. | ||
216 | * For now, assume 1s will work. | ||
217 | */ | ||
218 | msleep(TEMP_COLLECTION_TIME); | ||
219 | |||
220 | /* done reading temperature sensors */ | ||
221 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
222 | cfg &= ~0x80; | ||
223 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | ||
224 | |||
225 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) | ||
226 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
227 | ADT7470_TEMP_REG(i)); | ||
228 | |||
229 | for (i = 0; i < ADT7470_FAN_COUNT; i++) | ||
230 | data->fan[i] = adt7470_read_word_data(client, | ||
231 | ADT7470_REG_FAN(i)); | ||
232 | |||
233 | for (i = 0; i < ADT7470_PWM_COUNT; i++) { | ||
234 | int reg; | ||
235 | int reg_mask; | ||
236 | |||
237 | data->pwm[i] = i2c_smbus_read_byte_data(client, | ||
238 | ADT7470_REG_PWM(i)); | ||
239 | |||
240 | if (i % 2) | ||
241 | reg_mask = ADT7470_PWM2_AUTO_MASK; | ||
242 | else | ||
243 | reg_mask = ADT7470_PWM1_AUTO_MASK; | ||
244 | |||
245 | reg = ADT7470_REG_PWM_CFG(i); | ||
246 | if (i2c_smbus_read_byte_data(client, reg) & reg_mask) | ||
247 | data->pwm_automatic[i] = 1; | ||
248 | else | ||
249 | data->pwm_automatic[i] = 0; | ||
250 | |||
251 | reg = ADT7470_REG_PWM_AUTO_TEMP(i); | ||
252 | cfg = i2c_smbus_read_byte_data(client, reg); | ||
253 | if (!(i % 2)) | ||
254 | data->pwm_auto_temp[i] = cfg >> 4; | ||
255 | else | ||
256 | data->pwm_auto_temp[i] = cfg & 0xF; | ||
257 | } | ||
258 | |||
259 | if (i2c_smbus_read_byte_data(client, ADT7470_REG_CFG) & | ||
260 | ADT7470_FSPD_MASK) | ||
261 | data->force_pwm_max = 1; | ||
262 | else | ||
263 | data->force_pwm_max = 0; | ||
264 | |||
265 | data->alarms = adt7470_read_word_data(client, ADT7470_REG_ALARM1); | ||
266 | data->alarms_mask = adt7470_read_word_data(client, | ||
267 | ADT7470_REG_ALARM1_MASK); | ||
268 | |||
269 | data->sensors_last_updated = local_jiffies; | ||
270 | data->sensors_valid = 1; | ||
271 | |||
272 | no_sensor_update: | ||
273 | if (time_before(local_jiffies, data->limits_last_updated + | ||
274 | LIMIT_REFRESH_INTERVAL) | ||
275 | && data->limits_valid) | ||
276 | goto out; | ||
277 | |||
278 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) { | ||
279 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | ||
280 | ADT7470_TEMP_MIN_REG(i)); | ||
281 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | ||
282 | ADT7470_TEMP_MAX_REG(i)); | ||
283 | } | ||
284 | |||
285 | for (i = 0; i < ADT7470_FAN_COUNT; i++) { | ||
286 | data->fan_min[i] = adt7470_read_word_data(client, | ||
287 | ADT7470_REG_FAN_MIN(i)); | ||
288 | data->fan_max[i] = adt7470_read_word_data(client, | ||
289 | ADT7470_REG_FAN_MAX(i)); | ||
290 | } | ||
291 | |||
292 | for (i = 0; i < ADT7470_PWM_COUNT; i++) { | ||
293 | data->pwm_max[i] = i2c_smbus_read_byte_data(client, | ||
294 | ADT7470_REG_PWM_MAX(i)); | ||
295 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, | ||
296 | ADT7470_REG_PWM_MIN(i)); | ||
297 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, | ||
298 | ADT7470_REG_PWM_TMIN(i)); | ||
299 | } | ||
300 | |||
301 | data->limits_last_updated = local_jiffies; | ||
302 | data->limits_valid = 1; | ||
303 | |||
304 | out: | ||
305 | mutex_unlock(&data->lock); | ||
306 | return data; | ||
307 | } | ||
308 | |||
309 | static ssize_t show_temp_min(struct device *dev, | ||
310 | struct device_attribute *devattr, | ||
311 | char *buf) | ||
312 | { | ||
313 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
314 | struct adt7470_data *data = adt7470_update_device(dev); | ||
315 | return sprintf(buf, "%d\n", 1000 * data->temp_min[attr->index]); | ||
316 | } | ||
317 | |||
318 | static ssize_t set_temp_min(struct device *dev, | ||
319 | struct device_attribute *devattr, | ||
320 | const char *buf, | ||
321 | size_t count) | ||
322 | { | ||
323 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
324 | struct i2c_client *client = to_i2c_client(dev); | ||
325 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
326 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
327 | |||
328 | mutex_lock(&data->lock); | ||
329 | data->temp_min[attr->index] = temp; | ||
330 | i2c_smbus_write_byte_data(client, ADT7470_TEMP_MIN_REG(attr->index), | ||
331 | temp); | ||
332 | mutex_unlock(&data->lock); | ||
333 | |||
334 | return count; | ||
335 | } | ||
336 | |||
337 | static ssize_t show_temp_max(struct device *dev, | ||
338 | struct device_attribute *devattr, | ||
339 | char *buf) | ||
340 | { | ||
341 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
342 | struct adt7470_data *data = adt7470_update_device(dev); | ||
343 | return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]); | ||
344 | } | ||
345 | |||
346 | static ssize_t set_temp_max(struct device *dev, | ||
347 | struct device_attribute *devattr, | ||
348 | const char *buf, | ||
349 | size_t count) | ||
350 | { | ||
351 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
352 | struct i2c_client *client = to_i2c_client(dev); | ||
353 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
354 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
355 | |||
356 | mutex_lock(&data->lock); | ||
357 | data->temp_max[attr->index] = temp; | ||
358 | i2c_smbus_write_byte_data(client, ADT7470_TEMP_MAX_REG(attr->index), | ||
359 | temp); | ||
360 | mutex_unlock(&data->lock); | ||
361 | |||
362 | return count; | ||
363 | } | ||
364 | |||
365 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
366 | char *buf) | ||
367 | { | ||
368 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
369 | struct adt7470_data *data = adt7470_update_device(dev); | ||
370 | return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]); | ||
371 | } | ||
372 | |||
373 | static ssize_t show_alarms(struct device *dev, | ||
374 | struct device_attribute *devattr, | ||
375 | char *buf) | ||
376 | { | ||
377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
378 | struct adt7470_data *data = adt7470_update_device(dev); | ||
379 | |||
380 | if (attr->index) | ||
381 | return sprintf(buf, "%x\n", data->alarms); | ||
382 | else | ||
383 | return sprintf(buf, "%x\n", data->alarms_mask); | ||
384 | } | ||
385 | |||
386 | static ssize_t show_fan_max(struct device *dev, | ||
387 | struct device_attribute *devattr, | ||
388 | char *buf) | ||
389 | { | ||
390 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
391 | struct adt7470_data *data = adt7470_update_device(dev); | ||
392 | |||
393 | if (FAN_DATA_VALID(data->fan_max[attr->index])) | ||
394 | return sprintf(buf, "%d\n", | ||
395 | FAN_PERIOD_TO_RPM(data->fan_max[attr->index])); | ||
396 | else | ||
397 | return sprintf(buf, "0\n"); | ||
398 | } | ||
399 | |||
400 | static ssize_t set_fan_max(struct device *dev, | ||
401 | struct device_attribute *devattr, | ||
402 | const char *buf, size_t count) | ||
403 | { | ||
404 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
405 | struct i2c_client *client = to_i2c_client(dev); | ||
406 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
407 | int temp = simple_strtol(buf, NULL, 10); | ||
408 | |||
409 | if (!temp) | ||
410 | return -EINVAL; | ||
411 | temp = FAN_RPM_TO_PERIOD(temp); | ||
412 | |||
413 | mutex_lock(&data->lock); | ||
414 | data->fan_max[attr->index] = temp; | ||
415 | adt7470_write_word_data(client, ADT7470_REG_FAN_MAX(attr->index), temp); | ||
416 | mutex_unlock(&data->lock); | ||
417 | |||
418 | return count; | ||
419 | } | ||
420 | |||
421 | static ssize_t show_fan_min(struct device *dev, | ||
422 | struct device_attribute *devattr, | ||
423 | char *buf) | ||
424 | { | ||
425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
426 | struct adt7470_data *data = adt7470_update_device(dev); | ||
427 | |||
428 | if (FAN_DATA_VALID(data->fan_min[attr->index])) | ||
429 | return sprintf(buf, "%d\n", | ||
430 | FAN_PERIOD_TO_RPM(data->fan_min[attr->index])); | ||
431 | else | ||
432 | return sprintf(buf, "0\n"); | ||
433 | } | ||
434 | |||
435 | static ssize_t set_fan_min(struct device *dev, | ||
436 | struct device_attribute *devattr, | ||
437 | const char *buf, size_t count) | ||
438 | { | ||
439 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
440 | struct i2c_client *client = to_i2c_client(dev); | ||
441 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
442 | int temp = simple_strtol(buf, NULL, 10); | ||
443 | |||
444 | if (!temp) | ||
445 | return -EINVAL; | ||
446 | temp = FAN_RPM_TO_PERIOD(temp); | ||
447 | |||
448 | mutex_lock(&data->lock); | ||
449 | data->fan_min[attr->index] = temp; | ||
450 | adt7470_write_word_data(client, ADT7470_REG_FAN_MIN(attr->index), temp); | ||
451 | mutex_unlock(&data->lock); | ||
452 | |||
453 | return count; | ||
454 | } | ||
455 | |||
456 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
457 | char *buf) | ||
458 | { | ||
459 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
460 | struct adt7470_data *data = adt7470_update_device(dev); | ||
461 | |||
462 | if (FAN_DATA_VALID(data->fan[attr->index])) | ||
463 | return sprintf(buf, "%d\n", | ||
464 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); | ||
465 | else | ||
466 | return sprintf(buf, "0\n"); | ||
467 | } | ||
468 | |||
469 | static ssize_t show_force_pwm_max(struct device *dev, | ||
470 | struct device_attribute *devattr, | ||
471 | char *buf) | ||
472 | { | ||
473 | struct adt7470_data *data = adt7470_update_device(dev); | ||
474 | return sprintf(buf, "%d\n", data->force_pwm_max); | ||
475 | } | ||
476 | |||
477 | static ssize_t set_force_pwm_max(struct device *dev, | ||
478 | struct device_attribute *devattr, | ||
479 | const char *buf, | ||
480 | size_t count) | ||
481 | { | ||
482 | struct i2c_client *client = to_i2c_client(dev); | ||
483 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
484 | int temp = simple_strtol(buf, NULL, 10); | ||
485 | u8 reg; | ||
486 | |||
487 | mutex_lock(&data->lock); | ||
488 | data->force_pwm_max = temp; | ||
489 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
490 | if (temp) | ||
491 | reg |= ADT7470_FSPD_MASK; | ||
492 | else | ||
493 | reg &= ~ADT7470_FSPD_MASK; | ||
494 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg); | ||
495 | mutex_unlock(&data->lock); | ||
496 | |||
497 | return count; | ||
498 | } | ||
499 | |||
500 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | ||
501 | char *buf) | ||
502 | { | ||
503 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
504 | struct adt7470_data *data = adt7470_update_device(dev); | ||
505 | return sprintf(buf, "%d\n", data->pwm[attr->index]); | ||
506 | } | ||
507 | |||
508 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | ||
509 | const char *buf, size_t count) | ||
510 | { | ||
511 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
512 | struct i2c_client *client = to_i2c_client(dev); | ||
513 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
514 | int temp = simple_strtol(buf, NULL, 10); | ||
515 | |||
516 | mutex_lock(&data->lock); | ||
517 | data->pwm[attr->index] = temp; | ||
518 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM(attr->index), temp); | ||
519 | mutex_unlock(&data->lock); | ||
520 | |||
521 | return count; | ||
522 | } | ||
523 | |||
524 | static ssize_t show_pwm_max(struct device *dev, | ||
525 | struct device_attribute *devattr, | ||
526 | char *buf) | ||
527 | { | ||
528 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
529 | struct adt7470_data *data = adt7470_update_device(dev); | ||
530 | return sprintf(buf, "%d\n", data->pwm_max[attr->index]); | ||
531 | } | ||
532 | |||
533 | static ssize_t set_pwm_max(struct device *dev, | ||
534 | struct device_attribute *devattr, | ||
535 | const char *buf, | ||
536 | size_t count) | ||
537 | { | ||
538 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
539 | struct i2c_client *client = to_i2c_client(dev); | ||
540 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
541 | int temp = simple_strtol(buf, NULL, 10); | ||
542 | |||
543 | mutex_lock(&data->lock); | ||
544 | data->pwm_max[attr->index] = temp; | ||
545 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_MAX(attr->index), | ||
546 | temp); | ||
547 | mutex_unlock(&data->lock); | ||
548 | |||
549 | return count; | ||
550 | } | ||
551 | |||
552 | static ssize_t show_pwm_min(struct device *dev, | ||
553 | struct device_attribute *devattr, | ||
554 | char *buf) | ||
555 | { | ||
556 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
557 | struct adt7470_data *data = adt7470_update_device(dev); | ||
558 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); | ||
559 | } | ||
560 | |||
561 | static ssize_t set_pwm_min(struct device *dev, | ||
562 | struct device_attribute *devattr, | ||
563 | const char *buf, | ||
564 | size_t count) | ||
565 | { | ||
566 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
567 | struct i2c_client *client = to_i2c_client(dev); | ||
568 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
569 | int temp = simple_strtol(buf, NULL, 10); | ||
570 | |||
571 | mutex_lock(&data->lock); | ||
572 | data->pwm_min[attr->index] = temp; | ||
573 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_MIN(attr->index), | ||
574 | temp); | ||
575 | mutex_unlock(&data->lock); | ||
576 | |||
577 | return count; | ||
578 | } | ||
579 | |||
580 | static ssize_t show_pwm_tmax(struct device *dev, | ||
581 | struct device_attribute *devattr, | ||
582 | char *buf) | ||
583 | { | ||
584 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
585 | struct adt7470_data *data = adt7470_update_device(dev); | ||
586 | /* the datasheet says that tmax = tmin + 20C */ | ||
587 | return sprintf(buf, "%d\n", 1000 * (20 + data->pwm_tmin[attr->index])); | ||
588 | } | ||
589 | |||
590 | static ssize_t show_pwm_tmin(struct device *dev, | ||
591 | struct device_attribute *devattr, | ||
592 | char *buf) | ||
593 | { | ||
594 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
595 | struct adt7470_data *data = adt7470_update_device(dev); | ||
596 | return sprintf(buf, "%d\n", 1000 * data->pwm_tmin[attr->index]); | ||
597 | } | ||
598 | |||
599 | static ssize_t set_pwm_tmin(struct device *dev, | ||
600 | struct device_attribute *devattr, | ||
601 | const char *buf, | ||
602 | size_t count) | ||
603 | { | ||
604 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
605 | struct i2c_client *client = to_i2c_client(dev); | ||
606 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
607 | int temp = simple_strtol(buf, NULL, 10) / 1000; | ||
608 | |||
609 | mutex_lock(&data->lock); | ||
610 | data->pwm_tmin[attr->index] = temp; | ||
611 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_TMIN(attr->index), | ||
612 | temp); | ||
613 | mutex_unlock(&data->lock); | ||
614 | |||
615 | return count; | ||
616 | } | ||
617 | |||
618 | static ssize_t show_pwm_auto(struct device *dev, | ||
619 | struct device_attribute *devattr, | ||
620 | char *buf) | ||
621 | { | ||
622 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
623 | struct adt7470_data *data = adt7470_update_device(dev); | ||
624 | return sprintf(buf, "%d\n", 1 + data->pwm_automatic[attr->index]); | ||
625 | } | ||
626 | |||
627 | static ssize_t set_pwm_auto(struct device *dev, | ||
628 | struct device_attribute *devattr, | ||
629 | const char *buf, | ||
630 | size_t count) | ||
631 | { | ||
632 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
633 | struct i2c_client *client = to_i2c_client(dev); | ||
634 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
635 | int temp = simple_strtol(buf, NULL, 10); | ||
636 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); | ||
637 | int pwm_auto_reg_mask; | ||
638 | u8 reg; | ||
639 | |||
640 | if (attr->index % 2) | ||
641 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; | ||
642 | else | ||
643 | pwm_auto_reg_mask = ADT7470_PWM1_AUTO_MASK; | ||
644 | |||
645 | if (temp != 2 && temp != 1) | ||
646 | return -EINVAL; | ||
647 | temp--; | ||
648 | |||
649 | mutex_lock(&data->lock); | ||
650 | data->pwm_automatic[attr->index] = temp; | ||
651 | reg = i2c_smbus_read_byte_data(client, pwm_auto_reg); | ||
652 | if (temp) | ||
653 | reg |= pwm_auto_reg_mask; | ||
654 | else | ||
655 | reg &= ~pwm_auto_reg_mask; | ||
656 | i2c_smbus_write_byte_data(client, pwm_auto_reg, reg); | ||
657 | mutex_unlock(&data->lock); | ||
658 | |||
659 | return count; | ||
660 | } | ||
661 | |||
662 | static ssize_t show_pwm_auto_temp(struct device *dev, | ||
663 | struct device_attribute *devattr, | ||
664 | char *buf) | ||
665 | { | ||
666 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
667 | struct adt7470_data *data = adt7470_update_device(dev); | ||
668 | u8 ctrl = data->pwm_auto_temp[attr->index]; | ||
669 | |||
670 | if (ctrl) | ||
671 | return sprintf(buf, "%d\n", 1 << (ctrl - 1)); | ||
672 | else | ||
673 | return sprintf(buf, "%d\n", ADT7470_PWM_ALL_TEMPS); | ||
674 | } | ||
675 | |||
676 | static int cvt_auto_temp(int input) | ||
677 | { | ||
678 | if (input == ADT7470_PWM_ALL_TEMPS) | ||
679 | return 0; | ||
680 | if (input < 1 || !power_of_2(input)) | ||
681 | return -EINVAL; | ||
682 | return ilog2(input) + 1; | ||
683 | } | ||
684 | |||
685 | static ssize_t set_pwm_auto_temp(struct device *dev, | ||
686 | struct device_attribute *devattr, | ||
687 | const char *buf, | ||
688 | size_t count) | ||
689 | { | ||
690 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
691 | struct i2c_client *client = to_i2c_client(dev); | ||
692 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
693 | int temp = cvt_auto_temp(simple_strtol(buf, NULL, 10)); | ||
694 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); | ||
695 | u8 reg; | ||
696 | |||
697 | if (temp < 0) | ||
698 | return temp; | ||
699 | |||
700 | mutex_lock(&data->lock); | ||
701 | data->pwm_automatic[attr->index] = temp; | ||
702 | reg = i2c_smbus_read_byte_data(client, pwm_auto_reg); | ||
703 | |||
704 | if (!(attr->index % 2)) { | ||
705 | reg &= 0xF; | ||
706 | reg |= (temp << 4) & 0xF0; | ||
707 | } else { | ||
708 | reg &= 0xF0; | ||
709 | reg |= temp & 0xF; | ||
710 | } | ||
711 | |||
712 | i2c_smbus_write_byte_data(client, pwm_auto_reg, reg); | ||
713 | mutex_unlock(&data->lock); | ||
714 | |||
715 | return count; | ||
716 | } | ||
717 | |||
718 | static SENSOR_DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL, 0); | ||
719 | static SENSOR_DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarms, NULL, 1); | ||
720 | |||
721 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
722 | set_temp_max, 0); | ||
723 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
724 | set_temp_max, 1); | ||
725 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
726 | set_temp_max, 2); | ||
727 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
728 | set_temp_max, 3); | ||
729 | static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
730 | set_temp_max, 4); | ||
731 | static SENSOR_DEVICE_ATTR(temp6_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
732 | set_temp_max, 5); | ||
733 | static SENSOR_DEVICE_ATTR(temp7_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
734 | set_temp_max, 6); | ||
735 | static SENSOR_DEVICE_ATTR(temp8_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
736 | set_temp_max, 7); | ||
737 | static SENSOR_DEVICE_ATTR(temp9_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
738 | set_temp_max, 8); | ||
739 | static SENSOR_DEVICE_ATTR(temp10_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
740 | set_temp_max, 9); | ||
741 | |||
742 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
743 | set_temp_min, 0); | ||
744 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
745 | set_temp_min, 1); | ||
746 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
747 | set_temp_min, 2); | ||
748 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
749 | set_temp_min, 3); | ||
750 | static SENSOR_DEVICE_ATTR(temp5_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
751 | set_temp_min, 4); | ||
752 | static SENSOR_DEVICE_ATTR(temp6_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
753 | set_temp_min, 5); | ||
754 | static SENSOR_DEVICE_ATTR(temp7_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
755 | set_temp_min, 6); | ||
756 | static SENSOR_DEVICE_ATTR(temp8_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
757 | set_temp_min, 7); | ||
758 | static SENSOR_DEVICE_ATTR(temp9_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
759 | set_temp_min, 8); | ||
760 | static SENSOR_DEVICE_ATTR(temp10_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
761 | set_temp_min, 9); | ||
762 | |||
763 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
764 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
765 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
766 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
767 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); | ||
768 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5); | ||
769 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6); | ||
770 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7); | ||
771 | static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_temp, NULL, 8); | ||
772 | static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_temp, NULL, 9); | ||
773 | |||
774 | static SENSOR_DEVICE_ATTR(fan1_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
775 | set_fan_max, 0); | ||
776 | static SENSOR_DEVICE_ATTR(fan2_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
777 | set_fan_max, 1); | ||
778 | static SENSOR_DEVICE_ATTR(fan3_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
779 | set_fan_max, 2); | ||
780 | static SENSOR_DEVICE_ATTR(fan4_max, S_IWUSR | S_IRUGO, show_fan_max, | ||
781 | set_fan_max, 3); | ||
782 | |||
783 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
784 | set_fan_min, 0); | ||
785 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
786 | set_fan_min, 1); | ||
787 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
788 | set_fan_min, 2); | ||
789 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
790 | set_fan_min, 3); | ||
791 | |||
792 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
793 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
794 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | ||
795 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | ||
796 | |||
797 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, | ||
798 | show_force_pwm_max, set_force_pwm_max, 0); | ||
799 | |||
800 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); | ||
801 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | ||
802 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | ||
803 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | ||
804 | |||
805 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
806 | show_pwm_min, set_pwm_min, 0); | ||
807 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
808 | show_pwm_min, set_pwm_min, 1); | ||
809 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
810 | show_pwm_min, set_pwm_min, 2); | ||
811 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
812 | show_pwm_min, set_pwm_min, 3); | ||
813 | |||
814 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
815 | show_pwm_max, set_pwm_max, 0); | ||
816 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
817 | show_pwm_max, set_pwm_max, 1); | ||
818 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
819 | show_pwm_max, set_pwm_max, 2); | ||
820 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
821 | show_pwm_max, set_pwm_max, 3); | ||
822 | |||
823 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
824 | show_pwm_tmin, set_pwm_tmin, 0); | ||
825 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
826 | show_pwm_tmin, set_pwm_tmin, 1); | ||
827 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
828 | show_pwm_tmin, set_pwm_tmin, 2); | ||
829 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
830 | show_pwm_tmin, set_pwm_tmin, 3); | ||
831 | |||
832 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
833 | NULL, 0); | ||
834 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
835 | NULL, 1); | ||
836 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
837 | NULL, 2); | ||
838 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_temp, S_IRUGO, show_pwm_tmax, | ||
839 | NULL, 3); | ||
840 | |||
841 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
842 | set_pwm_auto, 0); | ||
843 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
844 | set_pwm_auto, 1); | ||
845 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
846 | set_pwm_auto, 2); | ||
847 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
848 | set_pwm_auto, 3); | ||
849 | |||
850 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
851 | show_pwm_auto_temp, set_pwm_auto_temp, 0); | ||
852 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
853 | show_pwm_auto_temp, set_pwm_auto_temp, 1); | ||
854 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
855 | show_pwm_auto_temp, set_pwm_auto_temp, 2); | ||
856 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
857 | show_pwm_auto_temp, set_pwm_auto_temp, 3); | ||
858 | |||
859 | static struct attribute *adt7470_attr[] = | ||
860 | { | ||
861 | &sensor_dev_attr_alarms.dev_attr.attr, | ||
862 | &sensor_dev_attr_alarm_mask.dev_attr.attr, | ||
863 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
864 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
865 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
866 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
867 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
868 | &sensor_dev_attr_temp6_max.dev_attr.attr, | ||
869 | &sensor_dev_attr_temp7_max.dev_attr.attr, | ||
870 | &sensor_dev_attr_temp8_max.dev_attr.attr, | ||
871 | &sensor_dev_attr_temp9_max.dev_attr.attr, | ||
872 | &sensor_dev_attr_temp10_max.dev_attr.attr, | ||
873 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
874 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
875 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
876 | &sensor_dev_attr_temp4_min.dev_attr.attr, | ||
877 | &sensor_dev_attr_temp5_min.dev_attr.attr, | ||
878 | &sensor_dev_attr_temp6_min.dev_attr.attr, | ||
879 | &sensor_dev_attr_temp7_min.dev_attr.attr, | ||
880 | &sensor_dev_attr_temp8_min.dev_attr.attr, | ||
881 | &sensor_dev_attr_temp9_min.dev_attr.attr, | ||
882 | &sensor_dev_attr_temp10_min.dev_attr.attr, | ||
883 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
884 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
885 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
886 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
887 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
888 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
889 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
890 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
891 | &sensor_dev_attr_temp9_input.dev_attr.attr, | ||
892 | &sensor_dev_attr_temp10_input.dev_attr.attr, | ||
893 | &sensor_dev_attr_fan1_max.dev_attr.attr, | ||
894 | &sensor_dev_attr_fan2_max.dev_attr.attr, | ||
895 | &sensor_dev_attr_fan3_max.dev_attr.attr, | ||
896 | &sensor_dev_attr_fan4_max.dev_attr.attr, | ||
897 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
898 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
899 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
900 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
901 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
902 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
903 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
904 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
905 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | ||
906 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
907 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
908 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
909 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
910 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
911 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
912 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
913 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, | ||
914 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
915 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | ||
916 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | ||
917 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, | ||
918 | &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, | ||
919 | &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr, | ||
920 | &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr, | ||
921 | &sensor_dev_attr_pwm4_auto_point1_temp.dev_attr.attr, | ||
922 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | ||
923 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, | ||
924 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, | ||
925 | &sensor_dev_attr_pwm4_auto_point2_temp.dev_attr.attr, | ||
926 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
927 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
928 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
929 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
930 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
931 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | ||
932 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | ||
933 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | ||
934 | NULL | ||
935 | }; | ||
936 | |||
937 | static int adt7470_attach_adapter(struct i2c_adapter *adapter) | ||
938 | { | ||
939 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
940 | return 0; | ||
941 | return i2c_probe(adapter, &addr_data, adt7470_detect); | ||
942 | } | ||
943 | |||
944 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) | ||
945 | { | ||
946 | struct i2c_client *client; | ||
947 | struct adt7470_data *data; | ||
948 | int err = 0; | ||
949 | |||
950 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
951 | goto exit; | ||
952 | |||
953 | if (!(data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL))) { | ||
954 | err = -ENOMEM; | ||
955 | goto exit; | ||
956 | } | ||
957 | |||
958 | client = &data->client; | ||
959 | client->addr = address; | ||
960 | client->adapter = adapter; | ||
961 | client->driver = &adt7470_driver; | ||
962 | |||
963 | i2c_set_clientdata(client, data); | ||
964 | |||
965 | mutex_init(&data->lock); | ||
966 | |||
967 | if (kind <= 0) { | ||
968 | int vendor, device, revision; | ||
969 | |||
970 | vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR); | ||
971 | if (vendor != ADT7470_VENDOR) { | ||
972 | err = -ENODEV; | ||
973 | goto exit_free; | ||
974 | } | ||
975 | |||
976 | device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE); | ||
977 | if (device != ADT7470_DEVICE) { | ||
978 | err = -ENODEV; | ||
979 | goto exit_free; | ||
980 | } | ||
981 | |||
982 | revision = i2c_smbus_read_byte_data(client, | ||
983 | ADT7470_REG_REVISION); | ||
984 | if (revision != ADT7470_REVISION) { | ||
985 | err = -ENODEV; | ||
986 | goto exit_free; | ||
987 | } | ||
988 | } else | ||
989 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
990 | |||
991 | strlcpy(client->name, "adt7470", I2C_NAME_SIZE); | ||
992 | |||
993 | if ((err = i2c_attach_client(client))) | ||
994 | goto exit_free; | ||
995 | |||
996 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
997 | |||
998 | /* Initialize the ADT7470 chip */ | ||
999 | adt7470_init_client(client); | ||
1000 | |||
1001 | /* Register sysfs hooks */ | ||
1002 | data->attrs.attrs = adt7470_attr; | ||
1003 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) | ||
1004 | goto exit_detach; | ||
1005 | |||
1006 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
1007 | if (IS_ERR(data->hwmon_dev)) { | ||
1008 | err = PTR_ERR(data->hwmon_dev); | ||
1009 | goto exit_remove; | ||
1010 | } | ||
1011 | |||
1012 | return 0; | ||
1013 | |||
1014 | exit_remove: | ||
1015 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1016 | exit_detach: | ||
1017 | i2c_detach_client(client); | ||
1018 | exit_free: | ||
1019 | kfree(data); | ||
1020 | exit: | ||
1021 | return err; | ||
1022 | } | ||
1023 | |||
1024 | static int adt7470_detach_client(struct i2c_client *client) | ||
1025 | { | ||
1026 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
1027 | |||
1028 | hwmon_device_unregister(data->hwmon_dev); | ||
1029 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1030 | i2c_detach_client(client); | ||
1031 | kfree(data); | ||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static int __init adt7470_init(void) | ||
1036 | { | ||
1037 | return i2c_add_driver(&adt7470_driver); | ||
1038 | } | ||
1039 | |||
1040 | static void __exit adt7470_exit(void) | ||
1041 | { | ||
1042 | i2c_del_driver(&adt7470_driver); | ||
1043 | } | ||
1044 | |||
1045 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1046 | MODULE_DESCRIPTION("ADT7470 driver"); | ||
1047 | MODULE_LICENSE("GPL"); | ||
1048 | |||
1049 | module_init(adt7470_init); | ||
1050 | module_exit(adt7470_exit); | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 56213b7f8188..f37fd7ebf65a 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -127,7 +127,7 @@ static s16 rest_x; | |||
127 | static s16 rest_y; | 127 | static s16 rest_y; |
128 | static struct timer_list applesmc_timer; | 128 | static struct timer_list applesmc_timer; |
129 | static struct input_dev *applesmc_idev; | 129 | static struct input_dev *applesmc_idev; |
130 | static struct class_device *hwmon_class_dev; | 130 | static struct device *hwmon_dev; |
131 | 131 | ||
132 | /* Indicates whether this computer has an accelerometer. */ | 132 | /* Indicates whether this computer has an accelerometer. */ |
133 | static unsigned int applesmc_accelerometer; | 133 | static unsigned int applesmc_accelerometer; |
@@ -1287,9 +1287,9 @@ static int __init applesmc_init(void) | |||
1287 | goto out_light_wq; | 1287 | goto out_light_wq; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | hwmon_class_dev = hwmon_device_register(&pdev->dev); | 1290 | hwmon_dev = hwmon_device_register(&pdev->dev); |
1291 | if (IS_ERR(hwmon_class_dev)) { | 1291 | if (IS_ERR(hwmon_dev)) { |
1292 | ret = PTR_ERR(hwmon_class_dev); | 1292 | ret = PTR_ERR(hwmon_dev); |
1293 | goto out_light_ledclass; | 1293 | goto out_light_ledclass; |
1294 | } | 1294 | } |
1295 | 1295 | ||
@@ -1331,7 +1331,7 @@ out: | |||
1331 | 1331 | ||
1332 | static void __exit applesmc_exit(void) | 1332 | static void __exit applesmc_exit(void) |
1333 | { | 1333 | { |
1334 | hwmon_device_unregister(hwmon_class_dev); | 1334 | hwmon_device_unregister(hwmon_dev); |
1335 | if (applesmc_light) { | 1335 | if (applesmc_light) { |
1336 | led_classdev_unregister(&applesmc_backlight); | 1336 | led_classdev_unregister(&applesmc_backlight); |
1337 | destroy_workqueue(applesmc_led_wq); | 1337 | destroy_workqueue(applesmc_led_wq); |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 57b1c7b7ac3f..9460dba4cf74 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -143,7 +143,7 @@ static int FAN_FROM_REG(u8 val, int div) | |||
143 | 143 | ||
144 | /* TEMP: 0.001C/bit (-128C to +127C) | 144 | /* TEMP: 0.001C/bit (-128C to +127C) |
145 | REG: 1C/bit, two's complement */ | 145 | REG: 1C/bit, two's complement */ |
146 | static u8 TEMP_TO_REG(int temp) | 146 | static u8 TEMP_TO_REG(long temp) |
147 | { | 147 | { |
148 | int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); | 148 | int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); |
149 | ntemp += (ntemp<0 ? -500 : 500); | 149 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -182,7 +182,7 @@ static u8 DIV_TO_REG(long val) | |||
182 | dynamically allocated, at the same time the client itself is allocated. */ | 182 | dynamically allocated, at the same time the client itself is allocated. */ |
183 | struct asb100_data { | 183 | struct asb100_data { |
184 | struct i2c_client client; | 184 | struct i2c_client client; |
185 | struct class_device *class_dev; | 185 | struct device *hwmon_dev; |
186 | struct mutex lock; | 186 | struct mutex lock; |
187 | enum chips type; | 187 | enum chips type; |
188 | 188 | ||
@@ -448,7 +448,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \ | |||
448 | { \ | 448 | { \ |
449 | struct i2c_client *client = to_i2c_client(dev); \ | 449 | struct i2c_client *client = to_i2c_client(dev); \ |
450 | struct asb100_data *data = i2c_get_clientdata(client); \ | 450 | struct asb100_data *data = i2c_get_clientdata(client); \ |
451 | unsigned long val = simple_strtoul(buf, NULL, 10); \ | 451 | long val = simple_strtol(buf, NULL, 10); \ |
452 | \ | 452 | \ |
453 | mutex_lock(&data->update_lock); \ | 453 | mutex_lock(&data->update_lock); \ |
454 | switch (nr) { \ | 454 | switch (nr) { \ |
@@ -514,7 +514,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
514 | /* VRM */ | 514 | /* VRM */ |
515 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 515 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
516 | { | 516 | { |
517 | struct asb100_data *data = asb100_update_device(dev); | 517 | struct asb100_data *data = dev_get_drvdata(dev); |
518 | return sprintf(buf, "%d\n", data->vrm); | 518 | return sprintf(buf, "%d\n", data->vrm); |
519 | } | 519 | } |
520 | 520 | ||
@@ -844,9 +844,9 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) | |||
844 | if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group))) | 844 | if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group))) |
845 | goto ERROR3; | 845 | goto ERROR3; |
846 | 846 | ||
847 | data->class_dev = hwmon_device_register(&new_client->dev); | 847 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
848 | if (IS_ERR(data->class_dev)) { | 848 | if (IS_ERR(data->hwmon_dev)) { |
849 | err = PTR_ERR(data->class_dev); | 849 | err = PTR_ERR(data->hwmon_dev); |
850 | goto ERROR4; | 850 | goto ERROR4; |
851 | } | 851 | } |
852 | 852 | ||
@@ -874,7 +874,7 @@ static int asb100_detach_client(struct i2c_client *client) | |||
874 | 874 | ||
875 | /* main client */ | 875 | /* main client */ |
876 | if (data) { | 876 | if (data) { |
877 | hwmon_device_unregister(data->class_dev); | 877 | hwmon_device_unregister(data->hwmon_dev); |
878 | sysfs_remove_group(&client->dev.kobj, &asb100_group); | 878 | sysfs_remove_group(&client->dev.kobj, &asb100_group); |
879 | } | 879 | } |
880 | 880 | ||
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 0ccdd0750c44..cce3350e539e 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -61,7 +61,7 @@ static struct i2c_driver atxp1_driver = { | |||
61 | 61 | ||
62 | struct atxp1_data { | 62 | struct atxp1_data { |
63 | struct i2c_client client; | 63 | struct i2c_client client; |
64 | struct class_device *class_dev; | 64 | struct device *hwmon_dev; |
65 | struct mutex update_lock; | 65 | struct mutex update_lock; |
66 | unsigned long last_updated; | 66 | unsigned long last_updated; |
67 | u8 valid; | 67 | u8 valid; |
@@ -335,9 +335,9 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
335 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) | 335 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) |
336 | goto exit_detach; | 336 | goto exit_detach; |
337 | 337 | ||
338 | data->class_dev = hwmon_device_register(&new_client->dev); | 338 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
339 | if (IS_ERR(data->class_dev)) { | 339 | if (IS_ERR(data->hwmon_dev)) { |
340 | err = PTR_ERR(data->class_dev); | 340 | err = PTR_ERR(data->hwmon_dev); |
341 | goto exit_remove_files; | 341 | goto exit_remove_files; |
342 | } | 342 | } |
343 | 343 | ||
@@ -361,7 +361,7 @@ static int atxp1_detach_client(struct i2c_client * client) | |||
361 | struct atxp1_data * data = i2c_get_clientdata(client); | 361 | struct atxp1_data * data = i2c_get_clientdata(client); |
362 | int err; | 362 | int err; |
363 | 363 | ||
364 | hwmon_device_unregister(data->class_dev); | 364 | hwmon_device_unregister(data->hwmon_dev); |
365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); | 365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); |
366 | 366 | ||
367 | err = i2c_detach_client(client); | 367 | err = i2c_detach_client(client); |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 7c1795225b06..6f66551d9e51 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -47,7 +47,7 @@ typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; | |||
47 | static struct coretemp_data *coretemp_update_device(struct device *dev); | 47 | static struct coretemp_data *coretemp_update_device(struct device *dev); |
48 | 48 | ||
49 | struct coretemp_data { | 49 | struct coretemp_data { |
50 | struct class_device *class_dev; | 50 | struct device *hwmon_dev; |
51 | struct mutex update_lock; | 51 | struct mutex update_lock; |
52 | const char *name; | 52 | const char *name; |
53 | u32 id; | 53 | u32 id; |
@@ -58,8 +58,6 @@ struct coretemp_data { | |||
58 | u8 alarm; | 58 | u8 alarm; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct coretemp_data *coretemp_update_device(struct device *dev); | ||
62 | |||
63 | /* | 61 | /* |
64 | * Sysfs stuff | 62 | * Sysfs stuff |
65 | */ | 63 | */ |
@@ -228,9 +226,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) | |||
228 | if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) | 226 | if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) |
229 | goto exit_free; | 227 | goto exit_free; |
230 | 228 | ||
231 | data->class_dev = hwmon_device_register(&pdev->dev); | 229 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
232 | if (IS_ERR(data->class_dev)) { | 230 | if (IS_ERR(data->hwmon_dev)) { |
233 | err = PTR_ERR(data->class_dev); | 231 | err = PTR_ERR(data->hwmon_dev); |
234 | dev_err(&pdev->dev, "Class registration failed (%d)\n", | 232 | dev_err(&pdev->dev, "Class registration failed (%d)\n", |
235 | err); | 233 | err); |
236 | goto exit_class; | 234 | goto exit_class; |
@@ -250,7 +248,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev) | |||
250 | { | 248 | { |
251 | struct coretemp_data *data = platform_get_drvdata(pdev); | 249 | struct coretemp_data *data = platform_get_drvdata(pdev); |
252 | 250 | ||
253 | hwmon_device_unregister(data->class_dev); | 251 | hwmon_device_unregister(data->hwmon_dev); |
254 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); | 252 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); |
255 | platform_set_drvdata(pdev, NULL); | 253 | platform_set_drvdata(pdev, NULL); |
256 | kfree(data); | 254 | kfree(data); |
@@ -350,7 +348,7 @@ static int coretemp_cpu_callback(struct notifier_block *nfb, | |||
350 | return NOTIFY_OK; | 348 | return NOTIFY_OK; |
351 | } | 349 | } |
352 | 350 | ||
353 | static struct notifier_block __cpuinitdata coretemp_cpu_notifier = { | 351 | static struct notifier_block coretemp_cpu_notifier = { |
354 | .notifier_call = coretemp_cpu_callback, | 352 | .notifier_call = coretemp_cpu_callback, |
355 | }; | 353 | }; |
356 | #endif /* !CONFIG_HOTPLUG_CPU */ | 354 | #endif /* !CONFIG_HOTPLUG_CPU */ |
@@ -371,9 +369,10 @@ static int __init coretemp_init(void) | |||
371 | for_each_online_cpu(i) { | 369 | for_each_online_cpu(i) { |
372 | struct cpuinfo_x86 *c = &(cpu_data)[i]; | 370 | struct cpuinfo_x86 *c = &(cpu_data)[i]; |
373 | 371 | ||
374 | /* check if family 6, models e, f */ | 372 | /* check if family 6, models e, f, 16 */ |
375 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || | 373 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || |
376 | !((c->x86_model == 0xe) || (c->x86_model == 0xf))) { | 374 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || |
375 | (c->x86_model == 0x16))) { | ||
377 | 376 | ||
378 | /* supported CPU not found, but report the unknown | 377 | /* supported CPU not found, but report the unknown |
379 | family 6 CPU */ | 378 | family 6 CPU */ |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index e9cbc727664d..a878c98e252e 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * dme1737.c - driver for the SMSC DME1737 and Asus A8000 Super-I/O chips | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, and SMSC SCH311x |
3 | * integrated hardware monitoring features. | 3 | * Super-I/O chips integrated hardware monitoring features. |
4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> | 4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> |
5 | * | 5 | * |
6 | * This driver is based on the LM85 driver. The hardware monitoring | 6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
7 | * capabilities of the DME1737 are very similar to the LM85 with some | 7 | * the chip registers if a DME1737 (or A8000) is found and the ISA bus if a |
8 | * additional features. Even though the DME1737 is a Super-I/O chip, the | 8 | * SCH311x chip is found. Both types of chips have very similar hardware |
9 | * hardware monitoring registers are only accessible via SMBus. | 9 | * monitoring capabilities but differ in the way they can be accessed. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 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 | 12 | * it under the terms of the GNU General Public License as published by |
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/jiffies.h> | 29 | #include <linux/jiffies.h> |
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include <linux/platform_device.h> | ||
31 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
32 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
33 | #include <linux/hwmon-vid.h> | 34 | #include <linux/hwmon-vid.h> |
@@ -35,6 +36,9 @@ | |||
35 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | 38 | ||
39 | /* ISA device, if found */ | ||
40 | static struct platform_device *pdev; | ||
41 | |||
38 | /* Module load parameters */ | 42 | /* Module load parameters */ |
39 | static int force_start; | 43 | static int force_start; |
40 | module_param(force_start, bool, 0); | 44 | module_param(force_start, bool, 0); |
@@ -133,6 +137,7 @@ static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6}; | |||
133 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | 137 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; |
134 | 138 | ||
135 | /* Miscellaneous registers */ | 139 | /* Miscellaneous registers */ |
140 | #define DME1737_REG_DEVICE 0x3d | ||
136 | #define DME1737_REG_COMPANY 0x3e | 141 | #define DME1737_REG_COMPANY 0x3e |
137 | #define DME1737_REG_VERSTEP 0x3f | 142 | #define DME1737_REG_VERSTEP 0x3f |
138 | #define DME1737_REG_CONFIG 0x40 | 143 | #define DME1737_REG_CONFIG 0x40 |
@@ -148,14 +153,20 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
148 | #define DME1737_COMPANY_SMSC 0x5c | 153 | #define DME1737_COMPANY_SMSC 0x5c |
149 | #define DME1737_VERSTEP 0x88 | 154 | #define DME1737_VERSTEP 0x88 |
150 | #define DME1737_VERSTEP_MASK 0xf8 | 155 | #define DME1737_VERSTEP_MASK 0xf8 |
156 | #define SCH311X_DEVICE 0x8c | ||
157 | |||
158 | /* Length of ISA address segment */ | ||
159 | #define DME1737_EXTENT 2 | ||
151 | 160 | ||
152 | /* --------------------------------------------------------------------- | 161 | /* --------------------------------------------------------------------- |
153 | * Data structures and manipulation thereof | 162 | * Data structures and manipulation thereof |
154 | * --------------------------------------------------------------------- */ | 163 | * --------------------------------------------------------------------- */ |
155 | 164 | ||
165 | /* For ISA chips, we abuse the i2c_client addr and name fields. We also use | ||
166 | the driver field to differentiate between I2C and ISA chips. */ | ||
156 | struct dme1737_data { | 167 | struct dme1737_data { |
157 | struct i2c_client client; | 168 | struct i2c_client client; |
158 | struct class_device *class_dev; | 169 | struct device *hwmon_dev; |
159 | 170 | ||
160 | struct mutex update_lock; | 171 | struct mutex update_lock; |
161 | int valid; /* !=0 if following fields are valid */ | 172 | int valid; /* !=0 if following fields are valid */ |
@@ -465,27 +476,48 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg) | |||
465 | 476 | ||
466 | /* --------------------------------------------------------------------- | 477 | /* --------------------------------------------------------------------- |
467 | * Device I/O access | 478 | * Device I/O access |
479 | * | ||
480 | * ISA access is performed through an index/data register pair and needs to | ||
481 | * be protected by a mutex during runtime (not required for initialization). | ||
482 | * We use data->update_lock for this and need to ensure that we acquire it | ||
483 | * before calling dme1737_read or dme1737_write. | ||
468 | * --------------------------------------------------------------------- */ | 484 | * --------------------------------------------------------------------- */ |
469 | 485 | ||
470 | static u8 dme1737_read(struct i2c_client *client, u8 reg) | 486 | static u8 dme1737_read(struct i2c_client *client, u8 reg) |
471 | { | 487 | { |
472 | s32 val = i2c_smbus_read_byte_data(client, reg); | 488 | s32 val; |
489 | |||
490 | if (client->driver) { /* I2C device */ | ||
491 | val = i2c_smbus_read_byte_data(client, reg); | ||
473 | 492 | ||
474 | if (val < 0) { | 493 | if (val < 0) { |
475 | dev_warn(&client->dev, "Read from register 0x%02x failed! " | 494 | dev_warn(&client->dev, "Read from register " |
476 | "Please report to the driver maintainer.\n", reg); | 495 | "0x%02x failed! Please report to the driver " |
496 | "maintainer.\n", reg); | ||
497 | } | ||
498 | } else { /* ISA device */ | ||
499 | outb(reg, client->addr); | ||
500 | val = inb(client->addr + 1); | ||
477 | } | 501 | } |
478 | 502 | ||
479 | return val; | 503 | return val; |
480 | } | 504 | } |
481 | 505 | ||
482 | static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 value) | 506 | static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) |
483 | { | 507 | { |
484 | s32 res = i2c_smbus_write_byte_data(client, reg, value); | 508 | s32 res = 0; |
509 | |||
510 | if (client->driver) { /* I2C device */ | ||
511 | res = i2c_smbus_write_byte_data(client, reg, val); | ||
485 | 512 | ||
486 | if (res < 0) { | 513 | if (res < 0) { |
487 | dev_warn(&client->dev, "Write to register 0x%02x failed! " | 514 | dev_warn(&client->dev, "Write to register " |
488 | "Please report to the driver maintainer.\n", reg); | 515 | "0x%02x failed! Please report to the driver " |
516 | "maintainer.\n", reg); | ||
517 | } | ||
518 | } else { /* ISA device */ | ||
519 | outb(reg, client->addr); | ||
520 | outb(val, client->addr + 1); | ||
489 | } | 521 | } |
490 | 522 | ||
491 | return res; | 523 | return res; |
@@ -493,8 +525,8 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 value) | |||
493 | 525 | ||
494 | static struct dme1737_data *dme1737_update_device(struct device *dev) | 526 | static struct dme1737_data *dme1737_update_device(struct device *dev) |
495 | { | 527 | { |
496 | struct i2c_client *client = to_i2c_client(dev); | 528 | struct dme1737_data *data = dev_get_drvdata(dev); |
497 | struct dme1737_data *data = i2c_get_clientdata(client); | 529 | struct i2c_client *client = &data->client; |
498 | int ix; | 530 | int ix; |
499 | u8 lsb[5]; | 531 | u8 lsb[5]; |
500 | 532 | ||
@@ -630,6 +662,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
630 | DME1737_REG_ALARM3) << 16; | 662 | DME1737_REG_ALARM3) << 16; |
631 | } | 663 | } |
632 | 664 | ||
665 | /* The ISA chips require explicit clearing of alarm bits. | ||
666 | * Don't worry, an alarm will come back if the condition | ||
667 | * that causes it still exists */ | ||
668 | if (!client->driver) { | ||
669 | if (data->alarms & 0xff0000) { | ||
670 | dme1737_write(client, DME1737_REG_ALARM3, | ||
671 | 0xff); | ||
672 | } | ||
673 | if (data->alarms & 0xff00) { | ||
674 | dme1737_write(client, DME1737_REG_ALARM2, | ||
675 | 0xff); | ||
676 | } | ||
677 | if (data->alarms & 0xff) { | ||
678 | dme1737_write(client, DME1737_REG_ALARM1, | ||
679 | 0xff); | ||
680 | } | ||
681 | } | ||
682 | |||
633 | data->last_update = jiffies; | 683 | data->last_update = jiffies; |
634 | data->valid = 1; | 684 | data->valid = 1; |
635 | } | 685 | } |
@@ -674,7 +724,7 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, | |||
674 | break; | 724 | break; |
675 | default: | 725 | default: |
676 | res = 0; | 726 | res = 0; |
677 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 727 | dev_dbg(dev, "Unknown function %d.\n", fn); |
678 | } | 728 | } |
679 | 729 | ||
680 | return sprintf(buf, "%d\n", res); | 730 | return sprintf(buf, "%d\n", res); |
@@ -683,8 +733,8 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, | |||
683 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, | 733 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, |
684 | const char *buf, size_t count) | 734 | const char *buf, size_t count) |
685 | { | 735 | { |
686 | struct i2c_client *client = to_i2c_client(dev); | 736 | struct dme1737_data *data = dev_get_drvdata(dev); |
687 | struct dme1737_data *data = i2c_get_clientdata(client); | 737 | struct i2c_client *client = &data->client; |
688 | struct sensor_device_attribute_2 | 738 | struct sensor_device_attribute_2 |
689 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 739 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
690 | int ix = sensor_attr_2->index; | 740 | int ix = sensor_attr_2->index; |
@@ -704,7 +754,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, | |||
704 | data->in_max[ix]); | 754 | data->in_max[ix]); |
705 | break; | 755 | break; |
706 | default: | 756 | default: |
707 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 757 | dev_dbg(dev, "Unknown function %d.\n", fn); |
708 | } | 758 | } |
709 | mutex_unlock(&data->update_lock); | 759 | mutex_unlock(&data->update_lock); |
710 | 760 | ||
@@ -754,7 +804,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | |||
754 | break; | 804 | break; |
755 | default: | 805 | default: |
756 | res = 0; | 806 | res = 0; |
757 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 807 | dev_dbg(dev, "Unknown function %d.\n", fn); |
758 | } | 808 | } |
759 | 809 | ||
760 | return sprintf(buf, "%d\n", res); | 810 | return sprintf(buf, "%d\n", res); |
@@ -763,8 +813,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | |||
763 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | 813 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, |
764 | const char *buf, size_t count) | 814 | const char *buf, size_t count) |
765 | { | 815 | { |
766 | struct i2c_client *client = to_i2c_client(dev); | 816 | struct dme1737_data *data = dev_get_drvdata(dev); |
767 | struct dme1737_data *data = i2c_get_clientdata(client); | 817 | struct i2c_client *client = &data->client; |
768 | struct sensor_device_attribute_2 | 818 | struct sensor_device_attribute_2 |
769 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 819 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
770 | int ix = sensor_attr_2->index; | 820 | int ix = sensor_attr_2->index; |
@@ -789,7 +839,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
789 | data->temp_offset[ix]); | 839 | data->temp_offset[ix]); |
790 | break; | 840 | break; |
791 | default: | 841 | default: |
792 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 842 | dev_dbg(dev, "Unknown function %d.\n", fn); |
793 | } | 843 | } |
794 | mutex_unlock(&data->update_lock); | 844 | mutex_unlock(&data->update_lock); |
795 | 845 | ||
@@ -843,7 +893,7 @@ static ssize_t show_zone(struct device *dev, struct device_attribute *attr, | |||
843 | break; | 893 | break; |
844 | default: | 894 | default: |
845 | res = 0; | 895 | res = 0; |
846 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 896 | dev_dbg(dev, "Unknown function %d.\n", fn); |
847 | } | 897 | } |
848 | 898 | ||
849 | return sprintf(buf, "%d\n", res); | 899 | return sprintf(buf, "%d\n", res); |
@@ -852,8 +902,8 @@ static ssize_t show_zone(struct device *dev, struct device_attribute *attr, | |||
852 | static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | 902 | static ssize_t set_zone(struct device *dev, struct device_attribute *attr, |
853 | const char *buf, size_t count) | 903 | const char *buf, size_t count) |
854 | { | 904 | { |
855 | struct i2c_client *client = to_i2c_client(dev); | 905 | struct dme1737_data *data = dev_get_drvdata(dev); |
856 | struct dme1737_data *data = i2c_get_clientdata(client); | 906 | struct i2c_client *client = &data->client; |
857 | struct sensor_device_attribute_2 | 907 | struct sensor_device_attribute_2 |
858 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 908 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
859 | int ix = sensor_attr_2->index; | 909 | int ix = sensor_attr_2->index; |
@@ -898,7 +948,7 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | |||
898 | data->zone_abs[ix]); | 948 | data->zone_abs[ix]); |
899 | break; | 949 | break; |
900 | default: | 950 | default: |
901 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 951 | dev_dbg(dev, "Unknown function %d.\n", fn); |
902 | } | 952 | } |
903 | mutex_unlock(&data->update_lock); | 953 | mutex_unlock(&data->update_lock); |
904 | 954 | ||
@@ -950,7 +1000,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | |||
950 | break; | 1000 | break; |
951 | default: | 1001 | default: |
952 | res = 0; | 1002 | res = 0; |
953 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 1003 | dev_dbg(dev, "Unknown function %d.\n", fn); |
954 | } | 1004 | } |
955 | 1005 | ||
956 | return sprintf(buf, "%d\n", res); | 1006 | return sprintf(buf, "%d\n", res); |
@@ -959,8 +1009,8 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | |||
959 | static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | 1009 | static ssize_t set_fan(struct device *dev, struct device_attribute *attr, |
960 | const char *buf, size_t count) | 1010 | const char *buf, size_t count) |
961 | { | 1011 | { |
962 | struct i2c_client *client = to_i2c_client(dev); | 1012 | struct dme1737_data *data = dev_get_drvdata(dev); |
963 | struct dme1737_data *data = i2c_get_clientdata(client); | 1013 | struct i2c_client *client = &data->client; |
964 | struct sensor_device_attribute_2 | 1014 | struct sensor_device_attribute_2 |
965 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 1015 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
966 | int ix = sensor_attr_2->index; | 1016 | int ix = sensor_attr_2->index; |
@@ -995,7 +1045,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
995 | /* Only valid for fan[1-4] */ | 1045 | /* Only valid for fan[1-4] */ |
996 | if (!(val == 1 || val == 2 || val == 4)) { | 1046 | if (!(val == 1 || val == 2 || val == 4)) { |
997 | count = -EINVAL; | 1047 | count = -EINVAL; |
998 | dev_warn(&client->dev, "Fan type value %ld not " | 1048 | dev_warn(dev, "Fan type value %ld not " |
999 | "supported. Choose one of 1, 2, or 4.\n", | 1049 | "supported. Choose one of 1, 2, or 4.\n", |
1000 | val); | 1050 | val); |
1001 | goto exit; | 1051 | goto exit; |
@@ -1006,7 +1056,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
1006 | data->fan_opt[ix]); | 1056 | data->fan_opt[ix]); |
1007 | break; | 1057 | break; |
1008 | default: | 1058 | default: |
1009 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 1059 | dev_dbg(dev, "Unknown function %d.\n", fn); |
1010 | } | 1060 | } |
1011 | exit: | 1061 | exit: |
1012 | mutex_unlock(&data->update_lock); | 1062 | mutex_unlock(&data->update_lock); |
@@ -1086,20 +1136,20 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | |||
1086 | break; | 1136 | break; |
1087 | default: | 1137 | default: |
1088 | res = 0; | 1138 | res = 0; |
1089 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 1139 | dev_dbg(dev, "Unknown function %d.\n", fn); |
1090 | } | 1140 | } |
1091 | 1141 | ||
1092 | return sprintf(buf, "%d\n", res); | 1142 | return sprintf(buf, "%d\n", res); |
1093 | } | 1143 | } |
1094 | 1144 | ||
1095 | static struct attribute *dme1737_attr_pwm[]; | 1145 | static struct attribute *dme1737_attr_pwm[]; |
1096 | static void dme1737_chmod_file(struct i2c_client*, struct attribute*, mode_t); | 1146 | static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); |
1097 | 1147 | ||
1098 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | 1148 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
1099 | const char *buf, size_t count) | 1149 | const char *buf, size_t count) |
1100 | { | 1150 | { |
1101 | struct i2c_client *client = to_i2c_client(dev); | 1151 | struct dme1737_data *data = dev_get_drvdata(dev); |
1102 | struct dme1737_data *data = i2c_get_clientdata(client); | 1152 | struct i2c_client *client = &data->client; |
1103 | struct sensor_device_attribute_2 | 1153 | struct sensor_device_attribute_2 |
1104 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 1154 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
1105 | int ix = sensor_attr_2->index; | 1155 | int ix = sensor_attr_2->index; |
@@ -1122,7 +1172,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1122 | /* Only valid for pwm[1-3] */ | 1172 | /* Only valid for pwm[1-3] */ |
1123 | if (val < 0 || val > 2) { | 1173 | if (val < 0 || val > 2) { |
1124 | count = -EINVAL; | 1174 | count = -EINVAL; |
1125 | dev_warn(&client->dev, "PWM enable %ld not " | 1175 | dev_warn(dev, "PWM enable %ld not " |
1126 | "supported. Choose one of 0, 1, or 2.\n", | 1176 | "supported. Choose one of 0, 1, or 2.\n", |
1127 | val); | 1177 | val); |
1128 | goto exit; | 1178 | goto exit; |
@@ -1156,7 +1206,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1156 | switch (val) { | 1206 | switch (val) { |
1157 | case 0: | 1207 | case 0: |
1158 | /* Change permissions of pwm[ix] to read-only */ | 1208 | /* Change permissions of pwm[ix] to read-only */ |
1159 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | 1209 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], |
1160 | S_IRUGO); | 1210 | S_IRUGO); |
1161 | /* Turn fan fully on */ | 1211 | /* Turn fan fully on */ |
1162 | data->pwm_config[ix] = PWM_EN_TO_REG(0, | 1212 | data->pwm_config[ix] = PWM_EN_TO_REG(0, |
@@ -1171,12 +1221,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1171 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1221 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), |
1172 | data->pwm_config[ix]); | 1222 | data->pwm_config[ix]); |
1173 | /* Change permissions of pwm[ix] to read-writeable */ | 1223 | /* Change permissions of pwm[ix] to read-writeable */ |
1174 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | 1224 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], |
1175 | S_IRUGO | S_IWUSR); | 1225 | S_IRUGO | S_IWUSR); |
1176 | break; | 1226 | break; |
1177 | case 2: | 1227 | case 2: |
1178 | /* Change permissions of pwm[ix] to read-only */ | 1228 | /* Change permissions of pwm[ix] to read-only */ |
1179 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | 1229 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], |
1180 | S_IRUGO); | 1230 | S_IRUGO); |
1181 | /* Turn on auto mode using the saved zone channel | 1231 | /* Turn on auto mode using the saved zone channel |
1182 | * assignment */ | 1232 | * assignment */ |
@@ -1223,7 +1273,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1223 | if (!(val == 1 || val == 2 || val == 4 || | 1273 | if (!(val == 1 || val == 2 || val == 4 || |
1224 | val == 6 || val == 7)) { | 1274 | val == 6 || val == 7)) { |
1225 | count = -EINVAL; | 1275 | count = -EINVAL; |
1226 | dev_warn(&client->dev, "PWM auto channels zone %ld " | 1276 | dev_warn(dev, "PWM auto channels zone %ld " |
1227 | "not supported. Choose one of 1, 2, 4, 6, " | 1277 | "not supported. Choose one of 1, 2, 4, 6, " |
1228 | "or 7.\n", val); | 1278 | "or 7.\n", val); |
1229 | goto exit; | 1279 | goto exit; |
@@ -1257,12 +1307,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1257 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, | 1307 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, |
1258 | dme1737_read(client, | 1308 | dme1737_read(client, |
1259 | DME1737_REG_PWM_RR(0))); | 1309 | DME1737_REG_PWM_RR(0))); |
1260 | |||
1261 | } else { | 1310 | } else { |
1262 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, | 1311 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, |
1263 | dme1737_read(client, | 1312 | dme1737_read(client, |
1264 | DME1737_REG_PWM_RR(0))); | 1313 | DME1737_REG_PWM_RR(0))); |
1265 | |||
1266 | } | 1314 | } |
1267 | dme1737_write(client, DME1737_REG_PWM_RR(0), | 1315 | dme1737_write(client, DME1737_REG_PWM_RR(0), |
1268 | data->pwm_rr[0]); | 1316 | data->pwm_rr[0]); |
@@ -1274,7 +1322,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1274 | data->pwm_min[ix]); | 1322 | data->pwm_min[ix]); |
1275 | break; | 1323 | break; |
1276 | default: | 1324 | default: |
1277 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | 1325 | dev_dbg(dev, "Unknown function %d.\n", fn); |
1278 | } | 1326 | } |
1279 | exit: | 1327 | exit: |
1280 | mutex_unlock(&data->update_lock); | 1328 | mutex_unlock(&data->update_lock); |
@@ -1298,8 +1346,7 @@ static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, | |||
1298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, | 1346 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, |
1299 | const char *buf, size_t count) | 1347 | const char *buf, size_t count) |
1300 | { | 1348 | { |
1301 | struct i2c_client *client = to_i2c_client(dev); | 1349 | struct dme1737_data *data = dev_get_drvdata(dev); |
1302 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1303 | long val = simple_strtol(buf, NULL, 10); | 1350 | long val = simple_strtol(buf, NULL, 10); |
1304 | 1351 | ||
1305 | data->vrm = val; | 1352 | data->vrm = val; |
@@ -1314,6 +1361,14 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | |||
1314 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | 1361 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); |
1315 | } | 1362 | } |
1316 | 1363 | ||
1364 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
1365 | char *buf) | ||
1366 | { | ||
1367 | struct dme1737_data *data = dev_get_drvdata(dev); | ||
1368 | |||
1369 | return sprintf(buf, "%s\n", data->client.name); | ||
1370 | } | ||
1371 | |||
1317 | /* --------------------------------------------------------------------- | 1372 | /* --------------------------------------------------------------------- |
1318 | * Sysfs device attribute defines and structs | 1373 | * Sysfs device attribute defines and structs |
1319 | * --------------------------------------------------------------------- */ | 1374 | * --------------------------------------------------------------------- */ |
@@ -1322,13 +1377,13 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | |||
1322 | 1377 | ||
1323 | #define SENSOR_DEVICE_ATTR_IN(ix) \ | 1378 | #define SENSOR_DEVICE_ATTR_IN(ix) \ |
1324 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ | 1379 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ |
1325 | show_in, NULL, SYS_IN_INPUT, ix); \ | 1380 | show_in, NULL, SYS_IN_INPUT, ix); \ |
1326 | static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ | 1381 | static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ |
1327 | show_in, set_in, SYS_IN_MIN, ix); \ | 1382 | show_in, set_in, SYS_IN_MIN, ix); \ |
1328 | static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ | 1383 | static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ |
1329 | show_in, set_in, SYS_IN_MAX, ix); \ | 1384 | show_in, set_in, SYS_IN_MAX, ix); \ |
1330 | static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \ | 1385 | static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \ |
1331 | show_in, NULL, SYS_IN_ALARM, ix) | 1386 | show_in, NULL, SYS_IN_ALARM, ix) |
1332 | 1387 | ||
1333 | SENSOR_DEVICE_ATTR_IN(0); | 1388 | SENSOR_DEVICE_ATTR_IN(0); |
1334 | SENSOR_DEVICE_ATTR_IN(1); | 1389 | SENSOR_DEVICE_ATTR_IN(1); |
@@ -1342,17 +1397,17 @@ SENSOR_DEVICE_ATTR_IN(6); | |||
1342 | 1397 | ||
1343 | #define SENSOR_DEVICE_ATTR_TEMP(ix) \ | 1398 | #define SENSOR_DEVICE_ATTR_TEMP(ix) \ |
1344 | static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \ | 1399 | static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \ |
1345 | show_temp, NULL, SYS_TEMP_INPUT, ix-1); \ | 1400 | show_temp, NULL, SYS_TEMP_INPUT, ix-1); \ |
1346 | static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \ | 1401 | static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \ |
1347 | show_temp, set_temp, SYS_TEMP_MIN, ix-1); \ | 1402 | show_temp, set_temp, SYS_TEMP_MIN, ix-1); \ |
1348 | static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ | 1403 | static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ |
1349 | show_temp, set_temp, SYS_TEMP_MAX, ix-1); \ | 1404 | show_temp, set_temp, SYS_TEMP_MAX, ix-1); \ |
1350 | static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \ | 1405 | static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \ |
1351 | show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \ | 1406 | show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \ |
1352 | static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \ | 1407 | static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \ |
1353 | show_temp, NULL, SYS_TEMP_ALARM, ix-1); \ | 1408 | show_temp, NULL, SYS_TEMP_ALARM, ix-1); \ |
1354 | static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \ | 1409 | static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \ |
1355 | show_temp, NULL, SYS_TEMP_FAULT, ix-1) | 1410 | show_temp, NULL, SYS_TEMP_FAULT, ix-1) |
1356 | 1411 | ||
1357 | SENSOR_DEVICE_ATTR_TEMP(1); | 1412 | SENSOR_DEVICE_ATTR_TEMP(1); |
1358 | SENSOR_DEVICE_ATTR_TEMP(2); | 1413 | SENSOR_DEVICE_ATTR_TEMP(2); |
@@ -1362,15 +1417,15 @@ SENSOR_DEVICE_ATTR_TEMP(3); | |||
1362 | 1417 | ||
1363 | #define SENSOR_DEVICE_ATTR_ZONE(ix) \ | 1418 | #define SENSOR_DEVICE_ATTR_ZONE(ix) \ |
1364 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \ | 1419 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \ |
1365 | show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \ | 1420 | show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \ |
1366 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp_hyst, S_IRUGO, \ | 1421 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp_hyst, S_IRUGO, \ |
1367 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP_HYST, ix-1); \ | 1422 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP_HYST, ix-1); \ |
1368 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \ | 1423 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \ |
1369 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \ | 1424 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \ |
1370 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \ | 1425 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \ |
1371 | show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \ | 1426 | show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \ |
1372 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \ | 1427 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \ |
1373 | show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1) | 1428 | show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1) |
1374 | 1429 | ||
1375 | SENSOR_DEVICE_ATTR_ZONE(1); | 1430 | SENSOR_DEVICE_ATTR_ZONE(1); |
1376 | SENSOR_DEVICE_ATTR_ZONE(2); | 1431 | SENSOR_DEVICE_ATTR_ZONE(2); |
@@ -1380,13 +1435,13 @@ SENSOR_DEVICE_ATTR_ZONE(3); | |||
1380 | 1435 | ||
1381 | #define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \ | 1436 | #define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \ |
1382 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | 1437 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ |
1383 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | 1438 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ |
1384 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | 1439 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ |
1385 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | 1440 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ |
1386 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | 1441 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ |
1387 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | 1442 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ |
1388 | static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \ | 1443 | static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \ |
1389 | show_fan, set_fan, SYS_FAN_TYPE, ix-1) | 1444 | show_fan, set_fan, SYS_FAN_TYPE, ix-1) |
1390 | 1445 | ||
1391 | SENSOR_DEVICE_ATTR_FAN_1TO4(1); | 1446 | SENSOR_DEVICE_ATTR_FAN_1TO4(1); |
1392 | SENSOR_DEVICE_ATTR_FAN_1TO4(2); | 1447 | SENSOR_DEVICE_ATTR_FAN_1TO4(2); |
@@ -1397,13 +1452,13 @@ SENSOR_DEVICE_ATTR_FAN_1TO4(4); | |||
1397 | 1452 | ||
1398 | #define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \ | 1453 | #define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \ |
1399 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | 1454 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ |
1400 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | 1455 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ |
1401 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | 1456 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ |
1402 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | 1457 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ |
1403 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | 1458 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ |
1404 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | 1459 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ |
1405 | static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \ | 1460 | static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \ |
1406 | show_fan, set_fan, SYS_FAN_MAX, ix-1) | 1461 | show_fan, set_fan, SYS_FAN_MAX, ix-1) |
1407 | 1462 | ||
1408 | SENSOR_DEVICE_ATTR_FAN_5TO6(5); | 1463 | SENSOR_DEVICE_ATTR_FAN_5TO6(5); |
1409 | SENSOR_DEVICE_ATTR_FAN_5TO6(6); | 1464 | SENSOR_DEVICE_ATTR_FAN_5TO6(6); |
@@ -1412,21 +1467,21 @@ SENSOR_DEVICE_ATTR_FAN_5TO6(6); | |||
1412 | 1467 | ||
1413 | #define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \ | 1468 | #define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \ |
1414 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \ | 1469 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \ |
1415 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | 1470 | show_pwm, set_pwm, SYS_PWM, ix-1); \ |
1416 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \ | 1471 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \ |
1417 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | 1472 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ |
1418 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | 1473 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ |
1419 | show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \ | 1474 | show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \ |
1420 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \ | 1475 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \ |
1421 | show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \ | 1476 | show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \ |
1422 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \ | 1477 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \ |
1423 | show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \ | 1478 | show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \ |
1424 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \ | 1479 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \ |
1425 | show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \ | 1480 | show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \ |
1426 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \ | 1481 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \ |
1427 | show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \ | 1482 | show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \ |
1428 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \ | 1483 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \ |
1429 | show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1) | 1484 | show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1) |
1430 | 1485 | ||
1431 | SENSOR_DEVICE_ATTR_PWM_1TO3(1); | 1486 | SENSOR_DEVICE_ATTR_PWM_1TO3(1); |
1432 | SENSOR_DEVICE_ATTR_PWM_1TO3(2); | 1487 | SENSOR_DEVICE_ATTR_PWM_1TO3(2); |
@@ -1436,11 +1491,11 @@ SENSOR_DEVICE_ATTR_PWM_1TO3(3); | |||
1436 | 1491 | ||
1437 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ | 1492 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ |
1438 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \ | 1493 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \ |
1439 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | 1494 | show_pwm, set_pwm, SYS_PWM, ix-1); \ |
1440 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ | 1495 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ |
1441 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | 1496 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ |
1442 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | 1497 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ |
1443 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) | 1498 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) |
1444 | 1499 | ||
1445 | SENSOR_DEVICE_ATTR_PWM_5TO6(5); | 1500 | SENSOR_DEVICE_ATTR_PWM_5TO6(5); |
1446 | SENSOR_DEVICE_ATTR_PWM_5TO6(6); | 1501 | SENSOR_DEVICE_ATTR_PWM_5TO6(6); |
@@ -1449,6 +1504,7 @@ SENSOR_DEVICE_ATTR_PWM_5TO6(6); | |||
1449 | 1504 | ||
1450 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); | 1505 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); |
1451 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 1506 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
1507 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ | ||
1452 | 1508 | ||
1453 | #define SENSOR_DEV_ATTR_IN(ix) \ | 1509 | #define SENSOR_DEV_ATTR_IN(ix) \ |
1454 | &sensor_dev_attr_in##ix##_input.dev_attr.attr, \ | 1510 | &sensor_dev_attr_in##ix##_input.dev_attr.attr, \ |
@@ -1519,53 +1575,53 @@ SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix), \ | |||
1519 | * permissions are created read-only and write permissions are added or removed | 1575 | * permissions are created read-only and write permissions are added or removed |
1520 | * on the fly when required */ | 1576 | * on the fly when required */ |
1521 | static struct attribute *dme1737_attr[] ={ | 1577 | static struct attribute *dme1737_attr[] ={ |
1522 | /* Voltages */ | 1578 | /* Voltages */ |
1523 | SENSOR_DEV_ATTR_IN(0), | 1579 | SENSOR_DEV_ATTR_IN(0), |
1524 | SENSOR_DEV_ATTR_IN(1), | 1580 | SENSOR_DEV_ATTR_IN(1), |
1525 | SENSOR_DEV_ATTR_IN(2), | 1581 | SENSOR_DEV_ATTR_IN(2), |
1526 | SENSOR_DEV_ATTR_IN(3), | 1582 | SENSOR_DEV_ATTR_IN(3), |
1527 | SENSOR_DEV_ATTR_IN(4), | 1583 | SENSOR_DEV_ATTR_IN(4), |
1528 | SENSOR_DEV_ATTR_IN(5), | 1584 | SENSOR_DEV_ATTR_IN(5), |
1529 | SENSOR_DEV_ATTR_IN(6), | 1585 | SENSOR_DEV_ATTR_IN(6), |
1530 | /* Temperatures */ | 1586 | /* Temperatures */ |
1531 | SENSOR_DEV_ATTR_TEMP(1), | 1587 | SENSOR_DEV_ATTR_TEMP(1), |
1532 | SENSOR_DEV_ATTR_TEMP(2), | 1588 | SENSOR_DEV_ATTR_TEMP(2), |
1533 | SENSOR_DEV_ATTR_TEMP(3), | 1589 | SENSOR_DEV_ATTR_TEMP(3), |
1534 | /* Zones */ | 1590 | /* Zones */ |
1535 | SENSOR_DEV_ATTR_ZONE(1), | 1591 | SENSOR_DEV_ATTR_ZONE(1), |
1536 | SENSOR_DEV_ATTR_ZONE(2), | 1592 | SENSOR_DEV_ATTR_ZONE(2), |
1537 | SENSOR_DEV_ATTR_ZONE(3), | 1593 | SENSOR_DEV_ATTR_ZONE(3), |
1538 | /* Misc */ | 1594 | /* Misc */ |
1539 | &dev_attr_vrm.attr, | 1595 | &dev_attr_vrm.attr, |
1540 | &dev_attr_cpu0_vid.attr, | 1596 | &dev_attr_cpu0_vid.attr, |
1541 | NULL | 1597 | NULL |
1542 | }; | 1598 | }; |
1543 | 1599 | ||
1544 | static const struct attribute_group dme1737_group = { | 1600 | static const struct attribute_group dme1737_group = { |
1545 | .attrs = dme1737_attr, | 1601 | .attrs = dme1737_attr, |
1546 | }; | 1602 | }; |
1547 | 1603 | ||
1548 | /* The following structs hold the PWM attributes, some of which are optional. | 1604 | /* The following structs hold the PWM attributes, some of which are optional. |
1549 | * Their creation depends on the chip configuration which is determined during | 1605 | * Their creation depends on the chip configuration which is determined during |
1550 | * module load. */ | 1606 | * module load. */ |
1551 | static struct attribute *dme1737_attr_pwm1[] = { | 1607 | static struct attribute *dme1737_attr_pwm1[] = { |
1552 | SENSOR_DEV_ATTR_PWM_1TO3(1), | 1608 | SENSOR_DEV_ATTR_PWM_1TO3(1), |
1553 | NULL | 1609 | NULL |
1554 | }; | 1610 | }; |
1555 | static struct attribute *dme1737_attr_pwm2[] = { | 1611 | static struct attribute *dme1737_attr_pwm2[] = { |
1556 | SENSOR_DEV_ATTR_PWM_1TO3(2), | 1612 | SENSOR_DEV_ATTR_PWM_1TO3(2), |
1557 | NULL | 1613 | NULL |
1558 | }; | 1614 | }; |
1559 | static struct attribute *dme1737_attr_pwm3[] = { | 1615 | static struct attribute *dme1737_attr_pwm3[] = { |
1560 | SENSOR_DEV_ATTR_PWM_1TO3(3), | 1616 | SENSOR_DEV_ATTR_PWM_1TO3(3), |
1561 | NULL | 1617 | NULL |
1562 | }; | 1618 | }; |
1563 | static struct attribute *dme1737_attr_pwm5[] = { | 1619 | static struct attribute *dme1737_attr_pwm5[] = { |
1564 | SENSOR_DEV_ATTR_PWM_5TO6(5), | 1620 | SENSOR_DEV_ATTR_PWM_5TO6(5), |
1565 | NULL | 1621 | NULL |
1566 | }; | 1622 | }; |
1567 | static struct attribute *dme1737_attr_pwm6[] = { | 1623 | static struct attribute *dme1737_attr_pwm6[] = { |
1568 | SENSOR_DEV_ATTR_PWM_5TO6(6), | 1624 | SENSOR_DEV_ATTR_PWM_5TO6(6), |
1569 | NULL | 1625 | NULL |
1570 | }; | 1626 | }; |
1571 | 1627 | ||
@@ -1582,27 +1638,27 @@ static const struct attribute_group dme1737_pwm_group[] = { | |||
1582 | * Their creation depends on the chip configuration which is determined during | 1638 | * Their creation depends on the chip configuration which is determined during |
1583 | * module load. */ | 1639 | * module load. */ |
1584 | static struct attribute *dme1737_attr_fan1[] = { | 1640 | static struct attribute *dme1737_attr_fan1[] = { |
1585 | SENSOR_DEV_ATTR_FAN_1TO4(1), | 1641 | SENSOR_DEV_ATTR_FAN_1TO4(1), |
1586 | NULL | 1642 | NULL |
1587 | }; | 1643 | }; |
1588 | static struct attribute *dme1737_attr_fan2[] = { | 1644 | static struct attribute *dme1737_attr_fan2[] = { |
1589 | SENSOR_DEV_ATTR_FAN_1TO4(2), | 1645 | SENSOR_DEV_ATTR_FAN_1TO4(2), |
1590 | NULL | 1646 | NULL |
1591 | }; | 1647 | }; |
1592 | static struct attribute *dme1737_attr_fan3[] = { | 1648 | static struct attribute *dme1737_attr_fan3[] = { |
1593 | SENSOR_DEV_ATTR_FAN_1TO4(3), | 1649 | SENSOR_DEV_ATTR_FAN_1TO4(3), |
1594 | NULL | 1650 | NULL |
1595 | }; | 1651 | }; |
1596 | static struct attribute *dme1737_attr_fan4[] = { | 1652 | static struct attribute *dme1737_attr_fan4[] = { |
1597 | SENSOR_DEV_ATTR_FAN_1TO4(4), | 1653 | SENSOR_DEV_ATTR_FAN_1TO4(4), |
1598 | NULL | 1654 | NULL |
1599 | }; | 1655 | }; |
1600 | static struct attribute *dme1737_attr_fan5[] = { | 1656 | static struct attribute *dme1737_attr_fan5[] = { |
1601 | SENSOR_DEV_ATTR_FAN_5TO6(5), | 1657 | SENSOR_DEV_ATTR_FAN_5TO6(5), |
1602 | NULL | 1658 | NULL |
1603 | }; | 1659 | }; |
1604 | static struct attribute *dme1737_attr_fan6[] = { | 1660 | static struct attribute *dme1737_attr_fan6[] = { |
1605 | SENSOR_DEV_ATTR_FAN_5TO6(6), | 1661 | SENSOR_DEV_ATTR_FAN_5TO6(6), |
1606 | NULL | 1662 | NULL |
1607 | }; | 1663 | }; |
1608 | 1664 | ||
@@ -1637,23 +1693,23 @@ static const struct attribute_group dme1737_lock_group = { | |||
1637 | * writeable if the chip is *not* locked and the respective PWM is available. | 1693 | * writeable if the chip is *not* locked and the respective PWM is available. |
1638 | * Otherwise they stay read-only. */ | 1694 | * Otherwise they stay read-only. */ |
1639 | static struct attribute *dme1737_attr_pwm1_lock[] = { | 1695 | static struct attribute *dme1737_attr_pwm1_lock[] = { |
1640 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1), | 1696 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1), |
1641 | NULL | 1697 | NULL |
1642 | }; | 1698 | }; |
1643 | static struct attribute *dme1737_attr_pwm2_lock[] = { | 1699 | static struct attribute *dme1737_attr_pwm2_lock[] = { |
1644 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2), | 1700 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2), |
1645 | NULL | 1701 | NULL |
1646 | }; | 1702 | }; |
1647 | static struct attribute *dme1737_attr_pwm3_lock[] = { | 1703 | static struct attribute *dme1737_attr_pwm3_lock[] = { |
1648 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3), | 1704 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3), |
1649 | NULL | 1705 | NULL |
1650 | }; | 1706 | }; |
1651 | static struct attribute *dme1737_attr_pwm5_lock[] = { | 1707 | static struct attribute *dme1737_attr_pwm5_lock[] = { |
1652 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5), | 1708 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5), |
1653 | NULL | 1709 | NULL |
1654 | }; | 1710 | }; |
1655 | static struct attribute *dme1737_attr_pwm6_lock[] = { | 1711 | static struct attribute *dme1737_attr_pwm6_lock[] = { |
1656 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6), | 1712 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6), |
1657 | NULL | 1713 | NULL |
1658 | }; | 1714 | }; |
1659 | 1715 | ||
@@ -1678,6 +1734,16 @@ static struct attribute *dme1737_attr_pwm[] = { | |||
1678 | * Super-IO functions | 1734 | * Super-IO functions |
1679 | * --------------------------------------------------------------------- */ | 1735 | * --------------------------------------------------------------------- */ |
1680 | 1736 | ||
1737 | static inline void dme1737_sio_enter(int sio_cip) | ||
1738 | { | ||
1739 | outb(0x55, sio_cip); | ||
1740 | } | ||
1741 | |||
1742 | static inline void dme1737_sio_exit(int sio_cip) | ||
1743 | { | ||
1744 | outb(0xaa, sio_cip); | ||
1745 | } | ||
1746 | |||
1681 | static inline int dme1737_sio_inb(int sio_cip, int reg) | 1747 | static inline int dme1737_sio_inb(int sio_cip, int reg) |
1682 | { | 1748 | { |
1683 | outb(reg, sio_cip); | 1749 | outb(reg, sio_cip); |
@@ -1690,136 +1756,196 @@ static inline void dme1737_sio_outb(int sio_cip, int reg, int val) | |||
1690 | outb(val, sio_cip + 1); | 1756 | outb(val, sio_cip + 1); |
1691 | } | 1757 | } |
1692 | 1758 | ||
1693 | static int dme1737_sio_get_features(int sio_cip, struct i2c_client *client) | 1759 | /* --------------------------------------------------------------------- |
1760 | * Device initialization | ||
1761 | * --------------------------------------------------------------------- */ | ||
1762 | |||
1763 | static int dme1737_i2c_get_features(int, struct dme1737_data*); | ||
1764 | |||
1765 | static void dme1737_chmod_file(struct device *dev, | ||
1766 | struct attribute *attr, mode_t mode) | ||
1694 | { | 1767 | { |
1695 | struct dme1737_data *data = i2c_get_clientdata(client); | 1768 | if (sysfs_chmod_file(&dev->kobj, attr, mode)) { |
1696 | int err = 0, reg; | 1769 | dev_warn(dev, "Failed to change permissions of %s.\n", |
1697 | u16 addr; | 1770 | attr->name); |
1771 | } | ||
1772 | } | ||
1698 | 1773 | ||
1699 | /* Enter configuration mode */ | 1774 | static void dme1737_chmod_group(struct device *dev, |
1700 | outb(0x55, sio_cip); | 1775 | const struct attribute_group *group, |
1776 | mode_t mode) | ||
1777 | { | ||
1778 | struct attribute **attr; | ||
1701 | 1779 | ||
1702 | /* Check device ID | 1780 | for (attr = group->attrs; *attr; attr++) { |
1703 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | 1781 | dme1737_chmod_file(dev, *attr, mode); |
1704 | reg = dme1737_sio_inb(sio_cip, 0x20); | ||
1705 | if (!(reg == 0x77 || reg == 0x78)) { | ||
1706 | err = -ENODEV; | ||
1707 | goto exit; | ||
1708 | } | 1782 | } |
1783 | } | ||
1709 | 1784 | ||
1710 | /* Select logical device A (runtime registers) */ | 1785 | static void dme1737_remove_files(struct device *dev) |
1711 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | 1786 | { |
1787 | struct dme1737_data *data = dev_get_drvdata(dev); | ||
1788 | int ix; | ||
1712 | 1789 | ||
1713 | /* Get the base address of the runtime registers */ | 1790 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1714 | if (!(addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | 1791 | if (data->has_fan & (1 << ix)) { |
1715 | dme1737_sio_inb(sio_cip, 0x61))) { | 1792 | sysfs_remove_group(&dev->kobj, |
1716 | err = -ENODEV; | 1793 | &dme1737_fan_group[ix]); |
1717 | goto exit; | 1794 | } |
1718 | } | 1795 | } |
1719 | 1796 | ||
1720 | /* Read the runtime registers to determine which optional features | 1797 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1721 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | 1798 | if (data->has_pwm & (1 << ix)) { |
1722 | * to '10' if the respective feature is enabled. */ | 1799 | sysfs_remove_group(&dev->kobj, |
1723 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | 1800 | &dme1737_pwm_group[ix]); |
1724 | data->has_fan |= (1 << 5); | 1801 | } |
1725 | } | 1802 | } |
1726 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | 1803 | |
1727 | data->has_pwm |= (1 << 5); | 1804 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
1805 | |||
1806 | if (!data->client.driver) { | ||
1807 | sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); | ||
1728 | } | 1808 | } |
1729 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | 1809 | } |
1730 | data->has_fan |= (1 << 4); | 1810 | |
1811 | static int dme1737_create_files(struct device *dev) | ||
1812 | { | ||
1813 | struct dme1737_data *data = dev_get_drvdata(dev); | ||
1814 | int err, ix; | ||
1815 | |||
1816 | /* Create a name attribute for ISA devices */ | ||
1817 | if (!data->client.driver && | ||
1818 | (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { | ||
1819 | goto exit; | ||
1731 | } | 1820 | } |
1732 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | 1821 | |
1733 | data->has_pwm |= (1 << 4); | 1822 | /* Create standard sysfs attributes */ |
1823 | if ((err = sysfs_create_group(&dev->kobj, &dme1737_group))) { | ||
1824 | goto exit_remove; | ||
1734 | } | 1825 | } |
1735 | 1826 | ||
1736 | exit: | 1827 | /* Create fan sysfs attributes */ |
1737 | /* Exit configuration mode */ | 1828 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1738 | outb(0xaa, sio_cip); | 1829 | if (data->has_fan & (1 << ix)) { |
1830 | if ((err = sysfs_create_group(&dev->kobj, | ||
1831 | &dme1737_fan_group[ix]))) { | ||
1832 | goto exit_remove; | ||
1833 | } | ||
1834 | } | ||
1835 | } | ||
1739 | 1836 | ||
1740 | return err; | 1837 | /* Create PWM sysfs attributes */ |
1741 | } | 1838 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
1839 | if (data->has_pwm & (1 << ix)) { | ||
1840 | if ((err = sysfs_create_group(&dev->kobj, | ||
1841 | &dme1737_pwm_group[ix]))) { | ||
1842 | goto exit_remove; | ||
1843 | } | ||
1844 | } | ||
1845 | } | ||
1742 | 1846 | ||
1743 | /* --------------------------------------------------------------------- | 1847 | /* Inform if the device is locked. Otherwise change the permissions of |
1744 | * Device detection, registration and initialization | 1848 | * selected attributes from read-only to read-writeable. */ |
1745 | * --------------------------------------------------------------------- */ | 1849 | if (data->config & 0x02) { |
1850 | dev_info(dev, "Device is locked. Some attributes " | ||
1851 | "will be read-only.\n"); | ||
1852 | } else { | ||
1853 | /* Change permissions of standard attributes */ | ||
1854 | dme1737_chmod_group(dev, &dme1737_lock_group, | ||
1855 | S_IRUGO | S_IWUSR); | ||
1746 | 1856 | ||
1747 | static struct i2c_driver dme1737_driver; | 1857 | /* Change permissions of PWM attributes */ |
1858 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { | ||
1859 | if (data->has_pwm & (1 << ix)) { | ||
1860 | dme1737_chmod_group(dev, | ||
1861 | &dme1737_pwm_lock_group[ix], | ||
1862 | S_IRUGO | S_IWUSR); | ||
1863 | } | ||
1864 | } | ||
1748 | 1865 | ||
1749 | static void dme1737_chmod_file(struct i2c_client *client, | 1866 | /* Change permissions of pwm[1-3] if in manual mode */ |
1750 | struct attribute *attr, mode_t mode) | 1867 | for (ix = 0; ix < 3; ix++) { |
1751 | { | 1868 | if ((data->has_pwm & (1 << ix)) && |
1752 | if (sysfs_chmod_file(&client->dev.kobj, attr, mode)) { | 1869 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
1753 | dev_warn(&client->dev, "Failed to change permissions of %s.\n", | 1870 | dme1737_chmod_file(dev, |
1754 | attr->name); | 1871 | dme1737_attr_pwm[ix], |
1872 | S_IRUGO | S_IWUSR); | ||
1873 | } | ||
1874 | } | ||
1755 | } | 1875 | } |
1756 | } | ||
1757 | 1876 | ||
1758 | static void dme1737_chmod_group(struct i2c_client *client, | 1877 | return 0; |
1759 | const struct attribute_group *group, | ||
1760 | mode_t mode) | ||
1761 | { | ||
1762 | struct attribute **attr; | ||
1763 | 1878 | ||
1764 | for (attr = group->attrs; *attr; attr++) { | 1879 | exit_remove: |
1765 | dme1737_chmod_file(client, *attr, mode); | 1880 | dme1737_remove_files(dev); |
1766 | } | 1881 | exit: |
1882 | return err; | ||
1767 | } | 1883 | } |
1768 | 1884 | ||
1769 | static int dme1737_init_client(struct i2c_client *client) | 1885 | static int dme1737_init_device(struct device *dev) |
1770 | { | 1886 | { |
1771 | struct dme1737_data *data = i2c_get_clientdata(client); | 1887 | struct dme1737_data *data = dev_get_drvdata(dev); |
1888 | struct i2c_client *client = &data->client; | ||
1772 | int ix; | 1889 | int ix; |
1773 | u8 reg; | 1890 | u8 reg; |
1774 | 1891 | ||
1775 | data->config = dme1737_read(client, DME1737_REG_CONFIG); | 1892 | data->config = dme1737_read(client, DME1737_REG_CONFIG); |
1776 | /* Inform if part is not monitoring/started */ | 1893 | /* Inform if part is not monitoring/started */ |
1777 | if (!(data->config & 0x01)) { | 1894 | if (!(data->config & 0x01)) { |
1778 | if (!force_start) { | 1895 | if (!force_start) { |
1779 | dev_err(&client->dev, "Device is not monitoring. " | 1896 | dev_err(dev, "Device is not monitoring. " |
1780 | "Use the force_start load parameter to " | 1897 | "Use the force_start load parameter to " |
1781 | "override.\n"); | 1898 | "override.\n"); |
1782 | return -EFAULT; | 1899 | return -EFAULT; |
1783 | } | 1900 | } |
1784 | 1901 | ||
1785 | /* Force monitoring */ | 1902 | /* Force monitoring */ |
1786 | data->config |= 0x01; | 1903 | data->config |= 0x01; |
1787 | dme1737_write(client, DME1737_REG_CONFIG, data->config); | 1904 | dme1737_write(client, DME1737_REG_CONFIG, data->config); |
1788 | } | 1905 | } |
1789 | /* Inform if part is not ready */ | 1906 | /* Inform if part is not ready */ |
1790 | if (!(data->config & 0x04)) { | 1907 | if (!(data->config & 0x04)) { |
1791 | dev_err(&client->dev, "Device is not ready.\n"); | 1908 | dev_err(dev, "Device is not ready.\n"); |
1792 | return -EFAULT; | 1909 | return -EFAULT; |
1793 | } | 1910 | } |
1794 | 1911 | ||
1795 | data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); | 1912 | /* Determine which optional fan and pwm features are enabled/present */ |
1796 | /* Check if optional fan3 input is enabled */ | 1913 | if (client->driver) { /* I2C chip */ |
1797 | if (data->config2 & 0x04) { | 1914 | data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); |
1798 | data->has_fan |= (1 << 2); | 1915 | /* Check if optional fan3 input is enabled */ |
1799 | } | 1916 | if (data->config2 & 0x04) { |
1917 | data->has_fan |= (1 << 2); | ||
1918 | } | ||
1800 | 1919 | ||
1801 | /* Fan4 and pwm3 are only available if the client's I2C address | 1920 | /* Fan4 and pwm3 are only available if the client's I2C address |
1802 | * is the default 0x2e. Otherwise the I/Os associated with these | 1921 | * is the default 0x2e. Otherwise the I/Os associated with |
1803 | * functions are used for addr enable/select. */ | 1922 | * these functions are used for addr enable/select. */ |
1804 | if (client->addr == 0x2e) { | 1923 | if (data->client.addr == 0x2e) { |
1805 | data->has_fan |= (1 << 3); | 1924 | data->has_fan |= (1 << 3); |
1806 | data->has_pwm |= (1 << 2); | 1925 | data->has_pwm |= (1 << 2); |
1807 | } | 1926 | } |
1808 | 1927 | ||
1809 | /* Determine if the optional fan[5-6] and/or pwm[5-6] are enabled. | 1928 | /* Determine which of the optional fan[5-6] and pwm[5-6] |
1810 | * For this, we need to query the runtime registers through the | 1929 | * features are enabled. For this, we need to query the runtime |
1811 | * Super-IO LPC interface. Try both config ports 0x2e and 0x4e. */ | 1930 | * registers through the Super-IO LPC interface. Try both |
1812 | if (dme1737_sio_get_features(0x2e, client) && | 1931 | * config ports 0x2e and 0x4e. */ |
1813 | dme1737_sio_get_features(0x4e, client)) { | 1932 | if (dme1737_i2c_get_features(0x2e, data) && |
1814 | dev_warn(&client->dev, "Failed to query Super-IO for optional " | 1933 | dme1737_i2c_get_features(0x4e, data)) { |
1815 | "features.\n"); | 1934 | dev_warn(dev, "Failed to query Super-IO for optional " |
1935 | "features.\n"); | ||
1936 | } | ||
1937 | } else { /* ISA chip */ | ||
1938 | /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6] | ||
1939 | * don't exist in the ISA chip. */ | ||
1940 | data->has_fan |= (1 << 2); | ||
1941 | data->has_pwm |= (1 << 2); | ||
1816 | } | 1942 | } |
1817 | 1943 | ||
1818 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | 1944 | /* Fan1, fan2, pwm1, and pwm2 are always present */ |
1819 | data->has_fan |= 0x03; | 1945 | data->has_fan |= 0x03; |
1820 | data->has_pwm |= 0x03; | 1946 | data->has_pwm |= 0x03; |
1821 | 1947 | ||
1822 | dev_info(&client->dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | 1948 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " |
1823 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | 1949 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", |
1824 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | 1950 | (data->has_pwm & (1 << 2)) ? "yes" : "no", |
1825 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | 1951 | (data->has_pwm & (1 << 4)) ? "yes" : "no", |
@@ -1831,13 +1957,19 @@ static int dme1737_init_client(struct i2c_client *client) | |||
1831 | 1957 | ||
1832 | reg = dme1737_read(client, DME1737_REG_TACH_PWM); | 1958 | reg = dme1737_read(client, DME1737_REG_TACH_PWM); |
1833 | /* Inform if fan-to-pwm mapping differs from the default */ | 1959 | /* Inform if fan-to-pwm mapping differs from the default */ |
1834 | if (reg != 0xa4) { | 1960 | if (client->driver && reg != 0xa4) { /* I2C chip */ |
1835 | dev_warn(&client->dev, "Non-standard fan to pwm mapping: " | 1961 | dev_warn(dev, "Non-standard fan to pwm mapping: " |
1836 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " | 1962 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " |
1837 | "fan4->pwm%d. Please report to the driver " | 1963 | "fan4->pwm%d. Please report to the driver " |
1838 | "maintainer.\n", | 1964 | "maintainer.\n", |
1839 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | 1965 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, |
1840 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); | 1966 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); |
1967 | } else if (!client->driver && reg != 0x24) { /* ISA chip */ | ||
1968 | dev_warn(dev, "Non-standard fan to pwm mapping: " | ||
1969 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " | ||
1970 | "Please report to the driver maintainer.\n", | ||
1971 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | ||
1972 | ((reg >> 4) & 0x03) + 1); | ||
1841 | } | 1973 | } |
1842 | 1974 | ||
1843 | /* Switch pwm[1-3] to manual mode if they are currently disabled and | 1975 | /* Switch pwm[1-3] to manual mode if they are currently disabled and |
@@ -1849,7 +1981,7 @@ static int dme1737_init_client(struct i2c_client *client) | |||
1849 | DME1737_REG_PWM_CONFIG(ix)); | 1981 | DME1737_REG_PWM_CONFIG(ix)); |
1850 | if ((data->has_pwm & (1 << ix)) && | 1982 | if ((data->has_pwm & (1 << ix)) && |
1851 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 1983 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
1852 | dev_info(&client->dev, "Switching pwm%d to " | 1984 | dev_info(dev, "Switching pwm%d to " |
1853 | "manual mode.\n", ix + 1); | 1985 | "manual mode.\n", ix + 1); |
1854 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | 1986 | data->pwm_config[ix] = PWM_EN_TO_REG(1, |
1855 | data->pwm_config[ix]); | 1987 | data->pwm_config[ix]); |
@@ -1872,13 +2004,67 @@ static int dme1737_init_client(struct i2c_client *client) | |||
1872 | return 0; | 2004 | return 0; |
1873 | } | 2005 | } |
1874 | 2006 | ||
1875 | static int dme1737_detect(struct i2c_adapter *adapter, int address, | 2007 | /* --------------------------------------------------------------------- |
1876 | int kind) | 2008 | * I2C device detection and registration |
2009 | * --------------------------------------------------------------------- */ | ||
2010 | |||
2011 | static struct i2c_driver dme1737_i2c_driver; | ||
2012 | |||
2013 | static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | ||
2014 | { | ||
2015 | int err = 0, reg; | ||
2016 | u16 addr; | ||
2017 | |||
2018 | dme1737_sio_enter(sio_cip); | ||
2019 | |||
2020 | /* Check device ID | ||
2021 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | ||
2022 | reg = dme1737_sio_inb(sio_cip, 0x20); | ||
2023 | if (!(reg == 0x77 || reg == 0x78)) { | ||
2024 | err = -ENODEV; | ||
2025 | goto exit; | ||
2026 | } | ||
2027 | |||
2028 | /* Select logical device A (runtime registers) */ | ||
2029 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | ||
2030 | |||
2031 | /* Get the base address of the runtime registers */ | ||
2032 | if (!(addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | ||
2033 | dme1737_sio_inb(sio_cip, 0x61))) { | ||
2034 | err = -ENODEV; | ||
2035 | goto exit; | ||
2036 | } | ||
2037 | |||
2038 | /* Read the runtime registers to determine which optional features | ||
2039 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | ||
2040 | * to '10' if the respective feature is enabled. */ | ||
2041 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | ||
2042 | data->has_fan |= (1 << 5); | ||
2043 | } | ||
2044 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | ||
2045 | data->has_pwm |= (1 << 5); | ||
2046 | } | ||
2047 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | ||
2048 | data->has_fan |= (1 << 4); | ||
2049 | } | ||
2050 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | ||
2051 | data->has_pwm |= (1 << 4); | ||
2052 | } | ||
2053 | |||
2054 | exit: | ||
2055 | dme1737_sio_exit(sio_cip); | ||
2056 | |||
2057 | return err; | ||
2058 | } | ||
2059 | |||
2060 | static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | ||
2061 | int kind) | ||
1877 | { | 2062 | { |
1878 | u8 company, verstep = 0; | 2063 | u8 company, verstep = 0; |
1879 | struct i2c_client *client; | 2064 | struct i2c_client *client; |
1880 | struct dme1737_data *data; | 2065 | struct dme1737_data *data; |
1881 | int ix, err = 0; | 2066 | struct device *dev; |
2067 | int err = 0; | ||
1882 | const char *name; | 2068 | const char *name; |
1883 | 2069 | ||
1884 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 2070 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
@@ -1894,7 +2080,8 @@ static int dme1737_detect(struct i2c_adapter *adapter, int address, | |||
1894 | i2c_set_clientdata(client, data); | 2080 | i2c_set_clientdata(client, data); |
1895 | client->addr = address; | 2081 | client->addr = address; |
1896 | client->adapter = adapter; | 2082 | client->adapter = adapter; |
1897 | client->driver = &dme1737_driver; | 2083 | client->driver = &dme1737_i2c_driver; |
2084 | dev = &client->dev; | ||
1898 | 2085 | ||
1899 | /* A negative kind means that the driver was loaded with no force | 2086 | /* A negative kind means that the driver was loaded with no force |
1900 | * parameter (default), so we must identify the chip. */ | 2087 | * parameter (default), so we must identify the chip. */ |
@@ -1922,92 +2109,33 @@ static int dme1737_detect(struct i2c_adapter *adapter, int address, | |||
1922 | goto exit_kfree; | 2109 | goto exit_kfree; |
1923 | } | 2110 | } |
1924 | 2111 | ||
2112 | dev_info(dev, "Found a DME1737 chip at 0x%02x (rev 0x%02x).\n", | ||
2113 | client->addr, verstep); | ||
2114 | |||
1925 | /* Initialize the DME1737 chip */ | 2115 | /* Initialize the DME1737 chip */ |
1926 | if ((err = dme1737_init_client(client))) { | 2116 | if ((err = dme1737_init_device(dev))) { |
2117 | dev_err(dev, "Failed to initialize device.\n"); | ||
1927 | goto exit_detach; | 2118 | goto exit_detach; |
1928 | } | 2119 | } |
1929 | 2120 | ||
1930 | /* Create standard sysfs attributes */ | 2121 | /* Create sysfs files */ |
1931 | if ((err = sysfs_create_group(&client->dev.kobj, &dme1737_group))) { | 2122 | if ((err = dme1737_create_files(dev))) { |
1932 | goto exit_detach; | 2123 | dev_err(dev, "Failed to create sysfs files.\n"); |
1933 | } | 2124 | goto exit_detach; |
1934 | |||
1935 | /* Create fan sysfs attributes */ | ||
1936 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
1937 | if (data->has_fan & (1 << ix)) { | ||
1938 | if ((err = sysfs_create_group(&client->dev.kobj, | ||
1939 | &dme1737_fan_group[ix]))) { | ||
1940 | goto exit_remove; | ||
1941 | } | ||
1942 | } | ||
1943 | } | ||
1944 | |||
1945 | /* Create PWM sysfs attributes */ | ||
1946 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
1947 | if (data->has_pwm & (1 << ix)) { | ||
1948 | if ((err = sysfs_create_group(&client->dev.kobj, | ||
1949 | &dme1737_pwm_group[ix]))) { | ||
1950 | goto exit_remove; | ||
1951 | } | ||
1952 | } | ||
1953 | } | ||
1954 | |||
1955 | /* Inform if the device is locked. Otherwise change the permissions of | ||
1956 | * selected attributes from read-only to read-writeable. */ | ||
1957 | if (data->config & 0x02) { | ||
1958 | dev_info(&client->dev, "Device is locked. Some attributes " | ||
1959 | "will be read-only.\n"); | ||
1960 | } else { | ||
1961 | /* Change permissions of standard attributes */ | ||
1962 | dme1737_chmod_group(client, &dme1737_lock_group, | ||
1963 | S_IRUGO | S_IWUSR); | ||
1964 | |||
1965 | /* Change permissions of PWM attributes */ | ||
1966 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { | ||
1967 | if (data->has_pwm & (1 << ix)) { | ||
1968 | dme1737_chmod_group(client, | ||
1969 | &dme1737_pwm_lock_group[ix], | ||
1970 | S_IRUGO | S_IWUSR); | ||
1971 | } | ||
1972 | } | ||
1973 | |||
1974 | /* Change permissions of pwm[1-3] if in manual mode */ | ||
1975 | for (ix = 0; ix < 3; ix++) { | ||
1976 | if ((data->has_pwm & (1 << ix)) && | ||
1977 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | ||
1978 | dme1737_chmod_file(client, | ||
1979 | dme1737_attr_pwm[ix], | ||
1980 | S_IRUGO | S_IWUSR); | ||
1981 | } | ||
1982 | } | ||
1983 | } | 2125 | } |
1984 | 2126 | ||
1985 | /* Register device */ | 2127 | /* Register device */ |
1986 | data->class_dev = hwmon_device_register(&client->dev); | 2128 | data->hwmon_dev = hwmon_device_register(dev); |
1987 | if (IS_ERR(data->class_dev)) { | 2129 | if (IS_ERR(data->hwmon_dev)) { |
1988 | err = PTR_ERR(data->class_dev); | 2130 | dev_err(dev, "Failed to register device.\n"); |
2131 | err = PTR_ERR(data->hwmon_dev); | ||
1989 | goto exit_remove; | 2132 | goto exit_remove; |
1990 | } | 2133 | } |
1991 | 2134 | ||
1992 | dev_info(&adapter->dev, "Found a DME1737 chip at 0x%02x " | ||
1993 | "(rev 0x%02x)\n", client->addr, verstep); | ||
1994 | |||
1995 | return 0; | 2135 | return 0; |
1996 | 2136 | ||
1997 | exit_remove: | 2137 | exit_remove: |
1998 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2138 | dme1737_remove_files(dev); |
1999 | if (data->has_fan & (1 << ix)) { | ||
2000 | sysfs_remove_group(&client->dev.kobj, | ||
2001 | &dme1737_fan_group[ix]); | ||
2002 | } | ||
2003 | } | ||
2004 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
2005 | if (data->has_pwm & (1 << ix)) { | ||
2006 | sysfs_remove_group(&client->dev.kobj, | ||
2007 | &dme1737_pwm_group[ix]); | ||
2008 | } | ||
2009 | } | ||
2010 | sysfs_remove_group(&client->dev.kobj, &dme1737_group); | ||
2011 | exit_detach: | 2139 | exit_detach: |
2012 | i2c_detach_client(client); | 2140 | i2c_detach_client(client); |
2013 | exit_kfree: | 2141 | exit_kfree: |
@@ -2016,60 +2144,260 @@ exit: | |||
2016 | return err; | 2144 | return err; |
2017 | } | 2145 | } |
2018 | 2146 | ||
2019 | static int dme1737_attach_adapter(struct i2c_adapter *adapter) | 2147 | static int dme1737_i2c_attach_adapter(struct i2c_adapter *adapter) |
2020 | { | 2148 | { |
2021 | if (!(adapter->class & I2C_CLASS_HWMON)) { | 2149 | if (!(adapter->class & I2C_CLASS_HWMON)) { |
2022 | return 0; | 2150 | return 0; |
2023 | } | 2151 | } |
2024 | 2152 | ||
2025 | return i2c_probe(adapter, &addr_data, dme1737_detect); | 2153 | return i2c_probe(adapter, &addr_data, dme1737_i2c_detect); |
2026 | } | 2154 | } |
2027 | 2155 | ||
2028 | static int dme1737_detach_client(struct i2c_client *client) | 2156 | static int dme1737_i2c_detach_client(struct i2c_client *client) |
2029 | { | 2157 | { |
2030 | struct dme1737_data *data = i2c_get_clientdata(client); | 2158 | struct dme1737_data *data = i2c_get_clientdata(client); |
2031 | int ix, err; | 2159 | int err; |
2032 | 2160 | ||
2033 | hwmon_device_unregister(data->class_dev); | 2161 | hwmon_device_unregister(data->hwmon_dev); |
2162 | dme1737_remove_files(&client->dev); | ||
2034 | 2163 | ||
2035 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2164 | if ((err = i2c_detach_client(client))) { |
2036 | if (data->has_fan & (1 << ix)) { | 2165 | return err; |
2037 | sysfs_remove_group(&client->dev.kobj, | ||
2038 | &dme1737_fan_group[ix]); | ||
2039 | } | ||
2040 | } | 2166 | } |
2041 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 2167 | |
2042 | if (data->has_pwm & (1 << ix)) { | 2168 | kfree(data); |
2043 | sysfs_remove_group(&client->dev.kobj, | 2169 | return 0; |
2044 | &dme1737_pwm_group[ix]); | 2170 | } |
2045 | } | 2171 | |
2172 | static struct i2c_driver dme1737_i2c_driver = { | ||
2173 | .driver = { | ||
2174 | .name = "dme1737", | ||
2175 | }, | ||
2176 | .attach_adapter = dme1737_i2c_attach_adapter, | ||
2177 | .detach_client = dme1737_i2c_detach_client, | ||
2178 | }; | ||
2179 | |||
2180 | /* --------------------------------------------------------------------- | ||
2181 | * ISA device detection and registration | ||
2182 | * --------------------------------------------------------------------- */ | ||
2183 | |||
2184 | static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) | ||
2185 | { | ||
2186 | int err = 0, reg; | ||
2187 | unsigned short base_addr; | ||
2188 | |||
2189 | dme1737_sio_enter(sio_cip); | ||
2190 | |||
2191 | /* Check device ID | ||
2192 | * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and | ||
2193 | * SCH3116 (0x7f). */ | ||
2194 | reg = dme1737_sio_inb(sio_cip, 0x20); | ||
2195 | if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { | ||
2196 | err = -ENODEV; | ||
2197 | goto exit; | ||
2046 | } | 2198 | } |
2047 | sysfs_remove_group(&client->dev.kobj, &dme1737_group); | ||
2048 | 2199 | ||
2049 | if ((err = i2c_detach_client(client))) { | 2200 | /* Select logical device A (runtime registers) */ |
2050 | return err; | 2201 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); |
2202 | |||
2203 | /* Get the base address of the runtime registers */ | ||
2204 | if (!(base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | ||
2205 | dme1737_sio_inb(sio_cip, 0x61))) { | ||
2206 | printk(KERN_ERR "dme1737: Base address not set.\n"); | ||
2207 | err = -ENODEV; | ||
2208 | goto exit; | ||
2209 | } | ||
2210 | |||
2211 | /* Access to the hwmon registers is through an index/data register | ||
2212 | * pair located at offset 0x70/0x71. */ | ||
2213 | *addr = base_addr + 0x70; | ||
2214 | |||
2215 | exit: | ||
2216 | dme1737_sio_exit(sio_cip); | ||
2217 | return err; | ||
2218 | } | ||
2219 | |||
2220 | static int __init dme1737_isa_device_add(unsigned short addr) | ||
2221 | { | ||
2222 | struct resource res = { | ||
2223 | .start = addr, | ||
2224 | .end = addr + DME1737_EXTENT - 1, | ||
2225 | .name = "dme1737", | ||
2226 | .flags = IORESOURCE_IO, | ||
2227 | }; | ||
2228 | int err; | ||
2229 | |||
2230 | if (!(pdev = platform_device_alloc("dme1737", addr))) { | ||
2231 | printk(KERN_ERR "dme1737: Failed to allocate device.\n"); | ||
2232 | err = -ENOMEM; | ||
2233 | goto exit; | ||
2234 | } | ||
2235 | |||
2236 | if ((err = platform_device_add_resources(pdev, &res, 1))) { | ||
2237 | printk(KERN_ERR "dme1737: Failed to add device resource " | ||
2238 | "(err = %d).\n", err); | ||
2239 | goto exit_device_put; | ||
2240 | } | ||
2241 | |||
2242 | if ((err = platform_device_add(pdev))) { | ||
2243 | printk(KERN_ERR "dme1737: Failed to add device (err = %d).\n", | ||
2244 | err); | ||
2245 | goto exit_device_put; | ||
2246 | } | ||
2247 | |||
2248 | return 0; | ||
2249 | |||
2250 | exit_device_put: | ||
2251 | platform_device_put(pdev); | ||
2252 | pdev = NULL; | ||
2253 | exit: | ||
2254 | return err; | ||
2255 | } | ||
2256 | |||
2257 | static int __devinit dme1737_isa_probe(struct platform_device *pdev) | ||
2258 | { | ||
2259 | u8 company, device; | ||
2260 | struct resource *res; | ||
2261 | struct i2c_client *client; | ||
2262 | struct dme1737_data *data; | ||
2263 | struct device *dev = &pdev->dev; | ||
2264 | int err; | ||
2265 | |||
2266 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
2267 | if (!request_region(res->start, DME1737_EXTENT, "dme1737")) { | ||
2268 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", | ||
2269 | (unsigned short)res->start, | ||
2270 | (unsigned short)res->start + DME1737_EXTENT - 1); | ||
2271 | err = -EBUSY; | ||
2272 | goto exit; | ||
2273 | } | ||
2274 | |||
2275 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | ||
2276 | err = -ENOMEM; | ||
2277 | goto exit_release_region; | ||
2278 | } | ||
2279 | |||
2280 | client = &data->client; | ||
2281 | i2c_set_clientdata(client, data); | ||
2282 | client->addr = res->start; | ||
2283 | platform_set_drvdata(pdev, data); | ||
2284 | |||
2285 | company = dme1737_read(client, DME1737_REG_COMPANY); | ||
2286 | device = dme1737_read(client, DME1737_REG_DEVICE); | ||
2287 | |||
2288 | if (!((company == DME1737_COMPANY_SMSC) && | ||
2289 | (device == SCH311X_DEVICE))) { | ||
2290 | err = -ENODEV; | ||
2291 | goto exit_kfree; | ||
2292 | } | ||
2293 | |||
2294 | /* Fill in the remaining client fields and initialize the mutex */ | ||
2295 | strlcpy(client->name, "sch311x", I2C_NAME_SIZE); | ||
2296 | mutex_init(&data->update_lock); | ||
2297 | |||
2298 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", client->addr); | ||
2299 | |||
2300 | /* Initialize the chip */ | ||
2301 | if ((err = dme1737_init_device(dev))) { | ||
2302 | dev_err(dev, "Failed to initialize device.\n"); | ||
2303 | goto exit_kfree; | ||
2051 | } | 2304 | } |
2052 | 2305 | ||
2306 | /* Create sysfs files */ | ||
2307 | if ((err = dme1737_create_files(dev))) { | ||
2308 | dev_err(dev, "Failed to create sysfs files.\n"); | ||
2309 | goto exit_kfree; | ||
2310 | } | ||
2311 | |||
2312 | /* Register device */ | ||
2313 | data->hwmon_dev = hwmon_device_register(dev); | ||
2314 | if (IS_ERR(data->hwmon_dev)) { | ||
2315 | dev_err(dev, "Failed to register device.\n"); | ||
2316 | err = PTR_ERR(data->hwmon_dev); | ||
2317 | goto exit_remove_files; | ||
2318 | } | ||
2319 | |||
2320 | return 0; | ||
2321 | |||
2322 | exit_remove_files: | ||
2323 | dme1737_remove_files(dev); | ||
2324 | exit_kfree: | ||
2325 | platform_set_drvdata(pdev, NULL); | ||
2326 | kfree(data); | ||
2327 | exit_release_region: | ||
2328 | release_region(res->start, DME1737_EXTENT); | ||
2329 | exit: | ||
2330 | return err; | ||
2331 | } | ||
2332 | |||
2333 | static int __devexit dme1737_isa_remove(struct platform_device *pdev) | ||
2334 | { | ||
2335 | struct dme1737_data *data = platform_get_drvdata(pdev); | ||
2336 | |||
2337 | hwmon_device_unregister(data->hwmon_dev); | ||
2338 | dme1737_remove_files(&pdev->dev); | ||
2339 | release_region(data->client.addr, DME1737_EXTENT); | ||
2340 | platform_set_drvdata(pdev, NULL); | ||
2053 | kfree(data); | 2341 | kfree(data); |
2342 | |||
2054 | return 0; | 2343 | return 0; |
2055 | } | 2344 | } |
2056 | 2345 | ||
2057 | static struct i2c_driver dme1737_driver = { | 2346 | static struct platform_driver dme1737_isa_driver = { |
2058 | .driver = { | 2347 | .driver = { |
2348 | .owner = THIS_MODULE, | ||
2059 | .name = "dme1737", | 2349 | .name = "dme1737", |
2060 | }, | 2350 | }, |
2061 | .attach_adapter = dme1737_attach_adapter, | 2351 | .probe = dme1737_isa_probe, |
2062 | .detach_client = dme1737_detach_client, | 2352 | .remove = __devexit_p(dme1737_isa_remove), |
2063 | }; | 2353 | }; |
2064 | 2354 | ||
2355 | /* --------------------------------------------------------------------- | ||
2356 | * Module initialization and cleanup | ||
2357 | * --------------------------------------------------------------------- */ | ||
2358 | |||
2065 | static int __init dme1737_init(void) | 2359 | static int __init dme1737_init(void) |
2066 | { | 2360 | { |
2067 | return i2c_add_driver(&dme1737_driver); | 2361 | int err; |
2362 | unsigned short addr; | ||
2363 | |||
2364 | if ((err = i2c_add_driver(&dme1737_i2c_driver))) { | ||
2365 | goto exit; | ||
2366 | } | ||
2367 | |||
2368 | if (dme1737_isa_detect(0x2e, &addr) && | ||
2369 | dme1737_isa_detect(0x4e, &addr)) { | ||
2370 | /* Return 0 if we didn't find an ISA device */ | ||
2371 | return 0; | ||
2372 | } | ||
2373 | |||
2374 | if ((err = platform_driver_register(&dme1737_isa_driver))) { | ||
2375 | goto exit_del_i2c_driver; | ||
2376 | } | ||
2377 | |||
2378 | /* Sets global pdev as a side effect */ | ||
2379 | if ((err = dme1737_isa_device_add(addr))) { | ||
2380 | goto exit_del_isa_driver; | ||
2381 | } | ||
2382 | |||
2383 | return 0; | ||
2384 | |||
2385 | exit_del_isa_driver: | ||
2386 | platform_driver_unregister(&dme1737_isa_driver); | ||
2387 | exit_del_i2c_driver: | ||
2388 | i2c_del_driver(&dme1737_i2c_driver); | ||
2389 | exit: | ||
2390 | return err; | ||
2068 | } | 2391 | } |
2069 | 2392 | ||
2070 | static void __exit dme1737_exit(void) | 2393 | static void __exit dme1737_exit(void) |
2071 | { | 2394 | { |
2072 | i2c_del_driver(&dme1737_driver); | 2395 | if (pdev) { |
2396 | platform_device_unregister(pdev); | ||
2397 | platform_driver_unregister(&dme1737_isa_driver); | ||
2398 | } | ||
2399 | |||
2400 | i2c_del_driver(&dme1737_i2c_driver); | ||
2073 | } | 2401 | } |
2074 | 2402 | ||
2075 | MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>"); | 2403 | MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>"); |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 1212d6b7f316..b7bd000b130f 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -73,7 +73,7 @@ static const u8 DS1621_REG_TEMP[3] = { | |||
73 | /* Each client has this additional data */ | 73 | /* Each client has this additional data */ |
74 | struct ds1621_data { | 74 | struct ds1621_data { |
75 | struct i2c_client client; | 75 | struct i2c_client client; |
76 | struct class_device *class_dev; | 76 | struct device *hwmon_dev; |
77 | struct mutex update_lock; | 77 | struct mutex update_lock; |
78 | char valid; /* !=0 if following fields are valid */ | 78 | char valid; /* !=0 if following fields are valid */ |
79 | unsigned long last_updated; /* In jiffies */ | 79 | unsigned long last_updated; /* In jiffies */ |
@@ -151,7 +151,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
152 | struct i2c_client *client = to_i2c_client(dev); | 152 | struct i2c_client *client = to_i2c_client(dev); |
153 | struct ds1621_data *data = ds1621_update_client(dev); | 153 | struct ds1621_data *data = ds1621_update_client(dev); |
154 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); | 154 | u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10)); |
155 | 155 | ||
156 | mutex_lock(&data->update_lock); | 156 | mutex_lock(&data->update_lock); |
157 | data->temp[attr->index] = val; | 157 | data->temp[attr->index] = val; |
@@ -266,9 +266,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) | 266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) |
267 | goto exit_detach; | 267 | goto exit_detach; |
268 | 268 | ||
269 | data->class_dev = hwmon_device_register(&client->dev); | 269 | data->hwmon_dev = hwmon_device_register(&client->dev); |
270 | if (IS_ERR(data->class_dev)) { | 270 | if (IS_ERR(data->hwmon_dev)) { |
271 | err = PTR_ERR(data->class_dev); | 271 | err = PTR_ERR(data->hwmon_dev); |
272 | goto exit_remove_files; | 272 | goto exit_remove_files; |
273 | } | 273 | } |
274 | 274 | ||
@@ -289,7 +289,7 @@ static int ds1621_detach_client(struct i2c_client *client) | |||
289 | struct ds1621_data *data = i2c_get_clientdata(client); | 289 | struct ds1621_data *data = i2c_get_clientdata(client); |
290 | int err; | 290 | int err; |
291 | 291 | ||
292 | hwmon_device_unregister(data->class_dev); | 292 | hwmon_device_unregister(data->hwmon_dev); |
293 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); | 293 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); |
294 | 294 | ||
295 | if ((err = i2c_detach_client(client))) | 295 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 6f60715f34f8..5d9d5cc816a2 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * The F71872F/FG is almost the same, with two more voltages monitored, | 10 | * The F71872F/FG is almost the same, with two more voltages monitored, |
11 | * and 6 VID inputs. | 11 | * and 6 VID inputs. |
12 | * | 12 | * |
13 | * The F71806F/FG is essentially the same as the F71872F/FG. It even has | ||
14 | * the same chip ID, so the driver can't differentiate between. | ||
15 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | 16 | * 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 | 17 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2 of the License, or | 18 | * the Free Software Foundation; either version 2 of the License, or |
@@ -159,7 +162,7 @@ struct f71805f_auto_point { | |||
159 | struct f71805f_data { | 162 | struct f71805f_data { |
160 | unsigned short addr; | 163 | unsigned short addr; |
161 | const char *name; | 164 | const char *name; |
162 | struct class_device *class_dev; | 165 | struct device *hwmon_dev; |
163 | 166 | ||
164 | struct mutex update_lock; | 167 | struct mutex update_lock; |
165 | char valid; /* !=0 if following fields are valid */ | 168 | char valid; /* !=0 if following fields are valid */ |
@@ -1378,9 +1381,9 @@ static int __devinit f71805f_probe(struct platform_device *pdev) | |||
1378 | } | 1381 | } |
1379 | } | 1382 | } |
1380 | 1383 | ||
1381 | data->class_dev = hwmon_device_register(&pdev->dev); | 1384 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1382 | if (IS_ERR(data->class_dev)) { | 1385 | if (IS_ERR(data->hwmon_dev)) { |
1383 | err = PTR_ERR(data->class_dev); | 1386 | err = PTR_ERR(data->hwmon_dev); |
1384 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | 1387 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); |
1385 | goto exit_remove_files; | 1388 | goto exit_remove_files; |
1386 | } | 1389 | } |
@@ -1407,7 +1410,7 @@ static int __devexit f71805f_remove(struct platform_device *pdev) | |||
1407 | struct resource *res; | 1410 | struct resource *res; |
1408 | int i; | 1411 | int i; |
1409 | 1412 | ||
1410 | hwmon_device_unregister(data->class_dev); | 1413 | hwmon_device_unregister(data->hwmon_dev); |
1411 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); | 1414 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); |
1412 | for (i = 0; i < 4; i++) | 1415 | for (i = 0; i < 4; i++) |
1413 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); | 1416 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); |
@@ -1485,7 +1488,7 @@ static int __init f71805f_find(int sioaddr, unsigned short *address, | |||
1485 | 1488 | ||
1486 | static const char *names[] = { | 1489 | static const char *names[] = { |
1487 | "F71805F/FG", | 1490 | "F71805F/FG", |
1488 | "F71872F/FG", | 1491 | "F71872F/FG or F71806F/FG", |
1489 | }; | 1492 | }; |
1490 | 1493 | ||
1491 | superio_enter(sioaddr); | 1494 | superio_enter(sioaddr); |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c new file mode 100644 index 000000000000..6db74434a02e --- /dev/null +++ b/drivers/hwmon/f71882fg.c | |||
@@ -0,0 +1,950 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * | ||
3 | * Copyright (C) 2007 by Hans de Goede <j.w.r.degoede@hhs.nl> * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | * * | ||
10 | * This program is distributed in the hope that it will be useful, * | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
13 | * GNU General Public License for more details. * | ||
14 | * * | ||
15 | * You should have received a copy of the GNU General Public License * | ||
16 | * along with this program; if not, write to the * | ||
17 | * Free Software Foundation, Inc., * | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
19 | ***************************************************************************/ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/hwmon.h> | ||
27 | #include <linux/hwmon-sysfs.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include <asm/io.h> | ||
31 | |||
32 | #define DRVNAME "f71882fg" | ||
33 | |||
34 | #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device*/ | ||
35 | #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ | ||
36 | #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ | ||
37 | |||
38 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
39 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
40 | #define SIO_REG_DEVREV 0x22 /* Device revision */ | ||
41 | #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ | ||
42 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
43 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
44 | |||
45 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | ||
46 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | ||
47 | |||
48 | #define REGION_LENGTH 8 | ||
49 | #define ADDR_REG_OFFSET 5 | ||
50 | #define DATA_REG_OFFSET 6 | ||
51 | |||
52 | #define F71882FG_REG_PECI 0x0A | ||
53 | |||
54 | #define F71882FG_REG_IN_STATUS 0x12 | ||
55 | #define F71882FG_REG_IN_BEEP 0x13 | ||
56 | #define F71882FG_REG_IN(nr) (0x20 + (nr)) | ||
57 | #define F71882FG_REG_IN1_HIGH 0x32 | ||
58 | |||
59 | #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) | ||
60 | #define F71882FG_REG_FAN_STATUS 0x92 | ||
61 | #define F71882FG_REG_FAN_BEEP 0x93 | ||
62 | |||
63 | #define F71882FG_REG_TEMP(nr) (0x72 + 2 * (nr)) | ||
64 | #define F71882FG_REG_TEMP_OVT(nr) (0x82 + 2 * (nr)) | ||
65 | #define F71882FG_REG_TEMP_HIGH(nr) (0x83 + 2 * (nr)) | ||
66 | #define F71882FG_REG_TEMP_STATUS 0x62 | ||
67 | #define F71882FG_REG_TEMP_BEEP 0x63 | ||
68 | #define F71882FG_REG_TEMP_HYST1 0x6C | ||
69 | #define F71882FG_REG_TEMP_HYST23 0x6D | ||
70 | #define F71882FG_REG_TEMP_TYPE 0x6B | ||
71 | #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F | ||
72 | |||
73 | #define F71882FG_REG_START 0x01 | ||
74 | |||
75 | #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ | ||
76 | |||
77 | static struct platform_device *f71882fg_pdev = NULL; | ||
78 | |||
79 | /* Super-I/O Function prototypes */ | ||
80 | static inline int superio_inb(int base, int reg); | ||
81 | static inline int superio_inw(int base, int reg); | ||
82 | static inline void superio_enter(int base); | ||
83 | static inline void superio_select(int base, int ld); | ||
84 | static inline void superio_exit(int base); | ||
85 | |||
86 | static inline u16 fan_from_reg ( u16 reg ); | ||
87 | |||
88 | struct f71882fg_data { | ||
89 | unsigned short addr; | ||
90 | struct device *hwmon_dev; | ||
91 | |||
92 | struct mutex update_lock; | ||
93 | char valid; /* !=0 if following fields are valid */ | ||
94 | unsigned long last_updated; /* In jiffies */ | ||
95 | unsigned long last_limits; /* In jiffies */ | ||
96 | |||
97 | /* Register Values */ | ||
98 | u8 in[9]; | ||
99 | u8 in1_max; | ||
100 | u8 in_status; | ||
101 | u8 in_beep; | ||
102 | u16 fan[4]; | ||
103 | u8 fan_status; | ||
104 | u8 fan_beep; | ||
105 | u8 temp[3]; | ||
106 | u8 temp_ovt[3]; | ||
107 | u8 temp_high[3]; | ||
108 | u8 temp_hyst[3]; | ||
109 | u8 temp_type[3]; | ||
110 | u8 temp_status; | ||
111 | u8 temp_beep; | ||
112 | u8 temp_diode_open; | ||
113 | }; | ||
114 | |||
115 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg); | ||
116 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg); | ||
117 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val); | ||
118 | |||
119 | /* Sysfs in*/ | ||
120 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
121 | char *buf); | ||
122 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
123 | *devattr, char *buf); | ||
124 | static ssize_t store_in_max(struct device *dev, struct device_attribute | ||
125 | *devattr, const char *buf, size_t count); | ||
126 | static ssize_t show_in_beep(struct device *dev, struct device_attribute | ||
127 | *devattr, char *buf); | ||
128 | static ssize_t store_in_beep(struct device *dev, struct device_attribute | ||
129 | *devattr, const char *buf, size_t count); | ||
130 | static ssize_t show_in_alarm(struct device *dev, struct device_attribute | ||
131 | *devattr, char *buf); | ||
132 | /* Sysfs Fan */ | ||
133 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
134 | char *buf); | ||
135 | static ssize_t show_fan_beep(struct device *dev, struct device_attribute | ||
136 | *devattr, char *buf); | ||
137 | static ssize_t store_fan_beep(struct device *dev, struct device_attribute | ||
138 | *devattr, const char *buf, size_t count); | ||
139 | static ssize_t show_fan_alarm(struct device *dev, struct device_attribute | ||
140 | *devattr, char *buf); | ||
141 | /* Sysfs Temp */ | ||
142 | static ssize_t show_temp(struct device *dev, struct device_attribute | ||
143 | *devattr, char *buf); | ||
144 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
145 | *devattr, char *buf); | ||
146 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
147 | *devattr, const char *buf, size_t count); | ||
148 | static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute | ||
149 | *devattr, char *buf); | ||
150 | static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | ||
151 | *devattr, const char *buf, size_t count); | ||
152 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute | ||
153 | *devattr, char *buf); | ||
154 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
155 | *devattr, const char *buf, size_t count); | ||
156 | static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute | ||
157 | *devattr, char *buf); | ||
158 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
159 | *devattr, char *buf); | ||
160 | static ssize_t show_temp_beep(struct device *dev, struct device_attribute | ||
161 | *devattr, char *buf); | ||
162 | static ssize_t store_temp_beep(struct device *dev, struct device_attribute | ||
163 | *devattr, const char *buf, size_t count); | ||
164 | static ssize_t show_temp_alarm(struct device *dev, struct device_attribute | ||
165 | *devattr, char *buf); | ||
166 | static ssize_t show_temp_fault(struct device *dev, struct device_attribute | ||
167 | *devattr, char *buf); | ||
168 | /* Sysfs misc */ | ||
169 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
170 | char *buf); | ||
171 | |||
172 | static int __devinit f71882fg_probe(struct platform_device * pdev); | ||
173 | static int __devexit f71882fg_remove(struct platform_device *pdev); | ||
174 | static int __init f71882fg_init(void); | ||
175 | static int __init f71882fg_find(int sioaddr, unsigned short *address); | ||
176 | static int __init f71882fg_device_add(unsigned short address); | ||
177 | static void __exit f71882fg_exit(void); | ||
178 | |||
179 | static struct platform_driver f71882fg_driver = { | ||
180 | .driver = { | ||
181 | .owner = THIS_MODULE, | ||
182 | .name = DRVNAME, | ||
183 | }, | ||
184 | .probe = f71882fg_probe, | ||
185 | .remove = __devexit_p(f71882fg_remove), | ||
186 | }; | ||
187 | |||
188 | static struct device_attribute f71882fg_dev_attr[] = | ||
189 | { | ||
190 | __ATTR( name, S_IRUGO, show_name, NULL ), | ||
191 | }; | ||
192 | |||
193 | static struct sensor_device_attribute f71882fg_in_temp_attr[] = | ||
194 | { | ||
195 | SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), | ||
196 | SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), | ||
197 | SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1), | ||
198 | SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1), | ||
199 | SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1), | ||
200 | SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), | ||
201 | SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), | ||
202 | SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), | ||
203 | SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), | ||
204 | SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), | ||
205 | SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), | ||
206 | SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), | ||
207 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), | ||
208 | SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
209 | store_temp_max, 0), | ||
210 | SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
211 | store_temp_max_hyst, 0), | ||
212 | SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
213 | store_temp_crit, 0), | ||
214 | SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0), | ||
215 | SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), | ||
216 | SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
217 | store_temp_beep, 0), | ||
218 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0), | ||
219 | SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), | ||
220 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), | ||
221 | SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
222 | store_temp_max, 1), | ||
223 | SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
224 | store_temp_max_hyst, 1), | ||
225 | SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
226 | store_temp_crit, 1), | ||
227 | SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), | ||
228 | SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), | ||
229 | SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
230 | store_temp_beep, 1), | ||
231 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1), | ||
232 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), | ||
233 | SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), | ||
234 | SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
235 | store_temp_max, 2), | ||
236 | SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
237 | store_temp_max_hyst, 2), | ||
238 | SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
239 | store_temp_crit, 2), | ||
240 | SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2), | ||
241 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | ||
242 | SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep, | ||
243 | store_temp_beep, 2), | ||
244 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2), | ||
245 | SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2) | ||
246 | }; | ||
247 | |||
248 | static struct sensor_device_attribute f71882fg_fan_attr[] = | ||
249 | { | ||
250 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), | ||
251 | SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
252 | store_fan_beep, 0), | ||
253 | SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0), | ||
254 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), | ||
255 | SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
256 | store_fan_beep, 1), | ||
257 | SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1), | ||
258 | SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), | ||
259 | SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
260 | store_fan_beep, 2), | ||
261 | SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2), | ||
262 | SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), | ||
263 | SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
264 | store_fan_beep, 3), | ||
265 | SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3) | ||
266 | }; | ||
267 | |||
268 | |||
269 | /* Super I/O functions */ | ||
270 | static inline int superio_inb(int base, int reg) | ||
271 | { | ||
272 | outb(reg, base); | ||
273 | return inb(base + 1); | ||
274 | } | ||
275 | |||
276 | static int superio_inw(int base, int reg) | ||
277 | { | ||
278 | int val; | ||
279 | outb(reg++, base); | ||
280 | val = inb(base + 1) << 8; | ||
281 | outb(reg, base); | ||
282 | val |= inb(base + 1); | ||
283 | return val; | ||
284 | } | ||
285 | |||
286 | static inline void superio_enter(int base) | ||
287 | { | ||
288 | /* according to the datasheet the key must be send twice! */ | ||
289 | outb( SIO_UNLOCK_KEY, base); | ||
290 | outb( SIO_UNLOCK_KEY, base); | ||
291 | } | ||
292 | |||
293 | static inline void superio_select( int base, int ld) | ||
294 | { | ||
295 | outb(SIO_REG_LDSEL, base); | ||
296 | outb(ld, base + 1); | ||
297 | } | ||
298 | |||
299 | static inline void superio_exit(int base) | ||
300 | { | ||
301 | outb(SIO_LOCK_KEY, base); | ||
302 | } | ||
303 | |||
304 | static inline u16 fan_from_reg(u16 reg) | ||
305 | { | ||
306 | return reg ? (1500000 / reg) : 0; | ||
307 | } | ||
308 | |||
309 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) | ||
310 | { | ||
311 | u8 val; | ||
312 | |||
313 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
314 | val = inb(data->addr + DATA_REG_OFFSET); | ||
315 | |||
316 | return val; | ||
317 | } | ||
318 | |||
319 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) | ||
320 | { | ||
321 | u16 val; | ||
322 | |||
323 | outb(reg++, data->addr + ADDR_REG_OFFSET); | ||
324 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | ||
325 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
326 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
327 | |||
328 | return val; | ||
329 | } | ||
330 | |||
331 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) | ||
332 | { | ||
333 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
334 | outb(val, data->addr + DATA_REG_OFFSET); | ||
335 | } | ||
336 | |||
337 | static struct f71882fg_data *f71882fg_update_device(struct device * dev) | ||
338 | { | ||
339 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
340 | int nr, reg, reg2; | ||
341 | |||
342 | mutex_lock(&data->update_lock); | ||
343 | |||
344 | /* Update once every 60 seconds */ | ||
345 | if ( time_after(jiffies, data->last_limits + 60 * HZ ) || | ||
346 | !data->valid) { | ||
347 | data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH); | ||
348 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); | ||
349 | |||
350 | /* Get High & boundary temps*/ | ||
351 | for (nr = 0; nr < 3; nr++) { | ||
352 | data->temp_ovt[nr] = f71882fg_read8(data, | ||
353 | F71882FG_REG_TEMP_OVT(nr)); | ||
354 | data->temp_high[nr] = f71882fg_read8(data, | ||
355 | F71882FG_REG_TEMP_HIGH(nr)); | ||
356 | } | ||
357 | |||
358 | /* Have to hardcode hyst*/ | ||
359 | data->temp_hyst[0] = f71882fg_read8(data, | ||
360 | F71882FG_REG_TEMP_HYST1) >> 4; | ||
361 | /* Hyst temps 2 & 3 stored in same register */ | ||
362 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST23); | ||
363 | data->temp_hyst[1] = reg & 0x0F; | ||
364 | data->temp_hyst[2] = reg >> 4; | ||
365 | |||
366 | /* Have to hardcode type, because temp1 is special */ | ||
367 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); | ||
368 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); | ||
369 | if ((reg2 & 0x03) == 0x01) | ||
370 | data->temp_type[0] = 6 /* PECI */; | ||
371 | else if ((reg2 & 0x03) == 0x02) | ||
372 | data->temp_type[0] = 5 /* AMDSI */; | ||
373 | else | ||
374 | data->temp_type[0] = (reg & 0x02) ? 2 : 4; | ||
375 | |||
376 | data->temp_type[1] = (reg & 0x04) ? 2 : 4; | ||
377 | data->temp_type[2] = (reg & 0x08) ? 2 : 4; | ||
378 | |||
379 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); | ||
380 | |||
381 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); | ||
382 | |||
383 | data->last_limits = jiffies; | ||
384 | } | ||
385 | |||
386 | /* Update every second */ | ||
387 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
388 | data->temp_status = f71882fg_read8(data, | ||
389 | F71882FG_REG_TEMP_STATUS); | ||
390 | data->temp_diode_open = f71882fg_read8(data, | ||
391 | F71882FG_REG_TEMP_DIODE_OPEN); | ||
392 | for (nr = 0; nr < 3; nr++) | ||
393 | data->temp[nr] = f71882fg_read8(data, | ||
394 | F71882FG_REG_TEMP(nr)); | ||
395 | |||
396 | data->fan_status = f71882fg_read8(data, | ||
397 | F71882FG_REG_FAN_STATUS); | ||
398 | for (nr = 0; nr < 4; nr++) | ||
399 | data->fan[nr] = f71882fg_read16(data, | ||
400 | F71882FG_REG_FAN(nr)); | ||
401 | |||
402 | data->in_status = f71882fg_read8(data, | ||
403 | F71882FG_REG_IN_STATUS); | ||
404 | for (nr = 0; nr < 9; nr++) | ||
405 | data->in[nr] = f71882fg_read8(data, | ||
406 | F71882FG_REG_IN(nr)); | ||
407 | |||
408 | data->last_updated = jiffies; | ||
409 | data->valid = 1; | ||
410 | } | ||
411 | |||
412 | mutex_unlock(&data->update_lock); | ||
413 | |||
414 | return data; | ||
415 | } | ||
416 | |||
417 | /* Sysfs Interface */ | ||
418 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
419 | char *buf) | ||
420 | { | ||
421 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
422 | int nr = to_sensor_dev_attr(devattr)->index; | ||
423 | int speed = fan_from_reg(data->fan[nr]); | ||
424 | |||
425 | if (speed == FAN_MIN_DETECT) | ||
426 | speed = 0; | ||
427 | |||
428 | return sprintf(buf, "%d\n", speed); | ||
429 | } | ||
430 | |||
431 | static ssize_t show_fan_beep(struct device *dev, struct device_attribute | ||
432 | *devattr, char *buf) | ||
433 | { | ||
434 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
435 | int nr = to_sensor_dev_attr(devattr)->index; | ||
436 | |||
437 | if (data->fan_beep & (1 << nr)) | ||
438 | return sprintf(buf, "1\n"); | ||
439 | else | ||
440 | return sprintf(buf, "0\n"); | ||
441 | } | ||
442 | |||
443 | static ssize_t store_fan_beep(struct device *dev, struct device_attribute | ||
444 | *devattr, const char *buf, size_t count) | ||
445 | { | ||
446 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
447 | int nr = to_sensor_dev_attr(devattr)->index; | ||
448 | int val = simple_strtoul(buf, NULL, 10); | ||
449 | |||
450 | mutex_lock(&data->update_lock); | ||
451 | if (val) | ||
452 | data->fan_beep |= 1 << nr; | ||
453 | else | ||
454 | data->fan_beep &= ~(1 << nr); | ||
455 | |||
456 | f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep); | ||
457 | mutex_unlock(&data->update_lock); | ||
458 | |||
459 | return count; | ||
460 | } | ||
461 | |||
462 | static ssize_t show_fan_alarm(struct device *dev, struct device_attribute | ||
463 | *devattr, char *buf) | ||
464 | { | ||
465 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
466 | int nr = to_sensor_dev_attr(devattr)->index; | ||
467 | |||
468 | if (data->fan_status & (1 << nr)) | ||
469 | return sprintf(buf, "1\n"); | ||
470 | else | ||
471 | return sprintf(buf, "0\n"); | ||
472 | } | ||
473 | |||
474 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
475 | char *buf) | ||
476 | { | ||
477 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
478 | int nr = to_sensor_dev_attr(devattr)->index; | ||
479 | |||
480 | return sprintf(buf, "%d\n", data->in[nr] * 8); | ||
481 | } | ||
482 | |||
483 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
484 | *devattr, char *buf) | ||
485 | { | ||
486 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
487 | |||
488 | return sprintf(buf, "%d\n", data->in1_max * 8); | ||
489 | } | ||
490 | |||
491 | static ssize_t store_in_max(struct device *dev, struct device_attribute | ||
492 | *devattr, const char *buf, size_t count) | ||
493 | { | ||
494 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
495 | int val = simple_strtoul(buf, NULL, 10) / 8; | ||
496 | |||
497 | if (val > 255) | ||
498 | val = 255; | ||
499 | |||
500 | mutex_lock(&data->update_lock); | ||
501 | f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); | ||
502 | data->in1_max = val; | ||
503 | mutex_unlock(&data->update_lock); | ||
504 | |||
505 | return count; | ||
506 | } | ||
507 | |||
508 | static ssize_t show_in_beep(struct device *dev, struct device_attribute | ||
509 | *devattr, char *buf) | ||
510 | { | ||
511 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
512 | int nr = to_sensor_dev_attr(devattr)->index; | ||
513 | |||
514 | if (data->in_beep & (1 << nr)) | ||
515 | return sprintf(buf, "1\n"); | ||
516 | else | ||
517 | return sprintf(buf, "0\n"); | ||
518 | } | ||
519 | |||
520 | static ssize_t store_in_beep(struct device *dev, struct device_attribute | ||
521 | *devattr, const char *buf, size_t count) | ||
522 | { | ||
523 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
524 | int nr = to_sensor_dev_attr(devattr)->index; | ||
525 | int val = simple_strtoul(buf, NULL, 10); | ||
526 | |||
527 | mutex_lock(&data->update_lock); | ||
528 | if (val) | ||
529 | data->in_beep |= 1 << nr; | ||
530 | else | ||
531 | data->in_beep &= ~(1 << nr); | ||
532 | |||
533 | f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep); | ||
534 | mutex_unlock(&data->update_lock); | ||
535 | |||
536 | return count; | ||
537 | } | ||
538 | |||
539 | static ssize_t show_in_alarm(struct device *dev, struct device_attribute | ||
540 | *devattr, char *buf) | ||
541 | { | ||
542 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
543 | int nr = to_sensor_dev_attr(devattr)->index; | ||
544 | |||
545 | if (data->in_status & (1 << nr)) | ||
546 | return sprintf(buf, "1\n"); | ||
547 | else | ||
548 | return sprintf(buf, "0\n"); | ||
549 | } | ||
550 | |||
551 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
552 | char *buf) | ||
553 | { | ||
554 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
555 | int nr = to_sensor_dev_attr(devattr)->index; | ||
556 | |||
557 | return sprintf(buf, "%d\n", data->temp[nr] * 1000); | ||
558 | } | ||
559 | |||
560 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
561 | *devattr, char *buf) | ||
562 | { | ||
563 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
564 | int nr = to_sensor_dev_attr(devattr)->index; | ||
565 | |||
566 | return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); | ||
567 | } | ||
568 | |||
569 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
570 | *devattr, const char *buf, size_t count) | ||
571 | { | ||
572 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
573 | int nr = to_sensor_dev_attr(devattr)->index; | ||
574 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
575 | |||
576 | if (val > 255) | ||
577 | val = 255; | ||
578 | |||
579 | mutex_lock(&data->update_lock); | ||
580 | f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); | ||
581 | data->temp_high[nr] = val; | ||
582 | mutex_unlock(&data->update_lock); | ||
583 | |||
584 | return count; | ||
585 | } | ||
586 | |||
587 | static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute | ||
588 | *devattr, char *buf) | ||
589 | { | ||
590 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
591 | int nr = to_sensor_dev_attr(devattr)->index; | ||
592 | |||
593 | return sprintf(buf, "%d\n", | ||
594 | (data->temp_high[nr] - data->temp_hyst[nr]) * 1000); | ||
595 | } | ||
596 | |||
597 | static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | ||
598 | *devattr, const char *buf, size_t count) | ||
599 | { | ||
600 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
601 | int nr = to_sensor_dev_attr(devattr)->index; | ||
602 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
603 | ssize_t ret = count; | ||
604 | |||
605 | mutex_lock(&data->update_lock); | ||
606 | |||
607 | /* convert abs to relative and check */ | ||
608 | val = data->temp_high[nr] - val; | ||
609 | if (val < 0 || val > 15) { | ||
610 | ret = -EINVAL; | ||
611 | goto store_temp_max_hyst_exit; | ||
612 | } | ||
613 | |||
614 | data->temp_hyst[nr] = val; | ||
615 | |||
616 | /* convert value to register contents */ | ||
617 | switch (nr) { | ||
618 | case 0: | ||
619 | val = val << 4; | ||
620 | break; | ||
621 | case 1: | ||
622 | val = val | (data->temp_hyst[2] << 4); | ||
623 | break; | ||
624 | case 2: | ||
625 | val = data->temp_hyst[1] | (val << 4); | ||
626 | break; | ||
627 | } | ||
628 | |||
629 | f71882fg_write8(data, nr ? F71882FG_REG_TEMP_HYST23 : | ||
630 | F71882FG_REG_TEMP_HYST1, val); | ||
631 | |||
632 | store_temp_max_hyst_exit: | ||
633 | mutex_unlock(&data->update_lock); | ||
634 | return ret; | ||
635 | } | ||
636 | |||
637 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute | ||
638 | *devattr, char *buf) | ||
639 | { | ||
640 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
641 | int nr = to_sensor_dev_attr(devattr)->index; | ||
642 | |||
643 | return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); | ||
644 | } | ||
645 | |||
646 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
647 | *devattr, const char *buf, size_t count) | ||
648 | { | ||
649 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
650 | int nr = to_sensor_dev_attr(devattr)->index; | ||
651 | int val = simple_strtoul(buf, NULL, 10) / 1000; | ||
652 | |||
653 | if (val > 255) | ||
654 | val = 255; | ||
655 | |||
656 | mutex_lock(&data->update_lock); | ||
657 | f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); | ||
658 | data->temp_ovt[nr] = val; | ||
659 | mutex_unlock(&data->update_lock); | ||
660 | |||
661 | return count; | ||
662 | } | ||
663 | |||
664 | static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute | ||
665 | *devattr, char *buf) | ||
666 | { | ||
667 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
668 | int nr = to_sensor_dev_attr(devattr)->index; | ||
669 | |||
670 | return sprintf(buf, "%d\n", | ||
671 | (data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000); | ||
672 | } | ||
673 | |||
674 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
675 | *devattr, char *buf) | ||
676 | { | ||
677 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
678 | int nr = to_sensor_dev_attr(devattr)->index; | ||
679 | |||
680 | return sprintf(buf, "%d\n", data->temp_type[nr]); | ||
681 | } | ||
682 | |||
683 | static ssize_t show_temp_beep(struct device *dev, struct device_attribute | ||
684 | *devattr, char *buf) | ||
685 | { | ||
686 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
687 | int nr = to_sensor_dev_attr(devattr)->index; | ||
688 | |||
689 | if (data->temp_beep & (1 << (nr + 1))) | ||
690 | return sprintf(buf, "1\n"); | ||
691 | else | ||
692 | return sprintf(buf, "0\n"); | ||
693 | } | ||
694 | |||
695 | static ssize_t store_temp_beep(struct device *dev, struct device_attribute | ||
696 | *devattr, const char *buf, size_t count) | ||
697 | { | ||
698 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
699 | int nr = to_sensor_dev_attr(devattr)->index; | ||
700 | int val = simple_strtoul(buf, NULL, 10); | ||
701 | |||
702 | mutex_lock(&data->update_lock); | ||
703 | if (val) | ||
704 | data->temp_beep |= 1 << (nr + 1); | ||
705 | else | ||
706 | data->temp_beep &= ~(1 << (nr + 1)); | ||
707 | |||
708 | f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); | ||
709 | mutex_unlock(&data->update_lock); | ||
710 | |||
711 | return count; | ||
712 | } | ||
713 | |||
714 | static ssize_t show_temp_alarm(struct device *dev, struct device_attribute | ||
715 | *devattr, char *buf) | ||
716 | { | ||
717 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
718 | int nr = to_sensor_dev_attr(devattr)->index; | ||
719 | |||
720 | if (data->temp_status & (1 << (nr + 1))) | ||
721 | return sprintf(buf, "1\n"); | ||
722 | else | ||
723 | return sprintf(buf, "0\n"); | ||
724 | } | ||
725 | |||
726 | static ssize_t show_temp_fault(struct device *dev, struct device_attribute | ||
727 | *devattr, char *buf) | ||
728 | { | ||
729 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
730 | int nr = to_sensor_dev_attr(devattr)->index; | ||
731 | |||
732 | if (data->temp_diode_open & (1 << (nr + 1))) | ||
733 | return sprintf(buf, "1\n"); | ||
734 | else | ||
735 | return sprintf(buf, "0\n"); | ||
736 | } | ||
737 | |||
738 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
739 | char *buf) | ||
740 | { | ||
741 | return sprintf(buf, DRVNAME "\n"); | ||
742 | } | ||
743 | |||
744 | |||
745 | static int __devinit f71882fg_probe(struct platform_device * pdev) | ||
746 | { | ||
747 | struct f71882fg_data *data; | ||
748 | int err, i; | ||
749 | u8 start_reg; | ||
750 | |||
751 | if (!(data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL))) | ||
752 | return -ENOMEM; | ||
753 | |||
754 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
755 | mutex_init(&data->update_lock); | ||
756 | platform_set_drvdata(pdev, data); | ||
757 | |||
758 | /* Register sysfs interface files */ | ||
759 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) { | ||
760 | err = device_create_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
761 | if (err) | ||
762 | goto exit_unregister_sysfs; | ||
763 | } | ||
764 | |||
765 | start_reg = f71882fg_read8(data, F71882FG_REG_START); | ||
766 | if (start_reg & 0x01) { | ||
767 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) { | ||
768 | err = device_create_file(&pdev->dev, | ||
769 | &f71882fg_in_temp_attr[i].dev_attr); | ||
770 | if (err) | ||
771 | goto exit_unregister_sysfs; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | if (start_reg & 0x02) { | ||
776 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) { | ||
777 | err = device_create_file(&pdev->dev, | ||
778 | &f71882fg_fan_attr[i].dev_attr); | ||
779 | if (err) | ||
780 | goto exit_unregister_sysfs; | ||
781 | } | ||
782 | } | ||
783 | |||
784 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
785 | if (IS_ERR(data->hwmon_dev)) { | ||
786 | err = PTR_ERR(data->hwmon_dev); | ||
787 | goto exit_unregister_sysfs; | ||
788 | } | ||
789 | |||
790 | return 0; | ||
791 | |||
792 | exit_unregister_sysfs: | ||
793 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) | ||
794 | device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
795 | |||
796 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) | ||
797 | device_remove_file(&pdev->dev, | ||
798 | &f71882fg_in_temp_attr[i].dev_attr); | ||
799 | |||
800 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) | ||
801 | device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); | ||
802 | |||
803 | kfree(data); | ||
804 | |||
805 | return err; | ||
806 | } | ||
807 | |||
808 | static int __devexit f71882fg_remove(struct platform_device *pdev) | ||
809 | { | ||
810 | int i; | ||
811 | struct f71882fg_data *data = platform_get_drvdata(pdev); | ||
812 | |||
813 | platform_set_drvdata(pdev, NULL); | ||
814 | hwmon_device_unregister(data->hwmon_dev); | ||
815 | |||
816 | for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) | ||
817 | device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); | ||
818 | |||
819 | for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) | ||
820 | device_remove_file(&pdev->dev, | ||
821 | &f71882fg_in_temp_attr[i].dev_attr); | ||
822 | |||
823 | for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) | ||
824 | device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); | ||
825 | |||
826 | kfree(data); | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int __init f71882fg_find(int sioaddr, unsigned short *address) | ||
832 | { | ||
833 | int err = -ENODEV; | ||
834 | u16 devid; | ||
835 | u8 start_reg; | ||
836 | struct f71882fg_data data; | ||
837 | |||
838 | superio_enter(sioaddr); | ||
839 | |||
840 | devid = superio_inw(sioaddr, SIO_REG_MANID); | ||
841 | if (devid != SIO_FINTEK_ID) { | ||
842 | printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); | ||
843 | goto exit; | ||
844 | } | ||
845 | |||
846 | devid = superio_inw(sioaddr, SIO_REG_DEVID); | ||
847 | if (devid != SIO_F71882_ID) { | ||
848 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); | ||
849 | goto exit; | ||
850 | } | ||
851 | |||
852 | superio_select(sioaddr, SIO_F71882FG_LD_HWM); | ||
853 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
854 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | ||
855 | goto exit; | ||
856 | } | ||
857 | |||
858 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | ||
859 | if (*address == 0) | ||
860 | { | ||
861 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | ||
862 | goto exit; | ||
863 | } | ||
864 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | ||
865 | |||
866 | data.addr = *address; | ||
867 | start_reg = f71882fg_read8(&data, F71882FG_REG_START); | ||
868 | if (!(start_reg & 0x03)) { | ||
869 | printk(KERN_WARNING DRVNAME | ||
870 | ": Hardware monitoring not activated\n"); | ||
871 | goto exit; | ||
872 | } | ||
873 | |||
874 | err = 0; | ||
875 | printk(KERN_INFO DRVNAME ": Found F71882FG chip at %#x, revision %d\n", | ||
876 | (unsigned int)*address, | ||
877 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | ||
878 | exit: | ||
879 | superio_exit(sioaddr); | ||
880 | return err; | ||
881 | } | ||
882 | |||
883 | static int __init f71882fg_device_add(unsigned short address) | ||
884 | { | ||
885 | struct resource res = { | ||
886 | .start = address, | ||
887 | .end = address + REGION_LENGTH - 1, | ||
888 | .flags = IORESOURCE_IO, | ||
889 | }; | ||
890 | int err; | ||
891 | |||
892 | f71882fg_pdev = platform_device_alloc(DRVNAME, address); | ||
893 | if (!f71882fg_pdev) | ||
894 | return -ENOMEM; | ||
895 | |||
896 | res.name = f71882fg_pdev->name; | ||
897 | err = platform_device_add_resources(f71882fg_pdev, &res, 1); | ||
898 | if (err) { | ||
899 | printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); | ||
900 | goto exit_device_put; | ||
901 | } | ||
902 | |||
903 | err = platform_device_add(f71882fg_pdev); | ||
904 | if (err) { | ||
905 | printk(KERN_ERR DRVNAME ": Device addition failed\n"); | ||
906 | goto exit_device_put; | ||
907 | } | ||
908 | |||
909 | return 0; | ||
910 | |||
911 | exit_device_put: | ||
912 | platform_device_put(f71882fg_pdev); | ||
913 | |||
914 | return err; | ||
915 | } | ||
916 | |||
917 | static int __init f71882fg_init(void) | ||
918 | { | ||
919 | int err = -ENODEV; | ||
920 | unsigned short address; | ||
921 | |||
922 | if (f71882fg_find(0x2e, &address) && f71882fg_find(0x4e, &address)) | ||
923 | goto exit; | ||
924 | |||
925 | if ((err = platform_driver_register(&f71882fg_driver))) | ||
926 | goto exit; | ||
927 | |||
928 | if ((err = f71882fg_device_add(address))) | ||
929 | goto exit_driver; | ||
930 | |||
931 | return 0; | ||
932 | |||
933 | exit_driver: | ||
934 | platform_driver_unregister(&f71882fg_driver); | ||
935 | exit: | ||
936 | return err; | ||
937 | } | ||
938 | |||
939 | static void __exit f71882fg_exit(void) | ||
940 | { | ||
941 | platform_device_unregister(f71882fg_pdev); | ||
942 | platform_driver_unregister(&f71882fg_driver); | ||
943 | } | ||
944 | |||
945 | MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); | ||
946 | MODULE_AUTHOR("Hans Edgington (hans@edgington.nl)"); | ||
947 | MODULE_LICENSE("GPL"); | ||
948 | |||
949 | module_init(f71882fg_init); | ||
950 | module_exit(f71882fg_exit); | ||
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c new file mode 100644 index 000000000000..13a041326a04 --- /dev/null +++ b/drivers/hwmon/f75375s.c | |||
@@ -0,0 +1,691 @@ | |||
1 | /* | ||
2 | * f75375s.c - driver for the Fintek F75375/SP and F75373 | ||
3 | * hardware monitoring features | ||
4 | * Copyright (C) 2006-2007 Riku Voipio <riku.voipio@movial.fi> | ||
5 | * | ||
6 | * Datasheets available at: | ||
7 | * | ||
8 | * f75375: | ||
9 | * http://www.fintek.com.tw/files/productfiles/2005111152950.pdf | ||
10 | * | ||
11 | * f75373: | ||
12 | * http://www.fintek.com.tw/files/productfiles/2005111153128.pdf | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/jiffies.h> | ||
32 | #include <linux/hwmon.h> | ||
33 | #include <linux/hwmon-sysfs.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/err.h> | ||
36 | #include <linux/mutex.h> | ||
37 | |||
38 | /* Addresses to scan */ | ||
39 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; | ||
40 | |||
41 | /* Insmod parameters */ | ||
42 | I2C_CLIENT_INSMOD_2(f75373, f75375); | ||
43 | |||
44 | /* Fintek F75375 registers */ | ||
45 | #define F75375_REG_CONFIG0 0x0 | ||
46 | #define F75375_REG_CONFIG1 0x1 | ||
47 | #define F75375_REG_CONFIG2 0x2 | ||
48 | #define F75375_REG_CONFIG3 0x3 | ||
49 | #define F75375_REG_ADDR 0x4 | ||
50 | #define F75375_REG_INTR 0x31 | ||
51 | #define F75375_CHIP_ID 0x5A | ||
52 | #define F75375_REG_VERSION 0x5C | ||
53 | #define F75375_REG_VENDOR 0x5D | ||
54 | #define F75375_REG_FAN_TIMER 0x60 | ||
55 | |||
56 | #define F75375_REG_VOLT(nr) (0x10 + (nr)) | ||
57 | #define F75375_REG_VOLT_HIGH(nr) (0x20 + (nr) * 2) | ||
58 | #define F75375_REG_VOLT_LOW(nr) (0x21 + (nr) * 2) | ||
59 | |||
60 | #define F75375_REG_TEMP(nr) (0x14 + (nr)) | ||
61 | #define F75375_REG_TEMP_HIGH(nr) (0x28 + (nr) * 2) | ||
62 | #define F75375_REG_TEMP_HYST(nr) (0x29 + (nr) * 2) | ||
63 | |||
64 | #define F75375_REG_FAN(nr) (0x16 + (nr) * 2) | ||
65 | #define F75375_REG_FAN_MIN(nr) (0x2C + (nr) * 2) | ||
66 | #define F75375_REG_FAN_FULL(nr) (0x70 + (nr) * 0x10) | ||
67 | #define F75375_REG_FAN_PWM_DUTY(nr) (0x76 + (nr) * 0x10) | ||
68 | #define F75375_REG_FAN_PWM_CLOCK(nr) (0x7D + (nr) * 0x10) | ||
69 | |||
70 | #define F75375_REG_FAN_EXP(nr) (0x74 + (nr) * 0x10) | ||
71 | #define F75375_REG_FAN_B_TEMP(nr, step) ((0xA0 + (nr) * 0x10) + (step)) | ||
72 | #define F75375_REG_FAN_B_SPEED(nr, step) \ | ||
73 | ((0xA5 + (nr) * 0x10) + (step) * 2) | ||
74 | |||
75 | #define F75375_REG_PWM1_RAISE_DUTY 0x69 | ||
76 | #define F75375_REG_PWM2_RAISE_DUTY 0x6A | ||
77 | #define F75375_REG_PWM1_DROP_DUTY 0x6B | ||
78 | #define F75375_REG_PWM2_DROP_DUTY 0x6C | ||
79 | |||
80 | #define FAN_CTRL_LINEAR(nr) (4 + nr) | ||
81 | #define FAN_CTRL_MODE(nr) (5 + ((nr) * 2)) | ||
82 | |||
83 | /* | ||
84 | * Data structures and manipulation thereof | ||
85 | */ | ||
86 | |||
87 | struct f75375_data { | ||
88 | unsigned short addr; | ||
89 | struct i2c_client client; | ||
90 | struct device *hwmon_dev; | ||
91 | |||
92 | const char *name; | ||
93 | int kind; | ||
94 | struct mutex update_lock; /* protect register access */ | ||
95 | char valid; | ||
96 | unsigned long last_updated; /* In jiffies */ | ||
97 | unsigned long last_limits; /* In jiffies */ | ||
98 | |||
99 | /* Register values */ | ||
100 | u8 in[4]; | ||
101 | u8 in_max[4]; | ||
102 | u8 in_min[4]; | ||
103 | u16 fan[2]; | ||
104 | u16 fan_min[2]; | ||
105 | u16 fan_full[2]; | ||
106 | u16 fan_exp[2]; | ||
107 | u8 fan_timer; | ||
108 | u8 pwm[2]; | ||
109 | u8 pwm_mode[2]; | ||
110 | u8 pwm_enable[2]; | ||
111 | s8 temp[2]; | ||
112 | s8 temp_high[2]; | ||
113 | s8 temp_max_hyst[2]; | ||
114 | }; | ||
115 | |||
116 | static int f75375_attach_adapter(struct i2c_adapter *adapter); | ||
117 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); | ||
118 | static int f75375_detach_client(struct i2c_client *client); | ||
119 | |||
120 | static struct i2c_driver f75375_driver = { | ||
121 | .driver = { | ||
122 | .name = "f75375", | ||
123 | }, | ||
124 | .attach_adapter = f75375_attach_adapter, | ||
125 | .detach_client = f75375_detach_client, | ||
126 | }; | ||
127 | |||
128 | static inline int f75375_read8(struct i2c_client *client, u8 reg) | ||
129 | { | ||
130 | return i2c_smbus_read_byte_data(client, reg); | ||
131 | } | ||
132 | |||
133 | /* in most cases, should be called while holding update_lock */ | ||
134 | static inline u16 f75375_read16(struct i2c_client *client, u8 reg) | ||
135 | { | ||
136 | return ((i2c_smbus_read_byte_data(client, reg) << 8) | ||
137 | | i2c_smbus_read_byte_data(client, reg + 1)); | ||
138 | } | ||
139 | |||
140 | static inline void f75375_write8(struct i2c_client *client, u8 reg, | ||
141 | u8 value) | ||
142 | { | ||
143 | i2c_smbus_write_byte_data(client, reg, value); | ||
144 | } | ||
145 | |||
146 | static inline void f75375_write16(struct i2c_client *client, u8 reg, | ||
147 | u16 value) | ||
148 | { | ||
149 | int err = i2c_smbus_write_byte_data(client, reg, (value << 8)); | ||
150 | if (err) | ||
151 | return; | ||
152 | i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); | ||
153 | } | ||
154 | |||
155 | static struct f75375_data *f75375_update_device(struct device *dev) | ||
156 | { | ||
157 | struct i2c_client *client = to_i2c_client(dev); | ||
158 | struct f75375_data *data = i2c_get_clientdata(client); | ||
159 | int nr; | ||
160 | |||
161 | mutex_lock(&data->update_lock); | ||
162 | |||
163 | /* Limit registers cache is refreshed after 60 seconds */ | ||
164 | if (time_after(jiffies, data->last_limits + 60 * HZ) | ||
165 | || !data->valid) { | ||
166 | for (nr = 0; nr < 2; nr++) { | ||
167 | data->temp_high[nr] = | ||
168 | f75375_read8(client, F75375_REG_TEMP_HIGH(nr)); | ||
169 | data->temp_max_hyst[nr] = | ||
170 | f75375_read8(client, F75375_REG_TEMP_HYST(nr)); | ||
171 | data->fan_full[nr] = | ||
172 | f75375_read16(client, F75375_REG_FAN_FULL(nr)); | ||
173 | data->fan_min[nr] = | ||
174 | f75375_read16(client, F75375_REG_FAN_MIN(nr)); | ||
175 | data->fan_exp[nr] = | ||
176 | f75375_read16(client, F75375_REG_FAN_EXP(nr)); | ||
177 | data->pwm[nr] = f75375_read8(client, | ||
178 | F75375_REG_FAN_PWM_DUTY(nr)); | ||
179 | |||
180 | } | ||
181 | for (nr = 0; nr < 4; nr++) { | ||
182 | data->in_max[nr] = | ||
183 | f75375_read8(client, F75375_REG_VOLT_HIGH(nr)); | ||
184 | data->in_min[nr] = | ||
185 | f75375_read8(client, F75375_REG_VOLT_LOW(nr)); | ||
186 | } | ||
187 | data->fan_timer = f75375_read8(client, F75375_REG_FAN_TIMER); | ||
188 | data->last_limits = jiffies; | ||
189 | } | ||
190 | |||
191 | /* Measurement registers cache is refreshed after 2 second */ | ||
192 | if (time_after(jiffies, data->last_updated + 2 * HZ) | ||
193 | || !data->valid) { | ||
194 | for (nr = 0; nr < 2; nr++) { | ||
195 | data->temp[nr] = | ||
196 | f75375_read8(client, F75375_REG_TEMP(nr)); | ||
197 | data->fan[nr] = | ||
198 | f75375_read16(client, F75375_REG_FAN(nr)); | ||
199 | } | ||
200 | for (nr = 0; nr < 4; nr++) | ||
201 | data->in[nr] = | ||
202 | f75375_read8(client, F75375_REG_VOLT(nr)); | ||
203 | |||
204 | data->last_updated = jiffies; | ||
205 | data->valid = 1; | ||
206 | } | ||
207 | |||
208 | mutex_unlock(&data->update_lock); | ||
209 | return data; | ||
210 | } | ||
211 | |||
212 | static inline u16 rpm_from_reg(u16 reg) | ||
213 | { | ||
214 | if (reg == 0 || reg == 0xffff) | ||
215 | return 0; | ||
216 | return (1500000 / reg); | ||
217 | } | ||
218 | |||
219 | static inline u16 rpm_to_reg(int rpm) | ||
220 | { | ||
221 | if (rpm < 367 || rpm > 0xffff) | ||
222 | return 0xffff; | ||
223 | return (1500000 / rpm); | ||
224 | } | ||
225 | |||
226 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | ||
227 | const char *buf, size_t count) | ||
228 | { | ||
229 | int nr = to_sensor_dev_attr(attr)->index; | ||
230 | struct i2c_client *client = to_i2c_client(dev); | ||
231 | struct f75375_data *data = i2c_get_clientdata(client); | ||
232 | int val = simple_strtoul(buf, NULL, 10); | ||
233 | |||
234 | mutex_lock(&data->update_lock); | ||
235 | data->fan_min[nr] = rpm_to_reg(val); | ||
236 | f75375_write16(client, F75375_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
237 | mutex_unlock(&data->update_lock); | ||
238 | return count; | ||
239 | } | ||
240 | |||
241 | static ssize_t set_fan_exp(struct device *dev, struct device_attribute *attr, | ||
242 | const char *buf, size_t count) | ||
243 | { | ||
244 | int nr = to_sensor_dev_attr(attr)->index; | ||
245 | struct i2c_client *client = to_i2c_client(dev); | ||
246 | struct f75375_data *data = i2c_get_clientdata(client); | ||
247 | int val = simple_strtoul(buf, NULL, 10); | ||
248 | |||
249 | mutex_lock(&data->update_lock); | ||
250 | data->fan_exp[nr] = rpm_to_reg(val); | ||
251 | f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_exp[nr]); | ||
252 | mutex_unlock(&data->update_lock); | ||
253 | return count; | ||
254 | } | ||
255 | |||
256 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | ||
257 | const char *buf, size_t count) | ||
258 | { | ||
259 | int nr = to_sensor_dev_attr(attr)->index; | ||
260 | struct i2c_client *client = to_i2c_client(dev); | ||
261 | struct f75375_data *data = i2c_get_clientdata(client); | ||
262 | int val = simple_strtoul(buf, NULL, 10); | ||
263 | |||
264 | mutex_lock(&data->update_lock); | ||
265 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); | ||
266 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); | ||
267 | mutex_unlock(&data->update_lock); | ||
268 | return count; | ||
269 | } | ||
270 | |||
271 | static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | ||
272 | *attr, char *buf) | ||
273 | { | ||
274 | int nr = to_sensor_dev_attr(attr)->index; | ||
275 | struct f75375_data *data = f75375_update_device(dev); | ||
276 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | ||
277 | } | ||
278 | |||
279 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | ||
280 | const char *buf, size_t count) | ||
281 | { | ||
282 | int nr = to_sensor_dev_attr(attr)->index; | ||
283 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct f75375_data *data = i2c_get_clientdata(client); | ||
285 | int val = simple_strtoul(buf, NULL, 10); | ||
286 | u8 fanmode; | ||
287 | |||
288 | if (val < 0 || val > 4) | ||
289 | return -EINVAL; | ||
290 | |||
291 | mutex_lock(&data->update_lock); | ||
292 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | ||
293 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); | ||
294 | |||
295 | switch (val) { | ||
296 | case 0: /* Full speed */ | ||
297 | fanmode |= (3 << FAN_CTRL_MODE(nr)); | ||
298 | data->pwm[nr] = 255; | ||
299 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | ||
300 | data->pwm[nr]); | ||
301 | break; | ||
302 | case 1: /* PWM */ | ||
303 | fanmode |= (3 << FAN_CTRL_MODE(nr)); | ||
304 | break; | ||
305 | case 2: /* AUTOMATIC*/ | ||
306 | fanmode |= (2 << FAN_CTRL_MODE(nr)); | ||
307 | break; | ||
308 | case 3: /* fan speed */ | ||
309 | break; | ||
310 | } | ||
311 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); | ||
312 | data->pwm_enable[nr] = val; | ||
313 | mutex_unlock(&data->update_lock); | ||
314 | return count; | ||
315 | } | ||
316 | |||
317 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | ||
318 | const char *buf, size_t count) | ||
319 | { | ||
320 | int nr = to_sensor_dev_attr(attr)->index; | ||
321 | struct i2c_client *client = to_i2c_client(dev); | ||
322 | struct f75375_data *data = i2c_get_clientdata(client); | ||
323 | int val = simple_strtoul(buf, NULL, 10); | ||
324 | u8 conf = 0; | ||
325 | |||
326 | if (val != 0 || val != 1 || data->kind == f75373) | ||
327 | return -EINVAL; | ||
328 | |||
329 | mutex_lock(&data->update_lock); | ||
330 | conf = f75375_read8(client, F75375_REG_CONFIG1); | ||
331 | conf = ~(1 << FAN_CTRL_LINEAR(nr)); | ||
332 | |||
333 | if (val == 0) | ||
334 | conf |= (1 << FAN_CTRL_LINEAR(nr)) ; | ||
335 | |||
336 | f75375_write8(client, F75375_REG_CONFIG1, conf); | ||
337 | data->pwm_mode[nr] = val; | ||
338 | mutex_unlock(&data->update_lock); | ||
339 | return count; | ||
340 | } | ||
341 | |||
342 | static ssize_t show_pwm(struct device *dev, struct device_attribute | ||
343 | *attr, char *buf) | ||
344 | { | ||
345 | int nr = to_sensor_dev_attr(attr)->index; | ||
346 | struct f75375_data *data = f75375_update_device(dev); | ||
347 | return sprintf(buf, "%d\n", data->pwm[nr]); | ||
348 | } | ||
349 | |||
350 | static ssize_t show_pwm_mode(struct device *dev, struct device_attribute | ||
351 | *attr, char *buf) | ||
352 | { | ||
353 | int nr = to_sensor_dev_attr(attr)->index; | ||
354 | struct f75375_data *data = f75375_update_device(dev); | ||
355 | return sprintf(buf, "%d\n", data->pwm_mode[nr]); | ||
356 | } | ||
357 | |||
358 | #define VOLT_FROM_REG(val) ((val) * 8) | ||
359 | #define VOLT_TO_REG(val) ((val) / 8) | ||
360 | |||
361 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
362 | char *buf) | ||
363 | { | ||
364 | int nr = to_sensor_dev_attr(attr)->index; | ||
365 | struct f75375_data *data = f75375_update_device(dev); | ||
366 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in[nr])); | ||
367 | } | ||
368 | |||
369 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
370 | char *buf) | ||
371 | { | ||
372 | int nr = to_sensor_dev_attr(attr)->index; | ||
373 | struct f75375_data *data = f75375_update_device(dev); | ||
374 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in_max[nr])); | ||
375 | } | ||
376 | |||
377 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
378 | char *buf) | ||
379 | { | ||
380 | int nr = to_sensor_dev_attr(attr)->index; | ||
381 | struct f75375_data *data = f75375_update_device(dev); | ||
382 | return sprintf(buf, "%d\n", VOLT_FROM_REG(data->in_min[nr])); | ||
383 | } | ||
384 | |||
385 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | ||
386 | const char *buf, size_t count) | ||
387 | { | ||
388 | int nr = to_sensor_dev_attr(attr)->index; | ||
389 | struct i2c_client *client = to_i2c_client(dev); | ||
390 | struct f75375_data *data = i2c_get_clientdata(client); | ||
391 | int val = simple_strtoul(buf, NULL, 10); | ||
392 | val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); | ||
393 | mutex_lock(&data->update_lock); | ||
394 | data->in_max[nr] = val; | ||
395 | f75375_write8(client, F75375_REG_VOLT_HIGH(nr), data->in_max[nr]); | ||
396 | mutex_unlock(&data->update_lock); | ||
397 | return count; | ||
398 | } | ||
399 | |||
400 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | ||
401 | const char *buf, size_t count) | ||
402 | { | ||
403 | int nr = to_sensor_dev_attr(attr)->index; | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | struct f75375_data *data = i2c_get_clientdata(client); | ||
406 | int val = simple_strtoul(buf, NULL, 10); | ||
407 | val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); | ||
408 | mutex_lock(&data->update_lock); | ||
409 | data->in_min[nr] = val; | ||
410 | f75375_write8(client, F75375_REG_VOLT_LOW(nr), data->in_min[nr]); | ||
411 | mutex_unlock(&data->update_lock); | ||
412 | return count; | ||
413 | } | ||
414 | #define TEMP_FROM_REG(val) ((val) * 1000) | ||
415 | #define TEMP_TO_REG(val) ((val) / 1000) | ||
416 | |||
417 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
418 | char *buf) | ||
419 | { | ||
420 | int nr = to_sensor_dev_attr(attr)->index; | ||
421 | struct f75375_data *data = f75375_update_device(dev); | ||
422 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); | ||
423 | } | ||
424 | |||
425 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
426 | char *buf) | ||
427 | { | ||
428 | int nr = to_sensor_dev_attr(attr)->index; | ||
429 | struct f75375_data *data = f75375_update_device(dev); | ||
430 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])); | ||
431 | } | ||
432 | |||
433 | static ssize_t show_temp_max_hyst(struct device *dev, | ||
434 | struct device_attribute *attr, char *buf) | ||
435 | { | ||
436 | int nr = to_sensor_dev_attr(attr)->index; | ||
437 | struct f75375_data *data = f75375_update_device(dev); | ||
438 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[nr])); | ||
439 | } | ||
440 | |||
441 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
442 | const char *buf, size_t count) | ||
443 | { | ||
444 | int nr = to_sensor_dev_attr(attr)->index; | ||
445 | struct i2c_client *client = to_i2c_client(dev); | ||
446 | struct f75375_data *data = i2c_get_clientdata(client); | ||
447 | int val = simple_strtol(buf, NULL, 10); | ||
448 | val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); | ||
449 | mutex_lock(&data->update_lock); | ||
450 | data->temp_high[nr] = val; | ||
451 | f75375_write8(client, F75375_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
452 | mutex_unlock(&data->update_lock); | ||
453 | return count; | ||
454 | } | ||
455 | |||
456 | static ssize_t set_temp_max_hyst(struct device *dev, | ||
457 | struct device_attribute *attr, const char *buf, size_t count) | ||
458 | { | ||
459 | int nr = to_sensor_dev_attr(attr)->index; | ||
460 | struct i2c_client *client = to_i2c_client(dev); | ||
461 | struct f75375_data *data = i2c_get_clientdata(client); | ||
462 | int val = simple_strtol(buf, NULL, 10); | ||
463 | val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); | ||
464 | mutex_lock(&data->update_lock); | ||
465 | data->temp_max_hyst[nr] = val; | ||
466 | f75375_write8(client, F75375_REG_TEMP_HYST(nr), | ||
467 | data->temp_max_hyst[nr]); | ||
468 | mutex_unlock(&data->update_lock); | ||
469 | return count; | ||
470 | } | ||
471 | |||
472 | #define show_fan(thing) \ | ||
473 | static ssize_t show_##thing(struct device *dev, struct device_attribute *attr, \ | ||
474 | char *buf)\ | ||
475 | {\ | ||
476 | int nr = to_sensor_dev_attr(attr)->index;\ | ||
477 | struct f75375_data *data = f75375_update_device(dev); \ | ||
478 | return sprintf(buf, "%d\n", rpm_from_reg(data->thing[nr])); \ | ||
479 | } | ||
480 | |||
481 | show_fan(fan); | ||
482 | show_fan(fan_min); | ||
483 | show_fan(fan_full); | ||
484 | show_fan(fan_exp); | ||
485 | |||
486 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); | ||
487 | static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO|S_IWUSR, | ||
488 | show_in_max, set_in_max, 0); | ||
489 | static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO|S_IWUSR, | ||
490 | show_in_min, set_in_min, 0); | ||
491 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); | ||
492 | static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO|S_IWUSR, | ||
493 | show_in_max, set_in_max, 1); | ||
494 | static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO|S_IWUSR, | ||
495 | show_in_min, set_in_min, 1); | ||
496 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2); | ||
497 | static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO|S_IWUSR, | ||
498 | show_in_max, set_in_max, 2); | ||
499 | static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO|S_IWUSR, | ||
500 | show_in_min, set_in_min, 2); | ||
501 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3); | ||
502 | static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO|S_IWUSR, | ||
503 | show_in_max, set_in_max, 3); | ||
504 | static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR, | ||
505 | show_in_min, set_in_min, 3); | ||
506 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
507 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, | ||
508 | show_temp_max_hyst, set_temp_max_hyst, 0); | ||
509 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR, | ||
510 | show_temp_max, set_temp_max, 0); | ||
511 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
512 | static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, | ||
513 | show_temp_max_hyst, set_temp_max_hyst, 1); | ||
514 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR, | ||
515 | show_temp_max, set_temp_max, 1); | ||
516 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
517 | static SENSOR_DEVICE_ATTR(fan1_full, S_IRUGO, show_fan_full, NULL, 0); | ||
518 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO|S_IWUSR, | ||
519 | show_fan_min, set_fan_min, 0); | ||
520 | static SENSOR_DEVICE_ATTR(fan1_exp, S_IRUGO|S_IWUSR, | ||
521 | show_fan_exp, set_fan_exp, 0); | ||
522 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
523 | static SENSOR_DEVICE_ATTR(fan2_full, S_IRUGO, show_fan_full, NULL, 1); | ||
524 | static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO|S_IWUSR, | ||
525 | show_fan_min, set_fan_min, 1); | ||
526 | static SENSOR_DEVICE_ATTR(fan2_exp, S_IRUGO|S_IWUSR, | ||
527 | show_fan_exp, set_fan_exp, 1); | ||
528 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, | ||
529 | show_pwm, set_pwm, 0); | ||
530 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, | ||
531 | show_pwm_enable, set_pwm_enable, 0); | ||
532 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO|S_IWUSR, | ||
533 | show_pwm_mode, set_pwm_mode, 0); | ||
534 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, | ||
535 | show_pwm, set_pwm, 1); | ||
536 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, | ||
537 | show_pwm_enable, set_pwm_enable, 1); | ||
538 | static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO|S_IWUSR, | ||
539 | show_pwm_mode, set_pwm_mode, 1); | ||
540 | |||
541 | static struct attribute *f75375_attributes[] = { | ||
542 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
543 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
544 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
545 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
546 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
547 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | ||
548 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
549 | &sensor_dev_attr_fan1_full.dev_attr.attr, | ||
550 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
551 | &sensor_dev_attr_fan1_exp.dev_attr.attr, | ||
552 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
553 | &sensor_dev_attr_fan2_full.dev_attr.attr, | ||
554 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
555 | &sensor_dev_attr_fan2_exp.dev_attr.attr, | ||
556 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
557 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
558 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | ||
559 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
560 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
561 | &sensor_dev_attr_pwm2_mode.dev_attr.attr, | ||
562 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
563 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
564 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
565 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
566 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
567 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
568 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
569 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
570 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
571 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
572 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
573 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
574 | NULL | ||
575 | }; | ||
576 | |||
577 | static const struct attribute_group f75375_group = { | ||
578 | .attrs = f75375_attributes, | ||
579 | }; | ||
580 | |||
581 | static int f75375_detach_client(struct i2c_client *client) | ||
582 | { | ||
583 | struct f75375_data *data = i2c_get_clientdata(client); | ||
584 | int err; | ||
585 | |||
586 | hwmon_device_unregister(data->hwmon_dev); | ||
587 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
588 | |||
589 | err = i2c_detach_client(client); | ||
590 | if (err) { | ||
591 | dev_err(&client->dev, | ||
592 | "Client deregistration failed, " | ||
593 | "client not detached.\n"); | ||
594 | return err; | ||
595 | } | ||
596 | kfree(data); | ||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static int f75375_attach_adapter(struct i2c_adapter *adapter) | ||
601 | { | ||
602 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
603 | return 0; | ||
604 | return i2c_probe(adapter, &addr_data, f75375_detect); | ||
605 | } | ||
606 | |||
607 | /* This function is called by i2c_probe */ | ||
608 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) | ||
609 | { | ||
610 | struct i2c_client *client; | ||
611 | struct f75375_data *data; | ||
612 | u8 version = 0; | ||
613 | int err = 0; | ||
614 | const char *name = ""; | ||
615 | |||
616 | if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) { | ||
617 | err = -ENOMEM; | ||
618 | goto exit; | ||
619 | } | ||
620 | client = &data->client; | ||
621 | i2c_set_clientdata(client, data); | ||
622 | client->addr = address; | ||
623 | client->adapter = adapter; | ||
624 | client->driver = &f75375_driver; | ||
625 | |||
626 | if (kind < 0) { | ||
627 | u16 vendid = f75375_read16(client, F75375_REG_VENDOR); | ||
628 | u16 chipid = f75375_read16(client, F75375_CHIP_ID); | ||
629 | version = f75375_read8(client, F75375_REG_VERSION); | ||
630 | if (chipid == 0x0306 && vendid == 0x1934) { | ||
631 | kind = f75375; | ||
632 | } else if (chipid == 0x0204 && vendid == 0x1934) { | ||
633 | kind = f75373; | ||
634 | } else { | ||
635 | dev_err(&adapter->dev, | ||
636 | "failed,%02X,%02X,%02X\n", | ||
637 | chipid, version, vendid); | ||
638 | goto exit_free; | ||
639 | } | ||
640 | } | ||
641 | |||
642 | if (kind == f75375) { | ||
643 | name = "f75375"; | ||
644 | } else if (kind == f75373) { | ||
645 | name = "f75373"; | ||
646 | } | ||
647 | |||
648 | dev_info(&adapter->dev, "found %s version: %02X\n", name, version); | ||
649 | strlcpy(client->name, name, I2C_NAME_SIZE); | ||
650 | data->kind = kind; | ||
651 | mutex_init(&data->update_lock); | ||
652 | if ((err = i2c_attach_client(client))) | ||
653 | goto exit_free; | ||
654 | |||
655 | if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) | ||
656 | goto exit_detach; | ||
657 | |||
658 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
659 | if (IS_ERR(data->hwmon_dev)) { | ||
660 | err = PTR_ERR(data->hwmon_dev); | ||
661 | goto exit_remove; | ||
662 | } | ||
663 | |||
664 | return 0; | ||
665 | |||
666 | exit_remove: | ||
667 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
668 | exit_detach: | ||
669 | i2c_detach_client(client); | ||
670 | exit_free: | ||
671 | kfree(data); | ||
672 | exit: | ||
673 | return err; | ||
674 | } | ||
675 | |||
676 | static int __init sensors_f75375_init(void) | ||
677 | { | ||
678 | return i2c_add_driver(&f75375_driver); | ||
679 | } | ||
680 | |||
681 | static void __exit sensors_f75375_exit(void) | ||
682 | { | ||
683 | i2c_del_driver(&f75375_driver); | ||
684 | } | ||
685 | |||
686 | MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>"); | ||
687 | MODULE_LICENSE("GPL"); | ||
688 | MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver"); | ||
689 | |||
690 | module_init(sensors_f75375_init); | ||
691 | module_exit(sensors_f75375_exit); | ||
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index b34b546c68b8..e67c36953b2d 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c | |||
@@ -134,7 +134,7 @@ static struct i2c_driver fscher_driver = { | |||
134 | 134 | ||
135 | struct fscher_data { | 135 | struct fscher_data { |
136 | struct i2c_client client; | 136 | struct i2c_client client; |
137 | struct class_device *class_dev; | 137 | struct device *hwmon_dev; |
138 | struct mutex update_lock; | 138 | struct mutex update_lock; |
139 | char valid; /* zero until following fields are valid */ | 139 | char valid; /* zero until following fields are valid */ |
140 | unsigned long last_updated; /* in jiffies */ | 140 | unsigned long last_updated; /* in jiffies */ |
@@ -344,9 +344,9 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) | |||
344 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) | 344 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) |
345 | goto exit_detach; | 345 | goto exit_detach; |
346 | 346 | ||
347 | data->class_dev = hwmon_device_register(&new_client->dev); | 347 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
348 | if (IS_ERR(data->class_dev)) { | 348 | if (IS_ERR(data->hwmon_dev)) { |
349 | err = PTR_ERR(data->class_dev); | 349 | err = PTR_ERR(data->hwmon_dev); |
350 | goto exit_remove_files; | 350 | goto exit_remove_files; |
351 | } | 351 | } |
352 | 352 | ||
@@ -367,7 +367,7 @@ static int fscher_detach_client(struct i2c_client *client) | |||
367 | struct fscher_data *data = i2c_get_clientdata(client); | 367 | struct fscher_data *data = i2c_get_clientdata(client); |
368 | int err; | 368 | int err; |
369 | 369 | ||
370 | hwmon_device_unregister(data->class_dev); | 370 | hwmon_device_unregister(data->hwmon_dev); |
371 | sysfs_remove_group(&client->dev.kobj, &fscher_group); | 371 | sysfs_remove_group(&client->dev.kobj, &fscher_group); |
372 | 372 | ||
373 | if ((err = i2c_detach_client(client))) | 373 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c new file mode 100644 index 000000000000..63a4df0580db --- /dev/null +++ b/drivers/hwmon/fschmd.c | |||
@@ -0,0 +1,778 @@ | |||
1 | /* fschmd.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes, | ||
22 | * Scylla, Heracles and Heimdall chips | ||
23 | * | ||
24 | * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6 | ||
25 | * (candidate) fschmd drivers: | ||
26 | * Copyright (C) 2006 Thilo Cestonaro | ||
27 | * <thilo.cestonaro.external@fujitsu-siemens.com> | ||
28 | * Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch> | ||
29 | * Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de> | ||
30 | * Copyright (c) 2001 Martin Knoblauch <mkn@teraport.de, knobi@knobisoft.de> | ||
31 | * Copyright (C) 2000 Hermann Jung <hej@odn.de> | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/jiffies.h> | ||
38 | #include <linux/i2c.h> | ||
39 | #include <linux/hwmon.h> | ||
40 | #include <linux/hwmon-sysfs.h> | ||
41 | #include <linux/err.h> | ||
42 | #include <linux/mutex.h> | ||
43 | #include <linux/sysfs.h> | ||
44 | |||
45 | /* Addresses to scan */ | ||
46 | static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | ||
47 | |||
48 | /* Insmod parameters */ | ||
49 | I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); | ||
50 | |||
51 | /* | ||
52 | * The FSCHMD registers and other defines | ||
53 | */ | ||
54 | |||
55 | /* chip identification */ | ||
56 | #define FSCHMD_REG_IDENT_0 0x00 | ||
57 | #define FSCHMD_REG_IDENT_1 0x01 | ||
58 | #define FSCHMD_REG_IDENT_2 0x02 | ||
59 | #define FSCHMD_REG_REVISION 0x03 | ||
60 | |||
61 | /* global control and status */ | ||
62 | #define FSCHMD_REG_EVENT_STATE 0x04 | ||
63 | #define FSCHMD_REG_CONTROL 0x05 | ||
64 | |||
65 | #define FSCHMD_CONTROL_ALERT_LED_MASK 0x01 | ||
66 | |||
67 | /* watchdog (support to be implemented) */ | ||
68 | #define FSCHMD_REG_WDOG_PRESET 0x28 | ||
69 | #define FSCHMD_REG_WDOG_STATE 0x23 | ||
70 | #define FSCHMD_REG_WDOG_CONTROL 0x21 | ||
71 | |||
72 | /* voltages, weird order is to keep the same order as the old drivers */ | ||
73 | static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 }; | ||
74 | |||
75 | /* minimum pwm at which the fan is driven (pwm can by increased depending on | ||
76 | the temp. Notice that for the scy some fans share there minimum speed. | ||
77 | Also notice that with the scy the sensor order is different then with the | ||
78 | other chips, this order was in the 2.4 driver and kept for consistency. */ | ||
79 | static const u8 FSCHMD_REG_FAN_MIN[5][6] = { | ||
80 | { 0x55, 0x65 }, /* pos */ | ||
81 | { 0x55, 0x65, 0xb5 }, /* her */ | ||
82 | { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */ | ||
83 | { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */ | ||
84 | { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */ | ||
85 | }; | ||
86 | |||
87 | /* actual fan speed */ | ||
88 | static const u8 FSCHMD_REG_FAN_ACT[5][6] = { | ||
89 | { 0x0e, 0x6b, 0xab }, /* pos */ | ||
90 | { 0x0e, 0x6b, 0xbb }, /* her */ | ||
91 | { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */ | ||
92 | { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */ | ||
93 | { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */ | ||
94 | }; | ||
95 | |||
96 | /* fan status registers */ | ||
97 | static const u8 FSCHMD_REG_FAN_STATE[5][6] = { | ||
98 | { 0x0d, 0x62, 0xa2 }, /* pos */ | ||
99 | { 0x0d, 0x62, 0xb2 }, /* her */ | ||
100 | { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */ | ||
101 | { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */ | ||
102 | { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */ | ||
103 | }; | ||
104 | |||
105 | /* fan ripple / divider registers */ | ||
106 | static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = { | ||
107 | { 0x0f, 0x6f, 0xaf }, /* pos */ | ||
108 | { 0x0f, 0x6f, 0xbf }, /* her */ | ||
109 | { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */ | ||
110 | { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */ | ||
111 | { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */ | ||
112 | }; | ||
113 | |||
114 | static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 }; | ||
115 | |||
116 | /* Fan status register bitmasks */ | ||
117 | #define FSCHMD_FAN_ALARM_MASK 0x04 /* called fault by FSC! */ | ||
118 | #define FSCHMD_FAN_NOT_PRESENT_MASK 0x08 /* not documented */ | ||
119 | |||
120 | |||
121 | /* actual temperature registers */ | ||
122 | static const u8 FSCHMD_REG_TEMP_ACT[5][5] = { | ||
123 | { 0x64, 0x32, 0x35 }, /* pos */ | ||
124 | { 0x64, 0x32, 0x35 }, /* her */ | ||
125 | { 0x64, 0xD0, 0x32, 0x35 }, /* scy */ | ||
126 | { 0x64, 0x32, 0x35 }, /* hrc */ | ||
127 | { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */ | ||
128 | }; | ||
129 | |||
130 | /* temperature state registers */ | ||
131 | static const u8 FSCHMD_REG_TEMP_STATE[5][5] = { | ||
132 | { 0x71, 0x81, 0x91 }, /* pos */ | ||
133 | { 0x71, 0x81, 0x91 }, /* her */ | ||
134 | { 0x71, 0xd1, 0x81, 0x91 }, /* scy */ | ||
135 | { 0x71, 0x81, 0x91 }, /* hrc */ | ||
136 | { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /*Â hmd */ | ||
137 | }; | ||
138 | |||
139 | /* temperature high limit registers, FSC does not document these. Proven to be | ||
140 | there with field testing on the fscher and fschrc, already supported / used | ||
141 | in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers | ||
142 | at these addresses, but doesn't want to confirm they are the same as with | ||
143 | the fscher?? */ | ||
144 | static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = { | ||
145 | { 0, 0, 0 }, /* pos */ | ||
146 | { 0x76, 0x86, 0x96 }, /* her */ | ||
147 | { 0x76, 0xd6, 0x86, 0x96 }, /* scy */ | ||
148 | { 0x76, 0x86, 0x96 }, /* hrc */ | ||
149 | { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /*Â hmd */ | ||
150 | }; | ||
151 | |||
152 | /* These were found through experimenting with an fscher, currently they are | ||
153 | not used, but we keep them around for future reference. | ||
154 | static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; | ||
155 | static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ | ||
156 | |||
157 | static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 }; | ||
158 | |||
159 | /* temp status register bitmasks */ | ||
160 | #define FSCHMD_TEMP_WORKING_MASK 0x01 | ||
161 | #define FSCHMD_TEMP_ALERT_MASK 0x02 | ||
162 | /* there only really is an alarm if the sensor is working and alert == 1 */ | ||
163 | #define FSCHMD_TEMP_ALARM_MASK \ | ||
164 | (FSCHMD_TEMP_WORKING_MASK | FSCHMD_TEMP_ALERT_MASK) | ||
165 | |||
166 | /* our driver name */ | ||
167 | #define FSCHMD_NAME "fschmd" | ||
168 | |||
169 | /* | ||
170 | * Functions declarations | ||
171 | */ | ||
172 | |||
173 | static int fschmd_attach_adapter(struct i2c_adapter *adapter); | ||
174 | static int fschmd_detach_client(struct i2c_client *client); | ||
175 | static struct fschmd_data *fschmd_update_device(struct device *dev); | ||
176 | |||
177 | /* | ||
178 | * Driver data (common to all clients) | ||
179 | */ | ||
180 | |||
181 | static struct i2c_driver fschmd_driver = { | ||
182 | .driver = { | ||
183 | .name = FSCHMD_NAME, | ||
184 | }, | ||
185 | .attach_adapter = fschmd_attach_adapter, | ||
186 | .detach_client = fschmd_detach_client, | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * Client data (each client gets its own) | ||
191 | */ | ||
192 | |||
193 | struct fschmd_data { | ||
194 | struct i2c_client client; | ||
195 | struct device *hwmon_dev; | ||
196 | struct mutex update_lock; | ||
197 | int kind; | ||
198 | char valid; /* zero until following fields are valid */ | ||
199 | unsigned long last_updated; /* in jiffies */ | ||
200 | |||
201 | /* register values */ | ||
202 | u8 global_control; /* global control register */ | ||
203 | u8 volt[3]; /* 12, 5, battery voltage */ | ||
204 | u8 temp_act[5]; /* temperature */ | ||
205 | u8 temp_status[5]; /* status of sensor */ | ||
206 | u8 temp_max[5]; /* high temp limit, notice: undocumented! */ | ||
207 | u8 fan_act[6]; /* fans revolutions per second */ | ||
208 | u8 fan_status[6]; /* fan status */ | ||
209 | u8 fan_min[6]; /* fan min value for rps */ | ||
210 | u8 fan_ripple[6]; /* divider for rps */ | ||
211 | }; | ||
212 | |||
213 | /* | ||
214 | * Sysfs attr show / store functions | ||
215 | */ | ||
216 | |||
217 | static ssize_t show_in_value(struct device *dev, | ||
218 | struct device_attribute *devattr, char *buf) | ||
219 | { | ||
220 | const int max_reading[3] = { 14200, 6600, 3300 }; | ||
221 | int index = to_sensor_dev_attr(devattr)->index; | ||
222 | struct fschmd_data *data = fschmd_update_device(dev); | ||
223 | |||
224 | return sprintf(buf, "%d\n", (data->volt[index] * | ||
225 | max_reading[index] + 128) / 255); | ||
226 | } | ||
227 | |||
228 | |||
229 | #define TEMP_FROM_REG(val) (((val) - 128) * 1000) | ||
230 | |||
231 | static ssize_t show_temp_value(struct device *dev, | ||
232 | struct device_attribute *devattr, char *buf) | ||
233 | { | ||
234 | int index = to_sensor_dev_attr(devattr)->index; | ||
235 | struct fschmd_data *data = fschmd_update_device(dev); | ||
236 | |||
237 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[index])); | ||
238 | } | ||
239 | |||
240 | static ssize_t show_temp_max(struct device *dev, | ||
241 | struct device_attribute *devattr, char *buf) | ||
242 | { | ||
243 | int index = to_sensor_dev_attr(devattr)->index; | ||
244 | struct fschmd_data *data = fschmd_update_device(dev); | ||
245 | |||
246 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[index])); | ||
247 | } | ||
248 | |||
249 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
250 | *devattr, const char *buf, size_t count) | ||
251 | { | ||
252 | int index = to_sensor_dev_attr(devattr)->index; | ||
253 | struct fschmd_data *data = dev_get_drvdata(dev); | ||
254 | long v = simple_strtol(buf, NULL, 10) / 1000; | ||
255 | |||
256 | v = SENSORS_LIMIT(v, -128, 127) + 128; | ||
257 | |||
258 | mutex_lock(&data->update_lock); | ||
259 | i2c_smbus_write_byte_data(&data->client, | ||
260 | FSCHMD_REG_TEMP_LIMIT[data->kind][index], v); | ||
261 | data->temp_max[index] = v; | ||
262 | mutex_unlock(&data->update_lock); | ||
263 | |||
264 | return count; | ||
265 | } | ||
266 | |||
267 | static ssize_t show_temp_fault(struct device *dev, | ||
268 | struct device_attribute *devattr, char *buf) | ||
269 | { | ||
270 | int index = to_sensor_dev_attr(devattr)->index; | ||
271 | struct fschmd_data *data = fschmd_update_device(dev); | ||
272 | |||
273 | /* bit 0 set means sensor working ok, so no fault! */ | ||
274 | if (data->temp_status[index] & FSCHMD_TEMP_WORKING_MASK) | ||
275 | return sprintf(buf, "0\n"); | ||
276 | else | ||
277 | return sprintf(buf, "1\n"); | ||
278 | } | ||
279 | |||
280 | static ssize_t show_temp_alarm(struct device *dev, | ||
281 | struct device_attribute *devattr, char *buf) | ||
282 | { | ||
283 | int index = to_sensor_dev_attr(devattr)->index; | ||
284 | struct fschmd_data *data = fschmd_update_device(dev); | ||
285 | |||
286 | if ((data->temp_status[index] & FSCHMD_TEMP_ALARM_MASK) == | ||
287 | FSCHMD_TEMP_ALARM_MASK) | ||
288 | return sprintf(buf, "1\n"); | ||
289 | else | ||
290 | return sprintf(buf, "0\n"); | ||
291 | } | ||
292 | |||
293 | |||
294 | #define RPM_FROM_REG(val) ((val) * 60) | ||
295 | |||
296 | static ssize_t show_fan_value(struct device *dev, | ||
297 | struct device_attribute *devattr, char *buf) | ||
298 | { | ||
299 | int index = to_sensor_dev_attr(devattr)->index; | ||
300 | struct fschmd_data *data = fschmd_update_device(dev); | ||
301 | |||
302 | return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[index])); | ||
303 | } | ||
304 | |||
305 | static ssize_t show_fan_div(struct device *dev, | ||
306 | struct device_attribute *devattr, char *buf) | ||
307 | { | ||
308 | int index = to_sensor_dev_attr(devattr)->index; | ||
309 | struct fschmd_data *data = fschmd_update_device(dev); | ||
310 | |||
311 | /* bits 2..7 reserved => mask with 3 */ | ||
312 | return sprintf(buf, "%d\n", 1 << (data->fan_ripple[index] & 3)); | ||
313 | } | ||
314 | |||
315 | static ssize_t store_fan_div(struct device *dev, struct device_attribute | ||
316 | *devattr, const char *buf, size_t count) | ||
317 | { | ||
318 | u8 reg; | ||
319 | int index = to_sensor_dev_attr(devattr)->index; | ||
320 | struct fschmd_data *data = dev_get_drvdata(dev); | ||
321 | /* supported values: 2, 4, 8 */ | ||
322 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
323 | |||
324 | switch (v) { | ||
325 | case 2: v = 1; break; | ||
326 | case 4: v = 2; break; | ||
327 | case 8: v = 3; break; | ||
328 | default: | ||
329 | dev_err(dev, "fan_div value %lu not supported. " | ||
330 | "Choose one of 2, 4 or 8!\n", v); | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | |||
334 | mutex_lock(&data->update_lock); | ||
335 | |||
336 | reg = i2c_smbus_read_byte_data(&data->client, | ||
337 | FSCHMD_REG_FAN_RIPPLE[data->kind][index]); | ||
338 | |||
339 | /* bits 2..7 reserved => mask with 0x03 */ | ||
340 | reg &= ~0x03; | ||
341 | reg |= v; | ||
342 | |||
343 | i2c_smbus_write_byte_data(&data->client, | ||
344 | FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg); | ||
345 | |||
346 | data->fan_ripple[index] = reg; | ||
347 | |||
348 | mutex_unlock(&data->update_lock); | ||
349 | |||
350 | return count; | ||
351 | } | ||
352 | |||
353 | static ssize_t show_fan_alarm(struct device *dev, | ||
354 | struct device_attribute *devattr, char *buf) | ||
355 | { | ||
356 | int index = to_sensor_dev_attr(devattr)->index; | ||
357 | struct fschmd_data *data = fschmd_update_device(dev); | ||
358 | |||
359 | if (data->fan_status[index] & FSCHMD_FAN_ALARM_MASK) | ||
360 | return sprintf(buf, "1\n"); | ||
361 | else | ||
362 | return sprintf(buf, "0\n"); | ||
363 | } | ||
364 | |||
365 | static ssize_t show_fan_fault(struct device *dev, | ||
366 | struct device_attribute *devattr, char *buf) | ||
367 | { | ||
368 | int index = to_sensor_dev_attr(devattr)->index; | ||
369 | struct fschmd_data *data = fschmd_update_device(dev); | ||
370 | |||
371 | if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT_MASK) | ||
372 | return sprintf(buf, "1\n"); | ||
373 | else | ||
374 | return sprintf(buf, "0\n"); | ||
375 | } | ||
376 | |||
377 | |||
378 | static ssize_t show_pwm_auto_point1_pwm(struct device *dev, | ||
379 | struct device_attribute *devattr, char *buf) | ||
380 | { | ||
381 | int index = to_sensor_dev_attr(devattr)->index; | ||
382 | int val = fschmd_update_device(dev)->fan_min[index]; | ||
383 | |||
384 | /* 0 = allow turning off, 1-255 = 50-100% */ | ||
385 | if (val) | ||
386 | val = val / 2 + 128; | ||
387 | |||
388 | return sprintf(buf, "%d\n", val); | ||
389 | } | ||
390 | |||
391 | static ssize_t store_pwm_auto_point1_pwm(struct device *dev, | ||
392 | struct device_attribute *devattr, const char *buf, size_t count) | ||
393 | { | ||
394 | int index = to_sensor_dev_attr(devattr)->index; | ||
395 | struct fschmd_data *data = dev_get_drvdata(dev); | ||
396 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
397 | |||
398 | /* register: 0 = allow turning off, 1-255 = 50-100% */ | ||
399 | if (v) { | ||
400 | v = SENSORS_LIMIT(v, 128, 255); | ||
401 | v = (v - 128) * 2 + 1; | ||
402 | } | ||
403 | |||
404 | mutex_lock(&data->update_lock); | ||
405 | |||
406 | i2c_smbus_write_byte_data(&data->client, | ||
407 | FSCHMD_REG_FAN_MIN[data->kind][index], v); | ||
408 | data->fan_min[index] = v; | ||
409 | |||
410 | mutex_unlock(&data->update_lock); | ||
411 | |||
412 | return count; | ||
413 | } | ||
414 | |||
415 | |||
416 | /* The FSC hwmon family has the ability to force an attached alert led to flash | ||
417 | from software, we export this as an alert_led sysfs attr */ | ||
418 | static ssize_t show_alert_led(struct device *dev, | ||
419 | struct device_attribute *devattr, char *buf) | ||
420 | { | ||
421 | struct fschmd_data *data = fschmd_update_device(dev); | ||
422 | |||
423 | if (data->global_control & FSCHMD_CONTROL_ALERT_LED_MASK) | ||
424 | return sprintf(buf, "1\n"); | ||
425 | else | ||
426 | return sprintf(buf, "0\n"); | ||
427 | } | ||
428 | |||
429 | static ssize_t store_alert_led(struct device *dev, | ||
430 | struct device_attribute *devattr, const char *buf, size_t count) | ||
431 | { | ||
432 | u8 reg; | ||
433 | struct fschmd_data *data = dev_get_drvdata(dev); | ||
434 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
435 | |||
436 | mutex_lock(&data->update_lock); | ||
437 | |||
438 | reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL); | ||
439 | |||
440 | if (v) | ||
441 | reg |= FSCHMD_CONTROL_ALERT_LED_MASK; | ||
442 | else | ||
443 | reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK; | ||
444 | |||
445 | i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg); | ||
446 | |||
447 | data->global_control = reg; | ||
448 | |||
449 | mutex_unlock(&data->update_lock); | ||
450 | |||
451 | return count; | ||
452 | } | ||
453 | |||
454 | static struct sensor_device_attribute fschmd_attr[] = { | ||
455 | SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0), | ||
456 | SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1), | ||
457 | SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2), | ||
458 | SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0), | ||
459 | }; | ||
460 | |||
461 | static struct sensor_device_attribute fschmd_temp_attr[] = { | ||
462 | SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), | ||
463 | SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0), | ||
464 | SENSOR_ATTR(temp1_fault, 0444, show_temp_fault, NULL, 0), | ||
465 | SENSOR_ATTR(temp1_alarm, 0444, show_temp_alarm, NULL, 0), | ||
466 | SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1), | ||
467 | SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1), | ||
468 | SENSOR_ATTR(temp2_fault, 0444, show_temp_fault, NULL, 1), | ||
469 | SENSOR_ATTR(temp2_alarm, 0444, show_temp_alarm, NULL, 1), | ||
470 | SENSOR_ATTR(temp3_input, 0444, show_temp_value, NULL, 2), | ||
471 | SENSOR_ATTR(temp3_max, 0644, show_temp_max, store_temp_max, 2), | ||
472 | SENSOR_ATTR(temp3_fault, 0444, show_temp_fault, NULL, 2), | ||
473 | SENSOR_ATTR(temp3_alarm, 0444, show_temp_alarm, NULL, 2), | ||
474 | SENSOR_ATTR(temp4_input, 0444, show_temp_value, NULL, 3), | ||
475 | SENSOR_ATTR(temp4_max, 0644, show_temp_max, store_temp_max, 3), | ||
476 | SENSOR_ATTR(temp4_fault, 0444, show_temp_fault, NULL, 3), | ||
477 | SENSOR_ATTR(temp4_alarm, 0444, show_temp_alarm, NULL, 3), | ||
478 | SENSOR_ATTR(temp5_input, 0444, show_temp_value, NULL, 4), | ||
479 | SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4), | ||
480 | SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4), | ||
481 | SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4), | ||
482 | }; | ||
483 | |||
484 | static struct sensor_device_attribute fschmd_fan_attr[] = { | ||
485 | SENSOR_ATTR(fan1_input, 0444, show_fan_value, NULL, 0), | ||
486 | SENSOR_ATTR(fan1_div, 0644, show_fan_div, store_fan_div, 0), | ||
487 | SENSOR_ATTR(fan1_alarm, 0444, show_fan_alarm, NULL, 0), | ||
488 | SENSOR_ATTR(fan1_fault, 0444, show_fan_fault, NULL, 0), | ||
489 | SENSOR_ATTR(pwm1_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
490 | store_pwm_auto_point1_pwm, 0), | ||
491 | SENSOR_ATTR(fan2_input, 0444, show_fan_value, NULL, 1), | ||
492 | SENSOR_ATTR(fan2_div, 0644, show_fan_div, store_fan_div, 1), | ||
493 | SENSOR_ATTR(fan2_alarm, 0444, show_fan_alarm, NULL, 1), | ||
494 | SENSOR_ATTR(fan2_fault, 0444, show_fan_fault, NULL, 1), | ||
495 | SENSOR_ATTR(pwm2_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
496 | store_pwm_auto_point1_pwm, 1), | ||
497 | SENSOR_ATTR(fan3_input, 0444, show_fan_value, NULL, 2), | ||
498 | SENSOR_ATTR(fan3_div, 0644, show_fan_div, store_fan_div, 2), | ||
499 | SENSOR_ATTR(fan3_alarm, 0444, show_fan_alarm, NULL, 2), | ||
500 | SENSOR_ATTR(fan3_fault, 0444, show_fan_fault, NULL, 2), | ||
501 | SENSOR_ATTR(pwm3_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
502 | store_pwm_auto_point1_pwm, 2), | ||
503 | SENSOR_ATTR(fan4_input, 0444, show_fan_value, NULL, 3), | ||
504 | SENSOR_ATTR(fan4_div, 0644, show_fan_div, store_fan_div, 3), | ||
505 | SENSOR_ATTR(fan4_alarm, 0444, show_fan_alarm, NULL, 3), | ||
506 | SENSOR_ATTR(fan4_fault, 0444, show_fan_fault, NULL, 3), | ||
507 | SENSOR_ATTR(pwm4_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
508 | store_pwm_auto_point1_pwm, 3), | ||
509 | SENSOR_ATTR(fan5_input, 0444, show_fan_value, NULL, 4), | ||
510 | SENSOR_ATTR(fan5_div, 0644, show_fan_div, store_fan_div, 4), | ||
511 | SENSOR_ATTR(fan5_alarm, 0444, show_fan_alarm, NULL, 4), | ||
512 | SENSOR_ATTR(fan5_fault, 0444, show_fan_fault, NULL, 4), | ||
513 | SENSOR_ATTR(pwm5_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
514 | store_pwm_auto_point1_pwm, 4), | ||
515 | SENSOR_ATTR(fan6_input, 0444, show_fan_value, NULL, 5), | ||
516 | SENSOR_ATTR(fan6_div, 0644, show_fan_div, store_fan_div, 5), | ||
517 | SENSOR_ATTR(fan6_alarm, 0444, show_fan_alarm, NULL, 5), | ||
518 | SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5), | ||
519 | SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, | ||
520 | store_pwm_auto_point1_pwm, 5), | ||
521 | }; | ||
522 | |||
523 | |||
524 | /* | ||
525 | * Real code | ||
526 | */ | ||
527 | |||
528 | static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) | ||
529 | { | ||
530 | struct i2c_client *client; | ||
531 | struct fschmd_data *data; | ||
532 | u8 revision; | ||
533 | const char * const names[5] = { "Poseidon", "Hermes", "Scylla", | ||
534 | "Heracles", "Heimdall" }; | ||
535 | const char * const client_names[5] = { "fscpos", "fscher", "fscscy", | ||
536 | "fschrc", "fschmd" }; | ||
537 | int i, err = 0; | ||
538 | |||
539 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
540 | return 0; | ||
541 | |||
542 | /* OK. For now, we presume we have a valid client. We now create the | ||
543 | * client structure, even though we cannot fill it completely yet. | ||
544 | * But it allows us to access i2c_smbus_read_byte_data. */ | ||
545 | if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL))) | ||
546 | return -ENOMEM; | ||
547 | |||
548 | client = &data->client; | ||
549 | i2c_set_clientdata(client, data); | ||
550 | client->addr = address; | ||
551 | client->adapter = adapter; | ||
552 | client->driver = &fschmd_driver; | ||
553 | mutex_init(&data->update_lock); | ||
554 | |||
555 | /* Detect & Identify the chip */ | ||
556 | if (kind <= 0) { | ||
557 | char id[4]; | ||
558 | |||
559 | id[0] = i2c_smbus_read_byte_data(client, | ||
560 | FSCHMD_REG_IDENT_0); | ||
561 | id[1] = i2c_smbus_read_byte_data(client, | ||
562 | FSCHMD_REG_IDENT_1); | ||
563 | id[2] = i2c_smbus_read_byte_data(client, | ||
564 | FSCHMD_REG_IDENT_2); | ||
565 | id[3] = '\0'; | ||
566 | |||
567 | if (!strcmp(id, "PEG")) | ||
568 | kind = fscpos; | ||
569 | else if (!strcmp(id, "HER")) | ||
570 | kind = fscher; | ||
571 | else if (!strcmp(id, "SCY")) | ||
572 | kind = fscscy; | ||
573 | else if (!strcmp(id, "HRC")) | ||
574 | kind = fschrc; | ||
575 | else if (!strcmp(id, "HMD")) | ||
576 | kind = fschmd; | ||
577 | else | ||
578 | goto exit_free; | ||
579 | } | ||
580 | |||
581 | if (kind == fscpos) { | ||
582 | /* The Poseidon has hardwired temp limits, fill these | ||
583 | in for the alarm resetting code */ | ||
584 | data->temp_max[0] = 70 + 128; | ||
585 | data->temp_max[1] = 50 + 128; | ||
586 | data->temp_max[2] = 50 + 128; | ||
587 | } | ||
588 | |||
589 | /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ | ||
590 | data->kind = kind - 1; | ||
591 | strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE); | ||
592 | |||
593 | /* Tell the I2C layer a new client has arrived */ | ||
594 | if ((err = i2c_attach_client(client))) | ||
595 | goto exit_free; | ||
596 | |||
597 | for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) { | ||
598 | err = device_create_file(&client->dev, | ||
599 | &fschmd_attr[i].dev_attr); | ||
600 | if (err) | ||
601 | goto exit_detach; | ||
602 | } | ||
603 | |||
604 | for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) { | ||
605 | /* Poseidon doesn't have TEMP_LIMIT registers */ | ||
606 | if (kind == fscpos && fschmd_temp_attr[i].dev_attr.show == | ||
607 | show_temp_max) | ||
608 | continue; | ||
609 | |||
610 | err = device_create_file(&client->dev, | ||
611 | &fschmd_temp_attr[i].dev_attr); | ||
612 | if (err) | ||
613 | goto exit_detach; | ||
614 | } | ||
615 | |||
616 | for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++) { | ||
617 | /* Poseidon doesn't have a FAN_MIN register for its 3rd fan */ | ||
618 | if (kind == fscpos && | ||
619 | !strcmp(fschmd_fan_attr[i].dev_attr.attr.name, | ||
620 | "pwm3_auto_point1_pwm")) | ||
621 | continue; | ||
622 | |||
623 | err = device_create_file(&client->dev, | ||
624 | &fschmd_fan_attr[i].dev_attr); | ||
625 | if (err) | ||
626 | goto exit_detach; | ||
627 | } | ||
628 | |||
629 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
630 | if (IS_ERR(data->hwmon_dev)) { | ||
631 | err = PTR_ERR(data->hwmon_dev); | ||
632 | data->hwmon_dev = NULL; | ||
633 | goto exit_detach; | ||
634 | } | ||
635 | |||
636 | revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); | ||
637 | printk(KERN_INFO FSCHMD_NAME ": Detected FSC %s chip, revision: %d\n", | ||
638 | names[data->kind], (int) revision); | ||
639 | |||
640 | return 0; | ||
641 | |||
642 | exit_detach: | ||
643 | fschmd_detach_client(client); /* will also free data for us */ | ||
644 | return err; | ||
645 | |||
646 | exit_free: | ||
647 | kfree(data); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int fschmd_attach_adapter(struct i2c_adapter *adapter) | ||
652 | { | ||
653 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
654 | return 0; | ||
655 | return i2c_probe(adapter, &addr_data, fschmd_detect); | ||
656 | } | ||
657 | |||
658 | static int fschmd_detach_client(struct i2c_client *client) | ||
659 | { | ||
660 | struct fschmd_data *data = i2c_get_clientdata(client); | ||
661 | int i, err; | ||
662 | |||
663 | /* Check if registered in case we're called from fschmd_detect | ||
664 | to cleanup after an error */ | ||
665 | if (data->hwmon_dev) | ||
666 | hwmon_device_unregister(data->hwmon_dev); | ||
667 | |||
668 | for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) | ||
669 | device_remove_file(&client->dev, &fschmd_attr[i].dev_attr); | ||
670 | for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) | ||
671 | device_remove_file(&client->dev, | ||
672 | &fschmd_temp_attr[i].dev_attr); | ||
673 | for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++) | ||
674 | device_remove_file(&client->dev, | ||
675 | &fschmd_fan_attr[i].dev_attr); | ||
676 | |||
677 | if ((err = i2c_detach_client(client))) | ||
678 | return err; | ||
679 | |||
680 | kfree(data); | ||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | static struct fschmd_data *fschmd_update_device(struct device *dev) | ||
685 | { | ||
686 | struct i2c_client *client = to_i2c_client(dev); | ||
687 | struct fschmd_data *data = i2c_get_clientdata(client); | ||
688 | int i; | ||
689 | |||
690 | mutex_lock(&data->update_lock); | ||
691 | |||
692 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
693 | |||
694 | for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->kind]; i++) { | ||
695 | data->temp_act[i] = i2c_smbus_read_byte_data(client, | ||
696 | FSCHMD_REG_TEMP_ACT[data->kind][i]); | ||
697 | data->temp_status[i] = i2c_smbus_read_byte_data(client, | ||
698 | FSCHMD_REG_TEMP_STATE[data->kind][i]); | ||
699 | |||
700 | /* The fscpos doesn't have TEMP_LIMIT registers */ | ||
701 | if (FSCHMD_REG_TEMP_LIMIT[data->kind][i]) | ||
702 | data->temp_max[i] = i2c_smbus_read_byte_data( | ||
703 | client, | ||
704 | FSCHMD_REG_TEMP_LIMIT[data->kind][i]); | ||
705 | |||
706 | /* reset alarm if the alarm condition is gone, | ||
707 | the chip doesn't do this itself */ | ||
708 | if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) == | ||
709 | FSCHMD_TEMP_ALARM_MASK && | ||
710 | data->temp_act[i] < data->temp_max[i]) | ||
711 | i2c_smbus_write_byte_data(client, | ||
712 | FSCHMD_REG_TEMP_STATE[data->kind][i], | ||
713 | FSCHMD_TEMP_ALERT_MASK); | ||
714 | } | ||
715 | |||
716 | for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) { | ||
717 | data->fan_act[i] = i2c_smbus_read_byte_data(client, | ||
718 | FSCHMD_REG_FAN_ACT[data->kind][i]); | ||
719 | data->fan_status[i] = i2c_smbus_read_byte_data(client, | ||
720 | FSCHMD_REG_FAN_STATE[data->kind][i]); | ||
721 | data->fan_ripple[i] = i2c_smbus_read_byte_data(client, | ||
722 | FSCHMD_REG_FAN_RIPPLE[data->kind][i]); | ||
723 | |||
724 | /* The fscpos third fan doesn't have a fan_min */ | ||
725 | if (FSCHMD_REG_FAN_MIN[data->kind][i]) | ||
726 | data->fan_min[i] = i2c_smbus_read_byte_data( | ||
727 | client, | ||
728 | FSCHMD_REG_FAN_MIN[data->kind][i]); | ||
729 | |||
730 | /* reset fan status if speed is back to > 0 */ | ||
731 | if ((data->fan_status[i] & FSCHMD_FAN_ALARM_MASK) && | ||
732 | data->fan_act[i]) | ||
733 | i2c_smbus_write_byte_data(client, | ||
734 | FSCHMD_REG_FAN_STATE[data->kind][i], | ||
735 | FSCHMD_FAN_ALARM_MASK); | ||
736 | } | ||
737 | |||
738 | for (i = 0; i < 3; i++) | ||
739 | data->volt[i] = i2c_smbus_read_byte_data(client, | ||
740 | FSCHMD_REG_VOLT[i]); | ||
741 | |||
742 | data->global_control = i2c_smbus_read_byte_data(client, | ||
743 | FSCHMD_REG_CONTROL); | ||
744 | |||
745 | /* To be implemented in the future | ||
746 | data->watchdog[0] = i2c_smbus_read_byte_data(client, | ||
747 | FSCHMD_REG_WDOG_PRESET); | ||
748 | data->watchdog[1] = i2c_smbus_read_byte_data(client, | ||
749 | FSCHMD_REG_WDOG_STATE); | ||
750 | data->watchdog[2] = i2c_smbus_read_byte_data(client, | ||
751 | FSCHMD_REG_WDOG_CONTROL); */ | ||
752 | |||
753 | data->last_updated = jiffies; | ||
754 | data->valid = 1; | ||
755 | } | ||
756 | |||
757 | mutex_unlock(&data->update_lock); | ||
758 | |||
759 | return data; | ||
760 | } | ||
761 | |||
762 | static int __init fschmd_init(void) | ||
763 | { | ||
764 | return i2c_add_driver(&fschmd_driver); | ||
765 | } | ||
766 | |||
767 | static void __exit fschmd_exit(void) | ||
768 | { | ||
769 | i2c_del_driver(&fschmd_driver); | ||
770 | } | ||
771 | |||
772 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | ||
773 | MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and " | ||
774 | "Heimdall driver"); | ||
775 | MODULE_LICENSE("GPL"); | ||
776 | |||
777 | module_init(fschmd_init); | ||
778 | module_exit(fschmd_exit); | ||
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index ea506a77f9c9..92c9703d0ac0 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -115,7 +115,7 @@ static struct i2c_driver fscpos_driver = { | |||
115 | */ | 115 | */ |
116 | struct fscpos_data { | 116 | struct fscpos_data { |
117 | struct i2c_client client; | 117 | struct i2c_client client; |
118 | struct class_device *class_dev; | 118 | struct device *hwmon_dev; |
119 | struct mutex update_lock; | 119 | struct mutex update_lock; |
120 | char valid; /* 0 until following fields are valid */ | 120 | char valid; /* 0 until following fields are valid */ |
121 | unsigned long last_updated; /* In jiffies */ | 121 | unsigned long last_updated; /* In jiffies */ |
@@ -539,9 +539,9 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) | |||
539 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) | 539 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) |
540 | goto exit_detach; | 540 | goto exit_detach; |
541 | 541 | ||
542 | data->class_dev = hwmon_device_register(&new_client->dev); | 542 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
543 | if (IS_ERR(data->class_dev)) { | 543 | if (IS_ERR(data->hwmon_dev)) { |
544 | err = PTR_ERR(data->class_dev); | 544 | err = PTR_ERR(data->hwmon_dev); |
545 | goto exit_remove_files; | 545 | goto exit_remove_files; |
546 | } | 546 | } |
547 | 547 | ||
@@ -562,7 +562,7 @@ static int fscpos_detach_client(struct i2c_client *client) | |||
562 | struct fscpos_data *data = i2c_get_clientdata(client); | 562 | struct fscpos_data *data = i2c_get_clientdata(client); |
563 | int err; | 563 | int err; |
564 | 564 | ||
565 | hwmon_device_unregister(data->class_dev); | 565 | hwmon_device_unregister(data->hwmon_dev); |
566 | sysfs_remove_group(&client->dev.kobj, &fscpos_group); | 566 | sysfs_remove_group(&client->dev.kobj, &fscpos_group); |
567 | 567 | ||
568 | if ((err = i2c_detach_client(client))) | 568 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index c103640455a3..bb58d9866a37 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -119,7 +119,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
119 | /* Each client has this additional data */ | 119 | /* Each client has this additional data */ |
120 | struct gl518_data { | 120 | struct gl518_data { |
121 | struct i2c_client client; | 121 | struct i2c_client client; |
122 | struct class_device *class_dev; | 122 | struct device *hwmon_dev; |
123 | enum chips type; | 123 | enum chips type; |
124 | 124 | ||
125 | struct mutex update_lock; | 125 | struct mutex update_lock; |
@@ -460,9 +460,9 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) | |||
460 | if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group))) | 460 | if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group))) |
461 | goto exit_detach; | 461 | goto exit_detach; |
462 | 462 | ||
463 | data->class_dev = hwmon_device_register(&new_client->dev); | 463 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
464 | if (IS_ERR(data->class_dev)) { | 464 | if (IS_ERR(data->hwmon_dev)) { |
465 | err = PTR_ERR(data->class_dev); | 465 | err = PTR_ERR(data->hwmon_dev); |
466 | goto exit_remove_files; | 466 | goto exit_remove_files; |
467 | } | 467 | } |
468 | 468 | ||
@@ -502,7 +502,7 @@ static int gl518_detach_client(struct i2c_client *client) | |||
502 | struct gl518_data *data = i2c_get_clientdata(client); | 502 | struct gl518_data *data = i2c_get_clientdata(client); |
503 | int err; | 503 | int err; |
504 | 504 | ||
505 | hwmon_device_unregister(data->class_dev); | 505 | hwmon_device_unregister(data->hwmon_dev); |
506 | sysfs_remove_group(&client->dev.kobj, &gl518_group); | 506 | sysfs_remove_group(&client->dev.kobj, &gl518_group); |
507 | 507 | ||
508 | if ((err = i2c_detach_client(client))) | 508 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index ebe7b9aaa916..a3b56c816e11 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -122,7 +122,7 @@ static struct i2c_driver gl520_driver = { | |||
122 | /* Client data */ | 122 | /* Client data */ |
123 | struct gl520_data { | 123 | struct gl520_data { |
124 | struct i2c_client client; | 124 | struct i2c_client client; |
125 | struct class_device *class_dev; | 125 | struct device *hwmon_dev; |
126 | struct mutex update_lock; | 126 | struct mutex update_lock; |
127 | char valid; /* zero until the following fields are valid */ | 127 | char valid; /* zero until the following fields are valid */ |
128 | unsigned long last_updated; /* in jiffies */ | 128 | unsigned long last_updated; /* in jiffies */ |
@@ -622,9 +622,9 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | |||
622 | } | 622 | } |
623 | 623 | ||
624 | 624 | ||
625 | data->class_dev = hwmon_device_register(&new_client->dev); | 625 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
626 | if (IS_ERR(data->class_dev)) { | 626 | if (IS_ERR(data->hwmon_dev)) { |
627 | err = PTR_ERR(data->class_dev); | 627 | err = PTR_ERR(data->hwmon_dev); |
628 | goto exit_remove_files; | 628 | goto exit_remove_files; |
629 | } | 629 | } |
630 | 630 | ||
@@ -685,7 +685,7 @@ static int gl520_detach_client(struct i2c_client *client) | |||
685 | struct gl520_data *data = i2c_get_clientdata(client); | 685 | struct gl520_data *data = i2c_get_clientdata(client); |
686 | int err; | 686 | int err; |
687 | 687 | ||
688 | hwmon_device_unregister(data->class_dev); | 688 | hwmon_device_unregister(data->hwmon_dev); |
689 | sysfs_remove_group(&client->dev.kobj, &gl520_group); | 689 | sysfs_remove_group(&client->dev.kobj, &gl520_group); |
690 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); | 690 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); |
691 | 691 | ||
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index affcc00764d3..3db28450a3b3 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -28,17 +28,17 @@ static DEFINE_IDR(hwmon_idr); | |||
28 | static DEFINE_SPINLOCK(idr_lock); | 28 | static DEFINE_SPINLOCK(idr_lock); |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * hwmon_device_register - register w/ hwmon sysfs class | 31 | * hwmon_device_register - register w/ hwmon |
32 | * @dev: the device to register | 32 | * @dev: the device to register |
33 | * | 33 | * |
34 | * hwmon_device_unregister() must be called when the class device is no | 34 | * hwmon_device_unregister() must be called when the device is no |
35 | * longer needed. | 35 | * longer needed. |
36 | * | 36 | * |
37 | * Returns the pointer to the new struct class device. | 37 | * Returns the pointer to the new device. |
38 | */ | 38 | */ |
39 | struct class_device *hwmon_device_register(struct device *dev) | 39 | struct device *hwmon_device_register(struct device *dev) |
40 | { | 40 | { |
41 | struct class_device *cdev; | 41 | struct device *hwdev; |
42 | int id, err; | 42 | int id, err; |
43 | 43 | ||
44 | again: | 44 | again: |
@@ -55,34 +55,33 @@ again: | |||
55 | return ERR_PTR(err); | 55 | return ERR_PTR(err); |
56 | 56 | ||
57 | id = id & MAX_ID_MASK; | 57 | id = id & MAX_ID_MASK; |
58 | cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, | 58 | hwdev = device_create(hwmon_class, dev, MKDEV(0,0), HWMON_ID_FORMAT, id); |
59 | HWMON_ID_FORMAT, id); | ||
60 | 59 | ||
61 | if (IS_ERR(cdev)) { | 60 | if (IS_ERR(hwdev)) { |
62 | spin_lock(&idr_lock); | 61 | spin_lock(&idr_lock); |
63 | idr_remove(&hwmon_idr, id); | 62 | idr_remove(&hwmon_idr, id); |
64 | spin_unlock(&idr_lock); | 63 | spin_unlock(&idr_lock); |
65 | } | 64 | } |
66 | 65 | ||
67 | return cdev; | 66 | return hwdev; |
68 | } | 67 | } |
69 | 68 | ||
70 | /** | 69 | /** |
71 | * hwmon_device_unregister - removes the previously registered class device | 70 | * hwmon_device_unregister - removes the previously registered class device |
72 | * | 71 | * |
73 | * @cdev: the class device to destroy | 72 | * @dev: the class device to destroy |
74 | */ | 73 | */ |
75 | void hwmon_device_unregister(struct class_device *cdev) | 74 | void hwmon_device_unregister(struct device *dev) |
76 | { | 75 | { |
77 | int id; | 76 | int id; |
78 | 77 | ||
79 | if (likely(sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1)) { | 78 | if (likely(sscanf(dev->bus_id, HWMON_ID_FORMAT, &id) == 1)) { |
80 | class_device_unregister(cdev); | 79 | device_unregister(dev); |
81 | spin_lock(&idr_lock); | 80 | spin_lock(&idr_lock); |
82 | idr_remove(&hwmon_idr, id); | 81 | idr_remove(&hwmon_idr, id); |
83 | spin_unlock(&idr_lock); | 82 | spin_unlock(&idr_lock); |
84 | } else | 83 | } else |
85 | dev_dbg(cdev->dev, | 84 | dev_dbg(dev->parent, |
86 | "hwmon_device_unregister() failed: bad class ID!\n"); | 85 | "hwmon_device_unregister() failed: bad class ID!\n"); |
87 | } | 86 | } |
88 | 87 | ||
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c new file mode 100644 index 000000000000..c462824ffccf --- /dev/null +++ b/drivers/hwmon/ibmpex.c | |||
@@ -0,0 +1,607 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the IBM PowerExecutive temperature/power sensors | ||
3 | * Copyright (C) 2007 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/ipmi.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/hwmon.h> | ||
25 | #include <linux/hwmon-sysfs.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/mutex.h> | ||
28 | |||
29 | #define REFRESH_INTERVAL (2 * HZ) | ||
30 | #define DRVNAME "ibmpex" | ||
31 | |||
32 | #define PEX_GET_VERSION 1 | ||
33 | #define PEX_GET_SENSOR_COUNT 2 | ||
34 | #define PEX_GET_SENSOR_NAME 3 | ||
35 | #define PEX_RESET_HIGH_LOW 4 | ||
36 | #define PEX_GET_SENSOR_DATA 6 | ||
37 | |||
38 | #define PEX_NET_FUNCTION 0x3A | ||
39 | #define PEX_COMMAND 0x3C | ||
40 | |||
41 | static inline u16 extract_value(const char *data, int offset) | ||
42 | { | ||
43 | return be16_to_cpup((u16 *)&data[offset]); | ||
44 | } | ||
45 | |||
46 | #define TEMP_SENSOR 1 | ||
47 | #define POWER_SENSOR 2 | ||
48 | |||
49 | #define PEX_SENSOR_TYPE_LEN 3 | ||
50 | static u8 const power_sensor_sig[] = {0x70, 0x77, 0x72}; | ||
51 | static u8 const temp_sensor_sig[] = {0x74, 0x65, 0x6D}; | ||
52 | |||
53 | #define PEX_MULT_LEN 2 | ||
54 | static u8 const watt_sensor_sig[] = {0x41, 0x43}; | ||
55 | |||
56 | #define PEX_NUM_SENSOR_FUNCS 3 | ||
57 | static char const * const power_sensor_name_templates[] = { | ||
58 | "%s%d_average", | ||
59 | "%s%d_average_lowest", | ||
60 | "%s%d_average_highest" | ||
61 | }; | ||
62 | static char const * const temp_sensor_name_templates[] = { | ||
63 | "%s%d_input", | ||
64 | "%s%d_input_lowest", | ||
65 | "%s%d_input_highest" | ||
66 | }; | ||
67 | |||
68 | static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | ||
69 | static void ibmpex_register_bmc(int iface, struct device *dev); | ||
70 | static void ibmpex_bmc_gone(int iface); | ||
71 | |||
72 | struct ibmpex_sensor_data { | ||
73 | int in_use; | ||
74 | s16 values[PEX_NUM_SENSOR_FUNCS]; | ||
75 | int multiplier; | ||
76 | |||
77 | struct sensor_device_attribute_2 attr[PEX_NUM_SENSOR_FUNCS]; | ||
78 | }; | ||
79 | |||
80 | struct ibmpex_bmc_data { | ||
81 | struct list_head list; | ||
82 | struct device *hwmon_dev; | ||
83 | struct device *bmc_device; | ||
84 | struct mutex lock; | ||
85 | char valid; | ||
86 | unsigned long last_updated; /* In jiffies */ | ||
87 | |||
88 | struct ipmi_addr address; | ||
89 | struct completion read_complete; | ||
90 | ipmi_user_t user; | ||
91 | int interface; | ||
92 | |||
93 | struct kernel_ipmi_msg tx_message; | ||
94 | unsigned char tx_msg_data[IPMI_MAX_MSG_LENGTH]; | ||
95 | long tx_msgid; | ||
96 | |||
97 | unsigned char rx_msg_data[IPMI_MAX_MSG_LENGTH]; | ||
98 | unsigned long rx_msg_len; | ||
99 | unsigned char rx_result; | ||
100 | int rx_recv_type; | ||
101 | |||
102 | unsigned char sensor_major; | ||
103 | unsigned char sensor_minor; | ||
104 | |||
105 | unsigned char num_sensors; | ||
106 | struct ibmpex_sensor_data *sensors; | ||
107 | }; | ||
108 | |||
109 | struct ibmpex_driver_data { | ||
110 | struct list_head bmc_data; | ||
111 | struct ipmi_smi_watcher bmc_events; | ||
112 | struct ipmi_user_hndl ipmi_hndlrs; | ||
113 | }; | ||
114 | |||
115 | static struct ibmpex_driver_data driver_data = { | ||
116 | .bmc_data = LIST_HEAD_INIT(driver_data.bmc_data), | ||
117 | .bmc_events = { | ||
118 | .owner = THIS_MODULE, | ||
119 | .new_smi = ibmpex_register_bmc, | ||
120 | .smi_gone = ibmpex_bmc_gone, | ||
121 | }, | ||
122 | .ipmi_hndlrs = { | ||
123 | .ipmi_recv_hndl = ibmpex_msg_handler, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | static int ibmpex_send_message(struct ibmpex_bmc_data *data) | ||
128 | { | ||
129 | int err; | ||
130 | |||
131 | err = ipmi_validate_addr(&data->address, sizeof(data->address)); | ||
132 | if (err) | ||
133 | goto out; | ||
134 | |||
135 | data->tx_msgid++; | ||
136 | err = ipmi_request_settime(data->user, &data->address, data->tx_msgid, | ||
137 | &data->tx_message, data, 0, 0, 0); | ||
138 | if (err) | ||
139 | goto out1; | ||
140 | |||
141 | return 0; | ||
142 | out1: | ||
143 | printk(KERN_ERR "%s: request_settime=%x\n", __FUNCTION__, err); | ||
144 | return err; | ||
145 | out: | ||
146 | printk(KERN_ERR "%s: validate_addr=%x\n", __FUNCTION__, err); | ||
147 | return err; | ||
148 | } | ||
149 | |||
150 | static int ibmpex_ver_check(struct ibmpex_bmc_data *data) | ||
151 | { | ||
152 | data->tx_msg_data[0] = PEX_GET_VERSION; | ||
153 | data->tx_message.data_len = 1; | ||
154 | ibmpex_send_message(data); | ||
155 | |||
156 | wait_for_completion(&data->read_complete); | ||
157 | |||
158 | if (data->rx_result || data->rx_msg_len != 6) | ||
159 | return -ENOENT; | ||
160 | |||
161 | data->sensor_major = data->rx_msg_data[0]; | ||
162 | data->sensor_minor = data->rx_msg_data[1]; | ||
163 | |||
164 | printk(KERN_INFO DRVNAME ": Found BMC with sensor interface " | ||
165 | "v%d.%d %d-%02d-%02d on interface %d\n", | ||
166 | data->sensor_major, | ||
167 | data->sensor_minor, | ||
168 | extract_value(data->rx_msg_data, 2), | ||
169 | data->rx_msg_data[4], | ||
170 | data->rx_msg_data[5], | ||
171 | data->interface); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int ibmpex_query_sensor_count(struct ibmpex_bmc_data *data) | ||
177 | { | ||
178 | data->tx_msg_data[0] = PEX_GET_SENSOR_COUNT; | ||
179 | data->tx_message.data_len = 1; | ||
180 | ibmpex_send_message(data); | ||
181 | |||
182 | wait_for_completion(&data->read_complete); | ||
183 | |||
184 | if (data->rx_result || data->rx_msg_len != 1) | ||
185 | return -ENOENT; | ||
186 | |||
187 | return data->rx_msg_data[0]; | ||
188 | } | ||
189 | |||
190 | static int ibmpex_query_sensor_name(struct ibmpex_bmc_data *data, int sensor) | ||
191 | { | ||
192 | data->tx_msg_data[0] = PEX_GET_SENSOR_NAME; | ||
193 | data->tx_msg_data[1] = sensor; | ||
194 | data->tx_message.data_len = 2; | ||
195 | ibmpex_send_message(data); | ||
196 | |||
197 | wait_for_completion(&data->read_complete); | ||
198 | |||
199 | if (data->rx_result || data->rx_msg_len < 1) | ||
200 | return -ENOENT; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int ibmpex_query_sensor_data(struct ibmpex_bmc_data *data, int sensor) | ||
206 | { | ||
207 | data->tx_msg_data[0] = PEX_GET_SENSOR_DATA; | ||
208 | data->tx_msg_data[1] = sensor; | ||
209 | data->tx_message.data_len = 2; | ||
210 | ibmpex_send_message(data); | ||
211 | |||
212 | wait_for_completion(&data->read_complete); | ||
213 | |||
214 | if (data->rx_result || data->rx_msg_len < 26) { | ||
215 | printk(KERN_ERR "Error reading sensor %d, please check.\n", | ||
216 | sensor); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int ibmpex_reset_high_low_data(struct ibmpex_bmc_data *data) | ||
224 | { | ||
225 | data->tx_msg_data[0] = PEX_RESET_HIGH_LOW; | ||
226 | data->tx_message.data_len = 1; | ||
227 | ibmpex_send_message(data); | ||
228 | |||
229 | wait_for_completion(&data->read_complete); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void ibmpex_update_device(struct ibmpex_bmc_data *data) | ||
235 | { | ||
236 | int i, err; | ||
237 | |||
238 | mutex_lock(&data->lock); | ||
239 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
240 | data->valid) | ||
241 | goto out; | ||
242 | |||
243 | for (i = 0; i < data->num_sensors; i++) { | ||
244 | if (!data->sensors[i].in_use) | ||
245 | continue; | ||
246 | err = ibmpex_query_sensor_data(data, i); | ||
247 | if (err) | ||
248 | continue; | ||
249 | data->sensors[i].values[0] = | ||
250 | extract_value(data->rx_msg_data, 16); | ||
251 | data->sensors[i].values[1] = | ||
252 | extract_value(data->rx_msg_data, 18); | ||
253 | data->sensors[i].values[2] = | ||
254 | extract_value(data->rx_msg_data, 20); | ||
255 | } | ||
256 | |||
257 | data->last_updated = jiffies; | ||
258 | data->valid = 1; | ||
259 | |||
260 | out: | ||
261 | mutex_unlock(&data->lock); | ||
262 | } | ||
263 | |||
264 | static struct ibmpex_bmc_data *get_bmc_data(int iface) | ||
265 | { | ||
266 | struct ibmpex_bmc_data *p, *next; | ||
267 | |||
268 | list_for_each_entry_safe(p, next, &driver_data.bmc_data, list) | ||
269 | if (p->interface == iface) | ||
270 | return p; | ||
271 | |||
272 | return NULL; | ||
273 | } | ||
274 | |||
275 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
276 | char *buf) | ||
277 | { | ||
278 | return sprintf(buf, "%s\n", DRVNAME); | ||
279 | } | ||
280 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); | ||
281 | |||
282 | static ssize_t ibmpex_show_sensor(struct device *dev, | ||
283 | struct device_attribute *devattr, | ||
284 | char *buf) | ||
285 | { | ||
286 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
287 | struct ibmpex_bmc_data *data = dev_get_drvdata(dev); | ||
288 | int mult = data->sensors[attr->index].multiplier; | ||
289 | ibmpex_update_device(data); | ||
290 | |||
291 | return sprintf(buf, "%d\n", | ||
292 | data->sensors[attr->index].values[attr->nr] * mult); | ||
293 | } | ||
294 | |||
295 | static ssize_t ibmpex_reset_high_low(struct device *dev, | ||
296 | struct device_attribute *devattr, | ||
297 | const char *buf, | ||
298 | size_t count) | ||
299 | { | ||
300 | struct ibmpex_bmc_data *data = dev_get_drvdata(dev); | ||
301 | |||
302 | ibmpex_reset_high_low_data(data); | ||
303 | |||
304 | return count; | ||
305 | } | ||
306 | |||
307 | static SENSOR_DEVICE_ATTR(reset_high_low, S_IWUSR, NULL, | ||
308 | ibmpex_reset_high_low, 0); | ||
309 | |||
310 | static int is_power_sensor(const char *sensor_id, int len) | ||
311 | { | ||
312 | if (len < PEX_SENSOR_TYPE_LEN) | ||
313 | return 0; | ||
314 | |||
315 | if (!memcmp(sensor_id, power_sensor_sig, PEX_SENSOR_TYPE_LEN)) | ||
316 | return 1; | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int is_temp_sensor(const char *sensor_id, int len) | ||
321 | { | ||
322 | if (len < PEX_SENSOR_TYPE_LEN) | ||
323 | return 0; | ||
324 | |||
325 | if (!memcmp(sensor_id, temp_sensor_sig, PEX_SENSOR_TYPE_LEN)) | ||
326 | return 1; | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int power_sensor_multiplier(const char *sensor_id, int len) | ||
331 | { | ||
332 | int i; | ||
333 | |||
334 | for (i = PEX_SENSOR_TYPE_LEN; i < len - 1; i++) | ||
335 | if (!memcmp(&sensor_id[i], watt_sensor_sig, PEX_MULT_LEN)) | ||
336 | return 1000000; | ||
337 | |||
338 | return 100000; | ||
339 | } | ||
340 | |||
341 | static int create_sensor(struct ibmpex_bmc_data *data, int type, | ||
342 | int counter, int sensor, int func) | ||
343 | { | ||
344 | int err; | ||
345 | char *n; | ||
346 | |||
347 | n = kmalloc(32, GFP_KERNEL); | ||
348 | if (!n) | ||
349 | return -ENOMEM; | ||
350 | |||
351 | if (type == TEMP_SENSOR) | ||
352 | sprintf(n, temp_sensor_name_templates[func], "temp", counter); | ||
353 | else if (type == POWER_SENSOR) | ||
354 | sprintf(n, power_sensor_name_templates[func], "power", counter); | ||
355 | |||
356 | data->sensors[sensor].attr[func].dev_attr.attr.name = n; | ||
357 | data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO; | ||
358 | data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor; | ||
359 | data->sensors[sensor].attr[func].index = sensor; | ||
360 | data->sensors[sensor].attr[func].nr = func; | ||
361 | |||
362 | err = device_create_file(data->bmc_device, | ||
363 | &data->sensors[sensor].attr[func].dev_attr); | ||
364 | if (err) { | ||
365 | data->sensors[sensor].attr[func].dev_attr.attr.name = NULL; | ||
366 | kfree(n); | ||
367 | return err; | ||
368 | } | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int ibmpex_find_sensors(struct ibmpex_bmc_data *data) | ||
374 | { | ||
375 | int i, j, err; | ||
376 | int sensor_type; | ||
377 | int sensor_counter; | ||
378 | int num_power = 0; | ||
379 | int num_temp = 0; | ||
380 | |||
381 | err = ibmpex_query_sensor_count(data); | ||
382 | if (err <= 0) | ||
383 | return -ENOENT; | ||
384 | data->num_sensors = err; | ||
385 | |||
386 | data->sensors = kzalloc(data->num_sensors * sizeof(*data->sensors), | ||
387 | GFP_KERNEL); | ||
388 | if (!data->sensors) | ||
389 | return -ENOMEM; | ||
390 | |||
391 | for (i = 0; i < data->num_sensors; i++) { | ||
392 | err = ibmpex_query_sensor_name(data, i); | ||
393 | if (err) | ||
394 | continue; | ||
395 | |||
396 | if (is_power_sensor(data->rx_msg_data, data->rx_msg_len)) { | ||
397 | sensor_type = POWER_SENSOR; | ||
398 | num_power++; | ||
399 | sensor_counter = num_power; | ||
400 | data->sensors[i].multiplier = | ||
401 | power_sensor_multiplier(data->rx_msg_data, | ||
402 | data->rx_msg_len); | ||
403 | } else if (is_temp_sensor(data->rx_msg_data, | ||
404 | data->rx_msg_len)) { | ||
405 | sensor_type = TEMP_SENSOR; | ||
406 | num_temp++; | ||
407 | sensor_counter = num_temp; | ||
408 | data->sensors[i].multiplier = 1; | ||
409 | } else | ||
410 | continue; | ||
411 | |||
412 | data->sensors[i].in_use = 1; | ||
413 | |||
414 | /* Create attributes */ | ||
415 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
416 | err = create_sensor(data, sensor_type, sensor_counter, | ||
417 | i, j); | ||
418 | if (err) | ||
419 | goto exit_remove; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | err = device_create_file(data->bmc_device, | ||
424 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
425 | if (err) | ||
426 | goto exit_remove; | ||
427 | |||
428 | err = device_create_file(data->bmc_device, | ||
429 | &sensor_dev_attr_name.dev_attr); | ||
430 | if (err) | ||
431 | goto exit_remove; | ||
432 | |||
433 | return 0; | ||
434 | |||
435 | exit_remove: | ||
436 | device_remove_file(data->bmc_device, | ||
437 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
438 | device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); | ||
439 | for (i = 0; i < data->num_sensors; i++) | ||
440 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
441 | if (!data->sensors[i].attr[j].dev_attr.attr.name) | ||
442 | continue; | ||
443 | device_remove_file(data->bmc_device, | ||
444 | &data->sensors[i].attr[j].dev_attr); | ||
445 | kfree(data->sensors[i].attr[j].dev_attr.attr.name); | ||
446 | } | ||
447 | |||
448 | kfree(data->sensors); | ||
449 | return err; | ||
450 | } | ||
451 | |||
452 | static void ibmpex_register_bmc(int iface, struct device *dev) | ||
453 | { | ||
454 | struct ibmpex_bmc_data *data; | ||
455 | int err; | ||
456 | |||
457 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
458 | if (!data) { | ||
459 | printk(KERN_ERR DRVNAME ": Insufficient memory for BMC " | ||
460 | "interface %d.\n", data->interface); | ||
461 | return; | ||
462 | } | ||
463 | |||
464 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
465 | data->address.channel = IPMI_BMC_CHANNEL; | ||
466 | data->address.data[0] = 0; | ||
467 | data->interface = iface; | ||
468 | data->bmc_device = dev; | ||
469 | |||
470 | /* Create IPMI messaging interface user */ | ||
471 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | ||
472 | data, &data->user); | ||
473 | if (err < 0) { | ||
474 | printk(KERN_ERR DRVNAME ": Error, unable to register user with " | ||
475 | "ipmi interface %d\n", | ||
476 | data->interface); | ||
477 | goto out; | ||
478 | } | ||
479 | |||
480 | mutex_init(&data->lock); | ||
481 | |||
482 | /* Initialize message */ | ||
483 | data->tx_msgid = 0; | ||
484 | init_completion(&data->read_complete); | ||
485 | data->tx_message.netfn = PEX_NET_FUNCTION; | ||
486 | data->tx_message.cmd = PEX_COMMAND; | ||
487 | data->tx_message.data = data->tx_msg_data; | ||
488 | |||
489 | /* Does this BMC support PowerExecutive? */ | ||
490 | err = ibmpex_ver_check(data); | ||
491 | if (err) | ||
492 | goto out_user; | ||
493 | |||
494 | /* Register the BMC as a HWMON class device */ | ||
495 | data->hwmon_dev = hwmon_device_register(data->bmc_device); | ||
496 | |||
497 | if (IS_ERR(data->hwmon_dev)) { | ||
498 | printk(KERN_ERR DRVNAME ": Error, unable to register hwmon " | ||
499 | "class device for interface %d\n", | ||
500 | data->interface); | ||
501 | goto out_user; | ||
502 | } | ||
503 | |||
504 | /* finally add the new bmc data to the bmc data list */ | ||
505 | dev_set_drvdata(dev, data); | ||
506 | list_add_tail(&data->list, &driver_data.bmc_data); | ||
507 | |||
508 | /* Now go find all the sensors */ | ||
509 | err = ibmpex_find_sensors(data); | ||
510 | if (err) { | ||
511 | printk(KERN_ERR "Error %d allocating memory\n", err); | ||
512 | goto out_register; | ||
513 | } | ||
514 | |||
515 | return; | ||
516 | |||
517 | out_register: | ||
518 | hwmon_device_unregister(data->hwmon_dev); | ||
519 | out_user: | ||
520 | ipmi_destroy_user(data->user); | ||
521 | out: | ||
522 | kfree(data); | ||
523 | } | ||
524 | |||
525 | static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) | ||
526 | { | ||
527 | int i, j; | ||
528 | |||
529 | device_remove_file(data->bmc_device, | ||
530 | &sensor_dev_attr_reset_high_low.dev_attr); | ||
531 | device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); | ||
532 | for (i = 0; i < data->num_sensors; i++) | ||
533 | for (j = 0; j < PEX_NUM_SENSOR_FUNCS; j++) { | ||
534 | if (!data->sensors[i].attr[j].dev_attr.attr.name) | ||
535 | continue; | ||
536 | device_remove_file(data->bmc_device, | ||
537 | &data->sensors[i].attr[j].dev_attr); | ||
538 | kfree(data->sensors[i].attr[j].dev_attr.attr.name); | ||
539 | } | ||
540 | |||
541 | list_del(&data->list); | ||
542 | dev_set_drvdata(data->bmc_device, NULL); | ||
543 | hwmon_device_unregister(data->hwmon_dev); | ||
544 | ipmi_destroy_user(data->user); | ||
545 | kfree(data->sensors); | ||
546 | kfree(data); | ||
547 | } | ||
548 | |||
549 | static void ibmpex_bmc_gone(int iface) | ||
550 | { | ||
551 | struct ibmpex_bmc_data *data = get_bmc_data(iface); | ||
552 | |||
553 | if (!data) | ||
554 | return; | ||
555 | |||
556 | ibmpex_bmc_delete(data); | ||
557 | } | ||
558 | |||
559 | static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | ||
560 | { | ||
561 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; | ||
562 | |||
563 | if (msg->msgid != data->tx_msgid) { | ||
564 | printk(KERN_ERR "Received msgid (%02x) and transmitted " | ||
565 | "msgid (%02x) mismatch!\n", | ||
566 | (int)msg->msgid, | ||
567 | (int)data->tx_msgid); | ||
568 | ipmi_free_recv_msg(msg); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | data->rx_recv_type = msg->recv_type; | ||
573 | if (msg->msg.data_len > 0) | ||
574 | data->rx_result = msg->msg.data[0]; | ||
575 | else | ||
576 | data->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; | ||
577 | |||
578 | if (msg->msg.data_len > 1) { | ||
579 | data->rx_msg_len = msg->msg.data_len - 1; | ||
580 | memcpy(data->rx_msg_data, msg->msg.data + 1, data->rx_msg_len); | ||
581 | } else | ||
582 | data->rx_msg_len = 0; | ||
583 | |||
584 | ipmi_free_recv_msg(msg); | ||
585 | complete(&data->read_complete); | ||
586 | } | ||
587 | |||
588 | static int __init ibmpex_init(void) | ||
589 | { | ||
590 | return ipmi_smi_watcher_register(&driver_data.bmc_events); | ||
591 | } | ||
592 | |||
593 | static void __exit ibmpex_exit(void) | ||
594 | { | ||
595 | struct ibmpex_bmc_data *p, *next; | ||
596 | |||
597 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | ||
598 | list_for_each_entry_safe(p, next, &driver_data.bmc_data, list) | ||
599 | ibmpex_bmc_delete(p); | ||
600 | } | ||
601 | |||
602 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
603 | MODULE_DESCRIPTION("IBM PowerExecutive power/temperature sensor driver"); | ||
604 | MODULE_LICENSE("GPL"); | ||
605 | |||
606 | module_init(ibmpex_init); | ||
607 | module_exit(ibmpex_exit); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index d75dba9b810b..6a182e14cf58 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -141,10 +141,10 @@ static int fix_pwm_polarity; | |||
141 | 141 | ||
142 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ | 142 | /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ |
143 | 143 | ||
144 | #define IT87_REG_FAN(nr) (0x0d + (nr)) | 144 | static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; |
145 | #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) | 145 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; |
146 | #define IT87_REG_FANX(nr) (0x18 + (nr)) | 146 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; |
147 | #define IT87_REG_FANX_MIN(nr) (0x1b + (nr)) | 147 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; |
148 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 148 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
149 | #define IT87_REG_FAN_CTL 0x14 | 149 | #define IT87_REG_FAN_CTL 0x14 |
150 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 150 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
@@ -222,7 +222,7 @@ struct it87_sio_data { | |||
222 | /* For each registered chip, we need to keep some data in memory. | 222 | /* For each registered chip, we need to keep some data in memory. |
223 | The structure is dynamically allocated. */ | 223 | The structure is dynamically allocated. */ |
224 | struct it87_data { | 224 | struct it87_data { |
225 | struct class_device *class_dev; | 225 | struct device *hwmon_dev; |
226 | enum chips type; | 226 | enum chips type; |
227 | 227 | ||
228 | unsigned short addr; | 228 | unsigned short addr; |
@@ -235,8 +235,8 @@ struct it87_data { | |||
235 | u8 in_max[8]; /* Register value */ | 235 | u8 in_max[8]; /* Register value */ |
236 | u8 in_min[8]; /* Register value */ | 236 | u8 in_min[8]; /* Register value */ |
237 | u8 has_fan; /* Bitfield, fans enabled */ | 237 | u8 has_fan; /* Bitfield, fans enabled */ |
238 | u16 fan[3]; /* Register values, possibly combined */ | 238 | u16 fan[5]; /* Register values, possibly combined */ |
239 | u16 fan_min[3]; /* Register values, possibly combined */ | 239 | u16 fan_min[5]; /* Register values, possibly combined */ |
240 | u8 temp[3]; /* Register value */ | 240 | u8 temp[3]; /* Register value */ |
241 | u8 temp_high[3]; /* Register value */ | 241 | u8 temp_high[3]; /* Register value */ |
242 | u8 temp_low[3]; /* Register value */ | 242 | u8 temp_low[3]; /* Register value */ |
@@ -555,7 +555,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
555 | } | 555 | } |
556 | 556 | ||
557 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 557 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
558 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 558 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); |
559 | mutex_unlock(&data->update_lock); | 559 | mutex_unlock(&data->update_lock); |
560 | return count; | 560 | return count; |
561 | } | 561 | } |
@@ -596,7 +596,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
596 | 596 | ||
597 | /* Restore fan min limit */ | 597 | /* Restore fan min limit */ |
598 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 598 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
599 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 599 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); |
600 | 600 | ||
601 | mutex_unlock(&data->update_lock); | 601 | mutex_unlock(&data->update_lock); |
602 | return count; | 602 | return count; |
@@ -729,9 +729,9 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | |||
729 | 729 | ||
730 | mutex_lock(&data->update_lock); | 730 | mutex_lock(&data->update_lock); |
731 | data->fan_min[nr] = FAN16_TO_REG(val); | 731 | data->fan_min[nr] = FAN16_TO_REG(val); |
732 | it87_write_value(data, IT87_REG_FAN_MIN(nr), | 732 | it87_write_value(data, IT87_REG_FAN_MIN[nr], |
733 | data->fan_min[nr] & 0xff); | 733 | data->fan_min[nr] & 0xff); |
734 | it87_write_value(data, IT87_REG_FANX_MIN(nr), | 734 | it87_write_value(data, IT87_REG_FANX_MIN[nr], |
735 | data->fan_min[nr] >> 8); | 735 | data->fan_min[nr] >> 8); |
736 | mutex_unlock(&data->update_lock); | 736 | mutex_unlock(&data->update_lock); |
737 | return count; | 737 | return count; |
@@ -751,6 +751,8 @@ static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \ | |||
751 | show_fan16_offset(1); | 751 | show_fan16_offset(1); |
752 | show_fan16_offset(2); | 752 | show_fan16_offset(2); |
753 | show_fan16_offset(3); | 753 | show_fan16_offset(3); |
754 | show_fan16_offset(4); | ||
755 | show_fan16_offset(5); | ||
754 | 756 | ||
755 | /* Alarms */ | 757 | /* Alarms */ |
756 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 758 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -763,7 +765,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | |||
763 | static ssize_t | 765 | static ssize_t |
764 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 766 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
765 | { | 767 | { |
766 | struct it87_data *data = it87_update_device(dev); | 768 | struct it87_data *data = dev_get_drvdata(dev); |
767 | return sprintf(buf, "%u\n", data->vrm); | 769 | return sprintf(buf, "%u\n", data->vrm); |
768 | } | 770 | } |
769 | static ssize_t | 771 | static ssize_t |
@@ -851,6 +853,10 @@ static struct attribute *it87_attributes_opt[] = { | |||
851 | &sensor_dev_attr_fan2_min16.dev_attr.attr, | 853 | &sensor_dev_attr_fan2_min16.dev_attr.attr, |
852 | &sensor_dev_attr_fan3_input16.dev_attr.attr, | 854 | &sensor_dev_attr_fan3_input16.dev_attr.attr, |
853 | &sensor_dev_attr_fan3_min16.dev_attr.attr, | 855 | &sensor_dev_attr_fan3_min16.dev_attr.attr, |
856 | &sensor_dev_attr_fan4_input16.dev_attr.attr, | ||
857 | &sensor_dev_attr_fan4_min16.dev_attr.attr, | ||
858 | &sensor_dev_attr_fan5_input16.dev_attr.attr, | ||
859 | &sensor_dev_attr_fan5_min16.dev_attr.attr, | ||
854 | 860 | ||
855 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 861 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
856 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 862 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
@@ -1024,6 +1030,20 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1024 | &sensor_dev_attr_fan3_min16.dev_attr))) | 1030 | &sensor_dev_attr_fan3_min16.dev_attr))) |
1025 | goto ERROR4; | 1031 | goto ERROR4; |
1026 | } | 1032 | } |
1033 | if (data->has_fan & (1 << 3)) { | ||
1034 | if ((err = device_create_file(dev, | ||
1035 | &sensor_dev_attr_fan4_input16.dev_attr)) | ||
1036 | || (err = device_create_file(dev, | ||
1037 | &sensor_dev_attr_fan4_min16.dev_attr))) | ||
1038 | goto ERROR4; | ||
1039 | } | ||
1040 | if (data->has_fan & (1 << 4)) { | ||
1041 | if ((err = device_create_file(dev, | ||
1042 | &sensor_dev_attr_fan5_input16.dev_attr)) | ||
1043 | || (err = device_create_file(dev, | ||
1044 | &sensor_dev_attr_fan5_min16.dev_attr))) | ||
1045 | goto ERROR4; | ||
1046 | } | ||
1027 | } else { | 1047 | } else { |
1028 | /* 8-bit tachometers with clock divider */ | 1048 | /* 8-bit tachometers with clock divider */ |
1029 | if (data->has_fan & (1 << 0)) { | 1049 | if (data->has_fan & (1 << 0)) { |
@@ -1089,9 +1109,9 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1089 | goto ERROR4; | 1109 | goto ERROR4; |
1090 | } | 1110 | } |
1091 | 1111 | ||
1092 | data->class_dev = hwmon_device_register(dev); | 1112 | data->hwmon_dev = hwmon_device_register(dev); |
1093 | if (IS_ERR(data->class_dev)) { | 1113 | if (IS_ERR(data->hwmon_dev)) { |
1094 | err = PTR_ERR(data->class_dev); | 1114 | err = PTR_ERR(data->hwmon_dev); |
1095 | goto ERROR4; | 1115 | goto ERROR4; |
1096 | } | 1116 | } |
1097 | 1117 | ||
@@ -1113,7 +1133,7 @@ static int __devexit it87_remove(struct platform_device *pdev) | |||
1113 | { | 1133 | { |
1114 | struct it87_data *data = platform_get_drvdata(pdev); | 1134 | struct it87_data *data = platform_get_drvdata(pdev); |
1115 | 1135 | ||
1116 | hwmon_device_unregister(data->class_dev); | 1136 | hwmon_device_unregister(data->hwmon_dev); |
1117 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); | 1137 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); |
1118 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); | 1138 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); |
1119 | 1139 | ||
@@ -1260,6 +1280,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1260 | it87_write_value(data, IT87_REG_FAN_16BIT, | 1280 | it87_write_value(data, IT87_REG_FAN_16BIT, |
1261 | tmp | 0x07); | 1281 | tmp | 0x07); |
1262 | } | 1282 | } |
1283 | if (tmp & (1 << 4)) | ||
1284 | data->has_fan |= (1 << 3); /* fan4 enabled */ | ||
1285 | if (tmp & (1 << 5)) | ||
1286 | data->has_fan |= (1 << 4); /* fan5 enabled */ | ||
1263 | } | 1287 | } |
1264 | 1288 | ||
1265 | /* Set current fan mode registers and the default settings for the | 1289 | /* Set current fan mode registers and the default settings for the |
@@ -1314,21 +1338,21 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1314 | data->in[8] = | 1338 | data->in[8] = |
1315 | it87_read_value(data, IT87_REG_VIN(8)); | 1339 | it87_read_value(data, IT87_REG_VIN(8)); |
1316 | 1340 | ||
1317 | for (i = 0; i < 3; i++) { | 1341 | for (i = 0; i < 5; i++) { |
1318 | /* Skip disabled fans */ | 1342 | /* Skip disabled fans */ |
1319 | if (!(data->has_fan & (1 << i))) | 1343 | if (!(data->has_fan & (1 << i))) |
1320 | continue; | 1344 | continue; |
1321 | 1345 | ||
1322 | data->fan_min[i] = | 1346 | data->fan_min[i] = |
1323 | it87_read_value(data, IT87_REG_FAN_MIN(i)); | 1347 | it87_read_value(data, IT87_REG_FAN_MIN[i]); |
1324 | data->fan[i] = it87_read_value(data, | 1348 | data->fan[i] = it87_read_value(data, |
1325 | IT87_REG_FAN(i)); | 1349 | IT87_REG_FAN[i]); |
1326 | /* Add high byte if in 16-bit mode */ | 1350 | /* Add high byte if in 16-bit mode */ |
1327 | if (data->type == it8716 || data->type == it8718) { | 1351 | if (data->type == it8716 || data->type == it8718) { |
1328 | data->fan[i] |= it87_read_value(data, | 1352 | data->fan[i] |= it87_read_value(data, |
1329 | IT87_REG_FANX(i)) << 8; | 1353 | IT87_REG_FANX[i]) << 8; |
1330 | data->fan_min[i] |= it87_read_value(data, | 1354 | data->fan_min[i] |= it87_read_value(data, |
1331 | IT87_REG_FANX_MIN(i)) << 8; | 1355 | IT87_REG_FANX_MIN[i]) << 8; |
1332 | } | 1356 | } |
1333 | } | 1357 | } |
1334 | for (i = 0; i < 3; i++) { | 1358 | for (i = 0; i < 3; i++) { |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 5d8d0ca08fa9..bd2bde0ef95e 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define SEL_CORE 0x04 | 38 | #define SEL_CORE 0x04 |
39 | 39 | ||
40 | struct k8temp_data { | 40 | struct k8temp_data { |
41 | struct class_device *class_dev; | 41 | struct device *hwmon_dev; |
42 | struct mutex update_lock; | 42 | struct mutex update_lock; |
43 | const char *name; | 43 | const char *name; |
44 | char valid; /* zero until following fields are valid */ | 44 | char valid; /* zero until following fields are valid */ |
@@ -225,10 +225,10 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, | |||
225 | if (err) | 225 | if (err) |
226 | goto exit_remove; | 226 | goto exit_remove; |
227 | 227 | ||
228 | data->class_dev = hwmon_device_register(&pdev->dev); | 228 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
229 | 229 | ||
230 | if (IS_ERR(data->class_dev)) { | 230 | if (IS_ERR(data->hwmon_dev)) { |
231 | err = PTR_ERR(data->class_dev); | 231 | err = PTR_ERR(data->hwmon_dev); |
232 | goto exit_remove; | 232 | goto exit_remove; |
233 | } | 233 | } |
234 | 234 | ||
@@ -255,7 +255,7 @@ static void __devexit k8temp_remove(struct pci_dev *pdev) | |||
255 | { | 255 | { |
256 | struct k8temp_data *data = dev_get_drvdata(&pdev->dev); | 256 | struct k8temp_data *data = dev_get_drvdata(&pdev->dev); |
257 | 257 | ||
258 | hwmon_device_unregister(data->class_dev); | 258 | hwmon_device_unregister(data->hwmon_dev); |
259 | device_remove_file(&pdev->dev, | 259 | device_remove_file(&pdev->dev, |
260 | &sensor_dev_attr_temp1_input.dev_attr); | 260 | &sensor_dev_attr_temp1_input.dev_attr); |
261 | device_remove_file(&pdev->dev, | 261 | device_remove_file(&pdev->dev, |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 2162d69a8c06..f207434730de 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -154,7 +154,7 @@ static struct i2c_driver lm63_driver = { | |||
154 | 154 | ||
155 | struct lm63_data { | 155 | struct lm63_data { |
156 | struct i2c_client client; | 156 | struct i2c_client client; |
157 | struct class_device *class_dev; | 157 | struct device *hwmon_dev; |
158 | struct mutex update_lock; | 158 | struct mutex update_lock; |
159 | char valid; /* zero until following fields are valid */ | 159 | char valid; /* zero until following fields are valid */ |
160 | unsigned long last_updated; /* in jiffies */ | 160 | unsigned long last_updated; /* in jiffies */ |
@@ -502,9 +502,9 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) | |||
502 | goto exit_remove_files; | 502 | goto exit_remove_files; |
503 | } | 503 | } |
504 | 504 | ||
505 | data->class_dev = hwmon_device_register(&new_client->dev); | 505 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
506 | if (IS_ERR(data->class_dev)) { | 506 | if (IS_ERR(data->hwmon_dev)) { |
507 | err = PTR_ERR(data->class_dev); | 507 | err = PTR_ERR(data->hwmon_dev); |
508 | goto exit_remove_files; | 508 | goto exit_remove_files; |
509 | } | 509 | } |
510 | 510 | ||
@@ -561,7 +561,7 @@ static int lm63_detach_client(struct i2c_client *client) | |||
561 | struct lm63_data *data = i2c_get_clientdata(client); | 561 | struct lm63_data *data = i2c_get_clientdata(client); |
562 | int err; | 562 | int err; |
563 | 563 | ||
564 | hwmon_device_unregister(data->class_dev); | 564 | hwmon_device_unregister(data->hwmon_dev); |
565 | sysfs_remove_group(&client->dev.kobj, &lm63_group); | 565 | sysfs_remove_group(&client->dev.kobj, &lm63_group); |
566 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); | 566 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); |
567 | 567 | ||
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 275d392eca61..dd366889ce9b 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #define DRVNAME "lm70" | 37 | #define DRVNAME "lm70" |
38 | 38 | ||
39 | struct lm70 { | 39 | struct lm70 { |
40 | struct class_device *cdev; | 40 | struct device *hwmon_dev; |
41 | struct semaphore sem; | 41 | struct semaphore sem; |
42 | }; | 42 | }; |
43 | 43 | ||
@@ -81,7 +81,7 @@ static ssize_t lm70_sense_temp(struct device *dev, | |||
81 | * So it's equivalent to multiplying by 0.25 * 1000 = 250. | 81 | * So it's equivalent to multiplying by 0.25 * 1000 = 250. |
82 | */ | 82 | */ |
83 | val = ((int)raw/32) * 250; | 83 | val = ((int)raw/32) * 250; |
84 | status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */ | 84 | status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ |
85 | out: | 85 | out: |
86 | up(&p_lm70->sem); | 86 | up(&p_lm70->sem); |
87 | return status; | 87 | return status; |
@@ -89,6 +89,14 @@ out: | |||
89 | 89 | ||
90 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); | 90 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); |
91 | 91 | ||
92 | static ssize_t lm70_show_name(struct device *dev, struct device_attribute | ||
93 | *devattr, char *buf) | ||
94 | { | ||
95 | return sprintf(buf, "lm70\n"); | ||
96 | } | ||
97 | |||
98 | static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); | ||
99 | |||
92 | /*----------------------------------------------------------------------*/ | 100 | /*----------------------------------------------------------------------*/ |
93 | 101 | ||
94 | static int __devinit lm70_probe(struct spi_device *spi) | 102 | static int __devinit lm70_probe(struct spi_device *spi) |
@@ -107,15 +115,16 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
107 | init_MUTEX(&p_lm70->sem); | 115 | init_MUTEX(&p_lm70->sem); |
108 | 116 | ||
109 | /* sysfs hook */ | 117 | /* sysfs hook */ |
110 | p_lm70->cdev = hwmon_device_register(&spi->dev); | 118 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); |
111 | if (IS_ERR(p_lm70->cdev)) { | 119 | if (IS_ERR(p_lm70->hwmon_dev)) { |
112 | dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); | 120 | dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); |
113 | status = PTR_ERR(p_lm70->cdev); | 121 | status = PTR_ERR(p_lm70->hwmon_dev); |
114 | goto out_dev_reg_failed; | 122 | goto out_dev_reg_failed; |
115 | } | 123 | } |
116 | dev_set_drvdata(&spi->dev, p_lm70); | 124 | dev_set_drvdata(&spi->dev, p_lm70); |
117 | 125 | ||
118 | if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) { | 126 | if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input)) |
127 | || (status = device_create_file(&spi->dev, &dev_attr_name))) { | ||
119 | dev_dbg(&spi->dev, "device_create_file failure.\n"); | 128 | dev_dbg(&spi->dev, "device_create_file failure.\n"); |
120 | goto out_dev_create_file_failed; | 129 | goto out_dev_create_file_failed; |
121 | } | 130 | } |
@@ -123,7 +132,8 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
123 | return 0; | 132 | return 0; |
124 | 133 | ||
125 | out_dev_create_file_failed: | 134 | out_dev_create_file_failed: |
126 | hwmon_device_unregister(p_lm70->cdev); | 135 | device_remove_file(&spi->dev, &dev_attr_temp1_input); |
136 | hwmon_device_unregister(p_lm70->hwmon_dev); | ||
127 | out_dev_reg_failed: | 137 | out_dev_reg_failed: |
128 | dev_set_drvdata(&spi->dev, NULL); | 138 | dev_set_drvdata(&spi->dev, NULL); |
129 | kfree(p_lm70); | 139 | kfree(p_lm70); |
@@ -135,7 +145,8 @@ static int __devexit lm70_remove(struct spi_device *spi) | |||
135 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); | 145 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); |
136 | 146 | ||
137 | device_remove_file(&spi->dev, &dev_attr_temp1_input); | 147 | device_remove_file(&spi->dev, &dev_attr_temp1_input); |
138 | hwmon_device_unregister(p_lm70->cdev); | 148 | device_remove_file(&spi->dev, &dev_attr_name); |
149 | hwmon_device_unregister(p_lm70->hwmon_dev); | ||
139 | dev_set_drvdata(&spi->dev, NULL); | 150 | dev_set_drvdata(&spi->dev, NULL); |
140 | kfree(p_lm70); | 151 | kfree(p_lm70); |
141 | 152 | ||
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index a40166ffad12..37a8cc032ffa 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -50,7 +50,7 @@ static const u8 LM75_REG_TEMP[3] = { | |||
50 | /* Each client has this additional data */ | 50 | /* Each client has this additional data */ |
51 | struct lm75_data { | 51 | struct lm75_data { |
52 | struct i2c_client client; | 52 | struct i2c_client client; |
53 | struct class_device *class_dev; | 53 | struct device *hwmon_dev; |
54 | struct mutex update_lock; | 54 | struct mutex update_lock; |
55 | char valid; /* !=0 if following fields are valid */ | 55 | char valid; /* !=0 if following fields are valid */ |
56 | unsigned long last_updated; /* In jiffies */ | 56 | unsigned long last_updated; /* In jiffies */ |
@@ -95,7 +95,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
95 | struct i2c_client *client = to_i2c_client(dev); | 95 | struct i2c_client *client = to_i2c_client(dev); |
96 | struct lm75_data *data = i2c_get_clientdata(client); | 96 | struct lm75_data *data = i2c_get_clientdata(client); |
97 | int nr = attr->index; | 97 | int nr = attr->index; |
98 | unsigned long temp = simple_strtoul(buf, NULL, 10); | 98 | long temp = simple_strtol(buf, NULL, 10); |
99 | 99 | ||
100 | mutex_lock(&data->update_lock); | 100 | mutex_lock(&data->update_lock); |
101 | data->temp[nr] = LM75_TEMP_TO_REG(temp); | 101 | data->temp[nr] = LM75_TEMP_TO_REG(temp); |
@@ -219,9 +219,9 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) | |||
219 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) | 219 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) |
220 | goto exit_detach; | 220 | goto exit_detach; |
221 | 221 | ||
222 | data->class_dev = hwmon_device_register(&new_client->dev); | 222 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
223 | if (IS_ERR(data->class_dev)) { | 223 | if (IS_ERR(data->hwmon_dev)) { |
224 | err = PTR_ERR(data->class_dev); | 224 | err = PTR_ERR(data->hwmon_dev); |
225 | goto exit_remove; | 225 | goto exit_remove; |
226 | } | 226 | } |
227 | 227 | ||
@@ -240,7 +240,7 @@ exit: | |||
240 | static int lm75_detach_client(struct i2c_client *client) | 240 | static int lm75_detach_client(struct i2c_client *client) |
241 | { | 241 | { |
242 | struct lm75_data *data = i2c_get_clientdata(client); | 242 | struct lm75_data *data = i2c_get_clientdata(client); |
243 | hwmon_device_unregister(data->class_dev); | 243 | hwmon_device_unregister(data->hwmon_dev); |
244 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | 244 | sysfs_remove_group(&client->dev.kobj, &lm75_group); |
245 | i2c_detach_client(client); | 245 | i2c_detach_client(client); |
246 | kfree(data); | 246 | kfree(data); |
diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h index af7dc650ee15..7c93454bb4e3 100644 --- a/drivers/hwmon/lm75.h +++ b/drivers/hwmon/lm75.h | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | /* TEMP: 0.001C/bit (-55C to +125C) | 34 | /* TEMP: 0.001C/bit (-55C to +125C) |
35 | REG: (0.5C/bit, two's complement) << 7 */ | 35 | REG: (0.5C/bit, two's complement) << 7 */ |
36 | static inline u16 LM75_TEMP_TO_REG(int temp) | 36 | static inline u16 LM75_TEMP_TO_REG(long temp) |
37 | { | 37 | { |
38 | int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); | 38 | int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); |
39 | ntemp += (ntemp<0 ? -250 : 250); | 39 | ntemp += (ntemp<0 ? -250 : 250); |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index dd969f1e8415..cee5c2e8cfad 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -51,7 +51,7 @@ I2C_CLIENT_INSMOD_1(lm77); | |||
51 | /* Each client has this additional data */ | 51 | /* Each client has this additional data */ |
52 | struct lm77_data { | 52 | struct lm77_data { |
53 | struct i2c_client client; | 53 | struct i2c_client client; |
54 | struct class_device *class_dev; | 54 | struct device *hwmon_dev; |
55 | struct mutex update_lock; | 55 | struct mutex update_lock; |
56 | char valid; | 56 | char valid; |
57 | unsigned long last_updated; /* In jiffies */ | 57 | unsigned long last_updated; /* In jiffies */ |
@@ -138,7 +138,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co | |||
138 | { \ | 138 | { \ |
139 | struct i2c_client *client = to_i2c_client(dev); \ | 139 | struct i2c_client *client = to_i2c_client(dev); \ |
140 | struct lm77_data *data = i2c_get_clientdata(client); \ | 140 | struct lm77_data *data = i2c_get_clientdata(client); \ |
141 | long val = simple_strtoul(buf, NULL, 10); \ | 141 | long val = simple_strtol(buf, NULL, 10); \ |
142 | \ | 142 | \ |
143 | mutex_lock(&data->update_lock); \ | 143 | mutex_lock(&data->update_lock); \ |
144 | data->value = val; \ | 144 | data->value = val; \ |
@@ -337,9 +337,9 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) | |||
337 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) | 337 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) |
338 | goto exit_detach; | 338 | goto exit_detach; |
339 | 339 | ||
340 | data->class_dev = hwmon_device_register(&new_client->dev); | 340 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
341 | if (IS_ERR(data->class_dev)) { | 341 | if (IS_ERR(data->hwmon_dev)) { |
342 | err = PTR_ERR(data->class_dev); | 342 | err = PTR_ERR(data->hwmon_dev); |
343 | goto exit_remove; | 343 | goto exit_remove; |
344 | } | 344 | } |
345 | 345 | ||
@@ -358,7 +358,7 @@ exit: | |||
358 | static int lm77_detach_client(struct i2c_client *client) | 358 | static int lm77_detach_client(struct i2c_client *client) |
359 | { | 359 | { |
360 | struct lm77_data *data = i2c_get_clientdata(client); | 360 | struct lm77_data *data = i2c_get_clientdata(client); |
361 | hwmon_device_unregister(data->class_dev); | 361 | hwmon_device_unregister(data->hwmon_dev); |
362 | sysfs_remove_group(&client->dev.kobj, &lm77_group); | 362 | sysfs_remove_group(&client->dev.kobj, &lm77_group); |
363 | i2c_detach_client(client); | 363 | i2c_detach_client(client); |
364 | kfree(data); | 364 | kfree(data); |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 6eea3476b90c..3f7055ee679f 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -131,7 +131,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
131 | the driver field to differentiate between I2C and ISA chips. */ | 131 | the driver field to differentiate between I2C and ISA chips. */ |
132 | struct lm78_data { | 132 | struct lm78_data { |
133 | struct i2c_client client; | 133 | struct i2c_client client; |
134 | struct class_device *class_dev; | 134 | struct device *hwmon_dev; |
135 | struct mutex lock; | 135 | struct mutex lock; |
136 | enum chips type; | 136 | enum chips type; |
137 | 137 | ||
@@ -438,6 +438,25 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *da, | |||
438 | } | 438 | } |
439 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 439 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
440 | 440 | ||
441 | static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | ||
442 | char *buf) | ||
443 | { | ||
444 | struct lm78_data *data = lm78_update_device(dev); | ||
445 | int nr = to_sensor_dev_attr(da)->index; | ||
446 | return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); | ||
447 | } | ||
448 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
449 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
450 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
451 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
452 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
453 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
454 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
455 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
456 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
457 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
458 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
459 | |||
441 | /* This function is called when: | 460 | /* This function is called when: |
442 | * lm78_driver is inserted (when this module is loaded), for each | 461 | * lm78_driver is inserted (when this module is loaded), for each |
443 | available adapter | 462 | available adapter |
@@ -453,36 +472,47 @@ static struct attribute *lm78_attributes[] = { | |||
453 | &sensor_dev_attr_in0_input.dev_attr.attr, | 472 | &sensor_dev_attr_in0_input.dev_attr.attr, |
454 | &sensor_dev_attr_in0_min.dev_attr.attr, | 473 | &sensor_dev_attr_in0_min.dev_attr.attr, |
455 | &sensor_dev_attr_in0_max.dev_attr.attr, | 474 | &sensor_dev_attr_in0_max.dev_attr.attr, |
475 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
456 | &sensor_dev_attr_in1_input.dev_attr.attr, | 476 | &sensor_dev_attr_in1_input.dev_attr.attr, |
457 | &sensor_dev_attr_in1_min.dev_attr.attr, | 477 | &sensor_dev_attr_in1_min.dev_attr.attr, |
458 | &sensor_dev_attr_in1_max.dev_attr.attr, | 478 | &sensor_dev_attr_in1_max.dev_attr.attr, |
479 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
459 | &sensor_dev_attr_in2_input.dev_attr.attr, | 480 | &sensor_dev_attr_in2_input.dev_attr.attr, |
460 | &sensor_dev_attr_in2_min.dev_attr.attr, | 481 | &sensor_dev_attr_in2_min.dev_attr.attr, |
461 | &sensor_dev_attr_in2_max.dev_attr.attr, | 482 | &sensor_dev_attr_in2_max.dev_attr.attr, |
483 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
462 | &sensor_dev_attr_in3_input.dev_attr.attr, | 484 | &sensor_dev_attr_in3_input.dev_attr.attr, |
463 | &sensor_dev_attr_in3_min.dev_attr.attr, | 485 | &sensor_dev_attr_in3_min.dev_attr.attr, |
464 | &sensor_dev_attr_in3_max.dev_attr.attr, | 486 | &sensor_dev_attr_in3_max.dev_attr.attr, |
487 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
465 | &sensor_dev_attr_in4_input.dev_attr.attr, | 488 | &sensor_dev_attr_in4_input.dev_attr.attr, |
466 | &sensor_dev_attr_in4_min.dev_attr.attr, | 489 | &sensor_dev_attr_in4_min.dev_attr.attr, |
467 | &sensor_dev_attr_in4_max.dev_attr.attr, | 490 | &sensor_dev_attr_in4_max.dev_attr.attr, |
491 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
468 | &sensor_dev_attr_in5_input.dev_attr.attr, | 492 | &sensor_dev_attr_in5_input.dev_attr.attr, |
469 | &sensor_dev_attr_in5_min.dev_attr.attr, | 493 | &sensor_dev_attr_in5_min.dev_attr.attr, |
470 | &sensor_dev_attr_in5_max.dev_attr.attr, | 494 | &sensor_dev_attr_in5_max.dev_attr.attr, |
495 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
471 | &sensor_dev_attr_in6_input.dev_attr.attr, | 496 | &sensor_dev_attr_in6_input.dev_attr.attr, |
472 | &sensor_dev_attr_in6_min.dev_attr.attr, | 497 | &sensor_dev_attr_in6_min.dev_attr.attr, |
473 | &sensor_dev_attr_in6_max.dev_attr.attr, | 498 | &sensor_dev_attr_in6_max.dev_attr.attr, |
499 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
474 | &dev_attr_temp1_input.attr, | 500 | &dev_attr_temp1_input.attr, |
475 | &dev_attr_temp1_max.attr, | 501 | &dev_attr_temp1_max.attr, |
476 | &dev_attr_temp1_max_hyst.attr, | 502 | &dev_attr_temp1_max_hyst.attr, |
503 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
477 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 504 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
478 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 505 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
479 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 506 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
507 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
480 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 508 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
481 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 509 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
482 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 510 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
511 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
483 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 512 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
484 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 513 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
485 | &sensor_dev_attr_fan3_div.dev_attr.attr, | 514 | &sensor_dev_attr_fan3_div.dev_attr.attr, |
515 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
486 | &dev_attr_alarms.attr, | 516 | &dev_attr_alarms.attr, |
487 | &dev_attr_cpu0_vid.attr, | 517 | &dev_attr_cpu0_vid.attr, |
488 | 518 | ||
@@ -585,9 +615,9 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
585 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) | 615 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) |
586 | goto ERROR3; | 616 | goto ERROR3; |
587 | 617 | ||
588 | data->class_dev = hwmon_device_register(&new_client->dev); | 618 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
589 | if (IS_ERR(data->class_dev)) { | 619 | if (IS_ERR(data->hwmon_dev)) { |
590 | err = PTR_ERR(data->class_dev); | 620 | err = PTR_ERR(data->hwmon_dev); |
591 | goto ERROR4; | 621 | goto ERROR4; |
592 | } | 622 | } |
593 | 623 | ||
@@ -608,7 +638,7 @@ static int lm78_detach_client(struct i2c_client *client) | |||
608 | struct lm78_data *data = i2c_get_clientdata(client); | 638 | struct lm78_data *data = i2c_get_clientdata(client); |
609 | int err; | 639 | int err; |
610 | 640 | ||
611 | hwmon_device_unregister(data->class_dev); | 641 | hwmon_device_unregister(data->hwmon_dev); |
612 | sysfs_remove_group(&client->dev.kobj, &lm78_group); | 642 | sysfs_remove_group(&client->dev.kobj, &lm78_group); |
613 | 643 | ||
614 | if ((err = i2c_detach_client(client))) | 644 | if ((err = i2c_detach_client(client))) |
@@ -659,9 +689,9 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
659 | || (err = device_create_file(&pdev->dev, &dev_attr_name))) | 689 | || (err = device_create_file(&pdev->dev, &dev_attr_name))) |
660 | goto exit_remove_files; | 690 | goto exit_remove_files; |
661 | 691 | ||
662 | data->class_dev = hwmon_device_register(&pdev->dev); | 692 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
663 | if (IS_ERR(data->class_dev)) { | 693 | if (IS_ERR(data->hwmon_dev)) { |
664 | err = PTR_ERR(data->class_dev); | 694 | err = PTR_ERR(data->hwmon_dev); |
665 | goto exit_remove_files; | 695 | goto exit_remove_files; |
666 | } | 696 | } |
667 | 697 | ||
@@ -681,7 +711,7 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev) | |||
681 | { | 711 | { |
682 | struct lm78_data *data = platform_get_drvdata(pdev); | 712 | struct lm78_data *data = platform_get_drvdata(pdev); |
683 | 713 | ||
684 | hwmon_device_unregister(data->class_dev); | 714 | hwmon_device_unregister(data->hwmon_dev); |
685 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); | 715 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); |
686 | device_remove_file(&pdev->dev, &dev_attr_name); | 716 | device_remove_file(&pdev->dev, &dev_attr_name); |
687 | release_region(data->client.addr, LM78_EXTENT); | 717 | release_region(data->client.addr, LM78_EXTENT); |
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 064516d824ad..063cdba00a88 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -108,7 +108,7 @@ static inline long TEMP_FROM_REG(u16 temp) | |||
108 | 108 | ||
109 | struct lm80_data { | 109 | struct lm80_data { |
110 | struct i2c_client client; | 110 | struct i2c_client client; |
111 | struct class_device *class_dev; | 111 | struct device *hwmon_dev; |
112 | struct mutex update_lock; | 112 | struct mutex update_lock; |
113 | char valid; /* !=0 if following fields are valid */ | 113 | char valid; /* !=0 if following fields are valid */ |
114 | unsigned long last_updated; /* In jiffies */ | 114 | unsigned long last_updated; /* In jiffies */ |
@@ -497,9 +497,9 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) | |||
497 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group))) | 497 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group))) |
498 | goto error_detach; | 498 | goto error_detach; |
499 | 499 | ||
500 | data->class_dev = hwmon_device_register(&new_client->dev); | 500 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
501 | if (IS_ERR(data->class_dev)) { | 501 | if (IS_ERR(data->hwmon_dev)) { |
502 | err = PTR_ERR(data->class_dev); | 502 | err = PTR_ERR(data->hwmon_dev); |
503 | goto error_remove; | 503 | goto error_remove; |
504 | } | 504 | } |
505 | 505 | ||
@@ -520,7 +520,7 @@ static int lm80_detach_client(struct i2c_client *client) | |||
520 | struct lm80_data *data = i2c_get_clientdata(client); | 520 | struct lm80_data *data = i2c_get_clientdata(client); |
521 | int err; | 521 | int err; |
522 | 522 | ||
523 | hwmon_device_unregister(data->class_dev); | 523 | hwmon_device_unregister(data->hwmon_dev); |
524 | sysfs_remove_group(&client->dev.kobj, &lm80_group); | 524 | sysfs_remove_group(&client->dev.kobj, &lm80_group); |
525 | if ((err = i2c_detach_client(client))) | 525 | if ((err = i2c_detach_client(client))) |
526 | return err; | 526 | return err; |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 654c0f73464d..0336b4572a61 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -144,7 +144,7 @@ static struct i2c_driver lm83_driver = { | |||
144 | 144 | ||
145 | struct lm83_data { | 145 | struct lm83_data { |
146 | struct i2c_client client; | 146 | struct i2c_client client; |
147 | struct class_device *class_dev; | 147 | struct device *hwmon_dev; |
148 | struct mutex update_lock; | 148 | struct mutex update_lock; |
149 | char valid; /* zero until following fields are valid */ | 149 | char valid; /* zero until following fields are valid */ |
150 | unsigned long last_updated; /* in jiffies */ | 150 | unsigned long last_updated; /* in jiffies */ |
@@ -400,9 +400,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
400 | goto exit_remove_files; | 400 | goto exit_remove_files; |
401 | } | 401 | } |
402 | 402 | ||
403 | data->class_dev = hwmon_device_register(&new_client->dev); | 403 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
404 | if (IS_ERR(data->class_dev)) { | 404 | if (IS_ERR(data->hwmon_dev)) { |
405 | err = PTR_ERR(data->class_dev); | 405 | err = PTR_ERR(data->hwmon_dev); |
406 | goto exit_remove_files; | 406 | goto exit_remove_files; |
407 | } | 407 | } |
408 | 408 | ||
@@ -424,7 +424,7 @@ static int lm83_detach_client(struct i2c_client *client) | |||
424 | struct lm83_data *data = i2c_get_clientdata(client); | 424 | struct lm83_data *data = i2c_get_clientdata(client); |
425 | int err; | 425 | int err; |
426 | 426 | ||
427 | hwmon_device_unregister(data->class_dev); | 427 | hwmon_device_unregister(data->hwmon_dev); |
428 | sysfs_remove_group(&client->dev.kobj, &lm83_group); | 428 | sysfs_remove_group(&client->dev.kobj, &lm83_group); |
429 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); | 429 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); |
430 | 430 | ||
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 20a8c648280d..a02480be65f2 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include <linux/hwmon.h> | 31 | #include <linux/hwmon.h> |
32 | #include <linux/hwmon-vid.h> | 32 | #include <linux/hwmon-vid.h> |
33 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <linux/err.h> | 34 | #include <linux/err.h> |
34 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
35 | 36 | ||
@@ -122,23 +123,6 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
122 | #define EMC6D102_REG_EXTEND_ADC3 0x87 | 123 | #define EMC6D102_REG_EXTEND_ADC3 0x87 |
123 | #define EMC6D102_REG_EXTEND_ADC4 0x88 | 124 | #define EMC6D102_REG_EXTEND_ADC4 0x88 |
124 | 125 | ||
125 | #define LM85_ALARM_IN0 0x0001 | ||
126 | #define LM85_ALARM_IN1 0x0002 | ||
127 | #define LM85_ALARM_IN2 0x0004 | ||
128 | #define LM85_ALARM_IN3 0x0008 | ||
129 | #define LM85_ALARM_TEMP1 0x0010 | ||
130 | #define LM85_ALARM_TEMP2 0x0020 | ||
131 | #define LM85_ALARM_TEMP3 0x0040 | ||
132 | #define LM85_ALARM_ALARM2 0x0080 | ||
133 | #define LM85_ALARM_IN4 0x0100 | ||
134 | #define LM85_ALARM_RESERVED 0x0200 | ||
135 | #define LM85_ALARM_FAN1 0x0400 | ||
136 | #define LM85_ALARM_FAN2 0x0800 | ||
137 | #define LM85_ALARM_FAN3 0x1000 | ||
138 | #define LM85_ALARM_FAN4 0x2000 | ||
139 | #define LM85_ALARM_TEMP1_FAULT 0x4000 | ||
140 | #define LM85_ALARM_TEMP3_FAULT 0x8000 | ||
141 | |||
142 | 126 | ||
143 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 127 | /* Conversions. Rounding and limit checking is only done on the TO_REG |
144 | variants. Note that you should be a bit careful with which arguments | 128 | variants. Note that you should be a bit careful with which arguments |
@@ -155,22 +139,26 @@ static int lm85_scaling[] = { /* .001 Volts */ | |||
155 | #define INS_TO_REG(n,val) \ | 139 | #define INS_TO_REG(n,val) \ |
156 | SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255) | 140 | SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255) |
157 | 141 | ||
158 | #define INSEXT_FROM_REG(n,val,ext,scale) \ | 142 | #define INSEXT_FROM_REG(n,val,ext) \ |
159 | SCALE((val)*(scale) + (ext),192*(scale),lm85_scaling[n]) | 143 | SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n]) |
160 | 144 | ||
161 | #define INS_FROM_REG(n,val) INSEXT_FROM_REG(n,val,0,1) | 145 | #define INS_FROM_REG(n,val) SCALE((val), 192, lm85_scaling[n]) |
162 | 146 | ||
163 | /* FAN speed is measured using 90kHz clock */ | 147 | /* FAN speed is measured using 90kHz clock */ |
164 | #define FAN_TO_REG(val) (SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534)) | 148 | static inline u16 FAN_TO_REG(unsigned long val) |
149 | { | ||
150 | if (!val) | ||
151 | return 0xffff; | ||
152 | return SENSORS_LIMIT(5400000 / val, 1, 0xfffe); | ||
153 | } | ||
165 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) | 154 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) |
166 | 155 | ||
167 | /* Temperature is reported in .001 degC increments */ | 156 | /* Temperature is reported in .001 degC increments */ |
168 | #define TEMP_TO_REG(val) \ | 157 | #define TEMP_TO_REG(val) \ |
169 | SENSORS_LIMIT(SCALE(val,1000,1),-127,127) | 158 | SENSORS_LIMIT(SCALE(val,1000,1),-127,127) |
170 | #define TEMPEXT_FROM_REG(val,ext,scale) \ | 159 | #define TEMPEXT_FROM_REG(val,ext) \ |
171 | SCALE((val)*scale + (ext),scale,1000) | 160 | SCALE(((val) << 4) + (ext), 16, 1000) |
172 | #define TEMP_FROM_REG(val) \ | 161 | #define TEMP_FROM_REG(val) ((val) * 1000) |
173 | TEMPEXT_FROM_REG(val,0,1) | ||
174 | 162 | ||
175 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) | 163 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) |
176 | #define PWM_FROM_REG(val) (val) | 164 | #define PWM_FROM_REG(val) (val) |
@@ -328,7 +316,7 @@ struct lm85_autofan { | |||
328 | The structure is dynamically allocated. */ | 316 | The structure is dynamically allocated. */ |
329 | struct lm85_data { | 317 | struct lm85_data { |
330 | struct i2c_client client; | 318 | struct i2c_client client; |
331 | struct class_device *class_dev; | 319 | struct device *hwmon_dev; |
332 | enum chips type; | 320 | enum chips type; |
333 | 321 | ||
334 | struct mutex update_lock; | 322 | struct mutex update_lock; |
@@ -350,7 +338,6 @@ struct lm85_data { | |||
350 | u8 tach_mode; /* Register encoding, combined */ | 338 | u8 tach_mode; /* Register encoding, combined */ |
351 | u8 temp_ext[3]; /* Decoded values */ | 339 | u8 temp_ext[3]; /* Decoded values */ |
352 | u8 in_ext[8]; /* Decoded values */ | 340 | u8 in_ext[8]; /* Decoded values */ |
353 | u8 adc_scale; /* ADC Extended bits scaling factor */ | ||
354 | u8 fan_ppr; /* Register value */ | 341 | u8 fan_ppr; /* Register value */ |
355 | u8 smooth[3]; /* Register encoding */ | 342 | u8 smooth[3]; /* Register encoding */ |
356 | u8 vid; /* Register value */ | 343 | u8 vid; /* Register value */ |
@@ -387,22 +374,29 @@ static struct i2c_driver lm85_driver = { | |||
387 | 374 | ||
388 | 375 | ||
389 | /* 4 Fans */ | 376 | /* 4 Fans */ |
390 | static ssize_t show_fan(struct device *dev, char *buf, int nr) | 377 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
378 | char *buf) | ||
391 | { | 379 | { |
380 | int nr = to_sensor_dev_attr(attr)->index; | ||
392 | struct lm85_data *data = lm85_update_device(dev); | 381 | struct lm85_data *data = lm85_update_device(dev); |
393 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); | 382 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); |
394 | } | 383 | } |
395 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) | 384 | |
385 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
386 | char *buf) | ||
396 | { | 387 | { |
388 | int nr = to_sensor_dev_attr(attr)->index; | ||
397 | struct lm85_data *data = lm85_update_device(dev); | 389 | struct lm85_data *data = lm85_update_device(dev); |
398 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); | 390 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); |
399 | } | 391 | } |
400 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 392 | |
401 | size_t count, int nr) | 393 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
394 | const char *buf, size_t count) | ||
402 | { | 395 | { |
396 | int nr = to_sensor_dev_attr(attr)->index; | ||
403 | struct i2c_client *client = to_i2c_client(dev); | 397 | struct i2c_client *client = to_i2c_client(dev); |
404 | struct lm85_data *data = i2c_get_clientdata(client); | 398 | struct lm85_data *data = i2c_get_clientdata(client); |
405 | long val = simple_strtol(buf, NULL, 10); | 399 | unsigned long val = simple_strtoul(buf, NULL, 10); |
406 | 400 | ||
407 | mutex_lock(&data->update_lock); | 401 | mutex_lock(&data->update_lock); |
408 | data->fan_min[nr] = FAN_TO_REG(val); | 402 | data->fan_min[nr] = FAN_TO_REG(val); |
@@ -412,23 +406,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, | |||
412 | } | 406 | } |
413 | 407 | ||
414 | #define show_fan_offset(offset) \ | 408 | #define show_fan_offset(offset) \ |
415 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 409 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
416 | { \ | 410 | show_fan, NULL, offset - 1); \ |
417 | return show_fan(dev, buf, offset - 1); \ | 411 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
418 | } \ | 412 | show_fan_min, set_fan_min, offset - 1) |
419 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
420 | { \ | ||
421 | return show_fan_min(dev, buf, offset - 1); \ | ||
422 | } \ | ||
423 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
424 | const char *buf, size_t count) \ | ||
425 | { \ | ||
426 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
427 | } \ | ||
428 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, \ | ||
429 | NULL); \ | ||
430 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
431 | show_fan_##offset##_min, set_fan_##offset##_min); | ||
432 | 413 | ||
433 | show_fan_offset(1); | 414 | show_fan_offset(1); |
434 | show_fan_offset(2); | 415 | show_fan_offset(2); |
@@ -457,7 +438,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
457 | 438 | ||
458 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 439 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
459 | { | 440 | { |
460 | struct lm85_data *data = lm85_update_device(dev); | 441 | struct lm85_data *data = dev_get_drvdata(dev); |
461 | return sprintf(buf, "%ld\n", (long) data->vrm); | 442 | return sprintf(buf, "%ld\n", (long) data->vrm); |
462 | } | 443 | } |
463 | 444 | ||
@@ -482,16 +463,46 @@ static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr | |||
482 | 463 | ||
483 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 464 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
484 | 465 | ||
466 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
467 | char *buf) | ||
468 | { | ||
469 | int nr = to_sensor_dev_attr(attr)->index; | ||
470 | struct lm85_data *data = lm85_update_device(dev); | ||
471 | return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); | ||
472 | } | ||
473 | |||
474 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
475 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
476 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
477 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
478 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
479 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 18); | ||
480 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 16); | ||
481 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 17); | ||
482 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
483 | static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_alarm, NULL, 14); | ||
484 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
485 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
486 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); | ||
487 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
488 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
489 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
490 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 13); | ||
491 | |||
485 | /* pwm */ | 492 | /* pwm */ |
486 | 493 | ||
487 | static ssize_t show_pwm(struct device *dev, char *buf, int nr) | 494 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, |
495 | char *buf) | ||
488 | { | 496 | { |
497 | int nr = to_sensor_dev_attr(attr)->index; | ||
489 | struct lm85_data *data = lm85_update_device(dev); | 498 | struct lm85_data *data = lm85_update_device(dev); |
490 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); | 499 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); |
491 | } | 500 | } |
492 | static ssize_t set_pwm(struct device *dev, const char *buf, | 501 | |
493 | size_t count, int nr) | 502 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
503 | const char *buf, size_t count) | ||
494 | { | 504 | { |
505 | int nr = to_sensor_dev_attr(attr)->index; | ||
495 | struct i2c_client *client = to_i2c_client(dev); | 506 | struct i2c_client *client = to_i2c_client(dev); |
496 | struct lm85_data *data = i2c_get_clientdata(client); | 507 | struct lm85_data *data = i2c_get_clientdata(client); |
497 | long val = simple_strtol(buf, NULL, 10); | 508 | long val = simple_strtol(buf, NULL, 10); |
@@ -502,8 +513,11 @@ static ssize_t set_pwm(struct device *dev, const char *buf, | |||
502 | mutex_unlock(&data->update_lock); | 513 | mutex_unlock(&data->update_lock); |
503 | return count; | 514 | return count; |
504 | } | 515 | } |
505 | static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) | 516 | |
517 | static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | ||
518 | *attr, char *buf) | ||
506 | { | 519 | { |
520 | int nr = to_sensor_dev_attr(attr)->index; | ||
507 | struct lm85_data *data = lm85_update_device(dev); | 521 | struct lm85_data *data = lm85_update_device(dev); |
508 | int pwm_zone; | 522 | int pwm_zone; |
509 | 523 | ||
@@ -512,23 +526,10 @@ static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) | |||
512 | } | 526 | } |
513 | 527 | ||
514 | #define show_pwm_reg(offset) \ | 528 | #define show_pwm_reg(offset) \ |
515 | static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 529 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
516 | { \ | 530 | show_pwm, set_pwm, offset - 1); \ |
517 | return show_pwm(dev, buf, offset - 1); \ | 531 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \ |
518 | } \ | 532 | show_pwm_enable, NULL, offset - 1) |
519 | static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr, \ | ||
520 | const char *buf, size_t count) \ | ||
521 | { \ | ||
522 | return set_pwm(dev, buf, count, offset - 1); \ | ||
523 | } \ | ||
524 | static ssize_t show_pwm_enable##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
525 | { \ | ||
526 | return show_pwm_enable(dev, buf, offset - 1); \ | ||
527 | } \ | ||
528 | static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | ||
529 | show_pwm_##offset, set_pwm_##offset); \ | ||
530 | static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \ | ||
531 | show_pwm_enable##offset, NULL); | ||
532 | 533 | ||
533 | show_pwm_reg(1); | 534 | show_pwm_reg(1); |
534 | show_pwm_reg(2); | 535 | show_pwm_reg(2); |
@@ -536,22 +537,28 @@ show_pwm_reg(3); | |||
536 | 537 | ||
537 | /* Voltages */ | 538 | /* Voltages */ |
538 | 539 | ||
539 | static ssize_t show_in(struct device *dev, char *buf, int nr) | 540 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
541 | char *buf) | ||
540 | { | 542 | { |
543 | int nr = to_sensor_dev_attr(attr)->index; | ||
541 | struct lm85_data *data = lm85_update_device(dev); | 544 | struct lm85_data *data = lm85_update_device(dev); |
542 | return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr, | 545 | return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr, |
543 | data->in[nr], | 546 | data->in[nr], |
544 | data->in_ext[nr], | 547 | data->in_ext[nr])); |
545 | data->adc_scale) ); | ||
546 | } | 548 | } |
547 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) | 549 | |
550 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
551 | char *buf) | ||
548 | { | 552 | { |
553 | int nr = to_sensor_dev_attr(attr)->index; | ||
549 | struct lm85_data *data = lm85_update_device(dev); | 554 | struct lm85_data *data = lm85_update_device(dev); |
550 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); | 555 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); |
551 | } | 556 | } |
552 | static ssize_t set_in_min(struct device *dev, const char *buf, | 557 | |
553 | size_t count, int nr) | 558 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, |
559 | const char *buf, size_t count) | ||
554 | { | 560 | { |
561 | int nr = to_sensor_dev_attr(attr)->index; | ||
555 | struct i2c_client *client = to_i2c_client(dev); | 562 | struct i2c_client *client = to_i2c_client(dev); |
556 | struct lm85_data *data = i2c_get_clientdata(client); | 563 | struct lm85_data *data = i2c_get_clientdata(client); |
557 | long val = simple_strtol(buf, NULL, 10); | 564 | long val = simple_strtol(buf, NULL, 10); |
@@ -562,14 +569,19 @@ static ssize_t set_in_min(struct device *dev, const char *buf, | |||
562 | mutex_unlock(&data->update_lock); | 569 | mutex_unlock(&data->update_lock); |
563 | return count; | 570 | return count; |
564 | } | 571 | } |
565 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) | 572 | |
573 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
574 | char *buf) | ||
566 | { | 575 | { |
576 | int nr = to_sensor_dev_attr(attr)->index; | ||
567 | struct lm85_data *data = lm85_update_device(dev); | 577 | struct lm85_data *data = lm85_update_device(dev); |
568 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); | 578 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); |
569 | } | 579 | } |
570 | static ssize_t set_in_max(struct device *dev, const char *buf, | 580 | |
571 | size_t count, int nr) | 581 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, |
582 | const char *buf, size_t count) | ||
572 | { | 583 | { |
584 | int nr = to_sensor_dev_attr(attr)->index; | ||
573 | struct i2c_client *client = to_i2c_client(dev); | 585 | struct i2c_client *client = to_i2c_client(dev); |
574 | struct lm85_data *data = i2c_get_clientdata(client); | 586 | struct lm85_data *data = i2c_get_clientdata(client); |
575 | long val = simple_strtol(buf, NULL, 10); | 587 | long val = simple_strtol(buf, NULL, 10); |
@@ -580,59 +592,47 @@ static ssize_t set_in_max(struct device *dev, const char *buf, | |||
580 | mutex_unlock(&data->update_lock); | 592 | mutex_unlock(&data->update_lock); |
581 | return count; | 593 | return count; |
582 | } | 594 | } |
595 | |||
583 | #define show_in_reg(offset) \ | 596 | #define show_in_reg(offset) \ |
584 | static ssize_t show_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 597 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
585 | { \ | 598 | show_in, NULL, offset); \ |
586 | return show_in(dev, buf, offset); \ | 599 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
587 | } \ | 600 | show_in_min, set_in_min, offset); \ |
588 | static ssize_t show_in_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 601 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
589 | { \ | 602 | show_in_max, set_in_max, offset) |
590 | return show_in_min(dev, buf, offset); \ | ||
591 | } \ | ||
592 | static ssize_t show_in_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
593 | { \ | ||
594 | return show_in_max(dev, buf, offset); \ | ||
595 | } \ | ||
596 | static ssize_t set_in_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
597 | const char *buf, size_t count) \ | ||
598 | { \ | ||
599 | return set_in_min(dev, buf, count, offset); \ | ||
600 | } \ | ||
601 | static ssize_t set_in_##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
602 | const char *buf, size_t count) \ | ||
603 | { \ | ||
604 | return set_in_max(dev, buf, count, offset); \ | ||
605 | } \ | ||
606 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, \ | ||
607 | NULL); \ | ||
608 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
609 | show_in_##offset##_min, set_in_##offset##_min); \ | ||
610 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
611 | show_in_##offset##_max, set_in_##offset##_max); | ||
612 | 603 | ||
613 | show_in_reg(0); | 604 | show_in_reg(0); |
614 | show_in_reg(1); | 605 | show_in_reg(1); |
615 | show_in_reg(2); | 606 | show_in_reg(2); |
616 | show_in_reg(3); | 607 | show_in_reg(3); |
617 | show_in_reg(4); | 608 | show_in_reg(4); |
609 | show_in_reg(5); | ||
610 | show_in_reg(6); | ||
611 | show_in_reg(7); | ||
618 | 612 | ||
619 | /* Temps */ | 613 | /* Temps */ |
620 | 614 | ||
621 | static ssize_t show_temp(struct device *dev, char *buf, int nr) | 615 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, |
616 | char *buf) | ||
622 | { | 617 | { |
618 | int nr = to_sensor_dev_attr(attr)->index; | ||
623 | struct lm85_data *data = lm85_update_device(dev); | 619 | struct lm85_data *data = lm85_update_device(dev); |
624 | return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr], | 620 | return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr], |
625 | data->temp_ext[nr], | 621 | data->temp_ext[nr])); |
626 | data->adc_scale) ); | ||
627 | } | 622 | } |
628 | static ssize_t show_temp_min(struct device *dev, char *buf, int nr) | 623 | |
624 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | ||
625 | char *buf) | ||
629 | { | 626 | { |
627 | int nr = to_sensor_dev_attr(attr)->index; | ||
630 | struct lm85_data *data = lm85_update_device(dev); | 628 | struct lm85_data *data = lm85_update_device(dev); |
631 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); | 629 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); |
632 | } | 630 | } |
633 | static ssize_t set_temp_min(struct device *dev, const char *buf, | 631 | |
634 | size_t count, int nr) | 632 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, |
633 | const char *buf, size_t count) | ||
635 | { | 634 | { |
635 | int nr = to_sensor_dev_attr(attr)->index; | ||
636 | struct i2c_client *client = to_i2c_client(dev); | 636 | struct i2c_client *client = to_i2c_client(dev); |
637 | struct lm85_data *data = i2c_get_clientdata(client); | 637 | struct lm85_data *data = i2c_get_clientdata(client); |
638 | long val = simple_strtol(buf, NULL, 10); | 638 | long val = simple_strtol(buf, NULL, 10); |
@@ -643,14 +643,19 @@ static ssize_t set_temp_min(struct device *dev, const char *buf, | |||
643 | mutex_unlock(&data->update_lock); | 643 | mutex_unlock(&data->update_lock); |
644 | return count; | 644 | return count; |
645 | } | 645 | } |
646 | static ssize_t show_temp_max(struct device *dev, char *buf, int nr) | 646 | |
647 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
648 | char *buf) | ||
647 | { | 649 | { |
650 | int nr = to_sensor_dev_attr(attr)->index; | ||
648 | struct lm85_data *data = lm85_update_device(dev); | 651 | struct lm85_data *data = lm85_update_device(dev); |
649 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); | 652 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); |
650 | } | 653 | } |
651 | static ssize_t set_temp_max(struct device *dev, const char *buf, | 654 | |
652 | size_t count, int nr) | 655 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, |
656 | const char *buf, size_t count) | ||
653 | { | 657 | { |
658 | int nr = to_sensor_dev_attr(attr)->index; | ||
654 | struct i2c_client *client = to_i2c_client(dev); | 659 | struct i2c_client *client = to_i2c_client(dev); |
655 | struct lm85_data *data = i2c_get_clientdata(client); | 660 | struct lm85_data *data = i2c_get_clientdata(client); |
656 | long val = simple_strtol(buf, NULL, 10); | 661 | long val = simple_strtol(buf, NULL, 10); |
@@ -661,35 +666,14 @@ static ssize_t set_temp_max(struct device *dev, const char *buf, | |||
661 | mutex_unlock(&data->update_lock); | 666 | mutex_unlock(&data->update_lock); |
662 | return count; | 667 | return count; |
663 | } | 668 | } |
669 | |||
664 | #define show_temp_reg(offset) \ | 670 | #define show_temp_reg(offset) \ |
665 | static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 671 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
666 | { \ | 672 | show_temp, NULL, offset - 1); \ |
667 | return show_temp(dev, buf, offset - 1); \ | 673 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ |
668 | } \ | 674 | show_temp_min, set_temp_min, offset - 1); \ |
669 | static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 675 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
670 | { \ | 676 | show_temp_max, set_temp_max, offset - 1); |
671 | return show_temp_min(dev, buf, offset - 1); \ | ||
672 | } \ | ||
673 | static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
674 | { \ | ||
675 | return show_temp_max(dev, buf, offset - 1); \ | ||
676 | } \ | ||
677 | static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
678 | const char *buf, size_t count) \ | ||
679 | { \ | ||
680 | return set_temp_min(dev, buf, count, offset - 1); \ | ||
681 | } \ | ||
682 | static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
683 | const char *buf, size_t count) \ | ||
684 | { \ | ||
685 | return set_temp_max(dev, buf, count, offset - 1); \ | ||
686 | } \ | ||
687 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, \ | ||
688 | NULL); \ | ||
689 | static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | ||
690 | show_temp_##offset##_min, set_temp_##offset##_min); \ | ||
691 | static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
692 | show_temp_##offset##_max, set_temp_##offset##_max); | ||
693 | 677 | ||
694 | show_temp_reg(1); | 678 | show_temp_reg(1); |
695 | show_temp_reg(2); | 679 | show_temp_reg(2); |
@@ -698,14 +682,18 @@ show_temp_reg(3); | |||
698 | 682 | ||
699 | /* Automatic PWM control */ | 683 | /* Automatic PWM control */ |
700 | 684 | ||
701 | static ssize_t show_pwm_auto_channels(struct device *dev, char *buf, int nr) | 685 | static ssize_t show_pwm_auto_channels(struct device *dev, |
686 | struct device_attribute *attr, char *buf) | ||
702 | { | 687 | { |
688 | int nr = to_sensor_dev_attr(attr)->index; | ||
703 | struct lm85_data *data = lm85_update_device(dev); | 689 | struct lm85_data *data = lm85_update_device(dev); |
704 | return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config)); | 690 | return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config)); |
705 | } | 691 | } |
706 | static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf, | 692 | |
707 | size_t count, int nr) | 693 | static ssize_t set_pwm_auto_channels(struct device *dev, |
694 | struct device_attribute *attr, const char *buf, size_t count) | ||
708 | { | 695 | { |
696 | int nr = to_sensor_dev_attr(attr)->index; | ||
709 | struct i2c_client *client = to_i2c_client(dev); | 697 | struct i2c_client *client = to_i2c_client(dev); |
710 | struct lm85_data *data = i2c_get_clientdata(client); | 698 | struct lm85_data *data = i2c_get_clientdata(client); |
711 | long val = simple_strtol(buf, NULL, 10); | 699 | long val = simple_strtol(buf, NULL, 10); |
@@ -718,14 +706,19 @@ static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf, | |||
718 | mutex_unlock(&data->update_lock); | 706 | mutex_unlock(&data->update_lock); |
719 | return count; | 707 | return count; |
720 | } | 708 | } |
721 | static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr) | 709 | |
710 | static ssize_t show_pwm_auto_pwm_min(struct device *dev, | ||
711 | struct device_attribute *attr, char *buf) | ||
722 | { | 712 | { |
713 | int nr = to_sensor_dev_attr(attr)->index; | ||
723 | struct lm85_data *data = lm85_update_device(dev); | 714 | struct lm85_data *data = lm85_update_device(dev); |
724 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); | 715 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); |
725 | } | 716 | } |
726 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf, | 717 | |
727 | size_t count, int nr) | 718 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, |
719 | struct device_attribute *attr, const char *buf, size_t count) | ||
728 | { | 720 | { |
721 | int nr = to_sensor_dev_attr(attr)->index; | ||
729 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct i2c_client *client = to_i2c_client(dev); |
730 | struct lm85_data *data = i2c_get_clientdata(client); | 723 | struct lm85_data *data = i2c_get_clientdata(client); |
731 | long val = simple_strtol(buf, NULL, 10); | 724 | long val = simple_strtol(buf, NULL, 10); |
@@ -737,14 +730,19 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf, | |||
737 | mutex_unlock(&data->update_lock); | 730 | mutex_unlock(&data->update_lock); |
738 | return count; | 731 | return count; |
739 | } | 732 | } |
740 | static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr) | 733 | |
734 | static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, | ||
735 | struct device_attribute *attr, char *buf) | ||
741 | { | 736 | { |
737 | int nr = to_sensor_dev_attr(attr)->index; | ||
742 | struct lm85_data *data = lm85_update_device(dev); | 738 | struct lm85_data *data = lm85_update_device(dev); |
743 | return sprintf(buf,"%d\n", data->autofan[nr].min_off); | 739 | return sprintf(buf,"%d\n", data->autofan[nr].min_off); |
744 | } | 740 | } |
745 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf, | 741 | |
746 | size_t count, int nr) | 742 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, |
743 | struct device_attribute *attr, const char *buf, size_t count) | ||
747 | { | 744 | { |
745 | int nr = to_sensor_dev_attr(attr)->index; | ||
748 | struct i2c_client *client = to_i2c_client(dev); | 746 | struct i2c_client *client = to_i2c_client(dev); |
749 | struct lm85_data *data = i2c_get_clientdata(client); | 747 | struct lm85_data *data = i2c_get_clientdata(client); |
750 | long val = simple_strtol(buf, NULL, 10); | 748 | long val = simple_strtol(buf, NULL, 10); |
@@ -760,14 +758,19 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf, | |||
760 | mutex_unlock(&data->update_lock); | 758 | mutex_unlock(&data->update_lock); |
761 | return count; | 759 | return count; |
762 | } | 760 | } |
763 | static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr) | 761 | |
762 | static ssize_t show_pwm_auto_pwm_freq(struct device *dev, | ||
763 | struct device_attribute *attr, char *buf) | ||
764 | { | 764 | { |
765 | int nr = to_sensor_dev_attr(attr)->index; | ||
765 | struct lm85_data *data = lm85_update_device(dev); | 766 | struct lm85_data *data = lm85_update_device(dev); |
766 | return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq)); | 767 | return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq)); |
767 | } | 768 | } |
768 | static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf, | 769 | |
769 | size_t count, int nr) | 770 | static ssize_t set_pwm_auto_pwm_freq(struct device *dev, |
771 | struct device_attribute *attr, const char *buf, size_t count) | ||
770 | { | 772 | { |
773 | int nr = to_sensor_dev_attr(attr)->index; | ||
771 | struct i2c_client *client = to_i2c_client(dev); | 774 | struct i2c_client *client = to_i2c_client(dev); |
772 | struct lm85_data *data = i2c_get_clientdata(client); | 775 | struct lm85_data *data = i2c_get_clientdata(client); |
773 | long val = simple_strtol(buf, NULL, 10); | 776 | long val = simple_strtol(buf, NULL, 10); |
@@ -781,74 +784,40 @@ static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf, | |||
781 | mutex_unlock(&data->update_lock); | 784 | mutex_unlock(&data->update_lock); |
782 | return count; | 785 | return count; |
783 | } | 786 | } |
787 | |||
784 | #define pwm_auto(offset) \ | 788 | #define pwm_auto(offset) \ |
785 | static ssize_t show_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \ | 789 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \ |
786 | char *buf) \ | 790 | S_IRUGO | S_IWUSR, show_pwm_auto_channels, \ |
787 | { \ | 791 | set_pwm_auto_channels, offset - 1); \ |
788 | return show_pwm_auto_channels(dev, buf, offset - 1); \ | 792 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \ |
789 | } \ | 793 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_min, \ |
790 | static ssize_t set_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \ | 794 | set_pwm_auto_pwm_min, offset - 1); \ |
791 | const char *buf, size_t count) \ | 795 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ |
792 | { \ | 796 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ |
793 | return set_pwm_auto_channels(dev, buf, count, offset - 1); \ | 797 | set_pwm_auto_pwm_minctl, offset - 1); \ |
794 | } \ | 798 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_freq, \ |
795 | static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \ | 799 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_freq, \ |
796 | char *buf) \ | 800 | set_pwm_auto_pwm_freq, offset - 1); |
797 | { \ | 801 | |
798 | return show_pwm_auto_pwm_min(dev, buf, offset - 1); \ | ||
799 | } \ | ||
800 | static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \ | ||
801 | const char *buf, size_t count) \ | ||
802 | { \ | ||
803 | return set_pwm_auto_pwm_min(dev, buf, count, offset - 1); \ | ||
804 | } \ | ||
805 | static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \ | ||
806 | char *buf) \ | ||
807 | { \ | ||
808 | return show_pwm_auto_pwm_minctl(dev, buf, offset - 1); \ | ||
809 | } \ | ||
810 | static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \ | ||
811 | const char *buf, size_t count) \ | ||
812 | { \ | ||
813 | return set_pwm_auto_pwm_minctl(dev, buf, count, offset - 1); \ | ||
814 | } \ | ||
815 | static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev, struct device_attribute *attr, \ | ||
816 | char *buf) \ | ||
817 | { \ | ||
818 | return show_pwm_auto_pwm_freq(dev, buf, offset - 1); \ | ||
819 | } \ | ||
820 | static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev, struct device_attribute *attr, \ | ||
821 | const char *buf, size_t count) \ | ||
822 | { \ | ||
823 | return set_pwm_auto_pwm_freq(dev, buf, count, offset - 1); \ | ||
824 | } \ | ||
825 | static DEVICE_ATTR(pwm##offset##_auto_channels, S_IRUGO | S_IWUSR, \ | ||
826 | show_pwm##offset##_auto_channels, \ | ||
827 | set_pwm##offset##_auto_channels); \ | ||
828 | static DEVICE_ATTR(pwm##offset##_auto_pwm_min, S_IRUGO | S_IWUSR, \ | ||
829 | show_pwm##offset##_auto_pwm_min, \ | ||
830 | set_pwm##offset##_auto_pwm_min); \ | ||
831 | static DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, S_IRUGO | S_IWUSR, \ | ||
832 | show_pwm##offset##_auto_pwm_minctl, \ | ||
833 | set_pwm##offset##_auto_pwm_minctl); \ | ||
834 | static DEVICE_ATTR(pwm##offset##_auto_pwm_freq, S_IRUGO | S_IWUSR, \ | ||
835 | show_pwm##offset##_auto_pwm_freq, \ | ||
836 | set_pwm##offset##_auto_pwm_freq); | ||
837 | pwm_auto(1); | 802 | pwm_auto(1); |
838 | pwm_auto(2); | 803 | pwm_auto(2); |
839 | pwm_auto(3); | 804 | pwm_auto(3); |
840 | 805 | ||
841 | /* Temperature settings for automatic PWM control */ | 806 | /* Temperature settings for automatic PWM control */ |
842 | 807 | ||
843 | static ssize_t show_temp_auto_temp_off(struct device *dev, char *buf, int nr) | 808 | static ssize_t show_temp_auto_temp_off(struct device *dev, |
809 | struct device_attribute *attr, char *buf) | ||
844 | { | 810 | { |
811 | int nr = to_sensor_dev_attr(attr)->index; | ||
845 | struct lm85_data *data = lm85_update_device(dev); | 812 | struct lm85_data *data = lm85_update_device(dev); |
846 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) - | 813 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) - |
847 | HYST_FROM_REG(data->zone[nr].hyst)); | 814 | HYST_FROM_REG(data->zone[nr].hyst)); |
848 | } | 815 | } |
849 | static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf, | 816 | |
850 | size_t count, int nr) | 817 | static ssize_t set_temp_auto_temp_off(struct device *dev, |
818 | struct device_attribute *attr, const char *buf, size_t count) | ||
851 | { | 819 | { |
820 | int nr = to_sensor_dev_attr(attr)->index; | ||
852 | struct i2c_client *client = to_i2c_client(dev); | 821 | struct i2c_client *client = to_i2c_client(dev); |
853 | struct lm85_data *data = i2c_get_clientdata(client); | 822 | struct lm85_data *data = i2c_get_clientdata(client); |
854 | int min; | 823 | int min; |
@@ -871,14 +840,19 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf, | |||
871 | mutex_unlock(&data->update_lock); | 840 | mutex_unlock(&data->update_lock); |
872 | return count; | 841 | return count; |
873 | } | 842 | } |
874 | static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr) | 843 | |
844 | static ssize_t show_temp_auto_temp_min(struct device *dev, | ||
845 | struct device_attribute *attr, char *buf) | ||
875 | { | 846 | { |
847 | int nr = to_sensor_dev_attr(attr)->index; | ||
876 | struct lm85_data *data = lm85_update_device(dev); | 848 | struct lm85_data *data = lm85_update_device(dev); |
877 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) ); | 849 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) ); |
878 | } | 850 | } |
879 | static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf, | 851 | |
880 | size_t count, int nr) | 852 | static ssize_t set_temp_auto_temp_min(struct device *dev, |
853 | struct device_attribute *attr, const char *buf, size_t count) | ||
881 | { | 854 | { |
855 | int nr = to_sensor_dev_attr(attr)->index; | ||
882 | struct i2c_client *client = to_i2c_client(dev); | 856 | struct i2c_client *client = to_i2c_client(dev); |
883 | struct lm85_data *data = i2c_get_clientdata(client); | 857 | struct lm85_data *data = i2c_get_clientdata(client); |
884 | long val = simple_strtol(buf, NULL, 10); | 858 | long val = simple_strtol(buf, NULL, 10); |
@@ -913,15 +887,20 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf, | |||
913 | mutex_unlock(&data->update_lock); | 887 | mutex_unlock(&data->update_lock); |
914 | return count; | 888 | return count; |
915 | } | 889 | } |
916 | static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr) | 890 | |
891 | static ssize_t show_temp_auto_temp_max(struct device *dev, | ||
892 | struct device_attribute *attr, char *buf) | ||
917 | { | 893 | { |
894 | int nr = to_sensor_dev_attr(attr)->index; | ||
918 | struct lm85_data *data = lm85_update_device(dev); | 895 | struct lm85_data *data = lm85_update_device(dev); |
919 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) + | 896 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) + |
920 | RANGE_FROM_REG(data->zone[nr].range)); | 897 | RANGE_FROM_REG(data->zone[nr].range)); |
921 | } | 898 | } |
922 | static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf, | 899 | |
923 | size_t count, int nr) | 900 | static ssize_t set_temp_auto_temp_max(struct device *dev, |
901 | struct device_attribute *attr, const char *buf, size_t count) | ||
924 | { | 902 | { |
903 | int nr = to_sensor_dev_attr(attr)->index; | ||
925 | struct i2c_client *client = to_i2c_client(dev); | 904 | struct i2c_client *client = to_i2c_client(dev); |
926 | struct lm85_data *data = i2c_get_clientdata(client); | 905 | struct lm85_data *data = i2c_get_clientdata(client); |
927 | int min; | 906 | int min; |
@@ -938,14 +917,19 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf, | |||
938 | mutex_unlock(&data->update_lock); | 917 | mutex_unlock(&data->update_lock); |
939 | return count; | 918 | return count; |
940 | } | 919 | } |
941 | static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr) | 920 | |
921 | static ssize_t show_temp_auto_temp_crit(struct device *dev, | ||
922 | struct device_attribute *attr, char *buf) | ||
942 | { | 923 | { |
924 | int nr = to_sensor_dev_attr(attr)->index; | ||
943 | struct lm85_data *data = lm85_update_device(dev); | 925 | struct lm85_data *data = lm85_update_device(dev); |
944 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical)); | 926 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical)); |
945 | } | 927 | } |
946 | static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf, | 928 | |
947 | size_t count, int nr) | 929 | static ssize_t set_temp_auto_temp_crit(struct device *dev, |
930 | struct device_attribute *attr,const char *buf, size_t count) | ||
948 | { | 931 | { |
932 | int nr = to_sensor_dev_attr(attr)->index; | ||
949 | struct i2c_client *client = to_i2c_client(dev); | 933 | struct i2c_client *client = to_i2c_client(dev); |
950 | struct lm85_data *data = i2c_get_clientdata(client); | 934 | struct lm85_data *data = i2c_get_clientdata(client); |
951 | long val = simple_strtol(buf, NULL, 10); | 935 | long val = simple_strtol(buf, NULL, 10); |
@@ -957,59 +941,21 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf, | |||
957 | mutex_unlock(&data->update_lock); | 941 | mutex_unlock(&data->update_lock); |
958 | return count; | 942 | return count; |
959 | } | 943 | } |
944 | |||
960 | #define temp_auto(offset) \ | 945 | #define temp_auto(offset) \ |
961 | static ssize_t show_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \ | 946 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_off, \ |
962 | char *buf) \ | 947 | S_IRUGO | S_IWUSR, show_temp_auto_temp_off, \ |
963 | { \ | 948 | set_temp_auto_temp_off, offset - 1); \ |
964 | return show_temp_auto_temp_off(dev, buf, offset - 1); \ | 949 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_min, \ |
965 | } \ | 950 | S_IRUGO | S_IWUSR, show_temp_auto_temp_min, \ |
966 | static ssize_t set_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \ | 951 | set_temp_auto_temp_min, offset - 1); \ |
967 | const char *buf, size_t count) \ | 952 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_max, \ |
968 | { \ | 953 | S_IRUGO | S_IWUSR, show_temp_auto_temp_max, \ |
969 | return set_temp_auto_temp_off(dev, buf, count, offset - 1); \ | 954 | set_temp_auto_temp_max, offset - 1); \ |
970 | } \ | 955 | static SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_crit, \ |
971 | static ssize_t show_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \ | 956 | S_IRUGO | S_IWUSR, show_temp_auto_temp_crit, \ |
972 | char *buf) \ | 957 | set_temp_auto_temp_crit, offset - 1); |
973 | { \ | 958 | |
974 | return show_temp_auto_temp_min(dev, buf, offset - 1); \ | ||
975 | } \ | ||
976 | static ssize_t set_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \ | ||
977 | const char *buf, size_t count) \ | ||
978 | { \ | ||
979 | return set_temp_auto_temp_min(dev, buf, count, offset - 1); \ | ||
980 | } \ | ||
981 | static ssize_t show_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \ | ||
982 | char *buf) \ | ||
983 | { \ | ||
984 | return show_temp_auto_temp_max(dev, buf, offset - 1); \ | ||
985 | } \ | ||
986 | static ssize_t set_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \ | ||
987 | const char *buf, size_t count) \ | ||
988 | { \ | ||
989 | return set_temp_auto_temp_max(dev, buf, count, offset - 1); \ | ||
990 | } \ | ||
991 | static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \ | ||
992 | char *buf) \ | ||
993 | { \ | ||
994 | return show_temp_auto_temp_crit(dev, buf, offset - 1); \ | ||
995 | } \ | ||
996 | static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \ | ||
997 | const char *buf, size_t count) \ | ||
998 | { \ | ||
999 | return set_temp_auto_temp_crit(dev, buf, count, offset - 1); \ | ||
1000 | } \ | ||
1001 | static DEVICE_ATTR(temp##offset##_auto_temp_off, S_IRUGO | S_IWUSR, \ | ||
1002 | show_temp##offset##_auto_temp_off, \ | ||
1003 | set_temp##offset##_auto_temp_off); \ | ||
1004 | static DEVICE_ATTR(temp##offset##_auto_temp_min, S_IRUGO | S_IWUSR, \ | ||
1005 | show_temp##offset##_auto_temp_min, \ | ||
1006 | set_temp##offset##_auto_temp_min); \ | ||
1007 | static DEVICE_ATTR(temp##offset##_auto_temp_max, S_IRUGO | S_IWUSR, \ | ||
1008 | show_temp##offset##_auto_temp_max, \ | ||
1009 | set_temp##offset##_auto_temp_max); \ | ||
1010 | static DEVICE_ATTR(temp##offset##_auto_temp_crit, S_IRUGO | S_IWUSR, \ | ||
1011 | show_temp##offset##_auto_temp_crit, \ | ||
1012 | set_temp##offset##_auto_temp_crit); | ||
1013 | temp_auto(1); | 959 | temp_auto(1); |
1014 | temp_auto(2); | 960 | temp_auto(2); |
1015 | temp_auto(3); | 961 | temp_auto(3); |
@@ -1022,69 +968,87 @@ static int lm85_attach_adapter(struct i2c_adapter *adapter) | |||
1022 | } | 968 | } |
1023 | 969 | ||
1024 | static struct attribute *lm85_attributes[] = { | 970 | static struct attribute *lm85_attributes[] = { |
1025 | &dev_attr_fan1_input.attr, | 971 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1026 | &dev_attr_fan2_input.attr, | 972 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1027 | &dev_attr_fan3_input.attr, | 973 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1028 | &dev_attr_fan4_input.attr, | 974 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1029 | &dev_attr_fan1_min.attr, | 975 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1030 | &dev_attr_fan2_min.attr, | 976 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1031 | &dev_attr_fan3_min.attr, | 977 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1032 | &dev_attr_fan4_min.attr, | 978 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1033 | &dev_attr_pwm1.attr, | 979 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
1034 | &dev_attr_pwm2.attr, | 980 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
1035 | &dev_attr_pwm3.attr, | 981 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
1036 | &dev_attr_pwm1_enable.attr, | 982 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1037 | &dev_attr_pwm2_enable.attr, | 983 | |
1038 | &dev_attr_pwm3_enable.attr, | 984 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1039 | &dev_attr_in0_input.attr, | 985 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1040 | &dev_attr_in1_input.attr, | 986 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1041 | &dev_attr_in2_input.attr, | 987 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1042 | &dev_attr_in3_input.attr, | 988 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
1043 | &dev_attr_in0_min.attr, | 989 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
1044 | &dev_attr_in1_min.attr, | 990 | |
1045 | &dev_attr_in2_min.attr, | 991 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1046 | &dev_attr_in3_min.attr, | 992 | &sensor_dev_attr_in1_input.dev_attr.attr, |
1047 | &dev_attr_in0_max.attr, | 993 | &sensor_dev_attr_in2_input.dev_attr.attr, |
1048 | &dev_attr_in1_max.attr, | 994 | &sensor_dev_attr_in3_input.dev_attr.attr, |
1049 | &dev_attr_in2_max.attr, | 995 | &sensor_dev_attr_in0_min.dev_attr.attr, |
1050 | &dev_attr_in3_max.attr, | 996 | &sensor_dev_attr_in1_min.dev_attr.attr, |
1051 | &dev_attr_temp1_input.attr, | 997 | &sensor_dev_attr_in2_min.dev_attr.attr, |
1052 | &dev_attr_temp2_input.attr, | 998 | &sensor_dev_attr_in3_min.dev_attr.attr, |
1053 | &dev_attr_temp3_input.attr, | 999 | &sensor_dev_attr_in0_max.dev_attr.attr, |
1054 | &dev_attr_temp1_min.attr, | 1000 | &sensor_dev_attr_in1_max.dev_attr.attr, |
1055 | &dev_attr_temp2_min.attr, | 1001 | &sensor_dev_attr_in2_max.dev_attr.attr, |
1056 | &dev_attr_temp3_min.attr, | 1002 | &sensor_dev_attr_in3_max.dev_attr.attr, |
1057 | &dev_attr_temp1_max.attr, | 1003 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
1058 | &dev_attr_temp2_max.attr, | 1004 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
1059 | &dev_attr_temp3_max.attr, | 1005 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
1006 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1007 | |||
1008 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1009 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1010 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1011 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
1012 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1013 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1014 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
1015 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1016 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1017 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1018 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1019 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1020 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
1021 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
1022 | |||
1023 | &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, | ||
1024 | &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, | ||
1025 | &sensor_dev_attr_pwm3_auto_channels.dev_attr.attr, | ||
1026 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
1027 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
1028 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
1029 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | ||
1030 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | ||
1031 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | ||
1032 | &sensor_dev_attr_pwm1_auto_pwm_freq.dev_attr.attr, | ||
1033 | &sensor_dev_attr_pwm2_auto_pwm_freq.dev_attr.attr, | ||
1034 | &sensor_dev_attr_pwm3_auto_pwm_freq.dev_attr.attr, | ||
1035 | |||
1036 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | ||
1037 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | ||
1038 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, | ||
1039 | &sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr, | ||
1040 | &sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr, | ||
1041 | &sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr, | ||
1042 | &sensor_dev_attr_temp1_auto_temp_max.dev_attr.attr, | ||
1043 | &sensor_dev_attr_temp2_auto_temp_max.dev_attr.attr, | ||
1044 | &sensor_dev_attr_temp3_auto_temp_max.dev_attr.attr, | ||
1045 | &sensor_dev_attr_temp1_auto_temp_crit.dev_attr.attr, | ||
1046 | &sensor_dev_attr_temp2_auto_temp_crit.dev_attr.attr, | ||
1047 | &sensor_dev_attr_temp3_auto_temp_crit.dev_attr.attr, | ||
1048 | |||
1060 | &dev_attr_vrm.attr, | 1049 | &dev_attr_vrm.attr, |
1061 | &dev_attr_cpu0_vid.attr, | 1050 | &dev_attr_cpu0_vid.attr, |
1062 | &dev_attr_alarms.attr, | 1051 | &dev_attr_alarms.attr, |
1063 | &dev_attr_pwm1_auto_channels.attr, | ||
1064 | &dev_attr_pwm2_auto_channels.attr, | ||
1065 | &dev_attr_pwm3_auto_channels.attr, | ||
1066 | &dev_attr_pwm1_auto_pwm_min.attr, | ||
1067 | &dev_attr_pwm2_auto_pwm_min.attr, | ||
1068 | &dev_attr_pwm3_auto_pwm_min.attr, | ||
1069 | &dev_attr_pwm1_auto_pwm_minctl.attr, | ||
1070 | &dev_attr_pwm2_auto_pwm_minctl.attr, | ||
1071 | &dev_attr_pwm3_auto_pwm_minctl.attr, | ||
1072 | &dev_attr_pwm1_auto_pwm_freq.attr, | ||
1073 | &dev_attr_pwm2_auto_pwm_freq.attr, | ||
1074 | &dev_attr_pwm3_auto_pwm_freq.attr, | ||
1075 | &dev_attr_temp1_auto_temp_off.attr, | ||
1076 | &dev_attr_temp2_auto_temp_off.attr, | ||
1077 | &dev_attr_temp3_auto_temp_off.attr, | ||
1078 | &dev_attr_temp1_auto_temp_min.attr, | ||
1079 | &dev_attr_temp2_auto_temp_min.attr, | ||
1080 | &dev_attr_temp3_auto_temp_min.attr, | ||
1081 | &dev_attr_temp1_auto_temp_max.attr, | ||
1082 | &dev_attr_temp2_auto_temp_max.attr, | ||
1083 | &dev_attr_temp3_auto_temp_max.attr, | ||
1084 | &dev_attr_temp1_auto_temp_crit.attr, | ||
1085 | &dev_attr_temp2_auto_temp_crit.attr, | ||
1086 | &dev_attr_temp3_auto_temp_crit.attr, | ||
1087 | |||
1088 | NULL | 1052 | NULL |
1089 | }; | 1053 | }; |
1090 | 1054 | ||
@@ -1092,16 +1056,36 @@ static const struct attribute_group lm85_group = { | |||
1092 | .attrs = lm85_attributes, | 1056 | .attrs = lm85_attributes, |
1093 | }; | 1057 | }; |
1094 | 1058 | ||
1095 | static struct attribute *lm85_attributes_opt[] = { | 1059 | static struct attribute *lm85_attributes_in4[] = { |
1096 | &dev_attr_in4_input.attr, | 1060 | &sensor_dev_attr_in4_input.dev_attr.attr, |
1097 | &dev_attr_in4_min.attr, | 1061 | &sensor_dev_attr_in4_min.dev_attr.attr, |
1098 | &dev_attr_in4_max.attr, | 1062 | &sensor_dev_attr_in4_max.dev_attr.attr, |
1063 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1064 | NULL | ||
1065 | }; | ||
1066 | |||
1067 | static const struct attribute_group lm85_group_in4 = { | ||
1068 | .attrs = lm85_attributes_in4, | ||
1069 | }; | ||
1099 | 1070 | ||
1071 | static struct attribute *lm85_attributes_in567[] = { | ||
1072 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
1073 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
1074 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
1075 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
1076 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
1077 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
1078 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
1079 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
1080 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
1081 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1082 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1083 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1100 | NULL | 1084 | NULL |
1101 | }; | 1085 | }; |
1102 | 1086 | ||
1103 | static const struct attribute_group lm85_group_opt = { | 1087 | static const struct attribute_group lm85_group_in567 = { |
1104 | .attrs = lm85_attributes_opt, | 1088 | .attrs = lm85_attributes_in567, |
1105 | }; | 1089 | }; |
1106 | 1090 | ||
1107 | static int lm85_detect(struct i2c_adapter *adapter, int address, | 1091 | static int lm85_detect(struct i2c_adapter *adapter, int address, |
@@ -1249,17 +1233,19 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1249 | as a sixth digital VID input rather than an analog input. */ | 1233 | as a sixth digital VID input rather than an analog input. */ |
1250 | data->vid = lm85_read_value(new_client, LM85_REG_VID); | 1234 | data->vid = lm85_read_value(new_client, LM85_REG_VID); |
1251 | if (!(kind == adt7463 && (data->vid & 0x80))) | 1235 | if (!(kind == adt7463 && (data->vid & 0x80))) |
1252 | if ((err = device_create_file(&new_client->dev, | 1236 | if ((err = sysfs_create_group(&new_client->dev.kobj, |
1253 | &dev_attr_in4_input)) | 1237 | &lm85_group_in4))) |
1254 | || (err = device_create_file(&new_client->dev, | ||
1255 | &dev_attr_in4_min)) | ||
1256 | || (err = device_create_file(&new_client->dev, | ||
1257 | &dev_attr_in4_max))) | ||
1258 | goto ERROR3; | 1238 | goto ERROR3; |
1259 | 1239 | ||
1260 | data->class_dev = hwmon_device_register(&new_client->dev); | 1240 | /* The EMC6D100 has 3 additional voltage inputs */ |
1261 | if (IS_ERR(data->class_dev)) { | 1241 | if (kind == emc6d100) |
1262 | err = PTR_ERR(data->class_dev); | 1242 | if ((err = sysfs_create_group(&new_client->dev.kobj, |
1243 | &lm85_group_in567))) | ||
1244 | goto ERROR3; | ||
1245 | |||
1246 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
1247 | if (IS_ERR(data->hwmon_dev)) { | ||
1248 | err = PTR_ERR(data->hwmon_dev); | ||
1263 | goto ERROR3; | 1249 | goto ERROR3; |
1264 | } | 1250 | } |
1265 | 1251 | ||
@@ -1268,7 +1254,9 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1268 | /* Error out and cleanup code */ | 1254 | /* Error out and cleanup code */ |
1269 | ERROR3: | 1255 | ERROR3: |
1270 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group); | 1256 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group); |
1271 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_opt); | 1257 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in4); |
1258 | if (kind == emc6d100) | ||
1259 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in567); | ||
1272 | ERROR2: | 1260 | ERROR2: |
1273 | i2c_detach_client(new_client); | 1261 | i2c_detach_client(new_client); |
1274 | ERROR1: | 1262 | ERROR1: |
@@ -1280,9 +1268,11 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1280 | static int lm85_detach_client(struct i2c_client *client) | 1268 | static int lm85_detach_client(struct i2c_client *client) |
1281 | { | 1269 | { |
1282 | struct lm85_data *data = i2c_get_clientdata(client); | 1270 | struct lm85_data *data = i2c_get_clientdata(client); |
1283 | hwmon_device_unregister(data->class_dev); | 1271 | hwmon_device_unregister(data->hwmon_dev); |
1284 | sysfs_remove_group(&client->dev.kobj, &lm85_group); | 1272 | sysfs_remove_group(&client->dev.kobj, &lm85_group); |
1285 | sysfs_remove_group(&client->dev.kobj, &lm85_group_opt); | 1273 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); |
1274 | if (data->type == emc6d100) | ||
1275 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); | ||
1286 | i2c_detach_client(client); | 1276 | i2c_detach_client(client); |
1287 | kfree(data); | 1277 | kfree(data); |
1288 | return 0; | 1278 | return 0; |
@@ -1405,6 +1395,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1405 | 1395 | ||
1406 | /* Have to read extended bits first to "freeze" the | 1396 | /* Have to read extended bits first to "freeze" the |
1407 | * more significant bits that are read later. | 1397 | * more significant bits that are read later. |
1398 | * There are 2 additional resolution bits per channel and we | ||
1399 | * have room for 4, so we shift them to the left. | ||
1408 | */ | 1400 | */ |
1409 | if ( (data->type == adm1027) || (data->type == adt7463) ) { | 1401 | if ( (data->type == adm1027) || (data->type == adt7463) ) { |
1410 | int ext1 = lm85_read_value(client, | 1402 | int ext1 = lm85_read_value(client, |
@@ -1414,18 +1406,12 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1414 | int val = (ext1 << 8) + ext2; | 1406 | int val = (ext1 << 8) + ext2; |
1415 | 1407 | ||
1416 | for(i = 0; i <= 4; i++) | 1408 | for(i = 0; i <= 4; i++) |
1417 | data->in_ext[i] = (val>>(i * 2))&0x03; | 1409 | data->in_ext[i] = ((val>>(i * 2))&0x03) << 2; |
1418 | 1410 | ||
1419 | for(i = 0; i <= 2; i++) | 1411 | for(i = 0; i <= 2; i++) |
1420 | data->temp_ext[i] = (val>>((i + 5) * 2))&0x03; | 1412 | data->temp_ext[i] = (val>>((i + 4) * 2))&0x0c; |
1421 | } | 1413 | } |
1422 | 1414 | ||
1423 | /* adc_scale is 2^(number of LSBs). There are 4 extra bits in | ||
1424 | the emc6d102 and 2 in the adt7463 and adm1027. In all | ||
1425 | other chips ext is always 0 and the value of scale is | ||
1426 | irrelevant. So it is left in 4*/ | ||
1427 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; | ||
1428 | |||
1429 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1415 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1430 | 1416 | ||
1431 | for (i = 0; i <= 3; ++i) { | 1417 | for (i = 0; i <= 3; ++i) { |
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 988ae1c4aada..28cdff0c556b 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/jiffies.h> | 58 | #include <linux/jiffies.h> |
59 | #include <linux/i2c.h> | 59 | #include <linux/i2c.h> |
60 | #include <linux/hwmon.h> | 60 | #include <linux/hwmon.h> |
61 | #include <linux/hwmon-sysfs.h> | ||
61 | #include <linux/hwmon-vid.h> | 62 | #include <linux/hwmon-vid.h> |
62 | #include <linux/err.h> | 63 | #include <linux/err.h> |
63 | #include <linux/mutex.h> | 64 | #include <linux/mutex.h> |
@@ -129,7 +130,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; | |||
129 | (((val) < 0 ? (val)-500 : (val)+500) / 1000)) | 130 | (((val) < 0 ? (val)-500 : (val)+500) / 1000)) |
130 | 131 | ||
131 | #define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \ | 132 | #define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \ |
132 | 1350000 + (reg)*(div) / 2) / ((reg)*(div)) | 133 | (1350000 + (reg)*(div) / 2) / ((reg)*(div))) |
133 | #define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \ | 134 | #define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \ |
134 | (1350000 + (val)*(div) / 2) / ((val)*(div))) | 135 | (1350000 + (val)*(div) / 2) / ((val)*(div))) |
135 | 136 | ||
@@ -145,7 +146,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; | |||
145 | #define CHAN_NO_FAN(nr) (1 << (nr)) | 146 | #define CHAN_NO_FAN(nr) (1 << (nr)) |
146 | #define CHAN_TEMP3 (1 << 2) | 147 | #define CHAN_TEMP3 (1 << 2) |
147 | #define CHAN_VCC_5V (1 << 3) | 148 | #define CHAN_VCC_5V (1 << 3) |
148 | #define CHAN_NO_VID (1 << 8) | 149 | #define CHAN_NO_VID (1 << 7) |
149 | 150 | ||
150 | /* | 151 | /* |
151 | * Functions declaration | 152 | * Functions declaration |
@@ -176,7 +177,7 @@ static struct i2c_driver lm87_driver = { | |||
176 | 177 | ||
177 | struct lm87_data { | 178 | struct lm87_data { |
178 | struct i2c_client client; | 179 | struct i2c_client client; |
179 | struct class_device *class_dev; | 180 | struct device *hwmon_dev; |
180 | struct mutex update_lock; | 181 | struct mutex update_lock; |
181 | char valid; /* zero until following fields are valid */ | 182 | char valid; /* zero until following fields are valid */ |
182 | unsigned long last_updated; /* In jiffies */ | 183 | unsigned long last_updated; /* In jiffies */ |
@@ -500,7 +501,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
500 | 501 | ||
501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 502 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
502 | { | 503 | { |
503 | struct lm87_data *data = lm87_update_device(dev); | 504 | struct lm87_data *data = dev_get_drvdata(dev); |
504 | return sprintf(buf, "%d\n", data->vrm); | 505 | return sprintf(buf, "%d\n", data->vrm); |
505 | } | 506 | } |
506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 507 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -531,6 +532,29 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const | |||
531 | } | 532 | } |
532 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); | 533 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); |
533 | 534 | ||
535 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
536 | char *buf) | ||
537 | { | ||
538 | struct lm87_data *data = lm87_update_device(dev); | ||
539 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
540 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
541 | } | ||
542 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
543 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
544 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
545 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
546 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
547 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
548 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
549 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
550 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
551 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
552 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
553 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
554 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
555 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 14); | ||
556 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); | ||
557 | |||
534 | /* | 558 | /* |
535 | * Real code | 559 | * Real code |
536 | */ | 560 | */ |
@@ -546,24 +570,31 @@ static struct attribute *lm87_attributes[] = { | |||
546 | &dev_attr_in1_input.attr, | 570 | &dev_attr_in1_input.attr, |
547 | &dev_attr_in1_min.attr, | 571 | &dev_attr_in1_min.attr, |
548 | &dev_attr_in1_max.attr, | 572 | &dev_attr_in1_max.attr, |
573 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
549 | &dev_attr_in2_input.attr, | 574 | &dev_attr_in2_input.attr, |
550 | &dev_attr_in2_min.attr, | 575 | &dev_attr_in2_min.attr, |
551 | &dev_attr_in2_max.attr, | 576 | &dev_attr_in2_max.attr, |
577 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
552 | &dev_attr_in3_input.attr, | 578 | &dev_attr_in3_input.attr, |
553 | &dev_attr_in3_min.attr, | 579 | &dev_attr_in3_min.attr, |
554 | &dev_attr_in3_max.attr, | 580 | &dev_attr_in3_max.attr, |
581 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
555 | &dev_attr_in4_input.attr, | 582 | &dev_attr_in4_input.attr, |
556 | &dev_attr_in4_min.attr, | 583 | &dev_attr_in4_min.attr, |
557 | &dev_attr_in4_max.attr, | 584 | &dev_attr_in4_max.attr, |
585 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
558 | 586 | ||
559 | &dev_attr_temp1_input.attr, | 587 | &dev_attr_temp1_input.attr, |
560 | &dev_attr_temp1_max.attr, | 588 | &dev_attr_temp1_max.attr, |
561 | &dev_attr_temp1_min.attr, | 589 | &dev_attr_temp1_min.attr, |
562 | &dev_attr_temp1_crit.attr, | 590 | &dev_attr_temp1_crit.attr, |
591 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
563 | &dev_attr_temp2_input.attr, | 592 | &dev_attr_temp2_input.attr, |
564 | &dev_attr_temp2_max.attr, | 593 | &dev_attr_temp2_max.attr, |
565 | &dev_attr_temp2_min.attr, | 594 | &dev_attr_temp2_min.attr, |
566 | &dev_attr_temp2_crit.attr, | 595 | &dev_attr_temp2_crit.attr, |
596 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
597 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
567 | 598 | ||
568 | &dev_attr_alarms.attr, | 599 | &dev_attr_alarms.attr, |
569 | &dev_attr_aout_output.attr, | 600 | &dev_attr_aout_output.attr, |
@@ -579,30 +610,38 @@ static struct attribute *lm87_attributes_opt[] = { | |||
579 | &dev_attr_in6_input.attr, | 610 | &dev_attr_in6_input.attr, |
580 | &dev_attr_in6_min.attr, | 611 | &dev_attr_in6_min.attr, |
581 | &dev_attr_in6_max.attr, | 612 | &dev_attr_in6_max.attr, |
613 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
582 | 614 | ||
583 | &dev_attr_fan1_input.attr, | 615 | &dev_attr_fan1_input.attr, |
584 | &dev_attr_fan1_min.attr, | 616 | &dev_attr_fan1_min.attr, |
585 | &dev_attr_fan1_div.attr, | 617 | &dev_attr_fan1_div.attr, |
618 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
586 | 619 | ||
587 | &dev_attr_in7_input.attr, | 620 | &dev_attr_in7_input.attr, |
588 | &dev_attr_in7_min.attr, | 621 | &dev_attr_in7_min.attr, |
589 | &dev_attr_in7_max.attr, | 622 | &dev_attr_in7_max.attr, |
623 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
590 | 624 | ||
591 | &dev_attr_fan2_input.attr, | 625 | &dev_attr_fan2_input.attr, |
592 | &dev_attr_fan2_min.attr, | 626 | &dev_attr_fan2_min.attr, |
593 | &dev_attr_fan2_div.attr, | 627 | &dev_attr_fan2_div.attr, |
628 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
594 | 629 | ||
595 | &dev_attr_temp3_input.attr, | 630 | &dev_attr_temp3_input.attr, |
596 | &dev_attr_temp3_max.attr, | 631 | &dev_attr_temp3_max.attr, |
597 | &dev_attr_temp3_min.attr, | 632 | &dev_attr_temp3_min.attr, |
598 | &dev_attr_temp3_crit.attr, | 633 | &dev_attr_temp3_crit.attr, |
634 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
635 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
599 | 636 | ||
600 | &dev_attr_in0_input.attr, | 637 | &dev_attr_in0_input.attr, |
601 | &dev_attr_in0_min.attr, | 638 | &dev_attr_in0_min.attr, |
602 | &dev_attr_in0_max.attr, | 639 | &dev_attr_in0_max.attr, |
640 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
603 | &dev_attr_in5_input.attr, | 641 | &dev_attr_in5_input.attr, |
604 | &dev_attr_in5_min.attr, | 642 | &dev_attr_in5_min.attr, |
605 | &dev_attr_in5_max.attr, | 643 | &dev_attr_in5_max.attr, |
644 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
606 | 645 | ||
607 | &dev_attr_cpu0_vid.attr, | 646 | &dev_attr_cpu0_vid.attr, |
608 | &dev_attr_vrm.attr, | 647 | &dev_attr_vrm.attr, |
@@ -690,7 +729,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
690 | || (err = device_create_file(&new_client->dev, | 729 | || (err = device_create_file(&new_client->dev, |
691 | &dev_attr_in6_min)) | 730 | &dev_attr_in6_min)) |
692 | || (err = device_create_file(&new_client->dev, | 731 | || (err = device_create_file(&new_client->dev, |
693 | &dev_attr_in6_max))) | 732 | &dev_attr_in6_max)) |
733 | || (err = device_create_file(&new_client->dev, | ||
734 | &sensor_dev_attr_in6_alarm.dev_attr))) | ||
694 | goto exit_remove; | 735 | goto exit_remove; |
695 | } else { | 736 | } else { |
696 | if ((err = device_create_file(&new_client->dev, | 737 | if ((err = device_create_file(&new_client->dev, |
@@ -698,7 +739,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
698 | || (err = device_create_file(&new_client->dev, | 739 | || (err = device_create_file(&new_client->dev, |
699 | &dev_attr_fan1_min)) | 740 | &dev_attr_fan1_min)) |
700 | || (err = device_create_file(&new_client->dev, | 741 | || (err = device_create_file(&new_client->dev, |
701 | &dev_attr_fan1_div))) | 742 | &dev_attr_fan1_div)) |
743 | || (err = device_create_file(&new_client->dev, | ||
744 | &sensor_dev_attr_fan1_alarm.dev_attr))) | ||
702 | goto exit_remove; | 745 | goto exit_remove; |
703 | } | 746 | } |
704 | 747 | ||
@@ -708,7 +751,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
708 | || (err = device_create_file(&new_client->dev, | 751 | || (err = device_create_file(&new_client->dev, |
709 | &dev_attr_in7_min)) | 752 | &dev_attr_in7_min)) |
710 | || (err = device_create_file(&new_client->dev, | 753 | || (err = device_create_file(&new_client->dev, |
711 | &dev_attr_in7_max))) | 754 | &dev_attr_in7_max)) |
755 | || (err = device_create_file(&new_client->dev, | ||
756 | &sensor_dev_attr_in7_alarm.dev_attr))) | ||
712 | goto exit_remove; | 757 | goto exit_remove; |
713 | } else { | 758 | } else { |
714 | if ((err = device_create_file(&new_client->dev, | 759 | if ((err = device_create_file(&new_client->dev, |
@@ -716,7 +761,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
716 | || (err = device_create_file(&new_client->dev, | 761 | || (err = device_create_file(&new_client->dev, |
717 | &dev_attr_fan2_min)) | 762 | &dev_attr_fan2_min)) |
718 | || (err = device_create_file(&new_client->dev, | 763 | || (err = device_create_file(&new_client->dev, |
719 | &dev_attr_fan2_div))) | 764 | &dev_attr_fan2_div)) |
765 | || (err = device_create_file(&new_client->dev, | ||
766 | &sensor_dev_attr_fan2_alarm.dev_attr))) | ||
720 | goto exit_remove; | 767 | goto exit_remove; |
721 | } | 768 | } |
722 | 769 | ||
@@ -728,7 +775,11 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
728 | || (err = device_create_file(&new_client->dev, | 775 | || (err = device_create_file(&new_client->dev, |
729 | &dev_attr_temp3_min)) | 776 | &dev_attr_temp3_min)) |
730 | || (err = device_create_file(&new_client->dev, | 777 | || (err = device_create_file(&new_client->dev, |
731 | &dev_attr_temp3_crit))) | 778 | &dev_attr_temp3_crit)) |
779 | || (err = device_create_file(&new_client->dev, | ||
780 | &sensor_dev_attr_temp3_alarm.dev_attr)) | ||
781 | || (err = device_create_file(&new_client->dev, | ||
782 | &sensor_dev_attr_temp3_fault.dev_attr))) | ||
732 | goto exit_remove; | 783 | goto exit_remove; |
733 | } else { | 784 | } else { |
734 | if ((err = device_create_file(&new_client->dev, | 785 | if ((err = device_create_file(&new_client->dev, |
@@ -738,11 +789,15 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
738 | || (err = device_create_file(&new_client->dev, | 789 | || (err = device_create_file(&new_client->dev, |
739 | &dev_attr_in0_max)) | 790 | &dev_attr_in0_max)) |
740 | || (err = device_create_file(&new_client->dev, | 791 | || (err = device_create_file(&new_client->dev, |
792 | &sensor_dev_attr_in0_alarm.dev_attr)) | ||
793 | || (err = device_create_file(&new_client->dev, | ||
741 | &dev_attr_in5_input)) | 794 | &dev_attr_in5_input)) |
742 | || (err = device_create_file(&new_client->dev, | 795 | || (err = device_create_file(&new_client->dev, |
743 | &dev_attr_in5_min)) | 796 | &dev_attr_in5_min)) |
744 | || (err = device_create_file(&new_client->dev, | 797 | || (err = device_create_file(&new_client->dev, |
745 | &dev_attr_in5_max))) | 798 | &dev_attr_in5_max)) |
799 | || (err = device_create_file(&new_client->dev, | ||
800 | &sensor_dev_attr_in5_alarm.dev_attr))) | ||
746 | goto exit_remove; | 801 | goto exit_remove; |
747 | } | 802 | } |
748 | 803 | ||
@@ -755,9 +810,9 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
755 | goto exit_remove; | 810 | goto exit_remove; |
756 | } | 811 | } |
757 | 812 | ||
758 | data->class_dev = hwmon_device_register(&new_client->dev); | 813 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
759 | if (IS_ERR(data->class_dev)) { | 814 | if (IS_ERR(data->hwmon_dev)) { |
760 | err = PTR_ERR(data->class_dev); | 815 | err = PTR_ERR(data->hwmon_dev); |
761 | goto exit_remove; | 816 | goto exit_remove; |
762 | } | 817 | } |
763 | 818 | ||
@@ -816,7 +871,7 @@ static int lm87_detach_client(struct i2c_client *client) | |||
816 | struct lm87_data *data = i2c_get_clientdata(client); | 871 | struct lm87_data *data = i2c_get_clientdata(client); |
817 | int err; | 872 | int err; |
818 | 873 | ||
819 | hwmon_device_unregister(data->class_dev); | 874 | hwmon_device_unregister(data->hwmon_dev); |
820 | sysfs_remove_group(&client->dev.kobj, &lm87_group); | 875 | sysfs_remove_group(&client->dev.kobj, &lm87_group); |
821 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); | 876 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); |
822 | 877 | ||
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index af541d67245d..960df9fa75af 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 | 41 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 |
42 | * Note that there is no easy way to differentiate between the three | 42 | * Note that there is no easy way to differentiate between the three |
43 | * variants. The extra address and features of the MAX6659 are not | 43 | * variants. The extra address and features of the MAX6659 are not |
44 | * supported by this driver. | 44 | * supported by this driver. These chips lack the remote temperature |
45 | * offset feature. | ||
45 | * | 46 | * |
46 | * This driver also supports the MAX6680 and MAX6681, two other sensor | 47 | * This driver also supports the MAX6680 and MAX6681, two other sensor |
47 | * chips made by Maxim. These are quite similar to the other Maxim | 48 | * chips made by Maxim. These are quite similar to the other Maxim |
@@ -214,7 +215,7 @@ static struct i2c_driver lm90_driver = { | |||
214 | 215 | ||
215 | struct lm90_data { | 216 | struct lm90_data { |
216 | struct i2c_client client; | 217 | struct i2c_client client; |
217 | struct class_device *class_dev; | 218 | struct device *hwmon_dev; |
218 | struct mutex update_lock; | 219 | struct mutex update_lock; |
219 | char valid; /* zero until following fields are valid */ | 220 | char valid; /* zero until following fields are valid */ |
220 | unsigned long last_updated; /* in jiffies */ | 221 | unsigned long last_updated; /* in jiffies */ |
@@ -226,9 +227,10 @@ struct lm90_data { | |||
226 | 2: local high limit | 227 | 2: local high limit |
227 | 3: local critical limit | 228 | 3: local critical limit |
228 | 4: remote critical limit */ | 229 | 4: remote critical limit */ |
229 | s16 temp11[3]; /* 0: remote input | 230 | s16 temp11[4]; /* 0: remote input |
230 | 1: remote low limit | 231 | 1: remote low limit |
231 | 2: remote high limit */ | 232 | 2: remote high limit |
233 | 3: remote offset (except max6657) */ | ||
232 | u8 temp_hyst; | 234 | u8 temp_hyst; |
233 | u8 alarms; /* bitvector */ | 235 | u8 alarms; /* bitvector */ |
234 | }; | 236 | }; |
@@ -282,11 +284,13 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
282 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 284 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
283 | const char *buf, size_t count) | 285 | const char *buf, size_t count) |
284 | { | 286 | { |
285 | static const u8 reg[4] = { | 287 | static const u8 reg[6] = { |
286 | LM90_REG_W_REMOTE_LOWH, | 288 | LM90_REG_W_REMOTE_LOWH, |
287 | LM90_REG_W_REMOTE_LOWL, | 289 | LM90_REG_W_REMOTE_LOWL, |
288 | LM90_REG_W_REMOTE_HIGHH, | 290 | LM90_REG_W_REMOTE_HIGHH, |
289 | LM90_REG_W_REMOTE_HIGHL, | 291 | LM90_REG_W_REMOTE_HIGHL, |
292 | LM90_REG_W_REMOTE_OFFSH, | ||
293 | LM90_REG_W_REMOTE_OFFSL, | ||
290 | }; | 294 | }; |
291 | 295 | ||
292 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 296 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
@@ -367,6 +371,8 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, | |||
367 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | 371 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, |
368 | set_temphyst, 3); | 372 | set_temphyst, 3); |
369 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | 373 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); |
374 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, | ||
375 | set_temp11, 3); | ||
370 | 376 | ||
371 | /* Individual alarm files */ | 377 | /* Individual alarm files */ |
372 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 378 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
@@ -652,10 +658,15 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
652 | &dev_attr_pec))) | 658 | &dev_attr_pec))) |
653 | goto exit_remove_files; | 659 | goto exit_remove_files; |
654 | } | 660 | } |
661 | if (data->kind != max6657) { | ||
662 | if ((err = device_create_file(&new_client->dev, | ||
663 | &sensor_dev_attr_temp2_offset.dev_attr))) | ||
664 | goto exit_remove_files; | ||
665 | } | ||
655 | 666 | ||
656 | data->class_dev = hwmon_device_register(&new_client->dev); | 667 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
657 | if (IS_ERR(data->class_dev)) { | 668 | if (IS_ERR(data->hwmon_dev)) { |
658 | err = PTR_ERR(data->class_dev); | 669 | err = PTR_ERR(data->hwmon_dev); |
659 | goto exit_remove_files; | 670 | goto exit_remove_files; |
660 | } | 671 | } |
661 | 672 | ||
@@ -707,9 +718,12 @@ static int lm90_detach_client(struct i2c_client *client) | |||
707 | struct lm90_data *data = i2c_get_clientdata(client); | 718 | struct lm90_data *data = i2c_get_clientdata(client); |
708 | int err; | 719 | int err; |
709 | 720 | ||
710 | hwmon_device_unregister(data->class_dev); | 721 | hwmon_device_unregister(data->hwmon_dev); |
711 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | 722 | sysfs_remove_group(&client->dev.kobj, &lm90_group); |
712 | device_remove_file(&client->dev, &dev_attr_pec); | 723 | device_remove_file(&client->dev, &dev_attr_pec); |
724 | if (data->kind != max6657) | ||
725 | device_remove_file(&client->dev, | ||
726 | &sensor_dev_attr_temp2_offset.dev_attr); | ||
713 | 727 | ||
714 | if ((err = i2c_detach_client(client))) | 728 | if ((err = i2c_detach_client(client))) |
715 | return err; | 729 | return err; |
@@ -763,6 +777,13 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
763 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 | 777 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 |
764 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) | 778 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) |
765 | data->temp11[2] = (newh << 8) | l; | 779 | data->temp11[2] = (newh << 8) | l; |
780 | if (data->kind != max6657) { | ||
781 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, | ||
782 | &newh) == 0 | ||
783 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, | ||
784 | &l) == 0) | ||
785 | data->temp11[3] = (newh << 8) | l; | ||
786 | } | ||
766 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); | 787 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); |
767 | 788 | ||
768 | data->last_updated = jiffies; | 789 | data->last_updated = jiffies; |
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 30b536333f14..61d1bd1d5b6e 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -96,7 +96,7 @@ static struct i2c_driver lm92_driver; | |||
96 | /* Client data (each client gets its own) */ | 96 | /* Client data (each client gets its own) */ |
97 | struct lm92_data { | 97 | struct lm92_data { |
98 | struct i2c_client client; | 98 | struct i2c_client client; |
99 | struct class_device *class_dev; | 99 | struct device *hwmon_dev; |
100 | struct mutex update_lock; | 100 | struct mutex update_lock; |
101 | char valid; /* zero until following fields are valid */ | 101 | char valid; /* zero until following fields are valid */ |
102 | unsigned long last_updated; /* in jiffies */ | 102 | unsigned long last_updated; /* in jiffies */ |
@@ -379,9 +379,9 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | |||
379 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) | 379 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) |
380 | goto exit_detach; | 380 | goto exit_detach; |
381 | 381 | ||
382 | data->class_dev = hwmon_device_register(&new_client->dev); | 382 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
383 | if (IS_ERR(data->class_dev)) { | 383 | if (IS_ERR(data->hwmon_dev)) { |
384 | err = PTR_ERR(data->class_dev); | 384 | err = PTR_ERR(data->hwmon_dev); |
385 | goto exit_remove; | 385 | goto exit_remove; |
386 | } | 386 | } |
387 | 387 | ||
@@ -409,7 +409,7 @@ static int lm92_detach_client(struct i2c_client *client) | |||
409 | struct lm92_data *data = i2c_get_clientdata(client); | 409 | struct lm92_data *data = i2c_get_clientdata(client); |
410 | int err; | 410 | int err; |
411 | 411 | ||
412 | hwmon_device_unregister(data->class_dev); | 412 | hwmon_device_unregister(data->hwmon_dev); |
413 | sysfs_remove_group(&client->dev.kobj, &lm92_group); | 413 | sysfs_remove_group(&client->dev.kobj, &lm92_group); |
414 | 414 | ||
415 | if ((err = i2c_detach_client(client))) | 415 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index d84f8bf6f284..ea61946a4bf7 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
@@ -201,7 +201,7 @@ struct block1_t { | |||
201 | */ | 201 | */ |
202 | struct lm93_data { | 202 | struct lm93_data { |
203 | struct i2c_client client; | 203 | struct i2c_client client; |
204 | struct class_device *class_dev; | 204 | struct device *hwmon_dev; |
205 | 205 | ||
206 | struct mutex update_lock; | 206 | struct mutex update_lock; |
207 | unsigned long last_updated; /* In jiffies */ | 207 | unsigned long last_updated; /* In jiffies */ |
@@ -413,7 +413,7 @@ static int LM93_TEMP_FROM_REG(u8 reg) | |||
413 | 413 | ||
414 | /* TEMP: 1/1000 degrees C (-128C to +127C) | 414 | /* TEMP: 1/1000 degrees C (-128C to +127C) |
415 | REG: 1C/bit, two's complement */ | 415 | REG: 1C/bit, two's complement */ |
416 | static u8 LM93_TEMP_TO_REG(int temp) | 416 | static u8 LM93_TEMP_TO_REG(long temp) |
417 | { | 417 | { |
418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); | 418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); |
419 | ntemp += (ntemp<0 ? -500 : 500); | 419 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -1268,7 +1268,7 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, | |||
1268 | int nr = (to_sensor_dev_attr(attr))->index; | 1268 | int nr = (to_sensor_dev_attr(attr))->index; |
1269 | struct i2c_client *client = to_i2c_client(dev); | 1269 | struct i2c_client *client = to_i2c_client(dev); |
1270 | struct lm93_data *data = i2c_get_clientdata(client); | 1270 | struct lm93_data *data = i2c_get_clientdata(client); |
1271 | u32 val = simple_strtoul(buf, NULL, 10); | 1271 | long val = simple_strtol(buf, NULL, 10); |
1272 | 1272 | ||
1273 | mutex_lock(&data->update_lock); | 1273 | mutex_lock(&data->update_lock); |
1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); | 1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); |
@@ -1298,7 +1298,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, | |||
1298 | int nr = (to_sensor_dev_attr(attr))->index; | 1298 | int nr = (to_sensor_dev_attr(attr))->index; |
1299 | struct i2c_client *client = to_i2c_client(dev); | 1299 | struct i2c_client *client = to_i2c_client(dev); |
1300 | struct lm93_data *data = i2c_get_clientdata(client); | 1300 | struct lm93_data *data = i2c_get_clientdata(client); |
1301 | u32 val = simple_strtoul(buf, NULL, 10); | 1301 | long val = simple_strtol(buf, NULL, 10); |
1302 | 1302 | ||
1303 | mutex_lock(&data->update_lock); | 1303 | mutex_lock(&data->update_lock); |
1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); | 1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); |
@@ -1329,7 +1329,7 @@ static ssize_t store_temp_auto_base(struct device *dev, | |||
1329 | int nr = (to_sensor_dev_attr(attr))->index; | 1329 | int nr = (to_sensor_dev_attr(attr))->index; |
1330 | struct i2c_client *client = to_i2c_client(dev); | 1330 | struct i2c_client *client = to_i2c_client(dev); |
1331 | struct lm93_data *data = i2c_get_clientdata(client); | 1331 | struct lm93_data *data = i2c_get_clientdata(client); |
1332 | u32 val = simple_strtoul(buf, NULL, 10); | 1332 | long val = simple_strtol(buf, NULL, 10); |
1333 | 1333 | ||
1334 | mutex_lock(&data->update_lock); | 1334 | mutex_lock(&data->update_lock); |
1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); | 1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); |
@@ -1360,7 +1360,7 @@ static ssize_t store_temp_auto_boost(struct device *dev, | |||
1360 | int nr = (to_sensor_dev_attr(attr))->index; | 1360 | int nr = (to_sensor_dev_attr(attr))->index; |
1361 | struct i2c_client *client = to_i2c_client(dev); | 1361 | struct i2c_client *client = to_i2c_client(dev); |
1362 | struct lm93_data *data = i2c_get_clientdata(client); | 1362 | struct lm93_data *data = i2c_get_clientdata(client); |
1363 | u32 val = simple_strtoul(buf, NULL, 10); | 1363 | long val = simple_strtol(buf, NULL, 10); |
1364 | 1364 | ||
1365 | mutex_lock(&data->update_lock); | 1365 | mutex_lock(&data->update_lock); |
1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); | 1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); |
@@ -2078,8 +2078,8 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | |||
2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); | 2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); |
2079 | } | 2079 | } |
2080 | 2080 | ||
2081 | static SENSOR_DEVICE_ATTR(vid1, S_IRUGO, show_vid, NULL, 0); | 2081 | static SENSOR_DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL, 0); |
2082 | static SENSOR_DEVICE_ATTR(vid2, S_IRUGO, show_vid, NULL, 1); | 2082 | static SENSOR_DEVICE_ATTR(cpu1_vid, S_IRUGO, show_vid, NULL, 1); |
2083 | 2083 | ||
2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, | 2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, |
2085 | char *buf) | 2085 | char *buf) |
@@ -2431,8 +2431,8 @@ static struct attribute *lm93_attrs[] = { | |||
2431 | &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, | 2431 | &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, |
2432 | &dev_attr_pwm_auto_prochot_ramp.attr, | 2432 | &dev_attr_pwm_auto_prochot_ramp.attr, |
2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, | 2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, |
2434 | &sensor_dev_attr_vid1.dev_attr.attr, | 2434 | &sensor_dev_attr_cpu0_vid.dev_attr.attr, |
2435 | &sensor_dev_attr_vid2.dev_attr.attr, | 2435 | &sensor_dev_attr_cpu1_vid.dev_attr.attr, |
2436 | &sensor_dev_attr_prochot1.dev_attr.attr, | 2436 | &sensor_dev_attr_prochot1.dev_attr.attr, |
2437 | &sensor_dev_attr_prochot2.dev_attr.attr, | 2437 | &sensor_dev_attr_prochot2.dev_attr.attr, |
2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, | 2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, |
@@ -2590,11 +2590,11 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) | |||
2590 | goto err_detach; | 2590 | goto err_detach; |
2591 | 2591 | ||
2592 | /* Register hwmon driver class */ | 2592 | /* Register hwmon driver class */ |
2593 | data->class_dev = hwmon_device_register(&client->dev); | 2593 | data->hwmon_dev = hwmon_device_register(&client->dev); |
2594 | if ( !IS_ERR(data->class_dev)) | 2594 | if ( !IS_ERR(data->hwmon_dev)) |
2595 | return 0; | 2595 | return 0; |
2596 | 2596 | ||
2597 | err = PTR_ERR(data->class_dev); | 2597 | err = PTR_ERR(data->hwmon_dev); |
2598 | dev_err(&client->dev, "error registering hwmon device.\n"); | 2598 | dev_err(&client->dev, "error registering hwmon device.\n"); |
2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | 2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); |
2600 | err_detach: | 2600 | err_detach: |
@@ -2619,7 +2619,7 @@ static int lm93_detach_client(struct i2c_client *client) | |||
2619 | struct lm93_data *data = i2c_get_clientdata(client); | 2619 | struct lm93_data *data = i2c_get_clientdata(client); |
2620 | int err = 0; | 2620 | int err = 0; |
2621 | 2621 | ||
2622 | hwmon_device_unregister(data->class_dev); | 2622 | hwmon_device_unregister(data->hwmon_dev); |
2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | 2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); |
2624 | 2624 | ||
2625 | err = i2c_detach_client(client); | 2625 | err = i2c_detach_client(client); |
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 2f58f651f03a..38a44c3d6cee 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -105,7 +105,7 @@ static struct i2c_driver max1619_driver = { | |||
105 | 105 | ||
106 | struct max1619_data { | 106 | struct max1619_data { |
107 | struct i2c_client client; | 107 | struct i2c_client client; |
108 | struct class_device *class_dev; | 108 | struct device *hwmon_dev; |
109 | struct mutex update_lock; | 109 | struct mutex update_lock; |
110 | char valid; /* zero until following fields are valid */ | 110 | char valid; /* zero until following fields are valid */ |
111 | unsigned long last_updated; /* in jiffies */ | 111 | unsigned long last_updated; /* in jiffies */ |
@@ -293,9 +293,9 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
293 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) | 293 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) |
294 | goto exit_detach; | 294 | goto exit_detach; |
295 | 295 | ||
296 | data->class_dev = hwmon_device_register(&new_client->dev); | 296 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
297 | if (IS_ERR(data->class_dev)) { | 297 | if (IS_ERR(data->hwmon_dev)) { |
298 | err = PTR_ERR(data->class_dev); | 298 | err = PTR_ERR(data->hwmon_dev); |
299 | goto exit_remove_files; | 299 | goto exit_remove_files; |
300 | } | 300 | } |
301 | 301 | ||
@@ -331,7 +331,7 @@ static int max1619_detach_client(struct i2c_client *client) | |||
331 | struct max1619_data *data = i2c_get_clientdata(client); | 331 | struct max1619_data *data = i2c_get_clientdata(client); |
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | hwmon_device_unregister(data->class_dev); | 334 | hwmon_device_unregister(data->hwmon_dev); |
335 | sysfs_remove_group(&client->dev.kobj, &max1619_group); | 335 | sysfs_remove_group(&client->dev.kobj, &max1619_group); |
336 | 336 | ||
337 | if ((err = i2c_detach_client(client))) | 337 | if ((err = i2c_detach_client(client))) |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 8415664f33c2..755570c1f4eb 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -128,7 +128,7 @@ static struct i2c_driver max6650_driver = { | |||
128 | struct max6650_data | 128 | struct max6650_data |
129 | { | 129 | { |
130 | struct i2c_client client; | 130 | struct i2c_client client; |
131 | struct class_device *class_dev; | 131 | struct device *hwmon_dev; |
132 | struct mutex update_lock; | 132 | struct mutex update_lock; |
133 | char valid; /* zero until following fields are valid */ | 133 | char valid; /* zero until following fields are valid */ |
134 | unsigned long last_updated; /* in jiffies */ | 134 | unsigned long last_updated; /* in jiffies */ |
@@ -523,11 +523,11 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) | |||
523 | if (err) | 523 | if (err) |
524 | goto err_detach; | 524 | goto err_detach; |
525 | 525 | ||
526 | data->class_dev = hwmon_device_register(&client->dev); | 526 | data->hwmon_dev = hwmon_device_register(&client->dev); |
527 | if (!IS_ERR(data->class_dev)) | 527 | if (!IS_ERR(data->hwmon_dev)) |
528 | return 0; | 528 | return 0; |
529 | 529 | ||
530 | err = PTR_ERR(data->class_dev); | 530 | err = PTR_ERR(data->hwmon_dev); |
531 | dev_err(&client->dev, "error registering hwmon device.\n"); | 531 | dev_err(&client->dev, "error registering hwmon device.\n"); |
532 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 532 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
533 | err_detach: | 533 | err_detach: |
@@ -543,7 +543,7 @@ static int max6650_detach_client(struct i2c_client *client) | |||
543 | int err; | 543 | int err; |
544 | 544 | ||
545 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 545 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
546 | hwmon_device_unregister(data->class_dev); | 546 | hwmon_device_unregister(data->hwmon_dev); |
547 | err = i2c_detach_client(client); | 547 | err = i2c_detach_client(client); |
548 | if (!err) | 548 | if (!err) |
549 | kfree(data); | 549 | kfree(data); |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index f57c75d59a5b..9d660133d517 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -180,7 +180,7 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
180 | 180 | ||
181 | struct pc87360_data { | 181 | struct pc87360_data { |
182 | const char *name; | 182 | const char *name; |
183 | struct class_device *class_dev; | 183 | struct device *hwmon_dev; |
184 | struct mutex lock; | 184 | struct mutex lock; |
185 | struct mutex update_lock; | 185 | struct mutex update_lock; |
186 | char valid; /* !=0 if following fields are valid */ | 186 | char valid; /* !=0 if following fields are valid */ |
@@ -500,7 +500,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
500 | 500 | ||
501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 501 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
502 | { | 502 | { |
503 | struct pc87360_data *data = pc87360_update_device(dev); | 503 | struct pc87360_data *data = dev_get_drvdata(dev); |
504 | return sprintf(buf, "%u\n", data->vrm); | 504 | return sprintf(buf, "%u\n", data->vrm); |
505 | } | 505 | } |
506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -1054,9 +1054,9 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
1054 | if ((err = device_create_file(dev, &dev_attr_name))) | 1054 | if ((err = device_create_file(dev, &dev_attr_name))) |
1055 | goto ERROR3; | 1055 | goto ERROR3; |
1056 | 1056 | ||
1057 | data->class_dev = hwmon_device_register(dev); | 1057 | data->hwmon_dev = hwmon_device_register(dev); |
1058 | if (IS_ERR(data->class_dev)) { | 1058 | if (IS_ERR(data->hwmon_dev)) { |
1059 | err = PTR_ERR(data->class_dev); | 1059 | err = PTR_ERR(data->hwmon_dev); |
1060 | goto ERROR3; | 1060 | goto ERROR3; |
1061 | } | 1061 | } |
1062 | return 0; | 1062 | return 0; |
@@ -1083,7 +1083,7 @@ static int __devexit pc87360_remove(struct platform_device *pdev) | |||
1083 | struct pc87360_data *data = platform_get_drvdata(pdev); | 1083 | struct pc87360_data *data = platform_get_drvdata(pdev); |
1084 | int i; | 1084 | int i; |
1085 | 1085 | ||
1086 | hwmon_device_unregister(data->class_dev); | 1086 | hwmon_device_unregister(data->hwmon_dev); |
1087 | 1087 | ||
1088 | device_remove_file(&pdev->dev, &dev_attr_name); | 1088 | device_remove_file(&pdev->dev, &dev_attr_name); |
1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); | 1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); |
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 2915bc4ad0d5..d40509ad6ae6 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -42,7 +42,7 @@ static struct platform_device *pdev; | |||
42 | device is using banked registers) and the register cache (needed to keep | 42 | device is using banked registers) and the register cache (needed to keep |
43 | the data in the registers and the cache in sync at any time). */ | 43 | the data in the registers and the cache in sync at any time). */ |
44 | struct pc87427_data { | 44 | struct pc87427_data { |
45 | struct class_device *class_dev; | 45 | struct device *hwmon_dev; |
46 | struct mutex lock; | 46 | struct mutex lock; |
47 | int address[2]; | 47 | int address[2]; |
48 | const char *name; | 48 | const char *name; |
@@ -454,9 +454,9 @@ static int __devinit pc87427_probe(struct platform_device *pdev) | |||
454 | goto exit_remove_files; | 454 | goto exit_remove_files; |
455 | } | 455 | } |
456 | 456 | ||
457 | data->class_dev = hwmon_device_register(&pdev->dev); | 457 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
458 | if (IS_ERR(data->class_dev)) { | 458 | if (IS_ERR(data->hwmon_dev)) { |
459 | err = PTR_ERR(data->class_dev); | 459 | err = PTR_ERR(data->hwmon_dev); |
460 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | 460 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); |
461 | goto exit_remove_files; | 461 | goto exit_remove_files; |
462 | } | 462 | } |
@@ -484,7 +484,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
484 | struct resource *res; | 484 | struct resource *res; |
485 | int i; | 485 | int i; |
486 | 486 | ||
487 | hwmon_device_unregister(data->class_dev); | 487 | hwmon_device_unregister(data->hwmon_dev); |
488 | device_remove_file(&pdev->dev, &dev_attr_name); | 488 | device_remove_file(&pdev->dev, &dev_attr_name); |
489 | for (i = 0; i < 8; i++) { | 489 | for (i = 0; i < 8; i++) { |
490 | if (!(data->fan_enabled & (1 << i))) | 490 | if (!(data->fan_enabled & (1 << i))) |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 92956eb3f3c1..860b71ccbb86 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -163,7 +163,7 @@ static inline u8 DIV_TO_REG(int val) | |||
163 | struct sis5595_data { | 163 | struct sis5595_data { |
164 | unsigned short addr; | 164 | unsigned short addr; |
165 | const char *name; | 165 | const char *name; |
166 | struct class_device *class_dev; | 166 | struct device *hwmon_dev; |
167 | struct mutex lock; | 167 | struct mutex lock; |
168 | 168 | ||
169 | struct mutex update_lock; | 169 | struct mutex update_lock; |
@@ -517,7 +517,7 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
517 | platform_set_drvdata(pdev, data); | 517 | platform_set_drvdata(pdev, data); |
518 | 518 | ||
519 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ | 519 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ |
520 | pci_read_config_byte(s_bridge, PCI_REVISION_ID, &data->revision); | 520 | data->revision = s_bridge->revision; |
521 | /* 4 voltages, 1 temp */ | 521 | /* 4 voltages, 1 temp */ |
522 | data->maxins = 3; | 522 | data->maxins = 3; |
523 | if (data->revision >= REV2MIN) { | 523 | if (data->revision >= REV2MIN) { |
@@ -557,9 +557,9 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
557 | goto exit_remove_files; | 557 | goto exit_remove_files; |
558 | } | 558 | } |
559 | 559 | ||
560 | data->class_dev = hwmon_device_register(&pdev->dev); | 560 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
561 | if (IS_ERR(data->class_dev)) { | 561 | if (IS_ERR(data->hwmon_dev)) { |
562 | err = PTR_ERR(data->class_dev); | 562 | err = PTR_ERR(data->hwmon_dev); |
563 | goto exit_remove_files; | 563 | goto exit_remove_files; |
564 | } | 564 | } |
565 | 565 | ||
@@ -580,7 +580,7 @@ static int __devexit sis5595_remove(struct platform_device *pdev) | |||
580 | { | 580 | { |
581 | struct sis5595_data *data = platform_get_drvdata(pdev); | 581 | struct sis5595_data *data = platform_get_drvdata(pdev); |
582 | 582 | ||
583 | hwmon_device_unregister(data->class_dev); | 583 | hwmon_device_unregister(data->hwmon_dev); |
584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); | 584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); | 585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
586 | 586 | ||
@@ -739,11 +739,10 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, | |||
739 | int *i; | 739 | int *i; |
740 | 740 | ||
741 | for (i = blacklist; *i != 0; i++) { | 741 | for (i = blacklist; *i != 0; i++) { |
742 | struct pci_dev *dev; | 742 | struct pci_dev *d; |
743 | dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL); | 743 | if ((d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL))) { |
744 | if (dev) { | 744 | dev_err(&d->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); |
745 | dev_err(&dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); | 745 | pci_dev_put(d); |
746 | pci_dev_put(dev); | ||
747 | return -ENODEV; | 746 | return -ENODEV; |
748 | } | 747 | } |
749 | } | 748 | } |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 45266b30ce1d..0b57d2ea2cf7 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -94,7 +94,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; | |||
94 | struct smsc47b397_data { | 94 | struct smsc47b397_data { |
95 | unsigned short addr; | 95 | unsigned short addr; |
96 | const char *name; | 96 | const char *name; |
97 | struct class_device *class_dev; | 97 | struct device *hwmon_dev; |
98 | struct mutex lock; | 98 | struct mutex lock; |
99 | 99 | ||
100 | struct mutex update_lock; | 100 | struct mutex update_lock; |
@@ -222,7 +222,7 @@ static int __devexit smsc47b397_remove(struct platform_device *pdev) | |||
222 | struct smsc47b397_data *data = platform_get_drvdata(pdev); | 222 | struct smsc47b397_data *data = platform_get_drvdata(pdev); |
223 | struct resource *res; | 223 | struct resource *res; |
224 | 224 | ||
225 | hwmon_device_unregister(data->class_dev); | 225 | hwmon_device_unregister(data->hwmon_dev); |
226 | sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); | 226 | sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); |
227 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 227 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
228 | release_region(res->start, SMSC_EXTENT); | 228 | release_region(res->start, SMSC_EXTENT); |
@@ -272,9 +272,9 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) | |||
272 | if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) | 272 | if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) |
273 | goto error_free; | 273 | goto error_free; |
274 | 274 | ||
275 | data->class_dev = hwmon_device_register(dev); | 275 | data->hwmon_dev = hwmon_device_register(dev); |
276 | if (IS_ERR(data->class_dev)) { | 276 | if (IS_ERR(data->hwmon_dev)) { |
277 | err = PTR_ERR(data->class_dev); | 277 | err = PTR_ERR(data->hwmon_dev); |
278 | goto error_remove; | 278 | goto error_remove; |
279 | } | 279 | } |
280 | 280 | ||
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index d3181967f167..a10a380868e2 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -116,7 +116,7 @@ struct smsc47m1_data { | |||
116 | unsigned short addr; | 116 | unsigned short addr; |
117 | const char *name; | 117 | const char *name; |
118 | enum chips type; | 118 | enum chips type; |
119 | struct class_device *class_dev; | 119 | struct device *hwmon_dev; |
120 | 120 | ||
121 | struct mutex update_lock; | 121 | struct mutex update_lock; |
122 | unsigned long last_updated; /* In jiffies */ | 122 | unsigned long last_updated; /* In jiffies */ |
@@ -553,7 +553,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
553 | || (err = device_create_file(dev, | 553 | || (err = device_create_file(dev, |
554 | &sensor_dev_attr_fan3_div.dev_attr))) | 554 | &sensor_dev_attr_fan3_div.dev_attr))) |
555 | goto error_remove_files; | 555 | goto error_remove_files; |
556 | } else | 556 | } else if (data->type == smsc47m2) |
557 | dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); | 557 | dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); |
558 | 558 | ||
559 | if (pwm1) { | 559 | if (pwm1) { |
@@ -580,7 +580,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
580 | || (err = device_create_file(dev, | 580 | || (err = device_create_file(dev, |
581 | &sensor_dev_attr_pwm3_enable.dev_attr))) | 581 | &sensor_dev_attr_pwm3_enable.dev_attr))) |
582 | goto error_remove_files; | 582 | goto error_remove_files; |
583 | } else | 583 | } else if (data->type == smsc47m2) |
584 | dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); | 584 | dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); |
585 | 585 | ||
586 | if ((err = device_create_file(dev, &dev_attr_alarms))) | 586 | if ((err = device_create_file(dev, &dev_attr_alarms))) |
@@ -588,9 +588,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
588 | if ((err = device_create_file(dev, &dev_attr_name))) | 588 | if ((err = device_create_file(dev, &dev_attr_name))) |
589 | goto error_remove_files; | 589 | goto error_remove_files; |
590 | 590 | ||
591 | data->class_dev = hwmon_device_register(dev); | 591 | data->hwmon_dev = hwmon_device_register(dev); |
592 | if (IS_ERR(data->class_dev)) { | 592 | if (IS_ERR(data->hwmon_dev)) { |
593 | err = PTR_ERR(data->class_dev); | 593 | err = PTR_ERR(data->hwmon_dev); |
594 | goto error_remove_files; | 594 | goto error_remove_files; |
595 | } | 595 | } |
596 | 596 | ||
@@ -611,7 +611,7 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev) | |||
611 | struct smsc47m1_data *data = platform_get_drvdata(pdev); | 611 | struct smsc47m1_data *data = platform_get_drvdata(pdev); |
612 | struct resource *res; | 612 | struct resource *res; |
613 | 613 | ||
614 | hwmon_device_unregister(data->class_dev); | 614 | hwmon_device_unregister(data->hwmon_dev); |
615 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); | 615 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); |
616 | 616 | ||
617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index d3a3ba04cb0f..b87552652588 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c | |||
@@ -97,7 +97,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
97 | 97 | ||
98 | struct smsc47m192_data { | 98 | struct smsc47m192_data { |
99 | struct i2c_client client; | 99 | struct i2c_client client; |
100 | struct class_device *class_dev; | 100 | struct device *hwmon_dev; |
101 | struct mutex update_lock; | 101 | struct mutex update_lock; |
102 | char valid; /* !=0 if following fields are valid */ | 102 | char valid; /* !=0 if following fields are valid */ |
103 | unsigned long last_updated; /* In jiffies */ | 103 | unsigned long last_updated; /* In jiffies */ |
@@ -334,7 +334,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | |||
334 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, | 334 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, |
335 | char *buf) | 335 | char *buf) |
336 | { | 336 | { |
337 | struct smsc47m192_data *data = smsc47m192_update_device(dev); | 337 | struct smsc47m192_data *data = dev_get_drvdata(dev); |
338 | return sprintf(buf, "%d\n", data->vrm); | 338 | return sprintf(buf, "%d\n", data->vrm); |
339 | } | 339 | } |
340 | 340 | ||
@@ -553,9 +553,9 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
553 | goto exit_remove_files; | 553 | goto exit_remove_files; |
554 | } | 554 | } |
555 | 555 | ||
556 | data->class_dev = hwmon_device_register(&client->dev); | 556 | data->hwmon_dev = hwmon_device_register(&client->dev); |
557 | if (IS_ERR(data->class_dev)) { | 557 | if (IS_ERR(data->hwmon_dev)) { |
558 | err = PTR_ERR(data->class_dev); | 558 | err = PTR_ERR(data->hwmon_dev); |
559 | goto exit_remove_files; | 559 | goto exit_remove_files; |
560 | } | 560 | } |
561 | 561 | ||
@@ -577,7 +577,7 @@ static int smsc47m192_detach_client(struct i2c_client *client) | |||
577 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 577 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
578 | int err; | 578 | int err; |
579 | 579 | ||
580 | hwmon_device_unregister(data->class_dev); | 580 | hwmon_device_unregister(data->hwmon_dev); |
581 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); | 581 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); |
582 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); | 582 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); |
583 | 583 | ||
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 9395b52d9b99..04dd7699b3ac 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c | |||
@@ -46,6 +46,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " | |||
46 | #define THMC50_REG_COMPANY_ID 0x3E | 46 | #define THMC50_REG_COMPANY_ID 0x3E |
47 | #define THMC50_REG_DIE_CODE 0x3F | 47 | #define THMC50_REG_DIE_CODE 0x3F |
48 | #define THMC50_REG_ANALOG_OUT 0x19 | 48 | #define THMC50_REG_ANALOG_OUT 0x19 |
49 | /* | ||
50 | * The mirror status register cannot be used as | ||
51 | * reading it does not clear alarms. | ||
52 | */ | ||
53 | #define THMC50_REG_INTR 0x41 | ||
49 | 54 | ||
50 | const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; | 55 | const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
51 | const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; | 56 | const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
@@ -56,7 +61,7 @@ const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; | |||
56 | /* Each client has this additional data */ | 61 | /* Each client has this additional data */ |
57 | struct thmc50_data { | 62 | struct thmc50_data { |
58 | struct i2c_client client; | 63 | struct i2c_client client; |
59 | struct class_device *class_dev; | 64 | struct device *hwmon_dev; |
60 | 65 | ||
61 | struct mutex update_lock; | 66 | struct mutex update_lock; |
62 | enum chips type; | 67 | enum chips type; |
@@ -69,6 +74,7 @@ struct thmc50_data { | |||
69 | s8 temp_max[3]; | 74 | s8 temp_max[3]; |
70 | s8 temp_min[3]; | 75 | s8 temp_min[3]; |
71 | u8 analog_out; | 76 | u8 analog_out; |
77 | u8 alarms; | ||
72 | }; | 78 | }; |
73 | 79 | ||
74 | static int thmc50_attach_adapter(struct i2c_adapter *adapter); | 80 | static int thmc50_attach_adapter(struct i2c_adapter *adapter); |
@@ -180,6 +186,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
180 | return count; | 186 | return count; |
181 | } | 187 | } |
182 | 188 | ||
189 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
190 | char *buf) | ||
191 | { | ||
192 | int index = to_sensor_dev_attr(attr)->index; | ||
193 | struct thmc50_data *data = thmc50_update_device(dev); | ||
194 | |||
195 | return sprintf(buf, "%u\n", (data->alarms >> index) & 1); | ||
196 | } | ||
197 | |||
183 | #define temp_reg(offset) \ | 198 | #define temp_reg(offset) \ |
184 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ | 199 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ |
185 | NULL, offset - 1); \ | 200 | NULL, offset - 1); \ |
@@ -192,6 +207,12 @@ temp_reg(1); | |||
192 | temp_reg(2); | 207 | temp_reg(2); |
193 | temp_reg(3); | 208 | temp_reg(3); |
194 | 209 | ||
210 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
211 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
212 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
213 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 7); | ||
214 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2); | ||
215 | |||
195 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out, | 216 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out, |
196 | set_analog_out, 0); | 217 | set_analog_out, 0); |
197 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); | 218 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); |
@@ -200,9 +221,12 @@ static struct attribute *thmc50_attributes[] = { | |||
200 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 221 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
201 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 222 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
202 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 223 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
224 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
203 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 225 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
204 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 226 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
205 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 227 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
228 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
229 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
206 | &sensor_dev_attr_pwm1.dev_attr.attr, | 230 | &sensor_dev_attr_pwm1.dev_attr.attr, |
207 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 231 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
208 | NULL | 232 | NULL |
@@ -213,15 +237,17 @@ static const struct attribute_group thmc50_group = { | |||
213 | }; | 237 | }; |
214 | 238 | ||
215 | /* for ADM1022 3rd temperature mode */ | 239 | /* for ADM1022 3rd temperature mode */ |
216 | static struct attribute *adm1022_attributes[] = { | 240 | static struct attribute *temp3_attributes[] = { |
217 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 241 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
218 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 242 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
219 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 243 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
244 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
245 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
220 | NULL | 246 | NULL |
221 | }; | 247 | }; |
222 | 248 | ||
223 | static const struct attribute_group adm1022_group = { | 249 | static const struct attribute_group temp3_group = { |
224 | .attrs = adm1022_attributes, | 250 | .attrs = temp3_attributes, |
225 | }; | 251 | }; |
226 | 252 | ||
227 | static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | 253 | static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) |
@@ -233,7 +259,7 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
233 | struct thmc50_data *data; | 259 | struct thmc50_data *data; |
234 | struct device *dev; | 260 | struct device *dev; |
235 | int err = 0; | 261 | int err = 0; |
236 | const char *type_name = ""; | 262 | const char *type_name; |
237 | 263 | ||
238 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 264 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
239 | pr_debug("thmc50: detect failed, " | 265 | pr_debug("thmc50: detect failed, " |
@@ -283,13 +309,9 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
283 | pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); | 309 | pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); |
284 | goto exit_free; | 310 | goto exit_free; |
285 | } | 311 | } |
286 | pr_debug("thmc50: Detected %s (version %x, revision %x)\n", | ||
287 | type_name, (revision >> 4) - 0xc, revision & 0xf); | ||
288 | data->type = kind; | 312 | data->type = kind; |
289 | 313 | ||
290 | if (kind == thmc50) | 314 | if (kind == adm1022) { |
291 | type_name = "thmc50"; | ||
292 | else if (kind == adm1022) { | ||
293 | int id = i2c_adapter_id(client->adapter); | 315 | int id = i2c_adapter_id(client->adapter); |
294 | int i; | 316 | int i; |
295 | 317 | ||
@@ -302,7 +324,11 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
302 | data->has_temp3 = 1; | 324 | data->has_temp3 = 1; |
303 | break; | 325 | break; |
304 | } | 326 | } |
327 | } else { | ||
328 | type_name = "thmc50"; | ||
305 | } | 329 | } |
330 | pr_debug("thmc50: Detected %s (version %x, revision %x)\n", | ||
331 | type_name, (revision >> 4) - 0xc, revision & 0xf); | ||
306 | 332 | ||
307 | /* Fill in the remaining client fields & put it into the global list */ | 333 | /* Fill in the remaining client fields & put it into the global list */ |
308 | strlcpy(client->name, type_name, I2C_NAME_SIZE); | 334 | strlcpy(client->name, type_name, I2C_NAME_SIZE); |
@@ -319,23 +345,23 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) | |||
319 | goto exit_detach; | 345 | goto exit_detach; |
320 | 346 | ||
321 | /* Register ADM1022 sysfs hooks */ | 347 | /* Register ADM1022 sysfs hooks */ |
322 | if (data->type == adm1022) | 348 | if (data->has_temp3) |
323 | if ((err = sysfs_create_group(&client->dev.kobj, | 349 | if ((err = sysfs_create_group(&client->dev.kobj, |
324 | &adm1022_group))) | 350 | &temp3_group))) |
325 | goto exit_remove_sysfs_thmc50; | 351 | goto exit_remove_sysfs_thmc50; |
326 | 352 | ||
327 | /* Register a new directory entry with module sensors */ | 353 | /* Register a new directory entry with module sensors */ |
328 | data->class_dev = hwmon_device_register(&client->dev); | 354 | data->hwmon_dev = hwmon_device_register(&client->dev); |
329 | if (IS_ERR(data->class_dev)) { | 355 | if (IS_ERR(data->hwmon_dev)) { |
330 | err = PTR_ERR(data->class_dev); | 356 | err = PTR_ERR(data->hwmon_dev); |
331 | goto exit_remove_sysfs; | 357 | goto exit_remove_sysfs; |
332 | } | 358 | } |
333 | 359 | ||
334 | return 0; | 360 | return 0; |
335 | 361 | ||
336 | exit_remove_sysfs: | 362 | exit_remove_sysfs: |
337 | if (data->type == adm1022) | 363 | if (data->has_temp3) |
338 | sysfs_remove_group(&client->dev.kobj, &adm1022_group); | 364 | sysfs_remove_group(&client->dev.kobj, &temp3_group); |
339 | exit_remove_sysfs_thmc50: | 365 | exit_remove_sysfs_thmc50: |
340 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); | 366 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); |
341 | exit_detach: | 367 | exit_detach: |
@@ -358,10 +384,10 @@ static int thmc50_detach_client(struct i2c_client *client) | |||
358 | struct thmc50_data *data = i2c_get_clientdata(client); | 384 | struct thmc50_data *data = i2c_get_clientdata(client); |
359 | int err; | 385 | int err; |
360 | 386 | ||
361 | hwmon_device_unregister(data->class_dev); | 387 | hwmon_device_unregister(data->hwmon_dev); |
362 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); | 388 | sysfs_remove_group(&client->dev.kobj, &thmc50_group); |
363 | if (data->type == adm1022) | 389 | if (data->has_temp3) |
364 | sysfs_remove_group(&client->dev.kobj, &adm1022_group); | 390 | sysfs_remove_group(&client->dev.kobj, &temp3_group); |
365 | 391 | ||
366 | if ((err = i2c_detach_client(client))) | 392 | if ((err = i2c_detach_client(client))) |
367 | return err; | 393 | return err; |
@@ -414,6 +440,8 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
414 | } | 440 | } |
415 | data->analog_out = | 441 | data->analog_out = |
416 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); | 442 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); |
443 | data->alarms = | ||
444 | i2c_smbus_read_byte_data(client, THMC50_REG_INTR); | ||
417 | data->last_updated = jiffies; | 445 | data->last_updated = jiffies; |
418 | data->valid = 1; | 446 | data->valid = 1; |
419 | } | 447 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 696c8a2e5374..8f63dada6019 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -294,7 +294,7 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
294 | struct via686a_data { | 294 | struct via686a_data { |
295 | unsigned short addr; | 295 | unsigned short addr; |
296 | const char *name; | 296 | const char *name; |
297 | struct class_device *class_dev; | 297 | struct device *hwmon_dev; |
298 | struct mutex update_lock; | 298 | struct mutex update_lock; |
299 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
300 | unsigned long last_updated; /* In jiffies */ | 300 | unsigned long last_updated; /* In jiffies */ |
@@ -627,9 +627,9 @@ static int __devinit via686a_probe(struct platform_device *pdev) | |||
627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) | 627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
628 | goto exit_free; | 628 | goto exit_free; |
629 | 629 | ||
630 | data->class_dev = hwmon_device_register(&pdev->dev); | 630 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
631 | if (IS_ERR(data->class_dev)) { | 631 | if (IS_ERR(data->hwmon_dev)) { |
632 | err = PTR_ERR(data->class_dev); | 632 | err = PTR_ERR(data->hwmon_dev); |
633 | goto exit_remove_files; | 633 | goto exit_remove_files; |
634 | } | 634 | } |
635 | 635 | ||
@@ -648,7 +648,7 @@ static int __devexit via686a_remove(struct platform_device *pdev) | |||
648 | { | 648 | { |
649 | struct via686a_data *data = platform_get_drvdata(pdev); | 649 | struct via686a_data *data = platform_get_drvdata(pdev); |
650 | 650 | ||
651 | hwmon_device_unregister(data->class_dev); | 651 | hwmon_device_unregister(data->hwmon_dev); |
652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); | 652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
653 | 653 | ||
654 | release_region(data->addr, VIA686A_EXTENT); | 654 | release_region(data->addr, VIA686A_EXTENT); |
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 9f3e332c5b7f..e69416465e6d 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -108,7 +108,7 @@ static const u8 bitalarmfan[] = {6, 7}; | |||
108 | struct vt1211_data { | 108 | struct vt1211_data { |
109 | unsigned short addr; | 109 | unsigned short addr; |
110 | const char *name; | 110 | const char *name; |
111 | struct class_device *class_dev; | 111 | struct device *hwmon_dev; |
112 | 112 | ||
113 | struct mutex update_lock; | 113 | struct mutex update_lock; |
114 | char valid; /* !=0 if following fields are valid */ | 114 | char valid; /* !=0 if following fields are valid */ |
@@ -1191,9 +1191,9 @@ static int __devinit vt1211_probe(struct platform_device *pdev) | |||
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | /* Register device */ | 1193 | /* Register device */ |
1194 | data->class_dev = hwmon_device_register(dev); | 1194 | data->hwmon_dev = hwmon_device_register(dev); |
1195 | if (IS_ERR(data->class_dev)) { | 1195 | if (IS_ERR(data->hwmon_dev)) { |
1196 | err = PTR_ERR(data->class_dev); | 1196 | err = PTR_ERR(data->hwmon_dev); |
1197 | dev_err(dev, "Class registration failed (%d)\n", err); | 1197 | dev_err(dev, "Class registration failed (%d)\n", err); |
1198 | goto EXIT_DEV_REMOVE_SILENT; | 1198 | goto EXIT_DEV_REMOVE_SILENT; |
1199 | } | 1199 | } |
@@ -1217,7 +1217,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev) | |||
1217 | struct vt1211_data *data = platform_get_drvdata(pdev); | 1217 | struct vt1211_data *data = platform_get_drvdata(pdev); |
1218 | struct resource *res; | 1218 | struct resource *res; |
1219 | 1219 | ||
1220 | hwmon_device_unregister(data->class_dev); | 1220 | hwmon_device_unregister(data->hwmon_dev); |
1221 | vt1211_remove_sysfs(pdev); | 1221 | vt1211_remove_sysfs(pdev); |
1222 | platform_set_drvdata(pdev, NULL); | 1222 | platform_set_drvdata(pdev, NULL); |
1223 | kfree(data); | 1223 | kfree(data); |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 3e63eaf19041..2196a84603f5 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -148,7 +148,7 @@ struct vt8231_data { | |||
148 | const char *name; | 148 | const char *name; |
149 | 149 | ||
150 | struct mutex update_lock; | 150 | struct mutex update_lock; |
151 | struct class_device *class_dev; | 151 | struct device *hwmon_dev; |
152 | char valid; /* !=0 if following fields are valid */ | 152 | char valid; /* !=0 if following fields are valid */ |
153 | unsigned long last_updated; /* In jiffies */ | 153 | unsigned long last_updated; /* In jiffies */ |
154 | 154 | ||
@@ -676,7 +676,7 @@ static struct pci_driver vt8231_pci_driver = { | |||
676 | .probe = vt8231_pci_probe, | 676 | .probe = vt8231_pci_probe, |
677 | }; | 677 | }; |
678 | 678 | ||
679 | int vt8231_probe(struct platform_device *pdev) | 679 | static int vt8231_probe(struct platform_device *pdev) |
680 | { | 680 | { |
681 | struct resource *res; | 681 | struct resource *res; |
682 | struct vt8231_data *data; | 682 | struct vt8231_data *data; |
@@ -726,9 +726,9 @@ int vt8231_probe(struct platform_device *pdev) | |||
726 | } | 726 | } |
727 | } | 727 | } |
728 | 728 | ||
729 | data->class_dev = hwmon_device_register(&pdev->dev); | 729 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
730 | if (IS_ERR(data->class_dev)) { | 730 | if (IS_ERR(data->hwmon_dev)) { |
731 | err = PTR_ERR(data->class_dev); | 731 | err = PTR_ERR(data->hwmon_dev); |
732 | goto exit_remove_files; | 732 | goto exit_remove_files; |
733 | } | 733 | } |
734 | return 0; | 734 | return 0; |
@@ -756,7 +756,7 @@ static int __devexit vt8231_remove(struct platform_device *pdev) | |||
756 | struct vt8231_data *data = platform_get_drvdata(pdev); | 756 | struct vt8231_data *data = platform_get_drvdata(pdev); |
757 | int i; | 757 | int i; |
758 | 758 | ||
759 | hwmon_device_unregister(data->class_dev); | 759 | hwmon_device_unregister(data->hwmon_dev); |
760 | 760 | ||
761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); | 762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index d9a9ec7dd84a..b15c6a998b72 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -223,7 +223,7 @@ temp1_from_reg(s8 reg) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | static inline s8 | 225 | static inline s8 |
226 | temp1_to_reg(int temp, int min, int max) | 226 | temp1_to_reg(long temp, int min, int max) |
227 | { | 227 | { |
228 | if (temp <= min) | 228 | if (temp <= min) |
229 | return min / 1000; | 229 | return min / 1000; |
@@ -256,7 +256,7 @@ struct w83627ehf_data { | |||
256 | int addr; /* IO base of hw monitor block */ | 256 | int addr; /* IO base of hw monitor block */ |
257 | const char *name; | 257 | const char *name; |
258 | 258 | ||
259 | struct class_device *class_dev; | 259 | struct device *hwmon_dev; |
260 | struct mutex lock; | 260 | struct mutex lock; |
261 | 261 | ||
262 | struct mutex update_lock; | 262 | struct mutex update_lock; |
@@ -805,7 +805,7 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | |||
805 | const char *buf, size_t count) \ | 805 | const char *buf, size_t count) \ |
806 | { \ | 806 | { \ |
807 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ | 807 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
808 | u32 val = simple_strtoul(buf, NULL, 10); \ | 808 | long val = simple_strtol(buf, NULL, 10); \ |
809 | \ | 809 | \ |
810 | mutex_lock(&data->update_lock); \ | 810 | mutex_lock(&data->update_lock); \ |
811 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 811 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
@@ -840,7 +840,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
840 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ | 840 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
841 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 841 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
842 | int nr = sensor_attr->index; \ | 842 | int nr = sensor_attr->index; \ |
843 | u32 val = simple_strtoul(buf, NULL, 10); \ | 843 | long val = simple_strtol(buf, NULL, 10); \ |
844 | \ | 844 | \ |
845 | mutex_lock(&data->update_lock); \ | 845 | mutex_lock(&data->update_lock); \ |
846 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 846 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
@@ -1384,9 +1384,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1384 | goto exit_remove; | 1384 | goto exit_remove; |
1385 | } | 1385 | } |
1386 | 1386 | ||
1387 | data->class_dev = hwmon_device_register(dev); | 1387 | data->hwmon_dev = hwmon_device_register(dev); |
1388 | if (IS_ERR(data->class_dev)) { | 1388 | if (IS_ERR(data->hwmon_dev)) { |
1389 | err = PTR_ERR(data->class_dev); | 1389 | err = PTR_ERR(data->hwmon_dev); |
1390 | goto exit_remove; | 1390 | goto exit_remove; |
1391 | } | 1391 | } |
1392 | 1392 | ||
@@ -1406,7 +1406,7 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) | |||
1406 | { | 1406 | { |
1407 | struct w83627ehf_data *data = platform_get_drvdata(pdev); | 1407 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
1408 | 1408 | ||
1409 | hwmon_device_unregister(data->class_dev); | 1409 | hwmon_device_unregister(data->hwmon_dev); |
1410 | w83627ehf_device_remove_files(&pdev->dev); | 1410 | w83627ehf_device_remove_files(&pdev->dev); |
1411 | release_region(data->addr, IOREGION_LENGTH); | 1411 | release_region(data->addr, IOREGION_LENGTH); |
1412 | platform_set_drvdata(pdev, NULL); | 1412 | platform_set_drvdata(pdev, NULL); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 7a4a15f4bf8b..20ae425a1980 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/jiffies.h> | 45 | #include <linux/jiffies.h> |
46 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
47 | #include <linux/hwmon.h> | 47 | #include <linux/hwmon.h> |
48 | #include <linux/hwmon-sysfs.h> | ||
48 | #include <linux/hwmon-vid.h> | 49 | #include <linux/hwmon-vid.h> |
49 | #include <linux/err.h> | 50 | #include <linux/err.h> |
50 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
@@ -218,7 +219,7 @@ static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; | |||
218 | static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, | 219 | static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, |
219 | W83627THF_REG_PWM3 }; | 220 | W83627THF_REG_PWM3 }; |
220 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ | 221 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ |
221 | regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) | 222 | regpwm_627hf[nr] : regpwm[nr]) |
222 | 223 | ||
223 | #define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ | 224 | #define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ |
224 | 225 | ||
@@ -263,7 +264,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
263 | 264 | ||
264 | /* TEMP: 0.001C/bit (-128C to +127C) | 265 | /* TEMP: 0.001C/bit (-128C to +127C) |
265 | REG: 1C/bit, two's complement */ | 266 | REG: 1C/bit, two's complement */ |
266 | static u8 TEMP_TO_REG(int temp) | 267 | static u8 TEMP_TO_REG(long temp) |
267 | { | 268 | { |
268 | int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); | 269 | int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); |
269 | ntemp += (ntemp<0 ? -500 : 500); | 270 | ntemp += (ntemp<0 ? -500 : 500); |
@@ -346,7 +347,7 @@ static inline u8 DIV_TO_REG(long val) | |||
346 | struct w83627hf_data { | 347 | struct w83627hf_data { |
347 | unsigned short addr; | 348 | unsigned short addr; |
348 | const char *name; | 349 | const char *name; |
349 | struct class_device *class_dev; | 350 | struct device *hwmon_dev; |
350 | struct mutex lock; | 351 | struct mutex lock; |
351 | enum chips type; | 352 | enum chips type; |
352 | 353 | ||
@@ -372,11 +373,8 @@ struct w83627hf_data { | |||
372 | u8 beep_enable; /* Boolean */ | 373 | u8 beep_enable; /* Boolean */ |
373 | u8 pwm[3]; /* Register value */ | 374 | u8 pwm[3]; /* Register value */ |
374 | u8 pwm_freq[3]; /* Register value */ | 375 | u8 pwm_freq[3]; /* Register value */ |
375 | u16 sens[3]; /* 782D/783S only. | 376 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; |
376 | 1 = pentium diode; 2 = 3904 diode; | 377 | 4 = thermistor */ |
377 | 3000-5000 = thermistor beta. | ||
378 | Default = 3435. | ||
379 | Other Betas unimplemented */ | ||
380 | u8 vrm; | 378 | u8 vrm; |
381 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ | 379 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ |
382 | }; | 380 | }; |
@@ -391,6 +389,7 @@ static int __devexit w83627hf_remove(struct platform_device *pdev); | |||
391 | 389 | ||
392 | static int w83627hf_read_value(struct w83627hf_data *data, u16 reg); | 390 | static int w83627hf_read_value(struct w83627hf_data *data, u16 reg); |
393 | static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); | 391 | static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); |
392 | static void w83627hf_update_fan_div(struct w83627hf_data *data); | ||
394 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); | 393 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); |
395 | static void w83627hf_init_device(struct platform_device *pdev); | 394 | static void w83627hf_init_device(struct platform_device *pdev); |
396 | 395 | ||
@@ -403,72 +402,71 @@ static struct platform_driver w83627hf_driver = { | |||
403 | .remove = __devexit_p(w83627hf_remove), | 402 | .remove = __devexit_p(w83627hf_remove), |
404 | }; | 403 | }; |
405 | 404 | ||
406 | /* following are the sysfs callback functions */ | 405 | static ssize_t |
407 | #define show_in_reg(reg) \ | 406 | show_in_input(struct device *dev, struct device_attribute *devattr, char *buf) |
408 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 407 | { |
409 | { \ | 408 | int nr = to_sensor_dev_attr(devattr)->index; |
410 | struct w83627hf_data *data = w83627hf_update_device(dev); \ | 409 | struct w83627hf_data *data = w83627hf_update_device(dev); |
411 | return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr])); \ | 410 | return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in[nr])); |
412 | } | 411 | } |
413 | show_in_reg(in) | 412 | static ssize_t |
414 | show_in_reg(in_min) | 413 | show_in_min(struct device *dev, struct device_attribute *devattr, char *buf) |
415 | show_in_reg(in_max) | 414 | { |
416 | 415 | int nr = to_sensor_dev_attr(devattr)->index; | |
417 | #define store_in_reg(REG, reg) \ | 416 | struct w83627hf_data *data = w83627hf_update_device(dev); |
418 | static ssize_t \ | 417 | return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_min[nr])); |
419 | store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | ||
420 | { \ | ||
421 | struct w83627hf_data *data = dev_get_drvdata(dev); \ | ||
422 | u32 val; \ | ||
423 | \ | ||
424 | val = simple_strtoul(buf, NULL, 10); \ | ||
425 | \ | ||
426 | mutex_lock(&data->update_lock); \ | ||
427 | data->in_##reg[nr] = IN_TO_REG(val); \ | ||
428 | w83627hf_write_value(data, W83781D_REG_IN_##REG(nr), \ | ||
429 | data->in_##reg[nr]); \ | ||
430 | \ | ||
431 | mutex_unlock(&data->update_lock); \ | ||
432 | return count; \ | ||
433 | } | 418 | } |
434 | store_in_reg(MIN, min) | 419 | static ssize_t |
435 | store_in_reg(MAX, max) | 420 | show_in_max(struct device *dev, struct device_attribute *devattr, char *buf) |
421 | { | ||
422 | int nr = to_sensor_dev_attr(devattr)->index; | ||
423 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
424 | return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_max[nr])); | ||
425 | } | ||
426 | static ssize_t | ||
427 | store_in_min(struct device *dev, struct device_attribute *devattr, | ||
428 | const char *buf, size_t count) | ||
429 | { | ||
430 | int nr = to_sensor_dev_attr(devattr)->index; | ||
431 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
432 | long val = simple_strtol(buf, NULL, 10); | ||
436 | 433 | ||
437 | #define sysfs_in_offset(offset) \ | 434 | mutex_lock(&data->update_lock); |
438 | static ssize_t \ | 435 | data->in_min[nr] = IN_TO_REG(val); |
439 | show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 436 | w83627hf_write_value(data, W83781D_REG_IN_MIN(nr), data->in_min[nr]); |
440 | { \ | 437 | mutex_unlock(&data->update_lock); |
441 | return show_in(dev, buf, offset); \ | 438 | return count; |
442 | } \ | 439 | } |
443 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); | 440 | static ssize_t |
441 | store_in_max(struct device *dev, struct device_attribute *devattr, | ||
442 | const char *buf, size_t count) | ||
443 | { | ||
444 | int nr = to_sensor_dev_attr(devattr)->index; | ||
445 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
446 | long val = simple_strtol(buf, NULL, 10); | ||
444 | 447 | ||
445 | #define sysfs_in_reg_offset(reg, offset) \ | 448 | mutex_lock(&data->update_lock); |
446 | static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 449 | data->in_max[nr] = IN_TO_REG(val); |
447 | { \ | 450 | w83627hf_write_value(data, W83781D_REG_IN_MAX(nr), data->in_max[nr]); |
448 | return show_in_##reg (dev, buf, offset); \ | 451 | mutex_unlock(&data->update_lock); |
449 | } \ | 452 | return count; |
450 | static ssize_t \ | 453 | } |
451 | store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, \ | 454 | #define sysfs_vin_decl(offset) \ |
452 | const char *buf, size_t count) \ | 455 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
453 | { \ | 456 | show_in_input, NULL, offset); \ |
454 | return store_in_##reg (dev, buf, count, offset); \ | 457 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO|S_IWUSR, \ |
455 | } \ | 458 | show_in_min, store_in_min, offset); \ |
456 | static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \ | 459 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO|S_IWUSR, \ |
457 | show_regs_in_##reg##offset, store_regs_in_##reg##offset); | 460 | show_in_max, store_in_max, offset); |
458 | 461 | ||
459 | #define sysfs_in_offsets(offset) \ | 462 | sysfs_vin_decl(1); |
460 | sysfs_in_offset(offset) \ | 463 | sysfs_vin_decl(2); |
461 | sysfs_in_reg_offset(min, offset) \ | 464 | sysfs_vin_decl(3); |
462 | sysfs_in_reg_offset(max, offset) | 465 | sysfs_vin_decl(4); |
463 | 466 | sysfs_vin_decl(5); | |
464 | sysfs_in_offsets(1); | 467 | sysfs_vin_decl(6); |
465 | sysfs_in_offsets(2); | 468 | sysfs_vin_decl(7); |
466 | sysfs_in_offsets(3); | 469 | sysfs_vin_decl(8); |
467 | sysfs_in_offsets(4); | ||
468 | sysfs_in_offsets(5); | ||
469 | sysfs_in_offsets(6); | ||
470 | sysfs_in_offsets(7); | ||
471 | sysfs_in_offsets(8); | ||
472 | 470 | ||
473 | /* use a different set of functions for in0 */ | 471 | /* use a different set of functions for in0 */ |
474 | static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) | 472 | static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) |
@@ -566,134 +564,148 @@ static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, | |||
566 | static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, | 564 | static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, |
567 | show_regs_in_max0, store_regs_in_max0); | 565 | show_regs_in_max0, store_regs_in_max0); |
568 | 566 | ||
569 | #define show_fan_reg(reg) \ | 567 | static ssize_t |
570 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 568 | show_fan_input(struct device *dev, struct device_attribute *devattr, char *buf) |
571 | { \ | 569 | { |
572 | struct w83627hf_data *data = w83627hf_update_device(dev); \ | 570 | int nr = to_sensor_dev_attr(devattr)->index; |
573 | return sprintf(buf,"%ld\n", \ | 571 | struct w83627hf_data *data = w83627hf_update_device(dev); |
574 | FAN_FROM_REG(data->reg[nr-1], \ | 572 | return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan[nr], |
575 | (long)DIV_FROM_REG(data->fan_div[nr-1]))); \ | 573 | (long)DIV_FROM_REG(data->fan_div[nr]))); |
576 | } | 574 | } |
577 | show_fan_reg(fan); | ||
578 | show_fan_reg(fan_min); | ||
579 | |||
580 | static ssize_t | 575 | static ssize_t |
581 | store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | 576 | show_fan_min(struct device *dev, struct device_attribute *devattr, char *buf) |
582 | { | 577 | { |
578 | int nr = to_sensor_dev_attr(devattr)->index; | ||
579 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
580 | return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan_min[nr], | ||
581 | (long)DIV_FROM_REG(data->fan_div[nr]))); | ||
582 | } | ||
583 | static ssize_t | ||
584 | store_fan_min(struct device *dev, struct device_attribute *devattr, | ||
585 | const char *buf, size_t count) | ||
586 | { | ||
587 | int nr = to_sensor_dev_attr(devattr)->index; | ||
583 | struct w83627hf_data *data = dev_get_drvdata(dev); | 588 | struct w83627hf_data *data = dev_get_drvdata(dev); |
584 | u32 val; | 589 | u32 val = simple_strtoul(buf, NULL, 10); |
585 | |||
586 | val = simple_strtoul(buf, NULL, 10); | ||
587 | 590 | ||
588 | mutex_lock(&data->update_lock); | 591 | mutex_lock(&data->update_lock); |
589 | data->fan_min[nr - 1] = | 592 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
590 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); | 593 | w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), |
591 | w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr), | 594 | data->fan_min[nr]); |
592 | data->fan_min[nr - 1]); | ||
593 | 595 | ||
594 | mutex_unlock(&data->update_lock); | 596 | mutex_unlock(&data->update_lock); |
595 | return count; | 597 | return count; |
596 | } | 598 | } |
599 | #define sysfs_fan_decl(offset) \ | ||
600 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
601 | show_fan_input, NULL, offset - 1); \ | ||
602 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
603 | show_fan_min, store_fan_min, offset - 1); | ||
597 | 604 | ||
598 | #define sysfs_fan_offset(offset) \ | 605 | sysfs_fan_decl(1); |
599 | static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 606 | sysfs_fan_decl(2); |
600 | { \ | 607 | sysfs_fan_decl(3); |
601 | return show_fan(dev, buf, offset); \ | ||
602 | } \ | ||
603 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); | ||
604 | 608 | ||
605 | #define sysfs_fan_min_offset(offset) \ | 609 | static ssize_t |
606 | static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 610 | show_temp(struct device *dev, struct device_attribute *devattr, char *buf) |
607 | { \ | 611 | { |
608 | return show_fan_min(dev, buf, offset); \ | 612 | int nr = to_sensor_dev_attr(devattr)->index; |
609 | } \ | 613 | struct w83627hf_data *data = w83627hf_update_device(dev); |
610 | static ssize_t \ | 614 | if (nr >= 2) { /* TEMP2 and TEMP3 */ |
611 | store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | 615 | return sprintf(buf, "%ld\n", |
612 | { \ | 616 | (long)LM75_TEMP_FROM_REG(data->temp_add[nr-2])); |
613 | return store_fan_min(dev, buf, count, offset); \ | 617 | } else { /* TEMP1 */ |
614 | } \ | 618 | return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->temp)); |
615 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | 619 | } |
616 | show_regs_fan_min##offset, store_regs_fan_min##offset); | ||
617 | |||
618 | sysfs_fan_offset(1); | ||
619 | sysfs_fan_min_offset(1); | ||
620 | sysfs_fan_offset(2); | ||
621 | sysfs_fan_min_offset(2); | ||
622 | sysfs_fan_offset(3); | ||
623 | sysfs_fan_min_offset(3); | ||
624 | |||
625 | #define show_temp_reg(reg) \ | ||
626 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | ||
627 | { \ | ||
628 | struct w83627hf_data *data = w83627hf_update_device(dev); \ | ||
629 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | ||
630 | return sprintf(buf,"%ld\n", \ | ||
631 | (long)LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ | ||
632 | } else { /* TEMP1 */ \ | ||
633 | return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \ | ||
634 | } \ | ||
635 | } | 620 | } |
636 | show_temp_reg(temp); | ||
637 | show_temp_reg(temp_max); | ||
638 | show_temp_reg(temp_max_hyst); | ||
639 | 621 | ||
640 | #define store_temp_reg(REG, reg) \ | 622 | static ssize_t |
641 | static ssize_t \ | 623 | show_temp_max(struct device *dev, struct device_attribute *devattr, |
642 | store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 624 | char *buf) |
643 | { \ | 625 | { |
644 | struct w83627hf_data *data = dev_get_drvdata(dev); \ | 626 | int nr = to_sensor_dev_attr(devattr)->index; |
645 | u32 val; \ | 627 | struct w83627hf_data *data = w83627hf_update_device(dev); |
646 | \ | 628 | if (nr >= 2) { /* TEMP2 and TEMP3 */ |
647 | val = simple_strtoul(buf, NULL, 10); \ | 629 | return sprintf(buf, "%ld\n", |
648 | \ | 630 | (long)LM75_TEMP_FROM_REG(data->temp_max_add[nr-2])); |
649 | mutex_lock(&data->update_lock); \ | 631 | } else { /* TEMP1 */ |
650 | \ | 632 | return sprintf(buf, "%ld\n", |
651 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | 633 | (long)TEMP_FROM_REG(data->temp_max)); |
652 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ | 634 | } |
653 | w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \ | ||
654 | data->temp_##reg##_add[nr-2]); \ | ||
655 | } else { /* TEMP1 */ \ | ||
656 | data->temp_##reg = TEMP_TO_REG(val); \ | ||
657 | w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \ | ||
658 | data->temp_##reg); \ | ||
659 | } \ | ||
660 | \ | ||
661 | mutex_unlock(&data->update_lock); \ | ||
662 | return count; \ | ||
663 | } | 635 | } |
664 | store_temp_reg(OVER, max); | ||
665 | store_temp_reg(HYST, max_hyst); | ||
666 | 636 | ||
667 | #define sysfs_temp_offset(offset) \ | 637 | static ssize_t |
668 | static ssize_t \ | 638 | show_temp_max_hyst(struct device *dev, struct device_attribute *devattr, |
669 | show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 639 | char *buf) |
670 | { \ | 640 | { |
671 | return show_temp(dev, buf, offset); \ | 641 | int nr = to_sensor_dev_attr(devattr)->index; |
672 | } \ | 642 | struct w83627hf_data *data = w83627hf_update_device(dev); |
673 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL); | 643 | if (nr >= 2) { /* TEMP2 and TEMP3 */ |
644 | return sprintf(buf, "%ld\n", | ||
645 | (long)LM75_TEMP_FROM_REG(data->temp_max_hyst_add[nr-2])); | ||
646 | } else { /* TEMP1 */ | ||
647 | return sprintf(buf, "%ld\n", | ||
648 | (long)TEMP_FROM_REG(data->temp_max_hyst)); | ||
649 | } | ||
650 | } | ||
674 | 651 | ||
675 | #define sysfs_temp_reg_offset(reg, offset) \ | 652 | static ssize_t |
676 | static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 653 | store_temp_max(struct device *dev, struct device_attribute *devattr, |
677 | { \ | 654 | const char *buf, size_t count) |
678 | return show_temp_##reg (dev, buf, offset); \ | 655 | { |
679 | } \ | 656 | int nr = to_sensor_dev_attr(devattr)->index; |
680 | static ssize_t \ | 657 | struct w83627hf_data *data = dev_get_drvdata(dev); |
681 | store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, \ | 658 | long val = simple_strtol(buf, NULL, 10); |
682 | const char *buf, size_t count) \ | ||
683 | { \ | ||
684 | return store_temp_##reg (dev, buf, count, offset); \ | ||
685 | } \ | ||
686 | static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ | ||
687 | show_regs_temp_##reg##offset, store_regs_temp_##reg##offset); | ||
688 | 659 | ||
689 | #define sysfs_temp_offsets(offset) \ | 660 | mutex_lock(&data->update_lock); |
690 | sysfs_temp_offset(offset) \ | ||
691 | sysfs_temp_reg_offset(max, offset) \ | ||
692 | sysfs_temp_reg_offset(max_hyst, offset) | ||
693 | 661 | ||
694 | sysfs_temp_offsets(1); | 662 | if (nr >= 2) { /* TEMP2 and TEMP3 */ |
695 | sysfs_temp_offsets(2); | 663 | data->temp_max_add[nr-2] = LM75_TEMP_TO_REG(val); |
696 | sysfs_temp_offsets(3); | 664 | w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr), |
665 | data->temp_max_add[nr-2]); | ||
666 | } else { /* TEMP1 */ | ||
667 | data->temp_max = TEMP_TO_REG(val); | ||
668 | w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr), | ||
669 | data->temp_max); | ||
670 | } | ||
671 | mutex_unlock(&data->update_lock); | ||
672 | return count; | ||
673 | } | ||
674 | |||
675 | static ssize_t | ||
676 | store_temp_max_hyst(struct device *dev, struct device_attribute *devattr, | ||
677 | const char *buf, size_t count) | ||
678 | { | ||
679 | int nr = to_sensor_dev_attr(devattr)->index; | ||
680 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
681 | long val = simple_strtol(buf, NULL, 10); | ||
682 | |||
683 | mutex_lock(&data->update_lock); | ||
684 | |||
685 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | ||
686 | data->temp_max_hyst_add[nr-2] = LM75_TEMP_TO_REG(val); | ||
687 | w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr), | ||
688 | data->temp_max_hyst_add[nr-2]); | ||
689 | } else { /* TEMP1 */ | ||
690 | data->temp_max_hyst = TEMP_TO_REG(val); | ||
691 | w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr), | ||
692 | data->temp_max_hyst); | ||
693 | } | ||
694 | mutex_unlock(&data->update_lock); | ||
695 | return count; | ||
696 | } | ||
697 | |||
698 | #define sysfs_temp_decl(offset) \ | ||
699 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
700 | show_temp, NULL, offset); \ | ||
701 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR, \ | ||
702 | show_temp_max, store_temp_max, offset); \ | ||
703 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR, \ | ||
704 | show_temp_max_hyst, store_temp_max_hyst, offset); | ||
705 | |||
706 | sysfs_temp_decl(1); | ||
707 | sysfs_temp_decl(2); | ||
708 | sysfs_temp_decl(3); | ||
697 | 709 | ||
698 | static ssize_t | 710 | static ssize_t |
699 | show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 711 | show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -706,7 +718,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
706 | static ssize_t | 718 | static ssize_t |
707 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 719 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
708 | { | 720 | { |
709 | struct w83627hf_data *data = w83627hf_update_device(dev); | 721 | struct w83627hf_data *data = dev_get_drvdata(dev); |
710 | return sprintf(buf, "%ld\n", (long) data->vrm); | 722 | return sprintf(buf, "%ld\n", (long) data->vrm); |
711 | } | 723 | } |
712 | static ssize_t | 724 | static ssize_t |
@@ -791,20 +803,22 @@ sysfs_beep(ENABLE, enable); | |||
791 | sysfs_beep(MASK, mask); | 803 | sysfs_beep(MASK, mask); |
792 | 804 | ||
793 | static ssize_t | 805 | static ssize_t |
794 | show_fan_div_reg(struct device *dev, char *buf, int nr) | 806 | show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) |
795 | { | 807 | { |
808 | int nr = to_sensor_dev_attr(devattr)->index; | ||
796 | struct w83627hf_data *data = w83627hf_update_device(dev); | 809 | struct w83627hf_data *data = w83627hf_update_device(dev); |
797 | return sprintf(buf, "%ld\n", | 810 | return sprintf(buf, "%ld\n", |
798 | (long) DIV_FROM_REG(data->fan_div[nr - 1])); | 811 | (long) DIV_FROM_REG(data->fan_div[nr])); |
799 | } | 812 | } |
800 | |||
801 | /* Note: we save and restore the fan minimum here, because its value is | 813 | /* Note: we save and restore the fan minimum here, because its value is |
802 | determined in part by the fan divisor. This follows the principle of | 814 | determined in part by the fan divisor. This follows the principle of |
803 | least surprise; the user doesn't expect the fan minimum to change just | 815 | least surprise; the user doesn't expect the fan minimum to change just |
804 | because the divisor changed. */ | 816 | because the divisor changed. */ |
805 | static ssize_t | 817 | static ssize_t |
806 | store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | 818 | store_fan_div(struct device *dev, struct device_attribute *devattr, |
819 | const char *buf, size_t count) | ||
807 | { | 820 | { |
821 | int nr = to_sensor_dev_attr(devattr)->index; | ||
808 | struct w83627hf_data *data = dev_get_drvdata(dev); | 822 | struct w83627hf_data *data = dev_get_drvdata(dev); |
809 | unsigned long min; | 823 | unsigned long min; |
810 | u8 reg; | 824 | u8 reg; |
@@ -836,92 +850,72 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
836 | return count; | 850 | return count; |
837 | } | 851 | } |
838 | 852 | ||
839 | #define sysfs_fan_div(offset) \ | 853 | static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO|S_IWUSR, |
840 | static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 854 | show_fan_div, store_fan_div, 0); |
841 | { \ | 855 | static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO|S_IWUSR, |
842 | return show_fan_div_reg(dev, buf, offset); \ | 856 | show_fan_div, store_fan_div, 1); |
843 | } \ | 857 | static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO|S_IWUSR, |
844 | static ssize_t \ | 858 | show_fan_div, store_fan_div, 2); |
845 | store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, \ | ||
846 | const char *buf, size_t count) \ | ||
847 | { \ | ||
848 | return store_fan_div_reg(dev, buf, count, offset - 1); \ | ||
849 | } \ | ||
850 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
851 | show_regs_fan_div_##offset, store_regs_fan_div_##offset); | ||
852 | |||
853 | sysfs_fan_div(1); | ||
854 | sysfs_fan_div(2); | ||
855 | sysfs_fan_div(3); | ||
856 | 859 | ||
857 | static ssize_t | 860 | static ssize_t |
858 | show_pwm_reg(struct device *dev, char *buf, int nr) | 861 | show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) |
859 | { | 862 | { |
863 | int nr = to_sensor_dev_attr(devattr)->index; | ||
860 | struct w83627hf_data *data = w83627hf_update_device(dev); | 864 | struct w83627hf_data *data = w83627hf_update_device(dev); |
861 | return sprintf(buf, "%ld\n", (long) data->pwm[nr - 1]); | 865 | return sprintf(buf, "%ld\n", (long) data->pwm[nr]); |
862 | } | 866 | } |
863 | 867 | ||
864 | static ssize_t | 868 | static ssize_t |
865 | store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) | 869 | store_pwm(struct device *dev, struct device_attribute *devattr, |
870 | const char *buf, size_t count) | ||
866 | { | 871 | { |
872 | int nr = to_sensor_dev_attr(devattr)->index; | ||
867 | struct w83627hf_data *data = dev_get_drvdata(dev); | 873 | struct w83627hf_data *data = dev_get_drvdata(dev); |
868 | u32 val; | 874 | u32 val = simple_strtoul(buf, NULL, 10); |
869 | |||
870 | val = simple_strtoul(buf, NULL, 10); | ||
871 | 875 | ||
872 | mutex_lock(&data->update_lock); | 876 | mutex_lock(&data->update_lock); |
873 | 877 | ||
874 | if (data->type == w83627thf) { | 878 | if (data->type == w83627thf) { |
875 | /* bits 0-3 are reserved in 627THF */ | 879 | /* bits 0-3 are reserved in 627THF */ |
876 | data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0; | 880 | data->pwm[nr] = PWM_TO_REG(val) & 0xf0; |
877 | w83627hf_write_value(data, | 881 | w83627hf_write_value(data, |
878 | W836X7HF_REG_PWM(data->type, nr), | 882 | W836X7HF_REG_PWM(data->type, nr), |
879 | data->pwm[nr - 1] | | 883 | data->pwm[nr] | |
880 | (w83627hf_read_value(data, | 884 | (w83627hf_read_value(data, |
881 | W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); | 885 | W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); |
882 | } else { | 886 | } else { |
883 | data->pwm[nr - 1] = PWM_TO_REG(val); | 887 | data->pwm[nr] = PWM_TO_REG(val); |
884 | w83627hf_write_value(data, | 888 | w83627hf_write_value(data, |
885 | W836X7HF_REG_PWM(data->type, nr), | 889 | W836X7HF_REG_PWM(data->type, nr), |
886 | data->pwm[nr - 1]); | 890 | data->pwm[nr]); |
887 | } | 891 | } |
888 | 892 | ||
889 | mutex_unlock(&data->update_lock); | 893 | mutex_unlock(&data->update_lock); |
890 | return count; | 894 | return count; |
891 | } | 895 | } |
892 | 896 | ||
893 | #define sysfs_pwm(offset) \ | 897 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0); |
894 | static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 898 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); |
895 | { \ | 899 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); |
896 | return show_pwm_reg(dev, buf, offset); \ | ||
897 | } \ | ||
898 | static ssize_t \ | ||
899 | store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
900 | { \ | ||
901 | return store_pwm_reg(dev, buf, count, offset); \ | ||
902 | } \ | ||
903 | static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | ||
904 | show_regs_pwm_##offset, store_regs_pwm_##offset); | ||
905 | |||
906 | sysfs_pwm(1); | ||
907 | sysfs_pwm(2); | ||
908 | sysfs_pwm(3); | ||
909 | 900 | ||
910 | static ssize_t | 901 | static ssize_t |
911 | show_pwm_freq_reg(struct device *dev, char *buf, int nr) | 902 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) |
912 | { | 903 | { |
904 | int nr = to_sensor_dev_attr(devattr)->index; | ||
913 | struct w83627hf_data *data = w83627hf_update_device(dev); | 905 | struct w83627hf_data *data = w83627hf_update_device(dev); |
914 | if (data->type == w83627hf) | 906 | if (data->type == w83627hf) |
915 | return sprintf(buf, "%ld\n", | 907 | return sprintf(buf, "%ld\n", |
916 | pwm_freq_from_reg_627hf(data->pwm_freq[nr - 1])); | 908 | pwm_freq_from_reg_627hf(data->pwm_freq[nr])); |
917 | else | 909 | else |
918 | return sprintf(buf, "%ld\n", | 910 | return sprintf(buf, "%ld\n", |
919 | pwm_freq_from_reg(data->pwm_freq[nr - 1])); | 911 | pwm_freq_from_reg(data->pwm_freq[nr])); |
920 | } | 912 | } |
921 | 913 | ||
922 | static ssize_t | 914 | static ssize_t |
923 | store_pwm_freq_reg(struct device *dev, const char *buf, size_t count, int nr) | 915 | store_pwm_freq(struct device *dev, struct device_attribute *devattr, |
916 | const char *buf, size_t count) | ||
924 | { | 917 | { |
918 | int nr = to_sensor_dev_attr(devattr)->index; | ||
925 | struct w83627hf_data *data = dev_get_drvdata(dev); | 919 | struct w83627hf_data *data = dev_get_drvdata(dev); |
926 | static const u8 mask[]={0xF8, 0x8F}; | 920 | static const u8 mask[]={0xF8, 0x8F}; |
927 | u32 val; | 921 | u32 val; |
@@ -931,50 +925,42 @@ store_pwm_freq_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
931 | mutex_lock(&data->update_lock); | 925 | mutex_lock(&data->update_lock); |
932 | 926 | ||
933 | if (data->type == w83627hf) { | 927 | if (data->type == w83627hf) { |
934 | data->pwm_freq[nr - 1] = pwm_freq_to_reg_627hf(val); | 928 | data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val); |
935 | w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, | 929 | w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, |
936 | (data->pwm_freq[nr - 1] << ((nr - 1)*4)) | | 930 | (data->pwm_freq[nr] << (nr*4)) | |
937 | (w83627hf_read_value(data, | 931 | (w83627hf_read_value(data, |
938 | W83627HF_REG_PWM_FREQ) & mask[nr - 1])); | 932 | W83627HF_REG_PWM_FREQ) & mask[nr])); |
939 | } else { | 933 | } else { |
940 | data->pwm_freq[nr - 1] = pwm_freq_to_reg(val); | 934 | data->pwm_freq[nr] = pwm_freq_to_reg(val); |
941 | w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr - 1], | 935 | w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr], |
942 | data->pwm_freq[nr - 1]); | 936 | data->pwm_freq[nr]); |
943 | } | 937 | } |
944 | 938 | ||
945 | mutex_unlock(&data->update_lock); | 939 | mutex_unlock(&data->update_lock); |
946 | return count; | 940 | return count; |
947 | } | 941 | } |
948 | 942 | ||
949 | #define sysfs_pwm_freq(offset) \ | 943 | static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO|S_IWUSR, |
950 | static ssize_t show_regs_pwm_freq_##offset(struct device *dev, \ | 944 | show_pwm_freq, store_pwm_freq, 0); |
951 | struct device_attribute *attr, char *buf) \ | 945 | static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO|S_IWUSR, |
952 | { \ | 946 | show_pwm_freq, store_pwm_freq, 1); |
953 | return show_pwm_freq_reg(dev, buf, offset); \ | 947 | static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO|S_IWUSR, |
954 | } \ | 948 | show_pwm_freq, store_pwm_freq, 2); |
955 | static ssize_t \ | ||
956 | store_regs_pwm_freq_##offset(struct device *dev, \ | ||
957 | struct device_attribute *attr, const char *buf, size_t count) \ | ||
958 | { \ | ||
959 | return store_pwm_freq_reg(dev, buf, count, offset); \ | ||
960 | } \ | ||
961 | static DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \ | ||
962 | show_regs_pwm_freq_##offset, store_regs_pwm_freq_##offset); | ||
963 | |||
964 | sysfs_pwm_freq(1); | ||
965 | sysfs_pwm_freq(2); | ||
966 | sysfs_pwm_freq(3); | ||
967 | 949 | ||
968 | static ssize_t | 950 | static ssize_t |
969 | show_sensor_reg(struct device *dev, char *buf, int nr) | 951 | show_temp_type(struct device *dev, struct device_attribute *devattr, |
952 | char *buf) | ||
970 | { | 953 | { |
954 | int nr = to_sensor_dev_attr(devattr)->index; | ||
971 | struct w83627hf_data *data = w83627hf_update_device(dev); | 955 | struct w83627hf_data *data = w83627hf_update_device(dev); |
972 | return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]); | 956 | return sprintf(buf, "%ld\n", (long) data->sens[nr]); |
973 | } | 957 | } |
974 | 958 | ||
975 | static ssize_t | 959 | static ssize_t |
976 | store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | 960 | store_temp_type(struct device *dev, struct device_attribute *devattr, |
961 | const char *buf, size_t count) | ||
977 | { | 962 | { |
963 | int nr = to_sensor_dev_attr(devattr)->index; | ||
978 | struct w83627hf_data *data = dev_get_drvdata(dev); | 964 | struct w83627hf_data *data = dev_get_drvdata(dev); |
979 | u32 val, tmp; | 965 | u32 val, tmp; |
980 | 966 | ||
@@ -986,31 +972,35 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
986 | case 1: /* PII/Celeron diode */ | 972 | case 1: /* PII/Celeron diode */ |
987 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 973 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
988 | w83627hf_write_value(data, W83781D_REG_SCFG1, | 974 | w83627hf_write_value(data, W83781D_REG_SCFG1, |
989 | tmp | BIT_SCFG1[nr - 1]); | 975 | tmp | BIT_SCFG1[nr]); |
990 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); | 976 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); |
991 | w83627hf_write_value(data, W83781D_REG_SCFG2, | 977 | w83627hf_write_value(data, W83781D_REG_SCFG2, |
992 | tmp | BIT_SCFG2[nr - 1]); | 978 | tmp | BIT_SCFG2[nr]); |
993 | data->sens[nr - 1] = val; | 979 | data->sens[nr] = val; |
994 | break; | 980 | break; |
995 | case 2: /* 3904 */ | 981 | case 2: /* 3904 */ |
996 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 982 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
997 | w83627hf_write_value(data, W83781D_REG_SCFG1, | 983 | w83627hf_write_value(data, W83781D_REG_SCFG1, |
998 | tmp | BIT_SCFG1[nr - 1]); | 984 | tmp | BIT_SCFG1[nr]); |
999 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); | 985 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); |
1000 | w83627hf_write_value(data, W83781D_REG_SCFG2, | 986 | w83627hf_write_value(data, W83781D_REG_SCFG2, |
1001 | tmp & ~BIT_SCFG2[nr - 1]); | 987 | tmp & ~BIT_SCFG2[nr]); |
1002 | data->sens[nr - 1] = val; | 988 | data->sens[nr] = val; |
1003 | break; | 989 | break; |
1004 | case W83781D_DEFAULT_BETA: /* thermistor */ | 990 | case W83781D_DEFAULT_BETA: |
991 | dev_warn(dev, "Sensor type %d is deprecated, please use 4 " | ||
992 | "instead\n", W83781D_DEFAULT_BETA); | ||
993 | /* fall through */ | ||
994 | case 4: /* thermistor */ | ||
1005 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 995 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
1006 | w83627hf_write_value(data, W83781D_REG_SCFG1, | 996 | w83627hf_write_value(data, W83781D_REG_SCFG1, |
1007 | tmp & ~BIT_SCFG1[nr - 1]); | 997 | tmp & ~BIT_SCFG1[nr]); |
1008 | data->sens[nr - 1] = val; | 998 | data->sens[nr] = val; |
1009 | break; | 999 | break; |
1010 | default: | 1000 | default: |
1011 | dev_err(dev, | 1001 | dev_err(dev, |
1012 | "Invalid sensor type %ld; must be 1, 2, or %d\n", | 1002 | "Invalid sensor type %ld; must be 1, 2, or 4\n", |
1013 | (long) val, W83781D_DEFAULT_BETA); | 1003 | (long) val); |
1014 | break; | 1004 | break; |
1015 | } | 1005 | } |
1016 | 1006 | ||
@@ -1018,25 +1008,16 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
1018 | return count; | 1008 | return count; |
1019 | } | 1009 | } |
1020 | 1010 | ||
1021 | #define sysfs_sensor(offset) \ | 1011 | #define sysfs_temp_type(offset) \ |
1022 | static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 1012 | static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ |
1023 | { \ | 1013 | show_temp_type, store_temp_type, offset - 1); |
1024 | return show_sensor_reg(dev, buf, offset); \ | ||
1025 | } \ | ||
1026 | static ssize_t \ | ||
1027 | store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
1028 | { \ | ||
1029 | return store_sensor_reg(dev, buf, count, offset); \ | ||
1030 | } \ | ||
1031 | static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ | ||
1032 | show_regs_sensor_##offset, store_regs_sensor_##offset); | ||
1033 | 1014 | ||
1034 | sysfs_sensor(1); | 1015 | sysfs_temp_type(1); |
1035 | sysfs_sensor(2); | 1016 | sysfs_temp_type(2); |
1036 | sysfs_sensor(3); | 1017 | sysfs_temp_type(3); |
1037 | 1018 | ||
1038 | static ssize_t show_name(struct device *dev, struct device_attribute | 1019 | static ssize_t |
1039 | *devattr, char *buf) | 1020 | show_name(struct device *dev, struct device_attribute *devattr, char *buf) |
1040 | { | 1021 | { |
1041 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1022 | struct w83627hf_data *data = dev_get_drvdata(dev); |
1042 | 1023 | ||
@@ -1118,49 +1099,44 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, | |||
1118 | return err; | 1099 | return err; |
1119 | } | 1100 | } |
1120 | 1101 | ||
1102 | #define VIN_UNIT_ATTRS(_X_) \ | ||
1103 | &sensor_dev_attr_in##_X_##_input.dev_attr.attr, \ | ||
1104 | &sensor_dev_attr_in##_X_##_min.dev_attr.attr, \ | ||
1105 | &sensor_dev_attr_in##_X_##_max.dev_attr.attr | ||
1106 | |||
1107 | #define FAN_UNIT_ATTRS(_X_) \ | ||
1108 | &sensor_dev_attr_fan##_X_##_input.dev_attr.attr, \ | ||
1109 | &sensor_dev_attr_fan##_X_##_min.dev_attr.attr, \ | ||
1110 | &sensor_dev_attr_fan##_X_##_div.dev_attr.attr | ||
1111 | |||
1112 | #define TEMP_UNIT_ATTRS(_X_) \ | ||
1113 | &sensor_dev_attr_temp##_X_##_input.dev_attr.attr, \ | ||
1114 | &sensor_dev_attr_temp##_X_##_max.dev_attr.attr, \ | ||
1115 | &sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr, \ | ||
1116 | &sensor_dev_attr_temp##_X_##_type.dev_attr.attr | ||
1117 | |||
1121 | static struct attribute *w83627hf_attributes[] = { | 1118 | static struct attribute *w83627hf_attributes[] = { |
1122 | &dev_attr_in0_input.attr, | 1119 | &dev_attr_in0_input.attr, |
1123 | &dev_attr_in0_min.attr, | 1120 | &dev_attr_in0_min.attr, |
1124 | &dev_attr_in0_max.attr, | 1121 | &dev_attr_in0_max.attr, |
1125 | &dev_attr_in2_input.attr, | 1122 | VIN_UNIT_ATTRS(2), |
1126 | &dev_attr_in2_min.attr, | 1123 | VIN_UNIT_ATTRS(3), |
1127 | &dev_attr_in2_max.attr, | 1124 | VIN_UNIT_ATTRS(4), |
1128 | &dev_attr_in3_input.attr, | 1125 | VIN_UNIT_ATTRS(7), |
1129 | &dev_attr_in3_min.attr, | 1126 | VIN_UNIT_ATTRS(8), |
1130 | &dev_attr_in3_max.attr, | 1127 | |
1131 | &dev_attr_in4_input.attr, | 1128 | FAN_UNIT_ATTRS(1), |
1132 | &dev_attr_in4_min.attr, | 1129 | FAN_UNIT_ATTRS(2), |
1133 | &dev_attr_in4_max.attr, | 1130 | |
1134 | &dev_attr_in7_input.attr, | 1131 | TEMP_UNIT_ATTRS(1), |
1135 | &dev_attr_in7_min.attr, | 1132 | TEMP_UNIT_ATTRS(2), |
1136 | &dev_attr_in7_max.attr, | ||
1137 | &dev_attr_in8_input.attr, | ||
1138 | &dev_attr_in8_min.attr, | ||
1139 | &dev_attr_in8_max.attr, | ||
1140 | |||
1141 | &dev_attr_fan1_input.attr, | ||
1142 | &dev_attr_fan1_min.attr, | ||
1143 | &dev_attr_fan1_div.attr, | ||
1144 | &dev_attr_fan2_input.attr, | ||
1145 | &dev_attr_fan2_min.attr, | ||
1146 | &dev_attr_fan2_div.attr, | ||
1147 | |||
1148 | &dev_attr_temp1_input.attr, | ||
1149 | &dev_attr_temp1_max.attr, | ||
1150 | &dev_attr_temp1_max_hyst.attr, | ||
1151 | &dev_attr_temp1_type.attr, | ||
1152 | &dev_attr_temp2_input.attr, | ||
1153 | &dev_attr_temp2_max.attr, | ||
1154 | &dev_attr_temp2_max_hyst.attr, | ||
1155 | &dev_attr_temp2_type.attr, | ||
1156 | 1133 | ||
1157 | &dev_attr_alarms.attr, | 1134 | &dev_attr_alarms.attr, |
1158 | &dev_attr_beep_enable.attr, | 1135 | &dev_attr_beep_enable.attr, |
1159 | &dev_attr_beep_mask.attr, | 1136 | &dev_attr_beep_mask.attr, |
1160 | 1137 | ||
1161 | &dev_attr_pwm1.attr, | 1138 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1162 | &dev_attr_pwm2.attr, | 1139 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1163 | |||
1164 | &dev_attr_name.attr, | 1140 | &dev_attr_name.attr, |
1165 | NULL | 1141 | NULL |
1166 | }; | 1142 | }; |
@@ -1170,30 +1146,17 @@ static const struct attribute_group w83627hf_group = { | |||
1170 | }; | 1146 | }; |
1171 | 1147 | ||
1172 | static struct attribute *w83627hf_attributes_opt[] = { | 1148 | static struct attribute *w83627hf_attributes_opt[] = { |
1173 | &dev_attr_in1_input.attr, | 1149 | VIN_UNIT_ATTRS(1), |
1174 | &dev_attr_in1_min.attr, | 1150 | VIN_UNIT_ATTRS(5), |
1175 | &dev_attr_in1_max.attr, | 1151 | VIN_UNIT_ATTRS(6), |
1176 | &dev_attr_in5_input.attr, | 1152 | |
1177 | &dev_attr_in5_min.attr, | 1153 | FAN_UNIT_ATTRS(3), |
1178 | &dev_attr_in5_max.attr, | 1154 | TEMP_UNIT_ATTRS(3), |
1179 | &dev_attr_in6_input.attr, | 1155 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1180 | &dev_attr_in6_min.attr, | 1156 | |
1181 | &dev_attr_in6_max.attr, | 1157 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
1182 | 1158 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | |
1183 | &dev_attr_fan3_input.attr, | 1159 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
1184 | &dev_attr_fan3_min.attr, | ||
1185 | &dev_attr_fan3_div.attr, | ||
1186 | |||
1187 | &dev_attr_temp3_input.attr, | ||
1188 | &dev_attr_temp3_max.attr, | ||
1189 | &dev_attr_temp3_max_hyst.attr, | ||
1190 | &dev_attr_temp3_type.attr, | ||
1191 | |||
1192 | &dev_attr_pwm3.attr, | ||
1193 | |||
1194 | &dev_attr_pwm1_freq.attr, | ||
1195 | &dev_attr_pwm2_freq.attr, | ||
1196 | &dev_attr_pwm3_freq.attr, | ||
1197 | NULL | 1160 | NULL |
1198 | }; | 1161 | }; |
1199 | 1162 | ||
@@ -1244,6 +1207,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1244 | data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); | 1207 | data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); |
1245 | data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); | 1208 | data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); |
1246 | data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); | 1209 | data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); |
1210 | w83627hf_update_fan_div(data); | ||
1247 | 1211 | ||
1248 | /* Register common device attributes */ | 1212 | /* Register common device attributes */ |
1249 | if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) | 1213 | if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) |
@@ -1251,27 +1215,45 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1251 | 1215 | ||
1252 | /* Register chip-specific device attributes */ | 1216 | /* Register chip-specific device attributes */ |
1253 | if (data->type == w83627hf || data->type == w83697hf) | 1217 | if (data->type == w83627hf || data->type == w83697hf) |
1254 | if ((err = device_create_file(dev, &dev_attr_in5_input)) | 1218 | if ((err = device_create_file(dev, |
1255 | || (err = device_create_file(dev, &dev_attr_in5_min)) | 1219 | &sensor_dev_attr_in5_input.dev_attr)) |
1256 | || (err = device_create_file(dev, &dev_attr_in5_max)) | 1220 | || (err = device_create_file(dev, |
1257 | || (err = device_create_file(dev, &dev_attr_in6_input)) | 1221 | &sensor_dev_attr_in5_min.dev_attr)) |
1258 | || (err = device_create_file(dev, &dev_attr_in6_min)) | 1222 | || (err = device_create_file(dev, |
1259 | || (err = device_create_file(dev, &dev_attr_in6_max)) | 1223 | &sensor_dev_attr_in5_max.dev_attr)) |
1260 | || (err = device_create_file(dev, &dev_attr_pwm1_freq)) | 1224 | || (err = device_create_file(dev, |
1261 | || (err = device_create_file(dev, &dev_attr_pwm2_freq))) | 1225 | &sensor_dev_attr_in6_input.dev_attr)) |
1226 | || (err = device_create_file(dev, | ||
1227 | &sensor_dev_attr_in6_min.dev_attr)) | ||
1228 | || (err = device_create_file(dev, | ||
1229 | &sensor_dev_attr_in6_max.dev_attr)) | ||
1230 | || (err = device_create_file(dev, | ||
1231 | &sensor_dev_attr_pwm1_freq.dev_attr)) | ||
1232 | || (err = device_create_file(dev, | ||
1233 | &sensor_dev_attr_pwm2_freq.dev_attr))) | ||
1262 | goto ERROR4; | 1234 | goto ERROR4; |
1263 | 1235 | ||
1264 | if (data->type != w83697hf) | 1236 | if (data->type != w83697hf) |
1265 | if ((err = device_create_file(dev, &dev_attr_in1_input)) | 1237 | if ((err = device_create_file(dev, |
1266 | || (err = device_create_file(dev, &dev_attr_in1_min)) | 1238 | &sensor_dev_attr_in1_input.dev_attr)) |
1267 | || (err = device_create_file(dev, &dev_attr_in1_max)) | 1239 | || (err = device_create_file(dev, |
1268 | || (err = device_create_file(dev, &dev_attr_fan3_input)) | 1240 | &sensor_dev_attr_in1_min.dev_attr)) |
1269 | || (err = device_create_file(dev, &dev_attr_fan3_min)) | 1241 | || (err = device_create_file(dev, |
1270 | || (err = device_create_file(dev, &dev_attr_fan3_div)) | 1242 | &sensor_dev_attr_in1_max.dev_attr)) |
1271 | || (err = device_create_file(dev, &dev_attr_temp3_input)) | 1243 | || (err = device_create_file(dev, |
1272 | || (err = device_create_file(dev, &dev_attr_temp3_max)) | 1244 | &sensor_dev_attr_fan3_input.dev_attr)) |
1273 | || (err = device_create_file(dev, &dev_attr_temp3_max_hyst)) | 1245 | || (err = device_create_file(dev, |
1274 | || (err = device_create_file(dev, &dev_attr_temp3_type))) | 1246 | &sensor_dev_attr_fan3_min.dev_attr)) |
1247 | || (err = device_create_file(dev, | ||
1248 | &sensor_dev_attr_fan3_div.dev_attr)) | ||
1249 | || (err = device_create_file(dev, | ||
1250 | &sensor_dev_attr_temp3_input.dev_attr)) | ||
1251 | || (err = device_create_file(dev, | ||
1252 | &sensor_dev_attr_temp3_max.dev_attr)) | ||
1253 | || (err = device_create_file(dev, | ||
1254 | &sensor_dev_attr_temp3_max_hyst.dev_attr)) | ||
1255 | || (err = device_create_file(dev, | ||
1256 | &sensor_dev_attr_temp3_type.dev_attr))) | ||
1275 | goto ERROR4; | 1257 | goto ERROR4; |
1276 | 1258 | ||
1277 | if (data->type != w83697hf && data->vid != 0xff) { | 1259 | if (data->type != w83697hf && data->vid != 0xff) { |
@@ -1285,18 +1267,22 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1285 | 1267 | ||
1286 | if (data->type == w83627thf || data->type == w83637hf | 1268 | if (data->type == w83627thf || data->type == w83637hf |
1287 | || data->type == w83687thf) | 1269 | || data->type == w83687thf) |
1288 | if ((err = device_create_file(dev, &dev_attr_pwm3))) | 1270 | if ((err = device_create_file(dev, |
1271 | &sensor_dev_attr_pwm3.dev_attr))) | ||
1289 | goto ERROR4; | 1272 | goto ERROR4; |
1290 | 1273 | ||
1291 | if (data->type == w83637hf || data->type == w83687thf) | 1274 | if (data->type == w83637hf || data->type == w83687thf) |
1292 | if ((err = device_create_file(dev, &dev_attr_pwm1_freq)) | 1275 | if ((err = device_create_file(dev, |
1293 | || (err = device_create_file(dev, &dev_attr_pwm2_freq)) | 1276 | &sensor_dev_attr_pwm1_freq.dev_attr)) |
1294 | || (err = device_create_file(dev, &dev_attr_pwm3_freq))) | 1277 | || (err = device_create_file(dev, |
1278 | &sensor_dev_attr_pwm2_freq.dev_attr)) | ||
1279 | || (err = device_create_file(dev, | ||
1280 | &sensor_dev_attr_pwm3_freq.dev_attr))) | ||
1295 | goto ERROR4; | 1281 | goto ERROR4; |
1296 | 1282 | ||
1297 | data->class_dev = hwmon_device_register(dev); | 1283 | data->hwmon_dev = hwmon_device_register(dev); |
1298 | if (IS_ERR(data->class_dev)) { | 1284 | if (IS_ERR(data->hwmon_dev)) { |
1299 | err = PTR_ERR(data->class_dev); | 1285 | err = PTR_ERR(data->hwmon_dev); |
1300 | goto ERROR4; | 1286 | goto ERROR4; |
1301 | } | 1287 | } |
1302 | 1288 | ||
@@ -1319,7 +1305,7 @@ static int __devexit w83627hf_remove(struct platform_device *pdev) | |||
1319 | struct w83627hf_data *data = platform_get_drvdata(pdev); | 1305 | struct w83627hf_data *data = platform_get_drvdata(pdev); |
1320 | struct resource *res; | 1306 | struct resource *res; |
1321 | 1307 | ||
1322 | hwmon_device_unregister(data->class_dev); | 1308 | hwmon_device_unregister(data->hwmon_dev); |
1323 | 1309 | ||
1324 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); | 1310 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); |
1325 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); | 1311 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); |
@@ -1333,6 +1319,24 @@ static int __devexit w83627hf_remove(struct platform_device *pdev) | |||
1333 | } | 1319 | } |
1334 | 1320 | ||
1335 | 1321 | ||
1322 | /* Registers 0x50-0x5f are banked */ | ||
1323 | static inline void w83627hf_set_bank(struct w83627hf_data *data, u16 reg) | ||
1324 | { | ||
1325 | if ((reg & 0x00f0) == 0x50) { | ||
1326 | outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); | ||
1327 | outb_p(reg >> 8, data->addr + W83781D_DATA_REG_OFFSET); | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | /* Not strictly necessary, but play it safe for now */ | ||
1332 | static inline void w83627hf_reset_bank(struct w83627hf_data *data, u16 reg) | ||
1333 | { | ||
1334 | if (reg & 0xff00) { | ||
1335 | outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); | ||
1336 | outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); | ||
1337 | } | ||
1338 | } | ||
1339 | |||
1336 | static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) | 1340 | static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) |
1337 | { | 1341 | { |
1338 | int res, word_sized; | 1342 | int res, word_sized; |
@@ -1343,12 +1347,7 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) | |||
1343 | && (((reg & 0x00ff) == 0x50) | 1347 | && (((reg & 0x00ff) == 0x50) |
1344 | || ((reg & 0x00ff) == 0x53) | 1348 | || ((reg & 0x00ff) == 0x53) |
1345 | || ((reg & 0x00ff) == 0x55)); | 1349 | || ((reg & 0x00ff) == 0x55)); |
1346 | if (reg & 0xff00) { | 1350 | w83627hf_set_bank(data, reg); |
1347 | outb_p(W83781D_REG_BANK, | ||
1348 | data->addr + W83781D_ADDR_REG_OFFSET); | ||
1349 | outb_p(reg >> 8, | ||
1350 | data->addr + W83781D_DATA_REG_OFFSET); | ||
1351 | } | ||
1352 | outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); | 1351 | outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); |
1353 | res = inb_p(data->addr + W83781D_DATA_REG_OFFSET); | 1352 | res = inb_p(data->addr + W83781D_DATA_REG_OFFSET); |
1354 | if (word_sized) { | 1353 | if (word_sized) { |
@@ -1358,11 +1357,7 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) | |||
1358 | (res << 8) + inb_p(data->addr + | 1357 | (res << 8) + inb_p(data->addr + |
1359 | W83781D_DATA_REG_OFFSET); | 1358 | W83781D_DATA_REG_OFFSET); |
1360 | } | 1359 | } |
1361 | if (reg & 0xff00) { | 1360 | w83627hf_reset_bank(data, reg); |
1362 | outb_p(W83781D_REG_BANK, | ||
1363 | data->addr + W83781D_ADDR_REG_OFFSET); | ||
1364 | outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); | ||
1365 | } | ||
1366 | mutex_unlock(&data->lock); | 1361 | mutex_unlock(&data->lock); |
1367 | return res; | 1362 | return res; |
1368 | } | 1363 | } |
@@ -1433,12 +1428,7 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) | |||
1433 | || ((reg & 0xff00) == 0x200)) | 1428 | || ((reg & 0xff00) == 0x200)) |
1434 | && (((reg & 0x00ff) == 0x53) | 1429 | && (((reg & 0x00ff) == 0x53) |
1435 | || ((reg & 0x00ff) == 0x55)); | 1430 | || ((reg & 0x00ff) == 0x55)); |
1436 | if (reg & 0xff00) { | 1431 | w83627hf_set_bank(data, reg); |
1437 | outb_p(W83781D_REG_BANK, | ||
1438 | data->addr + W83781D_ADDR_REG_OFFSET); | ||
1439 | outb_p(reg >> 8, | ||
1440 | data->addr + W83781D_DATA_REG_OFFSET); | ||
1441 | } | ||
1442 | outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); | 1432 | outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); |
1443 | if (word_sized) { | 1433 | if (word_sized) { |
1444 | outb_p(value >> 8, | 1434 | outb_p(value >> 8, |
@@ -1448,11 +1438,7 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) | |||
1448 | } | 1438 | } |
1449 | outb_p(value & 0xff, | 1439 | outb_p(value & 0xff, |
1450 | data->addr + W83781D_DATA_REG_OFFSET); | 1440 | data->addr + W83781D_DATA_REG_OFFSET); |
1451 | if (reg & 0xff00) { | 1441 | w83627hf_reset_bank(data, reg); |
1452 | outb_p(W83781D_REG_BANK, | ||
1453 | data->addr + W83781D_ADDR_REG_OFFSET); | ||
1454 | outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); | ||
1455 | } | ||
1456 | mutex_unlock(&data->lock); | 1442 | mutex_unlock(&data->lock); |
1457 | return 0; | 1443 | return 0; |
1458 | } | 1444 | } |
@@ -1513,7 +1499,7 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1513 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); | 1499 | tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); |
1514 | for (i = 1; i <= 3; i++) { | 1500 | for (i = 1; i <= 3; i++) { |
1515 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1501 | if (!(tmp & BIT_SCFG1[i - 1])) { |
1516 | data->sens[i - 1] = W83781D_DEFAULT_BETA; | 1502 | data->sens[i - 1] = 4; |
1517 | } else { | 1503 | } else { |
1518 | if (w83627hf_read_value | 1504 | if (w83627hf_read_value |
1519 | (data, | 1505 | (data, |
@@ -1556,6 +1542,24 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1556 | | 0x01); | 1542 | | 0x01); |
1557 | } | 1543 | } |
1558 | 1544 | ||
1545 | static void w83627hf_update_fan_div(struct w83627hf_data *data) | ||
1546 | { | ||
1547 | int reg; | ||
1548 | |||
1549 | reg = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); | ||
1550 | data->fan_div[0] = (reg >> 4) & 0x03; | ||
1551 | data->fan_div[1] = (reg >> 6) & 0x03; | ||
1552 | if (data->type != w83697hf) { | ||
1553 | data->fan_div[2] = (w83627hf_read_value(data, | ||
1554 | W83781D_REG_PIN) >> 6) & 0x03; | ||
1555 | } | ||
1556 | reg = w83627hf_read_value(data, W83781D_REG_VBAT); | ||
1557 | data->fan_div[0] |= (reg >> 3) & 0x04; | ||
1558 | data->fan_div[1] |= (reg >> 4) & 0x04; | ||
1559 | if (data->type != w83697hf) | ||
1560 | data->fan_div[2] |= (reg >> 5) & 0x04; | ||
1561 | } | ||
1562 | |||
1559 | static struct w83627hf_data *w83627hf_update_device(struct device *dev) | 1563 | static struct w83627hf_data *w83627hf_update_device(struct device *dev) |
1560 | { | 1564 | { |
1561 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1565 | struct w83627hf_data *data = dev_get_drvdata(dev); |
@@ -1587,15 +1591,15 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1587 | w83627hf_read_value(data, | 1591 | w83627hf_read_value(data, |
1588 | W83781D_REG_FAN_MIN(i)); | 1592 | W83781D_REG_FAN_MIN(i)); |
1589 | } | 1593 | } |
1590 | for (i = 1; i <= 3; i++) { | 1594 | for (i = 0; i <= 2; i++) { |
1591 | u8 tmp = w83627hf_read_value(data, | 1595 | u8 tmp = w83627hf_read_value(data, |
1592 | W836X7HF_REG_PWM(data->type, i)); | 1596 | W836X7HF_REG_PWM(data->type, i)); |
1593 | /* bits 0-3 are reserved in 627THF */ | 1597 | /* bits 0-3 are reserved in 627THF */ |
1594 | if (data->type == w83627thf) | 1598 | if (data->type == w83627thf) |
1595 | tmp &= 0xf0; | 1599 | tmp &= 0xf0; |
1596 | data->pwm[i - 1] = tmp; | 1600 | data->pwm[i] = tmp; |
1597 | if(i == 2 && | 1601 | if (i == 1 && |
1598 | (data->type == w83627hf || data->type == w83697hf)) | 1602 | (data->type == w83627hf || data->type == w83697hf)) |
1599 | break; | 1603 | break; |
1600 | } | 1604 | } |
1601 | if (data->type == w83627hf) { | 1605 | if (data->type == w83627hf) { |
@@ -1633,18 +1637,8 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1633 | w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3)); | 1637 | w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3)); |
1634 | } | 1638 | } |
1635 | 1639 | ||
1636 | i = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); | 1640 | w83627hf_update_fan_div(data); |
1637 | data->fan_div[0] = (i >> 4) & 0x03; | 1641 | |
1638 | data->fan_div[1] = (i >> 6) & 0x03; | ||
1639 | if (data->type != w83697hf) { | ||
1640 | data->fan_div[2] = (w83627hf_read_value(data, | ||
1641 | W83781D_REG_PIN) >> 6) & 0x03; | ||
1642 | } | ||
1643 | i = w83627hf_read_value(data, W83781D_REG_VBAT); | ||
1644 | data->fan_div[0] |= (i >> 3) & 0x04; | ||
1645 | data->fan_div[1] |= (i >> 4) & 0x04; | ||
1646 | if (data->type != w83697hf) | ||
1647 | data->fan_div[2] |= (i >> 5) & 0x04; | ||
1648 | data->alarms = | 1642 | data->alarms = |
1649 | w83627hf_read_value(data, W83781D_REG_ALARM1) | | 1643 | w83627hf_read_value(data, W83781D_REG_ALARM1) | |
1650 | (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) | | 1644 | (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) | |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index dcc941a5aaff..a6a1edfe7614 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -220,7 +220,7 @@ DIV_TO_REG(long val, enum chips type) | |||
220 | the driver field to differentiate between I2C and ISA chips. */ | 220 | the driver field to differentiate between I2C and ISA chips. */ |
221 | struct w83781d_data { | 221 | struct w83781d_data { |
222 | struct i2c_client client; | 222 | struct i2c_client client; |
223 | struct class_device *class_dev; | 223 | struct device *hwmon_dev; |
224 | struct mutex lock; | 224 | struct mutex lock; |
225 | enum chips type; | 225 | enum chips type; |
226 | 226 | ||
@@ -251,9 +251,7 @@ struct w83781d_data { | |||
251 | u8 pwm2_enable; /* Boolean */ | 251 | u8 pwm2_enable; /* Boolean */ |
252 | u16 sens[3]; /* 782D/783S only. | 252 | u16 sens[3]; /* 782D/783S only. |
253 | 1 = pentium diode; 2 = 3904 diode; | 253 | 1 = pentium diode; 2 = 3904 diode; |
254 | 3000-5000 = thermistor beta. | 254 | 4 = thermistor */ |
255 | Default = 3435. | ||
256 | Other Betas unimplemented */ | ||
257 | u8 vrm; | 255 | u8 vrm; |
258 | }; | 256 | }; |
259 | 257 | ||
@@ -410,7 +408,7 @@ static ssize_t store_temp_##reg (struct device *dev, \ | |||
410 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ | 408 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ |
411 | struct w83781d_data *data = dev_get_drvdata(dev); \ | 409 | struct w83781d_data *data = dev_get_drvdata(dev); \ |
412 | int nr = attr->index; \ | 410 | int nr = attr->index; \ |
413 | s32 val; \ | 411 | long val; \ |
414 | \ | 412 | \ |
415 | val = simple_strtol(buf, NULL, 10); \ | 413 | val = simple_strtol(buf, NULL, 10); \ |
416 | \ | 414 | \ |
@@ -456,7 +454,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
456 | static ssize_t | 454 | static ssize_t |
457 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 455 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
458 | { | 456 | { |
459 | struct w83781d_data *data = w83781d_update_device(dev); | 457 | struct w83781d_data *data = dev_get_drvdata(dev); |
460 | return sprintf(buf, "%ld\n", (long) data->vrm); | 458 | return sprintf(buf, "%ld\n", (long) data->vrm); |
461 | } | 459 | } |
462 | 460 | ||
@@ -483,6 +481,39 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
483 | 481 | ||
484 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 482 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
485 | 483 | ||
484 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
485 | char *buf) | ||
486 | { | ||
487 | struct w83781d_data *data = w83781d_update_device(dev); | ||
488 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
489 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
490 | } | ||
491 | |||
492 | /* The W83781D has a single alarm bit for temp2 and temp3 */ | ||
493 | static ssize_t show_temp3_alarm(struct device *dev, | ||
494 | struct device_attribute *attr, char *buf) | ||
495 | { | ||
496 | struct w83781d_data *data = w83781d_update_device(dev); | ||
497 | int bitnr = (data->type == w83781d) ? 5 : 13; | ||
498 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | ||
499 | } | ||
500 | |||
501 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
502 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
503 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
504 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
505 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
506 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
507 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
508 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16); | ||
509 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17); | ||
510 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
511 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
512 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
513 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
514 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
515 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp3_alarm, NULL, 0); | ||
516 | |||
486 | static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) | 517 | static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) |
487 | { | 518 | { |
488 | struct w83781d_data *data = w83781d_update_device(dev); | 519 | struct w83781d_data *data = w83781d_update_device(dev); |
@@ -546,6 +577,100 @@ static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, | |||
546 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, | 577 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, |
547 | show_beep_enable, store_beep_enable); | 578 | show_beep_enable, store_beep_enable); |
548 | 579 | ||
580 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | ||
581 | char *buf) | ||
582 | { | ||
583 | struct w83781d_data *data = w83781d_update_device(dev); | ||
584 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
585 | return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1); | ||
586 | } | ||
587 | |||
588 | static ssize_t | ||
589 | store_beep(struct device *dev, struct device_attribute *attr, | ||
590 | const char *buf, size_t count) | ||
591 | { | ||
592 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
593 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
594 | unsigned long bit; | ||
595 | u8 reg; | ||
596 | |||
597 | bit = simple_strtoul(buf, NULL, 10); | ||
598 | if (bit & ~1) | ||
599 | return -EINVAL; | ||
600 | |||
601 | mutex_lock(&data->update_lock); | ||
602 | if (bit) | ||
603 | data->beep_mask |= (1 << bitnr); | ||
604 | else | ||
605 | data->beep_mask &= ~(1 << bitnr); | ||
606 | |||
607 | if (bitnr < 8) { | ||
608 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS1); | ||
609 | if (bit) | ||
610 | reg |= (1 << bitnr); | ||
611 | else | ||
612 | reg &= ~(1 << bitnr); | ||
613 | w83781d_write_value(data, W83781D_REG_BEEP_INTS1, reg); | ||
614 | } else if (bitnr < 16) { | ||
615 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); | ||
616 | if (bit) | ||
617 | reg |= (1 << (bitnr - 8)); | ||
618 | else | ||
619 | reg &= ~(1 << (bitnr - 8)); | ||
620 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, reg); | ||
621 | } else { | ||
622 | reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS3); | ||
623 | if (bit) | ||
624 | reg |= (1 << (bitnr - 16)); | ||
625 | else | ||
626 | reg &= ~(1 << (bitnr - 16)); | ||
627 | w83781d_write_value(data, W83781D_REG_BEEP_INTS3, reg); | ||
628 | } | ||
629 | mutex_unlock(&data->update_lock); | ||
630 | |||
631 | return count; | ||
632 | } | ||
633 | |||
634 | /* The W83781D has a single beep bit for temp2 and temp3 */ | ||
635 | static ssize_t show_temp3_beep(struct device *dev, | ||
636 | struct device_attribute *attr, char *buf) | ||
637 | { | ||
638 | struct w83781d_data *data = w83781d_update_device(dev); | ||
639 | int bitnr = (data->type == w83781d) ? 5 : 13; | ||
640 | return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1); | ||
641 | } | ||
642 | |||
643 | static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR, | ||
644 | show_beep, store_beep, 0); | ||
645 | static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR, | ||
646 | show_beep, store_beep, 1); | ||
647 | static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR, | ||
648 | show_beep, store_beep, 2); | ||
649 | static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR, | ||
650 | show_beep, store_beep, 3); | ||
651 | static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR, | ||
652 | show_beep, store_beep, 8); | ||
653 | static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO | S_IWUSR, | ||
654 | show_beep, store_beep, 9); | ||
655 | static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO | S_IWUSR, | ||
656 | show_beep, store_beep, 10); | ||
657 | static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO | S_IWUSR, | ||
658 | show_beep, store_beep, 16); | ||
659 | static SENSOR_DEVICE_ATTR(in8_beep, S_IRUGO | S_IWUSR, | ||
660 | show_beep, store_beep, 17); | ||
661 | static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR, | ||
662 | show_beep, store_beep, 6); | ||
663 | static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR, | ||
664 | show_beep, store_beep, 7); | ||
665 | static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO | S_IWUSR, | ||
666 | show_beep, store_beep, 11); | ||
667 | static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, | ||
668 | show_beep, store_beep, 4); | ||
669 | static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, | ||
670 | show_beep, store_beep, 5); | ||
671 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, | ||
672 | show_temp3_beep, store_beep, 13); | ||
673 | |||
549 | static ssize_t | 674 | static ssize_t |
550 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) | 675 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) |
551 | { | 676 | { |
@@ -721,15 +846,19 @@ store_sensor(struct device *dev, struct device_attribute *da, | |||
721 | tmp & ~BIT_SCFG2[nr]); | 846 | tmp & ~BIT_SCFG2[nr]); |
722 | data->sens[nr] = val; | 847 | data->sens[nr] = val; |
723 | break; | 848 | break; |
724 | case W83781D_DEFAULT_BETA: /* thermistor */ | 849 | case W83781D_DEFAULT_BETA: |
850 | dev_warn(dev, "Sensor type %d is deprecated, please use 4 " | ||
851 | "instead\n", W83781D_DEFAULT_BETA); | ||
852 | /* fall through */ | ||
853 | case 4: /* thermistor */ | ||
725 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); | 854 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
726 | w83781d_write_value(data, W83781D_REG_SCFG1, | 855 | w83781d_write_value(data, W83781D_REG_SCFG1, |
727 | tmp & ~BIT_SCFG1[nr]); | 856 | tmp & ~BIT_SCFG1[nr]); |
728 | data->sens[nr] = val; | 857 | data->sens[nr] = val; |
729 | break; | 858 | break; |
730 | default: | 859 | default: |
731 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", | 860 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or 4\n", |
732 | (long) val, W83781D_DEFAULT_BETA); | 861 | (long) val); |
733 | break; | 862 | break; |
734 | } | 863 | } |
735 | 864 | ||
@@ -875,17 +1004,23 @@ ERROR_SC_0: | |||
875 | #define IN_UNIT_ATTRS(X) \ | 1004 | #define IN_UNIT_ATTRS(X) \ |
876 | &sensor_dev_attr_in##X##_input.dev_attr.attr, \ | 1005 | &sensor_dev_attr_in##X##_input.dev_attr.attr, \ |
877 | &sensor_dev_attr_in##X##_min.dev_attr.attr, \ | 1006 | &sensor_dev_attr_in##X##_min.dev_attr.attr, \ |
878 | &sensor_dev_attr_in##X##_max.dev_attr.attr | 1007 | &sensor_dev_attr_in##X##_max.dev_attr.attr, \ |
1008 | &sensor_dev_attr_in##X##_alarm.dev_attr.attr, \ | ||
1009 | &sensor_dev_attr_in##X##_beep.dev_attr.attr | ||
879 | 1010 | ||
880 | #define FAN_UNIT_ATTRS(X) \ | 1011 | #define FAN_UNIT_ATTRS(X) \ |
881 | &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ | 1012 | &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ |
882 | &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ | 1013 | &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ |
883 | &sensor_dev_attr_fan##X##_div.dev_attr.attr | 1014 | &sensor_dev_attr_fan##X##_div.dev_attr.attr, \ |
1015 | &sensor_dev_attr_fan##X##_alarm.dev_attr.attr, \ | ||
1016 | &sensor_dev_attr_fan##X##_beep.dev_attr.attr | ||
884 | 1017 | ||
885 | #define TEMP_UNIT_ATTRS(X) \ | 1018 | #define TEMP_UNIT_ATTRS(X) \ |
886 | &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ | 1019 | &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ |
887 | &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ | 1020 | &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ |
888 | &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr | 1021 | &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr, \ |
1022 | &sensor_dev_attr_temp##X##_alarm.dev_attr.attr, \ | ||
1023 | &sensor_dev_attr_temp##X##_beep.dev_attr.attr | ||
889 | 1024 | ||
890 | static struct attribute* w83781d_attributes[] = { | 1025 | static struct attribute* w83781d_attributes[] = { |
891 | IN_UNIT_ATTRS(0), | 1026 | IN_UNIT_ATTRS(0), |
@@ -944,7 +1079,11 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
944 | || (err = device_create_file(dev, | 1079 | || (err = device_create_file(dev, |
945 | &sensor_dev_attr_in1_min.dev_attr)) | 1080 | &sensor_dev_attr_in1_min.dev_attr)) |
946 | || (err = device_create_file(dev, | 1081 | || (err = device_create_file(dev, |
947 | &sensor_dev_attr_in1_max.dev_attr))) | 1082 | &sensor_dev_attr_in1_max.dev_attr)) |
1083 | || (err = device_create_file(dev, | ||
1084 | &sensor_dev_attr_in1_alarm.dev_attr)) | ||
1085 | || (err = device_create_file(dev, | ||
1086 | &sensor_dev_attr_in1_beep.dev_attr))) | ||
948 | return err; | 1087 | return err; |
949 | } | 1088 | } |
950 | if (kind != as99127f && kind != w83781d && kind != w83783s) { | 1089 | if (kind != as99127f && kind != w83781d && kind != w83783s) { |
@@ -955,11 +1094,19 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
955 | || (err = device_create_file(dev, | 1094 | || (err = device_create_file(dev, |
956 | &sensor_dev_attr_in7_max.dev_attr)) | 1095 | &sensor_dev_attr_in7_max.dev_attr)) |
957 | || (err = device_create_file(dev, | 1096 | || (err = device_create_file(dev, |
1097 | &sensor_dev_attr_in7_alarm.dev_attr)) | ||
1098 | || (err = device_create_file(dev, | ||
1099 | &sensor_dev_attr_in7_beep.dev_attr)) | ||
1100 | || (err = device_create_file(dev, | ||
958 | &sensor_dev_attr_in8_input.dev_attr)) | 1101 | &sensor_dev_attr_in8_input.dev_attr)) |
959 | || (err = device_create_file(dev, | 1102 | || (err = device_create_file(dev, |
960 | &sensor_dev_attr_in8_min.dev_attr)) | 1103 | &sensor_dev_attr_in8_min.dev_attr)) |
961 | || (err = device_create_file(dev, | 1104 | || (err = device_create_file(dev, |
962 | &sensor_dev_attr_in8_max.dev_attr))) | 1105 | &sensor_dev_attr_in8_max.dev_attr)) |
1106 | || (err = device_create_file(dev, | ||
1107 | &sensor_dev_attr_in8_alarm.dev_attr)) | ||
1108 | || (err = device_create_file(dev, | ||
1109 | &sensor_dev_attr_in8_beep.dev_attr))) | ||
963 | return err; | 1110 | return err; |
964 | } | 1111 | } |
965 | if (kind != w83783s) { | 1112 | if (kind != w83783s) { |
@@ -968,8 +1115,19 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
968 | || (err = device_create_file(dev, | 1115 | || (err = device_create_file(dev, |
969 | &sensor_dev_attr_temp3_max.dev_attr)) | 1116 | &sensor_dev_attr_temp3_max.dev_attr)) |
970 | || (err = device_create_file(dev, | 1117 | || (err = device_create_file(dev, |
971 | &sensor_dev_attr_temp3_max_hyst.dev_attr))) | 1118 | &sensor_dev_attr_temp3_max_hyst.dev_attr)) |
1119 | || (err = device_create_file(dev, | ||
1120 | &sensor_dev_attr_temp3_alarm.dev_attr)) | ||
1121 | || (err = device_create_file(dev, | ||
1122 | &sensor_dev_attr_temp3_beep.dev_attr))) | ||
972 | return err; | 1123 | return err; |
1124 | |||
1125 | if (kind != w83781d) | ||
1126 | err = sysfs_chmod_file(&dev->kobj, | ||
1127 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1128 | S_IRUGO | S_IWUSR); | ||
1129 | if (err) | ||
1130 | return err; | ||
973 | } | 1131 | } |
974 | 1132 | ||
975 | if (kind != w83781d && kind != as99127f) { | 1133 | if (kind != w83781d && kind != as99127f) { |
@@ -1156,9 +1314,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1156 | if (err) | 1314 | if (err) |
1157 | goto ERROR4; | 1315 | goto ERROR4; |
1158 | 1316 | ||
1159 | data->class_dev = hwmon_device_register(dev); | 1317 | data->hwmon_dev = hwmon_device_register(dev); |
1160 | if (IS_ERR(data->class_dev)) { | 1318 | if (IS_ERR(data->hwmon_dev)) { |
1161 | err = PTR_ERR(data->class_dev); | 1319 | err = PTR_ERR(data->hwmon_dev); |
1162 | goto ERROR4; | 1320 | goto ERROR4; |
1163 | } | 1321 | } |
1164 | 1322 | ||
@@ -1192,7 +1350,7 @@ w83781d_detach_client(struct i2c_client *client) | |||
1192 | 1350 | ||
1193 | /* main client */ | 1351 | /* main client */ |
1194 | if (data) { | 1352 | if (data) { |
1195 | hwmon_device_unregister(data->class_dev); | 1353 | hwmon_device_unregister(data->hwmon_dev); |
1196 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); | 1354 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); |
1197 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); | 1355 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); |
1198 | } | 1356 | } |
@@ -1259,9 +1417,9 @@ w83781d_isa_probe(struct platform_device *pdev) | |||
1259 | if (err) | 1417 | if (err) |
1260 | goto exit_remove_files; | 1418 | goto exit_remove_files; |
1261 | 1419 | ||
1262 | data->class_dev = hwmon_device_register(&pdev->dev); | 1420 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1263 | if (IS_ERR(data->class_dev)) { | 1421 | if (IS_ERR(data->hwmon_dev)) { |
1264 | err = PTR_ERR(data->class_dev); | 1422 | err = PTR_ERR(data->hwmon_dev); |
1265 | goto exit_remove_files; | 1423 | goto exit_remove_files; |
1266 | } | 1424 | } |
1267 | 1425 | ||
@@ -1283,7 +1441,7 @@ w83781d_isa_remove(struct platform_device *pdev) | |||
1283 | { | 1441 | { |
1284 | struct w83781d_data *data = platform_get_drvdata(pdev); | 1442 | struct w83781d_data *data = platform_get_drvdata(pdev); |
1285 | 1443 | ||
1286 | hwmon_device_unregister(data->class_dev); | 1444 | hwmon_device_unregister(data->hwmon_dev); |
1287 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | 1445 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); |
1288 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | 1446 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); |
1289 | device_remove_file(&pdev->dev, &dev_attr_name); | 1447 | device_remove_file(&pdev->dev, &dev_attr_name); |
@@ -1485,7 +1643,7 @@ w83781d_init_device(struct device *dev) | |||
1485 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); | 1643 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
1486 | for (i = 1; i <= 3; i++) { | 1644 | for (i = 1; i <= 3; i++) { |
1487 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1645 | if (!(tmp & BIT_SCFG1[i - 1])) { |
1488 | data->sens[i - 1] = W83781D_DEFAULT_BETA; | 1646 | data->sens[i - 1] = 4; |
1489 | } else { | 1647 | } else { |
1490 | if (w83781d_read_value | 1648 | if (w83781d_read_value |
1491 | (data, | 1649 | (data, |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 9e5f885368b4..b6f2ebf9f9cf 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -2,7 +2,7 @@ | |||
2 | w83791d.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | w83791d.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | 4 | ||
5 | Copyright (C) 2006 Charles Spirakis <bezaur@gmail.com> | 5 | Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com> |
6 | 6 | ||
7 | This program is free software; you can redistribute it and/or modify | 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 | 8 | it under the terms of the GNU General Public License as published by |
@@ -247,7 +247,7 @@ static u8 div_to_reg(int nr, long val) | |||
247 | 247 | ||
248 | struct w83791d_data { | 248 | struct w83791d_data { |
249 | struct i2c_client client; | 249 | struct i2c_client client; |
250 | struct class_device *class_dev; | 250 | struct device *hwmon_dev; |
251 | struct mutex update_lock; | 251 | struct mutex update_lock; |
252 | 252 | ||
253 | char valid; /* !=0 if following fields are valid */ | 253 | char valid; /* !=0 if following fields are valid */ |
@@ -384,6 +384,85 @@ static struct sensor_device_attribute sda_in_max[] = { | |||
384 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), | 384 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), |
385 | }; | 385 | }; |
386 | 386 | ||
387 | |||
388 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | ||
389 | char *buf) | ||
390 | { | ||
391 | struct sensor_device_attribute *sensor_attr = | ||
392 | to_sensor_dev_attr(attr); | ||
393 | struct w83791d_data *data = w83791d_update_device(dev); | ||
394 | int bitnr = sensor_attr->index; | ||
395 | |||
396 | return sprintf(buf, "%d\n", (data->beep_mask >> bitnr) & 1); | ||
397 | } | ||
398 | |||
399 | static ssize_t store_beep(struct device *dev, struct device_attribute *attr, | ||
400 | const char *buf, size_t count) | ||
401 | { | ||
402 | struct sensor_device_attribute *sensor_attr = | ||
403 | to_sensor_dev_attr(attr); | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
406 | int bitnr = sensor_attr->index; | ||
407 | int bytenr = bitnr / 8; | ||
408 | long val = simple_strtol(buf, NULL, 10) ? 1 : 0; | ||
409 | |||
410 | mutex_lock(&data->update_lock); | ||
411 | |||
412 | data->beep_mask &= ~(0xff << (bytenr * 8)); | ||
413 | data->beep_mask |= w83791d_read(client, W83791D_REG_BEEP_CTRL[bytenr]) | ||
414 | << (bytenr * 8); | ||
415 | |||
416 | data->beep_mask &= ~(1 << bitnr); | ||
417 | data->beep_mask |= val << bitnr; | ||
418 | |||
419 | w83791d_write(client, W83791D_REG_BEEP_CTRL[bytenr], | ||
420 | (data->beep_mask >> (bytenr * 8)) & 0xff); | ||
421 | |||
422 | mutex_unlock(&data->update_lock); | ||
423 | |||
424 | return count; | ||
425 | } | ||
426 | |||
427 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
428 | char *buf) | ||
429 | { | ||
430 | struct sensor_device_attribute *sensor_attr = | ||
431 | to_sensor_dev_attr(attr); | ||
432 | struct w83791d_data *data = w83791d_update_device(dev); | ||
433 | int bitnr = sensor_attr->index; | ||
434 | |||
435 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | ||
436 | } | ||
437 | |||
438 | /* Note: The bitmask for the beep enable/disable is different than | ||
439 | the bitmask for the alarm. */ | ||
440 | static struct sensor_device_attribute sda_in_beep[] = { | ||
441 | SENSOR_ATTR(in0_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 0), | ||
442 | SENSOR_ATTR(in1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 13), | ||
443 | SENSOR_ATTR(in2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 2), | ||
444 | SENSOR_ATTR(in3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 3), | ||
445 | SENSOR_ATTR(in4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 8), | ||
446 | SENSOR_ATTR(in5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 9), | ||
447 | SENSOR_ATTR(in6_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 10), | ||
448 | SENSOR_ATTR(in7_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 16), | ||
449 | SENSOR_ATTR(in8_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 17), | ||
450 | SENSOR_ATTR(in9_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 14), | ||
451 | }; | ||
452 | |||
453 | static struct sensor_device_attribute sda_in_alarm[] = { | ||
454 | SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), | ||
455 | SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), | ||
456 | SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), | ||
457 | SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), | ||
458 | SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), | ||
459 | SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9), | ||
460 | SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10), | ||
461 | SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 19), | ||
462 | SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20), | ||
463 | SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 14), | ||
464 | }; | ||
465 | |||
387 | #define show_fan_reg(reg) \ | 466 | #define show_fan_reg(reg) \ |
388 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ | 467 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ |
389 | char *buf) \ | 468 | char *buf) \ |
@@ -536,6 +615,22 @@ static struct sensor_device_attribute sda_fan_div[] = { | |||
536 | show_fan_div, store_fan_div, 4), | 615 | show_fan_div, store_fan_div, 4), |
537 | }; | 616 | }; |
538 | 617 | ||
618 | static struct sensor_device_attribute sda_fan_beep[] = { | ||
619 | SENSOR_ATTR(fan1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 6), | ||
620 | SENSOR_ATTR(fan2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 7), | ||
621 | SENSOR_ATTR(fan3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 11), | ||
622 | SENSOR_ATTR(fan4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 21), | ||
623 | SENSOR_ATTR(fan5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 22), | ||
624 | }; | ||
625 | |||
626 | static struct sensor_device_attribute sda_fan_alarm[] = { | ||
627 | SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), | ||
628 | SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), | ||
629 | SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11), | ||
630 | SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21), | ||
631 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), | ||
632 | }; | ||
633 | |||
539 | /* read/write the temperature1, includes measured value and limits */ | 634 | /* read/write the temperature1, includes measured value and limits */ |
540 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, | 635 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, |
541 | char *buf) | 636 | char *buf) |
@@ -618,6 +713,19 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { | |||
618 | show_temp23, store_temp23, 1, 2), | 713 | show_temp23, store_temp23, 1, 2), |
619 | }; | 714 | }; |
620 | 715 | ||
716 | /* Note: The bitmask for the beep enable/disable is different than | ||
717 | the bitmask for the alarm. */ | ||
718 | static struct sensor_device_attribute sda_temp_beep[] = { | ||
719 | SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4), | ||
720 | SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5), | ||
721 | SENSOR_ATTR(temp3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 1), | ||
722 | }; | ||
723 | |||
724 | static struct sensor_device_attribute sda_temp_alarm[] = { | ||
725 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), | ||
726 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), | ||
727 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), | ||
728 | }; | ||
621 | 729 | ||
622 | /* get reatime status of all sensors items: voltage, temp, fan */ | 730 | /* get reatime status of all sensors items: voltage, temp, fan */ |
623 | static ssize_t show_alarms_reg(struct device *dev, | 731 | static ssize_t show_alarms_reg(struct device *dev, |
@@ -724,7 +832,7 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | |||
724 | static ssize_t show_vrm_reg(struct device *dev, | 832 | static ssize_t show_vrm_reg(struct device *dev, |
725 | struct device_attribute *attr, char *buf) | 833 | struct device_attribute *attr, char *buf) |
726 | { | 834 | { |
727 | struct w83791d_data *data = w83791d_update_device(dev); | 835 | struct w83791d_data *data = dev_get_drvdata(dev); |
728 | return sprintf(buf, "%d\n", data->vrm); | 836 | return sprintf(buf, "%d\n", data->vrm); |
729 | } | 837 | } |
730 | 838 | ||
@@ -749,17 +857,23 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | |||
749 | #define IN_UNIT_ATTRS(X) \ | 857 | #define IN_UNIT_ATTRS(X) \ |
750 | &sda_in_input[X].dev_attr.attr, \ | 858 | &sda_in_input[X].dev_attr.attr, \ |
751 | &sda_in_min[X].dev_attr.attr, \ | 859 | &sda_in_min[X].dev_attr.attr, \ |
752 | &sda_in_max[X].dev_attr.attr | 860 | &sda_in_max[X].dev_attr.attr, \ |
861 | &sda_in_beep[X].dev_attr.attr, \ | ||
862 | &sda_in_alarm[X].dev_attr.attr | ||
753 | 863 | ||
754 | #define FAN_UNIT_ATTRS(X) \ | 864 | #define FAN_UNIT_ATTRS(X) \ |
755 | &sda_fan_input[X].dev_attr.attr, \ | 865 | &sda_fan_input[X].dev_attr.attr, \ |
756 | &sda_fan_min[X].dev_attr.attr, \ | 866 | &sda_fan_min[X].dev_attr.attr, \ |
757 | &sda_fan_div[X].dev_attr.attr | 867 | &sda_fan_div[X].dev_attr.attr, \ |
868 | &sda_fan_beep[X].dev_attr.attr, \ | ||
869 | &sda_fan_alarm[X].dev_attr.attr | ||
758 | 870 | ||
759 | #define TEMP_UNIT_ATTRS(X) \ | 871 | #define TEMP_UNIT_ATTRS(X) \ |
760 | &sda_temp_input[X].dev_attr.attr, \ | 872 | &sda_temp_input[X].dev_attr.attr, \ |
761 | &sda_temp_max[X].dev_attr.attr, \ | 873 | &sda_temp_max[X].dev_attr.attr, \ |
762 | &sda_temp_max_hyst[X].dev_attr.attr | 874 | &sda_temp_max_hyst[X].dev_attr.attr, \ |
875 | &sda_temp_beep[X].dev_attr.attr, \ | ||
876 | &sda_temp_alarm[X].dev_attr.attr | ||
763 | 877 | ||
764 | static struct attribute *w83791d_attributes[] = { | 878 | static struct attribute *w83791d_attributes[] = { |
765 | IN_UNIT_ATTRS(0), | 879 | IN_UNIT_ATTRS(0), |
@@ -1017,9 +1131,9 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1017 | goto error3; | 1131 | goto error3; |
1018 | 1132 | ||
1019 | /* Everything is ready, now register the working device */ | 1133 | /* Everything is ready, now register the working device */ |
1020 | data->class_dev = hwmon_device_register(dev); | 1134 | data->hwmon_dev = hwmon_device_register(dev); |
1021 | if (IS_ERR(data->class_dev)) { | 1135 | if (IS_ERR(data->hwmon_dev)) { |
1022 | err = PTR_ERR(data->class_dev); | 1136 | err = PTR_ERR(data->hwmon_dev); |
1023 | goto error4; | 1137 | goto error4; |
1024 | } | 1138 | } |
1025 | 1139 | ||
@@ -1051,7 +1165,7 @@ static int w83791d_detach_client(struct i2c_client *client) | |||
1051 | 1165 | ||
1052 | /* main client */ | 1166 | /* main client */ |
1053 | if (data) { | 1167 | if (data) { |
1054 | hwmon_device_unregister(data->class_dev); | 1168 | hwmon_device_unregister(data->hwmon_dev); |
1055 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); | 1169 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); |
1056 | } | 1170 | } |
1057 | 1171 | ||
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b0fa296740d1..f836198b705c 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -267,7 +267,7 @@ DIV_TO_REG(long val) | |||
267 | 267 | ||
268 | struct w83792d_data { | 268 | struct w83792d_data { |
269 | struct i2c_client client; | 269 | struct i2c_client client; |
270 | struct class_device *class_dev; | 270 | struct device *hwmon_dev; |
271 | enum chips type; | 271 | enum chips type; |
272 | 272 | ||
273 | struct mutex update_lock; | 273 | struct mutex update_lock; |
@@ -540,6 +540,15 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
540 | return sprintf(buf, "%d\n", data->alarms); | 540 | return sprintf(buf, "%d\n", data->alarms); |
541 | } | 541 | } |
542 | 542 | ||
543 | static ssize_t show_alarm(struct device *dev, | ||
544 | struct device_attribute *attr, char *buf) | ||
545 | { | ||
546 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
547 | int nr = sensor_attr->index; | ||
548 | struct w83792d_data *data = w83792d_update_device(dev); | ||
549 | return sprintf(buf, "%d\n", (data->alarms >> nr) & 1); | ||
550 | } | ||
551 | |||
543 | static ssize_t | 552 | static ssize_t |
544 | show_pwm(struct device *dev, struct device_attribute *attr, | 553 | show_pwm(struct device *dev, struct device_attribute *attr, |
545 | char *buf) | 554 | char *buf) |
@@ -1015,6 +1024,25 @@ static SENSOR_DEVICE_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, | |||
1015 | static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, | 1024 | static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, |
1016 | show_temp23, store_temp23, 1, 4); | 1025 | show_temp23, store_temp23, 1, 4); |
1017 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); | 1026 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); |
1027 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
1028 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
1029 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
1030 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
1031 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
1032 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
1033 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
1034 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
1035 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 8); | ||
1036 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
1037 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 10); | ||
1038 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
1039 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
1040 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, 15); | ||
1041 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 19); | ||
1042 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20); | ||
1043 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21); | ||
1044 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22); | ||
1045 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23); | ||
1018 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); | 1046 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); |
1019 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, | 1047 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, |
1020 | show_chassis_clear, store_chassis_clear); | 1048 | show_chassis_clear, store_chassis_clear); |
@@ -1123,26 +1151,30 @@ static SENSOR_DEVICE_ATTR(fan6_div, S_IWUSR | S_IRUGO, | |||
1123 | static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO, | 1151 | static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO, |
1124 | show_fan_div, store_fan_div, 7); | 1152 | show_fan_div, store_fan_div, 7); |
1125 | 1153 | ||
1126 | static struct attribute *w83792d_attributes_fan[4][4] = { | 1154 | static struct attribute *w83792d_attributes_fan[4][5] = { |
1127 | { | 1155 | { |
1128 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 1156 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1129 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 1157 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1130 | &sensor_dev_attr_fan4_div.dev_attr.attr, | 1158 | &sensor_dev_attr_fan4_div.dev_attr.attr, |
1159 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | ||
1131 | NULL | 1160 | NULL |
1132 | }, { | 1161 | }, { |
1133 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 1162 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
1134 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 1163 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1135 | &sensor_dev_attr_fan5_div.dev_attr.attr, | 1164 | &sensor_dev_attr_fan5_div.dev_attr.attr, |
1165 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | ||
1136 | NULL | 1166 | NULL |
1137 | }, { | 1167 | }, { |
1138 | &sensor_dev_attr_fan6_input.dev_attr.attr, | 1168 | &sensor_dev_attr_fan6_input.dev_attr.attr, |
1139 | &sensor_dev_attr_fan6_min.dev_attr.attr, | 1169 | &sensor_dev_attr_fan6_min.dev_attr.attr, |
1140 | &sensor_dev_attr_fan6_div.dev_attr.attr, | 1170 | &sensor_dev_attr_fan6_div.dev_attr.attr, |
1171 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
1141 | NULL | 1172 | NULL |
1142 | }, { | 1173 | }, { |
1143 | &sensor_dev_attr_fan7_input.dev_attr.attr, | 1174 | &sensor_dev_attr_fan7_input.dev_attr.attr, |
1144 | &sensor_dev_attr_fan7_min.dev_attr.attr, | 1175 | &sensor_dev_attr_fan7_min.dev_attr.attr, |
1145 | &sensor_dev_attr_fan7_div.dev_attr.attr, | 1176 | &sensor_dev_attr_fan7_div.dev_attr.attr, |
1177 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, | ||
1146 | NULL | 1178 | NULL |
1147 | } | 1179 | } |
1148 | }; | 1180 | }; |
@@ -1182,6 +1214,15 @@ static struct attribute *w83792d_attributes[] = { | |||
1182 | &sensor_dev_attr_in8_input.dev_attr.attr, | 1214 | &sensor_dev_attr_in8_input.dev_attr.attr, |
1183 | &sensor_dev_attr_in8_max.dev_attr.attr, | 1215 | &sensor_dev_attr_in8_max.dev_attr.attr, |
1184 | &sensor_dev_attr_in8_min.dev_attr.attr, | 1216 | &sensor_dev_attr_in8_min.dev_attr.attr, |
1217 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
1218 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
1219 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
1220 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1221 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1222 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1223 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1224 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1225 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
1185 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 1226 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1186 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 1227 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
1187 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 1228 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
@@ -1191,6 +1232,9 @@ static struct attribute *w83792d_attributes[] = { | |||
1191 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 1232 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
1192 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 1233 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
1193 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 1234 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
1235 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1237 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1194 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1238 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1195 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 1239 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
1196 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1240 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
@@ -1233,12 +1277,15 @@ static struct attribute *w83792d_attributes[] = { | |||
1233 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 1277 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1234 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 1278 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1235 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 1279 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
1280 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 1281 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1237 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 1282 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1238 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 1283 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
1284 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
1239 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 1285 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1240 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 1286 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1241 | &sensor_dev_attr_fan3_div.dev_attr.attr, | 1287 | &sensor_dev_attr_fan3_div.dev_attr.attr, |
1288 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
1242 | NULL | 1289 | NULL |
1243 | }; | 1290 | }; |
1244 | 1291 | ||
@@ -1396,9 +1443,9 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1396 | &w83792d_group_fan[3]))) | 1443 | &w83792d_group_fan[3]))) |
1397 | goto exit_remove_files; | 1444 | goto exit_remove_files; |
1398 | 1445 | ||
1399 | data->class_dev = hwmon_device_register(dev); | 1446 | data->hwmon_dev = hwmon_device_register(dev); |
1400 | if (IS_ERR(data->class_dev)) { | 1447 | if (IS_ERR(data->hwmon_dev)) { |
1401 | err = PTR_ERR(data->class_dev); | 1448 | err = PTR_ERR(data->hwmon_dev); |
1402 | goto exit_remove_files; | 1449 | goto exit_remove_files; |
1403 | } | 1450 | } |
1404 | 1451 | ||
@@ -1433,7 +1480,7 @@ w83792d_detach_client(struct i2c_client *client) | |||
1433 | 1480 | ||
1434 | /* main client */ | 1481 | /* main client */ |
1435 | if (data) { | 1482 | if (data) { |
1436 | hwmon_device_unregister(data->class_dev); | 1483 | hwmon_device_unregister(data->hwmon_dev); |
1437 | sysfs_remove_group(&client->dev.kobj, &w83792d_group); | 1484 | sysfs_remove_group(&client->dev.kobj, &w83792d_group); |
1438 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) | 1485 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) |
1439 | sysfs_remove_group(&client->dev.kobj, | 1486 | sysfs_remove_group(&client->dev.kobj, |
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 253ffaf1568a..48599e1cc554 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -179,7 +179,7 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) | |||
179 | struct w83793_data { | 179 | struct w83793_data { |
180 | struct i2c_client client; | 180 | struct i2c_client client; |
181 | struct i2c_client *lm75[2]; | 181 | struct i2c_client *lm75[2]; |
182 | struct class_device *class_dev; | 182 | struct device *hwmon_dev; |
183 | struct mutex update_lock; | 183 | struct mutex update_lock; |
184 | char valid; /* !=0 if following fields are valid */ | 184 | char valid; /* !=0 if following fields are valid */ |
185 | unsigned long last_updated; /* In jiffies */ | 185 | unsigned long last_updated; /* In jiffies */ |
@@ -1075,7 +1075,7 @@ static int w83793_detach_client(struct i2c_client *client) | |||
1075 | 1075 | ||
1076 | /* main client */ | 1076 | /* main client */ |
1077 | if (data) { | 1077 | if (data) { |
1078 | hwmon_device_unregister(data->class_dev); | 1078 | hwmon_device_unregister(data->hwmon_dev); |
1079 | 1079 | ||
1080 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) | 1080 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) |
1081 | device_remove_file(dev, | 1081 | device_remove_file(dev, |
@@ -1434,9 +1434,9 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1434 | } | 1434 | } |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | data->class_dev = hwmon_device_register(dev); | 1437 | data->hwmon_dev = hwmon_device_register(dev); |
1438 | if (IS_ERR(data->class_dev)) { | 1438 | if (IS_ERR(data->hwmon_dev)) { |
1439 | err = PTR_ERR(data->class_dev); | 1439 | err = PTR_ERR(data->hwmon_dev); |
1440 | goto exit_remove; | 1440 | goto exit_remove; |
1441 | } | 1441 | } |
1442 | 1442 | ||
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index a3fcace412f0..b5db354e2f19 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c | |||
@@ -107,7 +107,7 @@ static struct i2c_driver w83l785ts_driver = { | |||
107 | 107 | ||
108 | struct w83l785ts_data { | 108 | struct w83l785ts_data { |
109 | struct i2c_client client; | 109 | struct i2c_client client; |
110 | struct class_device *class_dev; | 110 | struct device *hwmon_dev; |
111 | struct mutex update_lock; | 111 | struct mutex update_lock; |
112 | char valid; /* zero until following fields are valid */ | 112 | char valid; /* zero until following fields are valid */ |
113 | unsigned long last_updated; /* in jiffies */ | 113 | unsigned long last_updated; /* in jiffies */ |
@@ -247,9 +247,9 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) | |||
247 | goto exit_remove; | 247 | goto exit_remove; |
248 | 248 | ||
249 | /* Register sysfs hooks */ | 249 | /* Register sysfs hooks */ |
250 | data->class_dev = hwmon_device_register(&new_client->dev); | 250 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
251 | if (IS_ERR(data->class_dev)) { | 251 | if (IS_ERR(data->hwmon_dev)) { |
252 | err = PTR_ERR(data->class_dev); | 252 | err = PTR_ERR(data->hwmon_dev); |
253 | goto exit_remove; | 253 | goto exit_remove; |
254 | } | 254 | } |
255 | 255 | ||
@@ -272,7 +272,7 @@ static int w83l785ts_detach_client(struct i2c_client *client) | |||
272 | struct w83l785ts_data *data = i2c_get_clientdata(client); | 272 | struct w83l785ts_data *data = i2c_get_clientdata(client); |
273 | int err; | 273 | int err; |
274 | 274 | ||
275 | hwmon_device_unregister(data->class_dev); | 275 | hwmon_device_unregister(data->hwmon_dev); |
276 | device_remove_file(&client->dev, | 276 | device_remove_file(&client->dev, |
277 | &sensor_dev_attr_temp1_input.dev_attr); | 277 | &sensor_dev_attr_temp1_input.dev_attr); |
278 | device_remove_file(&client->dev, | 278 | device_remove_file(&client->dev, |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 96581d08774f..51ae4fb7d123 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -83,7 +83,7 @@ struct ads7846 { | |||
83 | 83 | ||
84 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 84 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
85 | struct attribute_group *attr_group; | 85 | struct attribute_group *attr_group; |
86 | struct class_device *hwmon; | 86 | struct device *hwmon; |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | u16 model; | 89 | u16 model; |
@@ -369,7 +369,7 @@ static struct attribute_group ads7845_attr_group = { | |||
369 | 369 | ||
370 | static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) | 370 | static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) |
371 | { | 371 | { |
372 | struct class_device *hwmon; | 372 | struct device *hwmon; |
373 | int err; | 373 | int err; |
374 | 374 | ||
375 | /* hwmon sensors need a reference voltage */ | 375 | /* hwmon sensors need a reference voltage */ |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 6c0b2f0a51ab..216948dd71a5 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -517,7 +517,7 @@ static char *next_cmd(char **cmds) | |||
517 | ****************************************************************************/ | 517 | ****************************************************************************/ |
518 | 518 | ||
519 | static struct platform_device *tpacpi_pdev; | 519 | static struct platform_device *tpacpi_pdev; |
520 | static struct class_device *tpacpi_hwmon; | 520 | static struct device *tpacpi_hwmon; |
521 | static struct input_dev *tpacpi_inputdev; | 521 | static struct input_dev *tpacpi_inputdev; |
522 | 522 | ||
523 | 523 | ||
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 082a1cbc16c0..acd5835ec889 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -171,7 +171,7 @@ static int parse_strtoul(const char *buf, unsigned long max, | |||
171 | 171 | ||
172 | /* Device model */ | 172 | /* Device model */ |
173 | static struct platform_device *tpacpi_pdev; | 173 | static struct platform_device *tpacpi_pdev; |
174 | static struct class_device *tpacpi_hwmon; | 174 | static struct device *tpacpi_hwmon; |
175 | static struct platform_driver tpacpi_pdriver; | 175 | static struct platform_driver tpacpi_pdriver; |
176 | static struct input_dev *tpacpi_inputdev; | 176 | static struct input_dev *tpacpi_inputdev; |
177 | static int tpacpi_create_driver_attributes(struct device_driver *drv); | 177 | static int tpacpi_create_driver_attributes(struct device_driver *drv); |
diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 0efd994c37f1..6b6ee702b007 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h | |||
@@ -16,9 +16,9 @@ | |||
16 | 16 | ||
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | 18 | ||
19 | struct class_device *hwmon_device_register(struct device *dev); | 19 | struct device *hwmon_device_register(struct device *dev); |
20 | 20 | ||
21 | void hwmon_device_unregister(struct class_device *cdev); | 21 | void hwmon_device_unregister(struct device *dev); |
22 | 22 | ||
23 | /* Scale user input to sensible values */ | 23 | /* Scale user input to sensible values */ |
24 | static inline int SENSORS_LIMIT(long value, long low, long high) | 24 | static inline int SENSORS_LIMIT(long value, long low, long high) |