diff options
57 files changed, 8809 insertions, 1721 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a9941544ed8e..a5cb7839a679 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -164,15 +164,6 @@ Who: Kay Sievers <kay.sievers@suse.de> | |||
164 | 164 | ||
165 | --------------------------- | 165 | --------------------------- |
166 | 166 | ||
167 | What: i2c-isa | ||
168 | When: December 2006 | ||
169 | Why: i2c-isa is a non-sense and doesn't fit in the device driver | ||
170 | model. Drivers relying on it are better implemented as platform | ||
171 | drivers. | ||
172 | Who: Jean Delvare <khali@linux-fr.org> | ||
173 | |||
174 | --------------------------- | ||
175 | |||
176 | What: i2c_adapter.list | 167 | What: i2c_adapter.list |
177 | When: July 2007 | 168 | When: July 2007 |
178 | Why: Superfluous, this list duplicates the one maintained by the driver | 169 | Why: Superfluous, this list duplicates the one maintained by the driver |
diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru index b2c0d61b39a2..87ffa0f5ec70 100644 --- a/Documentation/hwmon/abituguru +++ b/Documentation/hwmon/abituguru | |||
@@ -2,7 +2,7 @@ Kernel driver abituguru | |||
2 | ======================= | 2 | ======================= |
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * Abit uGuru revision 1-3 (Hardware Monitor part only) | 5 | * Abit uGuru revision 1 & 2 (Hardware Monitor part only) |
6 | Prefix: 'abituguru' | 6 | Prefix: 'abituguru' |
7 | Addresses scanned: ISA 0x0E0 | 7 | Addresses scanned: ISA 0x0E0 |
8 | Datasheet: Not available, this driver is based on reverse engineering. | 8 | Datasheet: Not available, this driver is based on reverse engineering. |
@@ -20,8 +20,8 @@ Supported chips: | |||
20 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) | 20 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) |
21 | uGuru 2.2.0.0 ~ 2.2.0.6 (AA8 Fatal1ty) | 21 | uGuru 2.2.0.0 ~ 2.2.0.6 (AA8 Fatal1ty) |
22 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) | 22 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) |
23 | uGuru 3.0.0.0 ~ 3.0.1.2 (AW8, AL8, NI8) | 23 | uGuru 3.0.0.0 ~ 3.0.x.x (AW8, AL8, AT8, NI8 SLI, AT8 32X, AN8 32X, |
24 | uGuru 4.xxxxx? (AT8 32X) (2) | 24 | AW9D-MAX) (2) |
25 | 1) For revisions 2 and 3 uGuru's the driver can autodetect the | 25 | 1) For revisions 2 and 3 uGuru's the driver can autodetect the |
26 | sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's | 26 | sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's |
27 | this doesnot always work. For these uGuru's the autodection can | 27 | this doesnot always work. For these uGuru's the autodection can |
@@ -30,8 +30,9 @@ Supported chips: | |||
30 | bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 | 30 | bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 |
31 | You may also need to specify the fan_sensors option for these boards | 31 | You may also need to specify the fan_sensors option for these boards |
32 | fan_sensors=5 | 32 | fan_sensors=5 |
33 | 2) The current version of the abituguru driver is known to NOT work | 33 | 2) There is a seperate abituguru3 driver for these motherboards, |
34 | on these Motherboards | 34 | the abituguru (without the 3 !) driver will not work on these |
35 | motherboards (and visa versa)! | ||
35 | 36 | ||
36 | Authors: | 37 | Authors: |
37 | Hans de Goede <j.w.r.degoede@hhs.nl>, | 38 | Hans de Goede <j.w.r.degoede@hhs.nl>, |
@@ -43,8 +44,10 @@ Module Parameters | |||
43 | ----------------- | 44 | ----------------- |
44 | 45 | ||
45 | * force: bool Force detection. Note this parameter only causes the | 46 | * force: bool Force detection. Note this parameter only causes the |
46 | detection to be skipped, if the uGuru can't be read | 47 | detection to be skipped, and thus the insmod to |
47 | the module initialization (insmod) will still fail. | 48 | succeed. If the uGuru can't be read the actual hwmon |
49 | driver will not load and thus no hwmon device will get | ||
50 | registered. | ||
48 | * bank1_types: int[] Bank1 sensortype autodetection override: | 51 | * bank1_types: int[] Bank1 sensortype autodetection override: |
49 | -1 autodetect (default) | 52 | -1 autodetect (default) |
50 | 0 volt sensor | 53 | 0 volt sensor |
@@ -69,13 +72,15 @@ dmesg | grep abituguru | |||
69 | Description | 72 | Description |
70 | ----------- | 73 | ----------- |
71 | 74 | ||
72 | This driver supports the hardware monitoring features of the Abit uGuru chip | 75 | This driver supports the hardware monitoring features of the first and |
73 | found on Abit uGuru featuring motherboards (most modern Abit motherboards). | 76 | second revision of the Abit uGuru chip found on Abit uGuru featuring |
77 | motherboards (most modern Abit motherboards). | ||
74 | 78 | ||
75 | The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit | 79 | The first and second revision of the uGuru chip in reality is a Winbond |
76 | claiming it is "a new microprocessor designed by the ABIT Engineers"). | 80 | W83L950D in disguise (despite Abit claiming it is "a new microprocessor |
77 | Unfortunatly this doesn't help since the W83L950D is a generic | 81 | designed by the ABIT Engineers"). Unfortunatly this doesn't help since the |
78 | microcontroller with a custom Abit application running on it. | 82 | W83L950D is a generic microcontroller with a custom Abit application running |
83 | on it. | ||
79 | 84 | ||
80 | Despite Abit not releasing any information regarding the uGuru, Olle | 85 | Despite Abit not releasing any information regarding the uGuru, Olle |
81 | Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part | 86 | Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part |
diff --git a/Documentation/hwmon/abituguru3 b/Documentation/hwmon/abituguru3 new file mode 100644 index 000000000000..fa598aac22fa --- /dev/null +++ b/Documentation/hwmon/abituguru3 | |||
@@ -0,0 +1,65 @@ | |||
1 | Kernel driver abituguru3 | ||
2 | ======================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Abit uGuru revision 3 (Hardware Monitor part, reading only) | ||
6 | Prefix: 'abituguru3' | ||
7 | Addresses scanned: ISA 0x0E0 | ||
8 | Datasheet: Not available, this driver is based on reverse engineering. | ||
9 | Note: | ||
10 | The uGuru is a microcontroller with onboard firmware which programs | ||
11 | it to behave as a hwmon IC. There are many different revisions of the | ||
12 | firmware and thus effectivly many different revisions of the uGuru. | ||
13 | Below is an incomplete list with which revisions are used for which | ||
14 | Motherboards: | ||
15 | uGuru 1.00 ~ 1.24 (AI7, KV8-MAX3, AN7) | ||
16 | uGuru 2.0.0.0 ~ 2.0.4.2 (KV8-PRO) | ||
17 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) | ||
18 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) | ||
19 | uGuru 3.0.0.0 ~ 3.0.x.x (AW8, AL8, AT8, NI8 SLI, AT8 32X, AN8 32X, | ||
20 | AW9D-MAX) | ||
21 | The abituguru3 driver is only for revison 3.0.x.x motherboards, | ||
22 | this driver will not work on older motherboards. For older | ||
23 | motherboards use the abituguru (without the 3 !) driver. | ||
24 | |||
25 | Authors: | ||
26 | Hans de Goede <j.w.r.degoede@hhs.nl>, | ||
27 | (Initial reverse engineering done by Louis Kruger) | ||
28 | |||
29 | |||
30 | Module Parameters | ||
31 | ----------------- | ||
32 | |||
33 | * force: bool Force detection. Note this parameter only causes the | ||
34 | detection to be skipped, and thus the insmod to | ||
35 | succeed. If the uGuru can't be read the actual hwmon | ||
36 | driver will not load and thus no hwmon device will get | ||
37 | registered. | ||
38 | * verbose: bool Should the driver be verbose? | ||
39 | 0/off/false normal output | ||
40 | 1/on/true + verbose error reporting (default) | ||
41 | Default: 1 (the driver is still in the testing phase) | ||
42 | |||
43 | Description | ||
44 | ----------- | ||
45 | |||
46 | This driver supports the hardware monitoring features of the third revision of | ||
47 | the Abit uGuru chip, found on recent Abit uGuru featuring motherboards. | ||
48 | |||
49 | The 3rd revision of the uGuru chip in reality is a Winbond W83L951G. | ||
50 | Unfortunatly this doesn't help since the W83L951G is a generic microcontroller | ||
51 | with a custom Abit application running on it. | ||
52 | |||
53 | Despite Abit not releasing any information regarding the uGuru revision 3, | ||
54 | Louis Kruger has managed to reverse engineer the sensor part of the uGuru. | ||
55 | Without his work this driver would not have been possible. | ||
56 | |||
57 | Known Issues | ||
58 | ------------ | ||
59 | |||
60 | The voltage and frequency control parts of the Abit uGuru are not supported, | ||
61 | neither is writing any of the sensor settings and writing / reading the | ||
62 | fanspeed control registers (FanEQ) | ||
63 | |||
64 | If you encounter any problems please mail me <j.w.r.degoede@hhs.nl> and | ||
65 | include the output of: "dmesg | grep abituguru" | ||
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 new file mode 100644 index 000000000000..1a0f3d64ab80 --- /dev/null +++ b/Documentation/hwmon/dme1737 | |||
@@ -0,0 +1,257 @@ | |||
1 | Kernel driver dme1737 | ||
2 | ===================== | ||
3 | |||
4 | Supported chips: | ||
5 | * SMSC DME1737 and compatibles (like Asus A8000) | ||
6 | Prefix: 'dme1737' | ||
7 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | ||
8 | Datasheet: Provided by SMSC upon request and under NDA | ||
9 | |||
10 | Authors: | ||
11 | Juerg Haefliger <juergh@gmail.com> | ||
12 | |||
13 | |||
14 | Module Parameters | ||
15 | ----------------- | ||
16 | |||
17 | * force_start: bool Enables the monitoring of voltage, fan and temp inputs | ||
18 | and PWM output control functions. Using this parameter | ||
19 | shouldn't be required since the BIOS usually takes care | ||
20 | of this. | ||
21 | |||
22 | Note that there is no need to use this parameter if the driver loads without | ||
23 | complaining. The driver will say so if it is necessary. | ||
24 | |||
25 | |||
26 | Description | ||
27 | ----------- | ||
28 | |||
29 | 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 | ||
31 | features monitoring of 3 temp sensors temp[1-3] (2 remote diodes and 1 | ||
32 | internal), 7 voltages in[0-6] (6 external and 1 internal) and 6 fan speeds | ||
33 | fan[1-6]. Additionally, the chip implements 5 PWM outputs pwm[1-3,5-6] for | ||
34 | controlling fan speeds both manually and automatically. | ||
35 | |||
36 | Fan[3-6] and pwm[3,5-6] are optional features and their availability is | ||
37 | dependent on the configuration of the chip. The driver will detect which | ||
38 | features are present during initialization and create the sysfs attributes | ||
39 | accordingly. | ||
40 | |||
41 | |||
42 | Voltage Monitoring | ||
43 | ------------------ | ||
44 | |||
45 | The voltage inputs are sampled with 12-bit resolution and have internal | ||
46 | scaling resistors. The values returned by the driver therefore reflect true | ||
47 | millivolts and don't need scaling. The voltage inputs are mapped as follows | ||
48 | (the last column indicates the input ranges): | ||
49 | |||
50 | in0: +5VTR (+5V standby) 0V - 6.64V | ||
51 | in1: Vccp (processor core) 0V - 3V | ||
52 | in2: VCC (internal +3.3V) 0V - 4.38V | ||
53 | in3: +5V 0V - 6.64V | ||
54 | in4: +12V 0V - 16V | ||
55 | in5: VTR (+3.3V standby) 0V - 4.38V | ||
56 | in6: Vbat (+3.0V) 0V - 4.38V | ||
57 | |||
58 | Each voltage input has associated min and max limits which trigger an alarm | ||
59 | when crossed. | ||
60 | |||
61 | |||
62 | Temperature Monitoring | ||
63 | ---------------------- | ||
64 | |||
65 | Temperatures are measured with 12-bit resolution and reported in millidegree | ||
66 | Celsius. The chip also features offsets for all 3 temperature inputs which - | ||
67 | when programmed - get added to the input readings. The chip does all the | ||
68 | scaling by itself and the driver therefore reports true temperatures that don't | ||
69 | need any user-space adjustments. The temperature inputs are mapped as follows | ||
70 | (the last column indicates the input ranges): | ||
71 | |||
72 | temp1: Remote diode 1 (3904 type) temperature -127C - +127C | ||
73 | temp2: DME1737 internal temperature -127C - +127C | ||
74 | temp3: Remote diode 2 (3904 type) temperature -127C - +127C | ||
75 | |||
76 | Each temperature input has associated min and max limits which trigger an alarm | ||
77 | when crossed. Additionally, each temperature input has a fault attribute that | ||
78 | returns 1 when a faulty diode or an unconnected input is detected and 0 | ||
79 | otherwise. | ||
80 | |||
81 | |||
82 | Fan Monitoring | ||
83 | -------------- | ||
84 | |||
85 | Fan RPMs are measured with 16-bit resolution. The chip provides inputs for 6 | ||
86 | fan tachometers. All 6 inputs have an associated min limit which triggers an | ||
87 | alarm when crossed. Fan inputs 1-4 provide type attributes that need to be set | ||
88 | to the number of pulses per fan revolution that the connected tachometer | ||
89 | generates. Supported values are 1, 2, and 4. Fan inputs 5-6 only support fans | ||
90 | that generate 2 pulses per revolution. Fan inputs 5-6 also provide a max | ||
91 | attribute that needs to be set to the maximum attainable RPM (fan at 100% duty- | ||
92 | cycle) of the input. The chip adjusts the sampling rate based on this value. | ||
93 | |||
94 | |||
95 | PWM Output Control | ||
96 | ------------------ | ||
97 | |||
98 | This chip features 5 PWM outputs. PWM outputs 1-3 are associated with fan | ||
99 | inputs 1-3 and PWM outputs 5-6 are associated with fan inputs 5-6. PWM outputs | ||
100 | 1-3 can be configured to operate either in manual or automatic mode by setting | ||
101 | the appropriate enable attribute accordingly. PWM outputs 5-6 can only operate | ||
102 | in manual mode, their enable attributes are therefore read-only. When set to | ||
103 | manual mode, the fan speed is set by writing the duty-cycle value to the | ||
104 | appropriate PWM attribute. In automatic mode, the PWM attribute returns the | ||
105 | current duty-cycle as set by the fan controller in the chip. All PWM outputs | ||
106 | support the setting of the output frequency via the freq attribute. | ||
107 | |||
108 | In automatic mode, the chip supports the setting of the PWM ramp rate which | ||
109 | defines how fast the PWM output is adjusting to changes of the associated | ||
110 | temperature input. Associating PWM outputs to temperature inputs is done via | ||
111 | temperature zones. The chip features 3 zones whose assignments to temperature | ||
112 | inputs is static and determined during initialization. These assignments can | ||
113 | be retrieved via the zone[1-3]_auto_channels_temp attributes. Each PWM output | ||
114 | is assigned to one (or hottest of multiple) temperature zone(s) through the | ||
115 | pwm[1-3]_auto_channels_zone attributes. Each PWM output has 3 distinct output | ||
116 | duty-cycles: full, low, and min. Full is internally hard-wired to 255 (100%) | ||
117 | and low and min can be programmed via pwm[1-3]_auto_point1_pwm and | ||
118 | pwm[1-3]_auto_pwm_min, respectively. The thermal thresholds of the zones are | ||
119 | programmed via zone[1-3]_auto_point[1-3]_temp and | ||
120 | zone[1-3]_auto_point1_temp_hyst: | ||
121 | |||
122 | pwm[1-3]_auto_point2_pwm full-speed duty-cycle (255, i.e., 100%) | ||
123 | pwm[1-3]_auto_point1_pwm low-speed duty-cycle | ||
124 | pwm[1-3]_auto_pwm_min min-speed duty-cycle | ||
125 | |||
126 | zone[1-3]_auto_point3_temp full-speed temp (all outputs) | ||
127 | zone[1-3]_auto_point2_temp full-speed temp | ||
128 | zone[1-3]_auto_point1_temp low-speed temp | ||
129 | zone[1-3]_auto_point1_temp_hyst min-speed temp | ||
130 | |||
131 | The chip adjusts the output duty-cycle linearly in the range of auto_point1_pwm | ||
132 | to auto_point2_pwm if the temperature of the associated zone is between | ||
133 | auto_point1_temp and auto_point2_temp. If the temperature drops below the | ||
134 | auto_point1_temp_hyst value, the output duty-cycle is set to the auto_pwm_min | ||
135 | value which only supports two values: 0 or auto_point1_pwm. That means that the | ||
136 | fan either turns completely off or keeps spinning with the low-speed | ||
137 | duty-cycle. If any of the temperatures rise above the auto_point3_temp value, | ||
138 | all PWM outputs are set to 100% duty-cycle. | ||
139 | |||
140 | Following is another representation of how the chip sets the output duty-cycle | ||
141 | based on the temperature of the associated thermal zone: | ||
142 | |||
143 | Duty-Cycle Duty-Cycle | ||
144 | Temperature Rising Temp Falling Temp | ||
145 | ----------- ----------- ------------ | ||
146 | full-speed full-speed full-speed | ||
147 | |||
148 | < linearly adjusted duty-cycle > | ||
149 | |||
150 | low-speed low-speed low-speed | ||
151 | min-speed low-speed | ||
152 | min-speed min-speed min-speed | ||
153 | min-speed min-speed | ||
154 | |||
155 | |||
156 | Sysfs Attributes | ||
157 | ---------------- | ||
158 | |||
159 | Following is a list of all sysfs attributes that the driver provides, their | ||
160 | permissions and a short description: | ||
161 | |||
162 | Name Perm Description | ||
163 | ---- ---- ----------- | ||
164 | cpu0_vid RO CPU core reference voltage in | ||
165 | millivolts. | ||
166 | vrm RW Voltage regulator module version | ||
167 | number. | ||
168 | |||
169 | in[0-6]_input RO Measured voltage in millivolts. | ||
170 | in[0-6]_min RW Low limit for voltage input. | ||
171 | in[0-6]_max RW High limit for voltage input. | ||
172 | in[0-6]_alarm RO Voltage input alarm. Returns 1 if | ||
173 | voltage input is or went outside the | ||
174 | associated min-max range, 0 otherwise. | ||
175 | |||
176 | temp[1-3]_input RO Measured temperature in millidegree | ||
177 | Celsius. | ||
178 | temp[1-3]_min RW Low limit for temp input. | ||
179 | temp[1-3]_max RW High limit for temp input. | ||
180 | temp[1-3]_offset RW Offset for temp input. This value will | ||
181 | be added by the chip to the measured | ||
182 | temperature. | ||
183 | temp[1-3]_alarm RO Alarm for temp input. Returns 1 if temp | ||
184 | input is or went outside the associated | ||
185 | min-max range, 0 otherwise. | ||
186 | temp[1-3]_fault RO Temp input fault. Returns 1 if the chip | ||
187 | detects a faulty thermal diode or an | ||
188 | unconnected temp input, 0 otherwise. | ||
189 | |||
190 | zone[1-3]_auto_channels_temp RO Temperature zone to temperature input | ||
191 | mapping. This attribute is a bitfield | ||
192 | and supports the following values: | ||
193 | 1: temp1 | ||
194 | 2: temp2 | ||
195 | 4: temp3 | ||
196 | zone[1-3]_auto_point1_temp_hyst RW Auto PWM temp point1 hysteresis. The | ||
197 | output of the corresponding PWM is set | ||
198 | to the pwm_auto_min value if the temp | ||
199 | falls below the auto_point1_temp_hyst | ||
200 | value. | ||
201 | zone[1-3]_auto_point[1-3]_temp RW Auto PWM temp points. Auto_point1 is | ||
202 | the low-speed temp, auto_point2 is the | ||
203 | full-speed temp, and auto_point3 is the | ||
204 | temp at which all PWM outputs are set | ||
205 | to full-speed (100% duty-cycle). | ||
206 | |||
207 | fan[1-6]_input RO Measured fan speed in RPM. | ||
208 | fan[1-6]_min RW Low limit for fan input. | ||
209 | fan[1-6]_alarm RO Alarm for fan input. Returns 1 if fan | ||
210 | input is or went below the associated | ||
211 | min value, 0 otherwise. | ||
212 | fan[1-4]_type RW Type of attached fan. Expressed in | ||
213 | number of pulses per revolution that | ||
214 | the fan generates. Supported values are | ||
215 | 1, 2, and 4. | ||
216 | fan[5-6]_max RW Max attainable RPM at 100% duty-cycle. | ||
217 | Required for chip to adjust the | ||
218 | sampling rate accordingly. | ||
219 | |||
220 | pmw[1-3,5-6] RO/RW Duty-cycle of PWM output. Supported | ||
221 | values are 0-255 (0%-100%). Only | ||
222 | writeable if the associated PWM is in | ||
223 | manual mode. | ||
224 | pwm[1-3]_enable RW Enable of PWM outputs 1-3. Supported | ||
225 | values are: | ||
226 | 0: turned off (output @ 100%) | ||
227 | 1: manual mode | ||
228 | 2: automatic mode | ||
229 | pwm[5-6]_enable RO Enable of PWM outputs 5-6. Always | ||
230 | returns 1 since these 2 outputs are | ||
231 | hard-wired to manual mode. | ||
232 | pmw[1-3,5-6]_freq RW Frequency of PWM output. Supported | ||
233 | values are in the range 11Hz-30000Hz | ||
234 | (default is 25000Hz). | ||
235 | pmw[1-3]_ramp_rate RW Ramp rate of PWM output. Determines how | ||
236 | fast the PWM duty-cycle will change | ||
237 | when the PWM is in automatic mode. | ||
238 | Expressed in ms per PWM step. Supported | ||
239 | values are in the range 0ms-206ms | ||
240 | (default is 0, which means the duty- | ||
241 | cycle changes instantly). | ||
242 | pwm[1-3]_auto_channels_zone RW PWM output to temperature zone mapping. | ||
243 | This attribute is a bitfield and | ||
244 | supports the following values: | ||
245 | 1: zone1 | ||
246 | 2: zone2 | ||
247 | 4: zone3 | ||
248 | 6: highest of zone[2-3] | ||
249 | 7: highest of zone[1-3] | ||
250 | pwm[1-3]_auto_pwm_min RW Auto PWM min pwm. Minimum PWM duty- | ||
251 | cycle. Supported values are 0 or | ||
252 | auto_point1_pwm. | ||
253 | pwm[1-3]_auto_point1_pwm RW Auto PWM pwm point. Auto_point1 is the | ||
254 | low-speed duty-cycle. | ||
255 | pwm[1-3]_auto_point2_pwm RO Auto PWM pwm point. Auto_point2 is the | ||
256 | full-speed duty-cycle which is hard- | ||
257 | wired to 255 (100% duty-cycle). | ||
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f index bfd0f154959c..94e0d2cbd3d2 100644 --- a/Documentation/hwmon/f71805f +++ b/Documentation/hwmon/f71805f | |||
@@ -5,11 +5,11 @@ Supported chips: | |||
5 | * Fintek F71805F/FG | 5 | * Fintek F71805F/FG |
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: Provided by Fintek on request | 8 | Datasheet: Available from the Fintek website |
9 | * Fintek F71872F/FG | 9 | * Fintek F71872F/FG |
10 | Prefix: 'f71872f' | 10 | Prefix: 'f71872f' |
11 | Addresses scanned: none, address read from Super I/O config space | 11 | Addresses scanned: none, address read from Super I/O config space |
12 | Datasheet: Provided by Fintek on request | 12 | Datasheet: Available from the Fintek website |
13 | 13 | ||
14 | Author: Jean Delvare <khali@linux-fr.org> | 14 | Author: Jean Delvare <khali@linux-fr.org> |
15 | 15 | ||
@@ -128,7 +128,9 @@ it. | |||
128 | When the PWM method is used, you can select the operating frequency, | 128 | When the PWM method is used, you can select the operating frequency, |
129 | from 187.5 kHz (default) to 31 Hz. The best frequency depends on the | 129 | from 187.5 kHz (default) to 31 Hz. The best frequency depends on the |
130 | fan model. As a rule of thumb, lower frequencies seem to give better | 130 | fan model. As a rule of thumb, lower frequencies seem to give better |
131 | control, but may generate annoying high-pitch noise. Fintek recommends | 131 | control, but may generate annoying high-pitch noise. So a frequency just |
132 | above the audible range, such as 25 kHz, may be a good choice; if this | ||
133 | doesn't give you good linear control, try reducing it. Fintek recommends | ||
132 | not going below 1 kHz, as the fan tachometers get confused by lower | 134 | not going below 1 kHz, as the fan tachometers get confused by lower |
133 | frequencies as well. | 135 | frequencies as well. |
134 | 136 | ||
@@ -136,16 +138,23 @@ When the DC method is used, Fintek recommends not going below 5 V, which | |||
136 | corresponds to a pwm value of 106 for the driver. The driver doesn't | 138 | corresponds to a pwm value of 106 for the driver. The driver doesn't |
137 | enforce this limit though. | 139 | enforce this limit though. |
138 | 140 | ||
139 | Three different fan control modes are supported: | 141 | Three different fan control modes are supported; the mode number is written |
142 | to the pwm<n>_enable file. | ||
140 | 143 | ||
141 | * Manual mode | 144 | * 1: Manual mode |
142 | You ask for a specific PWM duty cycle or DC voltage. | 145 | You ask for a specific PWM duty cycle or DC voltage by writing to the |
146 | pwm<n> file. | ||
143 | 147 | ||
144 | * Fan speed mode | 148 | * 2: Temperature mode |
145 | You ask for a specific fan speed. This mode assumes that pwm1 | 149 | You define 3 temperature/fan speed trip points using the |
146 | corresponds to fan1, pwm2 to fan2 and pwm3 to fan3. | 150 | pwm<n>_auto_point<m>_temp and _fan files. These define a staircase |
151 | relationship between temperature and fan speed with two additional points | ||
152 | interpolated between the values that you define. When the temperature | ||
153 | is below auto_point1_temp the fan is switched off. | ||
147 | 154 | ||
148 | * Temperature mode | 155 | * 3: Fan speed mode |
149 | You define 3 temperature/fan speed trip points, and the fan speed is | 156 | You ask for a specific fan speed by writing to the fan<n>_target file. |
150 | adjusted depending on the measured temperature, using interpolation. | 157 | |
151 | This mode is not yet supported by the driver. | 158 | Both of the automatic modes require that pwm1 corresponds to fan1, pwm2 to |
159 | fan2 and pwm3 to fan3. Temperature mode also requires that temp1 corresponds | ||
160 | to pwm1 and fan1, etc. | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index c0528d6f9ace..81ecc7e41c50 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -12,11 +12,12 @@ Supported chips: | |||
12 | Addresses scanned: from Super I/O config space (8 I/O ports) | 12 | Addresses scanned: from Super I/O config space (8 I/O ports) |
13 | Datasheet: Publicly available at the ITE website | 13 | Datasheet: Publicly available at the ITE website |
14 | http://www.ite.com.tw/ | 14 | http://www.ite.com.tw/ |
15 | * IT8716F | 15 | * IT8716F/IT8726F |
16 | Prefix: 'it8716' | 16 | Prefix: 'it8716' |
17 | Addresses scanned: from Super I/O config space (8 I/O ports) | 17 | Addresses scanned: from Super I/O config space (8 I/O ports) |
18 | Datasheet: Publicly available at the ITE website | 18 | Datasheet: Publicly available at the ITE website |
19 | http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP | 19 | http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP |
20 | http://www.ite.com.tw/product_info/file/pc/IT8726F_V0.3.pdf | ||
20 | * IT8718F | 21 | * IT8718F |
21 | Prefix: 'it8718' | 22 | Prefix: 'it8718' |
22 | Addresses scanned: from Super I/O config space (8 I/O ports) | 23 | Addresses scanned: from Super I/O config space (8 I/O ports) |
@@ -68,7 +69,7 @@ Description | |||
68 | ----------- | 69 | ----------- |
69 | 70 | ||
70 | This driver implements support for the IT8705F, IT8712F, IT8716F, | 71 | This driver implements support for the IT8705F, IT8712F, IT8716F, |
71 | IT8718F and SiS950 chips. | 72 | IT8718F, IT8726F and SiS950 chips. |
72 | 73 | ||
73 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, | 74 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, |
74 | joysticks and other miscellaneous stuff. For hardware monitoring, they | 75 | joysticks and other miscellaneous stuff. For hardware monitoring, they |
@@ -97,6 +98,10 @@ clock divider mess) but not compatible with the older chips and | |||
97 | revisions. For now, the driver only uses the 16-bit mode on the | 98 | revisions. For now, the driver only uses the 16-bit mode on the |
98 | IT8716F and IT8718F. | 99 | IT8716F and IT8718F. |
99 | 100 | ||
101 | The IT8726F is just bit enhanced IT8716F with additional hardware | ||
102 | for AMD power sequencing. Therefore the chip will appear as IT8716F | ||
103 | to userspace applications. | ||
104 | |||
100 | Temperatures are measured in degrees Celsius. An alarm is triggered once | 105 | Temperatures are measured in degrees Celsius. An alarm is triggered once |
101 | when the Overtemperature Shutdown limit is crossed. | 106 | when the Overtemperature Shutdown limit is crossed. |
102 | 107 | ||
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 438cb24cee5b..aa4a0ec20081 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 | |||
@@ -48,6 +48,18 @@ Supported chips: | |||
48 | Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e) | 48 | Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e) |
49 | Datasheet: Publicly available at the Maxim website | 49 | Datasheet: Publicly available at the Maxim website |
50 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 | 50 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 |
51 | * Maxim MAX6680 | ||
52 | Prefix: 'max6680' | ||
53 | Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
54 | 0x4c, 0x4d and 0x4e | ||
55 | Datasheet: Publicly available at the Maxim website | ||
56 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
57 | * Maxim MAX6681 | ||
58 | Prefix: 'max6680' | ||
59 | Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
60 | 0x4c, 0x4d and 0x4e | ||
61 | Datasheet: Publicly available at the Maxim website | ||
62 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
51 | 63 | ||
52 | 64 | ||
53 | Author: Jean Delvare <khali@linux-fr.org> | 65 | Author: Jean Delvare <khali@linux-fr.org> |
@@ -59,11 +71,15 @@ Description | |||
59 | The LM90 is a digital temperature sensor. It senses its own temperature as | 71 | The LM90 is a digital temperature sensor. It senses its own temperature as |
60 | well as the temperature of up to one external diode. It is compatible | 72 | well as the temperature of up to one external diode. It is compatible |
61 | with many other devices such as the LM86, the LM89, the LM99, the ADM1032, | 73 | with many other devices such as the LM86, the LM89, the LM99, the ADM1032, |
62 | the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver. | 74 | the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are |
63 | Note that there is no easy way to differentiate between the last three | 75 | supported by this driver. |
64 | variants. The extra address and features of the MAX6659 are not supported by | 76 | |
65 | this driver. Additionally, the ADT7461 is supported if found in ADM1032 | 77 | Note that there is no easy way to differentiate between the MAX6657, |
66 | compatibility mode. | 78 | MAX6658 and MAX6659 variants. The extra address and features of the |
79 | MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only | ||
80 | differ in their pinout, therefore they obviously can't (and don't need to) | ||
81 | be distinguished. Additionally, the ADT7461 is supported if found in | ||
82 | ADM1032 compatibility mode. | ||
67 | 83 | ||
68 | The specificity of this family of chipsets over the ADM1021/LM84 | 84 | The specificity of this family of chipsets over the ADM1021/LM84 |
69 | family is that it features critical limits with hysteresis, and an | 85 | family is that it features critical limits with hysteresis, and an |
@@ -93,18 +109,22 @@ ADM1032: | |||
93 | * ALERT is triggered by open remote sensor. | 109 | * ALERT is triggered by open remote sensor. |
94 | * SMBus PEC support for Write Byte and Receive Byte transactions. | 110 | * SMBus PEC support for Write Byte and Receive Byte transactions. |
95 | 111 | ||
96 | ADT7461 | 112 | ADT7461: |
97 | * Extended temperature range (breaks compatibility) | 113 | * Extended temperature range (breaks compatibility) |
98 | * Lower resolution for remote temperature | 114 | * Lower resolution for remote temperature |
99 | 115 | ||
100 | MAX6657 and MAX6658: | 116 | MAX6657 and MAX6658: |
101 | * Remote sensor type selection | 117 | * Remote sensor type selection |
102 | 118 | ||
103 | MAX6659 | 119 | MAX6659: |
104 | * Selectable address | 120 | * Selectable address |
105 | * Second critical temperature limit | 121 | * Second critical temperature limit |
106 | * Remote sensor type selection | 122 | * Remote sensor type selection |
107 | 123 | ||
124 | MAX6680 and MAX6681: | ||
125 | * Selectable address | ||
126 | * Remote sensor type selection | ||
127 | |||
108 | All temperature values are given in degrees Celsius. Resolution | 128 | All temperature values are given in degrees Celsius. Resolution |
109 | is 1.0 degree for the local temperature, 0.125 degree for the remote | 129 | is 1.0 degree for the local temperature, 0.125 degree for the remote |
110 | temperature. | 130 | temperature. |
@@ -141,7 +161,7 @@ SMBus Read Byte, and PEC will work properly. | |||
141 | Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC. | 161 | Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC. |
142 | Instead, it will try to write the PEC value to the register (because the | 162 | Instead, it will try to write the PEC value to the register (because the |
143 | SMBus Send Byte transaction with PEC is similar to a Write Byte transaction | 163 | SMBus Send Byte transaction with PEC is similar to a Write Byte transaction |
144 | without PEC), which is not what we want. Thus, PEC is explicitely disabled | 164 | without PEC), which is not what we want. Thus, PEC is explicitly disabled |
145 | on SMBus Send Byte transactions in the lm90 driver. | 165 | on SMBus Send Byte transactions in the lm90 driver. |
146 | 166 | ||
147 | PEC on byte data transactions represents a significant increase in bandwidth | 167 | PEC on byte data transactions represents a significant increase in bandwidth |
diff --git a/Documentation/hwmon/lm93 b/Documentation/hwmon/lm93 new file mode 100644 index 000000000000..4e4a1dc1d2da --- /dev/null +++ b/Documentation/hwmon/lm93 | |||
@@ -0,0 +1,412 @@ | |||
1 | Kernel driver lm93 | ||
2 | ================== | ||
3 | |||
4 | Supported chips: | ||
5 | * National Semiconductor LM93 | ||
6 | Prefix 'lm93' | ||
7 | Addresses scanned: I2C 0x2c-0x2e | ||
8 | Datasheet: http://www.national.com/ds.cgi/LM/LM93.pdf | ||
9 | |||
10 | Author: | ||
11 | Mark M. Hoffman <mhoffman@lightlink.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> | ||
14 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | ||
15 | |||
16 | Module Parameters | ||
17 | ----------------- | ||
18 | |||
19 | (specific to LM93) | ||
20 | * init: integer | ||
21 | Set to non-zero to force some initializations (default is 0). | ||
22 | * disable_block: integer | ||
23 | A "0" allows SMBus block data transactions if the host supports them. A "1" | ||
24 | disables SMBus block data transactions. The default is 0. | ||
25 | * vccp_limit_type: integer array (2) | ||
26 | Configures in7 and in8 limit type, where 0 means absolute and non-zero | ||
27 | means relative. "Relative" here refers to "Dynamic Vccp Monitoring using | ||
28 | VID" from the datasheet. It greatly simplifies the interface to allow | ||
29 | only one set of limits (absolute or relative) to be in operation at a | ||
30 | time (even though the hardware is capable of enabling both). There's | ||
31 | not a compelling use case for enabling both at once, anyway. The default | ||
32 | is "0,0". | ||
33 | * vid_agtl: integer | ||
34 | A "0" configures the VID pins for V(ih) = 2.1V min, V(il) = 0.8V max. | ||
35 | A "1" configures the VID pins for V(ih) = 0.8V min, V(il) = 0.4V max. | ||
36 | (The latter setting is referred to as AGTL+ Compatible in the datasheet.) | ||
37 | 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". | ||
39 | |||
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 | |||
58 | Hardware Description | ||
59 | -------------------- | ||
60 | |||
61 | (from the datasheet) | ||
62 | |||
63 | 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 | ||
65 | 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 | ||
67 | controlled by up to four temperature zones. The fancontrol algorithm is lookup | ||
68 | 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 | ||
70 | tachometer inputs to measure fan speed. Limit and status registers for all | ||
71 | measured values are included. The LM93 builds upon the functionality of | ||
72 | 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 | ||
74 | for dynamic Vccp monitoring and PROCHOT. It is designed to monitor a dual | ||
75 | processor Xeon class motherboard with a minimum of external components. | ||
76 | |||
77 | |||
78 | Driver Description | ||
79 | ------------------ | ||
80 | |||
81 | This driver implements support for the National Semiconductor LM93. | ||
82 | |||
83 | |||
84 | User Interface | ||
85 | -------------- | ||
86 | |||
87 | #PROCHOT: | ||
88 | |||
89 | The LM93 can monitor two #PROCHOT signals. The results are found in the | ||
90 | sysfs files prochot1, prochot2, prochot1_avg, prochot2_avg, prochot1_max, | ||
91 | and prochot2_max. prochot1_max and prochot2_max contain the user limits | ||
92 | for #PROCHOT1 and #PROCHOT2, respectively. prochot1 and prochot2 contain | ||
93 | the current readings for the most recent complete time interval. The | ||
94 | value of prochot1_avg and prochot2_avg is something like a 2 period | ||
95 | exponential moving average (but not quite - check the datasheet). Note | ||
96 | that this third value is calculated by the chip itself. All values range | ||
97 | from 0-255 where 0 indicates no throttling, and 255 indicates > 99.6%. | ||
98 | |||
99 | The monitoring intervals for the two #PROCHOT signals is also configurable. | ||
100 | These intervals can be found in the sysfs files prochot1_interval and | ||
101 | prochot2_interval. The values in these files specify the intervals for | ||
102 | #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 | ||
104 | intervals are: | ||
105 | |||
106 | #PROCHOT intervals: 0.73, 1.46, 2.9, 5.8, 11.7, 23.3, 46.6, 93.2, 186, 372 | ||
107 | |||
108 | It is possible to configure the LM93 to logically short the two #PROCHOT | ||
109 | signals. I.e. when #P1_PROCHOT is asserted, the LM93 will automatically | ||
110 | assert #P2_PROCHOT, and vice-versa. This mode is enabled by writing a | ||
111 | non-zero integer to the sysfs file prochot_short. | ||
112 | |||
113 | 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, | ||
115 | 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). | ||
117 | |||
118 | The sysfs files prochot1_override and prochot2_override contain boolean | ||
119 | intgers which enable or disable the override function for #P1_PROCHOT and | ||
120 | #P2_PROCHOT, respectively. The sysfs file prochot_override_duty_cycle | ||
121 | 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 | ||
123 | indicating minimum duty cycle and 15 indicating maximum. | ||
124 | |||
125 | #VRD_HOT: | ||
126 | |||
127 | The LM93 can monitor two #VRD_HOT signals. The results are found in the | ||
128 | sysfs files vrdhot1 and vrdhot2. There is one value per file: a boolean for | ||
129 | which 1 indicates #VRD_HOT is asserted and 0 indicates it is negated. These | ||
130 | files are read-only. | ||
131 | |||
132 | Smart Tach Mode: | ||
133 | |||
134 | (from the datasheet) | ||
135 | |||
136 | If a fan is driven using a low-side drive PWM, the tachometer | ||
137 | output of the fan is corrupted. The LM93 includes smart tachometer | ||
138 | circuitry that allows an accurate tachometer reading to be | ||
139 | achieved despite the signal corruption. In smart tach mode all | ||
140 | four signals are measured within 4 seconds. | ||
141 | |||
142 | Smart tach mode is enabled by the driver by writing 1 or 2 (associating the | ||
143 | the fan tachometer with a pwm) to the sysfs file fan<n>_smart_tach. A zero | ||
144 | will disable the function for that fan. Note that Smart tach mode cannot be | ||
145 | enabled if the PWM output frequency is 22500 Hz (see below). | ||
146 | |||
147 | Manual PWM: | ||
148 | |||
149 | The LM93 has a fixed or override mode for the two PWM outputs (although, there | ||
150 | are still some conditions that will override even this mode - see section | ||
151 | 15.10.6 of the datasheet for details.) The sysfs files pwm1_override | ||
152 | and pwm2_override are used to enable this mode; each is a boolean integer | ||
153 | where 0 disables and 1 enables the manual control mode. The sysfs files pwm1 | ||
154 | and pwm2 are used to set the manual duty cycle; each is an integer (0-255) | ||
155 | where 0 is 0% duty cycle, and 255 is 100%. Note that the duty cycle values | ||
156 | are constrained by the hardware. Selecting a value which is not available | ||
157 | will cause the driver to use the next largest value. Also note: when manual | ||
158 | PWM mode is disabled, the value of pwm1 and pwm2 indicates the current duty | ||
159 | cycle chosen by the h/w. | ||
160 | |||
161 | PWM Output Frequency: | ||
162 | |||
163 | The LM93 supports several different frequencies for the PWM output channels. | ||
164 | The sysfs files pwm1_freq and pwm2_freq are used to select the frequency. The | ||
165 | 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 | ||
167 | that this parameter has implications for the Smart Tach Mode (see above). | ||
168 | |||
169 | PWM Output Frequencies: 12, 36, 48, 60, 72, 84, 96, 22500 (h/w default) | ||
170 | |||
171 | Automatic PWM: | ||
172 | |||
173 | The LM93 is capable of complex automatic fan control, with many different | ||
174 | points of configuration. To start, each PWM output can be bound to any | ||
175 | combination of eight control sources. The final PWM is the largest of all | ||
176 | individual control sources to which the PWM output is bound. | ||
177 | |||
178 | 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 | ||
180 | 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). | ||
182 | |||
183 | 0x01 - Temp 1 | ||
184 | 0x02 - Temp 2 | ||
185 | 0x04 - Temp 3 | ||
186 | 0x08 - Temp 4 | ||
187 | 0x10 - #PROCHOT 1 | ||
188 | 0x20 - #PROCHOT 2 | ||
189 | 0x40 - #VRDHOT 1 | ||
190 | 0x80 - #VRDHOT 2 | ||
191 | |||
192 | The function y = f(x) takes a source temperature x to a PWM output y. This | ||
193 | function of the LM93 is derived from a base temperature and a table of 12 | ||
194 | temperature offsets. The base temperature is expressed in degrees C in the | ||
195 | sysfs files temp<n>_auto_base. The offsets are expressed in cumulative | ||
196 | degrees C, with the value of offset <i> for temperature value <n> being | ||
197 | contained in the file temp<n>_auto_offset<i>. E.g. if the base temperature | ||
198 | is 40C: | ||
199 | |||
200 | offset # temp<n>_auto_offset<i> range pwm | ||
201 | 1 0 - 25.00% | ||
202 | 2 0 - 28.57% | ||
203 | 3 1 40C - 41C 32.14% | ||
204 | 4 1 41C - 42C 35.71% | ||
205 | 5 2 42C - 44C 39.29% | ||
206 | 6 2 44C - 46C 42.86% | ||
207 | 7 2 48C - 50C 46.43% | ||
208 | 8 2 50C - 52C 50.00% | ||
209 | 9 2 52C - 54C 53.57% | ||
210 | 10 2 54C - 56C 57.14% | ||
211 | 11 2 56C - 58C 71.43% | ||
212 | 12 2 58C - 60C 85.71% | ||
213 | > 60C 100.00% | ||
214 | |||
215 | Valid offsets are in the range 0C <= x <= 7.5C in 0.5C increments. | ||
216 | |||
217 | There is an independent base temperature for each temperature channel. Note, | ||
218 | however, there are only two tables of offsets: one each for temp[12] and | ||
219 | temp[34]. Therefore, any change to e.g. temp1_auto_offset<i> will also | ||
220 | affect temp2_auto_offset<i>. | ||
221 | |||
222 | The LM93 can also apply hysteresis to the offset table, to prevent unwanted | ||
223 | oscillation between two steps in the offsets table. These values are found in | ||
224 | the sysfs files temp<n>_auto_offset_hyst. The value in this file has the | ||
225 | same representation as in temp<n>_auto_offset<i>. | ||
226 | |||
227 | If a temperature reading falls below the base value for that channel, the LM93 | ||
228 | will use the minimum PWM value. These values are found in the sysfs files | ||
229 | temp<n>_auto_pwm_min. Note, there are only two minimums: one each for temp[12] | ||
230 | and temp[34]. Therefore, any change to e.g. temp1_auto_pwm_min will also | ||
231 | affect temp2_auto_pwm_min. | ||
232 | |||
233 | PWM Spin-Up Cycle: | ||
234 | |||
235 | A spin-up cycle occurs when a PWM output is commanded from 0% duty cycle to | ||
236 | some value > 0%. The LM93 supports a minimum duty cycle during spin-up. These | ||
237 | values are found in the sysfs files pwm<n>_auto_spinup_min. The value in this | ||
238 | file has the same representation as other PWM duty cycle values. The | ||
239 | duration of the spin-up cycle is also configurable. These values are found in | ||
240 | the sysfs files pwm<n>_auto_spinup_time. The value in this file is | ||
241 | the spin-up time in seconds. The available spin-up times are constrained by | ||
242 | the hardware. Selecting a value which is not available will cause the driver | ||
243 | to use the next largest value. | ||
244 | |||
245 | Spin-up Durations: 0 (disabled, h/w default), 0.1, 0.25, 0.4, 0.7, 1.0, | ||
246 | 2.0, 4.0 | ||
247 | |||
248 | #PROCHOT and #VRDHOT PWM Ramping: | ||
249 | |||
250 | If the #PROCHOT or #VRDHOT signals are asserted while bound to a PWM output | ||
251 | channel, the LM93 will ramp the PWM output up to 100% duty cycle in discrete | ||
252 | steps. The duration of each step is configurable. There are two files, with | ||
253 | one value each in seconds: pwm_auto_prochot_ramp and pwm_auto_vrdhot_ramp. | ||
254 | The available ramp times are constrained by the hardware. Selecting a value | ||
255 | which is not available will cause the driver to use the next largest value. | ||
256 | |||
257 | Ramp Times: 0 (disabled, h/w default) to 0.75 in 0.05 second intervals | ||
258 | |||
259 | Fan Boost: | ||
260 | |||
261 | For each temperature channel, there is a boost temperature: if the channel | ||
262 | exceeds this limit, the LM93 will immediately drive both PWM outputs to 100%. | ||
263 | This limit is expressed in degrees C in the sysfs files temp<n>_auto_boost. | ||
264 | There is also a hysteresis temperature for this function: after the boost | ||
265 | limit is reached, the temperature channel must drop below this value before | ||
266 | the boost function is disabled. This temperature is also expressed in degrees | ||
267 | C in the sysfs files temp<n>_auto_boost_hyst. | ||
268 | |||
269 | GPIO Pins: | ||
270 | |||
271 | The LM93 can monitor the logic level of four dedicated GPIO pins as well as the | ||
272 | four tach input pins. GPIO0-GPIO3 correspond to (fan) tach 1-4, respectively. | ||
273 | All eight GPIOs are read by reading the bitmask in the sysfs file gpio. The | ||
274 | LSB is GPIO0, and the MSB is GPIO7. | ||
275 | |||
276 | |||
277 | LM93 Unique sysfs Files | ||
278 | ----------------------- | ||
279 | |||
280 | file description | ||
281 | ------------------------------------------------------------- | ||
282 | |||
283 | prochot<n> current #PROCHOT % | ||
284 | |||
285 | prochot<n>_avg moving average #PROCHOT % | ||
286 | |||
287 | prochot<n>_max limit #PROCHOT % | ||
288 | |||
289 | prochot_short enable or disable logical #PROCHOT pin short | ||
290 | |||
291 | prochot<n>_override force #PROCHOT assertion as PWM | ||
292 | |||
293 | prochot_override_duty_cycle | ||
294 | duty cycle for the PWM signal used when | ||
295 | #PROCHOT is overridden | ||
296 | |||
297 | prochot<n>_interval #PROCHOT PWM sampling interval | ||
298 | |||
299 | vrdhot<n> 0 means negated, 1 means asserted | ||
300 | |||
301 | fan<n>_smart_tach enable or disable smart tach mode | ||
302 | |||
303 | pwm<n>_auto_channels select control sources for PWM outputs | ||
304 | |||
305 | pwm<n>_auto_spinup_min minimum duty cycle during spin-up | ||
306 | |||
307 | pwm<n>_auto_spinup_time duration of spin-up | ||
308 | |||
309 | pwm_auto_prochot_ramp ramp time per step when #PROCHOT asserted | ||
310 | |||
311 | pwm_auto_vrdhot_ramp ramp time per step when #VRDHOT asserted | ||
312 | |||
313 | temp<n>_auto_base temperature channel base | ||
314 | |||
315 | temp<n>_auto_offset[1-12] | ||
316 | temperature channel offsets | ||
317 | |||
318 | temp<n>_auto_offset_hyst | ||
319 | temperature channel offset hysteresis | ||
320 | |||
321 | temp<n>_auto_boost temperature channel boost (PWMs to 100%) limit | ||
322 | |||
323 | temp<n>_auto_boost_hyst temperature channel boost hysteresis | ||
324 | |||
325 | gpio input state of 8 GPIO pins; read-only | ||
326 | |||
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/smsc47b397 b/Documentation/hwmon/smsc47b397 index 20682f15ae41..3a43b6948924 100644 --- a/Documentation/hwmon/smsc47b397 +++ b/Documentation/hwmon/smsc47b397 | |||
@@ -4,6 +4,7 @@ Kernel driver smsc47b397 | |||
4 | Supported chips: | 4 | Supported chips: |
5 | * SMSC LPC47B397-NC | 5 | * SMSC LPC47B397-NC |
6 | * SMSC SCH5307-NS | 6 | * SMSC SCH5307-NS |
7 | * SMSC SCH5317 | ||
7 | Prefix: 'smsc47b397' | 8 | Prefix: 'smsc47b397' |
8 | Addresses scanned: none, address read from Super I/O config space | 9 | Addresses scanned: none, address read from Super I/O config space |
9 | Datasheet: In this file | 10 | Datasheet: In this file |
@@ -18,8 +19,8 @@ The following specification describes the SMSC LPC47B397-NC[1] sensor chip | |||
18 | provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected | 19 | provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected |
19 | by Mark M. Hoffman <mhoffman@lightlink.com>. | 20 | by Mark M. Hoffman <mhoffman@lightlink.com>. |
20 | 21 | ||
21 | [1] And SMSC SCH5307-NS, which has a different device ID but is otherwise | 22 | [1] And SMSC SCH5307-NS and SCH5317, which have different device IDs but are |
22 | compatible. | 23 | otherwise compatible. |
23 | 24 | ||
24 | * * * * * | 25 | * * * * * |
25 | 26 | ||
@@ -131,7 +132,7 @@ OUT DX,AL | |||
131 | The registers of interest for identifying the SIO on the dc7100 are Device ID | 132 | The registers of interest for identifying the SIO on the dc7100 are Device ID |
132 | (0x20) and Device Rev (0x21). | 133 | (0x20) and Device Rev (0x21). |
133 | 134 | ||
134 | The Device ID will read 0x6F (for SCH5307-NS, 0x81) | 135 | The Device ID will read 0x6F (0x81 for SCH5307-NS, and 0x85 for SCH5317) |
135 | The Device Rev currently reads 0x01 | 136 | The Device Rev currently reads 0x01 |
136 | 137 | ||
137 | Obtaining the HWM Base Address. | 138 | Obtaining the HWM Base Address. |
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index a9a18ad0d17a..b3a9e1b9dbda 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
@@ -172,11 +172,10 @@ pwm[1-*] Pulse width modulation fan control. | |||
172 | 255 is max or 100%. | 172 | 255 is max or 100%. |
173 | 173 | ||
174 | pwm[1-*]_enable | 174 | pwm[1-*]_enable |
175 | Switch PWM on and off. | 175 | Fan speed control method: |
176 | Not always present even if pwmN is. | 176 | 0: no fan speed control (i.e. fan at full speed) |
177 | 0: turn off | 177 | 1: manual fan speed control enabled (using pwm[1-*]) |
178 | 1: turn on in manual mode | 178 | 2+: automatic fan speed control enabled |
179 | 2+: turn on in automatic mode | ||
180 | Check individual chip documentation files for automatic mode | 179 | Check individual chip documentation files for automatic mode |
181 | details. | 180 | details. |
182 | RW | 181 | RW |
@@ -343,9 +342,9 @@ to notify open diodes, unconnected fans etc. where the hardware | |||
343 | supports it. When this boolean has value 1, the measurement for that | 342 | supports it. When this boolean has value 1, the measurement for that |
344 | channel should not be trusted. | 343 | channel should not be trusted. |
345 | 344 | ||
346 | in[0-*]_input_fault | 345 | in[0-*]_fault |
347 | fan[1-*]_input_fault | 346 | fan[1-*]_fault |
348 | temp[1-*]_input_fault | 347 | temp[1-*]_fault |
349 | Input fault condition | 348 | Input fault condition |
350 | 0: no fault occured | 349 | 0: no fault occured |
351 | 1: fault condition | 350 | 1: fault condition |
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 030fac6cec7a..ccc2bcb61068 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf | |||
@@ -22,9 +22,9 @@ This driver implements support for the Winbond W83627EHF, W83627EHG, and | |||
22 | W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. | 22 | W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. |
23 | 23 | ||
24 | The chips implement three temperature sensors, five fan rotation | 24 | The chips implement three temperature sensors, five fan rotation |
25 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms | 25 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), one |
26 | with beep warnings (control unimplemented), and some automatic fan regulation | 26 | VID (6 pins), alarms with beep warnings (control unimplemented), and |
27 | strategies (plus manual fan control mode). | 27 | some automatic fan regulation strategies (plus manual fan control mode). |
28 | 28 | ||
29 | Temperatures are measured in degrees Celsius and measurement resolution is 1 | 29 | Temperatures are measured in degrees Celsius and measurement resolution is 1 |
30 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when | 30 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when |
diff --git a/MAINTAINERS b/MAINTAINERS index 0c83823f14c3..fbe0dca1c0ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -607,6 +607,12 @@ W: http://sourceforge.net/projects/acpi4asus | |||
607 | W: http://xf.iksaif.net/acpi4asus | 607 | W: http://xf.iksaif.net/acpi4asus |
608 | S: Maintained | 608 | S: Maintained |
609 | 609 | ||
610 | ASUS ASB100 HARDWARE MONITOR DRIVER | ||
611 | P: Mark M. Hoffman | ||
612 | M: mhoffman@lightlink.com | ||
613 | L: lm-sensors@lm-sensors.org | ||
614 | S: Maintained | ||
615 | |||
610 | ASUS LAPTOP EXTRAS DRIVER | 616 | ASUS LAPTOP EXTRAS DRIVER |
611 | P: Corentin Chary | 617 | P: Corentin Chary |
612 | M: corentincj@iksaif.net | 618 | M: corentincj@iksaif.net |
@@ -1273,6 +1279,12 @@ M: shannon.nelson@intel.com | |||
1273 | L: linux-kernel@vger.kernel.org | 1279 | L: linux-kernel@vger.kernel.org |
1274 | S: Maintained | 1280 | S: Maintained |
1275 | 1281 | ||
1282 | DME1737 HARDWARE MONITOR DRIVER | ||
1283 | P: Juerg Haefliger | ||
1284 | M: juergh@gmail.com | ||
1285 | L: lm-sensors@lm-sensors.org | ||
1286 | S: Maintained | ||
1287 | |||
1276 | DOCBOOK FOR DOCUMENTATION | 1288 | DOCBOOK FOR DOCUMENTATION |
1277 | P: Randy Dunlap | 1289 | P: Randy Dunlap |
1278 | M: rdunlap@xenotime.net | 1290 | M: rdunlap@xenotime.net |
@@ -1623,11 +1635,11 @@ W: http://gigaset307x.sourceforge.net/ | |||
1623 | S: Maintained | 1635 | S: Maintained |
1624 | 1636 | ||
1625 | HARDWARE MONITORING | 1637 | HARDWARE MONITORING |
1626 | P: Jean Delvare | 1638 | P: Mark M. Hoffman |
1627 | M: khali@linux-fr.org | 1639 | M: mhoffman@lightlink.com |
1628 | L: lm-sensors@lm-sensors.org | 1640 | L: lm-sensors@lm-sensors.org |
1629 | W: http://www.lm-sensors.org/ | 1641 | W: http://www.lm-sensors.org/ |
1630 | T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-hwmon/ | 1642 | T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git |
1631 | S: Maintained | 1643 | S: Maintained |
1632 | 1644 | ||
1633 | HARDWARE RANDOM NUMBER GENERATOR CORE | 1645 | HARDWARE RANDOM NUMBER GENERATOR CORE |
@@ -1763,6 +1775,12 @@ P: William Irwin | |||
1763 | M: wli@holomorphy.com | 1775 | M: wli@holomorphy.com |
1764 | S: Maintained | 1776 | S: Maintained |
1765 | 1777 | ||
1778 | I2C/SMBUS STUB DRIVER | ||
1779 | P: Mark M. Hoffman | ||
1780 | M: mhoffman@lightlink.com | ||
1781 | L: lm-sensors@lm-sensors.org | ||
1782 | S: Maintained | ||
1783 | |||
1766 | I2C SUBSYSTEM | 1784 | I2C SUBSYSTEM |
1767 | P: Jean Delvare | 1785 | P: Jean Delvare |
1768 | M: khali@linux-fr.org | 1786 | M: khali@linux-fr.org |
@@ -3292,6 +3310,12 @@ W: http://www.brownhat.org/sis900.html | |||
3292 | L: netdev@vger.kernel.org | 3310 | L: netdev@vger.kernel.org |
3293 | S: Maintained | 3311 | S: Maintained |
3294 | 3312 | ||
3313 | SIS 96X I2C/SMBUS DRIVER | ||
3314 | P: Mark M. Hoffman | ||
3315 | M: mhoffman@lightlink.com | ||
3316 | L: lm-sensors@lm-sensors.org | ||
3317 | S: Maintained | ||
3318 | |||
3295 | SIS FRAMEBUFFER DRIVER | 3319 | SIS FRAMEBUFFER DRIVER |
3296 | P: Thomas Winischhofer | 3320 | P: Thomas Winischhofer |
3297 | M: thomas@winischhofer.net | 3321 | M: thomas@winischhofer.net |
@@ -3309,6 +3333,12 @@ P: Nicolas Pitre | |||
3309 | M: nico@cam.org | 3333 | M: nico@cam.org |
3310 | S: Maintained | 3334 | S: Maintained |
3311 | 3335 | ||
3336 | SMSC47B397 HARDWARE MONITOR DRIVER | ||
3337 | P: Mark M. Hoffman | ||
3338 | M: mhoffman@lightlink.com | ||
3339 | L: lm-sensors@lm-sensors.org | ||
3340 | S: Maintained | ||
3341 | |||
3312 | SOFTMAC LAYER (IEEE 802.11) | 3342 | SOFTMAC LAYER (IEEE 802.11) |
3313 | P: Johannes Berg | 3343 | P: Johannes Berg |
3314 | M: johannes@sipsolutions.net | 3344 | M: johannes@sipsolutions.net |
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index 821865f75605..b2bbf217c707 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig | |||
@@ -708,7 +708,6 @@ CONFIG_I2C_ALGOPCF=m | |||
708 | # I2C Hardware Bus support | 708 | # I2C Hardware Bus support |
709 | # | 709 | # |
710 | CONFIG_I2C_ELEKTOR=m | 710 | CONFIG_I2C_ELEKTOR=m |
711 | # CONFIG_I2C_ISA is not set | ||
712 | # CONFIG_I2C_PARPORT is not set | 711 | # CONFIG_I2C_PARPORT is not set |
713 | # CONFIG_I2C_PARPORT_LIGHT is not set | 712 | # CONFIG_I2C_PARPORT_LIGHT is not set |
714 | # CONFIG_I2C_STUB is not set | 713 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/clps7500_defconfig b/arch/arm/configs/clps7500_defconfig index af9ae5389131..49e9f9d8b3d1 100644 --- a/arch/arm/configs/clps7500_defconfig +++ b/arch/arm/configs/clps7500_defconfig | |||
@@ -536,7 +536,6 @@ CONFIG_I2C_ALGOBIT=y | |||
536 | # I2C Hardware Bus support | 536 | # I2C Hardware Bus support |
537 | # | 537 | # |
538 | # CONFIG_I2C_ELEKTOR is not set | 538 | # CONFIG_I2C_ELEKTOR is not set |
539 | # CONFIG_I2C_ISA is not set | ||
540 | # CONFIG_I2C_PARPORT is not set | 539 | # CONFIG_I2C_PARPORT is not set |
541 | # CONFIG_I2C_PARPORT_LIGHT is not set | 540 | # CONFIG_I2C_PARPORT_LIGHT is not set |
542 | # CONFIG_I2C_PCA_ISA is not set | 541 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig index 2a612d23120b..299dc22294a0 100644 --- a/arch/arm/configs/footbridge_defconfig +++ b/arch/arm/configs/footbridge_defconfig | |||
@@ -748,7 +748,6 @@ CONFIG_I2C=m | |||
748 | # CONFIG_I2C_ELEKTOR is not set | 748 | # CONFIG_I2C_ELEKTOR is not set |
749 | # CONFIG_I2C_I801 is not set | 749 | # CONFIG_I2C_I801 is not set |
750 | # CONFIG_I2C_I810 is not set | 750 | # CONFIG_I2C_I810 is not set |
751 | # CONFIG_I2C_ISA is not set | ||
752 | # CONFIG_I2C_NFORCE2 is not set | 751 | # CONFIG_I2C_NFORCE2 is not set |
753 | # CONFIG_I2C_PARPORT is not set | 752 | # CONFIG_I2C_PARPORT is not set |
754 | # CONFIG_I2C_PARPORT_LIGHT is not set | 753 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig index e86794a10fc0..92ccdc6492f7 100644 --- a/arch/arm/configs/neponset_defconfig +++ b/arch/arm/configs/neponset_defconfig | |||
@@ -698,7 +698,6 @@ CONFIG_I2C_ALGOBIT=y | |||
698 | # I2C Hardware Bus support | 698 | # I2C Hardware Bus support |
699 | # | 699 | # |
700 | # CONFIG_I2C_ELEKTOR is not set | 700 | # CONFIG_I2C_ELEKTOR is not set |
701 | # CONFIG_I2C_ISA is not set | ||
702 | # CONFIG_I2C_PARPORT_LIGHT is not set | 701 | # CONFIG_I2C_PARPORT_LIGHT is not set |
703 | # CONFIG_I2C_STUB is not set | 702 | # CONFIG_I2C_STUB is not set |
704 | # CONFIG_I2C_PCA_ISA is not set | 703 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig index 339c48953a62..3c0c4f192dc1 100644 --- a/arch/arm/configs/picotux200_defconfig +++ b/arch/arm/configs/picotux200_defconfig | |||
@@ -735,7 +735,6 @@ CONFIG_I2C_CHARDEV=m | |||
735 | # I2C Hardware Bus support | 735 | # I2C Hardware Bus support |
736 | # | 736 | # |
737 | CONFIG_I2C_AT91=m | 737 | CONFIG_I2C_AT91=m |
738 | CONFIG_I2C_ISA=m | ||
739 | # CONFIG_I2C_OCORES is not set | 738 | # CONFIG_I2C_OCORES is not set |
740 | # CONFIG_I2C_PARPORT_LIGHT is not set | 739 | # CONFIG_I2C_PARPORT_LIGHT is not set |
741 | # CONFIG_I2C_STUB is not set | 740 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index bc091264d354..8452dc8c7cc3 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig | |||
@@ -558,7 +558,6 @@ CONFIG_I2C_ALGOBIT=y | |||
558 | # | 558 | # |
559 | # I2C Hardware Bus support | 559 | # I2C Hardware Bus support |
560 | # | 560 | # |
561 | # CONFIG_I2C_ISA is not set | ||
562 | # CONFIG_I2C_PARPORT is not set | 561 | # CONFIG_I2C_PARPORT is not set |
563 | # CONFIG_I2C_PARPORT_LIGHT is not set | 562 | # CONFIG_I2C_PARPORT_LIGHT is not set |
564 | # CONFIG_I2C_STUB is not set | 563 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index a850da377a29..1d5150e4d6b3 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
@@ -826,7 +826,6 @@ CONFIG_I2C_ALGOBIT=m | |||
826 | # I2C Hardware Bus support | 826 | # I2C Hardware Bus support |
827 | # | 827 | # |
828 | # CONFIG_I2C_ELEKTOR is not set | 828 | # CONFIG_I2C_ELEKTOR is not set |
829 | CONFIG_I2C_ISA=m | ||
830 | # CONFIG_I2C_OCORES is not set | 829 | # CONFIG_I2C_OCORES is not set |
831 | # CONFIG_I2C_PARPORT is not set | 830 | # CONFIG_I2C_PARPORT is not set |
832 | # CONFIG_I2C_PARPORT_LIGHT is not set | 831 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/m32r/m32104ut/defconfig.m32104ut b/arch/m32r/m32104ut/defconfig.m32104ut index 7b68fe8d921e..1f88f493a9e2 100644 --- a/arch/m32r/m32104ut/defconfig.m32104ut +++ b/arch/m32r/m32104ut/defconfig.m32104ut | |||
@@ -699,7 +699,6 @@ CONFIG_I2C_ALGOPCF=m | |||
699 | # I2C Hardware Bus support | 699 | # I2C Hardware Bus support |
700 | # | 700 | # |
701 | CONFIG_I2C_ELEKTOR=m | 701 | CONFIG_I2C_ELEKTOR=m |
702 | CONFIG_I2C_ISA=m | ||
703 | # CONFIG_I2C_OCORES is not set | 702 | # CONFIG_I2C_OCORES is not set |
704 | # CONFIG_I2C_PARPORT is not set | 703 | # CONFIG_I2C_PARPORT is not set |
705 | # CONFIG_I2C_PARPORT_LIGHT is not set | 704 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/ev64260_defconfig b/arch/ppc/configs/ev64260_defconfig index 84cc142a67bb..587e9a3b9491 100644 --- a/arch/ppc/configs/ev64260_defconfig +++ b/arch/ppc/configs/ev64260_defconfig | |||
@@ -531,7 +531,6 @@ CONFIG_I2C_CHARDEV=m | |||
531 | # CONFIG_I2C_AMD8111 is not set | 531 | # CONFIG_I2C_AMD8111 is not set |
532 | # CONFIG_I2C_I801 is not set | 532 | # CONFIG_I2C_I801 is not set |
533 | # CONFIG_I2C_I810 is not set | 533 | # CONFIG_I2C_I810 is not set |
534 | # CONFIG_I2C_ISA is not set | ||
535 | # CONFIG_I2C_NFORCE2 is not set | 534 | # CONFIG_I2C_NFORCE2 is not set |
536 | # CONFIG_I2C_PARPORT_LIGHT is not set | 535 | # CONFIG_I2C_PARPORT_LIGHT is not set |
537 | # CONFIG_I2C_PIIX4 is not set | 536 | # CONFIG_I2C_PIIX4 is not set |
diff --git a/arch/ppc/configs/mpc8540_ads_defconfig b/arch/ppc/configs/mpc8540_ads_defconfig index c5c86025e261..bf676ebd99ab 100644 --- a/arch/ppc/configs/mpc8540_ads_defconfig +++ b/arch/ppc/configs/mpc8540_ads_defconfig | |||
@@ -452,7 +452,6 @@ CONFIG_I2C_CHARDEV=y | |||
452 | # CONFIG_I2C_AMD8111 is not set | 452 | # CONFIG_I2C_AMD8111 is not set |
453 | # CONFIG_I2C_I801 is not set | 453 | # CONFIG_I2C_I801 is not set |
454 | # CONFIG_I2C_I810 is not set | 454 | # CONFIG_I2C_I810 is not set |
455 | # CONFIG_I2C_ISA is not set | ||
456 | CONFIG_I2C_MPC=y | 455 | CONFIG_I2C_MPC=y |
457 | # CONFIG_I2C_NFORCE2 is not set | 456 | # CONFIG_I2C_NFORCE2 is not set |
458 | # CONFIG_I2C_PARPORT_LIGHT is not set | 457 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/mpc8548_cds_defconfig b/arch/ppc/configs/mpc8548_cds_defconfig index abe034f24b83..f36fc5db540b 100644 --- a/arch/ppc/configs/mpc8548_cds_defconfig +++ b/arch/ppc/configs/mpc8548_cds_defconfig | |||
@@ -413,7 +413,6 @@ CONFIG_I2C_CHARDEV=y | |||
413 | # | 413 | # |
414 | # I2C Hardware Bus support | 414 | # I2C Hardware Bus support |
415 | # | 415 | # |
416 | # CONFIG_I2C_ISA is not set | ||
417 | CONFIG_I2C_MPC=y | 416 | CONFIG_I2C_MPC=y |
418 | # CONFIG_I2C_PARPORT_LIGHT is not set | 417 | # CONFIG_I2C_PARPORT_LIGHT is not set |
419 | # CONFIG_I2C_PCA_ISA is not set | 418 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig index 15abebf46b96..4f1e320acfbe 100644 --- a/arch/ppc/configs/mpc8555_cds_defconfig +++ b/arch/ppc/configs/mpc8555_cds_defconfig | |||
@@ -518,7 +518,6 @@ CONFIG_I2C_CHARDEV=y | |||
518 | # CONFIG_I2C_I801 is not set | 518 | # CONFIG_I2C_I801 is not set |
519 | # CONFIG_I2C_I810 is not set | 519 | # CONFIG_I2C_I810 is not set |
520 | # CONFIG_I2C_PIIX4 is not set | 520 | # CONFIG_I2C_PIIX4 is not set |
521 | # CONFIG_I2C_ISA is not set | ||
522 | CONFIG_I2C_MPC=y | 521 | CONFIG_I2C_MPC=y |
523 | # CONFIG_I2C_NFORCE2 is not set | 522 | # CONFIG_I2C_NFORCE2 is not set |
524 | # CONFIG_I2C_PARPORT_LIGHT is not set | 523 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/mpc8560_ads_defconfig b/arch/ppc/configs/mpc8560_ads_defconfig index f834fb541ad5..f12d48fcbba7 100644 --- a/arch/ppc/configs/mpc8560_ads_defconfig +++ b/arch/ppc/configs/mpc8560_ads_defconfig | |||
@@ -489,7 +489,6 @@ CONFIG_I2C_CHARDEV=y | |||
489 | # CONFIG_I2C_I801 is not set | 489 | # CONFIG_I2C_I801 is not set |
490 | # CONFIG_I2C_I810 is not set | 490 | # CONFIG_I2C_I810 is not set |
491 | # CONFIG_I2C_PIIX4 is not set | 491 | # CONFIG_I2C_PIIX4 is not set |
492 | # CONFIG_I2C_ISA is not set | ||
493 | CONFIG_I2C_MPC=y | 492 | CONFIG_I2C_MPC=y |
494 | # CONFIG_I2C_NFORCE2 is not set | 493 | # CONFIG_I2C_NFORCE2 is not set |
495 | # CONFIG_I2C_PARPORT_LIGHT is not set | 494 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/radstone_ppc7d_defconfig b/arch/ppc/configs/radstone_ppc7d_defconfig index ca4d1fd0ca05..9f64532f2a81 100644 --- a/arch/ppc/configs/radstone_ppc7d_defconfig +++ b/arch/ppc/configs/radstone_ppc7d_defconfig | |||
@@ -710,7 +710,6 @@ CONFIG_I2C_CHARDEV=y | |||
710 | # CONFIG_I2C_I801 is not set | 710 | # CONFIG_I2C_I801 is not set |
711 | # CONFIG_I2C_I810 is not set | 711 | # CONFIG_I2C_I810 is not set |
712 | # CONFIG_I2C_PIIX4 is not set | 712 | # CONFIG_I2C_PIIX4 is not set |
713 | # CONFIG_I2C_ISA is not set | ||
714 | # CONFIG_I2C_MPC is not set | 713 | # CONFIG_I2C_MPC is not set |
715 | # CONFIG_I2C_NFORCE2 is not set | 714 | # CONFIG_I2C_NFORCE2 is not set |
716 | # CONFIG_I2C_PARPORT_LIGHT is not set | 715 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig index 3fedc43e44ad..70d6f842aa9b 100644 --- a/arch/ppc/configs/stx_gp3_defconfig +++ b/arch/ppc/configs/stx_gp3_defconfig | |||
@@ -661,7 +661,6 @@ CONFIG_I2C_ALGOBIT=m | |||
661 | # CONFIG_I2C_I801 is not set | 661 | # CONFIG_I2C_I801 is not set |
662 | # CONFIG_I2C_I810 is not set | 662 | # CONFIG_I2C_I810 is not set |
663 | # CONFIG_I2C_PIIX4 is not set | 663 | # CONFIG_I2C_PIIX4 is not set |
664 | # CONFIG_I2C_ISA is not set | ||
665 | # CONFIG_I2C_MPC is not set | 664 | # CONFIG_I2C_MPC is not set |
666 | # CONFIG_I2C_NFORCE2 is not set | 665 | # CONFIG_I2C_NFORCE2 is not set |
667 | # CONFIG_I2C_PARPORT is not set | 666 | # CONFIG_I2C_PARPORT is not set |
diff --git a/arch/ppc/configs/sycamore_defconfig b/arch/ppc/configs/sycamore_defconfig index 758114cfea5c..6996cca18f3e 100644 --- a/arch/ppc/configs/sycamore_defconfig +++ b/arch/ppc/configs/sycamore_defconfig | |||
@@ -461,7 +461,6 @@ CONFIG_I2C_CHARDEV=y | |||
461 | # CONFIG_I2C_I801 is not set | 461 | # CONFIG_I2C_I801 is not set |
462 | # CONFIG_I2C_I810 is not set | 462 | # CONFIG_I2C_I810 is not set |
463 | # CONFIG_I2C_IBM_IIC is not set | 463 | # CONFIG_I2C_IBM_IIC is not set |
464 | # CONFIG_I2C_ISA is not set | ||
465 | # CONFIG_I2C_NFORCE2 is not set | 464 | # CONFIG_I2C_NFORCE2 is not set |
466 | # CONFIG_I2C_PARPORT_LIGHT is not set | 465 | # CONFIG_I2C_PARPORT_LIGHT is not set |
467 | # CONFIG_I2C_PIIX4 is not set | 466 | # CONFIG_I2C_PIIX4 is not set |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 13eea47dceb3..dbdca6f10e46 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -29,17 +29,34 @@ config HWMON_VID | |||
29 | default n | 29 | default n |
30 | 30 | ||
31 | config SENSORS_ABITUGURU | 31 | config SENSORS_ABITUGURU |
32 | tristate "Abit uGuru" | 32 | tristate "Abit uGuru (rev 1 & 2)" |
33 | depends on EXPERIMENTAL | 33 | depends on EXPERIMENTAL |
34 | help | 34 | help |
35 | If you say yes here you get support for the Abit uGuru chips | 35 | If you say yes here you get support for the sensor part of the first |
36 | sensor part. The voltage and frequency control parts of the Abit | 36 | and second revision of the Abit uGuru chip. The voltage and frequency |
37 | uGuru are not supported. The Abit uGuru chip can be found on Abit | 37 | control parts of the Abit uGuru are not supported. The Abit uGuru |
38 | uGuru featuring motherboards (most modern Abit motherboards). | 38 | chip can be found on Abit uGuru featuring motherboards (most modern |
39 | Abit motherboards from before end 2005). For more info and a list | ||
40 | of which motherboards have which revision see | ||
41 | Documentation/hwmon/abituguru | ||
39 | 42 | ||
40 | This driver can also be built as a module. If so, the module | 43 | This driver can also be built as a module. If so, the module |
41 | will be called abituguru. | 44 | will be called abituguru. |
42 | 45 | ||
46 | config SENSORS_ABITUGURU3 | ||
47 | tristate "Abit uGuru (rev 3)" | ||
48 | depends on HWMON && EXPERIMENTAL | ||
49 | help | ||
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 | ||
52 | and their settings is supported. The third revision of the Abit | ||
53 | uGuru chip can be found on recent Abit motherboards (since end | ||
54 | 2005). For more info and a list of which motherboards have which | ||
55 | revision see Documentation/hwmon/abituguru3 | ||
56 | |||
57 | This driver can also be built as a module. If so, the module | ||
58 | will be called abituguru3. | ||
59 | |||
43 | config SENSORS_AD7418 | 60 | config SENSORS_AD7418 |
44 | tristate "Analog Devices AD7416, AD7417 and AD7418" | 61 | tristate "Analog Devices AD7416, AD7417 and AD7418" |
45 | depends on I2C && EXPERIMENTAL | 62 | depends on I2C && EXPERIMENTAL |
@@ -250,12 +267,10 @@ config SENSORS_CORETEMP | |||
250 | 267 | ||
251 | config SENSORS_IT87 | 268 | config SENSORS_IT87 |
252 | tristate "ITE IT87xx and compatibles" | 269 | tristate "ITE IT87xx and compatibles" |
253 | depends on I2C | ||
254 | select I2C_ISA | ||
255 | select HWMON_VID | 270 | select HWMON_VID |
256 | help | 271 | help |
257 | If you say yes here you get support for ITE IT8705F, IT8712F, | 272 | If you say yes here you get support for ITE IT8705F, IT8712F, |
258 | IT8716F and IT8718F sensor chips, and the SiS960 clone. | 273 | IT8716F, IT8718F and IT8726F sensor chips, and the SiS960 clone. |
259 | 274 | ||
260 | This driver can also be built as a module. If so, the module | 275 | This driver can also be built as a module. If so, the module |
261 | will be called it87. | 276 | will be called it87. |
@@ -365,8 +380,8 @@ config SENSORS_LM90 | |||
365 | depends on I2C | 380 | depends on I2C |
366 | help | 381 | help |
367 | If you say yes here you get support for National Semiconductor LM90, | 382 | If you say yes here you get support for National Semiconductor LM90, |
368 | LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and | 383 | LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657, |
369 | MAX6658 sensor chips. | 384 | MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips. |
370 | 385 | ||
371 | The Analog Devices ADT7461 sensor chip is also supported, but only | 386 | The Analog Devices ADT7461 sensor chip is also supported, but only |
372 | if found in ADM1032 compatibility mode. | 387 | if found in ADM1032 compatibility mode. |
@@ -384,6 +399,17 @@ config SENSORS_LM92 | |||
384 | This driver can also be built as a module. If so, the module | 399 | This driver can also be built as a module. If so, the module |
385 | will be called lm92. | 400 | will be called lm92. |
386 | 401 | ||
402 | config SENSORS_LM93 | ||
403 | tristate "National Semiconductor LM93 and compatibles" | ||
404 | depends on HWMON && I2C | ||
405 | select HWMON_VID | ||
406 | help | ||
407 | If you say yes here you get support for National Semiconductor LM93 | ||
408 | sensor chips. | ||
409 | |||
410 | This driver can also be built as a module. If so, the module | ||
411 | will be called lm93. | ||
412 | |||
387 | config SENSORS_MAX1619 | 413 | config SENSORS_MAX1619 |
388 | tristate "Maxim MAX1619 sensor chip" | 414 | tristate "Maxim MAX1619 sensor chip" |
389 | depends on I2C | 415 | depends on I2C |
@@ -405,8 +431,6 @@ config SENSORS_MAX6650 | |||
405 | 431 | ||
406 | config SENSORS_PC87360 | 432 | config SENSORS_PC87360 |
407 | tristate "National Semiconductor PC87360 family" | 433 | tristate "National Semiconductor PC87360 family" |
408 | depends on I2C && EXPERIMENTAL | ||
409 | select I2C_ISA | ||
410 | select HWMON_VID | 434 | select HWMON_VID |
411 | help | 435 | help |
412 | If you say yes here you get access to the hardware monitoring | 436 | If you say yes here you get access to the hardware monitoring |
@@ -433,8 +457,7 @@ config SENSORS_PC87427 | |||
433 | 457 | ||
434 | config SENSORS_SIS5595 | 458 | config SENSORS_SIS5595 |
435 | tristate "Silicon Integrated Systems Corp. SiS5595" | 459 | tristate "Silicon Integrated Systems Corp. SiS5595" |
436 | depends on I2C && PCI && EXPERIMENTAL | 460 | depends on PCI |
437 | select I2C_ISA | ||
438 | help | 461 | help |
439 | If you say yes here you get support for the integrated sensors in | 462 | If you say yes here you get support for the integrated sensors in |
440 | SiS5595 South Bridges. | 463 | SiS5595 South Bridges. |
@@ -442,6 +465,18 @@ config SENSORS_SIS5595 | |||
442 | This driver can also be built as a module. If so, the module | 465 | This driver can also be built as a module. If so, the module |
443 | will be called sis5595. | 466 | will be called sis5595. |
444 | 467 | ||
468 | config SENSORS_DME1737 | ||
469 | tristate "SMSC DME1737 and compatibles" | ||
470 | depends on I2C && EXPERIMENTAL | ||
471 | select HWMON_VID | ||
472 | help | ||
473 | If you say yes here you get support for the hardware monitoring | ||
474 | and fan control features of the SMSC DME1737 (and compatibles | ||
475 | like the Asus A8000) Super-I/O chip. | ||
476 | |||
477 | This driver can also be built as a module. If so, the module | ||
478 | will be called dme1737. | ||
479 | |||
445 | config SENSORS_SMSC47M1 | 480 | config SENSORS_SMSC47M1 |
446 | tristate "SMSC LPC47M10x and compatibles" | 481 | tristate "SMSC LPC47M10x and compatibles" |
447 | help | 482 | help |
@@ -487,8 +522,7 @@ config SENSORS_SMSC47B397 | |||
487 | 522 | ||
488 | config SENSORS_VIA686A | 523 | config SENSORS_VIA686A |
489 | tristate "VIA686A" | 524 | tristate "VIA686A" |
490 | depends on I2C && PCI | 525 | depends on PCI |
491 | select I2C_ISA | ||
492 | help | 526 | help |
493 | If you say yes here you get support for the integrated sensors in | 527 | If you say yes here you get support for the integrated sensors in |
494 | Via 686A/B South Bridges. | 528 | Via 686A/B South Bridges. |
@@ -509,9 +543,8 @@ config SENSORS_VT1211 | |||
509 | 543 | ||
510 | config SENSORS_VT8231 | 544 | config SENSORS_VT8231 |
511 | tristate "VIA VT8231" | 545 | tristate "VIA VT8231" |
512 | depends on I2C && PCI && EXPERIMENTAL | 546 | depends on PCI |
513 | select HWMON_VID | 547 | select HWMON_VID |
514 | select I2C_ISA | ||
515 | help | 548 | help |
516 | If you say yes here then you get support for the integrated sensors | 549 | If you say yes here then you get support for the integrated sensors |
517 | in the VIA VT8231 device. | 550 | in the VIA VT8231 device. |
@@ -584,17 +617,16 @@ config SENSORS_W83627HF | |||
584 | will be called w83627hf. | 617 | will be called w83627hf. |
585 | 618 | ||
586 | config SENSORS_W83627EHF | 619 | config SENSORS_W83627EHF |
587 | tristate "Winbond W83627EHF" | 620 | tristate "Winbond W83627EHF/DHG" |
588 | depends on I2C && EXPERIMENTAL | 621 | select HWMON_VID |
589 | select I2C_ISA | ||
590 | help | 622 | help |
591 | If you say yes here you get preliminary support for the hardware | 623 | If you say yes here you get support for the hardware |
592 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. | 624 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. |
593 | Only fan and temperature inputs are supported at the moment, while | ||
594 | the chip does much more than that. | ||
595 | 625 | ||
596 | This driver also supports the W83627EHG, which is the lead-free | 626 | This driver also supports the W83627EHG, which is the lead-free |
597 | version of the W83627EHF. | 627 | version of the W83627EHF, and the W83627DHG, which is a similar |
628 | chip suited for specific Intel processors that use PECI such as | ||
629 | the Core 2 Duo. | ||
598 | 630 | ||
599 | This driver can also be built as a module. If so, the module | 631 | This driver can also be built as a module. If so, the module |
600 | will be called w83627ehf. | 632 | will be called w83627ehf. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index cfaf338919dd..59f81fae40a0 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_SENSORS_W83781D) += w83781d.o | |||
14 | obj-$(CONFIG_SENSORS_W83791D) += w83791d.o | 14 | obj-$(CONFIG_SENSORS_W83791D) += w83791d.o |
15 | 15 | ||
16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o |
17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | ||
17 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 18 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
18 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o | 19 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o |
19 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o | 20 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o |
@@ -25,6 +26,7 @@ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | |||
25 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 26 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
26 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 27 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
27 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | 28 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o |
29 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | ||
28 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 30 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
29 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 31 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
30 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 32 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
@@ -45,6 +47,7 @@ obj-$(CONFIG_SENSORS_LM85) += lm85.o | |||
45 | obj-$(CONFIG_SENSORS_LM87) += lm87.o | 47 | obj-$(CONFIG_SENSORS_LM87) += lm87.o |
46 | obj-$(CONFIG_SENSORS_LM90) += lm90.o | 48 | obj-$(CONFIG_SENSORS_LM90) += lm90.o |
47 | obj-$(CONFIG_SENSORS_LM92) += lm92.o | 49 | obj-$(CONFIG_SENSORS_LM92) += lm92.o |
50 | obj-$(CONFIG_SENSORS_LM93) += lm93.o | ||
48 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 51 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
49 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 52 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
50 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 53 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index bede4d990ea6..d575ee958de5 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -16,9 +16,9 @@ | |||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | */ | 17 | */ |
18 | /* | 18 | /* |
19 | This driver supports the sensor part of the custom Abit uGuru chip found | 19 | This driver supports the sensor part of the first and second revision of |
20 | on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM / | 20 | the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because |
21 | etc voltage & frequency control is not supported! | 21 | of lack of specs the CPU/RAM voltage & frequency control is not supported! |
22 | */ | 22 | */ |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
33 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
34 | #include <linux/dmi.h> | ||
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | 36 | ||
36 | /* Banks */ | 37 | /* Banks */ |
@@ -418,7 +419,7 @@ static int __devinit | |||
418 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | 419 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, |
419 | u8 sensor_addr) | 420 | u8 sensor_addr) |
420 | { | 421 | { |
421 | u8 val, buf[3]; | 422 | u8 val, test_flag, buf[3]; |
422 | int i, ret = -ENODEV; /* error is the most common used retval :| */ | 423 | int i, ret = -ENODEV; /* error is the most common used retval :| */ |
423 | 424 | ||
424 | /* If overriden by the user return the user selected type */ | 425 | /* If overriden by the user return the user selected type */ |
@@ -436,7 +437,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
436 | return -ENODEV; | 437 | return -ENODEV; |
437 | 438 | ||
438 | /* Test val is sane / usable for sensor type detection. */ | 439 | /* Test val is sane / usable for sensor type detection. */ |
439 | if ((val < 10u) || (val > 240u)) { | 440 | if ((val < 10u) || (val > 250u)) { |
440 | printk(KERN_WARNING ABIT_UGURU_NAME | 441 | printk(KERN_WARNING ABIT_UGURU_NAME |
441 | ": bank1-sensor: %d reading (%d) too close to limits, " | 442 | ": bank1-sensor: %d reading (%d) too close to limits, " |
442 | "unable to determine sensor type, skipping sensor\n", | 443 | "unable to determine sensor type, skipping sensor\n", |
@@ -449,10 +450,20 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
449 | 450 | ||
450 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); | 451 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); |
451 | /* Volt sensor test, enable volt low alarm, set min value ridicously | 452 | /* Volt sensor test, enable volt low alarm, set min value ridicously |
452 | high. If its a volt sensor this should always give us an alarm. */ | 453 | high, or vica versa if the reading is very high. If its a volt |
453 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; | 454 | sensor this should always give us an alarm. */ |
454 | buf[1] = 245; | 455 | if (val <= 240u) { |
455 | buf[2] = 250; | 456 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; |
457 | buf[1] = 245; | ||
458 | buf[2] = 250; | ||
459 | test_flag = ABIT_UGURU_VOLT_LOW_ALARM_FLAG; | ||
460 | } else { | ||
461 | buf[0] = ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE; | ||
462 | buf[1] = 5; | ||
463 | buf[2] = 10; | ||
464 | test_flag = ABIT_UGURU_VOLT_HIGH_ALARM_FLAG; | ||
465 | } | ||
466 | |||
456 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, | 467 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, |
457 | buf, 3) != 3) | 468 | buf, 3) != 3) |
458 | goto abituguru_detect_bank1_sensor_type_exit; | 469 | goto abituguru_detect_bank1_sensor_type_exit; |
@@ -469,13 +480,13 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
469 | sensor_addr, buf, 3, | 480 | sensor_addr, buf, 3, |
470 | ABIT_UGURU_MAX_RETRIES) != 3) | 481 | ABIT_UGURU_MAX_RETRIES) != 3) |
471 | goto abituguru_detect_bank1_sensor_type_exit; | 482 | goto abituguru_detect_bank1_sensor_type_exit; |
472 | if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { | 483 | if (buf[0] & test_flag) { |
473 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); | 484 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); |
474 | ret = ABIT_UGURU_IN_SENSOR; | 485 | ret = ABIT_UGURU_IN_SENSOR; |
475 | goto abituguru_detect_bank1_sensor_type_exit; | 486 | goto abituguru_detect_bank1_sensor_type_exit; |
476 | } else | 487 | } else |
477 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " | 488 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " |
478 | "sensor test, but volt low flag not set\n"); | 489 | "sensor test, but volt range flag not set\n"); |
479 | } else | 490 | } else |
480 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " | 491 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " |
481 | "test\n"); | 492 | "test\n"); |
@@ -1287,6 +1298,7 @@ abituguru_probe_error: | |||
1287 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1298 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
1288 | device_remove_file(&pdev->dev, | 1299 | device_remove_file(&pdev->dev, |
1289 | &abituguru_sysfs_attr[i].dev_attr); | 1300 | &abituguru_sysfs_attr[i].dev_attr); |
1301 | platform_set_drvdata(pdev, NULL); | ||
1290 | kfree(data); | 1302 | kfree(data); |
1291 | return res; | 1303 | return res; |
1292 | } | 1304 | } |
@@ -1296,13 +1308,13 @@ static int __devexit abituguru_remove(struct platform_device *pdev) | |||
1296 | int i; | 1308 | int i; |
1297 | struct abituguru_data *data = platform_get_drvdata(pdev); | 1309 | struct abituguru_data *data = platform_get_drvdata(pdev); |
1298 | 1310 | ||
1299 | platform_set_drvdata(pdev, NULL); | ||
1300 | hwmon_device_unregister(data->class_dev); | 1311 | hwmon_device_unregister(data->class_dev); |
1301 | 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++) |
1302 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
1303 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
1304 | device_remove_file(&pdev->dev, | 1315 | device_remove_file(&pdev->dev, |
1305 | &abituguru_sysfs_attr[i].dev_attr); | 1316 | &abituguru_sysfs_attr[i].dev_attr); |
1317 | platform_set_drvdata(pdev, NULL); | ||
1306 | kfree(data); | 1318 | kfree(data); |
1307 | 1319 | ||
1308 | return 0; | 1320 | return 0; |
@@ -1436,6 +1448,15 @@ static int __init abituguru_init(void) | |||
1436 | int address, err; | 1448 | int address, err; |
1437 | struct resource res = { .flags = IORESOURCE_IO }; | 1449 | struct resource res = { .flags = IORESOURCE_IO }; |
1438 | 1450 | ||
1451 | #ifdef CONFIG_DMI | ||
1452 | char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
1453 | |||
1454 | /* safety check, refuse to load on non Abit motherboards */ | ||
1455 | if (!force && (!board_vendor || | ||
1456 | strcmp(board_vendor, "http://www.abit.com.tw/"))) | ||
1457 | return -ENODEV; | ||
1458 | #endif | ||
1459 | |||
1439 | address = abituguru_detect(); | 1460 | address = abituguru_detect(); |
1440 | if (address < 0) | 1461 | if (address < 0) |
1441 | return address; | 1462 | return address; |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c new file mode 100644 index 000000000000..a003d104ca45 --- /dev/null +++ b/drivers/hwmon/abituguru3.c | |||
@@ -0,0 +1,1140 @@ | |||
1 | /* | ||
2 | abituguru3.c Copyright (c) 2006 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | /* | ||
19 | This driver supports the sensor part of revision 3 of the custom Abit uGuru | ||
20 | chip found on newer Abit uGuru motherboards. Note: because of lack of specs | ||
21 | only reading the sensors and their settings is supported. | ||
22 | */ | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/hwmon.h> | ||
32 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <asm/io.h> | ||
34 | |||
35 | /* uGuru3 bank addresses */ | ||
36 | #define ABIT_UGURU3_SETTINGS_BANK 0x01 | ||
37 | #define ABIT_UGURU3_SENSORS_BANK 0x08 | ||
38 | #define ABIT_UGURU3_MISC_BANK 0x09 | ||
39 | #define ABIT_UGURU3_ALARMS_START 0x1E | ||
40 | #define ABIT_UGURU3_SETTINGS_START 0x24 | ||
41 | #define ABIT_UGURU3_VALUES_START 0x80 | ||
42 | #define ABIT_UGURU3_BOARD_ID 0x0A | ||
43 | /* uGuru3 sensor bank flags */ /* Alarm if: */ | ||
44 | #define ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */ | ||
45 | #define ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */ | ||
46 | #define ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */ | ||
47 | #define ABIT_UGURU3_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */ | ||
48 | #define ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */ | ||
49 | #define ABIT_UGURU3_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */ | ||
50 | #define ABIT_UGURU3_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */ | ||
51 | #define ABIT_UGURU3_BEEP_ENABLE 0x08 /* beep if alarm */ | ||
52 | #define ABIT_UGURU3_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */ | ||
53 | /* sensor types */ | ||
54 | #define ABIT_UGURU3_IN_SENSOR 0 | ||
55 | #define ABIT_UGURU3_TEMP_SENSOR 1 | ||
56 | #define ABIT_UGURU3_FAN_SENSOR 2 | ||
57 | |||
58 | /* Timeouts / Retries, if these turn out to need a lot of fiddling we could | ||
59 | convert them to params. Determined by trial and error. I assume this is | ||
60 | cpu-speed independent, since the ISA-bus and not the CPU should be the | ||
61 | bottleneck. */ | ||
62 | #define ABIT_UGURU3_WAIT_TIMEOUT 250 | ||
63 | /* Normally the 0xAC at the end of synchronize() is reported after the | ||
64 | first read, but sometimes not and we need to poll */ | ||
65 | #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 | ||
66 | /* utility macros */ | ||
67 | #define ABIT_UGURU3_NAME "abituguru3" | ||
68 | #define ABIT_UGURU3_DEBUG(format, arg...) \ | ||
69 | if (verbose) \ | ||
70 | printk(KERN_DEBUG ABIT_UGURU3_NAME ": " format , ## arg) | ||
71 | |||
72 | /* Macros to help calculate the sysfs_names array length */ | ||
73 | #define ABIT_UGURU3_MAX_NO_SENSORS 26 | ||
74 | /* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, | ||
75 | in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */ | ||
76 | #define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11) | ||
77 | /* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0, | ||
78 | temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0, | ||
79 | temp??_label\0 */ | ||
80 | #define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13) | ||
81 | /* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0, | ||
82 | fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */ | ||
83 | #define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12) | ||
84 | /* Worst case scenario 16 in sensors (longest names_length) and the rest | ||
85 | temp sensors (second longest names_length). */ | ||
86 | #define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \ | ||
87 | (ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH) | ||
88 | |||
89 | /* All the macros below are named identical to the openguru2 program | ||
90 | reverse engineered by Louis Kruger, hence the names might not be 100% | ||
91 | logical. I could come up with better names, but I prefer keeping the names | ||
92 | identical so that this driver can be compared with his work more easily. */ | ||
93 | /* Two i/o-ports are used by uGuru */ | ||
94 | #define ABIT_UGURU3_BASE 0x00E0 | ||
95 | #define ABIT_UGURU3_CMD 0x00 | ||
96 | #define ABIT_UGURU3_DATA 0x04 | ||
97 | #define ABIT_UGURU3_REGION_LENGTH 5 | ||
98 | /* The wait_xxx functions return this on success and the last contents | ||
99 | of the DATA register (0-255) on failure. */ | ||
100 | #define ABIT_UGURU3_SUCCESS -1 | ||
101 | /* uGuru status flags */ | ||
102 | #define ABIT_UGURU3_STATUS_READY_FOR_READ 0x01 | ||
103 | #define ABIT_UGURU3_STATUS_BUSY 0x02 | ||
104 | |||
105 | |||
106 | /* Structures */ | ||
107 | struct abituguru3_sensor_info { | ||
108 | const char* name; | ||
109 | int port; | ||
110 | int type; | ||
111 | int multiplier; | ||
112 | int divisor; | ||
113 | int offset; | ||
114 | }; | ||
115 | |||
116 | struct abituguru3_motherboard_info { | ||
117 | u16 id; | ||
118 | const char *name; | ||
119 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ | ||
120 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; | ||
121 | }; | ||
122 | |||
123 | /* For the Abit uGuru, we need to keep some data in memory. | ||
124 | The structure is dynamically allocated, at the same time when a new | ||
125 | abituguru3 device is allocated. */ | ||
126 | struct abituguru3_data { | ||
127 | struct class_device *class_dev; /* hwmon registered device */ | ||
128 | struct mutex update_lock; /* protect access to data and uGuru */ | ||
129 | unsigned short addr; /* uguru base address */ | ||
130 | char valid; /* !=0 if following fields are valid */ | ||
131 | unsigned long last_updated; /* In jiffies */ | ||
132 | |||
133 | /* For convenience the sysfs attr and their names are generated | ||
134 | automatically. We have max 10 entries per sensor (for in sensors) */ | ||
135 | struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS | ||
136 | * 10]; | ||
137 | |||
138 | /* Buffer to store the dynamically generated sysfs names */ | ||
139 | char sysfs_names[ABIT_UGURU3_SYSFS_NAMES_LENGTH]; | ||
140 | |||
141 | /* Pointer to the sensors info for the detected motherboard */ | ||
142 | const struct abituguru3_sensor_info *sensors; | ||
143 | |||
144 | /* The abituguru3 supports upto 48 sensors, and thus has registers | ||
145 | sets for 48 sensors, for convienence reasons / simplicity of the | ||
146 | code we always read and store all registers for all 48 sensors */ | ||
147 | |||
148 | /* Alarms for all 48 sensors (1 bit per sensor) */ | ||
149 | u8 alarms[48/8]; | ||
150 | |||
151 | /* Value of all 48 sensors */ | ||
152 | u8 value[48]; | ||
153 | |||
154 | /* Settings of all 48 sensors, note in and temp sensors (the first 32 | ||
155 | sensors) have 3 bytes of settings, while fans only have 2 bytes, | ||
156 | for convenience we use 3 bytes for all sensors */ | ||
157 | u8 settings[48][3]; | ||
158 | }; | ||
159 | |||
160 | |||
161 | /* Constants */ | ||
162 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | ||
163 | { 0x000C, "unknown", { | ||
164 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
165 | { "DDR", 1, 0, 10, 1, 0 }, | ||
166 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
167 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
168 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
169 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
170 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
171 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
172 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
173 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
174 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
175 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
176 | { "CPU", 24, 1, 1, 1, 0 }, | ||
177 | { "System ", 25, 1, 1, 1, 0 }, | ||
178 | { "PWM", 26, 1, 1, 1, 0 }, | ||
179 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
180 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
181 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
182 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
183 | { NULL, 0, 0, 0, 0, 0 } } | ||
184 | }, | ||
185 | { 0x000D, "Abit AW8", { | ||
186 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
187 | { "DDR", 1, 0, 10, 1, 0 }, | ||
188 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
189 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
190 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
191 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
192 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
193 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
194 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
195 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
196 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
197 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
198 | { "CPU", 24, 1, 1, 1, 0 }, | ||
199 | { "System ", 25, 1, 1, 1, 0 }, | ||
200 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
201 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
202 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
203 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
204 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
205 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
206 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
207 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
208 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
209 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
210 | { "AUX4 Fan", 38, 2, 60, 1, 0 }, | ||
211 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | ||
212 | { NULL, 0, 0, 0, 0, 0 } } | ||
213 | }, | ||
214 | { 0x000E, "AL-8", { | ||
215 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
216 | { "DDR", 1, 0, 10, 1, 0 }, | ||
217 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
218 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
219 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
220 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
221 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
222 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
223 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
224 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
225 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
226 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
227 | { "CPU", 24, 1, 1, 1, 0 }, | ||
228 | { "System ", 25, 1, 1, 1, 0 }, | ||
229 | { "PWM", 26, 1, 1, 1, 0 }, | ||
230 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
231 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
232 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
233 | { NULL, 0, 0, 0, 0, 0 } } | ||
234 | }, | ||
235 | { 0x000F, "unknown", { | ||
236 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
237 | { "DDR", 1, 0, 10, 1, 0 }, | ||
238 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
239 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
240 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
241 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
242 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
243 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
244 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
245 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
246 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
247 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
248 | { "CPU", 24, 1, 1, 1, 0 }, | ||
249 | { "System ", 25, 1, 1, 1, 0 }, | ||
250 | { "PWM", 26, 1, 1, 1, 0 }, | ||
251 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
252 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
253 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
254 | { NULL, 0, 0, 0, 0, 0 } } | ||
255 | }, | ||
256 | { 0x0010, "Abit NI8 SLI GR", { | ||
257 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
258 | { "DDR", 1, 0, 10, 1, 0 }, | ||
259 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
260 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
261 | { "NB 1.4V", 4, 0, 10, 1, 0 }, | ||
262 | { "SB 1.5V", 6, 0, 10, 1, 0 }, | ||
263 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
264 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
265 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
266 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
267 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
268 | { "CPU", 24, 1, 1, 1, 0 }, | ||
269 | { "SYS", 25, 1, 1, 1, 0 }, | ||
270 | { "PWM", 26, 1, 1, 1, 0 }, | ||
271 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
272 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
273 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
274 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
275 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, | ||
276 | { NULL, 0, 0, 0, 0, 0 } } | ||
277 | }, | ||
278 | { 0x0011, "Abit AT8 32X", { | ||
279 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
280 | { "DDR", 1, 0, 20, 1, 0 }, | ||
281 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
282 | { "CPU VDDA 2.5V", 6, 0, 20, 1, 0 }, | ||
283 | { "NB 1.8V", 4, 0, 10, 1, 0 }, | ||
284 | { "NB 1.8V Dual", 5, 0, 10, 1, 0 }, | ||
285 | { "HTV 1.2", 3, 0, 10, 1, 0 }, | ||
286 | { "PCIE 1.2V", 12, 0, 10, 1, 0 }, | ||
287 | { "NB 1.2V", 13, 0, 10, 1, 0 }, | ||
288 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
289 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
290 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
291 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
292 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
293 | { "CPU", 24, 1, 1, 1, 0 }, | ||
294 | { "NB", 25, 1, 1, 1, 0 }, | ||
295 | { "System", 26, 1, 1, 1, 0 }, | ||
296 | { "PWM", 27, 1, 1, 1, 0 }, | ||
297 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
298 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
299 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
300 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
301 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
302 | { NULL, 0, 0, 0, 0, 0 } } | ||
303 | }, | ||
304 | { 0x0012, "Abit AN8 32X", { | ||
305 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
306 | { "DDR", 1, 0, 20, 1, 0 }, | ||
307 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
308 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
309 | { "CPU VDDA 2.5V", 5, 0, 20, 1, 0 }, | ||
310 | { "NB", 4, 0, 10, 1, 0 }, | ||
311 | { "SB", 6, 0, 10, 1, 0 }, | ||
312 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
313 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
314 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
315 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
316 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
317 | { "CPU", 24, 1, 1, 1, 0 }, | ||
318 | { "SYS", 25, 1, 1, 1, 0 }, | ||
319 | { "PWM", 26, 1, 1, 1, 0 }, | ||
320 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
321 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
322 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
323 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, | ||
324 | { NULL, 0, 0, 0, 0, 0 } } | ||
325 | }, | ||
326 | { 0x0013, "unknown", { | ||
327 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
328 | { "DDR", 1, 0, 10, 1, 0 }, | ||
329 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
330 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
331 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
332 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
333 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
334 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
335 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
336 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
337 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
338 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
339 | { "CPU", 24, 1, 1, 1, 0 }, | ||
340 | { "System ", 25, 1, 1, 1, 0 }, | ||
341 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
342 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
343 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
344 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
345 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
346 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
347 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
348 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
349 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
350 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
351 | { "AUX4 Fan", 38, 2, 60, 1, 0 }, | ||
352 | { NULL, 0, 0, 0, 0, 0 } } | ||
353 | }, | ||
354 | { 0x0014, "Abit AB9 Pro", { | ||
355 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
356 | { "DDR", 1, 0, 10, 1, 0 }, | ||
357 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
358 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
359 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
360 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
361 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
362 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
363 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
364 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
365 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
366 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
367 | { "CPU", 24, 1, 1, 1, 0 }, | ||
368 | { "System ", 25, 1, 1, 1, 0 }, | ||
369 | { "PWM", 26, 1, 1, 1, 0 }, | ||
370 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
371 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
372 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
373 | { NULL, 0, 0, 0, 0, 0 } } | ||
374 | }, | ||
375 | { 0x0015, "unknown", { | ||
376 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
377 | { "DDR", 1, 0, 20, 1, 0 }, | ||
378 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
379 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
380 | { "CPU VDDA 2.5V", 5, 0, 20, 1, 0 }, | ||
381 | { "NB", 4, 0, 10, 1, 0 }, | ||
382 | { "SB", 6, 0, 10, 1, 0 }, | ||
383 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
384 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
385 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
386 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
387 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
388 | { "CPU", 24, 1, 1, 1, 0 }, | ||
389 | { "SYS", 25, 1, 1, 1, 0 }, | ||
390 | { "PWM", 26, 1, 1, 1, 0 }, | ||
391 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
392 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
393 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
394 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
395 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
396 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
397 | { NULL, 0, 0, 0, 0, 0 } } | ||
398 | }, | ||
399 | { 0x0016, "AW9D-MAX", { | ||
400 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
401 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
402 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
403 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
404 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
405 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
406 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
407 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
408 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
409 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
410 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
411 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
412 | { "CPU", 24, 1, 1, 1, 0 }, | ||
413 | { "System ", 25, 1, 1, 1, 0 }, | ||
414 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
415 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
416 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
417 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
418 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
419 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
420 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
421 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
422 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
423 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
424 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, | ||
425 | { NULL, 0, 0, 0, 0, 0 } } | ||
426 | }, | ||
427 | { 0x0017, "unknown", { | ||
428 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
429 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
430 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
431 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
432 | { "CPU VDDA 2.5V", 6, 0, 20, 1, 0 }, | ||
433 | { "NB 1.8V", 4, 0, 10, 1, 0 }, | ||
434 | { "NB 1.2V ", 13, 0, 10, 1, 0 }, | ||
435 | { "SB 1.2V", 5, 0, 10, 1, 0 }, | ||
436 | { "PCIE 1.2V", 12, 0, 10, 1, 0 }, | ||
437 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
438 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
439 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
440 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | ||
441 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | ||
442 | { "CPU", 24, 1, 1, 1, 0 }, | ||
443 | { "System ", 26, 1, 1, 1, 0 }, | ||
444 | { "PWM", 27, 1, 1, 1, 0 }, | ||
445 | { "CPU FAN", 32, 2, 60, 1, 0 }, | ||
446 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
447 | { "AUX1 FAN", 35, 2, 60, 1, 0 }, | ||
448 | { "AUX2 FAN", 36, 2, 60, 1, 0 }, | ||
449 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | ||
450 | { NULL, 0, 0, 0, 0, 0 } } | ||
451 | }, | ||
452 | { 0x0018, "unknown", { | ||
453 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
454 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
455 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
456 | { "CPU VTT", 3, 0, 10, 1, 0 }, | ||
457 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
458 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
459 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
460 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
461 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
462 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
463 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
464 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
465 | { "CPU", 24, 1, 1, 1, 0 }, | ||
466 | { "System ", 25, 1, 1, 1, 0 }, | ||
467 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
468 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
469 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
470 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
471 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
472 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
473 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
474 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
475 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
476 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
477 | { NULL, 0, 0, 0, 0, 0 } } | ||
478 | }, | ||
479 | { 0x0019, "unknown", { | ||
480 | { "CPU Core", 7, 0, 10, 1, 0 }, | ||
481 | { "DDR2", 13, 0, 20, 1, 0 }, | ||
482 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, | ||
483 | { "CPU VTT", 3, 0, 20, 1, 0 }, | ||
484 | { "NB 1.2V ", 4, 0, 10, 1, 0 }, | ||
485 | { "SB 1.5V", 6, 0, 10, 1, 0 }, | ||
486 | { "HyperTransport", 5, 0, 10, 1, 0 }, | ||
487 | { "ATX +12V (24-Pin)", 12, 0, 60, 1, 0 }, | ||
488 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
489 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
490 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | ||
491 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | ||
492 | { "CPU", 24, 1, 1, 1, 0 }, | ||
493 | { "System ", 25, 1, 1, 1, 0 }, | ||
494 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
495 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
496 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
497 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
498 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
499 | { "CPU FAN", 32, 2, 60, 1, 0 }, | ||
500 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
501 | { "AUX1 FAN", 33, 2, 60, 1, 0 }, | ||
502 | { "AUX2 FAN", 35, 2, 60, 1, 0 }, | ||
503 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | ||
504 | { NULL, 0, 0, 0, 0, 0 } } | ||
505 | }, | ||
506 | { 0x001A, "unknown", { | ||
507 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
508 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
509 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
510 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
511 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
512 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
513 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
514 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
515 | { "ATX +12V (8-pin)", 8, 0, 60, 1, 0 }, | ||
516 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
517 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
518 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
519 | { "CPU", 24, 1, 1, 1, 0 }, | ||
520 | { "System ", 25, 1, 1, 1, 0 }, | ||
521 | { "PWM ", 26, 1, 1, 1, 0 }, | ||
522 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
523 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
524 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
525 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
526 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
527 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
528 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
529 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
530 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
531 | { NULL, 0, 0, 0, 0, 0 } } | ||
532 | }, | ||
533 | { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } | ||
534 | }; | ||
535 | |||
536 | |||
537 | /* Insmod parameters */ | ||
538 | static int force; | ||
539 | module_param(force, bool, 0); | ||
540 | MODULE_PARM_DESC(force, "Set to one to force detection."); | ||
541 | /* Default verbose is 1, since this driver is still in the testing phase */ | ||
542 | static int verbose = 1; | ||
543 | module_param(verbose, bool, 0644); | ||
544 | MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting"); | ||
545 | |||
546 | |||
547 | /* wait while the uguru is busy (usually after a write) */ | ||
548 | static int abituguru3_wait_while_busy(struct abituguru3_data *data) | ||
549 | { | ||
550 | u8 x; | ||
551 | int timeout = ABIT_UGURU3_WAIT_TIMEOUT; | ||
552 | |||
553 | while ((x = inb_p(data->addr + ABIT_UGURU3_DATA)) & | ||
554 | ABIT_UGURU3_STATUS_BUSY) { | ||
555 | timeout--; | ||
556 | if (timeout == 0) | ||
557 | return x; | ||
558 | /* sleep a bit before our last try, to give the uGuru3 one | ||
559 | last chance to respond. */ | ||
560 | if (timeout == 1) | ||
561 | msleep(1); | ||
562 | } | ||
563 | return ABIT_UGURU3_SUCCESS; | ||
564 | } | ||
565 | |||
566 | /* wait till uguru is ready to be read */ | ||
567 | static int abituguru3_wait_for_read(struct abituguru3_data *data) | ||
568 | { | ||
569 | u8 x; | ||
570 | int timeout = ABIT_UGURU3_WAIT_TIMEOUT; | ||
571 | |||
572 | while (!((x = inb_p(data->addr + ABIT_UGURU3_DATA)) & | ||
573 | ABIT_UGURU3_STATUS_READY_FOR_READ)) { | ||
574 | timeout--; | ||
575 | if (timeout == 0) | ||
576 | return x; | ||
577 | /* sleep a bit before our last try, to give the uGuru3 one | ||
578 | last chance to respond. */ | ||
579 | if (timeout == 1) | ||
580 | msleep(1); | ||
581 | } | ||
582 | return ABIT_UGURU3_SUCCESS; | ||
583 | } | ||
584 | |||
585 | /* This synchronizes us with the uGuru3's protocol state machine, this | ||
586 | must be done before each command. */ | ||
587 | static int abituguru3_synchronize(struct abituguru3_data *data) | ||
588 | { | ||
589 | int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT; | ||
590 | |||
591 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
592 | ABIT_UGURU3_DEBUG("synchronize timeout during initial busy " | ||
593 | "wait, status: 0x%02x\n", x); | ||
594 | return -EIO; | ||
595 | } | ||
596 | |||
597 | outb(0x20, data->addr + ABIT_UGURU3_DATA); | ||
598 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
599 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, " | ||
600 | "status: 0x%02x\n", x); | ||
601 | return -EIO; | ||
602 | } | ||
603 | |||
604 | outb(0x10, data->addr + ABIT_UGURU3_CMD); | ||
605 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
606 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, " | ||
607 | "status: 0x%02x\n", x); | ||
608 | return -EIO; | ||
609 | } | ||
610 | |||
611 | outb(0x00, data->addr + ABIT_UGURU3_CMD); | ||
612 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
613 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, " | ||
614 | "status: 0x%02x\n", x); | ||
615 | return -EIO; | ||
616 | } | ||
617 | |||
618 | if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) { | ||
619 | ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, " | ||
620 | "status: 0x%02x\n", x); | ||
621 | return -EIO; | ||
622 | } | ||
623 | |||
624 | while ((x = inb(data->addr + ABIT_UGURU3_CMD)) != 0xAC) { | ||
625 | timeout--; | ||
626 | if (timeout == 0) { | ||
627 | ABIT_UGURU3_DEBUG("synchronize timeout cmd does not " | ||
628 | "hold 0xAC after synchronize, cmd: 0x%02x\n", | ||
629 | x); | ||
630 | return -EIO; | ||
631 | } | ||
632 | msleep(1); | ||
633 | } | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | /* Read count bytes from sensor sensor_addr in bank bank_addr and store the | ||
638 | result in buf */ | ||
639 | static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, | ||
640 | u8 count, u8 *buf) | ||
641 | { | ||
642 | int i, x; | ||
643 | |||
644 | if ((x = abituguru3_synchronize(data))) | ||
645 | return x; | ||
646 | |||
647 | outb(0x1A, data->addr + ABIT_UGURU3_DATA); | ||
648 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
649 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
650 | "sending 0x1A, status: 0x%02x\n", (unsigned int)bank, | ||
651 | (unsigned int)offset, x); | ||
652 | return -EIO; | ||
653 | } | ||
654 | |||
655 | outb(bank, data->addr + ABIT_UGURU3_CMD); | ||
656 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
657 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
658 | "sending the bank, status: 0x%02x\n", | ||
659 | (unsigned int)bank, (unsigned int)offset, x); | ||
660 | return -EIO; | ||
661 | } | ||
662 | |||
663 | outb(offset, data->addr + ABIT_UGURU3_CMD); | ||
664 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
665 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
666 | "sending the offset, status: 0x%02x\n", | ||
667 | (unsigned int)bank, (unsigned int)offset, x); | ||
668 | return -EIO; | ||
669 | } | ||
670 | |||
671 | outb(count, data->addr + ABIT_UGURU3_CMD); | ||
672 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
673 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
674 | "sending the count, status: 0x%02x\n", | ||
675 | (unsigned int)bank, (unsigned int)offset, x); | ||
676 | return -EIO; | ||
677 | } | ||
678 | |||
679 | for (i = 0; i < count; i++) { | ||
680 | if ((x = abituguru3_wait_for_read(data)) != | ||
681 | ABIT_UGURU3_SUCCESS) { | ||
682 | ABIT_UGURU3_DEBUG("timeout reading byte %d from " | ||
683 | "0x%02x:0x%02x, status: 0x%02x\n", i, | ||
684 | (unsigned int)bank, (unsigned int)offset, x); | ||
685 | break; | ||
686 | } | ||
687 | buf[i] = inb(data->addr + ABIT_UGURU3_CMD); | ||
688 | } | ||
689 | return i; | ||
690 | } | ||
691 | |||
692 | /* Sensor settings are stored 1 byte per offset with the bytes | ||
693 | placed add consecutive offsets. */ | ||
694 | int abituguru3_read_increment_offset(struct abituguru3_data *data, u8 bank, | ||
695 | u8 offset, u8 count, u8 *buf, int offset_count) | ||
696 | { | ||
697 | int i, x; | ||
698 | |||
699 | for (i = 0; i < offset_count; i++) | ||
700 | if ((x = abituguru3_read(data, bank, offset + i, count, | ||
701 | buf + i * count)) != count) | ||
702 | return i * count + (i && (x < 0)) ? 0 : x; | ||
703 | |||
704 | return i * count; | ||
705 | } | ||
706 | |||
707 | /* Following are the sysfs callback functions. These functions expect: | ||
708 | sensor_device_attribute_2->index: index into the data->sensors array | ||
709 | sensor_device_attribute_2->nr: register offset, bitmask or NA. */ | ||
710 | static struct abituguru3_data *abituguru3_update_device(struct device *dev); | ||
711 | |||
712 | static ssize_t show_value(struct device *dev, | ||
713 | struct device_attribute *devattr, char *buf) | ||
714 | { | ||
715 | int value; | ||
716 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
717 | struct abituguru3_data *data = abituguru3_update_device(dev); | ||
718 | const struct abituguru3_sensor_info *sensor; | ||
719 | |||
720 | if (!data) | ||
721 | return -EIO; | ||
722 | |||
723 | sensor = &data->sensors[attr->index]; | ||
724 | |||
725 | /* are we reading a setting, or is this a normal read? */ | ||
726 | if (attr->nr) | ||
727 | value = data->settings[sensor->port][attr->nr]; | ||
728 | else | ||
729 | value = data->value[sensor->port]; | ||
730 | |||
731 | /* convert the value */ | ||
732 | value = (value * sensor->multiplier) / sensor->divisor + | ||
733 | sensor->offset; | ||
734 | |||
735 | /* alternatively we could update the sensors settings struct for this, | ||
736 | but then its contents would differ from the windows sw ini files */ | ||
737 | if (sensor->type == ABIT_UGURU3_TEMP_SENSOR) | ||
738 | value *= 1000; | ||
739 | |||
740 | return sprintf(buf, "%d\n", value); | ||
741 | } | ||
742 | |||
743 | static ssize_t show_alarm(struct device *dev, | ||
744 | struct device_attribute *devattr, char *buf) | ||
745 | { | ||
746 | int port; | ||
747 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
748 | struct abituguru3_data *data = abituguru3_update_device(dev); | ||
749 | |||
750 | if (!data) | ||
751 | return -EIO; | ||
752 | |||
753 | port = data->sensors[attr->index].port; | ||
754 | |||
755 | /* See if the alarm bit for this sensor is set and if a bitmask is | ||
756 | given in attr->nr also check if the alarm matches the type of alarm | ||
757 | we're looking for (for volt it can be either low or high). The type | ||
758 | is stored in a few readonly bits in the settings of the sensor. */ | ||
759 | if ((data->alarms[port / 8] & (0x01 << (port % 8))) && | ||
760 | (!attr->nr || (data->settings[port][0] & attr->nr))) | ||
761 | return sprintf(buf, "1\n"); | ||
762 | else | ||
763 | return sprintf(buf, "0\n"); | ||
764 | } | ||
765 | |||
766 | static ssize_t show_mask(struct device *dev, | ||
767 | struct device_attribute *devattr, char *buf) | ||
768 | { | ||
769 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
770 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
771 | |||
772 | if (data->settings[data->sensors[attr->index].port][0] & attr->nr) | ||
773 | return sprintf(buf, "1\n"); | ||
774 | else | ||
775 | return sprintf(buf, "0\n"); | ||
776 | } | ||
777 | |||
778 | static ssize_t show_label(struct device *dev, | ||
779 | struct device_attribute *devattr, char *buf) | ||
780 | { | ||
781 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
782 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
783 | |||
784 | return sprintf(buf, "%s\n", data->sensors[attr->index].name); | ||
785 | } | ||
786 | |||
787 | static ssize_t show_name(struct device *dev, | ||
788 | struct device_attribute *devattr, char *buf) | ||
789 | { | ||
790 | return sprintf(buf, "%s\n", ABIT_UGURU3_NAME); | ||
791 | } | ||
792 | |||
793 | /* Sysfs attr templates, the real entries are generated automatically. */ | ||
794 | static const | ||
795 | struct sensor_device_attribute_2 abituguru3_sysfs_templ[3][10] = { { | ||
796 | SENSOR_ATTR_2(in%d_input, 0444, show_value, NULL, 0, 0), | ||
797 | SENSOR_ATTR_2(in%d_min, 0444, show_value, NULL, 1, 0), | ||
798 | SENSOR_ATTR_2(in%d_max, 0444, show_value, NULL, 2, 0), | ||
799 | SENSOR_ATTR_2(in%d_min_alarm, 0444, show_alarm, NULL, | ||
800 | ABIT_UGURU3_VOLT_LOW_ALARM_FLAG, 0), | ||
801 | SENSOR_ATTR_2(in%d_max_alarm, 0444, show_alarm, NULL, | ||
802 | ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG, 0), | ||
803 | SENSOR_ATTR_2(in%d_beep, 0444, show_mask, NULL, | ||
804 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
805 | SENSOR_ATTR_2(in%d_shutdown, 0444, show_mask, NULL, | ||
806 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
807 | SENSOR_ATTR_2(in%d_min_alarm_enable, 0444, show_mask, NULL, | ||
808 | ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE, 0), | ||
809 | SENSOR_ATTR_2(in%d_max_alarm_enable, 0444, show_mask, NULL, | ||
810 | ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE, 0), | ||
811 | SENSOR_ATTR_2(in%d_label, 0444, show_label, NULL, 0, 0) | ||
812 | }, { | ||
813 | SENSOR_ATTR_2(temp%d_input, 0444, show_value, NULL, 0, 0), | ||
814 | SENSOR_ATTR_2(temp%d_max, 0444, show_value, NULL, 1, 0), | ||
815 | SENSOR_ATTR_2(temp%d_crit, 0444, show_value, NULL, 2, 0), | ||
816 | SENSOR_ATTR_2(temp%d_alarm, 0444, show_alarm, NULL, 0, 0), | ||
817 | SENSOR_ATTR_2(temp%d_beep, 0444, show_mask, NULL, | ||
818 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
819 | SENSOR_ATTR_2(temp%d_shutdown, 0444, show_mask, NULL, | ||
820 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
821 | SENSOR_ATTR_2(temp%d_alarm_enable, 0444, show_mask, NULL, | ||
822 | ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE, 0), | ||
823 | SENSOR_ATTR_2(temp%d_label, 0444, show_label, NULL, 0, 0) | ||
824 | }, { | ||
825 | SENSOR_ATTR_2(fan%d_input, 0444, show_value, NULL, 0, 0), | ||
826 | SENSOR_ATTR_2(fan%d_min, 0444, show_value, NULL, 1, 0), | ||
827 | SENSOR_ATTR_2(fan%d_alarm, 0444, show_alarm, NULL, 0, 0), | ||
828 | SENSOR_ATTR_2(fan%d_beep, 0444, show_mask, NULL, | ||
829 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
830 | SENSOR_ATTR_2(fan%d_shutdown, 0444, show_mask, NULL, | ||
831 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
832 | SENSOR_ATTR_2(fan%d_alarm_enable, 0444, show_mask, NULL, | ||
833 | ABIT_UGURU3_FAN_LOW_ALARM_ENABLE, 0), | ||
834 | SENSOR_ATTR_2(fan%d_label, 0444, show_label, NULL, 0, 0) | ||
835 | } }; | ||
836 | |||
837 | static struct sensor_device_attribute_2 abituguru3_sysfs_attr[] = { | ||
838 | SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), | ||
839 | }; | ||
840 | |||
841 | static int __devinit abituguru3_probe(struct platform_device *pdev) | ||
842 | { | ||
843 | const int no_sysfs_attr[3] = { 10, 8, 7 }; | ||
844 | int sensor_index[3] = { 0, 1, 1 }; | ||
845 | struct abituguru3_data *data; | ||
846 | int i, j, type, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; | ||
847 | char *sysfs_filename; | ||
848 | u8 buf[2]; | ||
849 | u16 id; | ||
850 | |||
851 | if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL))) | ||
852 | return -ENOMEM; | ||
853 | |||
854 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
855 | mutex_init(&data->update_lock); | ||
856 | platform_set_drvdata(pdev, data); | ||
857 | |||
858 | /* Read the motherboard ID */ | ||
859 | if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK, | ||
860 | ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) { | ||
861 | goto abituguru3_probe_error; | ||
862 | } | ||
863 | |||
864 | /* Completely read the uGuru to see if one really is there */ | ||
865 | if (!abituguru3_update_device(&pdev->dev)) | ||
866 | goto abituguru3_probe_error; | ||
867 | |||
868 | /* lookup the ID in our motherboard table */ | ||
869 | id = ((u16)buf[0] << 8) | (u16)buf[1]; | ||
870 | for (i = 0; abituguru3_motherboards[i].id; i++) | ||
871 | if (abituguru3_motherboards[i].id == id) | ||
872 | break; | ||
873 | if (!abituguru3_motherboards[i].id) { | ||
874 | printk(KERN_ERR ABIT_UGURU3_NAME ": error unknown motherboard " | ||
875 | "ID: %04X. Please report this to the abituguru3 " | ||
876 | "maintainer (see MAINTAINERS)\n", (unsigned int)id); | ||
877 | goto abituguru3_probe_error; | ||
878 | } | ||
879 | data->sensors = abituguru3_motherboards[i].sensors; | ||
880 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " | ||
881 | "ID: %04X (%s)\n", (unsigned int)id, | ||
882 | abituguru3_motherboards[i].name); | ||
883 | |||
884 | /* Fill the sysfs attr array */ | ||
885 | sysfs_attr_i = 0; | ||
886 | sysfs_filename = data->sysfs_names; | ||
887 | sysfs_names_free = ABIT_UGURU3_SYSFS_NAMES_LENGTH; | ||
888 | for (i = 0; data->sensors[i].name; i++) { | ||
889 | /* Fail safe check, this should never happen! */ | ||
890 | if (i >= ABIT_UGURU3_MAX_NO_SENSORS) { | ||
891 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
892 | ": Fatal error motherboard has more sensors " | ||
893 | "then ABIT_UGURU3_MAX_NO_SENSORS. This should " | ||
894 | "never happen please report to the abituguru3 " | ||
895 | "maintainer (see MAINTAINERS)\n"); | ||
896 | res = -ENAMETOOLONG; | ||
897 | goto abituguru3_probe_error; | ||
898 | } | ||
899 | type = data->sensors[i].type; | ||
900 | for (j = 0; j < no_sysfs_attr[type]; j++) { | ||
901 | used = snprintf(sysfs_filename, sysfs_names_free, | ||
902 | abituguru3_sysfs_templ[type][j].dev_attr.attr. | ||
903 | name, sensor_index[type]) + 1; | ||
904 | data->sysfs_attr[sysfs_attr_i] = | ||
905 | abituguru3_sysfs_templ[type][j]; | ||
906 | data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = | ||
907 | sysfs_filename; | ||
908 | data->sysfs_attr[sysfs_attr_i].index = i; | ||
909 | sysfs_filename += used; | ||
910 | sysfs_names_free -= used; | ||
911 | sysfs_attr_i++; | ||
912 | } | ||
913 | sensor_index[type]++; | ||
914 | } | ||
915 | /* Fail safe check, this should never happen! */ | ||
916 | if (sysfs_names_free < 0) { | ||
917 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
918 | ": Fatal error ran out of space for sysfs attr names. " | ||
919 | "This should never happen please report to the " | ||
920 | "abituguru3 maintainer (see MAINTAINERS)\n"); | ||
921 | res = -ENAMETOOLONG; | ||
922 | goto abituguru3_probe_error; | ||
923 | } | ||
924 | |||
925 | /* Register sysfs hooks */ | ||
926 | for (i = 0; i < sysfs_attr_i; i++) | ||
927 | if (device_create_file(&pdev->dev, | ||
928 | &data->sysfs_attr[i].dev_attr)) | ||
929 | goto abituguru3_probe_error; | ||
930 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
931 | if (device_create_file(&pdev->dev, | ||
932 | &abituguru3_sysfs_attr[i].dev_attr)) | ||
933 | goto abituguru3_probe_error; | ||
934 | |||
935 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
936 | if (IS_ERR(data->class_dev)) { | ||
937 | res = PTR_ERR(data->class_dev); | ||
938 | goto abituguru3_probe_error; | ||
939 | } | ||
940 | |||
941 | return 0; /* success */ | ||
942 | |||
943 | abituguru3_probe_error: | ||
944 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | ||
945 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | ||
946 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
947 | device_remove_file(&pdev->dev, | ||
948 | &abituguru3_sysfs_attr[i].dev_attr); | ||
949 | kfree(data); | ||
950 | return res; | ||
951 | } | ||
952 | |||
953 | static int __devexit abituguru3_remove(struct platform_device *pdev) | ||
954 | { | ||
955 | int i; | ||
956 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
957 | |||
958 | platform_set_drvdata(pdev, NULL); | ||
959 | hwmon_device_unregister(data->class_dev); | ||
960 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | ||
961 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | ||
962 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
963 | device_remove_file(&pdev->dev, | ||
964 | &abituguru3_sysfs_attr[i].dev_attr); | ||
965 | kfree(data); | ||
966 | |||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static struct abituguru3_data *abituguru3_update_device(struct device *dev) | ||
971 | { | ||
972 | int i; | ||
973 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
974 | |||
975 | mutex_lock(&data->update_lock); | ||
976 | if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { | ||
977 | /* Clear data->valid while updating */ | ||
978 | data->valid = 0; | ||
979 | /* Read alarms */ | ||
980 | if (abituguru3_read_increment_offset(data, | ||
981 | ABIT_UGURU3_SETTINGS_BANK, | ||
982 | ABIT_UGURU3_ALARMS_START, | ||
983 | 1, data->alarms, 48/8) != (48/8)) | ||
984 | goto LEAVE_UPDATE; | ||
985 | /* Read in and temp sensors (3 byte settings / sensor) */ | ||
986 | for (i = 0; i < 32; i++) { | ||
987 | if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK, | ||
988 | ABIT_UGURU3_VALUES_START + i, | ||
989 | 1, &data->value[i]) != 1) | ||
990 | goto LEAVE_UPDATE; | ||
991 | if (abituguru3_read_increment_offset(data, | ||
992 | ABIT_UGURU3_SETTINGS_BANK, | ||
993 | ABIT_UGURU3_SETTINGS_START + i * 3, | ||
994 | 1, | ||
995 | data->settings[i], 3) != 3) | ||
996 | goto LEAVE_UPDATE; | ||
997 | } | ||
998 | /* Read temp sensors (2 byte settings / sensor) */ | ||
999 | for (i = 0; i < 16; i++) { | ||
1000 | if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK, | ||
1001 | ABIT_UGURU3_VALUES_START + 32 + i, | ||
1002 | 1, &data->value[32 + i]) != 1) | ||
1003 | goto LEAVE_UPDATE; | ||
1004 | if (abituguru3_read_increment_offset(data, | ||
1005 | ABIT_UGURU3_SETTINGS_BANK, | ||
1006 | ABIT_UGURU3_SETTINGS_START + 32 * 3 + | ||
1007 | i * 2, 1, | ||
1008 | data->settings[32 + i], 2) != 2) | ||
1009 | goto LEAVE_UPDATE; | ||
1010 | } | ||
1011 | data->last_updated = jiffies; | ||
1012 | data->valid = 1; | ||
1013 | } | ||
1014 | LEAVE_UPDATE: | ||
1015 | mutex_unlock(&data->update_lock); | ||
1016 | if (data->valid) | ||
1017 | return data; | ||
1018 | else | ||
1019 | return NULL; | ||
1020 | } | ||
1021 | |||
1022 | #ifdef CONFIG_PM | ||
1023 | static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state) | ||
1024 | { | ||
1025 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
1026 | /* make sure all communications with the uguru3 are done and no new | ||
1027 | ones are started */ | ||
1028 | mutex_lock(&data->update_lock); | ||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
1032 | static int abituguru3_resume(struct platform_device *pdev) | ||
1033 | { | ||
1034 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
1035 | mutex_unlock(&data->update_lock); | ||
1036 | return 0; | ||
1037 | } | ||
1038 | #else | ||
1039 | #define abituguru3_suspend NULL | ||
1040 | #define abituguru3_resume NULL | ||
1041 | #endif /* CONFIG_PM */ | ||
1042 | |||
1043 | static struct platform_driver abituguru3_driver = { | ||
1044 | .driver = { | ||
1045 | .owner = THIS_MODULE, | ||
1046 | .name = ABIT_UGURU3_NAME, | ||
1047 | }, | ||
1048 | .probe = abituguru3_probe, | ||
1049 | .remove = __devexit_p(abituguru3_remove), | ||
1050 | .suspend = abituguru3_suspend, | ||
1051 | .resume = abituguru3_resume | ||
1052 | }; | ||
1053 | |||
1054 | static int __init abituguru3_detect(void) | ||
1055 | { | ||
1056 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or | ||
1057 | 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05 | ||
1058 | at CMD instead, why is unknown. So we test for 0x05 too. */ | ||
1059 | u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA); | ||
1060 | u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD); | ||
1061 | if (((data_val == 0x00) || (data_val == 0x08)) && | ||
1062 | ((cmd_val == 0xAC) || (cmd_val == 0x05))) | ||
1063 | return ABIT_UGURU3_BASE; | ||
1064 | |||
1065 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " | ||
1066 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); | ||
1067 | |||
1068 | if (force) { | ||
1069 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " | ||
1070 | "present because of \"force\" parameter\n"); | ||
1071 | return ABIT_UGURU3_BASE; | ||
1072 | } | ||
1073 | |||
1074 | /* No uGuru3 found */ | ||
1075 | return -ENODEV; | ||
1076 | } | ||
1077 | |||
1078 | static struct platform_device *abituguru3_pdev; | ||
1079 | |||
1080 | static int __init abituguru3_init(void) | ||
1081 | { | ||
1082 | int address, err; | ||
1083 | struct resource res = { .flags = IORESOURCE_IO }; | ||
1084 | |||
1085 | address = abituguru3_detect(); | ||
1086 | if (address < 0) | ||
1087 | return address; | ||
1088 | |||
1089 | err = platform_driver_register(&abituguru3_driver); | ||
1090 | if (err) | ||
1091 | goto exit; | ||
1092 | |||
1093 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, address); | ||
1094 | if (!abituguru3_pdev) { | ||
1095 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
1096 | ": Device allocation failed\n"); | ||
1097 | err = -ENOMEM; | ||
1098 | goto exit_driver_unregister; | ||
1099 | } | ||
1100 | |||
1101 | res.start = address; | ||
1102 | res.end = address + ABIT_UGURU3_REGION_LENGTH - 1; | ||
1103 | res.name = ABIT_UGURU3_NAME; | ||
1104 | |||
1105 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); | ||
1106 | if (err) { | ||
1107 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
1108 | ": Device resource addition failed (%d)\n", err); | ||
1109 | goto exit_device_put; | ||
1110 | } | ||
1111 | |||
1112 | err = platform_device_add(abituguru3_pdev); | ||
1113 | if (err) { | ||
1114 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
1115 | ": Device addition failed (%d)\n", err); | ||
1116 | goto exit_device_put; | ||
1117 | } | ||
1118 | |||
1119 | return 0; | ||
1120 | |||
1121 | exit_device_put: | ||
1122 | platform_device_put(abituguru3_pdev); | ||
1123 | exit_driver_unregister: | ||
1124 | platform_driver_unregister(&abituguru3_driver); | ||
1125 | exit: | ||
1126 | return err; | ||
1127 | } | ||
1128 | |||
1129 | static void __exit abituguru3_exit(void) | ||
1130 | { | ||
1131 | platform_device_unregister(abituguru3_pdev); | ||
1132 | platform_driver_unregister(&abituguru3_driver); | ||
1133 | } | ||
1134 | |||
1135 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | ||
1136 | MODULE_DESCRIPTION("Abit uGuru3 Sensor device"); | ||
1137 | MODULE_LICENSE("GPL"); | ||
1138 | |||
1139 | module_init(abituguru3_init); | ||
1140 | module_exit(abituguru3_exit); | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 6d54c8caed79..7c1795225b06 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -318,7 +318,7 @@ exit: | |||
318 | } | 318 | } |
319 | 319 | ||
320 | #ifdef CONFIG_HOTPLUG_CPU | 320 | #ifdef CONFIG_HOTPLUG_CPU |
321 | void coretemp_device_remove(unsigned int cpu) | 321 | static void coretemp_device_remove(unsigned int cpu) |
322 | { | 322 | { |
323 | struct pdev_entry *p, *n; | 323 | struct pdev_entry *p, *n; |
324 | mutex_lock(&pdev_list_mutex); | 324 | mutex_lock(&pdev_list_mutex); |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c new file mode 100644 index 000000000000..be3aaa5d0b91 --- /dev/null +++ b/drivers/hwmon/dme1737.c | |||
@@ -0,0 +1,2080 @@ | |||
1 | /* | ||
2 | * dme1737.c - driver for the SMSC DME1737 and Asus A8000 Super-I/O chips | ||
3 | * integrated hardware monitoring features. | ||
4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> | ||
5 | * | ||
6 | * This driver is based on the LM85 driver. The hardware monitoring | ||
7 | * capabilities of the DME1737 are very similar to the LM85 with some | ||
8 | * additional features. Even though the DME1737 is a Super-I/O chip, the | ||
9 | * hardware monitoring registers are only accessible via SMBus. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/jiffies.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/hwmon.h> | ||
32 | #include <linux/hwmon-sysfs.h> | ||
33 | #include <linux/hwmon-vid.h> | ||
34 | #include <linux/err.h> | ||
35 | #include <linux/mutex.h> | ||
36 | #include <asm/io.h> | ||
37 | |||
38 | /* Module load parameters */ | ||
39 | static int force_start; | ||
40 | module_param(force_start, bool, 0); | ||
41 | MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); | ||
42 | |||
43 | /* Addresses to scan */ | ||
44 | static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | ||
45 | |||
46 | /* Insmod parameters */ | ||
47 | I2C_CLIENT_INSMOD_1(dme1737); | ||
48 | |||
49 | /* --------------------------------------------------------------------- | ||
50 | * Registers | ||
51 | * | ||
52 | * The sensors are defined as follows: | ||
53 | * | ||
54 | * Voltages Temperatures | ||
55 | * -------- ------------ | ||
56 | * in0 +5VTR (+5V stdby) temp1 Remote diode 1 | ||
57 | * in1 Vccp (proc core) temp2 Internal temp | ||
58 | * in2 VCC (internal +3.3V) temp3 Remote diode 2 | ||
59 | * in3 +5V | ||
60 | * in4 +12V | ||
61 | * in5 VTR (+3.3V stby) | ||
62 | * in6 Vbat | ||
63 | * | ||
64 | * --------------------------------------------------------------------- */ | ||
65 | |||
66 | /* Voltages (in) numbered 0-6 (ix) */ | ||
67 | #define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) \ | ||
68 | : 0x94 + (ix)) | ||
69 | #define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ | ||
70 | : 0x91 + (ix) * 2) | ||
71 | #define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ | ||
72 | : 0x92 + (ix) * 2) | ||
73 | |||
74 | /* Temperatures (temp) numbered 0-2 (ix) */ | ||
75 | #define DME1737_REG_TEMP(ix) (0x25 + (ix)) | ||
76 | #define DME1737_REG_TEMP_MIN(ix) (0x4e + (ix) * 2) | ||
77 | #define DME1737_REG_TEMP_MAX(ix) (0x4f + (ix) * 2) | ||
78 | #define DME1737_REG_TEMP_OFFSET(ix) ((ix) == 0 ? 0x1f \ | ||
79 | : 0x1c + (ix)) | ||
80 | |||
81 | /* Voltage and temperature LSBs | ||
82 | * The LSBs (4 bits each) are stored in 5 registers with the following layouts: | ||
83 | * IN_TEMP_LSB(0) = [in5, in6] | ||
84 | * IN_TEMP_LSB(1) = [temp3, temp1] | ||
85 | * IN_TEMP_LSB(2) = [in4, temp2] | ||
86 | * IN_TEMP_LSB(3) = [in3, in0] | ||
87 | * IN_TEMP_LSB(4) = [in2, in1] */ | ||
88 | #define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix)) | ||
89 | static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0}; | ||
90 | static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4}; | ||
91 | static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1}; | ||
92 | static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; | ||
93 | |||
94 | /* Fans numbered 0-5 (ix) */ | ||
95 | #define DME1737_REG_FAN(ix) ((ix) < 4 ? 0x28 + (ix) * 2 \ | ||
96 | : 0xa1 + (ix) * 2) | ||
97 | #define DME1737_REG_FAN_MIN(ix) ((ix) < 4 ? 0x54 + (ix) * 2 \ | ||
98 | : 0xa5 + (ix) * 2) | ||
99 | #define DME1737_REG_FAN_OPT(ix) ((ix) < 4 ? 0x90 + (ix) \ | ||
100 | : 0xb2 + (ix)) | ||
101 | #define DME1737_REG_FAN_MAX(ix) (0xb4 + (ix)) /* only for fan[4-5] */ | ||
102 | |||
103 | /* PWMs numbered 0-2, 4-5 (ix) */ | ||
104 | #define DME1737_REG_PWM(ix) ((ix) < 3 ? 0x30 + (ix) \ | ||
105 | : 0xa1 + (ix)) | ||
106 | #define DME1737_REG_PWM_CONFIG(ix) (0x5c + (ix)) /* only for pwm[0-2] */ | ||
107 | #define DME1737_REG_PWM_MIN(ix) (0x64 + (ix)) /* only for pwm[0-2] */ | ||
108 | #define DME1737_REG_PWM_FREQ(ix) ((ix) < 3 ? 0x5f + (ix) \ | ||
109 | : 0xa3 + (ix)) | ||
110 | /* The layout of the ramp rate registers is different from the other pwm | ||
111 | * registers. The bits for the 3 PWMs are stored in 2 registers: | ||
112 | * PWM_RR(0) = [OFF3, OFF2, OFF1, RES, RR1E, RR1-2, RR1-1, RR1-0] | ||
113 | * PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0] */ | ||
114 | #define DME1737_REG_PWM_RR(ix) (0x62 + (ix)) /* only for pwm[0-2] */ | ||
115 | |||
116 | /* Thermal zones 0-2 */ | ||
117 | #define DME1737_REG_ZONE_LOW(ix) (0x67 + (ix)) | ||
118 | #define DME1737_REG_ZONE_ABS(ix) (0x6a + (ix)) | ||
119 | /* The layout of the hysteresis registers is different from the other zone | ||
120 | * registers. The bits for the 3 zones are stored in 2 registers: | ||
121 | * ZONE_HYST(0) = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] | ||
122 | * ZONE_HYST(1) = [H3-3, H3-2, H3-1, H3-0, RES, RES, RES, RES] */ | ||
123 | #define DME1737_REG_ZONE_HYST(ix) (0x6d + (ix)) | ||
124 | |||
125 | /* Alarm registers and bit mapping | ||
126 | * The 3 8-bit alarm registers will be concatenated to a single 32-bit | ||
127 | * alarm value [0, ALARM3, ALARM2, ALARM1]. */ | ||
128 | #define DME1737_REG_ALARM1 0x41 | ||
129 | #define DME1737_REG_ALARM2 0x42 | ||
130 | #define DME1737_REG_ALARM3 0x83 | ||
131 | static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17}; | ||
132 | static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6}; | ||
133 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | ||
134 | |||
135 | /* Miscellaneous registers */ | ||
136 | #define DME1737_REG_COMPANY 0x3e | ||
137 | #define DME1737_REG_VERSTEP 0x3f | ||
138 | #define DME1737_REG_CONFIG 0x40 | ||
139 | #define DME1737_REG_CONFIG2 0x7f | ||
140 | #define DME1737_REG_VID 0x43 | ||
141 | #define DME1737_REG_TACH_PWM 0x81 | ||
142 | |||
143 | /* --------------------------------------------------------------------- | ||
144 | * Misc defines | ||
145 | * --------------------------------------------------------------------- */ | ||
146 | |||
147 | /* Chip identification */ | ||
148 | #define DME1737_COMPANY_SMSC 0x5c | ||
149 | #define DME1737_VERSTEP 0x88 | ||
150 | #define DME1737_VERSTEP_MASK 0xf8 | ||
151 | |||
152 | /* --------------------------------------------------------------------- | ||
153 | * Data structures and manipulation thereof | ||
154 | * --------------------------------------------------------------------- */ | ||
155 | |||
156 | struct dme1737_data { | ||
157 | struct i2c_client client; | ||
158 | struct class_device *class_dev; | ||
159 | |||
160 | struct mutex update_lock; | ||
161 | int valid; /* !=0 if following fields are valid */ | ||
162 | unsigned long last_update; /* in jiffies */ | ||
163 | unsigned long last_vbat; /* in jiffies */ | ||
164 | |||
165 | u8 vid; | ||
166 | u8 pwm_rr_en; | ||
167 | u8 has_pwm; | ||
168 | u8 has_fan; | ||
169 | |||
170 | /* Register values */ | ||
171 | u16 in[7]; | ||
172 | u8 in_min[7]; | ||
173 | u8 in_max[7]; | ||
174 | s16 temp[3]; | ||
175 | s8 temp_min[3]; | ||
176 | s8 temp_max[3]; | ||
177 | s8 temp_offset[3]; | ||
178 | u8 config; | ||
179 | u8 config2; | ||
180 | u8 vrm; | ||
181 | u16 fan[6]; | ||
182 | u16 fan_min[6]; | ||
183 | u8 fan_max[2]; | ||
184 | u8 fan_opt[6]; | ||
185 | u8 pwm[6]; | ||
186 | u8 pwm_min[3]; | ||
187 | u8 pwm_config[3]; | ||
188 | u8 pwm_acz[3]; | ||
189 | u8 pwm_freq[6]; | ||
190 | u8 pwm_rr[2]; | ||
191 | u8 zone_low[3]; | ||
192 | u8 zone_abs[3]; | ||
193 | u8 zone_hyst[2]; | ||
194 | u32 alarms; | ||
195 | }; | ||
196 | |||
197 | /* Nominal voltage values */ | ||
198 | static const int IN_NOMINAL[] = {5000, 2250, 3300, 5000, 12000, 3300, 3300}; | ||
199 | |||
200 | /* Voltage input | ||
201 | * Voltage inputs have 16 bits resolution, limit values have 8 bits | ||
202 | * resolution. */ | ||
203 | static inline int IN_FROM_REG(int reg, int ix, int res) | ||
204 | { | ||
205 | return (reg * IN_NOMINAL[ix] + (3 << (res - 3))) / (3 << (res - 2)); | ||
206 | } | ||
207 | |||
208 | static inline int IN_TO_REG(int val, int ix) | ||
209 | { | ||
210 | return SENSORS_LIMIT((val * 192 + IN_NOMINAL[ix] / 2) / | ||
211 | IN_NOMINAL[ix], 0, 255); | ||
212 | } | ||
213 | |||
214 | /* Temperature input | ||
215 | * The register values represent temperatures in 2's complement notation from | ||
216 | * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit | ||
217 | * values have 8 bits resolution. */ | ||
218 | static inline int TEMP_FROM_REG(int reg, int res) | ||
219 | { | ||
220 | return (reg * 1000) >> (res - 8); | ||
221 | } | ||
222 | |||
223 | static inline int TEMP_TO_REG(int val) | ||
224 | { | ||
225 | return SENSORS_LIMIT((val < 0 ? val - 500 : val + 500) / 1000, | ||
226 | -128, 127); | ||
227 | } | ||
228 | |||
229 | /* Temperature range */ | ||
230 | static const int TEMP_RANGE[] = {2000, 2500, 3333, 4000, 5000, 6666, 8000, | ||
231 | 10000, 13333, 16000, 20000, 26666, 32000, | ||
232 | 40000, 53333, 80000}; | ||
233 | |||
234 | static inline int TEMP_RANGE_FROM_REG(int reg) | ||
235 | { | ||
236 | return TEMP_RANGE[(reg >> 4) & 0x0f]; | ||
237 | } | ||
238 | |||
239 | static int TEMP_RANGE_TO_REG(int val, int reg) | ||
240 | { | ||
241 | int i; | ||
242 | |||
243 | for (i = 15; i > 0; i--) { | ||
244 | if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2) { | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | return (reg & 0x0f) | (i << 4); | ||
250 | } | ||
251 | |||
252 | /* Temperature hysteresis | ||
253 | * Register layout: | ||
254 | * reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] | ||
255 | * reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx] */ | ||
256 | static inline int TEMP_HYST_FROM_REG(int reg, int ix) | ||
257 | { | ||
258 | return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000; | ||
259 | } | ||
260 | |||
261 | static inline int TEMP_HYST_TO_REG(int val, int ix, int reg) | ||
262 | { | ||
263 | int hyst = SENSORS_LIMIT((val + 500) / 1000, 0, 15); | ||
264 | |||
265 | return (ix == 1) ? (reg & 0xf0) | hyst : (reg & 0x0f) | (hyst << 4); | ||
266 | } | ||
267 | |||
268 | /* Fan input RPM */ | ||
269 | static inline int FAN_FROM_REG(int reg, int tpc) | ||
270 | { | ||
271 | return (reg == 0 || reg == 0xffff) ? 0 : | ||
272 | (tpc == 0) ? 90000 * 60 / reg : tpc * reg; | ||
273 | } | ||
274 | |||
275 | static inline int FAN_TO_REG(int val, int tpc) | ||
276 | { | ||
277 | return SENSORS_LIMIT((tpc == 0) ? 90000 * 60 / val : val / tpc, | ||
278 | 0, 0xffff); | ||
279 | } | ||
280 | |||
281 | /* Fan TPC (tach pulse count) | ||
282 | * Converts a register value to a TPC multiplier or returns 0 if the tachometer | ||
283 | * is configured in legacy (non-tpc) mode */ | ||
284 | static inline int FAN_TPC_FROM_REG(int reg) | ||
285 | { | ||
286 | return (reg & 0x20) ? 0 : 60 >> (reg & 0x03); | ||
287 | } | ||
288 | |||
289 | /* Fan type | ||
290 | * The type of a fan is expressed in number of pulses-per-revolution that it | ||
291 | * emits */ | ||
292 | static inline int FAN_TYPE_FROM_REG(int reg) | ||
293 | { | ||
294 | int edge = (reg >> 1) & 0x03; | ||
295 | |||
296 | return (edge > 0) ? 1 << (edge - 1) : 0; | ||
297 | } | ||
298 | |||
299 | static inline int FAN_TYPE_TO_REG(int val, int reg) | ||
300 | { | ||
301 | int edge = (val == 4) ? 3 : val; | ||
302 | |||
303 | return (reg & 0xf9) | (edge << 1); | ||
304 | } | ||
305 | |||
306 | /* Fan max RPM */ | ||
307 | static const int FAN_MAX[] = {0x54, 0x38, 0x2a, 0x21, 0x1c, 0x18, 0x15, 0x12, | ||
308 | 0x11, 0x0f, 0x0e}; | ||
309 | |||
310 | static int FAN_MAX_FROM_REG(int reg) | ||
311 | { | ||
312 | int i; | ||
313 | |||
314 | for (i = 10; i > 0; i--) { | ||
315 | if (reg == FAN_MAX[i]) { | ||
316 | break; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | return 1000 + i * 500; | ||
321 | } | ||
322 | |||
323 | static int FAN_MAX_TO_REG(int val) | ||
324 | { | ||
325 | int i; | ||
326 | |||
327 | for (i = 10; i > 0; i--) { | ||
328 | if (val > (1000 + (i - 1) * 500)) { | ||
329 | break; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | return FAN_MAX[i]; | ||
334 | } | ||
335 | |||
336 | /* PWM enable | ||
337 | * Register to enable mapping: | ||
338 | * 000: 2 fan on zone 1 auto | ||
339 | * 001: 2 fan on zone 2 auto | ||
340 | * 010: 2 fan on zone 3 auto | ||
341 | * 011: 0 fan full on | ||
342 | * 100: -1 fan disabled | ||
343 | * 101: 2 fan on hottest of zones 2,3 auto | ||
344 | * 110: 2 fan on hottest of zones 1,2,3 auto | ||
345 | * 111: 1 fan in manual mode */ | ||
346 | static inline int PWM_EN_FROM_REG(int reg) | ||
347 | { | ||
348 | static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1}; | ||
349 | |||
350 | return en[(reg >> 5) & 0x07]; | ||
351 | } | ||
352 | |||
353 | static inline int PWM_EN_TO_REG(int val, int reg) | ||
354 | { | ||
355 | int en = (val == 1) ? 7 : 3; | ||
356 | |||
357 | return (reg & 0x1f) | ((en & 0x07) << 5); | ||
358 | } | ||
359 | |||
360 | /* PWM auto channels zone | ||
361 | * Register to auto channels zone mapping (ACZ is a bitfield with bit x | ||
362 | * corresponding to zone x+1): | ||
363 | * 000: 001 fan on zone 1 auto | ||
364 | * 001: 010 fan on zone 2 auto | ||
365 | * 010: 100 fan on zone 3 auto | ||
366 | * 011: 000 fan full on | ||
367 | * 100: 000 fan disabled | ||
368 | * 101: 110 fan on hottest of zones 2,3 auto | ||
369 | * 110: 111 fan on hottest of zones 1,2,3 auto | ||
370 | * 111: 000 fan in manual mode */ | ||
371 | static inline int PWM_ACZ_FROM_REG(int reg) | ||
372 | { | ||
373 | static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0}; | ||
374 | |||
375 | return acz[(reg >> 5) & 0x07]; | ||
376 | } | ||
377 | |||
378 | static inline int PWM_ACZ_TO_REG(int val, int reg) | ||
379 | { | ||
380 | int acz = (val == 4) ? 2 : val - 1; | ||
381 | |||
382 | return (reg & 0x1f) | ((acz & 0x07) << 5); | ||
383 | } | ||
384 | |||
385 | /* PWM frequency */ | ||
386 | static const int PWM_FREQ[] = {11, 15, 22, 29, 35, 44, 59, 88, | ||
387 | 15000, 20000, 30000, 25000, 0, 0, 0, 0}; | ||
388 | |||
389 | static inline int PWM_FREQ_FROM_REG(int reg) | ||
390 | { | ||
391 | return PWM_FREQ[reg & 0x0f]; | ||
392 | } | ||
393 | |||
394 | static int PWM_FREQ_TO_REG(int val, int reg) | ||
395 | { | ||
396 | int i; | ||
397 | |||
398 | /* the first two cases are special - stupid chip design! */ | ||
399 | if (val > 27500) { | ||
400 | i = 10; | ||
401 | } else if (val > 22500) { | ||
402 | i = 11; | ||
403 | } else { | ||
404 | for (i = 9; i > 0; i--) { | ||
405 | if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2) { | ||
406 | break; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | |||
411 | return (reg & 0xf0) | i; | ||
412 | } | ||
413 | |||
414 | /* PWM ramp rate | ||
415 | * Register layout: | ||
416 | * reg[0] = [OFF3, OFF2, OFF1, RES, RR1-E, RR1-2, RR1-1, RR1-0] | ||
417 | * reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0] */ | ||
418 | static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5}; | ||
419 | |||
420 | static inline int PWM_RR_FROM_REG(int reg, int ix) | ||
421 | { | ||
422 | int rr = (ix == 1) ? reg >> 4 : reg; | ||
423 | |||
424 | return (rr & 0x08) ? PWM_RR[rr & 0x07] : 0; | ||
425 | } | ||
426 | |||
427 | static int PWM_RR_TO_REG(int val, int ix, int reg) | ||
428 | { | ||
429 | int i; | ||
430 | |||
431 | for (i = 0; i < 7; i++) { | ||
432 | if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2) { | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i; | ||
438 | } | ||
439 | |||
440 | /* PWM ramp rate enable */ | ||
441 | static inline int PWM_RR_EN_FROM_REG(int reg, int ix) | ||
442 | { | ||
443 | return PWM_RR_FROM_REG(reg, ix) ? 1 : 0; | ||
444 | } | ||
445 | |||
446 | static inline int PWM_RR_EN_TO_REG(int val, int ix, int reg) | ||
447 | { | ||
448 | int en = (ix == 1) ? 0x80 : 0x08; | ||
449 | |||
450 | return val ? reg | en : reg & ~en; | ||
451 | } | ||
452 | |||
453 | /* PWM min/off | ||
454 | * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for | ||
455 | * the register layout). */ | ||
456 | static inline int PWM_OFF_FROM_REG(int reg, int ix) | ||
457 | { | ||
458 | return (reg >> (ix + 5)) & 0x01; | ||
459 | } | ||
460 | |||
461 | static inline int PWM_OFF_TO_REG(int val, int ix, int reg) | ||
462 | { | ||
463 | return (reg & ~(1 << (ix + 5))) | ((val & 0x01) << (ix + 5)); | ||
464 | } | ||
465 | |||
466 | /* --------------------------------------------------------------------- | ||
467 | * Device I/O access | ||
468 | * --------------------------------------------------------------------- */ | ||
469 | |||
470 | static u8 dme1737_read(struct i2c_client *client, u8 reg) | ||
471 | { | ||
472 | s32 val = i2c_smbus_read_byte_data(client, reg); | ||
473 | |||
474 | if (val < 0) { | ||
475 | dev_warn(&client->dev, "Read from register 0x%02x failed! " | ||
476 | "Please report to the driver maintainer.\n", reg); | ||
477 | } | ||
478 | |||
479 | return val; | ||
480 | } | ||
481 | |||
482 | static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 value) | ||
483 | { | ||
484 | s32 res = i2c_smbus_write_byte_data(client, reg, value); | ||
485 | |||
486 | if (res < 0) { | ||
487 | dev_warn(&client->dev, "Write to register 0x%02x failed! " | ||
488 | "Please report to the driver maintainer.\n", reg); | ||
489 | } | ||
490 | |||
491 | return res; | ||
492 | } | ||
493 | |||
494 | static struct dme1737_data *dme1737_update_device(struct device *dev) | ||
495 | { | ||
496 | struct i2c_client *client = to_i2c_client(dev); | ||
497 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
498 | int ix; | ||
499 | u8 lsb[5]; | ||
500 | |||
501 | mutex_lock(&data->update_lock); | ||
502 | |||
503 | /* Enable a Vbat monitoring cycle every 10 mins */ | ||
504 | if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { | ||
505 | dme1737_write(client, DME1737_REG_CONFIG, dme1737_read(client, | ||
506 | DME1737_REG_CONFIG) | 0x10); | ||
507 | data->last_vbat = jiffies; | ||
508 | } | ||
509 | |||
510 | /* Sample register contents every 1 sec */ | ||
511 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | ||
512 | data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; | ||
513 | |||
514 | /* In (voltage) registers */ | ||
515 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | ||
516 | /* Voltage inputs are stored as 16 bit values even | ||
517 | * though they have only 12 bits resolution. This is | ||
518 | * to make it consistent with the temp inputs. */ | ||
519 | data->in[ix] = dme1737_read(client, | ||
520 | DME1737_REG_IN(ix)) << 8; | ||
521 | data->in_min[ix] = dme1737_read(client, | ||
522 | DME1737_REG_IN_MIN(ix)); | ||
523 | data->in_max[ix] = dme1737_read(client, | ||
524 | DME1737_REG_IN_MAX(ix)); | ||
525 | } | ||
526 | |||
527 | /* Temp registers */ | ||
528 | for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { | ||
529 | /* Temp inputs are stored as 16 bit values even | ||
530 | * though they have only 12 bits resolution. This is | ||
531 | * to take advantage of implicit conversions between | ||
532 | * register values (2's complement) and temp values | ||
533 | * (signed decimal). */ | ||
534 | data->temp[ix] = dme1737_read(client, | ||
535 | DME1737_REG_TEMP(ix)) << 8; | ||
536 | data->temp_min[ix] = dme1737_read(client, | ||
537 | DME1737_REG_TEMP_MIN(ix)); | ||
538 | data->temp_max[ix] = dme1737_read(client, | ||
539 | DME1737_REG_TEMP_MAX(ix)); | ||
540 | data->temp_offset[ix] = dme1737_read(client, | ||
541 | DME1737_REG_TEMP_OFFSET(ix)); | ||
542 | } | ||
543 | |||
544 | /* In and temp LSB registers | ||
545 | * The LSBs are latched when the MSBs are read, so the order in | ||
546 | * which the registers are read (MSB first, then LSB) is | ||
547 | * important! */ | ||
548 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { | ||
549 | lsb[ix] = dme1737_read(client, | ||
550 | DME1737_REG_IN_TEMP_LSB(ix)); | ||
551 | } | ||
552 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | ||
553 | data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] << | ||
554 | DME1737_REG_IN_LSB_SHL[ix]) & 0xf0; | ||
555 | } | ||
556 | for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { | ||
557 | data->temp[ix] |= (lsb[DME1737_REG_TEMP_LSB[ix]] << | ||
558 | DME1737_REG_TEMP_LSB_SHL[ix]) & 0xf0; | ||
559 | } | ||
560 | |||
561 | /* Fan registers */ | ||
562 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { | ||
563 | /* Skip reading registers if optional fans are not | ||
564 | * present */ | ||
565 | if (!(data->has_fan & (1 << ix))) { | ||
566 | continue; | ||
567 | } | ||
568 | data->fan[ix] = dme1737_read(client, | ||
569 | DME1737_REG_FAN(ix)); | ||
570 | data->fan[ix] |= dme1737_read(client, | ||
571 | DME1737_REG_FAN(ix) + 1) << 8; | ||
572 | data->fan_min[ix] = dme1737_read(client, | ||
573 | DME1737_REG_FAN_MIN(ix)); | ||
574 | data->fan_min[ix] |= dme1737_read(client, | ||
575 | DME1737_REG_FAN_MIN(ix) + 1) << 8; | ||
576 | data->fan_opt[ix] = dme1737_read(client, | ||
577 | DME1737_REG_FAN_OPT(ix)); | ||
578 | /* fan_max exists only for fan[5-6] */ | ||
579 | if (ix > 3) { | ||
580 | data->fan_max[ix - 4] = dme1737_read(client, | ||
581 | DME1737_REG_FAN_MAX(ix)); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | /* PWM registers */ | ||
586 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { | ||
587 | /* Skip reading registers if optional PWMs are not | ||
588 | * present */ | ||
589 | if (!(data->has_pwm & (1 << ix))) { | ||
590 | continue; | ||
591 | } | ||
592 | data->pwm[ix] = dme1737_read(client, | ||
593 | DME1737_REG_PWM(ix)); | ||
594 | data->pwm_freq[ix] = dme1737_read(client, | ||
595 | DME1737_REG_PWM_FREQ(ix)); | ||
596 | /* pwm_config and pwm_min exist only for pwm[1-3] */ | ||
597 | if (ix < 3) { | ||
598 | data->pwm_config[ix] = dme1737_read(client, | ||
599 | DME1737_REG_PWM_CONFIG(ix)); | ||
600 | data->pwm_min[ix] = dme1737_read(client, | ||
601 | DME1737_REG_PWM_MIN(ix)); | ||
602 | } | ||
603 | } | ||
604 | for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { | ||
605 | data->pwm_rr[ix] = dme1737_read(client, | ||
606 | DME1737_REG_PWM_RR(ix)); | ||
607 | } | ||
608 | |||
609 | /* Thermal zone registers */ | ||
610 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | ||
611 | data->zone_low[ix] = dme1737_read(client, | ||
612 | DME1737_REG_ZONE_LOW(ix)); | ||
613 | data->zone_abs[ix] = dme1737_read(client, | ||
614 | DME1737_REG_ZONE_ABS(ix)); | ||
615 | } | ||
616 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | ||
617 | data->zone_hyst[ix] = dme1737_read(client, | ||
618 | DME1737_REG_ZONE_HYST(ix)); | ||
619 | } | ||
620 | |||
621 | /* Alarm registers */ | ||
622 | data->alarms = dme1737_read(client, | ||
623 | DME1737_REG_ALARM1); | ||
624 | /* Bit 7 tells us if the other alarm registers are non-zero and | ||
625 | * therefore also need to be read */ | ||
626 | if (data->alarms & 0x80) { | ||
627 | data->alarms |= dme1737_read(client, | ||
628 | DME1737_REG_ALARM2) << 8; | ||
629 | data->alarms |= dme1737_read(client, | ||
630 | DME1737_REG_ALARM3) << 16; | ||
631 | } | ||
632 | |||
633 | data->last_update = jiffies; | ||
634 | data->valid = 1; | ||
635 | } | ||
636 | |||
637 | mutex_unlock(&data->update_lock); | ||
638 | |||
639 | return data; | ||
640 | } | ||
641 | |||
642 | /* --------------------------------------------------------------------- | ||
643 | * Voltage sysfs attributes | ||
644 | * ix = [0-5] | ||
645 | * --------------------------------------------------------------------- */ | ||
646 | |||
647 | #define SYS_IN_INPUT 0 | ||
648 | #define SYS_IN_MIN 1 | ||
649 | #define SYS_IN_MAX 2 | ||
650 | #define SYS_IN_ALARM 3 | ||
651 | |||
652 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
653 | char *buf) | ||
654 | { | ||
655 | struct dme1737_data *data = dme1737_update_device(dev); | ||
656 | struct sensor_device_attribute_2 | ||
657 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
658 | int ix = sensor_attr_2->index; | ||
659 | int fn = sensor_attr_2->nr; | ||
660 | int res; | ||
661 | |||
662 | switch (fn) { | ||
663 | case SYS_IN_INPUT: | ||
664 | res = IN_FROM_REG(data->in[ix], ix, 16); | ||
665 | break; | ||
666 | case SYS_IN_MIN: | ||
667 | res = IN_FROM_REG(data->in_min[ix], ix, 8); | ||
668 | break; | ||
669 | case SYS_IN_MAX: | ||
670 | res = IN_FROM_REG(data->in_max[ix], ix, 8); | ||
671 | break; | ||
672 | case SYS_IN_ALARM: | ||
673 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; | ||
674 | break; | ||
675 | default: | ||
676 | res = 0; | ||
677 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
678 | } | ||
679 | |||
680 | return sprintf(buf, "%d\n", res); | ||
681 | } | ||
682 | |||
683 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, | ||
684 | const char *buf, size_t count) | ||
685 | { | ||
686 | struct i2c_client *client = to_i2c_client(dev); | ||
687 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
688 | struct sensor_device_attribute_2 | ||
689 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
690 | int ix = sensor_attr_2->index; | ||
691 | int fn = sensor_attr_2->nr; | ||
692 | long val = simple_strtol(buf, NULL, 10); | ||
693 | |||
694 | mutex_lock(&data->update_lock); | ||
695 | switch (fn) { | ||
696 | case SYS_IN_MIN: | ||
697 | data->in_min[ix] = IN_TO_REG(val, ix); | ||
698 | dme1737_write(client, DME1737_REG_IN_MIN(ix), | ||
699 | data->in_min[ix]); | ||
700 | break; | ||
701 | case SYS_IN_MAX: | ||
702 | data->in_max[ix] = IN_TO_REG(val, ix); | ||
703 | dme1737_write(client, DME1737_REG_IN_MAX(ix), | ||
704 | data->in_max[ix]); | ||
705 | break; | ||
706 | default: | ||
707 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
708 | } | ||
709 | mutex_unlock(&data->update_lock); | ||
710 | |||
711 | return count; | ||
712 | } | ||
713 | |||
714 | /* --------------------------------------------------------------------- | ||
715 | * Temperature sysfs attributes | ||
716 | * ix = [0-2] | ||
717 | * --------------------------------------------------------------------- */ | ||
718 | |||
719 | #define SYS_TEMP_INPUT 0 | ||
720 | #define SYS_TEMP_MIN 1 | ||
721 | #define SYS_TEMP_MAX 2 | ||
722 | #define SYS_TEMP_OFFSET 3 | ||
723 | #define SYS_TEMP_ALARM 4 | ||
724 | #define SYS_TEMP_FAULT 5 | ||
725 | |||
726 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
727 | char *buf) | ||
728 | { | ||
729 | struct dme1737_data *data = dme1737_update_device(dev); | ||
730 | struct sensor_device_attribute_2 | ||
731 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
732 | int ix = sensor_attr_2->index; | ||
733 | int fn = sensor_attr_2->nr; | ||
734 | int res; | ||
735 | |||
736 | switch (fn) { | ||
737 | case SYS_TEMP_INPUT: | ||
738 | res = TEMP_FROM_REG(data->temp[ix], 16); | ||
739 | break; | ||
740 | case SYS_TEMP_MIN: | ||
741 | res = TEMP_FROM_REG(data->temp_min[ix], 8); | ||
742 | break; | ||
743 | case SYS_TEMP_MAX: | ||
744 | res = TEMP_FROM_REG(data->temp_max[ix], 8); | ||
745 | break; | ||
746 | case SYS_TEMP_OFFSET: | ||
747 | res = TEMP_FROM_REG(data->temp_offset[ix], 8); | ||
748 | break; | ||
749 | case SYS_TEMP_ALARM: | ||
750 | res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01; | ||
751 | break; | ||
752 | case SYS_TEMP_FAULT: | ||
753 | res = (data->temp[ix] == 0x0800); | ||
754 | break; | ||
755 | default: | ||
756 | res = 0; | ||
757 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
758 | } | ||
759 | |||
760 | return sprintf(buf, "%d\n", res); | ||
761 | } | ||
762 | |||
763 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | ||
764 | const char *buf, size_t count) | ||
765 | { | ||
766 | struct i2c_client *client = to_i2c_client(dev); | ||
767 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
768 | struct sensor_device_attribute_2 | ||
769 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
770 | int ix = sensor_attr_2->index; | ||
771 | int fn = sensor_attr_2->nr; | ||
772 | long val = simple_strtol(buf, NULL, 10); | ||
773 | |||
774 | mutex_lock(&data->update_lock); | ||
775 | switch (fn) { | ||
776 | case SYS_TEMP_MIN: | ||
777 | data->temp_min[ix] = TEMP_TO_REG(val); | ||
778 | dme1737_write(client, DME1737_REG_TEMP_MIN(ix), | ||
779 | data->temp_min[ix]); | ||
780 | break; | ||
781 | case SYS_TEMP_MAX: | ||
782 | data->temp_max[ix] = TEMP_TO_REG(val); | ||
783 | dme1737_write(client, DME1737_REG_TEMP_MAX(ix), | ||
784 | data->temp_max[ix]); | ||
785 | break; | ||
786 | case SYS_TEMP_OFFSET: | ||
787 | data->temp_offset[ix] = TEMP_TO_REG(val); | ||
788 | dme1737_write(client, DME1737_REG_TEMP_OFFSET(ix), | ||
789 | data->temp_offset[ix]); | ||
790 | break; | ||
791 | default: | ||
792 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
793 | } | ||
794 | mutex_unlock(&data->update_lock); | ||
795 | |||
796 | return count; | ||
797 | } | ||
798 | |||
799 | /* --------------------------------------------------------------------- | ||
800 | * Zone sysfs attributes | ||
801 | * ix = [0-2] | ||
802 | * --------------------------------------------------------------------- */ | ||
803 | |||
804 | #define SYS_ZONE_AUTO_CHANNELS_TEMP 0 | ||
805 | #define SYS_ZONE_AUTO_POINT1_TEMP_HYST 1 | ||
806 | #define SYS_ZONE_AUTO_POINT1_TEMP 2 | ||
807 | #define SYS_ZONE_AUTO_POINT2_TEMP 3 | ||
808 | #define SYS_ZONE_AUTO_POINT3_TEMP 4 | ||
809 | |||
810 | static ssize_t show_zone(struct device *dev, struct device_attribute *attr, | ||
811 | char *buf) | ||
812 | { | ||
813 | struct dme1737_data *data = dme1737_update_device(dev); | ||
814 | struct sensor_device_attribute_2 | ||
815 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
816 | int ix = sensor_attr_2->index; | ||
817 | int fn = sensor_attr_2->nr; | ||
818 | int res; | ||
819 | |||
820 | switch (fn) { | ||
821 | case SYS_ZONE_AUTO_CHANNELS_TEMP: | ||
822 | /* check config2 for non-standard temp-to-zone mapping */ | ||
823 | if ((ix == 1) && (data->config2 & 0x02)) { | ||
824 | res = 4; | ||
825 | } else { | ||
826 | res = 1 << ix; | ||
827 | } | ||
828 | break; | ||
829 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: | ||
830 | res = TEMP_FROM_REG(data->zone_low[ix], 8) - | ||
831 | TEMP_HYST_FROM_REG(data->zone_hyst[ix == 2], ix); | ||
832 | break; | ||
833 | case SYS_ZONE_AUTO_POINT1_TEMP: | ||
834 | res = TEMP_FROM_REG(data->zone_low[ix], 8); | ||
835 | break; | ||
836 | case SYS_ZONE_AUTO_POINT2_TEMP: | ||
837 | /* pwm_freq holds the temp range bits in the upper nibble */ | ||
838 | res = TEMP_FROM_REG(data->zone_low[ix], 8) + | ||
839 | TEMP_RANGE_FROM_REG(data->pwm_freq[ix]); | ||
840 | break; | ||
841 | case SYS_ZONE_AUTO_POINT3_TEMP: | ||
842 | res = TEMP_FROM_REG(data->zone_abs[ix], 8); | ||
843 | break; | ||
844 | default: | ||
845 | res = 0; | ||
846 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
847 | } | ||
848 | |||
849 | return sprintf(buf, "%d\n", res); | ||
850 | } | ||
851 | |||
852 | static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | ||
853 | const char *buf, size_t count) | ||
854 | { | ||
855 | struct i2c_client *client = to_i2c_client(dev); | ||
856 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
857 | struct sensor_device_attribute_2 | ||
858 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
859 | int ix = sensor_attr_2->index; | ||
860 | int fn = sensor_attr_2->nr; | ||
861 | long val = simple_strtol(buf, NULL, 10); | ||
862 | |||
863 | mutex_lock(&data->update_lock); | ||
864 | switch (fn) { | ||
865 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: | ||
866 | /* Refresh the cache */ | ||
867 | data->zone_low[ix] = dme1737_read(client, | ||
868 | DME1737_REG_ZONE_LOW(ix)); | ||
869 | /* Modify the temp hyst value */ | ||
870 | data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( | ||
871 | TEMP_FROM_REG(data->zone_low[ix], 8) - | ||
872 | val, ix, dme1737_read(client, | ||
873 | DME1737_REG_ZONE_HYST(ix == 2))); | ||
874 | dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2), | ||
875 | data->zone_hyst[ix == 2]); | ||
876 | break; | ||
877 | case SYS_ZONE_AUTO_POINT1_TEMP: | ||
878 | data->zone_low[ix] = TEMP_TO_REG(val); | ||
879 | dme1737_write(client, DME1737_REG_ZONE_LOW(ix), | ||
880 | data->zone_low[ix]); | ||
881 | break; | ||
882 | case SYS_ZONE_AUTO_POINT2_TEMP: | ||
883 | /* Refresh the cache */ | ||
884 | data->zone_low[ix] = dme1737_read(client, | ||
885 | DME1737_REG_ZONE_LOW(ix)); | ||
886 | /* Modify the temp range value (which is stored in the upper | ||
887 | * nibble of the pwm_freq register) */ | ||
888 | data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - | ||
889 | TEMP_FROM_REG(data->zone_low[ix], 8), | ||
890 | dme1737_read(client, | ||
891 | DME1737_REG_PWM_FREQ(ix))); | ||
892 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | ||
893 | data->pwm_freq[ix]); | ||
894 | break; | ||
895 | case SYS_ZONE_AUTO_POINT3_TEMP: | ||
896 | data->zone_abs[ix] = TEMP_TO_REG(val); | ||
897 | dme1737_write(client, DME1737_REG_ZONE_ABS(ix), | ||
898 | data->zone_abs[ix]); | ||
899 | break; | ||
900 | default: | ||
901 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
902 | } | ||
903 | mutex_unlock(&data->update_lock); | ||
904 | |||
905 | return count; | ||
906 | } | ||
907 | |||
908 | /* --------------------------------------------------------------------- | ||
909 | * Fan sysfs attributes | ||
910 | * ix = [0-5] | ||
911 | * --------------------------------------------------------------------- */ | ||
912 | |||
913 | #define SYS_FAN_INPUT 0 | ||
914 | #define SYS_FAN_MIN 1 | ||
915 | #define SYS_FAN_MAX 2 | ||
916 | #define SYS_FAN_ALARM 3 | ||
917 | #define SYS_FAN_TYPE 4 | ||
918 | |||
919 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | ||
920 | char *buf) | ||
921 | { | ||
922 | struct dme1737_data *data = dme1737_update_device(dev); | ||
923 | struct sensor_device_attribute_2 | ||
924 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
925 | int ix = sensor_attr_2->index; | ||
926 | int fn = sensor_attr_2->nr; | ||
927 | int res; | ||
928 | |||
929 | switch (fn) { | ||
930 | case SYS_FAN_INPUT: | ||
931 | res = FAN_FROM_REG(data->fan[ix], | ||
932 | ix < 4 ? 0 : | ||
933 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
934 | break; | ||
935 | case SYS_FAN_MIN: | ||
936 | res = FAN_FROM_REG(data->fan_min[ix], | ||
937 | ix < 4 ? 0 : | ||
938 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
939 | break; | ||
940 | case SYS_FAN_MAX: | ||
941 | /* only valid for fan[5-6] */ | ||
942 | res = FAN_MAX_FROM_REG(data->fan_max[ix - 4]); | ||
943 | break; | ||
944 | case SYS_FAN_ALARM: | ||
945 | res = (data->alarms >> DME1737_BIT_ALARM_FAN[ix]) & 0x01; | ||
946 | break; | ||
947 | case SYS_FAN_TYPE: | ||
948 | /* only valid for fan[1-4] */ | ||
949 | res = FAN_TYPE_FROM_REG(data->fan_opt[ix]); | ||
950 | break; | ||
951 | default: | ||
952 | res = 0; | ||
953 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
954 | } | ||
955 | |||
956 | return sprintf(buf, "%d\n", res); | ||
957 | } | ||
958 | |||
959 | static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | ||
960 | const char *buf, size_t count) | ||
961 | { | ||
962 | struct i2c_client *client = to_i2c_client(dev); | ||
963 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
964 | struct sensor_device_attribute_2 | ||
965 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
966 | int ix = sensor_attr_2->index; | ||
967 | int fn = sensor_attr_2->nr; | ||
968 | long val = simple_strtol(buf, NULL, 10); | ||
969 | |||
970 | mutex_lock(&data->update_lock); | ||
971 | switch (fn) { | ||
972 | case SYS_FAN_MIN: | ||
973 | if (ix < 4) { | ||
974 | data->fan_min[ix] = FAN_TO_REG(val, 0); | ||
975 | } else { | ||
976 | /* Refresh the cache */ | ||
977 | data->fan_opt[ix] = dme1737_read(client, | ||
978 | DME1737_REG_FAN_OPT(ix)); | ||
979 | /* Modify the fan min value */ | ||
980 | data->fan_min[ix] = FAN_TO_REG(val, | ||
981 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
982 | } | ||
983 | dme1737_write(client, DME1737_REG_FAN_MIN(ix), | ||
984 | data->fan_min[ix] & 0xff); | ||
985 | dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1, | ||
986 | data->fan_min[ix] >> 8); | ||
987 | break; | ||
988 | case SYS_FAN_MAX: | ||
989 | /* Only valid for fan[5-6] */ | ||
990 | data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); | ||
991 | dme1737_write(client, DME1737_REG_FAN_MAX(ix), | ||
992 | data->fan_max[ix - 4]); | ||
993 | break; | ||
994 | case SYS_FAN_TYPE: | ||
995 | /* Only valid for fan[1-4] */ | ||
996 | if (!(val == 1 || val == 2 || val == 4)) { | ||
997 | count = -EINVAL; | ||
998 | dev_warn(&client->dev, "Fan type value %ld not " | ||
999 | "supported. Choose one of 1, 2, or 4.\n", | ||
1000 | val); | ||
1001 | goto exit; | ||
1002 | } | ||
1003 | data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client, | ||
1004 | DME1737_REG_FAN_OPT(ix))); | ||
1005 | dme1737_write(client, DME1737_REG_FAN_OPT(ix), | ||
1006 | data->fan_opt[ix]); | ||
1007 | break; | ||
1008 | default: | ||
1009 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
1010 | } | ||
1011 | exit: | ||
1012 | mutex_unlock(&data->update_lock); | ||
1013 | |||
1014 | return count; | ||
1015 | } | ||
1016 | |||
1017 | /* --------------------------------------------------------------------- | ||
1018 | * PWM sysfs attributes | ||
1019 | * ix = [0-4] | ||
1020 | * --------------------------------------------------------------------- */ | ||
1021 | |||
1022 | #define SYS_PWM 0 | ||
1023 | #define SYS_PWM_FREQ 1 | ||
1024 | #define SYS_PWM_ENABLE 2 | ||
1025 | #define SYS_PWM_RAMP_RATE 3 | ||
1026 | #define SYS_PWM_AUTO_CHANNELS_ZONE 4 | ||
1027 | #define SYS_PWM_AUTO_PWM_MIN 5 | ||
1028 | #define SYS_PWM_AUTO_POINT1_PWM 6 | ||
1029 | #define SYS_PWM_AUTO_POINT2_PWM 7 | ||
1030 | |||
1031 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
1032 | char *buf) | ||
1033 | { | ||
1034 | struct dme1737_data *data = dme1737_update_device(dev); | ||
1035 | struct sensor_device_attribute_2 | ||
1036 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
1037 | int ix = sensor_attr_2->index; | ||
1038 | int fn = sensor_attr_2->nr; | ||
1039 | int res; | ||
1040 | |||
1041 | switch (fn) { | ||
1042 | case SYS_PWM: | ||
1043 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) { | ||
1044 | res = 255; | ||
1045 | } else { | ||
1046 | res = data->pwm[ix]; | ||
1047 | } | ||
1048 | break; | ||
1049 | case SYS_PWM_FREQ: | ||
1050 | res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]); | ||
1051 | break; | ||
1052 | case SYS_PWM_ENABLE: | ||
1053 | if (ix > 3) { | ||
1054 | res = 1; /* pwm[5-6] hard-wired to manual mode */ | ||
1055 | } else { | ||
1056 | res = PWM_EN_FROM_REG(data->pwm_config[ix]); | ||
1057 | } | ||
1058 | break; | ||
1059 | case SYS_PWM_RAMP_RATE: | ||
1060 | /* Only valid for pwm[1-3] */ | ||
1061 | res = PWM_RR_FROM_REG(data->pwm_rr[ix > 0], ix); | ||
1062 | break; | ||
1063 | case SYS_PWM_AUTO_CHANNELS_ZONE: | ||
1064 | /* Only valid for pwm[1-3] */ | ||
1065 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
1066 | res = PWM_ACZ_FROM_REG(data->pwm_config[ix]); | ||
1067 | } else { | ||
1068 | res = data->pwm_acz[ix]; | ||
1069 | } | ||
1070 | break; | ||
1071 | case SYS_PWM_AUTO_PWM_MIN: | ||
1072 | /* Only valid for pwm[1-3] */ | ||
1073 | if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) { | ||
1074 | res = data->pwm_min[ix]; | ||
1075 | } else { | ||
1076 | res = 0; | ||
1077 | } | ||
1078 | break; | ||
1079 | case SYS_PWM_AUTO_POINT1_PWM: | ||
1080 | /* Only valid for pwm[1-3] */ | ||
1081 | res = data->pwm_min[ix]; | ||
1082 | break; | ||
1083 | case SYS_PWM_AUTO_POINT2_PWM: | ||
1084 | /* Only valid for pwm[1-3] */ | ||
1085 | res = 255; /* hard-wired */ | ||
1086 | break; | ||
1087 | default: | ||
1088 | res = 0; | ||
1089 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
1090 | } | ||
1091 | |||
1092 | return sprintf(buf, "%d\n", res); | ||
1093 | } | ||
1094 | |||
1095 | static struct attribute *dme1737_attr_pwm[]; | ||
1096 | static void dme1737_chmod_file(struct i2c_client*, struct attribute*, mode_t); | ||
1097 | |||
1098 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | ||
1099 | const char *buf, size_t count) | ||
1100 | { | ||
1101 | struct i2c_client *client = to_i2c_client(dev); | ||
1102 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1103 | struct sensor_device_attribute_2 | ||
1104 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
1105 | int ix = sensor_attr_2->index; | ||
1106 | int fn = sensor_attr_2->nr; | ||
1107 | long val = simple_strtol(buf, NULL, 10); | ||
1108 | |||
1109 | mutex_lock(&data->update_lock); | ||
1110 | switch (fn) { | ||
1111 | case SYS_PWM: | ||
1112 | data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); | ||
1113 | dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]); | ||
1114 | break; | ||
1115 | case SYS_PWM_FREQ: | ||
1116 | data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client, | ||
1117 | DME1737_REG_PWM_FREQ(ix))); | ||
1118 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | ||
1119 | data->pwm_freq[ix]); | ||
1120 | break; | ||
1121 | case SYS_PWM_ENABLE: | ||
1122 | /* Only valid for pwm[1-3] */ | ||
1123 | if (val < 0 || val > 2) { | ||
1124 | count = -EINVAL; | ||
1125 | dev_warn(&client->dev, "PWM enable %ld not " | ||
1126 | "supported. Choose one of 0, 1, or 2.\n", | ||
1127 | val); | ||
1128 | goto exit; | ||
1129 | } | ||
1130 | /* Refresh the cache */ | ||
1131 | data->pwm_config[ix] = dme1737_read(client, | ||
1132 | DME1737_REG_PWM_CONFIG(ix)); | ||
1133 | if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { | ||
1134 | /* Bail out if no change */ | ||
1135 | goto exit; | ||
1136 | } | ||
1137 | /* Do some housekeeping if we are currently in auto mode */ | ||
1138 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
1139 | /* Save the current zone channel assignment */ | ||
1140 | data->pwm_acz[ix] = PWM_ACZ_FROM_REG( | ||
1141 | data->pwm_config[ix]); | ||
1142 | /* Save the current ramp rate state and disable it */ | ||
1143 | data->pwm_rr[ix > 0] = dme1737_read(client, | ||
1144 | DME1737_REG_PWM_RR(ix > 0)); | ||
1145 | data->pwm_rr_en &= ~(1 << ix); | ||
1146 | if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { | ||
1147 | data->pwm_rr_en |= (1 << ix); | ||
1148 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, | ||
1149 | data->pwm_rr[ix > 0]); | ||
1150 | dme1737_write(client, | ||
1151 | DME1737_REG_PWM_RR(ix > 0), | ||
1152 | data->pwm_rr[ix > 0]); | ||
1153 | } | ||
1154 | } | ||
1155 | /* Set the new PWM mode */ | ||
1156 | switch (val) { | ||
1157 | case 0: | ||
1158 | /* Change permissions of pwm[ix] to read-only */ | ||
1159 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
1160 | S_IRUGO); | ||
1161 | /* Turn fan fully on */ | ||
1162 | data->pwm_config[ix] = PWM_EN_TO_REG(0, | ||
1163 | data->pwm_config[ix]); | ||
1164 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
1165 | data->pwm_config[ix]); | ||
1166 | break; | ||
1167 | case 1: | ||
1168 | /* Turn on manual mode */ | ||
1169 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | ||
1170 | data->pwm_config[ix]); | ||
1171 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
1172 | data->pwm_config[ix]); | ||
1173 | /* Change permissions of pwm[ix] to read-writeable */ | ||
1174 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
1175 | S_IRUGO | S_IWUSR); | ||
1176 | break; | ||
1177 | case 2: | ||
1178 | /* Change permissions of pwm[ix] to read-only */ | ||
1179 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
1180 | S_IRUGO); | ||
1181 | /* Turn on auto mode using the saved zone channel | ||
1182 | * assignment */ | ||
1183 | data->pwm_config[ix] = PWM_ACZ_TO_REG( | ||
1184 | data->pwm_acz[ix], | ||
1185 | data->pwm_config[ix]); | ||
1186 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
1187 | data->pwm_config[ix]); | ||
1188 | /* Enable PWM ramp rate if previously enabled */ | ||
1189 | if (data->pwm_rr_en & (1 << ix)) { | ||
1190 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, | ||
1191 | dme1737_read(client, | ||
1192 | DME1737_REG_PWM_RR(ix > 0))); | ||
1193 | dme1737_write(client, | ||
1194 | DME1737_REG_PWM_RR(ix > 0), | ||
1195 | data->pwm_rr[ix > 0]); | ||
1196 | } | ||
1197 | break; | ||
1198 | } | ||
1199 | break; | ||
1200 | case SYS_PWM_RAMP_RATE: | ||
1201 | /* Only valid for pwm[1-3] */ | ||
1202 | /* Refresh the cache */ | ||
1203 | data->pwm_config[ix] = dme1737_read(client, | ||
1204 | DME1737_REG_PWM_CONFIG(ix)); | ||
1205 | data->pwm_rr[ix > 0] = dme1737_read(client, | ||
1206 | DME1737_REG_PWM_RR(ix > 0)); | ||
1207 | /* Set the ramp rate value */ | ||
1208 | if (val > 0) { | ||
1209 | data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix, | ||
1210 | data->pwm_rr[ix > 0]); | ||
1211 | } | ||
1212 | /* Enable/disable the feature only if the associated PWM | ||
1213 | * output is in automatic mode. */ | ||
1214 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
1215 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, | ||
1216 | data->pwm_rr[ix > 0]); | ||
1217 | } | ||
1218 | dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), | ||
1219 | data->pwm_rr[ix > 0]); | ||
1220 | break; | ||
1221 | case SYS_PWM_AUTO_CHANNELS_ZONE: | ||
1222 | /* Only valid for pwm[1-3] */ | ||
1223 | if (!(val == 1 || val == 2 || val == 4 || | ||
1224 | val == 6 || val == 7)) { | ||
1225 | count = -EINVAL; | ||
1226 | dev_warn(&client->dev, "PWM auto channels zone %ld " | ||
1227 | "not supported. Choose one of 1, 2, 4, 6, " | ||
1228 | "or 7.\n", val); | ||
1229 | goto exit; | ||
1230 | } | ||
1231 | /* Refresh the cache */ | ||
1232 | data->pwm_config[ix] = dme1737_read(client, | ||
1233 | DME1737_REG_PWM_CONFIG(ix)); | ||
1234 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
1235 | /* PWM is already in auto mode so update the temp | ||
1236 | * channel assignment */ | ||
1237 | data->pwm_config[ix] = PWM_ACZ_TO_REG(val, | ||
1238 | data->pwm_config[ix]); | ||
1239 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
1240 | data->pwm_config[ix]); | ||
1241 | } else { | ||
1242 | /* PWM is not in auto mode so we save the temp | ||
1243 | * channel assignment for later use */ | ||
1244 | data->pwm_acz[ix] = val; | ||
1245 | } | ||
1246 | break; | ||
1247 | case SYS_PWM_AUTO_PWM_MIN: | ||
1248 | /* Only valid for pwm[1-3] */ | ||
1249 | /* Refresh the cache */ | ||
1250 | data->pwm_min[ix] = dme1737_read(client, | ||
1251 | DME1737_REG_PWM_MIN(ix)); | ||
1252 | /* There are only 2 values supported for the auto_pwm_min | ||
1253 | * value: 0 or auto_point1_pwm. So if the temperature drops | ||
1254 | * below the auto_point1_temp_hyst value, the fan either turns | ||
1255 | * off or runs at auto_point1_pwm duty-cycle. */ | ||
1256 | if (val > ((data->pwm_min[ix] + 1) / 2)) { | ||
1257 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, | ||
1258 | dme1737_read(client, | ||
1259 | DME1737_REG_PWM_RR(0))); | ||
1260 | |||
1261 | } else { | ||
1262 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, | ||
1263 | dme1737_read(client, | ||
1264 | DME1737_REG_PWM_RR(0))); | ||
1265 | |||
1266 | } | ||
1267 | dme1737_write(client, DME1737_REG_PWM_RR(0), | ||
1268 | data->pwm_rr[0]); | ||
1269 | break; | ||
1270 | case SYS_PWM_AUTO_POINT1_PWM: | ||
1271 | /* Only valid for pwm[1-3] */ | ||
1272 | data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); | ||
1273 | dme1737_write(client, DME1737_REG_PWM_MIN(ix), | ||
1274 | data->pwm_min[ix]); | ||
1275 | break; | ||
1276 | default: | ||
1277 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
1278 | } | ||
1279 | exit: | ||
1280 | mutex_unlock(&data->update_lock); | ||
1281 | |||
1282 | return count; | ||
1283 | } | ||
1284 | |||
1285 | /* --------------------------------------------------------------------- | ||
1286 | * Miscellaneous sysfs attributes | ||
1287 | * --------------------------------------------------------------------- */ | ||
1288 | |||
1289 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, | ||
1290 | char *buf) | ||
1291 | { | ||
1292 | struct i2c_client *client = to_i2c_client(dev); | ||
1293 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1294 | |||
1295 | return sprintf(buf, "%d\n", data->vrm); | ||
1296 | } | ||
1297 | |||
1298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, | ||
1299 | const char *buf, size_t count) | ||
1300 | { | ||
1301 | struct i2c_client *client = to_i2c_client(dev); | ||
1302 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1303 | long val = simple_strtol(buf, NULL, 10); | ||
1304 | |||
1305 | data->vrm = val; | ||
1306 | return count; | ||
1307 | } | ||
1308 | |||
1309 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | ||
1310 | char *buf) | ||
1311 | { | ||
1312 | struct dme1737_data *data = dme1737_update_device(dev); | ||
1313 | |||
1314 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
1315 | } | ||
1316 | |||
1317 | /* --------------------------------------------------------------------- | ||
1318 | * Sysfs device attribute defines and structs | ||
1319 | * --------------------------------------------------------------------- */ | ||
1320 | |||
1321 | /* Voltages 0-6 */ | ||
1322 | |||
1323 | #define SENSOR_DEVICE_ATTR_IN(ix) \ | ||
1324 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ | ||
1325 | show_in, NULL, SYS_IN_INPUT, ix); \ | ||
1326 | static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ | ||
1327 | show_in, set_in, SYS_IN_MIN, ix); \ | ||
1328 | static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ | ||
1329 | show_in, set_in, SYS_IN_MAX, ix); \ | ||
1330 | static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \ | ||
1331 | show_in, NULL, SYS_IN_ALARM, ix) | ||
1332 | |||
1333 | SENSOR_DEVICE_ATTR_IN(0); | ||
1334 | SENSOR_DEVICE_ATTR_IN(1); | ||
1335 | SENSOR_DEVICE_ATTR_IN(2); | ||
1336 | SENSOR_DEVICE_ATTR_IN(3); | ||
1337 | SENSOR_DEVICE_ATTR_IN(4); | ||
1338 | SENSOR_DEVICE_ATTR_IN(5); | ||
1339 | SENSOR_DEVICE_ATTR_IN(6); | ||
1340 | |||
1341 | /* Temperatures 1-3 */ | ||
1342 | |||
1343 | #define SENSOR_DEVICE_ATTR_TEMP(ix) \ | ||
1344 | static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \ | ||
1345 | show_temp, NULL, SYS_TEMP_INPUT, ix-1); \ | ||
1346 | static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \ | ||
1347 | show_temp, set_temp, SYS_TEMP_MIN, ix-1); \ | ||
1348 | static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ | ||
1349 | show_temp, set_temp, SYS_TEMP_MAX, ix-1); \ | ||
1350 | static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \ | ||
1351 | show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \ | ||
1352 | static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \ | ||
1353 | show_temp, NULL, SYS_TEMP_ALARM, ix-1); \ | ||
1354 | static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \ | ||
1355 | show_temp, NULL, SYS_TEMP_FAULT, ix-1) | ||
1356 | |||
1357 | SENSOR_DEVICE_ATTR_TEMP(1); | ||
1358 | SENSOR_DEVICE_ATTR_TEMP(2); | ||
1359 | SENSOR_DEVICE_ATTR_TEMP(3); | ||
1360 | |||
1361 | /* Zones 1-3 */ | ||
1362 | |||
1363 | #define SENSOR_DEVICE_ATTR_ZONE(ix) \ | ||
1364 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \ | ||
1365 | show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \ | ||
1366 | 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); \ | ||
1368 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \ | ||
1369 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \ | ||
1370 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \ | ||
1371 | show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \ | ||
1372 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \ | ||
1373 | show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1) | ||
1374 | |||
1375 | SENSOR_DEVICE_ATTR_ZONE(1); | ||
1376 | SENSOR_DEVICE_ATTR_ZONE(2); | ||
1377 | SENSOR_DEVICE_ATTR_ZONE(3); | ||
1378 | |||
1379 | /* Fans 1-4 */ | ||
1380 | |||
1381 | #define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \ | ||
1382 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | ||
1383 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | ||
1384 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | ||
1385 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | ||
1386 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | ||
1387 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | ||
1388 | static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \ | ||
1389 | show_fan, set_fan, SYS_FAN_TYPE, ix-1) | ||
1390 | |||
1391 | SENSOR_DEVICE_ATTR_FAN_1TO4(1); | ||
1392 | SENSOR_DEVICE_ATTR_FAN_1TO4(2); | ||
1393 | SENSOR_DEVICE_ATTR_FAN_1TO4(3); | ||
1394 | SENSOR_DEVICE_ATTR_FAN_1TO4(4); | ||
1395 | |||
1396 | /* Fans 5-6 */ | ||
1397 | |||
1398 | #define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \ | ||
1399 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | ||
1400 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | ||
1401 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | ||
1402 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | ||
1403 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | ||
1404 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | ||
1405 | static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \ | ||
1406 | show_fan, set_fan, SYS_FAN_MAX, ix-1) | ||
1407 | |||
1408 | SENSOR_DEVICE_ATTR_FAN_5TO6(5); | ||
1409 | SENSOR_DEVICE_ATTR_FAN_5TO6(6); | ||
1410 | |||
1411 | /* PWMs 1-3 */ | ||
1412 | |||
1413 | #define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \ | ||
1414 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \ | ||
1415 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | ||
1416 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \ | ||
1417 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | ||
1418 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | ||
1419 | show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \ | ||
1420 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \ | ||
1421 | show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \ | ||
1422 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \ | ||
1423 | show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \ | ||
1424 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \ | ||
1425 | show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \ | ||
1426 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \ | ||
1427 | show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \ | ||
1428 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \ | ||
1429 | show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1) | ||
1430 | |||
1431 | SENSOR_DEVICE_ATTR_PWM_1TO3(1); | ||
1432 | SENSOR_DEVICE_ATTR_PWM_1TO3(2); | ||
1433 | SENSOR_DEVICE_ATTR_PWM_1TO3(3); | ||
1434 | |||
1435 | /* PWMs 5-6 */ | ||
1436 | |||
1437 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ | ||
1438 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \ | ||
1439 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | ||
1440 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ | ||
1441 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | ||
1442 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | ||
1443 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) | ||
1444 | |||
1445 | SENSOR_DEVICE_ATTR_PWM_5TO6(5); | ||
1446 | SENSOR_DEVICE_ATTR_PWM_5TO6(6); | ||
1447 | |||
1448 | /* Misc */ | ||
1449 | |||
1450 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); | ||
1451 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
1452 | |||
1453 | #define SENSOR_DEV_ATTR_IN(ix) \ | ||
1454 | &sensor_dev_attr_in##ix##_input.dev_attr.attr, \ | ||
1455 | &sensor_dev_attr_in##ix##_min.dev_attr.attr, \ | ||
1456 | &sensor_dev_attr_in##ix##_max.dev_attr.attr, \ | ||
1457 | &sensor_dev_attr_in##ix##_alarm.dev_attr.attr | ||
1458 | |||
1459 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1460 | #define SENSOR_DEV_ATTR_TEMP_LOCK(ix) \ | ||
1461 | &sensor_dev_attr_temp##ix##_offset.dev_attr.attr | ||
1462 | |||
1463 | #define SENSOR_DEV_ATTR_TEMP(ix) \ | ||
1464 | SENSOR_DEV_ATTR_TEMP_LOCK(ix), \ | ||
1465 | &sensor_dev_attr_temp##ix##_input.dev_attr.attr, \ | ||
1466 | &sensor_dev_attr_temp##ix##_min.dev_attr.attr, \ | ||
1467 | &sensor_dev_attr_temp##ix##_max.dev_attr.attr, \ | ||
1468 | &sensor_dev_attr_temp##ix##_alarm.dev_attr.attr, \ | ||
1469 | &sensor_dev_attr_temp##ix##_fault.dev_attr.attr | ||
1470 | |||
1471 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1472 | #define SENSOR_DEV_ATTR_ZONE_LOCK(ix) \ | ||
1473 | &sensor_dev_attr_zone##ix##_auto_point1_temp_hyst.dev_attr.attr, \ | ||
1474 | &sensor_dev_attr_zone##ix##_auto_point1_temp.dev_attr.attr, \ | ||
1475 | &sensor_dev_attr_zone##ix##_auto_point2_temp.dev_attr.attr, \ | ||
1476 | &sensor_dev_attr_zone##ix##_auto_point3_temp.dev_attr.attr | ||
1477 | |||
1478 | #define SENSOR_DEV_ATTR_ZONE(ix) \ | ||
1479 | SENSOR_DEV_ATTR_ZONE_LOCK(ix), \ | ||
1480 | &sensor_dev_attr_zone##ix##_auto_channels_temp.dev_attr.attr | ||
1481 | |||
1482 | #define SENSOR_DEV_ATTR_FAN_1TO4(ix) \ | ||
1483 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
1484 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
1485 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
1486 | &sensor_dev_attr_fan##ix##_type.dev_attr.attr | ||
1487 | |||
1488 | #define SENSOR_DEV_ATTR_FAN_5TO6(ix) \ | ||
1489 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
1490 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
1491 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
1492 | &sensor_dev_attr_fan##ix##_max.dev_attr.attr | ||
1493 | |||
1494 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1495 | #define SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix) \ | ||
1496 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr, \ | ||
1497 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr, \ | ||
1498 | &sensor_dev_attr_pwm##ix##_ramp_rate.dev_attr.attr, \ | ||
1499 | &sensor_dev_attr_pwm##ix##_auto_channels_zone.dev_attr.attr, \ | ||
1500 | &sensor_dev_attr_pwm##ix##_auto_pwm_min.dev_attr.attr, \ | ||
1501 | &sensor_dev_attr_pwm##ix##_auto_point1_pwm.dev_attr.attr | ||
1502 | |||
1503 | #define SENSOR_DEV_ATTR_PWM_1TO3(ix) \ | ||
1504 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix), \ | ||
1505 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
1506 | &sensor_dev_attr_pwm##ix##_auto_point2_pwm.dev_attr.attr | ||
1507 | |||
1508 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1509 | #define SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix) \ | ||
1510 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
1511 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr | ||
1512 | |||
1513 | #define SENSOR_DEV_ATTR_PWM_5TO6(ix) \ | ||
1514 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix), \ | ||
1515 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr | ||
1516 | |||
1517 | /* This struct holds all the attributes that are always present and need to be | ||
1518 | * created unconditionally. The attributes that need modification of their | ||
1519 | * permissions are created read-only and write permissions are added or removed | ||
1520 | * on the fly when required */ | ||
1521 | static struct attribute *dme1737_attr[] ={ | ||
1522 | /* Voltages */ | ||
1523 | SENSOR_DEV_ATTR_IN(0), | ||
1524 | SENSOR_DEV_ATTR_IN(1), | ||
1525 | SENSOR_DEV_ATTR_IN(2), | ||
1526 | SENSOR_DEV_ATTR_IN(3), | ||
1527 | SENSOR_DEV_ATTR_IN(4), | ||
1528 | SENSOR_DEV_ATTR_IN(5), | ||
1529 | SENSOR_DEV_ATTR_IN(6), | ||
1530 | /* Temperatures */ | ||
1531 | SENSOR_DEV_ATTR_TEMP(1), | ||
1532 | SENSOR_DEV_ATTR_TEMP(2), | ||
1533 | SENSOR_DEV_ATTR_TEMP(3), | ||
1534 | /* Zones */ | ||
1535 | SENSOR_DEV_ATTR_ZONE(1), | ||
1536 | SENSOR_DEV_ATTR_ZONE(2), | ||
1537 | SENSOR_DEV_ATTR_ZONE(3), | ||
1538 | /* Misc */ | ||
1539 | &dev_attr_vrm.attr, | ||
1540 | &dev_attr_cpu0_vid.attr, | ||
1541 | NULL | ||
1542 | }; | ||
1543 | |||
1544 | static const struct attribute_group dme1737_group = { | ||
1545 | .attrs = dme1737_attr, | ||
1546 | }; | ||
1547 | |||
1548 | /* The following structs hold the PWM attributes, some of which are optional. | ||
1549 | * Their creation depends on the chip configuration which is determined during | ||
1550 | * module load. */ | ||
1551 | static struct attribute *dme1737_attr_pwm1[] = { | ||
1552 | SENSOR_DEV_ATTR_PWM_1TO3(1), | ||
1553 | NULL | ||
1554 | }; | ||
1555 | static struct attribute *dme1737_attr_pwm2[] = { | ||
1556 | SENSOR_DEV_ATTR_PWM_1TO3(2), | ||
1557 | NULL | ||
1558 | }; | ||
1559 | static struct attribute *dme1737_attr_pwm3[] = { | ||
1560 | SENSOR_DEV_ATTR_PWM_1TO3(3), | ||
1561 | NULL | ||
1562 | }; | ||
1563 | static struct attribute *dme1737_attr_pwm5[] = { | ||
1564 | SENSOR_DEV_ATTR_PWM_5TO6(5), | ||
1565 | NULL | ||
1566 | }; | ||
1567 | static struct attribute *dme1737_attr_pwm6[] = { | ||
1568 | SENSOR_DEV_ATTR_PWM_5TO6(6), | ||
1569 | NULL | ||
1570 | }; | ||
1571 | |||
1572 | static const struct attribute_group dme1737_pwm_group[] = { | ||
1573 | { .attrs = dme1737_attr_pwm1 }, | ||
1574 | { .attrs = dme1737_attr_pwm2 }, | ||
1575 | { .attrs = dme1737_attr_pwm3 }, | ||
1576 | { .attrs = NULL }, | ||
1577 | { .attrs = dme1737_attr_pwm5 }, | ||
1578 | { .attrs = dme1737_attr_pwm6 }, | ||
1579 | }; | ||
1580 | |||
1581 | /* The following structs hold the fan attributes, some of which are optional. | ||
1582 | * Their creation depends on the chip configuration which is determined during | ||
1583 | * module load. */ | ||
1584 | static struct attribute *dme1737_attr_fan1[] = { | ||
1585 | SENSOR_DEV_ATTR_FAN_1TO4(1), | ||
1586 | NULL | ||
1587 | }; | ||
1588 | static struct attribute *dme1737_attr_fan2[] = { | ||
1589 | SENSOR_DEV_ATTR_FAN_1TO4(2), | ||
1590 | NULL | ||
1591 | }; | ||
1592 | static struct attribute *dme1737_attr_fan3[] = { | ||
1593 | SENSOR_DEV_ATTR_FAN_1TO4(3), | ||
1594 | NULL | ||
1595 | }; | ||
1596 | static struct attribute *dme1737_attr_fan4[] = { | ||
1597 | SENSOR_DEV_ATTR_FAN_1TO4(4), | ||
1598 | NULL | ||
1599 | }; | ||
1600 | static struct attribute *dme1737_attr_fan5[] = { | ||
1601 | SENSOR_DEV_ATTR_FAN_5TO6(5), | ||
1602 | NULL | ||
1603 | }; | ||
1604 | static struct attribute *dme1737_attr_fan6[] = { | ||
1605 | SENSOR_DEV_ATTR_FAN_5TO6(6), | ||
1606 | NULL | ||
1607 | }; | ||
1608 | |||
1609 | static const struct attribute_group dme1737_fan_group[] = { | ||
1610 | { .attrs = dme1737_attr_fan1 }, | ||
1611 | { .attrs = dme1737_attr_fan2 }, | ||
1612 | { .attrs = dme1737_attr_fan3 }, | ||
1613 | { .attrs = dme1737_attr_fan4 }, | ||
1614 | { .attrs = dme1737_attr_fan5 }, | ||
1615 | { .attrs = dme1737_attr_fan6 }, | ||
1616 | }; | ||
1617 | |||
1618 | /* The permissions of all of the following attributes are changed to read- | ||
1619 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | ||
1620 | static struct attribute *dme1737_attr_lock[] = { | ||
1621 | /* Temperatures */ | ||
1622 | SENSOR_DEV_ATTR_TEMP_LOCK(1), | ||
1623 | SENSOR_DEV_ATTR_TEMP_LOCK(2), | ||
1624 | SENSOR_DEV_ATTR_TEMP_LOCK(3), | ||
1625 | /* Zones */ | ||
1626 | SENSOR_DEV_ATTR_ZONE_LOCK(1), | ||
1627 | SENSOR_DEV_ATTR_ZONE_LOCK(2), | ||
1628 | SENSOR_DEV_ATTR_ZONE_LOCK(3), | ||
1629 | NULL | ||
1630 | }; | ||
1631 | |||
1632 | static const struct attribute_group dme1737_lock_group = { | ||
1633 | .attrs = dme1737_attr_lock, | ||
1634 | }; | ||
1635 | |||
1636 | /* The permissions of the following PWM attributes are changed to read- | ||
1637 | * writeable if the chip is *not* locked and the respective PWM is available. | ||
1638 | * Otherwise they stay read-only. */ | ||
1639 | static struct attribute *dme1737_attr_pwm1_lock[] = { | ||
1640 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1), | ||
1641 | NULL | ||
1642 | }; | ||
1643 | static struct attribute *dme1737_attr_pwm2_lock[] = { | ||
1644 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2), | ||
1645 | NULL | ||
1646 | }; | ||
1647 | static struct attribute *dme1737_attr_pwm3_lock[] = { | ||
1648 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3), | ||
1649 | NULL | ||
1650 | }; | ||
1651 | static struct attribute *dme1737_attr_pwm5_lock[] = { | ||
1652 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5), | ||
1653 | NULL | ||
1654 | }; | ||
1655 | static struct attribute *dme1737_attr_pwm6_lock[] = { | ||
1656 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6), | ||
1657 | NULL | ||
1658 | }; | ||
1659 | |||
1660 | static const struct attribute_group dme1737_pwm_lock_group[] = { | ||
1661 | { .attrs = dme1737_attr_pwm1_lock }, | ||
1662 | { .attrs = dme1737_attr_pwm2_lock }, | ||
1663 | { .attrs = dme1737_attr_pwm3_lock }, | ||
1664 | { .attrs = NULL }, | ||
1665 | { .attrs = dme1737_attr_pwm5_lock }, | ||
1666 | { .attrs = dme1737_attr_pwm6_lock }, | ||
1667 | }; | ||
1668 | |||
1669 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the | ||
1670 | * chip is not locked. Otherwise they are read-only. */ | ||
1671 | static struct attribute *dme1737_attr_pwm[] = { | ||
1672 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
1673 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
1674 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
1675 | }; | ||
1676 | |||
1677 | /* --------------------------------------------------------------------- | ||
1678 | * Super-IO functions | ||
1679 | * --------------------------------------------------------------------- */ | ||
1680 | |||
1681 | static inline int dme1737_sio_inb(int sio_cip, int reg) | ||
1682 | { | ||
1683 | outb(reg, sio_cip); | ||
1684 | return inb(sio_cip + 1); | ||
1685 | } | ||
1686 | |||
1687 | static inline void dme1737_sio_outb(int sio_cip, int reg, int val) | ||
1688 | { | ||
1689 | outb(reg, sio_cip); | ||
1690 | outb(val, sio_cip + 1); | ||
1691 | } | ||
1692 | |||
1693 | static int dme1737_sio_get_features(int sio_cip, struct i2c_client *client) | ||
1694 | { | ||
1695 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1696 | int err = 0, reg; | ||
1697 | u16 addr; | ||
1698 | |||
1699 | /* Enter configuration mode */ | ||
1700 | outb(0x55, sio_cip); | ||
1701 | |||
1702 | /* Check device ID | ||
1703 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | ||
1704 | reg = dme1737_sio_inb(sio_cip, 0x20); | ||
1705 | if (!(reg == 0x77 || reg == 0x78)) { | ||
1706 | err = -ENODEV; | ||
1707 | goto exit; | ||
1708 | } | ||
1709 | |||
1710 | /* Select logical device A (runtime registers) */ | ||
1711 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | ||
1712 | |||
1713 | /* Get the base address of the runtime registers */ | ||
1714 | if (!(addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | ||
1715 | dme1737_sio_inb(sio_cip, 0x61))) { | ||
1716 | err = -ENODEV; | ||
1717 | goto exit; | ||
1718 | } | ||
1719 | |||
1720 | /* Read the runtime registers to determine which optional features | ||
1721 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | ||
1722 | * to '10' if the respective feature is enabled. */ | ||
1723 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | ||
1724 | data->has_fan |= (1 << 5); | ||
1725 | } | ||
1726 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | ||
1727 | data->has_pwm |= (1 << 5); | ||
1728 | } | ||
1729 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | ||
1730 | data->has_fan |= (1 << 4); | ||
1731 | } | ||
1732 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | ||
1733 | data->has_pwm |= (1 << 4); | ||
1734 | } | ||
1735 | |||
1736 | exit: | ||
1737 | /* Exit configuration mode */ | ||
1738 | outb(0xaa, sio_cip); | ||
1739 | |||
1740 | return err; | ||
1741 | } | ||
1742 | |||
1743 | /* --------------------------------------------------------------------- | ||
1744 | * Device detection, registration and initialization | ||
1745 | * --------------------------------------------------------------------- */ | ||
1746 | |||
1747 | static struct i2c_driver dme1737_driver; | ||
1748 | |||
1749 | static void dme1737_chmod_file(struct i2c_client *client, | ||
1750 | struct attribute *attr, mode_t mode) | ||
1751 | { | ||
1752 | if (sysfs_chmod_file(&client->dev.kobj, attr, mode)) { | ||
1753 | dev_warn(&client->dev, "Failed to change permissions of %s.\n", | ||
1754 | attr->name); | ||
1755 | } | ||
1756 | } | ||
1757 | |||
1758 | static void dme1737_chmod_group(struct i2c_client *client, | ||
1759 | const struct attribute_group *group, | ||
1760 | mode_t mode) | ||
1761 | { | ||
1762 | struct attribute **attr; | ||
1763 | |||
1764 | for (attr = group->attrs; *attr; attr++) { | ||
1765 | dme1737_chmod_file(client, *attr, mode); | ||
1766 | } | ||
1767 | } | ||
1768 | |||
1769 | static int dme1737_init_client(struct i2c_client *client) | ||
1770 | { | ||
1771 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
1772 | int ix; | ||
1773 | u8 reg; | ||
1774 | |||
1775 | data->config = dme1737_read(client, DME1737_REG_CONFIG); | ||
1776 | /* Inform if part is not monitoring/started */ | ||
1777 | if (!(data->config & 0x01)) { | ||
1778 | if (!force_start) { | ||
1779 | dev_err(&client->dev, "Device is not monitoring. " | ||
1780 | "Use the force_start load parameter to " | ||
1781 | "override.\n"); | ||
1782 | return -EFAULT; | ||
1783 | } | ||
1784 | |||
1785 | /* Force monitoring */ | ||
1786 | data->config |= 0x01; | ||
1787 | dme1737_write(client, DME1737_REG_CONFIG, data->config); | ||
1788 | } | ||
1789 | /* Inform if part is not ready */ | ||
1790 | if (!(data->config & 0x04)) { | ||
1791 | dev_err(&client->dev, "Device is not ready.\n"); | ||
1792 | return -EFAULT; | ||
1793 | } | ||
1794 | |||
1795 | data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); | ||
1796 | /* Check if optional fan3 input is enabled */ | ||
1797 | if (data->config2 & 0x04) { | ||
1798 | data->has_fan |= (1 << 2); | ||
1799 | } | ||
1800 | |||
1801 | /* Fan4 and pwm3 are only available if the client's I2C address | ||
1802 | * is the default 0x2e. Otherwise the I/Os associated with these | ||
1803 | * functions are used for addr enable/select. */ | ||
1804 | if (client->addr == 0x2e) { | ||
1805 | data->has_fan |= (1 << 3); | ||
1806 | data->has_pwm |= (1 << 2); | ||
1807 | } | ||
1808 | |||
1809 | /* Determine if the optional fan[5-6] and/or pwm[5-6] are enabled. | ||
1810 | * For this, we need to query the runtime registers through the | ||
1811 | * Super-IO LPC interface. Try both config ports 0x2e and 0x4e. */ | ||
1812 | if (dme1737_sio_get_features(0x2e, client) && | ||
1813 | dme1737_sio_get_features(0x4e, client)) { | ||
1814 | dev_warn(&client->dev, "Failed to query Super-IO for optional " | ||
1815 | "features.\n"); | ||
1816 | } | ||
1817 | |||
1818 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | ||
1819 | data->has_fan |= 0x03; | ||
1820 | data->has_pwm |= 0x03; | ||
1821 | |||
1822 | dev_info(&client->dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | ||
1823 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | ||
1824 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | ||
1825 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | ||
1826 | (data->has_pwm & (1 << 5)) ? "yes" : "no", | ||
1827 | (data->has_fan & (1 << 2)) ? "yes" : "no", | ||
1828 | (data->has_fan & (1 << 3)) ? "yes" : "no", | ||
1829 | (data->has_fan & (1 << 4)) ? "yes" : "no", | ||
1830 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | ||
1831 | |||
1832 | reg = dme1737_read(client, DME1737_REG_TACH_PWM); | ||
1833 | /* Inform if fan-to-pwm mapping differs from the default */ | ||
1834 | if (reg != 0xa4) { | ||
1835 | dev_warn(&client->dev, "Non-standard fan to pwm mapping: " | ||
1836 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " | ||
1837 | "fan4->pwm%d. Please report to the driver " | ||
1838 | "maintainer.\n", | ||
1839 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | ||
1840 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); | ||
1841 | } | ||
1842 | |||
1843 | /* Switch pwm[1-3] to manual mode if they are currently disabled and | ||
1844 | * set the duty-cycles to 0% (which is identical to the PWMs being | ||
1845 | * disabled). */ | ||
1846 | if (!(data->config & 0x02)) { | ||
1847 | for (ix = 0; ix < 3; ix++) { | ||
1848 | data->pwm_config[ix] = dme1737_read(client, | ||
1849 | DME1737_REG_PWM_CONFIG(ix)); | ||
1850 | if ((data->has_pwm & (1 << ix)) && | ||
1851 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | ||
1852 | dev_info(&client->dev, "Switching pwm%d to " | ||
1853 | "manual mode.\n", ix + 1); | ||
1854 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | ||
1855 | data->pwm_config[ix]); | ||
1856 | dme1737_write(client, DME1737_REG_PWM(ix), 0); | ||
1857 | dme1737_write(client, | ||
1858 | DME1737_REG_PWM_CONFIG(ix), | ||
1859 | data->pwm_config[ix]); | ||
1860 | } | ||
1861 | } | ||
1862 | } | ||
1863 | |||
1864 | /* Initialize the default PWM auto channels zone (acz) assignments */ | ||
1865 | data->pwm_acz[0] = 1; /* pwm1 -> zone1 */ | ||
1866 | data->pwm_acz[1] = 2; /* pwm2 -> zone2 */ | ||
1867 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | ||
1868 | |||
1869 | /* Set VRM */ | ||
1870 | data->vrm = vid_which_vrm(); | ||
1871 | |||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | static int dme1737_detect(struct i2c_adapter *adapter, int address, | ||
1876 | int kind) | ||
1877 | { | ||
1878 | u8 company, verstep = 0; | ||
1879 | struct i2c_client *client; | ||
1880 | struct dme1737_data *data; | ||
1881 | int ix, err = 0; | ||
1882 | const char *name; | ||
1883 | |||
1884 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
1885 | goto exit; | ||
1886 | } | ||
1887 | |||
1888 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | ||
1889 | err = -ENOMEM; | ||
1890 | goto exit; | ||
1891 | } | ||
1892 | |||
1893 | client = &data->client; | ||
1894 | i2c_set_clientdata(client, data); | ||
1895 | client->addr = address; | ||
1896 | client->adapter = adapter; | ||
1897 | client->driver = &dme1737_driver; | ||
1898 | |||
1899 | /* A negative kind means that the driver was loaded with no force | ||
1900 | * parameter (default), so we must identify the chip. */ | ||
1901 | if (kind < 0) { | ||
1902 | company = dme1737_read(client, DME1737_REG_COMPANY); | ||
1903 | verstep = dme1737_read(client, DME1737_REG_VERSTEP); | ||
1904 | |||
1905 | if (!((company == DME1737_COMPANY_SMSC) && | ||
1906 | ((verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP))) { | ||
1907 | err = -ENODEV; | ||
1908 | goto exit_kfree; | ||
1909 | } | ||
1910 | } | ||
1911 | |||
1912 | kind = dme1737; | ||
1913 | name = "dme1737"; | ||
1914 | |||
1915 | /* Fill in the remaining client fields and put it into the global | ||
1916 | * list */ | ||
1917 | strlcpy(client->name, name, I2C_NAME_SIZE); | ||
1918 | mutex_init(&data->update_lock); | ||
1919 | |||
1920 | /* Tell the I2C layer a new client has arrived */ | ||
1921 | if ((err = i2c_attach_client(client))) { | ||
1922 | goto exit_kfree; | ||
1923 | } | ||
1924 | |||
1925 | /* Initialize the DME1737 chip */ | ||
1926 | if ((err = dme1737_init_client(client))) { | ||
1927 | goto exit_detach; | ||
1928 | } | ||
1929 | |||
1930 | /* Create standard sysfs attributes */ | ||
1931 | if ((err = sysfs_create_group(&client->dev.kobj, &dme1737_group))) { | ||
1932 | goto exit_detach; | ||
1933 | } | ||
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 | } | ||
1984 | |||
1985 | /* Register device */ | ||
1986 | data->class_dev = hwmon_device_register(&client->dev); | ||
1987 | if (IS_ERR(data->class_dev)) { | ||
1988 | err = PTR_ERR(data->class_dev); | ||
1989 | goto exit_remove; | ||
1990 | } | ||
1991 | |||
1992 | dev_info(&adapter->dev, "Found a DME1737 chip at 0x%02x " | ||
1993 | "(rev 0x%02x)\n", client->addr, verstep); | ||
1994 | |||
1995 | return 0; | ||
1996 | |||
1997 | exit_remove: | ||
1998 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
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: | ||
2012 | i2c_detach_client(client); | ||
2013 | exit_kfree: | ||
2014 | kfree(data); | ||
2015 | exit: | ||
2016 | return err; | ||
2017 | } | ||
2018 | |||
2019 | static int dme1737_attach_adapter(struct i2c_adapter *adapter) | ||
2020 | { | ||
2021 | if (!(adapter->class & I2C_CLASS_HWMON)) { | ||
2022 | return 0; | ||
2023 | } | ||
2024 | |||
2025 | return i2c_probe(adapter, &addr_data, dme1737_detect); | ||
2026 | } | ||
2027 | |||
2028 | static int dme1737_detach_client(struct i2c_client *client) | ||
2029 | { | ||
2030 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
2031 | int ix, err; | ||
2032 | |||
2033 | hwmon_device_unregister(data->class_dev); | ||
2034 | |||
2035 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
2036 | if (data->has_fan & (1 << ix)) { | ||
2037 | sysfs_remove_group(&client->dev.kobj, | ||
2038 | &dme1737_fan_group[ix]); | ||
2039 | } | ||
2040 | } | ||
2041 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
2042 | if (data->has_pwm & (1 << ix)) { | ||
2043 | sysfs_remove_group(&client->dev.kobj, | ||
2044 | &dme1737_pwm_group[ix]); | ||
2045 | } | ||
2046 | } | ||
2047 | sysfs_remove_group(&client->dev.kobj, &dme1737_group); | ||
2048 | |||
2049 | if ((err = i2c_detach_client(client))) { | ||
2050 | return err; | ||
2051 | } | ||
2052 | |||
2053 | kfree(data); | ||
2054 | return 0; | ||
2055 | } | ||
2056 | |||
2057 | static struct i2c_driver dme1737_driver = { | ||
2058 | .driver = { | ||
2059 | .name = "dme1737", | ||
2060 | }, | ||
2061 | .attach_adapter = dme1737_attach_adapter, | ||
2062 | .detach_client = dme1737_detach_client, | ||
2063 | }; | ||
2064 | |||
2065 | static int __init dme1737_init(void) | ||
2066 | { | ||
2067 | return i2c_add_driver(&dme1737_driver); | ||
2068 | } | ||
2069 | |||
2070 | static void __exit dme1737_exit(void) | ||
2071 | { | ||
2072 | i2c_del_driver(&dme1737_driver); | ||
2073 | } | ||
2074 | |||
2075 | MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>"); | ||
2076 | MODULE_DESCRIPTION("DME1737 sensors"); | ||
2077 | MODULE_LICENSE("GPL"); | ||
2078 | |||
2079 | module_init(dme1737_init); | ||
2080 | module_exit(dme1737_exit); | ||
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index d5ac422d73b2..1212d6b7f316 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/hwmon.h> | 29 | #include <linux/hwmon.h> |
30 | #include <linux/hwmon-sysfs.h> | ||
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
32 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
@@ -52,9 +53,11 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") | |||
52 | #define DS1621_REG_CONFIG_DONE 0x80 | 53 | #define DS1621_REG_CONFIG_DONE 0x80 |
53 | 54 | ||
54 | /* The DS1621 registers */ | 55 | /* The DS1621 registers */ |
55 | #define DS1621_REG_TEMP 0xAA /* word, RO */ | 56 | static const u8 DS1621_REG_TEMP[3] = { |
56 | #define DS1621_REG_TEMP_MIN 0xA2 /* word, RW */ | 57 | 0xAA, /* input, word, RO */ |
57 | #define DS1621_REG_TEMP_MAX 0xA1 /* word, RW */ | 58 | 0xA2, /* min, word, RW */ |
59 | 0xA1, /* max, word, RW */ | ||
60 | }; | ||
58 | #define DS1621_REG_CONF 0xAC /* byte, RW */ | 61 | #define DS1621_REG_CONF 0xAC /* byte, RW */ |
59 | #define DS1621_COM_START 0xEE /* no data */ | 62 | #define DS1621_COM_START 0xEE /* no data */ |
60 | #define DS1621_COM_STOP 0x22 /* no data */ | 63 | #define DS1621_COM_STOP 0x22 /* no data */ |
@@ -63,10 +66,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") | |||
63 | #define DS1621_ALARM_TEMP_HIGH 0x40 | 66 | #define DS1621_ALARM_TEMP_HIGH 0x40 |
64 | #define DS1621_ALARM_TEMP_LOW 0x20 | 67 | #define DS1621_ALARM_TEMP_LOW 0x20 |
65 | 68 | ||
66 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 69 | /* Conversions */ |
67 | variants. Note that you should be a bit careful with which arguments | ||
68 | these macros are called: arguments may be evaluated more than once. | ||
69 | Fixing this is just not worth it. */ | ||
70 | #define ALARMS_FROM_REG(val) ((val) & \ | 70 | #define ALARMS_FROM_REG(val) ((val) & \ |
71 | (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) | 71 | (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) |
72 | 72 | ||
@@ -78,7 +78,7 @@ struct ds1621_data { | |||
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 */ |
80 | 80 | ||
81 | u16 temp, temp_min, temp_max; /* Register values, word */ | 81 | u16 temp[3]; /* Register values, word */ |
82 | u8 conf; /* Register encoding, combined */ | 82 | u8 conf; /* Register encoding, combined */ |
83 | }; | 83 | }; |
84 | 84 | ||
@@ -101,7 +101,7 @@ static struct i2c_driver ds1621_driver = { | |||
101 | 101 | ||
102 | /* All registers are word-sized, except for the configuration register. | 102 | /* All registers are word-sized, except for the configuration register. |
103 | DS1621 uses a high-byte first convention, which is exactly opposite to | 103 | DS1621 uses a high-byte first convention, which is exactly opposite to |
104 | the usual practice. */ | 104 | the SMBus standard. */ |
105 | static int ds1621_read_value(struct i2c_client *client, u8 reg) | 105 | static int ds1621_read_value(struct i2c_client *client, u8 reg) |
106 | { | 106 | { |
107 | if (reg == DS1621_REG_CONF) | 107 | if (reg == DS1621_REG_CONF) |
@@ -110,9 +110,6 @@ static int ds1621_read_value(struct i2c_client *client, u8 reg) | |||
110 | return swab16(i2c_smbus_read_word_data(client, reg)); | 110 | return swab16(i2c_smbus_read_word_data(client, reg)); |
111 | } | 111 | } |
112 | 112 | ||
113 | /* All registers are word-sized, except for the configuration register. | ||
114 | DS1621 uses a high-byte first convention, which is exactly opposite to | ||
115 | the usual practice. */ | ||
116 | static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) | 113 | static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) |
117 | { | 114 | { |
118 | if (reg == DS1621_REG_CONF) | 115 | if (reg == DS1621_REG_CONF) |
@@ -139,50 +136,61 @@ static void ds1621_init_client(struct i2c_client *client) | |||
139 | i2c_smbus_write_byte(client, DS1621_COM_START); | 136 | i2c_smbus_write_byte(client, DS1621_COM_START); |
140 | } | 137 | } |
141 | 138 | ||
142 | #define show(value) \ | 139 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
143 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 140 | char *buf) |
144 | { \ | 141 | { |
145 | struct ds1621_data *data = ds1621_update_client(dev); \ | 142 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
146 | return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \ | 143 | struct ds1621_data *data = ds1621_update_client(dev); |
144 | return sprintf(buf, "%d\n", | ||
145 | LM75_TEMP_FROM_REG(data->temp[attr->index])); | ||
147 | } | 146 | } |
148 | 147 | ||
149 | show(temp); | 148 | static ssize_t set_temp(struct device *dev, struct device_attribute *da, |
150 | show(temp_min); | 149 | const char *buf, size_t count) |
151 | show(temp_max); | 150 | { |
152 | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | |
153 | #define set_temp(suffix, value, reg) \ | 152 | struct i2c_client *client = to_i2c_client(dev); |
154 | static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ | 153 | struct ds1621_data *data = ds1621_update_client(dev); |
155 | size_t count) \ | 154 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); |
156 | { \ | ||
157 | struct i2c_client *client = to_i2c_client(dev); \ | ||
158 | struct ds1621_data *data = ds1621_update_client(dev); \ | ||
159 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \ | ||
160 | \ | ||
161 | mutex_lock(&data->update_lock); \ | ||
162 | data->value = val; \ | ||
163 | ds1621_write_value(client, reg, data->value); \ | ||
164 | mutex_unlock(&data->update_lock); \ | ||
165 | return count; \ | ||
166 | } | ||
167 | 155 | ||
168 | set_temp(min, temp_min, DS1621_REG_TEMP_MIN); | 156 | mutex_lock(&data->update_lock); |
169 | set_temp(max, temp_max, DS1621_REG_TEMP_MAX); | 157 | data->temp[attr->index] = val; |
158 | ds1621_write_value(client, DS1621_REG_TEMP[attr->index], | ||
159 | data->temp[attr->index]); | ||
160 | mutex_unlock(&data->update_lock); | ||
161 | return count; | ||
162 | } | ||
170 | 163 | ||
171 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 164 | static ssize_t show_alarms(struct device *dev, struct device_attribute *da, |
165 | char *buf) | ||
172 | { | 166 | { |
173 | struct ds1621_data *data = ds1621_update_client(dev); | 167 | struct ds1621_data *data = ds1621_update_client(dev); |
174 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf)); | 168 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf)); |
175 | } | 169 | } |
176 | 170 | ||
171 | static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | ||
172 | char *buf) | ||
173 | { | ||
174 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
175 | struct ds1621_data *data = ds1621_update_client(dev); | ||
176 | return sprintf(buf, "%d\n", !!(data->conf & attr->index)); | ||
177 | } | ||
178 | |||
177 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 179 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
178 | static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL); | 180 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); |
179 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min); | 181 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, 1); |
180 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); | 182 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, 2); |
183 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, | ||
184 | DS1621_ALARM_TEMP_LOW); | ||
185 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
186 | DS1621_ALARM_TEMP_HIGH); | ||
181 | 187 | ||
182 | static struct attribute *ds1621_attributes[] = { | 188 | static struct attribute *ds1621_attributes[] = { |
183 | &dev_attr_temp1_input.attr, | 189 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
184 | &dev_attr_temp1_min.attr, | 190 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
185 | &dev_attr_temp1_max.attr, | 191 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
192 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
193 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
186 | &dev_attr_alarms.attr, | 194 | &dev_attr_alarms.attr, |
187 | NULL | 195 | NULL |
188 | }; | 196 | }; |
@@ -204,9 +212,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
204 | int kind) | 212 | int kind) |
205 | { | 213 | { |
206 | int conf, temp; | 214 | int conf, temp; |
207 | struct i2c_client *new_client; | 215 | struct i2c_client *client; |
208 | struct ds1621_data *data; | 216 | struct ds1621_data *data; |
209 | int err = 0; | 217 | int i, err = 0; |
210 | 218 | ||
211 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 219 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
212 | | I2C_FUNC_SMBUS_WORD_DATA | 220 | | I2C_FUNC_SMBUS_WORD_DATA |
@@ -221,55 +229,44 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
221 | goto exit; | 229 | goto exit; |
222 | } | 230 | } |
223 | 231 | ||
224 | new_client = &data->client; | 232 | client = &data->client; |
225 | i2c_set_clientdata(new_client, data); | 233 | i2c_set_clientdata(client, data); |
226 | new_client->addr = address; | 234 | client->addr = address; |
227 | new_client->adapter = adapter; | 235 | client->adapter = adapter; |
228 | new_client->driver = &ds1621_driver; | 236 | client->driver = &ds1621_driver; |
229 | new_client->flags = 0; | ||
230 | |||
231 | 237 | ||
232 | /* Now, we do the remaining detection. It is lousy. */ | 238 | /* Now, we do the remaining detection. It is lousy. */ |
233 | if (kind < 0) { | 239 | if (kind < 0) { |
234 | /* The NVB bit should be low if no EEPROM write has been | 240 | /* The NVB bit should be low if no EEPROM write has been |
235 | requested during the latest 10ms, which is highly | 241 | requested during the latest 10ms, which is highly |
236 | improbable in our case. */ | 242 | improbable in our case. */ |
237 | conf = ds1621_read_value(new_client, DS1621_REG_CONF); | 243 | conf = ds1621_read_value(client, DS1621_REG_CONF); |
238 | if (conf & DS1621_REG_CONFIG_NVB) | 244 | if (conf & DS1621_REG_CONFIG_NVB) |
239 | goto exit_free; | 245 | goto exit_free; |
240 | /* The 7 lowest bits of a temperature should always be 0. */ | 246 | /* The 7 lowest bits of a temperature should always be 0. */ |
241 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP); | 247 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
242 | if (temp & 0x007f) | 248 | temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); |
243 | goto exit_free; | 249 | if (temp & 0x007f) |
244 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MIN); | 250 | goto exit_free; |
245 | if (temp & 0x007f) | 251 | } |
246 | goto exit_free; | ||
247 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MAX); | ||
248 | if (temp & 0x007f) | ||
249 | goto exit_free; | ||
250 | } | 252 | } |
251 | 253 | ||
252 | /* Determine the chip type - only one kind supported! */ | ||
253 | if (kind <= 0) | ||
254 | kind = ds1621; | ||
255 | |||
256 | /* Fill in remaining client fields and put it into the global list */ | 254 | /* Fill in remaining client fields and put it into the global list */ |
257 | strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE); | 255 | strlcpy(client->name, "ds1621", I2C_NAME_SIZE); |
258 | data->valid = 0; | ||
259 | mutex_init(&data->update_lock); | 256 | mutex_init(&data->update_lock); |
260 | 257 | ||
261 | /* Tell the I2C layer a new client has arrived */ | 258 | /* Tell the I2C layer a new client has arrived */ |
262 | if ((err = i2c_attach_client(new_client))) | 259 | if ((err = i2c_attach_client(client))) |
263 | goto exit_free; | 260 | goto exit_free; |
264 | 261 | ||
265 | /* Initialize the DS1621 chip */ | 262 | /* Initialize the DS1621 chip */ |
266 | ds1621_init_client(new_client); | 263 | ds1621_init_client(client); |
267 | 264 | ||
268 | /* Register sysfs hooks */ | 265 | /* Register sysfs hooks */ |
269 | if ((err = sysfs_create_group(&new_client->dev.kobj, &ds1621_group))) | 266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) |
270 | goto exit_detach; | 267 | goto exit_detach; |
271 | 268 | ||
272 | data->class_dev = hwmon_device_register(&new_client->dev); | 269 | data->class_dev = hwmon_device_register(&client->dev); |
273 | if (IS_ERR(data->class_dev)) { | 270 | if (IS_ERR(data->class_dev)) { |
274 | err = PTR_ERR(data->class_dev); | 271 | err = PTR_ERR(data->class_dev); |
275 | goto exit_remove_files; | 272 | goto exit_remove_files; |
@@ -278,9 +275,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
278 | return 0; | 275 | return 0; |
279 | 276 | ||
280 | exit_remove_files: | 277 | exit_remove_files: |
281 | sysfs_remove_group(&new_client->dev.kobj, &ds1621_group); | 278 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); |
282 | exit_detach: | 279 | exit_detach: |
283 | i2c_detach_client(new_client); | 280 | i2c_detach_client(client); |
284 | exit_free: | 281 | exit_free: |
285 | kfree(data); | 282 | kfree(data); |
286 | exit: | 283 | exit: |
@@ -314,23 +311,21 @@ static struct ds1621_data *ds1621_update_client(struct device *dev) | |||
314 | 311 | ||
315 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 312 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
316 | || !data->valid) { | 313 | || !data->valid) { |
314 | int i; | ||
317 | 315 | ||
318 | dev_dbg(&client->dev, "Starting ds1621 update\n"); | 316 | dev_dbg(&client->dev, "Starting ds1621 update\n"); |
319 | 317 | ||
320 | data->conf = ds1621_read_value(client, DS1621_REG_CONF); | 318 | data->conf = ds1621_read_value(client, DS1621_REG_CONF); |
321 | 319 | ||
322 | data->temp = ds1621_read_value(client, DS1621_REG_TEMP); | 320 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) |
323 | 321 | data->temp[i] = ds1621_read_value(client, | |
324 | data->temp_min = ds1621_read_value(client, | 322 | DS1621_REG_TEMP[i]); |
325 | DS1621_REG_TEMP_MIN); | ||
326 | data->temp_max = ds1621_read_value(client, | ||
327 | DS1621_REG_TEMP_MAX); | ||
328 | 323 | ||
329 | /* reset alarms if necessary */ | 324 | /* reset alarms if necessary */ |
330 | new_conf = data->conf; | 325 | new_conf = data->conf; |
331 | if (data->temp > data->temp_min) | 326 | if (data->temp[0] > data->temp[1]) /* input > min */ |
332 | new_conf &= ~DS1621_ALARM_TEMP_LOW; | 327 | new_conf &= ~DS1621_ALARM_TEMP_LOW; |
333 | if (data->temp < data->temp_max) | 328 | if (data->temp[0] < data->temp[2]) /* input < max */ |
334 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; | 329 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; |
335 | if (data->conf != new_conf) | 330 | if (data->conf != new_conf) |
336 | ds1621_write_value(client, DS1621_REG_CONF, | 331 | ds1621_write_value(client, DS1621_REG_CONF, |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index cdbe309b8fc4..6f60715f34f8 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -127,6 +127,13 @@ superio_exit(int base) | |||
127 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) | 127 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) |
128 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) | 128 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) |
129 | #define F71805F_REG_TEMP_MODE 0x01 | 129 | #define F71805F_REG_TEMP_MODE 0x01 |
130 | /* pwm/fan pwmnr from 0 to 2, auto point apnr from 0 to 2 */ | ||
131 | /* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */ | ||
132 | #define F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr) \ | ||
133 | (0xA0 + 0x10 * (pwmnr) + (2 - (apnr))) | ||
134 | #define F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr) \ | ||
135 | (0xA4 + 0x10 * (pwmnr) + \ | ||
136 | 2 * (2 - (apnr))) | ||
130 | 137 | ||
131 | #define F71805F_REG_START 0x00 | 138 | #define F71805F_REG_START 0x00 |
132 | /* status nr from 0 to 2 */ | 139 | /* status nr from 0 to 2 */ |
@@ -144,6 +151,11 @@ superio_exit(int base) | |||
144 | * Data structures and manipulation thereof | 151 | * Data structures and manipulation thereof |
145 | */ | 152 | */ |
146 | 153 | ||
154 | struct f71805f_auto_point { | ||
155 | u8 temp[3]; | ||
156 | u16 fan[3]; | ||
157 | }; | ||
158 | |||
147 | struct f71805f_data { | 159 | struct f71805f_data { |
148 | unsigned short addr; | 160 | unsigned short addr; |
149 | const char *name; | 161 | const char *name; |
@@ -170,6 +182,7 @@ struct f71805f_data { | |||
170 | u8 temp_hyst[3]; | 182 | u8 temp_hyst[3]; |
171 | u8 temp_mode; | 183 | u8 temp_mode; |
172 | unsigned long alarms; | 184 | unsigned long alarms; |
185 | struct f71805f_auto_point auto_points[3]; | ||
173 | }; | 186 | }; |
174 | 187 | ||
175 | struct f71805f_sio_data { | 188 | struct f71805f_sio_data { |
@@ -312,7 +325,7 @@ static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | |||
312 | static struct f71805f_data *f71805f_update_device(struct device *dev) | 325 | static struct f71805f_data *f71805f_update_device(struct device *dev) |
313 | { | 326 | { |
314 | struct f71805f_data *data = dev_get_drvdata(dev); | 327 | struct f71805f_data *data = dev_get_drvdata(dev); |
315 | int nr; | 328 | int nr, apnr; |
316 | 329 | ||
317 | mutex_lock(&data->update_lock); | 330 | mutex_lock(&data->update_lock); |
318 | 331 | ||
@@ -342,6 +355,18 @@ static struct f71805f_data *f71805f_update_device(struct device *dev) | |||
342 | F71805F_REG_TEMP_HYST(nr)); | 355 | F71805F_REG_TEMP_HYST(nr)); |
343 | } | 356 | } |
344 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); | 357 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); |
358 | for (nr = 0; nr < 3; nr++) { | ||
359 | for (apnr = 0; apnr < 3; apnr++) { | ||
360 | data->auto_points[nr].temp[apnr] = | ||
361 | f71805f_read8(data, | ||
362 | F71805F_REG_PWM_AUTO_POINT_TEMP(nr, | ||
363 | apnr)); | ||
364 | data->auto_points[nr].fan[apnr] = | ||
365 | f71805f_read16(data, | ||
366 | F71805F_REG_PWM_AUTO_POINT_FAN(nr, | ||
367 | apnr)); | ||
368 | } | ||
369 | } | ||
345 | 370 | ||
346 | data->last_limits = jiffies; | 371 | data->last_limits = jiffies; |
347 | } | 372 | } |
@@ -705,6 +730,70 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute | |||
705 | return count; | 730 | return count; |
706 | } | 731 | } |
707 | 732 | ||
733 | static ssize_t show_pwm_auto_point_temp(struct device *dev, | ||
734 | struct device_attribute *devattr, | ||
735 | char* buf) | ||
736 | { | ||
737 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
738 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
739 | int pwmnr = attr->nr; | ||
740 | int apnr = attr->index; | ||
741 | |||
742 | return sprintf(buf, "%ld\n", | ||
743 | temp_from_reg(data->auto_points[pwmnr].temp[apnr])); | ||
744 | } | ||
745 | |||
746 | static ssize_t set_pwm_auto_point_temp(struct device *dev, | ||
747 | struct device_attribute *devattr, | ||
748 | const char* buf, size_t count) | ||
749 | { | ||
750 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
751 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
752 | int pwmnr = attr->nr; | ||
753 | int apnr = attr->index; | ||
754 | unsigned long val = simple_strtol(buf, NULL, 10); | ||
755 | |||
756 | mutex_lock(&data->update_lock); | ||
757 | data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val); | ||
758 | f71805f_write8(data, F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr), | ||
759 | data->auto_points[pwmnr].temp[apnr]); | ||
760 | mutex_unlock(&data->update_lock); | ||
761 | |||
762 | return count; | ||
763 | } | ||
764 | |||
765 | static ssize_t show_pwm_auto_point_fan(struct device *dev, | ||
766 | struct device_attribute *devattr, | ||
767 | char* buf) | ||
768 | { | ||
769 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
770 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
771 | int pwmnr = attr->nr; | ||
772 | int apnr = attr->index; | ||
773 | |||
774 | return sprintf(buf, "%ld\n", | ||
775 | fan_from_reg(data->auto_points[pwmnr].fan[apnr])); | ||
776 | } | ||
777 | |||
778 | static ssize_t set_pwm_auto_point_fan(struct device *dev, | ||
779 | struct device_attribute *devattr, | ||
780 | const char* buf, size_t count) | ||
781 | { | ||
782 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
783 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
784 | int pwmnr = attr->nr; | ||
785 | int apnr = attr->index; | ||
786 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
787 | |||
788 | mutex_lock(&data->update_lock); | ||
789 | data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val); | ||
790 | f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr), | ||
791 | data->auto_points[pwmnr].fan[apnr]); | ||
792 | mutex_unlock(&data->update_lock); | ||
793 | |||
794 | return count; | ||
795 | } | ||
796 | |||
708 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | 797 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
709 | char *buf) | 798 | char *buf) |
710 | { | 799 | { |
@@ -932,6 +1021,63 @@ static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR, | |||
932 | show_pwm_freq, set_pwm_freq, 2); | 1021 | show_pwm_freq, set_pwm_freq, 2); |
933 | static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); | 1022 | static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); |
934 | 1023 | ||
1024 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1025 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1026 | 0, 0); | ||
1027 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
1028 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1029 | 0, 0); | ||
1030 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1031 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1032 | 0, 1); | ||
1033 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
1034 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1035 | 0, 1); | ||
1036 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1037 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1038 | 0, 2); | ||
1039 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
1040 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1041 | 0, 2); | ||
1042 | |||
1043 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1044 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1045 | 1, 0); | ||
1046 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
1047 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1048 | 1, 0); | ||
1049 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1050 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1051 | 1, 1); | ||
1052 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
1053 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1054 | 1, 1); | ||
1055 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1056 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1057 | 1, 2); | ||
1058 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
1059 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1060 | 1, 2); | ||
1061 | |||
1062 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
1063 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1064 | 2, 0); | ||
1065 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
1066 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1067 | 2, 0); | ||
1068 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
1069 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1070 | 2, 1); | ||
1071 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
1072 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1073 | 2, 1); | ||
1074 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
1075 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
1076 | 2, 2); | ||
1077 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
1078 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
1079 | 2, 2); | ||
1080 | |||
935 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | 1081 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); |
936 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | 1082 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); |
937 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | 1083 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); |
@@ -1014,6 +1160,25 @@ static struct attribute *f71805f_attributes[] = { | |||
1014 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 1160 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
1015 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 1161 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
1016 | 1162 | ||
1163 | &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, | ||
1164 | &sensor_dev_attr_pwm1_auto_point1_fan.dev_attr.attr, | ||
1165 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | ||
1166 | &sensor_dev_attr_pwm1_auto_point2_fan.dev_attr.attr, | ||
1167 | &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, | ||
1168 | &sensor_dev_attr_pwm1_auto_point3_fan.dev_attr.attr, | ||
1169 | &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr, | ||
1170 | &sensor_dev_attr_pwm2_auto_point1_fan.dev_attr.attr, | ||
1171 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, | ||
1172 | &sensor_dev_attr_pwm2_auto_point2_fan.dev_attr.attr, | ||
1173 | &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr, | ||
1174 | &sensor_dev_attr_pwm2_auto_point3_fan.dev_attr.attr, | ||
1175 | &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr, | ||
1176 | &sensor_dev_attr_pwm3_auto_point1_fan.dev_attr.attr, | ||
1177 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, | ||
1178 | &sensor_dev_attr_pwm3_auto_point2_fan.dev_attr.attr, | ||
1179 | &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr, | ||
1180 | &sensor_dev_attr_pwm3_auto_point3_fan.dev_attr.attr, | ||
1181 | |||
1017 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | 1182 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
1018 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 1183 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
1019 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | 1184 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
@@ -1242,12 +1407,12 @@ static int __devexit f71805f_remove(struct platform_device *pdev) | |||
1242 | struct resource *res; | 1407 | struct resource *res; |
1243 | int i; | 1408 | int i; |
1244 | 1409 | ||
1245 | platform_set_drvdata(pdev, NULL); | ||
1246 | hwmon_device_unregister(data->class_dev); | 1410 | hwmon_device_unregister(data->class_dev); |
1247 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); | 1411 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); |
1248 | for (i = 0; i < 4; i++) | 1412 | for (i = 0; i < 4; i++) |
1249 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); | 1413 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); |
1250 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); | 1414 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); |
1415 | platform_set_drvdata(pdev, NULL); | ||
1251 | kfree(data); | 1416 | kfree(data); |
1252 | 1417 | ||
1253 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1418 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
@@ -1290,15 +1455,12 @@ static int __init f71805f_device_add(unsigned short address, | |||
1290 | goto exit_device_put; | 1455 | goto exit_device_put; |
1291 | } | 1456 | } |
1292 | 1457 | ||
1293 | pdev->dev.platform_data = kmalloc(sizeof(struct f71805f_sio_data), | 1458 | err = platform_device_add_data(pdev, sio_data, |
1294 | GFP_KERNEL); | 1459 | sizeof(struct f71805f_sio_data)); |
1295 | if (!pdev->dev.platform_data) { | 1460 | if (err) { |
1296 | err = -ENOMEM; | ||
1297 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 1461 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
1298 | goto exit_device_put; | 1462 | goto exit_device_put; |
1299 | } | 1463 | } |
1300 | memcpy(pdev->dev.platform_data, sio_data, | ||
1301 | sizeof(struct f71805f_sio_data)); | ||
1302 | 1464 | ||
1303 | err = platform_device_add(pdev); | 1465 | err = platform_device_add(pdev); |
1304 | if (err) { | 1466 | if (err) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 62afc63708a5..eff6036e15c0 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -6,6 +6,7 @@ | |||
6 | IT8712F Super I/O chip w/LPC interface | 6 | IT8712F Super I/O chip w/LPC interface |
7 | IT8716F Super I/O chip w/LPC interface | 7 | IT8716F Super I/O chip w/LPC interface |
8 | IT8718F Super I/O chip w/LPC interface | 8 | IT8718F Super I/O chip w/LPC interface |
9 | IT8726F Super I/O chip w/LPC interface | ||
9 | Sis950 A clone of the IT8705F | 10 | Sis950 A clone of the IT8705F |
10 | 11 | ||
11 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> | 12 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> |
@@ -30,8 +31,7 @@ | |||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/jiffies.h> | 33 | #include <linux/jiffies.h> |
33 | #include <linux/i2c.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/i2c-isa.h> | ||
35 | #include <linux/hwmon.h> | 35 | #include <linux/hwmon.h> |
36 | #include <linux/hwmon-sysfs.h> | 36 | #include <linux/hwmon-sysfs.h> |
37 | #include <linux/hwmon-vid.h> | 37 | #include <linux/hwmon-vid.h> |
@@ -40,10 +40,12 @@ | |||
40 | #include <linux/sysfs.h> | 40 | #include <linux/sysfs.h> |
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | 42 | ||
43 | #define DRVNAME "it87" | ||
43 | 44 | ||
44 | static unsigned short isa_address; | ||
45 | enum chips { it87, it8712, it8716, it8718 }; | 45 | enum chips { it87, it8712, it8716, it8718 }; |
46 | 46 | ||
47 | static struct platform_device *pdev; | ||
48 | |||
47 | #define REG 0x2e /* The register to read/write */ | 49 | #define REG 0x2e /* The register to read/write */ |
48 | #define DEV 0x07 /* Register: Logical device select */ | 50 | #define DEV 0x07 /* Register: Logical device select */ |
49 | #define VAL 0x2f /* The value to read/write */ | 51 | #define VAL 0x2f /* The value to read/write */ |
@@ -97,6 +99,7 @@ superio_exit(void) | |||
97 | #define IT8705F_DEVID 0x8705 | 99 | #define IT8705F_DEVID 0x8705 |
98 | #define IT8716F_DEVID 0x8716 | 100 | #define IT8716F_DEVID 0x8716 |
99 | #define IT8718F_DEVID 0x8718 | 101 | #define IT8718F_DEVID 0x8718 |
102 | #define IT8726F_DEVID 0x8726 | ||
100 | #define IT87_ACT_REG 0x30 | 103 | #define IT87_ACT_REG 0x30 |
101 | #define IT87_BASE_REG 0x60 | 104 | #define IT87_BASE_REG 0x60 |
102 | 105 | ||
@@ -110,10 +113,6 @@ static int update_vbat; | |||
110 | /* Not all BIOSes properly configure the PWM registers */ | 113 | /* Not all BIOSes properly configure the PWM registers */ |
111 | static int fix_pwm_polarity; | 114 | static int fix_pwm_polarity; |
112 | 115 | ||
113 | /* Values read from Super-I/O config space */ | ||
114 | static u16 chip_type; | ||
115 | static u8 vid_value; | ||
116 | |||
117 | /* Many IT87 constants specified below */ | 116 | /* Many IT87 constants specified below */ |
118 | 117 | ||
119 | /* Length of ISA address segment */ | 118 | /* Length of ISA address segment */ |
@@ -214,13 +213,20 @@ static const unsigned int pwm_freq[8] = { | |||
214 | }; | 213 | }; |
215 | 214 | ||
216 | 215 | ||
216 | struct it87_sio_data { | ||
217 | enum chips type; | ||
218 | /* Values read from Super-I/O config space */ | ||
219 | u8 vid_value; | ||
220 | }; | ||
221 | |||
217 | /* 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. |
218 | The structure is dynamically allocated. */ | 223 | The structure is dynamically allocated. */ |
219 | struct it87_data { | 224 | struct it87_data { |
220 | struct i2c_client client; | ||
221 | struct class_device *class_dev; | 225 | struct class_device *class_dev; |
222 | enum chips type; | 226 | enum chips type; |
223 | 227 | ||
228 | unsigned short addr; | ||
229 | const char *name; | ||
224 | struct mutex update_lock; | 230 | struct mutex update_lock; |
225 | char valid; /* !=0 if following fields are valid */ | 231 | char valid; /* !=0 if following fields are valid */ |
226 | unsigned long last_updated; /* In jiffies */ | 232 | unsigned long last_updated; /* In jiffies */ |
@@ -245,26 +251,25 @@ struct it87_data { | |||
245 | }; | 251 | }; |
246 | 252 | ||
247 | 253 | ||
248 | static int it87_detect(struct i2c_adapter *adapter); | 254 | static int it87_probe(struct platform_device *pdev); |
249 | static int it87_detach_client(struct i2c_client *client); | 255 | static int it87_remove(struct platform_device *pdev); |
250 | 256 | ||
251 | static int it87_read_value(struct i2c_client *client, u8 reg); | 257 | static int it87_read_value(struct it87_data *data, u8 reg); |
252 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value); | 258 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value); |
253 | static struct it87_data *it87_update_device(struct device *dev); | 259 | static struct it87_data *it87_update_device(struct device *dev); |
254 | static int it87_check_pwm(struct i2c_client *client); | 260 | static int it87_check_pwm(struct device *dev); |
255 | static void it87_init_client(struct i2c_client *client, struct it87_data *data); | 261 | static void it87_init_device(struct platform_device *pdev); |
256 | 262 | ||
257 | 263 | ||
258 | static struct i2c_driver it87_isa_driver = { | 264 | static struct platform_driver it87_driver = { |
259 | .driver = { | 265 | .driver = { |
260 | .owner = THIS_MODULE, | 266 | .owner = THIS_MODULE, |
261 | .name = "it87-isa", | 267 | .name = DRVNAME, |
262 | }, | 268 | }, |
263 | .attach_adapter = it87_detect, | 269 | .probe = it87_probe, |
264 | .detach_client = it87_detach_client, | 270 | .remove = __devexit_p(it87_remove), |
265 | }; | 271 | }; |
266 | 272 | ||
267 | |||
268 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 273 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
269 | char *buf) | 274 | char *buf) |
270 | { | 275 | { |
@@ -301,13 +306,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
301 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 306 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
302 | int nr = sensor_attr->index; | 307 | int nr = sensor_attr->index; |
303 | 308 | ||
304 | struct i2c_client *client = to_i2c_client(dev); | 309 | struct it87_data *data = dev_get_drvdata(dev); |
305 | struct it87_data *data = i2c_get_clientdata(client); | ||
306 | unsigned long val = simple_strtoul(buf, NULL, 10); | 310 | unsigned long val = simple_strtoul(buf, NULL, 10); |
307 | 311 | ||
308 | mutex_lock(&data->update_lock); | 312 | mutex_lock(&data->update_lock); |
309 | data->in_min[nr] = IN_TO_REG(val); | 313 | data->in_min[nr] = IN_TO_REG(val); |
310 | it87_write_value(client, IT87_REG_VIN_MIN(nr), | 314 | it87_write_value(data, IT87_REG_VIN_MIN(nr), |
311 | data->in_min[nr]); | 315 | data->in_min[nr]); |
312 | mutex_unlock(&data->update_lock); | 316 | mutex_unlock(&data->update_lock); |
313 | return count; | 317 | return count; |
@@ -318,13 +322,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
318 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 322 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
319 | int nr = sensor_attr->index; | 323 | int nr = sensor_attr->index; |
320 | 324 | ||
321 | struct i2c_client *client = to_i2c_client(dev); | 325 | struct it87_data *data = dev_get_drvdata(dev); |
322 | struct it87_data *data = i2c_get_clientdata(client); | ||
323 | unsigned long val = simple_strtoul(buf, NULL, 10); | 326 | unsigned long val = simple_strtoul(buf, NULL, 10); |
324 | 327 | ||
325 | mutex_lock(&data->update_lock); | 328 | mutex_lock(&data->update_lock); |
326 | data->in_max[nr] = IN_TO_REG(val); | 329 | data->in_max[nr] = IN_TO_REG(val); |
327 | it87_write_value(client, IT87_REG_VIN_MAX(nr), | 330 | it87_write_value(data, IT87_REG_VIN_MAX(nr), |
328 | data->in_max[nr]); | 331 | data->in_max[nr]); |
329 | mutex_unlock(&data->update_lock); | 332 | mutex_unlock(&data->update_lock); |
330 | return count; | 333 | return count; |
@@ -392,13 +395,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
392 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 395 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
393 | int nr = sensor_attr->index; | 396 | int nr = sensor_attr->index; |
394 | 397 | ||
395 | struct i2c_client *client = to_i2c_client(dev); | 398 | struct it87_data *data = dev_get_drvdata(dev); |
396 | struct it87_data *data = i2c_get_clientdata(client); | ||
397 | int val = simple_strtol(buf, NULL, 10); | 399 | int val = simple_strtol(buf, NULL, 10); |
398 | 400 | ||
399 | mutex_lock(&data->update_lock); | 401 | mutex_lock(&data->update_lock); |
400 | data->temp_high[nr] = TEMP_TO_REG(val); | 402 | data->temp_high[nr] = TEMP_TO_REG(val); |
401 | it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); | 403 | it87_write_value(data, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); |
402 | mutex_unlock(&data->update_lock); | 404 | mutex_unlock(&data->update_lock); |
403 | return count; | 405 | return count; |
404 | } | 406 | } |
@@ -408,13 +410,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
408 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 410 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
409 | int nr = sensor_attr->index; | 411 | int nr = sensor_attr->index; |
410 | 412 | ||
411 | struct i2c_client *client = to_i2c_client(dev); | 413 | struct it87_data *data = dev_get_drvdata(dev); |
412 | struct it87_data *data = i2c_get_clientdata(client); | ||
413 | int val = simple_strtol(buf, NULL, 10); | 414 | int val = simple_strtol(buf, NULL, 10); |
414 | 415 | ||
415 | mutex_lock(&data->update_lock); | 416 | mutex_lock(&data->update_lock); |
416 | data->temp_low[nr] = TEMP_TO_REG(val); | 417 | data->temp_low[nr] = TEMP_TO_REG(val); |
417 | it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); | 418 | it87_write_value(data, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); |
418 | mutex_unlock(&data->update_lock); | 419 | mutex_unlock(&data->update_lock); |
419 | return count; | 420 | return count; |
420 | } | 421 | } |
@@ -451,8 +452,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
451 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 452 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
452 | int nr = sensor_attr->index; | 453 | int nr = sensor_attr->index; |
453 | 454 | ||
454 | struct i2c_client *client = to_i2c_client(dev); | 455 | struct it87_data *data = dev_get_drvdata(dev); |
455 | struct it87_data *data = i2c_get_clientdata(client); | ||
456 | int val = simple_strtol(buf, NULL, 10); | 456 | int val = simple_strtol(buf, NULL, 10); |
457 | 457 | ||
458 | mutex_lock(&data->update_lock); | 458 | mutex_lock(&data->update_lock); |
@@ -468,7 +468,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
468 | mutex_unlock(&data->update_lock); | 468 | mutex_unlock(&data->update_lock); |
469 | return -EINVAL; | 469 | return -EINVAL; |
470 | } | 470 | } |
471 | it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor); | 471 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); |
472 | mutex_unlock(&data->update_lock); | 472 | mutex_unlock(&data->update_lock); |
473 | return count; | 473 | return count; |
474 | } | 474 | } |
@@ -542,13 +542,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
542 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 542 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
543 | int nr = sensor_attr->index; | 543 | int nr = sensor_attr->index; |
544 | 544 | ||
545 | struct i2c_client *client = to_i2c_client(dev); | 545 | struct it87_data *data = dev_get_drvdata(dev); |
546 | struct it87_data *data = i2c_get_clientdata(client); | ||
547 | int val = simple_strtol(buf, NULL, 10); | 546 | int val = simple_strtol(buf, NULL, 10); |
548 | u8 reg; | 547 | u8 reg; |
549 | 548 | ||
550 | mutex_lock(&data->update_lock); | 549 | mutex_lock(&data->update_lock); |
551 | reg = it87_read_value(client, IT87_REG_FAN_DIV); | 550 | reg = it87_read_value(data, IT87_REG_FAN_DIV); |
552 | switch (nr) { | 551 | switch (nr) { |
553 | case 0: data->fan_div[nr] = reg & 0x07; break; | 552 | case 0: data->fan_div[nr] = reg & 0x07; break; |
554 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; | 553 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; |
@@ -556,7 +555,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
556 | } | 555 | } |
557 | 556 | ||
558 | 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])); |
559 | it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 558 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); |
560 | mutex_unlock(&data->update_lock); | 559 | mutex_unlock(&data->update_lock); |
561 | return count; | 560 | return count; |
562 | } | 561 | } |
@@ -566,14 +565,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
566 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 565 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
567 | int nr = sensor_attr->index; | 566 | int nr = sensor_attr->index; |
568 | 567 | ||
569 | struct i2c_client *client = to_i2c_client(dev); | 568 | struct it87_data *data = dev_get_drvdata(dev); |
570 | struct it87_data *data = i2c_get_clientdata(client); | ||
571 | unsigned long val = simple_strtoul(buf, NULL, 10); | 569 | unsigned long val = simple_strtoul(buf, NULL, 10); |
572 | int min; | 570 | int min; |
573 | u8 old; | 571 | u8 old; |
574 | 572 | ||
575 | mutex_lock(&data->update_lock); | 573 | mutex_lock(&data->update_lock); |
576 | old = it87_read_value(client, IT87_REG_FAN_DIV); | 574 | old = it87_read_value(data, IT87_REG_FAN_DIV); |
577 | 575 | ||
578 | /* Save fan min limit */ | 576 | /* Save fan min limit */ |
579 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); | 577 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); |
@@ -594,11 +592,11 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
594 | val |= (data->fan_div[1] & 0x07) << 3; | 592 | val |= (data->fan_div[1] & 0x07) << 3; |
595 | if (data->fan_div[2] == 3) | 593 | if (data->fan_div[2] == 3) |
596 | val |= 0x1 << 6; | 594 | val |= 0x1 << 6; |
597 | it87_write_value(client, IT87_REG_FAN_DIV, val); | 595 | it87_write_value(data, IT87_REG_FAN_DIV, val); |
598 | 596 | ||
599 | /* Restore fan min limit */ | 597 | /* Restore fan min limit */ |
600 | 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])); |
601 | it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 599 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); |
602 | 600 | ||
603 | mutex_unlock(&data->update_lock); | 601 | mutex_unlock(&data->update_lock); |
604 | return count; | 602 | return count; |
@@ -609,8 +607,7 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
609 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 607 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
610 | int nr = sensor_attr->index; | 608 | int nr = sensor_attr->index; |
611 | 609 | ||
612 | struct i2c_client *client = to_i2c_client(dev); | 610 | struct it87_data *data = dev_get_drvdata(dev); |
613 | struct it87_data *data = i2c_get_clientdata(client); | ||
614 | int val = simple_strtol(buf, NULL, 10); | 611 | int val = simple_strtol(buf, NULL, 10); |
615 | 612 | ||
616 | mutex_lock(&data->update_lock); | 613 | mutex_lock(&data->update_lock); |
@@ -618,17 +615,17 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
618 | if (val == 0) { | 615 | if (val == 0) { |
619 | int tmp; | 616 | int tmp; |
620 | /* make sure the fan is on when in on/off mode */ | 617 | /* make sure the fan is on when in on/off mode */ |
621 | tmp = it87_read_value(client, IT87_REG_FAN_CTL); | 618 | tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
622 | it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr)); | 619 | it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr)); |
623 | /* set on/off mode */ | 620 | /* set on/off mode */ |
624 | data->fan_main_ctrl &= ~(1 << nr); | 621 | data->fan_main_ctrl &= ~(1 << nr); |
625 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 622 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
626 | } else if (val == 1) { | 623 | } else if (val == 1) { |
627 | /* set SmartGuardian mode */ | 624 | /* set SmartGuardian mode */ |
628 | data->fan_main_ctrl |= (1 << nr); | 625 | data->fan_main_ctrl |= (1 << nr); |
629 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 626 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
630 | /* set saved pwm value, clear FAN_CTLX PWM mode bit */ | 627 | /* set saved pwm value, clear FAN_CTLX PWM mode bit */ |
631 | it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); | 628 | it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); |
632 | } else { | 629 | } else { |
633 | mutex_unlock(&data->update_lock); | 630 | mutex_unlock(&data->update_lock); |
634 | return -EINVAL; | 631 | return -EINVAL; |
@@ -643,8 +640,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
643 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 640 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
644 | int nr = sensor_attr->index; | 641 | int nr = sensor_attr->index; |
645 | 642 | ||
646 | struct i2c_client *client = to_i2c_client(dev); | 643 | struct it87_data *data = dev_get_drvdata(dev); |
647 | struct it87_data *data = i2c_get_clientdata(client); | ||
648 | int val = simple_strtol(buf, NULL, 10); | 644 | int val = simple_strtol(buf, NULL, 10); |
649 | 645 | ||
650 | if (val < 0 || val > 255) | 646 | if (val < 0 || val > 255) |
@@ -653,15 +649,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
653 | mutex_lock(&data->update_lock); | 649 | mutex_lock(&data->update_lock); |
654 | data->manual_pwm_ctl[nr] = val; | 650 | data->manual_pwm_ctl[nr] = val; |
655 | if (data->fan_main_ctrl & (1 << nr)) | 651 | if (data->fan_main_ctrl & (1 << nr)) |
656 | it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); | 652 | it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); |
657 | mutex_unlock(&data->update_lock); | 653 | mutex_unlock(&data->update_lock); |
658 | return count; | 654 | return count; |
659 | } | 655 | } |
660 | static ssize_t set_pwm_freq(struct device *dev, | 656 | static ssize_t set_pwm_freq(struct device *dev, |
661 | struct device_attribute *attr, const char *buf, size_t count) | 657 | struct device_attribute *attr, const char *buf, size_t count) |
662 | { | 658 | { |
663 | struct i2c_client *client = to_i2c_client(dev); | 659 | struct it87_data *data = dev_get_drvdata(dev); |
664 | struct it87_data *data = i2c_get_clientdata(client); | ||
665 | unsigned long val = simple_strtoul(buf, NULL, 10); | 660 | unsigned long val = simple_strtoul(buf, NULL, 10); |
666 | int i; | 661 | int i; |
667 | 662 | ||
@@ -672,9 +667,9 @@ static ssize_t set_pwm_freq(struct device *dev, | |||
672 | } | 667 | } |
673 | 668 | ||
674 | mutex_lock(&data->update_lock); | 669 | mutex_lock(&data->update_lock); |
675 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL) & 0x8f; | 670 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f; |
676 | data->fan_ctl |= i << 4; | 671 | data->fan_ctl |= i << 4; |
677 | it87_write_value(client, IT87_REG_FAN_CTL, data->fan_ctl); | 672 | it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl); |
678 | mutex_unlock(&data->update_lock); | 673 | mutex_unlock(&data->update_lock); |
679 | 674 | ||
680 | return count; | 675 | return count; |
@@ -729,15 +724,14 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | |||
729 | { | 724 | { |
730 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 725 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
731 | int nr = sensor_attr->index; | 726 | int nr = sensor_attr->index; |
732 | struct i2c_client *client = to_i2c_client(dev); | 727 | struct it87_data *data = dev_get_drvdata(dev); |
733 | struct it87_data *data = i2c_get_clientdata(client); | ||
734 | int val = simple_strtol(buf, NULL, 10); | 728 | int val = simple_strtol(buf, NULL, 10); |
735 | 729 | ||
736 | mutex_lock(&data->update_lock); | 730 | mutex_lock(&data->update_lock); |
737 | data->fan_min[nr] = FAN16_TO_REG(val); | 731 | data->fan_min[nr] = FAN16_TO_REG(val); |
738 | it87_write_value(client, IT87_REG_FAN_MIN(nr), | 732 | it87_write_value(data, IT87_REG_FAN_MIN(nr), |
739 | data->fan_min[nr] & 0xff); | 733 | data->fan_min[nr] & 0xff); |
740 | it87_write_value(client, IT87_REG_FANX_MIN(nr), | 734 | it87_write_value(data, IT87_REG_FANX_MIN(nr), |
741 | data->fan_min[nr] >> 8); | 735 | data->fan_min[nr] >> 8); |
742 | mutex_unlock(&data->update_lock); | 736 | mutex_unlock(&data->update_lock); |
743 | return count; | 737 | return count; |
@@ -775,8 +769,7 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
775 | static ssize_t | 769 | static ssize_t |
776 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 770 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
777 | { | 771 | { |
778 | struct i2c_client *client = to_i2c_client(dev); | 772 | struct it87_data *data = dev_get_drvdata(dev); |
779 | struct it87_data *data = i2c_get_clientdata(client); | ||
780 | u32 val; | 773 | u32 val; |
781 | 774 | ||
782 | val = simple_strtoul(buf, NULL, 10); | 775 | val = simple_strtoul(buf, NULL, 10); |
@@ -794,6 +787,14 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
794 | } | 787 | } |
795 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 788 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
796 | 789 | ||
790 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
791 | *devattr, char *buf) | ||
792 | { | ||
793 | struct it87_data *data = dev_get_drvdata(dev); | ||
794 | return sprintf(buf, "%s\n", data->name); | ||
795 | } | ||
796 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
797 | |||
797 | static struct attribute *it87_attributes[] = { | 798 | static struct attribute *it87_attributes[] = { |
798 | &sensor_dev_attr_in0_input.dev_attr.attr, | 799 | &sensor_dev_attr_in0_input.dev_attr.attr, |
799 | &sensor_dev_attr_in1_input.dev_attr.attr, | 800 | &sensor_dev_attr_in1_input.dev_attr.attr, |
@@ -835,6 +836,7 @@ static struct attribute *it87_attributes[] = { | |||
835 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 836 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
836 | 837 | ||
837 | &dev_attr_alarms.attr, | 838 | &dev_attr_alarms.attr, |
839 | &dev_attr_name.attr, | ||
838 | NULL | 840 | NULL |
839 | }; | 841 | }; |
840 | 842 | ||
@@ -877,17 +879,36 @@ static const struct attribute_group it87_group_opt = { | |||
877 | }; | 879 | }; |
878 | 880 | ||
879 | /* SuperIO detection - will change isa_address if a chip is found */ | 881 | /* SuperIO detection - will change isa_address if a chip is found */ |
880 | static int __init it87_find(unsigned short *address) | 882 | static int __init it87_find(unsigned short *address, |
883 | struct it87_sio_data *sio_data) | ||
881 | { | 884 | { |
882 | int err = -ENODEV; | 885 | int err = -ENODEV; |
886 | u16 chip_type; | ||
883 | 887 | ||
884 | superio_enter(); | 888 | superio_enter(); |
885 | chip_type = superio_inw(DEVID); | 889 | chip_type = superio_inw(DEVID); |
886 | if (chip_type != IT8712F_DEVID | 890 | |
887 | && chip_type != IT8716F_DEVID | 891 | switch (chip_type) { |
888 | && chip_type != IT8718F_DEVID | 892 | case IT8705F_DEVID: |
889 | && chip_type != IT8705F_DEVID) | 893 | sio_data->type = it87; |
890 | goto exit; | 894 | break; |
895 | case IT8712F_DEVID: | ||
896 | sio_data->type = it8712; | ||
897 | break; | ||
898 | case IT8716F_DEVID: | ||
899 | case IT8726F_DEVID: | ||
900 | sio_data->type = it8716; | ||
901 | break; | ||
902 | case IT8718F_DEVID: | ||
903 | sio_data->type = it8718; | ||
904 | break; | ||
905 | case 0xffff: /* No device at all */ | ||
906 | goto exit; | ||
907 | default: | ||
908 | pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", | ||
909 | chip_type); | ||
910 | goto exit; | ||
911 | } | ||
891 | 912 | ||
892 | superio_select(PME); | 913 | superio_select(PME); |
893 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { | 914 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { |
@@ -911,7 +932,7 @@ static int __init it87_find(unsigned short *address) | |||
911 | 932 | ||
912 | superio_select(GPIO); | 933 | superio_select(GPIO); |
913 | if (chip_type == it8718) | 934 | if (chip_type == it8718) |
914 | vid_value = superio_inb(IT87_SIO_VID_REG); | 935 | sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); |
915 | 936 | ||
916 | reg = superio_inb(IT87_SIO_PINX2_REG); | 937 | reg = superio_inb(IT87_SIO_PINX2_REG); |
917 | if (reg & (1 << 0)) | 938 | if (reg & (1 << 0)) |
@@ -925,18 +946,26 @@ exit: | |||
925 | return err; | 946 | return err; |
926 | } | 947 | } |
927 | 948 | ||
928 | /* This function is called by i2c_probe */ | 949 | static int __devinit it87_probe(struct platform_device *pdev) |
929 | static int it87_detect(struct i2c_adapter *adapter) | ||
930 | { | 950 | { |
931 | struct i2c_client *new_client; | ||
932 | struct it87_data *data; | 951 | struct it87_data *data; |
952 | struct resource *res; | ||
953 | struct device *dev = &pdev->dev; | ||
954 | struct it87_sio_data *sio_data = dev->platform_data; | ||
933 | int err = 0; | 955 | int err = 0; |
934 | const char *name; | ||
935 | int enable_pwm_interface; | 956 | int enable_pwm_interface; |
936 | 957 | static const char *names[] = { | |
937 | /* Reserve the ISA region */ | 958 | "it87", |
938 | if (!request_region(isa_address, IT87_EXTENT, | 959 | "it8712", |
939 | it87_isa_driver.driver.name)){ | 960 | "it8716", |
961 | "it8718", | ||
962 | }; | ||
963 | |||
964 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
965 | if (!request_region(res->start, IT87_EXTENT, DRVNAME)) { | ||
966 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
967 | (unsigned long)res->start, | ||
968 | (unsigned long)(res->start + IT87_EXTENT - 1)); | ||
940 | err = -EBUSY; | 969 | err = -EBUSY; |
941 | goto ERROR0; | 970 | goto ERROR0; |
942 | } | 971 | } |
@@ -946,129 +975,104 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
946 | goto ERROR1; | 975 | goto ERROR1; |
947 | } | 976 | } |
948 | 977 | ||
949 | new_client = &data->client; | 978 | data->addr = res->start; |
950 | i2c_set_clientdata(new_client, data); | 979 | data->type = sio_data->type; |
951 | new_client->addr = isa_address; | 980 | data->name = names[sio_data->type]; |
952 | new_client->adapter = adapter; | ||
953 | new_client->driver = &it87_isa_driver; | ||
954 | 981 | ||
955 | /* Now, we do the remaining detection. */ | 982 | /* Now, we do the remaining detection. */ |
956 | if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) | 983 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) |
957 | || it87_read_value(new_client, IT87_REG_CHIPID) != 0x90) { | 984 | || it87_read_value(data, IT87_REG_CHIPID) != 0x90) { |
958 | err = -ENODEV; | 985 | err = -ENODEV; |
959 | goto ERROR2; | 986 | goto ERROR2; |
960 | } | 987 | } |
961 | 988 | ||
962 | /* Determine the chip type. */ | 989 | platform_set_drvdata(pdev, data); |
963 | switch (chip_type) { | ||
964 | case IT8712F_DEVID: | ||
965 | data->type = it8712; | ||
966 | name = "it8712"; | ||
967 | break; | ||
968 | case IT8716F_DEVID: | ||
969 | data->type = it8716; | ||
970 | name = "it8716"; | ||
971 | break; | ||
972 | case IT8718F_DEVID: | ||
973 | data->type = it8718; | ||
974 | name = "it8718"; | ||
975 | break; | ||
976 | default: | ||
977 | data->type = it87; | ||
978 | name = "it87"; | ||
979 | } | ||
980 | 990 | ||
981 | /* Fill in the remaining client fields and put it into the global list */ | ||
982 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
983 | mutex_init(&data->update_lock); | 991 | mutex_init(&data->update_lock); |
984 | 992 | ||
985 | /* Tell the I2C layer a new client has arrived */ | ||
986 | if ((err = i2c_attach_client(new_client))) | ||
987 | goto ERROR2; | ||
988 | |||
989 | /* Check PWM configuration */ | 993 | /* Check PWM configuration */ |
990 | enable_pwm_interface = it87_check_pwm(new_client); | 994 | enable_pwm_interface = it87_check_pwm(dev); |
991 | 995 | ||
992 | /* Initialize the IT87 chip */ | 996 | /* Initialize the IT87 chip */ |
993 | it87_init_client(new_client, data); | 997 | it87_init_device(pdev); |
994 | 998 | ||
995 | /* Register sysfs hooks */ | 999 | /* Register sysfs hooks */ |
996 | if ((err = sysfs_create_group(&new_client->dev.kobj, &it87_group))) | 1000 | if ((err = sysfs_create_group(&dev->kobj, &it87_group))) |
997 | goto ERROR3; | 1001 | goto ERROR2; |
998 | 1002 | ||
999 | /* Do not create fan files for disabled fans */ | 1003 | /* Do not create fan files for disabled fans */ |
1000 | if (data->type == it8716 || data->type == it8718) { | 1004 | if (data->type == it8716 || data->type == it8718) { |
1001 | /* 16-bit tachometers */ | 1005 | /* 16-bit tachometers */ |
1002 | if (data->has_fan & (1 << 0)) { | 1006 | if (data->has_fan & (1 << 0)) { |
1003 | if ((err = device_create_file(&new_client->dev, | 1007 | if ((err = device_create_file(dev, |
1004 | &sensor_dev_attr_fan1_input16.dev_attr)) | 1008 | &sensor_dev_attr_fan1_input16.dev_attr)) |
1005 | || (err = device_create_file(&new_client->dev, | 1009 | || (err = device_create_file(dev, |
1006 | &sensor_dev_attr_fan1_min16.dev_attr))) | 1010 | &sensor_dev_attr_fan1_min16.dev_attr))) |
1007 | goto ERROR4; | 1011 | goto ERROR4; |
1008 | } | 1012 | } |
1009 | if (data->has_fan & (1 << 1)) { | 1013 | if (data->has_fan & (1 << 1)) { |
1010 | if ((err = device_create_file(&new_client->dev, | 1014 | if ((err = device_create_file(dev, |
1011 | &sensor_dev_attr_fan2_input16.dev_attr)) | 1015 | &sensor_dev_attr_fan2_input16.dev_attr)) |
1012 | || (err = device_create_file(&new_client->dev, | 1016 | || (err = device_create_file(dev, |
1013 | &sensor_dev_attr_fan2_min16.dev_attr))) | 1017 | &sensor_dev_attr_fan2_min16.dev_attr))) |
1014 | goto ERROR4; | 1018 | goto ERROR4; |
1015 | } | 1019 | } |
1016 | if (data->has_fan & (1 << 2)) { | 1020 | if (data->has_fan & (1 << 2)) { |
1017 | if ((err = device_create_file(&new_client->dev, | 1021 | if ((err = device_create_file(dev, |
1018 | &sensor_dev_attr_fan3_input16.dev_attr)) | 1022 | &sensor_dev_attr_fan3_input16.dev_attr)) |
1019 | || (err = device_create_file(&new_client->dev, | 1023 | || (err = device_create_file(dev, |
1020 | &sensor_dev_attr_fan3_min16.dev_attr))) | 1024 | &sensor_dev_attr_fan3_min16.dev_attr))) |
1021 | goto ERROR4; | 1025 | goto ERROR4; |
1022 | } | 1026 | } |
1023 | } else { | 1027 | } else { |
1024 | /* 8-bit tachometers with clock divider */ | 1028 | /* 8-bit tachometers with clock divider */ |
1025 | if (data->has_fan & (1 << 0)) { | 1029 | if (data->has_fan & (1 << 0)) { |
1026 | if ((err = device_create_file(&new_client->dev, | 1030 | if ((err = device_create_file(dev, |
1027 | &sensor_dev_attr_fan1_input.dev_attr)) | 1031 | &sensor_dev_attr_fan1_input.dev_attr)) |
1028 | || (err = device_create_file(&new_client->dev, | 1032 | || (err = device_create_file(dev, |
1029 | &sensor_dev_attr_fan1_min.dev_attr)) | 1033 | &sensor_dev_attr_fan1_min.dev_attr)) |
1030 | || (err = device_create_file(&new_client->dev, | 1034 | || (err = device_create_file(dev, |
1031 | &sensor_dev_attr_fan1_div.dev_attr))) | 1035 | &sensor_dev_attr_fan1_div.dev_attr))) |
1032 | goto ERROR4; | 1036 | goto ERROR4; |
1033 | } | 1037 | } |
1034 | if (data->has_fan & (1 << 1)) { | 1038 | if (data->has_fan & (1 << 1)) { |
1035 | if ((err = device_create_file(&new_client->dev, | 1039 | if ((err = device_create_file(dev, |
1036 | &sensor_dev_attr_fan2_input.dev_attr)) | 1040 | &sensor_dev_attr_fan2_input.dev_attr)) |
1037 | || (err = device_create_file(&new_client->dev, | 1041 | || (err = device_create_file(dev, |
1038 | &sensor_dev_attr_fan2_min.dev_attr)) | 1042 | &sensor_dev_attr_fan2_min.dev_attr)) |
1039 | || (err = device_create_file(&new_client->dev, | 1043 | || (err = device_create_file(dev, |
1040 | &sensor_dev_attr_fan2_div.dev_attr))) | 1044 | &sensor_dev_attr_fan2_div.dev_attr))) |
1041 | goto ERROR4; | 1045 | goto ERROR4; |
1042 | } | 1046 | } |
1043 | if (data->has_fan & (1 << 2)) { | 1047 | if (data->has_fan & (1 << 2)) { |
1044 | if ((err = device_create_file(&new_client->dev, | 1048 | if ((err = device_create_file(dev, |
1045 | &sensor_dev_attr_fan3_input.dev_attr)) | 1049 | &sensor_dev_attr_fan3_input.dev_attr)) |
1046 | || (err = device_create_file(&new_client->dev, | 1050 | || (err = device_create_file(dev, |
1047 | &sensor_dev_attr_fan3_min.dev_attr)) | 1051 | &sensor_dev_attr_fan3_min.dev_attr)) |
1048 | || (err = device_create_file(&new_client->dev, | 1052 | || (err = device_create_file(dev, |
1049 | &sensor_dev_attr_fan3_div.dev_attr))) | 1053 | &sensor_dev_attr_fan3_div.dev_attr))) |
1050 | goto ERROR4; | 1054 | goto ERROR4; |
1051 | } | 1055 | } |
1052 | } | 1056 | } |
1053 | 1057 | ||
1054 | if (enable_pwm_interface) { | 1058 | if (enable_pwm_interface) { |
1055 | if ((err = device_create_file(&new_client->dev, | 1059 | if ((err = device_create_file(dev, |
1056 | &sensor_dev_attr_pwm1_enable.dev_attr)) | 1060 | &sensor_dev_attr_pwm1_enable.dev_attr)) |
1057 | || (err = device_create_file(&new_client->dev, | 1061 | || (err = device_create_file(dev, |
1058 | &sensor_dev_attr_pwm2_enable.dev_attr)) | 1062 | &sensor_dev_attr_pwm2_enable.dev_attr)) |
1059 | || (err = device_create_file(&new_client->dev, | 1063 | || (err = device_create_file(dev, |
1060 | &sensor_dev_attr_pwm3_enable.dev_attr)) | 1064 | &sensor_dev_attr_pwm3_enable.dev_attr)) |
1061 | || (err = device_create_file(&new_client->dev, | 1065 | || (err = device_create_file(dev, |
1062 | &sensor_dev_attr_pwm1.dev_attr)) | 1066 | &sensor_dev_attr_pwm1.dev_attr)) |
1063 | || (err = device_create_file(&new_client->dev, | 1067 | || (err = device_create_file(dev, |
1064 | &sensor_dev_attr_pwm2.dev_attr)) | 1068 | &sensor_dev_attr_pwm2.dev_attr)) |
1065 | || (err = device_create_file(&new_client->dev, | 1069 | || (err = device_create_file(dev, |
1066 | &sensor_dev_attr_pwm3.dev_attr)) | 1070 | &sensor_dev_attr_pwm3.dev_attr)) |
1067 | || (err = device_create_file(&new_client->dev, | 1071 | || (err = device_create_file(dev, |
1068 | &dev_attr_pwm1_freq)) | 1072 | &dev_attr_pwm1_freq)) |
1069 | || (err = device_create_file(&new_client->dev, | 1073 | || (err = device_create_file(dev, |
1070 | &dev_attr_pwm2_freq)) | 1074 | &dev_attr_pwm2_freq)) |
1071 | || (err = device_create_file(&new_client->dev, | 1075 | || (err = device_create_file(dev, |
1072 | &dev_attr_pwm3_freq))) | 1076 | &dev_attr_pwm3_freq))) |
1073 | goto ERROR4; | 1077 | goto ERROR4; |
1074 | } | 1078 | } |
@@ -1077,15 +1081,15 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
1077 | || data->type == it8718) { | 1081 | || data->type == it8718) { |
1078 | data->vrm = vid_which_vrm(); | 1082 | data->vrm = vid_which_vrm(); |
1079 | /* VID reading from Super-I/O config space if available */ | 1083 | /* VID reading from Super-I/O config space if available */ |
1080 | data->vid = vid_value; | 1084 | data->vid = sio_data->vid_value; |
1081 | if ((err = device_create_file(&new_client->dev, | 1085 | if ((err = device_create_file(dev, |
1082 | &dev_attr_vrm)) | 1086 | &dev_attr_vrm)) |
1083 | || (err = device_create_file(&new_client->dev, | 1087 | || (err = device_create_file(dev, |
1084 | &dev_attr_cpu0_vid))) | 1088 | &dev_attr_cpu0_vid))) |
1085 | goto ERROR4; | 1089 | goto ERROR4; |
1086 | } | 1090 | } |
1087 | 1091 | ||
1088 | data->class_dev = hwmon_device_register(&new_client->dev); | 1092 | data->class_dev = hwmon_device_register(dev); |
1089 | if (IS_ERR(data->class_dev)) { | 1093 | if (IS_ERR(data->class_dev)) { |
1090 | err = PTR_ERR(data->class_dev); | 1094 | err = PTR_ERR(data->class_dev); |
1091 | goto ERROR4; | 1095 | goto ERROR4; |
@@ -1094,31 +1098,27 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
1094 | return 0; | 1098 | return 0; |
1095 | 1099 | ||
1096 | ERROR4: | 1100 | ERROR4: |
1097 | sysfs_remove_group(&new_client->dev.kobj, &it87_group); | 1101 | sysfs_remove_group(&dev->kobj, &it87_group); |
1098 | sysfs_remove_group(&new_client->dev.kobj, &it87_group_opt); | 1102 | sysfs_remove_group(&dev->kobj, &it87_group_opt); |
1099 | ERROR3: | ||
1100 | i2c_detach_client(new_client); | ||
1101 | ERROR2: | 1103 | ERROR2: |
1104 | platform_set_drvdata(pdev, NULL); | ||
1102 | kfree(data); | 1105 | kfree(data); |
1103 | ERROR1: | 1106 | ERROR1: |
1104 | release_region(isa_address, IT87_EXTENT); | 1107 | release_region(res->start, IT87_EXTENT); |
1105 | ERROR0: | 1108 | ERROR0: |
1106 | return err; | 1109 | return err; |
1107 | } | 1110 | } |
1108 | 1111 | ||
1109 | static int it87_detach_client(struct i2c_client *client) | 1112 | static int __devexit it87_remove(struct platform_device *pdev) |
1110 | { | 1113 | { |
1111 | struct it87_data *data = i2c_get_clientdata(client); | 1114 | struct it87_data *data = platform_get_drvdata(pdev); |
1112 | int err; | ||
1113 | 1115 | ||
1114 | hwmon_device_unregister(data->class_dev); | 1116 | hwmon_device_unregister(data->class_dev); |
1115 | sysfs_remove_group(&client->dev.kobj, &it87_group); | 1117 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); |
1116 | sysfs_remove_group(&client->dev.kobj, &it87_group_opt); | 1118 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); |
1117 | 1119 | ||
1118 | if ((err = i2c_detach_client(client))) | 1120 | release_region(data->addr, IT87_EXTENT); |
1119 | return err; | 1121 | platform_set_drvdata(pdev, NULL); |
1120 | |||
1121 | release_region(client->addr, IT87_EXTENT); | ||
1122 | kfree(data); | 1122 | kfree(data); |
1123 | 1123 | ||
1124 | return 0; | 1124 | return 0; |
@@ -1127,28 +1127,29 @@ static int it87_detach_client(struct i2c_client *client) | |||
1127 | /* Must be called with data->update_lock held, except during initialization. | 1127 | /* Must be called with data->update_lock held, except during initialization. |
1128 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1128 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
1129 | would slow down the IT87 access and should not be necessary. */ | 1129 | would slow down the IT87 access and should not be necessary. */ |
1130 | static int it87_read_value(struct i2c_client *client, u8 reg) | 1130 | static int it87_read_value(struct it87_data *data, u8 reg) |
1131 | { | 1131 | { |
1132 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1132 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); |
1133 | return inb_p(client->addr + IT87_DATA_REG_OFFSET); | 1133 | return inb_p(data->addr + IT87_DATA_REG_OFFSET); |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | /* Must be called with data->update_lock held, except during initialization. | 1136 | /* Must be called with data->update_lock held, except during initialization. |
1137 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1137 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
1138 | would slow down the IT87 access and should not be necessary. */ | 1138 | would slow down the IT87 access and should not be necessary. */ |
1139 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value) | 1139 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value) |
1140 | { | 1140 | { |
1141 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1141 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); |
1142 | outb_p(value, client->addr + IT87_DATA_REG_OFFSET); | 1142 | outb_p(value, data->addr + IT87_DATA_REG_OFFSET); |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | /* Return 1 if and only if the PWM interface is safe to use */ | 1145 | /* Return 1 if and only if the PWM interface is safe to use */ |
1146 | static int it87_check_pwm(struct i2c_client *client) | 1146 | static int __devinit it87_check_pwm(struct device *dev) |
1147 | { | 1147 | { |
1148 | struct it87_data *data = dev_get_drvdata(dev); | ||
1148 | /* Some BIOSes fail to correctly configure the IT87 fans. All fans off | 1149 | /* Some BIOSes fail to correctly configure the IT87 fans. All fans off |
1149 | * and polarity set to active low is sign that this is the case so we | 1150 | * and polarity set to active low is sign that this is the case so we |
1150 | * disable pwm control to protect the user. */ | 1151 | * disable pwm control to protect the user. */ |
1151 | int tmp = it87_read_value(client, IT87_REG_FAN_CTL); | 1152 | int tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
1152 | if ((tmp & 0x87) == 0) { | 1153 | if ((tmp & 0x87) == 0) { |
1153 | if (fix_pwm_polarity) { | 1154 | if (fix_pwm_polarity) { |
1154 | /* The user asks us to attempt a chip reconfiguration. | 1155 | /* The user asks us to attempt a chip reconfiguration. |
@@ -1158,7 +1159,7 @@ static int it87_check_pwm(struct i2c_client *client) | |||
1158 | u8 pwm[3]; | 1159 | u8 pwm[3]; |
1159 | 1160 | ||
1160 | for (i = 0; i < 3; i++) | 1161 | for (i = 0; i < 3; i++) |
1161 | pwm[i] = it87_read_value(client, | 1162 | pwm[i] = it87_read_value(data, |
1162 | IT87_REG_PWM(i)); | 1163 | IT87_REG_PWM(i)); |
1163 | 1164 | ||
1164 | /* If any fan is in automatic pwm mode, the polarity | 1165 | /* If any fan is in automatic pwm mode, the polarity |
@@ -1166,26 +1167,26 @@ static int it87_check_pwm(struct i2c_client *client) | |||
1166 | * better don't change anything (but still disable the | 1167 | * better don't change anything (but still disable the |
1167 | * PWM interface). */ | 1168 | * PWM interface). */ |
1168 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { | 1169 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { |
1169 | dev_info(&client->dev, "Reconfiguring PWM to " | 1170 | dev_info(dev, "Reconfiguring PWM to " |
1170 | "active high polarity\n"); | 1171 | "active high polarity\n"); |
1171 | it87_write_value(client, IT87_REG_FAN_CTL, | 1172 | it87_write_value(data, IT87_REG_FAN_CTL, |
1172 | tmp | 0x87); | 1173 | tmp | 0x87); |
1173 | for (i = 0; i < 3; i++) | 1174 | for (i = 0; i < 3; i++) |
1174 | it87_write_value(client, | 1175 | it87_write_value(data, |
1175 | IT87_REG_PWM(i), | 1176 | IT87_REG_PWM(i), |
1176 | 0x7f & ~pwm[i]); | 1177 | 0x7f & ~pwm[i]); |
1177 | return 1; | 1178 | return 1; |
1178 | } | 1179 | } |
1179 | 1180 | ||
1180 | dev_info(&client->dev, "PWM configuration is " | 1181 | dev_info(dev, "PWM configuration is " |
1181 | "too broken to be fixed\n"); | 1182 | "too broken to be fixed\n"); |
1182 | } | 1183 | } |
1183 | 1184 | ||
1184 | dev_info(&client->dev, "Detected broken BIOS " | 1185 | dev_info(dev, "Detected broken BIOS " |
1185 | "defaults, disabling PWM interface\n"); | 1186 | "defaults, disabling PWM interface\n"); |
1186 | return 0; | 1187 | return 0; |
1187 | } else if (fix_pwm_polarity) { | 1188 | } else if (fix_pwm_polarity) { |
1188 | dev_info(&client->dev, "PWM configuration looks " | 1189 | dev_info(dev, "PWM configuration looks " |
1189 | "sane, won't touch\n"); | 1190 | "sane, won't touch\n"); |
1190 | } | 1191 | } |
1191 | 1192 | ||
@@ -1193,8 +1194,9 @@ static int it87_check_pwm(struct i2c_client *client) | |||
1193 | } | 1194 | } |
1194 | 1195 | ||
1195 | /* Called when we have found a new IT87. */ | 1196 | /* Called when we have found a new IT87. */ |
1196 | static void it87_init_client(struct i2c_client *client, struct it87_data *data) | 1197 | static void __devinit it87_init_device(struct platform_device *pdev) |
1197 | { | 1198 | { |
1199 | struct it87_data *data = platform_get_drvdata(pdev); | ||
1198 | int tmp, i; | 1200 | int tmp, i; |
1199 | 1201 | ||
1200 | /* initialize to sane defaults: | 1202 | /* initialize to sane defaults: |
@@ -1214,48 +1216,48 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
1214 | * means -1 degree C, which surprisingly doesn't trigger an alarm, | 1216 | * means -1 degree C, which surprisingly doesn't trigger an alarm, |
1215 | * but is still confusing, so change to 127 degrees C. */ | 1217 | * but is still confusing, so change to 127 degrees C. */ |
1216 | for (i = 0; i < 8; i++) { | 1218 | for (i = 0; i < 8; i++) { |
1217 | tmp = it87_read_value(client, IT87_REG_VIN_MIN(i)); | 1219 | tmp = it87_read_value(data, IT87_REG_VIN_MIN(i)); |
1218 | if (tmp == 0xff) | 1220 | if (tmp == 0xff) |
1219 | it87_write_value(client, IT87_REG_VIN_MIN(i), 0); | 1221 | it87_write_value(data, IT87_REG_VIN_MIN(i), 0); |
1220 | } | 1222 | } |
1221 | for (i = 0; i < 3; i++) { | 1223 | for (i = 0; i < 3; i++) { |
1222 | tmp = it87_read_value(client, IT87_REG_TEMP_HIGH(i)); | 1224 | tmp = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); |
1223 | if (tmp == 0xff) | 1225 | if (tmp == 0xff) |
1224 | it87_write_value(client, IT87_REG_TEMP_HIGH(i), 127); | 1226 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); |
1225 | } | 1227 | } |
1226 | 1228 | ||
1227 | /* Check if temperature channnels are reset manually or by some reason */ | 1229 | /* Check if temperature channnels are reset manually or by some reason */ |
1228 | tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1230 | tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
1229 | if ((tmp & 0x3f) == 0) { | 1231 | if ((tmp & 0x3f) == 0) { |
1230 | /* Temp1,Temp3=thermistor; Temp2=thermal diode */ | 1232 | /* Temp1,Temp3=thermistor; Temp2=thermal diode */ |
1231 | tmp = (tmp & 0xc0) | 0x2a; | 1233 | tmp = (tmp & 0xc0) | 0x2a; |
1232 | it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp); | 1234 | it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp); |
1233 | } | 1235 | } |
1234 | data->sensor = tmp; | 1236 | data->sensor = tmp; |
1235 | 1237 | ||
1236 | /* Check if voltage monitors are reset manually or by some reason */ | 1238 | /* Check if voltage monitors are reset manually or by some reason */ |
1237 | tmp = it87_read_value(client, IT87_REG_VIN_ENABLE); | 1239 | tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); |
1238 | if ((tmp & 0xff) == 0) { | 1240 | if ((tmp & 0xff) == 0) { |
1239 | /* Enable all voltage monitors */ | 1241 | /* Enable all voltage monitors */ |
1240 | it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff); | 1242 | it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff); |
1241 | } | 1243 | } |
1242 | 1244 | ||
1243 | /* Check if tachometers are reset manually or by some reason */ | 1245 | /* Check if tachometers are reset manually or by some reason */ |
1244 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); | 1246 | data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL); |
1245 | if ((data->fan_main_ctrl & 0x70) == 0) { | 1247 | if ((data->fan_main_ctrl & 0x70) == 0) { |
1246 | /* Enable all fan tachometers */ | 1248 | /* Enable all fan tachometers */ |
1247 | data->fan_main_ctrl |= 0x70; | 1249 | data->fan_main_ctrl |= 0x70; |
1248 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 1250 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
1249 | } | 1251 | } |
1250 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1252 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
1251 | 1253 | ||
1252 | /* Set tachometers to 16-bit mode if needed */ | 1254 | /* Set tachometers to 16-bit mode if needed */ |
1253 | if (data->type == it8716 || data->type == it8718) { | 1255 | if (data->type == it8716 || data->type == it8718) { |
1254 | tmp = it87_read_value(client, IT87_REG_FAN_16BIT); | 1256 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
1255 | if (~tmp & 0x07 & data->has_fan) { | 1257 | if (~tmp & 0x07 & data->has_fan) { |
1256 | dev_dbg(&client->dev, | 1258 | dev_dbg(&pdev->dev, |
1257 | "Setting fan1-3 to 16-bit mode\n"); | 1259 | "Setting fan1-3 to 16-bit mode\n"); |
1258 | it87_write_value(client, IT87_REG_FAN_16BIT, | 1260 | it87_write_value(data, IT87_REG_FAN_16BIT, |
1259 | tmp | 0x07); | 1261 | tmp | 0x07); |
1260 | } | 1262 | } |
1261 | } | 1263 | } |
@@ -1265,7 +1267,7 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
1265 | for (i = 0; i < 3; i++) { | 1267 | for (i = 0; i < 3; i++) { |
1266 | if (data->fan_main_ctrl & (1 << i)) { | 1268 | if (data->fan_main_ctrl & (1 << i)) { |
1267 | /* pwm mode */ | 1269 | /* pwm mode */ |
1268 | tmp = it87_read_value(client, IT87_REG_PWM(i)); | 1270 | tmp = it87_read_value(data, IT87_REG_PWM(i)); |
1269 | if (tmp & 0x80) { | 1271 | if (tmp & 0x80) { |
1270 | /* automatic pwm - not yet implemented, but | 1272 | /* automatic pwm - not yet implemented, but |
1271 | * leave the settings made by the BIOS alone | 1273 | * leave the settings made by the BIOS alone |
@@ -1279,15 +1281,14 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
1279 | } | 1281 | } |
1280 | 1282 | ||
1281 | /* Start monitoring */ | 1283 | /* Start monitoring */ |
1282 | it87_write_value(client, IT87_REG_CONFIG, | 1284 | it87_write_value(data, IT87_REG_CONFIG, |
1283 | (it87_read_value(client, IT87_REG_CONFIG) & 0x36) | 1285 | (it87_read_value(data, IT87_REG_CONFIG) & 0x36) |
1284 | | (update_vbat ? 0x41 : 0x01)); | 1286 | | (update_vbat ? 0x41 : 0x01)); |
1285 | } | 1287 | } |
1286 | 1288 | ||
1287 | static struct it87_data *it87_update_device(struct device *dev) | 1289 | static struct it87_data *it87_update_device(struct device *dev) |
1288 | { | 1290 | { |
1289 | struct i2c_client *client = to_i2c_client(dev); | 1291 | struct it87_data *data = dev_get_drvdata(dev); |
1290 | struct it87_data *data = i2c_get_clientdata(client); | ||
1291 | int i; | 1292 | int i; |
1292 | 1293 | ||
1293 | mutex_lock(&data->update_lock); | 1294 | mutex_lock(&data->update_lock); |
@@ -1298,20 +1299,20 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1298 | if (update_vbat) { | 1299 | if (update_vbat) { |
1299 | /* Cleared after each update, so reenable. Value | 1300 | /* Cleared after each update, so reenable. Value |
1300 | returned by this read will be previous value */ | 1301 | returned by this read will be previous value */ |
1301 | it87_write_value(client, IT87_REG_CONFIG, | 1302 | it87_write_value(data, IT87_REG_CONFIG, |
1302 | it87_read_value(client, IT87_REG_CONFIG) | 0x40); | 1303 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); |
1303 | } | 1304 | } |
1304 | for (i = 0; i <= 7; i++) { | 1305 | for (i = 0; i <= 7; i++) { |
1305 | data->in[i] = | 1306 | data->in[i] = |
1306 | it87_read_value(client, IT87_REG_VIN(i)); | 1307 | it87_read_value(data, IT87_REG_VIN(i)); |
1307 | data->in_min[i] = | 1308 | data->in_min[i] = |
1308 | it87_read_value(client, IT87_REG_VIN_MIN(i)); | 1309 | it87_read_value(data, IT87_REG_VIN_MIN(i)); |
1309 | data->in_max[i] = | 1310 | data->in_max[i] = |
1310 | it87_read_value(client, IT87_REG_VIN_MAX(i)); | 1311 | it87_read_value(data, IT87_REG_VIN_MAX(i)); |
1311 | } | 1312 | } |
1312 | /* in8 (battery) has no limit registers */ | 1313 | /* in8 (battery) has no limit registers */ |
1313 | data->in[8] = | 1314 | data->in[8] = |
1314 | it87_read_value(client, IT87_REG_VIN(8)); | 1315 | it87_read_value(data, IT87_REG_VIN(8)); |
1315 | 1316 | ||
1316 | for (i = 0; i < 3; i++) { | 1317 | for (i = 0; i < 3; i++) { |
1317 | /* Skip disabled fans */ | 1318 | /* Skip disabled fans */ |
@@ -1319,46 +1320,47 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1319 | continue; | 1320 | continue; |
1320 | 1321 | ||
1321 | data->fan_min[i] = | 1322 | data->fan_min[i] = |
1322 | it87_read_value(client, IT87_REG_FAN_MIN(i)); | 1323 | it87_read_value(data, IT87_REG_FAN_MIN(i)); |
1323 | data->fan[i] = it87_read_value(client, | 1324 | data->fan[i] = it87_read_value(data, |
1324 | IT87_REG_FAN(i)); | 1325 | IT87_REG_FAN(i)); |
1325 | /* Add high byte if in 16-bit mode */ | 1326 | /* Add high byte if in 16-bit mode */ |
1326 | if (data->type == it8716 || data->type == it8718) { | 1327 | if (data->type == it8716 || data->type == it8718) { |
1327 | data->fan[i] |= it87_read_value(client, | 1328 | data->fan[i] |= it87_read_value(data, |
1328 | IT87_REG_FANX(i)) << 8; | 1329 | IT87_REG_FANX(i)) << 8; |
1329 | data->fan_min[i] |= it87_read_value(client, | 1330 | data->fan_min[i] |= it87_read_value(data, |
1330 | IT87_REG_FANX_MIN(i)) << 8; | 1331 | IT87_REG_FANX_MIN(i)) << 8; |
1331 | } | 1332 | } |
1332 | } | 1333 | } |
1333 | for (i = 0; i < 3; i++) { | 1334 | for (i = 0; i < 3; i++) { |
1334 | data->temp[i] = | 1335 | data->temp[i] = |
1335 | it87_read_value(client, IT87_REG_TEMP(i)); | 1336 | it87_read_value(data, IT87_REG_TEMP(i)); |
1336 | data->temp_high[i] = | 1337 | data->temp_high[i] = |
1337 | it87_read_value(client, IT87_REG_TEMP_HIGH(i)); | 1338 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); |
1338 | data->temp_low[i] = | 1339 | data->temp_low[i] = |
1339 | it87_read_value(client, IT87_REG_TEMP_LOW(i)); | 1340 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); |
1340 | } | 1341 | } |
1341 | 1342 | ||
1342 | /* Newer chips don't have clock dividers */ | 1343 | /* Newer chips don't have clock dividers */ |
1343 | if ((data->has_fan & 0x07) && data->type != it8716 | 1344 | if ((data->has_fan & 0x07) && data->type != it8716 |
1344 | && data->type != it8718) { | 1345 | && data->type != it8718) { |
1345 | i = it87_read_value(client, IT87_REG_FAN_DIV); | 1346 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
1346 | data->fan_div[0] = i & 0x07; | 1347 | data->fan_div[0] = i & 0x07; |
1347 | data->fan_div[1] = (i >> 3) & 0x07; | 1348 | data->fan_div[1] = (i >> 3) & 0x07; |
1348 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | 1349 | data->fan_div[2] = (i & 0x40) ? 3 : 1; |
1349 | } | 1350 | } |
1350 | 1351 | ||
1351 | data->alarms = | 1352 | data->alarms = |
1352 | it87_read_value(client, IT87_REG_ALARM1) | | 1353 | it87_read_value(data, IT87_REG_ALARM1) | |
1353 | (it87_read_value(client, IT87_REG_ALARM2) << 8) | | 1354 | (it87_read_value(data, IT87_REG_ALARM2) << 8) | |
1354 | (it87_read_value(client, IT87_REG_ALARM3) << 16); | 1355 | (it87_read_value(data, IT87_REG_ALARM3) << 16); |
1355 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); | 1356 | data->fan_main_ctrl = it87_read_value(data, |
1356 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL); | 1357 | IT87_REG_FAN_MAIN_CTRL); |
1357 | 1358 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | |
1358 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1359 | |
1360 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | ||
1359 | /* The 8705 does not have VID capability */ | 1361 | /* The 8705 does not have VID capability */ |
1360 | if (data->type == it8712 || data->type == it8716) { | 1362 | if (data->type == it8712 || data->type == it8716) { |
1361 | data->vid = it87_read_value(client, IT87_REG_VID); | 1363 | data->vid = it87_read_value(data, IT87_REG_VID); |
1362 | /* The older IT8712F revisions had only 5 VID pins, | 1364 | /* The older IT8712F revisions had only 5 VID pins, |
1363 | but we assume it is always safe to read 6 bits. */ | 1365 | but we assume it is always safe to read 6 bits. */ |
1364 | data->vid &= 0x3f; | 1366 | data->vid &= 0x3f; |
@@ -1372,24 +1374,85 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1372 | return data; | 1374 | return data; |
1373 | } | 1375 | } |
1374 | 1376 | ||
1377 | static int __init it87_device_add(unsigned short address, | ||
1378 | const struct it87_sio_data *sio_data) | ||
1379 | { | ||
1380 | struct resource res = { | ||
1381 | .start = address , | ||
1382 | .end = address + IT87_EXTENT - 1, | ||
1383 | .name = DRVNAME, | ||
1384 | .flags = IORESOURCE_IO, | ||
1385 | }; | ||
1386 | int err; | ||
1387 | |||
1388 | pdev = platform_device_alloc(DRVNAME, address); | ||
1389 | if (!pdev) { | ||
1390 | err = -ENOMEM; | ||
1391 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
1392 | goto exit; | ||
1393 | } | ||
1394 | |||
1395 | err = platform_device_add_resources(pdev, &res, 1); | ||
1396 | if (err) { | ||
1397 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
1398 | "(%d)\n", err); | ||
1399 | goto exit_device_put; | ||
1400 | } | ||
1401 | |||
1402 | err = platform_device_add_data(pdev, sio_data, | ||
1403 | sizeof(struct it87_sio_data)); | ||
1404 | if (err) { | ||
1405 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
1406 | goto exit_device_put; | ||
1407 | } | ||
1408 | |||
1409 | err = platform_device_add(pdev); | ||
1410 | if (err) { | ||
1411 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
1412 | err); | ||
1413 | goto exit_device_put; | ||
1414 | } | ||
1415 | |||
1416 | return 0; | ||
1417 | |||
1418 | exit_device_put: | ||
1419 | platform_device_put(pdev); | ||
1420 | exit: | ||
1421 | return err; | ||
1422 | } | ||
1423 | |||
1375 | static int __init sm_it87_init(void) | 1424 | static int __init sm_it87_init(void) |
1376 | { | 1425 | { |
1377 | int res; | 1426 | int err; |
1427 | unsigned short isa_address=0; | ||
1428 | struct it87_sio_data sio_data; | ||
1429 | |||
1430 | err = it87_find(&isa_address, &sio_data); | ||
1431 | if (err) | ||
1432 | return err; | ||
1433 | err = platform_driver_register(&it87_driver); | ||
1434 | if (err) | ||
1435 | return err; | ||
1378 | 1436 | ||
1379 | if ((res = it87_find(&isa_address))) | 1437 | err = it87_device_add(isa_address, &sio_data); |
1380 | return res; | 1438 | if (err){ |
1381 | return i2c_isa_add_driver(&it87_isa_driver); | 1439 | platform_driver_unregister(&it87_driver); |
1440 | return err; | ||
1441 | } | ||
1442 | |||
1443 | return 0; | ||
1382 | } | 1444 | } |
1383 | 1445 | ||
1384 | static void __exit sm_it87_exit(void) | 1446 | static void __exit sm_it87_exit(void) |
1385 | { | 1447 | { |
1386 | i2c_isa_del_driver(&it87_isa_driver); | 1448 | platform_device_unregister(pdev); |
1449 | platform_driver_unregister(&it87_driver); | ||
1387 | } | 1450 | } |
1388 | 1451 | ||
1389 | 1452 | ||
1390 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, " | 1453 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, " |
1391 | "Jean Delvare <khali@linux-fr.org>"); | 1454 | "Jean Delvare <khali@linux-fr.org>"); |
1392 | MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver"); | 1455 | MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8726F, SiS950 driver"); |
1393 | module_param(update_vbat, bool, 0); | 1456 | module_param(update_vbat, bool, 0); |
1394 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); | 1457 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); |
1395 | module_param(fix_pwm_polarity, bool, 0); | 1458 | module_param(fix_pwm_polarity, bool, 0); |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index d69f3cf07122..2162d69a8c06 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -364,7 +364,7 @@ static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, | |||
364 | /* Individual alarm files */ | 364 | /* Individual alarm files */ |
365 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); | 365 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); |
366 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 366 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
367 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); | 367 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
368 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | 368 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); |
369 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 369 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
370 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | 370 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); |
@@ -383,7 +383,7 @@ static struct attribute *lm63_attributes[] = { | |||
383 | &dev_attr_temp2_crit_hyst.attr, | 383 | &dev_attr_temp2_crit_hyst.attr, |
384 | 384 | ||
385 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 385 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
386 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 386 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
387 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 387 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
388 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 388 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
389 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 389 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index feb87b41e986..654c0f73464d 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -223,14 +223,14 @@ static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8); | |||
223 | /* Individual alarm files */ | 223 | /* Individual alarm files */ |
224 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 224 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
225 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 225 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
226 | static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 2); | 226 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2); |
227 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 227 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
228 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | 228 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); |
229 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); | 229 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); |
230 | static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9); | 230 | static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9); |
231 | static SENSOR_DEVICE_ATTR(temp4_input_fault, S_IRUGO, show_alarm, NULL, 10); | 231 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, 10); |
232 | static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12); | 232 | static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12); |
233 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 13); | 233 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 13); |
234 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15); | 234 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15); |
235 | /* Raw alarm file for compatibility */ | 235 | /* Raw alarm file for compatibility */ |
236 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 236 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
@@ -245,7 +245,7 @@ static struct attribute *lm83_attributes[] = { | |||
245 | 245 | ||
246 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 246 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
247 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 247 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
248 | &sensor_dev_attr_temp3_input_fault.dev_attr.attr, | 248 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
249 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 249 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
250 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 250 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
251 | &dev_attr_alarms.attr, | 251 | &dev_attr_alarms.attr, |
@@ -266,9 +266,9 @@ static struct attribute *lm83_attributes_opt[] = { | |||
266 | 266 | ||
267 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 267 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
268 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, | 268 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, |
269 | &sensor_dev_attr_temp4_input_fault.dev_attr.attr, | 269 | &sensor_dev_attr_temp4_fault.dev_attr.attr, |
270 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | 270 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, |
271 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 271 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
272 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 272 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
273 | NULL | 273 | NULL |
274 | }; | 274 | }; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 6882ce75feee..48833fff4920 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -43,6 +43,13 @@ | |||
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. |
45 | * | 45 | * |
46 | * 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. Complete datasheet can be obtained at: | ||
49 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
50 | * The MAX6680 and MAX6681 only differ in the pinout so they can be | ||
51 | * treated identically. | ||
52 | * | ||
46 | * This driver also supports the ADT7461 chip from Analog Devices but | 53 | * This driver also supports the ADT7461 chip from Analog Devices but |
47 | * only in its "compatability mode". If an ADT7461 chip is found but | 54 | * only in its "compatability mode". If an ADT7461 chip is found but |
48 | * is configured in non-compatible mode (where its temperature | 55 | * is configured in non-compatible mode (where its temperature |
@@ -84,20 +91,25 @@ | |||
84 | /* | 91 | /* |
85 | * Addresses to scan | 92 | * Addresses to scan |
86 | * Address is fully defined internally and cannot be changed except for | 93 | * Address is fully defined internally and cannot be changed except for |
87 | * MAX6659. | 94 | * MAX6659, MAX6680 and MAX6681. |
88 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 | 95 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 |
89 | * have address 0x4c. | 96 | * have address 0x4c. |
90 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. | 97 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. |
91 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). | 98 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). |
99 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
100 | * 0x4c, 0x4d or 0x4e. | ||
92 | */ | 101 | */ |
93 | 102 | ||
94 | static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; | 103 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, |
104 | 0x29, 0x2a, 0x2b, | ||
105 | 0x4c, 0x4d, 0x4e, | ||
106 | I2C_CLIENT_END }; | ||
95 | 107 | ||
96 | /* | 108 | /* |
97 | * Insmod parameters | 109 | * Insmod parameters |
98 | */ | 110 | */ |
99 | 111 | ||
100 | I2C_CLIENT_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461); | 112 | I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); |
101 | 113 | ||
102 | /* | 114 | /* |
103 | * The LM90 registers | 115 | * The LM90 registers |
@@ -359,7 +371,7 @@ static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | |||
359 | /* Individual alarm files */ | 371 | /* Individual alarm files */ |
360 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 372 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
361 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 373 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
362 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); | 374 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
363 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | 375 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); |
364 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 376 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
365 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | 377 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); |
@@ -381,7 +393,7 @@ static struct attribute *lm90_attributes[] = { | |||
381 | 393 | ||
382 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 394 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
383 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 395 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
384 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 396 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
385 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 397 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
386 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 398 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
387 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 399 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
@@ -429,7 +441,7 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | |||
429 | */ | 441 | */ |
430 | 442 | ||
431 | /* The ADM1032 supports PEC but not on write byte transactions, so we need | 443 | /* The ADM1032 supports PEC but not on write byte transactions, so we need |
432 | to explicitely ask for a transaction without PEC. */ | 444 | to explicitly ask for a transaction without PEC. */ |
433 | static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) | 445 | static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) |
434 | { | 446 | { |
435 | return i2c_smbus_xfer(client->adapter, client->addr, | 447 | return i2c_smbus_xfer(client->adapter, client->addr, |
@@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
525 | ®_convrate) < 0) | 537 | ®_convrate) < 0) |
526 | goto exit_free; | 538 | goto exit_free; |
527 | 539 | ||
528 | if (man_id == 0x01) { /* National Semiconductor */ | 540 | if ((address == 0x4C || address == 0x4D) |
541 | && man_id == 0x01) { /* National Semiconductor */ | ||
529 | u8 reg_config2; | 542 | u8 reg_config2; |
530 | 543 | ||
531 | if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, | 544 | if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, |
@@ -548,7 +561,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
548 | } | 561 | } |
549 | } | 562 | } |
550 | } else | 563 | } else |
551 | if (man_id == 0x41) { /* Analog Devices */ | 564 | if ((address == 0x4C || address == 0x4D) |
565 | && man_id == 0x41) { /* Analog Devices */ | ||
552 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ | 566 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ |
553 | && (reg_config1 & 0x3F) == 0x00 | 567 | && (reg_config1 & 0x3F) == 0x00 |
554 | && reg_convrate <= 0x0A) { | 568 | && reg_convrate <= 0x0A) { |
@@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
562 | } else | 576 | } else |
563 | if (man_id == 0x4D) { /* Maxim */ | 577 | if (man_id == 0x4D) { /* Maxim */ |
564 | /* | 578 | /* |
565 | * The Maxim variants do NOT have a chip_id register. | 579 | * The MAX6657, MAX6658 and MAX6659 do NOT have a |
566 | * Reading from that address will return the last read | 580 | * chip_id register. Reading from that address will |
567 | * value, which in our case is those of the man_id | 581 | * return the last read value, which in our case is |
568 | * register. Likewise, the config1 register seems to | 582 | * those of the man_id register. Likewise, the config1 |
569 | * lack a low nibble, so the value will be those of the | 583 | * register seems to lack a low nibble, so the value |
570 | * previous read, so in our case those of the man_id | 584 | * will be those of the previous read, so in our case |
571 | * register. | 585 | * those of the man_id register. |
572 | */ | 586 | */ |
573 | if (chip_id == man_id | 587 | if (chip_id == man_id |
588 | && (address == 0x4F || address == 0x4D) | ||
574 | && (reg_config1 & 0x1F) == (man_id & 0x0F) | 589 | && (reg_config1 & 0x1F) == (man_id & 0x0F) |
575 | && reg_convrate <= 0x09) { | 590 | && reg_convrate <= 0x09) { |
576 | kind = max6657; | 591 | kind = max6657; |
592 | } else | ||
593 | /* The chip_id register of the MAX6680 and MAX6681 | ||
594 | * holds the revision of the chip. | ||
595 | * the lowest bit of the config1 register is unused | ||
596 | * and should return zero when read, so should the | ||
597 | * second to last bit of config1 (software reset) | ||
598 | */ | ||
599 | if (chip_id == 0x01 | ||
600 | && (reg_config1 & 0x03) == 0x00 | ||
601 | && reg_convrate <= 0x07) { | ||
602 | kind = max6680; | ||
577 | } | 603 | } |
578 | } | 604 | } |
579 | 605 | ||
@@ -599,6 +625,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
599 | name = "lm86"; | 625 | name = "lm86"; |
600 | } else if (kind == max6657) { | 626 | } else if (kind == max6657) { |
601 | name = "max6657"; | 627 | name = "max6657"; |
628 | } else if (kind == max6680) { | ||
629 | name = "max6680"; | ||
602 | } else if (kind == adt7461) { | 630 | } else if (kind == adt7461) { |
603 | name = "adt7461"; | 631 | name = "adt7461"; |
604 | } | 632 | } |
@@ -646,7 +674,8 @@ exit: | |||
646 | 674 | ||
647 | static void lm90_init_client(struct i2c_client *client) | 675 | static void lm90_init_client(struct i2c_client *client) |
648 | { | 676 | { |
649 | u8 config; | 677 | u8 config, config_orig; |
678 | struct lm90_data *data = i2c_get_clientdata(client); | ||
650 | 679 | ||
651 | /* | 680 | /* |
652 | * Start the conversions. | 681 | * Start the conversions. |
@@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client) | |||
657 | dev_warn(&client->dev, "Initialization failed!\n"); | 686 | dev_warn(&client->dev, "Initialization failed!\n"); |
658 | return; | 687 | return; |
659 | } | 688 | } |
660 | if (config & 0x40) | 689 | config_orig = config; |
661 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | 690 | |
662 | config & 0xBF); /* run */ | 691 | /* |
692 | * Put MAX6680/MAX8881 into extended resolution (bit 0x10, | ||
693 | * 0.125 degree resolution) and range (0x08, extend range | ||
694 | * to -64 degree) mode for the remote temperature sensor. | ||
695 | */ | ||
696 | if (data->kind == max6680) { | ||
697 | config |= 0x18; | ||
698 | } | ||
699 | |||
700 | config &= 0xBF; /* run */ | ||
701 | if (config != config_orig) /* Only write if changed */ | ||
702 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); | ||
663 | } | 703 | } |
664 | 704 | ||
665 | static int lm90_detach_client(struct i2c_client *client) | 705 | static int lm90_detach_client(struct i2c_client *client) |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c new file mode 100644 index 000000000000..23edf4fe4221 --- /dev/null +++ b/drivers/hwmon/lm93.c | |||
@@ -0,0 +1,2655 @@ | |||
1 | /* | ||
2 | lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring | ||
3 | |||
4 | Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> | ||
5 | Copyright (c) 2004 Utilitek Systems, Inc. | ||
6 | |||
7 | derived in part from lm78.c: | ||
8 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
9 | |||
10 | derived in part from lm85.c: | ||
11 | Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> | ||
12 | Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> | ||
13 | |||
14 | derived in part from w83l785ts.c: | ||
15 | Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org> | ||
16 | |||
17 | Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com> | ||
18 | Copyright (c) 2005 Aspen Systems, Inc. | ||
19 | |||
20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> | ||
21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab | ||
22 | |||
23 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | ||
24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH | ||
25 | |||
26 | This program is free software; you can redistribute it and/or modify | ||
27 | it under the terms of the GNU General Public License as published by | ||
28 | the Free Software Foundation; either version 2 of the License, or | ||
29 | (at your option) any later version. | ||
30 | |||
31 | This program is distributed in the hope that it will be useful, | ||
32 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
34 | GNU General Public License for more details. | ||
35 | |||
36 | You should have received a copy of the GNU General Public License | ||
37 | along with this program; if not, write to the Free Software | ||
38 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
39 | */ | ||
40 | |||
41 | #include <linux/module.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/slab.h> | ||
44 | #include <linux/i2c.h> | ||
45 | #include <linux/hwmon.h> | ||
46 | #include <linux/hwmon-sysfs.h> | ||
47 | #include <linux/hwmon-vid.h> | ||
48 | #include <linux/err.h> | ||
49 | #include <linux/delay.h> | ||
50 | |||
51 | /* LM93 REGISTER ADDRESSES */ | ||
52 | |||
53 | /* miscellaneous */ | ||
54 | #define LM93_REG_MFR_ID 0x3e | ||
55 | #define LM93_REG_VER 0x3f | ||
56 | #define LM93_REG_STATUS_CONTROL 0xe2 | ||
57 | #define LM93_REG_CONFIG 0xe3 | ||
58 | #define LM93_REG_SLEEP_CONTROL 0xe4 | ||
59 | |||
60 | /* alarm values start here */ | ||
61 | #define LM93_REG_HOST_ERROR_1 0x48 | ||
62 | |||
63 | /* voltage inputs: in1-in16 (nr => 0-15) */ | ||
64 | #define LM93_REG_IN(nr) (0x56 + (nr)) | ||
65 | #define LM93_REG_IN_MIN(nr) (0x90 + (nr) * 2) | ||
66 | #define LM93_REG_IN_MAX(nr) (0x91 + (nr) * 2) | ||
67 | |||
68 | /* temperature inputs: temp1-temp4 (nr => 0-3) */ | ||
69 | #define LM93_REG_TEMP(nr) (0x50 + (nr)) | ||
70 | #define LM93_REG_TEMP_MIN(nr) (0x78 + (nr) * 2) | ||
71 | #define LM93_REG_TEMP_MAX(nr) (0x79 + (nr) * 2) | ||
72 | |||
73 | /* temp[1-4]_auto_boost (nr => 0-3) */ | ||
74 | #define LM93_REG_BOOST(nr) (0x80 + (nr)) | ||
75 | |||
76 | /* #PROCHOT inputs: prochot1-prochot2 (nr => 0-1) */ | ||
77 | #define LM93_REG_PROCHOT_CUR(nr) (0x67 + (nr) * 2) | ||
78 | #define LM93_REG_PROCHOT_AVG(nr) (0x68 + (nr) * 2) | ||
79 | #define LM93_REG_PROCHOT_MAX(nr) (0xb0 + (nr)) | ||
80 | |||
81 | /* fan tach inputs: fan1-fan4 (nr => 0-3) */ | ||
82 | #define LM93_REG_FAN(nr) (0x6e + (nr) * 2) | ||
83 | #define LM93_REG_FAN_MIN(nr) (0xb4 + (nr) * 2) | ||
84 | |||
85 | /* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */ | ||
86 | #define LM93_REG_PWM_CTL(nr,reg) (0xc8 + (reg) + (nr) * 4) | ||
87 | #define LM93_PWM_CTL1 0x0 | ||
88 | #define LM93_PWM_CTL2 0x1 | ||
89 | #define LM93_PWM_CTL3 0x2 | ||
90 | #define LM93_PWM_CTL4 0x3 | ||
91 | |||
92 | /* GPIO input state */ | ||
93 | #define LM93_REG_GPI 0x6b | ||
94 | |||
95 | /* vid inputs: vid1-vid2 (nr => 0-1) */ | ||
96 | #define LM93_REG_VID(nr) (0x6c + (nr)) | ||
97 | |||
98 | /* vccp1 & vccp2: VID relative inputs (nr => 0-1) */ | ||
99 | #define LM93_REG_VCCP_LIMIT_OFF(nr) (0xb2 + (nr)) | ||
100 | |||
101 | /* temp[1-4]_auto_boost_hyst */ | ||
102 | #define LM93_REG_BOOST_HYST_12 0xc0 | ||
103 | #define LM93_REG_BOOST_HYST_34 0xc1 | ||
104 | #define LM93_REG_BOOST_HYST(nr) (0xc0 + (nr)/2) | ||
105 | |||
106 | /* temp[1-4]_auto_pwm_[min|hyst] */ | ||
107 | #define LM93_REG_PWM_MIN_HYST_12 0xc3 | ||
108 | #define LM93_REG_PWM_MIN_HYST_34 0xc4 | ||
109 | #define LM93_REG_PWM_MIN_HYST(nr) (0xc3 + (nr)/2) | ||
110 | |||
111 | /* prochot_override & prochot_interval */ | ||
112 | #define LM93_REG_PROCHOT_OVERRIDE 0xc6 | ||
113 | #define LM93_REG_PROCHOT_INTERVAL 0xc7 | ||
114 | |||
115 | /* temp[1-4]_auto_base (nr => 0-3) */ | ||
116 | #define LM93_REG_TEMP_BASE(nr) (0xd0 + (nr)) | ||
117 | |||
118 | /* temp[1-4]_auto_offsets (step => 0-11) */ | ||
119 | #define LM93_REG_TEMP_OFFSET(step) (0xd4 + (step)) | ||
120 | |||
121 | /* #PROCHOT & #VRDHOT PWM ramp control */ | ||
122 | #define LM93_REG_PWM_RAMP_CTL 0xbf | ||
123 | |||
124 | /* miscellaneous */ | ||
125 | #define LM93_REG_SFC1 0xbc | ||
126 | #define LM93_REG_SFC2 0xbd | ||
127 | #define LM93_REG_GPI_VID_CTL 0xbe | ||
128 | #define LM93_REG_SF_TACH_TO_PWM 0xe0 | ||
129 | |||
130 | /* error masks */ | ||
131 | #define LM93_REG_GPI_ERR_MASK 0xec | ||
132 | #define LM93_REG_MISC_ERR_MASK 0xed | ||
133 | |||
134 | /* LM93 REGISTER VALUES */ | ||
135 | #define LM93_MFR_ID 0x73 | ||
136 | #define LM93_MFR_ID_PROTOTYPE 0x72 | ||
137 | |||
138 | /* SMBus capabilities */ | ||
139 | #define LM93_SMBUS_FUNC_FULL (I2C_FUNC_SMBUS_BYTE_DATA | \ | ||
140 | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA) | ||
141 | #define LM93_SMBUS_FUNC_MIN (I2C_FUNC_SMBUS_BYTE_DATA | \ | ||
142 | I2C_FUNC_SMBUS_WORD_DATA) | ||
143 | |||
144 | /* Addresses to scan */ | ||
145 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | ||
146 | |||
147 | /* Insmod parameters */ | ||
148 | I2C_CLIENT_INSMOD_1(lm93); | ||
149 | |||
150 | static int disable_block; | ||
151 | module_param(disable_block, bool, 0); | ||
152 | MODULE_PARM_DESC(disable_block, | ||
153 | "Set to non-zero to disable SMBus block data transactions."); | ||
154 | |||
155 | static int init; | ||
156 | module_param(init, bool, 0); | ||
157 | MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); | ||
158 | |||
159 | static int vccp_limit_type[2] = {0,0}; | ||
160 | module_param_array(vccp_limit_type, int, NULL, 0); | ||
161 | MODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes."); | ||
162 | |||
163 | static int vid_agtl; | ||
164 | module_param(vid_agtl, int, 0); | ||
165 | MODULE_PARM_DESC(vid_agtl, "Configures VID pin input thresholds."); | ||
166 | |||
167 | /* Driver data */ | ||
168 | static struct i2c_driver lm93_driver; | ||
169 | |||
170 | /* LM93 BLOCK READ COMMANDS */ | ||
171 | static const struct { u8 cmd; u8 len; } lm93_block_read_cmds[12] = { | ||
172 | { 0xf2, 8 }, | ||
173 | { 0xf3, 8 }, | ||
174 | { 0xf4, 6 }, | ||
175 | { 0xf5, 16 }, | ||
176 | { 0xf6, 4 }, | ||
177 | { 0xf7, 8 }, | ||
178 | { 0xf8, 12 }, | ||
179 | { 0xf9, 32 }, | ||
180 | { 0xfa, 8 }, | ||
181 | { 0xfb, 8 }, | ||
182 | { 0xfc, 16 }, | ||
183 | { 0xfd, 9 }, | ||
184 | }; | ||
185 | |||
186 | /* ALARMS: SYSCTL format described further below | ||
187 | REG: 64 bits in 8 registers, as immediately below */ | ||
188 | struct block1_t { | ||
189 | u8 host_status_1; | ||
190 | u8 host_status_2; | ||
191 | u8 host_status_3; | ||
192 | u8 host_status_4; | ||
193 | u8 p1_prochot_status; | ||
194 | u8 p2_prochot_status; | ||
195 | u8 gpi_status; | ||
196 | u8 fan_status; | ||
197 | }; | ||
198 | |||
199 | /* | ||
200 | * Client-specific data | ||
201 | */ | ||
202 | struct lm93_data { | ||
203 | struct i2c_client client; | ||
204 | struct class_device *class_dev; | ||
205 | |||
206 | struct mutex update_lock; | ||
207 | unsigned long last_updated; /* In jiffies */ | ||
208 | |||
209 | /* client update function */ | ||
210 | void (*update)(struct lm93_data *, struct i2c_client *); | ||
211 | |||
212 | char valid; /* !=0 if following fields are valid */ | ||
213 | |||
214 | /* register values, arranged by block read groups */ | ||
215 | struct block1_t block1; | ||
216 | |||
217 | /* temp1 - temp4: unfiltered readings | ||
218 | temp1 - temp2: filtered readings */ | ||
219 | u8 block2[6]; | ||
220 | |||
221 | /* vin1 - vin16: readings */ | ||
222 | u8 block3[16]; | ||
223 | |||
224 | /* prochot1 - prochot2: readings */ | ||
225 | struct { | ||
226 | u8 cur; | ||
227 | u8 avg; | ||
228 | } block4[2]; | ||
229 | |||
230 | /* fan counts 1-4 => 14-bits, LE, *left* justified */ | ||
231 | u16 block5[4]; | ||
232 | |||
233 | /* block6 has a lot of data we don't need */ | ||
234 | struct { | ||
235 | u8 min; | ||
236 | u8 max; | ||
237 | } temp_lim[3]; | ||
238 | |||
239 | /* vin1 - vin16: low and high limits */ | ||
240 | struct { | ||
241 | u8 min; | ||
242 | u8 max; | ||
243 | } block7[16]; | ||
244 | |||
245 | /* fan count limits 1-4 => same format as block5 */ | ||
246 | u16 block8[4]; | ||
247 | |||
248 | /* pwm control registers (2 pwms, 4 regs) */ | ||
249 | u8 block9[2][4]; | ||
250 | |||
251 | /* auto/pwm base temp and offset temp registers */ | ||
252 | struct { | ||
253 | u8 base[4]; | ||
254 | u8 offset[12]; | ||
255 | } block10; | ||
256 | |||
257 | /* master config register */ | ||
258 | u8 config; | ||
259 | |||
260 | /* VID1 & VID2 => register format, 6-bits, right justified */ | ||
261 | u8 vid[2]; | ||
262 | |||
263 | /* prochot1 - prochot2: limits */ | ||
264 | u8 prochot_max[2]; | ||
265 | |||
266 | /* vccp1 & vccp2 (in7 & in8): VID relative limits (register format) */ | ||
267 | u8 vccp_limits[2]; | ||
268 | |||
269 | /* GPIO input state (register format, i.e. inverted) */ | ||
270 | u8 gpi; | ||
271 | |||
272 | /* #PROCHOT override (register format) */ | ||
273 | u8 prochot_override; | ||
274 | |||
275 | /* #PROCHOT intervals (register format) */ | ||
276 | u8 prochot_interval; | ||
277 | |||
278 | /* Fan Boost Temperatures (register format) */ | ||
279 | u8 boost[4]; | ||
280 | |||
281 | /* Fan Boost Hysteresis (register format) */ | ||
282 | u8 boost_hyst[2]; | ||
283 | |||
284 | /* Temperature Zone Min. PWM & Hysteresis (register format) */ | ||
285 | u8 auto_pwm_min_hyst[2]; | ||
286 | |||
287 | /* #PROCHOT & #VRDHOT PWM Ramp Control */ | ||
288 | u8 pwm_ramp_ctl; | ||
289 | |||
290 | /* miscellaneous setup regs */ | ||
291 | u8 sfc1; | ||
292 | u8 sfc2; | ||
293 | u8 sf_tach_to_pwm; | ||
294 | |||
295 | /* The two PWM CTL2 registers can read something other than what was | ||
296 | last written for the OVR_DC field (duty cycle override). So, we | ||
297 | save the user-commanded value here. */ | ||
298 | u8 pwm_override[2]; | ||
299 | }; | ||
300 | |||
301 | /* VID: mV | ||
302 | REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 */ | ||
303 | static int LM93_VID_FROM_REG(u8 reg) | ||
304 | { | ||
305 | return vid_from_reg((reg & 0x3f), 100); | ||
306 | } | ||
307 | |||
308 | /* min, max, and nominal register values, per channel (u8) */ | ||
309 | static const u8 lm93_vin_reg_min[16] = { | ||
310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
311 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, | ||
312 | }; | ||
313 | static const u8 lm93_vin_reg_max[16] = { | ||
314 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
315 | 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, | ||
316 | }; | ||
317 | /* Values from the datasheet. They're here for documentation only. | ||
318 | static const u8 lm93_vin_reg_nom[16] = { | ||
319 | 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, | ||
320 | 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0, | ||
321 | }; | ||
322 | */ | ||
323 | |||
324 | /* min, max, and nominal voltage readings, per channel (mV)*/ | ||
325 | static const unsigned long lm93_vin_val_min[16] = { | ||
326 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
327 | 0, 0, 0, 0, 0, 0, 0, 3000, | ||
328 | }; | ||
329 | |||
330 | static const unsigned long lm93_vin_val_max[16] = { | ||
331 | 1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600, | ||
332 | 4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600, | ||
333 | }; | ||
334 | /* Values from the datasheet. They're here for documentation only. | ||
335 | static const unsigned long lm93_vin_val_nom[16] = { | ||
336 | 927, 927, 927, 1200, 1500, 1500, 1200, 1200, | ||
337 | 3300, 5000, 2500, 1969, 984, 984, 309, 3300, | ||
338 | }; | ||
339 | */ | ||
340 | |||
341 | static unsigned LM93_IN_FROM_REG(int nr, u8 reg) | ||
342 | { | ||
343 | const long uV_max = lm93_vin_val_max[nr] * 1000; | ||
344 | const long uV_min = lm93_vin_val_min[nr] * 1000; | ||
345 | |||
346 | const long slope = (uV_max - uV_min) / | ||
347 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | ||
348 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | ||
349 | |||
350 | return (slope * reg + intercept + 500) / 1000; | ||
351 | } | ||
352 | |||
353 | /* IN: mV, limits determined by channel nr | ||
354 | REG: scaling determined by channel nr */ | ||
355 | static u8 LM93_IN_TO_REG(int nr, unsigned val) | ||
356 | { | ||
357 | /* range limit */ | ||
358 | const long mV = SENSORS_LIMIT(val, | ||
359 | lm93_vin_val_min[nr], lm93_vin_val_max[nr]); | ||
360 | |||
361 | /* try not to lose too much precision here */ | ||
362 | const long uV = mV * 1000; | ||
363 | const long uV_max = lm93_vin_val_max[nr] * 1000; | ||
364 | const long uV_min = lm93_vin_val_min[nr] * 1000; | ||
365 | |||
366 | /* convert */ | ||
367 | const long slope = (uV_max - uV_min) / | ||
368 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | ||
369 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | ||
370 | |||
371 | u8 result = ((uV - intercept + (slope/2)) / slope); | ||
372 | result = SENSORS_LIMIT(result, | ||
373 | lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); | ||
374 | return result; | ||
375 | } | ||
376 | |||
377 | /* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ | ||
378 | static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) | ||
379 | { | ||
380 | const long uV_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : | ||
381 | (((reg >> 0 & 0x0f) + 1) * -25000); | ||
382 | const long uV_vid = vid * 1000; | ||
383 | return (uV_vid + uV_offset + 5000) / 10000; | ||
384 | } | ||
385 | |||
386 | #define LM93_IN_MIN_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,0,vid) | ||
387 | #define LM93_IN_MAX_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,1,vid) | ||
388 | |||
389 | /* vid in mV , upper == 0 indicates low limit, otherwise upper limit | ||
390 | upper also determines which nibble of the register is returned | ||
391 | (the other nibble will be 0x0) */ | ||
392 | static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) | ||
393 | { | ||
394 | long uV_offset = vid * 1000 - val * 10000; | ||
395 | if (upper) { | ||
396 | uV_offset = SENSORS_LIMIT(uV_offset, 12500, 200000); | ||
397 | return (u8)((uV_offset / 12500 - 1) << 4); | ||
398 | } else { | ||
399 | uV_offset = SENSORS_LIMIT(uV_offset, -400000, -25000); | ||
400 | return (u8)((uV_offset / -25000 - 1) << 0); | ||
401 | } | ||
402 | } | ||
403 | |||
404 | /* TEMP: 1/1000 degrees C (-128C to +127C) | ||
405 | REG: 1C/bit, two's complement */ | ||
406 | static int LM93_TEMP_FROM_REG(u8 reg) | ||
407 | { | ||
408 | return (s8)reg * 1000; | ||
409 | } | ||
410 | |||
411 | #define LM93_TEMP_MIN (-128000) | ||
412 | #define LM93_TEMP_MAX ( 127000) | ||
413 | |||
414 | /* TEMP: 1/1000 degrees C (-128C to +127C) | ||
415 | REG: 1C/bit, two's complement */ | ||
416 | static u8 LM93_TEMP_TO_REG(int temp) | ||
417 | { | ||
418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); | ||
419 | ntemp += (ntemp<0 ? -500 : 500); | ||
420 | return (u8)(ntemp / 1000); | ||
421 | } | ||
422 | |||
423 | /* Determine 4-bit temperature offset resolution */ | ||
424 | static int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr) | ||
425 | { | ||
426 | /* mode: 0 => 1C/bit, nonzero => 0.5C/bit */ | ||
427 | return sfc2 & (nr < 2 ? 0x10 : 0x20); | ||
428 | } | ||
429 | |||
430 | /* This function is common to all 4-bit temperature offsets | ||
431 | reg is 4 bits right justified | ||
432 | mode 0 => 1C/bit, mode !0 => 0.5C/bit */ | ||
433 | static int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode) | ||
434 | { | ||
435 | return (reg & 0x0f) * (mode ? 5 : 10); | ||
436 | } | ||
437 | |||
438 | #define LM93_TEMP_OFFSET_MIN ( 0) | ||
439 | #define LM93_TEMP_OFFSET_MAX0 (150) | ||
440 | #define LM93_TEMP_OFFSET_MAX1 ( 75) | ||
441 | |||
442 | /* This function is common to all 4-bit temperature offsets | ||
443 | returns 4 bits right justified | ||
444 | mode 0 => 1C/bit, mode !0 => 0.5C/bit */ | ||
445 | static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode) | ||
446 | { | ||
447 | int factor = mode ? 5 : 10; | ||
448 | |||
449 | off = SENSORS_LIMIT(off, LM93_TEMP_OFFSET_MIN, | ||
450 | mode ? LM93_TEMP_OFFSET_MAX1 : LM93_TEMP_OFFSET_MAX0); | ||
451 | return (u8)((off + factor/2) / factor); | ||
452 | } | ||
453 | |||
454 | /* 0 <= nr <= 3 */ | ||
455 | static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) | ||
456 | { | ||
457 | /* temp1-temp2 (nr=0,1) use lower nibble */ | ||
458 | if (nr < 2) | ||
459 | return LM93_TEMP_OFFSET_FROM_REG(reg & 0x0f, mode); | ||
460 | |||
461 | /* temp3-temp4 (nr=2,3) use upper nibble */ | ||
462 | else | ||
463 | return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode); | ||
464 | } | ||
465 | |||
466 | /* TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) | ||
467 | REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) | ||
468 | 0 <= nr <= 3 */ | ||
469 | static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) | ||
470 | { | ||
471 | u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); | ||
472 | |||
473 | /* temp1-temp2 (nr=0,1) use lower nibble */ | ||
474 | if (nr < 2) | ||
475 | return (old & 0xf0) | (new & 0x0f); | ||
476 | |||
477 | /* temp3-temp4 (nr=2,3) use upper nibble */ | ||
478 | else | ||
479 | return (new << 4 & 0xf0) | (old & 0x0f); | ||
480 | } | ||
481 | |||
482 | static int LM93_AUTO_BOOST_HYST_FROM_REGS(struct lm93_data *data, int nr, | ||
483 | int mode) | ||
484 | { | ||
485 | u8 reg; | ||
486 | |||
487 | switch (nr) { | ||
488 | case 0: | ||
489 | reg = data->boost_hyst[0] & 0x0f; | ||
490 | break; | ||
491 | case 1: | ||
492 | reg = data->boost_hyst[0] >> 4 & 0x0f; | ||
493 | break; | ||
494 | case 2: | ||
495 | reg = data->boost_hyst[1] & 0x0f; | ||
496 | break; | ||
497 | case 3: | ||
498 | default: | ||
499 | reg = data->boost_hyst[1] >> 4 & 0x0f; | ||
500 | break; | ||
501 | } | ||
502 | |||
503 | return LM93_TEMP_FROM_REG(data->boost[nr]) - | ||
504 | LM93_TEMP_OFFSET_FROM_REG(reg, mode); | ||
505 | } | ||
506 | |||
507 | static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst, | ||
508 | int nr, int mode) | ||
509 | { | ||
510 | u8 reg = LM93_TEMP_OFFSET_TO_REG( | ||
511 | (LM93_TEMP_FROM_REG(data->boost[nr]) - hyst), mode); | ||
512 | |||
513 | switch (nr) { | ||
514 | case 0: | ||
515 | reg = (data->boost_hyst[0] & 0xf0) | (reg & 0x0f); | ||
516 | break; | ||
517 | case 1: | ||
518 | reg = (reg << 4 & 0xf0) | (data->boost_hyst[0] & 0x0f); | ||
519 | break; | ||
520 | case 2: | ||
521 | reg = (data->boost_hyst[1] & 0xf0) | (reg & 0x0f); | ||
522 | break; | ||
523 | case 3: | ||
524 | default: | ||
525 | reg = (reg << 4 & 0xf0) | (data->boost_hyst[1] & 0x0f); | ||
526 | break; | ||
527 | } | ||
528 | |||
529 | return reg; | ||
530 | } | ||
531 | |||
532 | /* PWM: 0-255 per sensors documentation | ||
533 | REG: 0-13 as mapped below... right justified */ | ||
534 | typedef enum { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ } pwm_freq_t; | ||
535 | static int lm93_pwm_map[2][16] = { | ||
536 | { | ||
537 | 0x00, /* 0.00% */ 0x40, /* 25.00% */ | ||
538 | 0x50, /* 31.25% */ 0x60, /* 37.50% */ | ||
539 | 0x70, /* 43.75% */ 0x80, /* 50.00% */ | ||
540 | 0x90, /* 56.25% */ 0xa0, /* 62.50% */ | ||
541 | 0xb0, /* 68.75% */ 0xc0, /* 75.00% */ | ||
542 | 0xd0, /* 81.25% */ 0xe0, /* 87.50% */ | ||
543 | 0xf0, /* 93.75% */ 0xff, /* 100.00% */ | ||
544 | 0xff, 0xff, /* 14, 15 are reserved and should never occur */ | ||
545 | }, | ||
546 | { | ||
547 | 0x00, /* 0.00% */ 0x40, /* 25.00% */ | ||
548 | 0x49, /* 28.57% */ 0x52, /* 32.14% */ | ||
549 | 0x5b, /* 35.71% */ 0x64, /* 39.29% */ | ||
550 | 0x6d, /* 42.86% */ 0x76, /* 46.43% */ | ||
551 | 0x80, /* 50.00% */ 0x89, /* 53.57% */ | ||
552 | 0x92, /* 57.14% */ 0xb6, /* 71.43% */ | ||
553 | 0xdb, /* 85.71% */ 0xff, /* 100.00% */ | ||
554 | 0xff, 0xff, /* 14, 15 are reserved and should never occur */ | ||
555 | }, | ||
556 | }; | ||
557 | |||
558 | static int LM93_PWM_FROM_REG(u8 reg, pwm_freq_t freq) | ||
559 | { | ||
560 | return lm93_pwm_map[freq][reg & 0x0f]; | ||
561 | } | ||
562 | |||
563 | /* round up to nearest match */ | ||
564 | static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq) | ||
565 | { | ||
566 | int i; | ||
567 | for (i = 0; i < 13; i++) | ||
568 | if (pwm <= lm93_pwm_map[freq][i]) | ||
569 | break; | ||
570 | |||
571 | /* can fall through with i==13 */ | ||
572 | return (u8)i; | ||
573 | } | ||
574 | |||
575 | static int LM93_FAN_FROM_REG(u16 regs) | ||
576 | { | ||
577 | const u16 count = le16_to_cpu(regs) >> 2; | ||
578 | return count==0 ? -1 : count==0x3fff ? 0: 1350000 / count; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * RPM: (82.5 to 1350000) | ||
583 | * REG: 14-bits, LE, *left* justified | ||
584 | */ | ||
585 | static u16 LM93_FAN_TO_REG(long rpm) | ||
586 | { | ||
587 | u16 count, regs; | ||
588 | |||
589 | if (rpm == 0) { | ||
590 | count = 0x3fff; | ||
591 | } else { | ||
592 | rpm = SENSORS_LIMIT(rpm, 1, 1000000); | ||
593 | count = SENSORS_LIMIT((1350000 + rpm) / rpm, 1, 0x3ffe); | ||
594 | } | ||
595 | |||
596 | regs = count << 2; | ||
597 | return cpu_to_le16(regs); | ||
598 | } | ||
599 | |||
600 | /* PWM FREQ: HZ | ||
601 | REG: 0-7 as mapped below */ | ||
602 | static int lm93_pwm_freq_map[8] = { | ||
603 | 22500, 96, 84, 72, 60, 48, 36, 12 | ||
604 | }; | ||
605 | |||
606 | static int LM93_PWM_FREQ_FROM_REG(u8 reg) | ||
607 | { | ||
608 | return lm93_pwm_freq_map[reg & 0x07]; | ||
609 | } | ||
610 | |||
611 | /* round up to nearest match */ | ||
612 | static u8 LM93_PWM_FREQ_TO_REG(int freq) | ||
613 | { | ||
614 | int i; | ||
615 | for (i = 7; i > 0; i--) | ||
616 | if (freq <= lm93_pwm_freq_map[i]) | ||
617 | break; | ||
618 | |||
619 | /* can fall through with i==0 */ | ||
620 | return (u8)i; | ||
621 | } | ||
622 | |||
623 | /* TIME: 1/100 seconds | ||
624 | * REG: 0-7 as mapped below */ | ||
625 | static int lm93_spinup_time_map[8] = { | ||
626 | 0, 10, 25, 40, 70, 100, 200, 400, | ||
627 | }; | ||
628 | |||
629 | static int LM93_SPINUP_TIME_FROM_REG(u8 reg) | ||
630 | { | ||
631 | return lm93_spinup_time_map[reg >> 5 & 0x07]; | ||
632 | } | ||
633 | |||
634 | /* round up to nearest match */ | ||
635 | static u8 LM93_SPINUP_TIME_TO_REG(int time) | ||
636 | { | ||
637 | int i; | ||
638 | for (i = 0; i < 7; i++) | ||
639 | if (time <= lm93_spinup_time_map[i]) | ||
640 | break; | ||
641 | |||
642 | /* can fall through with i==8 */ | ||
643 | return (u8)i; | ||
644 | } | ||
645 | |||
646 | #define LM93_RAMP_MIN 0 | ||
647 | #define LM93_RAMP_MAX 75 | ||
648 | |||
649 | static int LM93_RAMP_FROM_REG(u8 reg) | ||
650 | { | ||
651 | return (reg & 0x0f) * 5; | ||
652 | } | ||
653 | |||
654 | /* RAMP: 1/100 seconds | ||
655 | REG: 50mS/bit 4-bits right justified */ | ||
656 | static u8 LM93_RAMP_TO_REG(int ramp) | ||
657 | { | ||
658 | ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX); | ||
659 | return (u8)((ramp + 2) / 5); | ||
660 | } | ||
661 | |||
662 | /* PROCHOT: 0-255, 0 => 0%, 255 => > 96.6% | ||
663 | * REG: (same) */ | ||
664 | static u8 LM93_PROCHOT_TO_REG(long prochot) | ||
665 | { | ||
666 | prochot = SENSORS_LIMIT(prochot, 0, 255); | ||
667 | return (u8)prochot; | ||
668 | } | ||
669 | |||
670 | /* PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) | ||
671 | * REG: 0-9 as mapped below */ | ||
672 | static int lm93_interval_map[10] = { | ||
673 | 73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200, | ||
674 | }; | ||
675 | |||
676 | static int LM93_INTERVAL_FROM_REG(u8 reg) | ||
677 | { | ||
678 | return lm93_interval_map[reg & 0x0f]; | ||
679 | } | ||
680 | |||
681 | /* round up to nearest match */ | ||
682 | static u8 LM93_INTERVAL_TO_REG(long interval) | ||
683 | { | ||
684 | int i; | ||
685 | for (i = 0; i < 9; i++) | ||
686 | if (interval <= lm93_interval_map[i]) | ||
687 | break; | ||
688 | |||
689 | /* can fall through with i==9 */ | ||
690 | return (u8)i; | ||
691 | } | ||
692 | |||
693 | /* GPIO: 0-255, GPIO0 is LSB | ||
694 | * REG: inverted */ | ||
695 | static unsigned LM93_GPI_FROM_REG(u8 reg) | ||
696 | { | ||
697 | return ~reg & 0xff; | ||
698 | } | ||
699 | |||
700 | /* alarm bitmask definitions | ||
701 | The LM93 has nearly 64 bits of error status... I've pared that down to | ||
702 | what I think is a useful subset in order to fit it into 32 bits. | ||
703 | |||
704 | Especially note that the #VRD_HOT alarms are missing because we provide | ||
705 | that information as values in another sysfs file. | ||
706 | |||
707 | If libsensors is extended to support 64 bit values, this could be revisited. | ||
708 | */ | ||
709 | #define LM93_ALARM_IN1 0x00000001 | ||
710 | #define LM93_ALARM_IN2 0x00000002 | ||
711 | #define LM93_ALARM_IN3 0x00000004 | ||
712 | #define LM93_ALARM_IN4 0x00000008 | ||
713 | #define LM93_ALARM_IN5 0x00000010 | ||
714 | #define LM93_ALARM_IN6 0x00000020 | ||
715 | #define LM93_ALARM_IN7 0x00000040 | ||
716 | #define LM93_ALARM_IN8 0x00000080 | ||
717 | #define LM93_ALARM_IN9 0x00000100 | ||
718 | #define LM93_ALARM_IN10 0x00000200 | ||
719 | #define LM93_ALARM_IN11 0x00000400 | ||
720 | #define LM93_ALARM_IN12 0x00000800 | ||
721 | #define LM93_ALARM_IN13 0x00001000 | ||
722 | #define LM93_ALARM_IN14 0x00002000 | ||
723 | #define LM93_ALARM_IN15 0x00004000 | ||
724 | #define LM93_ALARM_IN16 0x00008000 | ||
725 | #define LM93_ALARM_FAN1 0x00010000 | ||
726 | #define LM93_ALARM_FAN2 0x00020000 | ||
727 | #define LM93_ALARM_FAN3 0x00040000 | ||
728 | #define LM93_ALARM_FAN4 0x00080000 | ||
729 | #define LM93_ALARM_PH1_ERR 0x00100000 | ||
730 | #define LM93_ALARM_PH2_ERR 0x00200000 | ||
731 | #define LM93_ALARM_SCSI1_ERR 0x00400000 | ||
732 | #define LM93_ALARM_SCSI2_ERR 0x00800000 | ||
733 | #define LM93_ALARM_DVDDP1_ERR 0x01000000 | ||
734 | #define LM93_ALARM_DVDDP2_ERR 0x02000000 | ||
735 | #define LM93_ALARM_D1_ERR 0x04000000 | ||
736 | #define LM93_ALARM_D2_ERR 0x08000000 | ||
737 | #define LM93_ALARM_TEMP1 0x10000000 | ||
738 | #define LM93_ALARM_TEMP2 0x20000000 | ||
739 | #define LM93_ALARM_TEMP3 0x40000000 | ||
740 | |||
741 | static unsigned LM93_ALARMS_FROM_REG(struct block1_t b1) | ||
742 | { | ||
743 | unsigned result; | ||
744 | result = b1.host_status_2 & 0x3f; | ||
745 | |||
746 | if (vccp_limit_type[0]) | ||
747 | result |= (b1.host_status_4 & 0x10) << 2; | ||
748 | else | ||
749 | result |= b1.host_status_2 & 0x40; | ||
750 | |||
751 | if (vccp_limit_type[1]) | ||
752 | result |= (b1.host_status_4 & 0x20) << 2; | ||
753 | else | ||
754 | result |= b1.host_status_2 & 0x80; | ||
755 | |||
756 | result |= b1.host_status_3 << 8; | ||
757 | result |= (b1.fan_status & 0x0f) << 16; | ||
758 | result |= (b1.p1_prochot_status & 0x80) << 13; | ||
759 | result |= (b1.p2_prochot_status & 0x80) << 14; | ||
760 | result |= (b1.host_status_4 & 0xfc) << 20; | ||
761 | result |= (b1.host_status_1 & 0x07) << 28; | ||
762 | return result; | ||
763 | } | ||
764 | |||
765 | #define MAX_RETRIES 5 | ||
766 | |||
767 | static u8 lm93_read_byte(struct i2c_client *client, u8 reg) | ||
768 | { | ||
769 | int value, i; | ||
770 | |||
771 | /* retry in case of read errors */ | ||
772 | for (i=1; i<=MAX_RETRIES; i++) { | ||
773 | if ((value = i2c_smbus_read_byte_data(client, reg)) >= 0) { | ||
774 | return value; | ||
775 | } else { | ||
776 | dev_warn(&client->dev,"lm93: read byte data failed, " | ||
777 | "address 0x%02x.\n", reg); | ||
778 | mdelay(i + 3); | ||
779 | } | ||
780 | |||
781 | } | ||
782 | |||
783 | /* <TODO> what to return in case of error? */ | ||
784 | dev_err(&client->dev,"lm93: All read byte retries failed!!\n"); | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) | ||
789 | { | ||
790 | int result; | ||
791 | |||
792 | /* <TODO> how to handle write errors? */ | ||
793 | result = i2c_smbus_write_byte_data(client, reg, value); | ||
794 | |||
795 | if (result < 0) | ||
796 | dev_warn(&client->dev,"lm93: write byte data failed, " | ||
797 | "0x%02x at address 0x%02x.\n", value, reg); | ||
798 | |||
799 | return result; | ||
800 | } | ||
801 | |||
802 | static u16 lm93_read_word(struct i2c_client *client, u8 reg) | ||
803 | { | ||
804 | int value, i; | ||
805 | |||
806 | /* retry in case of read errors */ | ||
807 | for (i=1; i<=MAX_RETRIES; i++) { | ||
808 | if ((value = i2c_smbus_read_word_data(client, reg)) >= 0) { | ||
809 | return value; | ||
810 | } else { | ||
811 | dev_warn(&client->dev,"lm93: read word data failed, " | ||
812 | "address 0x%02x.\n", reg); | ||
813 | mdelay(i + 3); | ||
814 | } | ||
815 | |||
816 | } | ||
817 | |||
818 | /* <TODO> what to return in case of error? */ | ||
819 | dev_err(&client->dev,"lm93: All read word retries failed!!\n"); | ||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) | ||
824 | { | ||
825 | int result; | ||
826 | |||
827 | /* <TODO> how to handle write errors? */ | ||
828 | result = i2c_smbus_write_word_data(client, reg, value); | ||
829 | |||
830 | if (result < 0) | ||
831 | dev_warn(&client->dev,"lm93: write word data failed, " | ||
832 | "0x%04x at address 0x%02x.\n", value, reg); | ||
833 | |||
834 | return result; | ||
835 | } | ||
836 | |||
837 | static u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX]; | ||
838 | |||
839 | /* | ||
840 | read block data into values, retry if not expected length | ||
841 | fbn => index to lm93_block_read_cmds table | ||
842 | (Fixed Block Number - section 14.5.2 of LM93 datasheet) | ||
843 | */ | ||
844 | static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) | ||
845 | { | ||
846 | int i, result=0; | ||
847 | |||
848 | for (i = 1; i <= MAX_RETRIES; i++) { | ||
849 | result = i2c_smbus_read_block_data(client, | ||
850 | lm93_block_read_cmds[fbn].cmd, lm93_block_buffer); | ||
851 | |||
852 | if (result == lm93_block_read_cmds[fbn].len) { | ||
853 | break; | ||
854 | } else { | ||
855 | dev_warn(&client->dev,"lm93: block read data failed, " | ||
856 | "command 0x%02x.\n", | ||
857 | lm93_block_read_cmds[fbn].cmd); | ||
858 | mdelay(i + 3); | ||
859 | } | ||
860 | } | ||
861 | |||
862 | if (result == lm93_block_read_cmds[fbn].len) { | ||
863 | memcpy(values,lm93_block_buffer,lm93_block_read_cmds[fbn].len); | ||
864 | } else { | ||
865 | /* <TODO> what to do in case of error? */ | ||
866 | } | ||
867 | } | ||
868 | |||
869 | static struct lm93_data *lm93_update_device(struct device *dev) | ||
870 | { | ||
871 | struct i2c_client *client = to_i2c_client(dev); | ||
872 | struct lm93_data *data = i2c_get_clientdata(client); | ||
873 | const unsigned long interval = HZ + (HZ / 2); | ||
874 | |||
875 | mutex_lock(&data->update_lock); | ||
876 | |||
877 | if (time_after(jiffies, data->last_updated + interval) || | ||
878 | !data->valid) { | ||
879 | |||
880 | data->update(data, client); | ||
881 | data->last_updated = jiffies; | ||
882 | data->valid = 1; | ||
883 | } | ||
884 | |||
885 | mutex_unlock(&data->update_lock); | ||
886 | return data; | ||
887 | } | ||
888 | |||
889 | /* update routine for data that has no corresponding SMBus block command */ | ||
890 | static void lm93_update_client_common(struct lm93_data *data, | ||
891 | struct i2c_client *client) | ||
892 | { | ||
893 | int i; | ||
894 | u8 *ptr; | ||
895 | |||
896 | /* temp1 - temp4: limits */ | ||
897 | for (i = 0; i < 4; i++) { | ||
898 | data->temp_lim[i].min = | ||
899 | lm93_read_byte(client, LM93_REG_TEMP_MIN(i)); | ||
900 | data->temp_lim[i].max = | ||
901 | lm93_read_byte(client, LM93_REG_TEMP_MAX(i)); | ||
902 | } | ||
903 | |||
904 | /* config register */ | ||
905 | data->config = lm93_read_byte(client, LM93_REG_CONFIG); | ||
906 | |||
907 | /* vid1 - vid2: values */ | ||
908 | for (i = 0; i < 2; i++) | ||
909 | data->vid[i] = lm93_read_byte(client, LM93_REG_VID(i)); | ||
910 | |||
911 | /* prochot1 - prochot2: limits */ | ||
912 | for (i = 0; i < 2; i++) | ||
913 | data->prochot_max[i] = lm93_read_byte(client, | ||
914 | LM93_REG_PROCHOT_MAX(i)); | ||
915 | |||
916 | /* vccp1 - vccp2: VID relative limits */ | ||
917 | for (i = 0; i < 2; i++) | ||
918 | data->vccp_limits[i] = lm93_read_byte(client, | ||
919 | LM93_REG_VCCP_LIMIT_OFF(i)); | ||
920 | |||
921 | /* GPIO input state */ | ||
922 | data->gpi = lm93_read_byte(client, LM93_REG_GPI); | ||
923 | |||
924 | /* #PROCHOT override state */ | ||
925 | data->prochot_override = lm93_read_byte(client, | ||
926 | LM93_REG_PROCHOT_OVERRIDE); | ||
927 | |||
928 | /* #PROCHOT intervals */ | ||
929 | data->prochot_interval = lm93_read_byte(client, | ||
930 | LM93_REG_PROCHOT_INTERVAL); | ||
931 | |||
932 | /* Fan Boost Termperature registers */ | ||
933 | for (i = 0; i < 4; i++) | ||
934 | data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i)); | ||
935 | |||
936 | /* Fan Boost Temperature Hyst. registers */ | ||
937 | data->boost_hyst[0] = lm93_read_byte(client, LM93_REG_BOOST_HYST_12); | ||
938 | data->boost_hyst[1] = lm93_read_byte(client, LM93_REG_BOOST_HYST_34); | ||
939 | |||
940 | /* Temperature Zone Min. PWM & Hysteresis registers */ | ||
941 | data->auto_pwm_min_hyst[0] = | ||
942 | lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_12); | ||
943 | data->auto_pwm_min_hyst[1] = | ||
944 | lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_34); | ||
945 | |||
946 | /* #PROCHOT & #VRDHOT PWM Ramp Control register */ | ||
947 | data->pwm_ramp_ctl = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
948 | |||
949 | /* misc setup registers */ | ||
950 | data->sfc1 = lm93_read_byte(client, LM93_REG_SFC1); | ||
951 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
952 | data->sf_tach_to_pwm = lm93_read_byte(client, | ||
953 | LM93_REG_SF_TACH_TO_PWM); | ||
954 | |||
955 | /* write back alarm values to clear */ | ||
956 | for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) | ||
957 | lm93_write_byte(client, LM93_REG_HOST_ERROR_1 + i, *(ptr + i)); | ||
958 | } | ||
959 | |||
960 | /* update routine which uses SMBus block data commands */ | ||
961 | static void lm93_update_client_full(struct lm93_data *data, | ||
962 | struct i2c_client *client) | ||
963 | { | ||
964 | dev_dbg(&client->dev,"starting device update (block data enabled)\n"); | ||
965 | |||
966 | /* in1 - in16: values & limits */ | ||
967 | lm93_read_block(client, 3, (u8 *)(data->block3)); | ||
968 | lm93_read_block(client, 7, (u8 *)(data->block7)); | ||
969 | |||
970 | /* temp1 - temp4: values */ | ||
971 | lm93_read_block(client, 2, (u8 *)(data->block2)); | ||
972 | |||
973 | /* prochot1 - prochot2: values */ | ||
974 | lm93_read_block(client, 4, (u8 *)(data->block4)); | ||
975 | |||
976 | /* fan1 - fan4: values & limits */ | ||
977 | lm93_read_block(client, 5, (u8 *)(data->block5)); | ||
978 | lm93_read_block(client, 8, (u8 *)(data->block8)); | ||
979 | |||
980 | /* pmw control registers */ | ||
981 | lm93_read_block(client, 9, (u8 *)(data->block9)); | ||
982 | |||
983 | /* alarm values */ | ||
984 | lm93_read_block(client, 1, (u8 *)(&data->block1)); | ||
985 | |||
986 | /* auto/pwm registers */ | ||
987 | lm93_read_block(client, 10, (u8 *)(&data->block10)); | ||
988 | |||
989 | lm93_update_client_common(data, client); | ||
990 | } | ||
991 | |||
992 | /* update routine which uses SMBus byte/word data commands only */ | ||
993 | static void lm93_update_client_min(struct lm93_data *data, | ||
994 | struct i2c_client *client) | ||
995 | { | ||
996 | int i,j; | ||
997 | u8 *ptr; | ||
998 | |||
999 | dev_dbg(&client->dev,"starting device update (block data disabled)\n"); | ||
1000 | |||
1001 | /* in1 - in16: values & limits */ | ||
1002 | for (i = 0; i < 16; i++) { | ||
1003 | data->block3[i] = | ||
1004 | lm93_read_byte(client, LM93_REG_IN(i)); | ||
1005 | data->block7[i].min = | ||
1006 | lm93_read_byte(client, LM93_REG_IN_MIN(i)); | ||
1007 | data->block7[i].max = | ||
1008 | lm93_read_byte(client, LM93_REG_IN_MAX(i)); | ||
1009 | } | ||
1010 | |||
1011 | /* temp1 - temp4: values */ | ||
1012 | for (i = 0; i < 4; i++) { | ||
1013 | data->block2[i] = | ||
1014 | lm93_read_byte(client, LM93_REG_TEMP(i)); | ||
1015 | } | ||
1016 | |||
1017 | /* prochot1 - prochot2: values */ | ||
1018 | for (i = 0; i < 2; i++) { | ||
1019 | data->block4[i].cur = | ||
1020 | lm93_read_byte(client, LM93_REG_PROCHOT_CUR(i)); | ||
1021 | data->block4[i].avg = | ||
1022 | lm93_read_byte(client, LM93_REG_PROCHOT_AVG(i)); | ||
1023 | } | ||
1024 | |||
1025 | /* fan1 - fan4: values & limits */ | ||
1026 | for (i = 0; i < 4; i++) { | ||
1027 | data->block5[i] = | ||
1028 | lm93_read_word(client, LM93_REG_FAN(i)); | ||
1029 | data->block8[i] = | ||
1030 | lm93_read_word(client, LM93_REG_FAN_MIN(i)); | ||
1031 | } | ||
1032 | |||
1033 | /* pwm control registers */ | ||
1034 | for (i = 0; i < 2; i++) { | ||
1035 | for (j = 0; j < 4; j++) { | ||
1036 | data->block9[i][j] = | ||
1037 | lm93_read_byte(client, LM93_REG_PWM_CTL(i,j)); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | /* alarm values */ | ||
1042 | for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) { | ||
1043 | *(ptr + i) = | ||
1044 | lm93_read_byte(client, LM93_REG_HOST_ERROR_1 + i); | ||
1045 | } | ||
1046 | |||
1047 | /* auto/pwm (base temp) registers */ | ||
1048 | for (i = 0; i < 4; i++) { | ||
1049 | data->block10.base[i] = | ||
1050 | lm93_read_byte(client, LM93_REG_TEMP_BASE(i)); | ||
1051 | } | ||
1052 | |||
1053 | /* auto/pwm (offset temp) registers */ | ||
1054 | for (i = 0; i < 12; i++) { | ||
1055 | data->block10.offset[i] = | ||
1056 | lm93_read_byte(client, LM93_REG_TEMP_OFFSET(i)); | ||
1057 | } | ||
1058 | |||
1059 | lm93_update_client_common(data, client); | ||
1060 | } | ||
1061 | |||
1062 | /* following are the sysfs callback functions */ | ||
1063 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
1064 | char *buf) | ||
1065 | { | ||
1066 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1067 | |||
1068 | struct lm93_data *data = lm93_update_device(dev); | ||
1069 | return sprintf(buf, "%d\n", LM93_IN_FROM_REG(nr, data->block3[nr])); | ||
1070 | } | ||
1071 | |||
1072 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 0); | ||
1073 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 1); | ||
1074 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 2); | ||
1075 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 3); | ||
1076 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 4); | ||
1077 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 5); | ||
1078 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 6); | ||
1079 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 7); | ||
1080 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in, NULL, 8); | ||
1081 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in, NULL, 9); | ||
1082 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_in, NULL, 10); | ||
1083 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_in, NULL, 11); | ||
1084 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_in, NULL, 12); | ||
1085 | static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_in, NULL, 13); | ||
1086 | static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_in, NULL, 14); | ||
1087 | static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in, NULL, 15); | ||
1088 | |||
1089 | static ssize_t show_in_min(struct device *dev, | ||
1090 | struct device_attribute *attr, char *buf) | ||
1091 | { | ||
1092 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1093 | struct lm93_data *data = lm93_update_device(dev); | ||
1094 | int vccp = nr - 6; | ||
1095 | long rc, vid; | ||
1096 | |||
1097 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
1098 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
1099 | rc = LM93_IN_MIN_FROM_REG(data->vccp_limits[vccp], vid); | ||
1100 | } | ||
1101 | else { | ||
1102 | rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); \ | ||
1103 | } | ||
1104 | return sprintf(buf, "%ld\n", rc); \ | ||
1105 | } | ||
1106 | |||
1107 | static ssize_t store_in_min(struct device *dev, struct device_attribute *attr, | ||
1108 | const char *buf, size_t count) | ||
1109 | { | ||
1110 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1111 | struct i2c_client *client = to_i2c_client(dev); | ||
1112 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1113 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1114 | int vccp = nr - 6; | ||
1115 | long vid; | ||
1116 | |||
1117 | mutex_lock(&data->update_lock); | ||
1118 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
1119 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
1120 | data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0xf0) | | ||
1121 | LM93_IN_REL_TO_REG(val, 0, vid); | ||
1122 | lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), | ||
1123 | data->vccp_limits[vccp]); | ||
1124 | } | ||
1125 | else { | ||
1126 | data->block7[nr].min = LM93_IN_TO_REG(nr,val); | ||
1127 | lm93_write_byte(client, LM93_REG_IN_MIN(nr), | ||
1128 | data->block7[nr].min); | ||
1129 | } | ||
1130 | mutex_unlock(&data->update_lock); | ||
1131 | return count; | ||
1132 | } | ||
1133 | |||
1134 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, | ||
1135 | show_in_min, store_in_min, 0); | ||
1136 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, | ||
1137 | show_in_min, store_in_min, 1); | ||
1138 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, | ||
1139 | show_in_min, store_in_min, 2); | ||
1140 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, | ||
1141 | show_in_min, store_in_min, 3); | ||
1142 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, | ||
1143 | show_in_min, store_in_min, 4); | ||
1144 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, | ||
1145 | show_in_min, store_in_min, 5); | ||
1146 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, | ||
1147 | show_in_min, store_in_min, 6); | ||
1148 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, | ||
1149 | show_in_min, store_in_min, 7); | ||
1150 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, | ||
1151 | show_in_min, store_in_min, 8); | ||
1152 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, | ||
1153 | show_in_min, store_in_min, 9); | ||
1154 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, | ||
1155 | show_in_min, store_in_min, 10); | ||
1156 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, | ||
1157 | show_in_min, store_in_min, 11); | ||
1158 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, | ||
1159 | show_in_min, store_in_min, 12); | ||
1160 | static SENSOR_DEVICE_ATTR(in14_min, S_IWUSR | S_IRUGO, | ||
1161 | show_in_min, store_in_min, 13); | ||
1162 | static SENSOR_DEVICE_ATTR(in15_min, S_IWUSR | S_IRUGO, | ||
1163 | show_in_min, store_in_min, 14); | ||
1164 | static SENSOR_DEVICE_ATTR(in16_min, S_IWUSR | S_IRUGO, | ||
1165 | show_in_min, store_in_min, 15); | ||
1166 | |||
1167 | static ssize_t show_in_max(struct device *dev, | ||
1168 | struct device_attribute *attr, char *buf) | ||
1169 | { | ||
1170 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1171 | struct lm93_data *data = lm93_update_device(dev); | ||
1172 | int vccp = nr - 6; | ||
1173 | long rc, vid; | ||
1174 | |||
1175 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
1176 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
1177 | rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp],vid); | ||
1178 | } | ||
1179 | else { | ||
1180 | rc = LM93_IN_FROM_REG(nr,data->block7[nr].max); \ | ||
1181 | } | ||
1182 | return sprintf(buf,"%ld\n",rc); \ | ||
1183 | } | ||
1184 | |||
1185 | static ssize_t store_in_max(struct device *dev, struct device_attribute *attr, | ||
1186 | const char *buf, size_t count) | ||
1187 | { | ||
1188 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1189 | struct i2c_client *client = to_i2c_client(dev); | ||
1190 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1191 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1192 | int vccp = nr - 6; | ||
1193 | long vid; | ||
1194 | |||
1195 | mutex_lock(&data->update_lock); | ||
1196 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
1197 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
1198 | data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0x0f) | | ||
1199 | LM93_IN_REL_TO_REG(val, 1, vid); | ||
1200 | lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), | ||
1201 | data->vccp_limits[vccp]); | ||
1202 | } | ||
1203 | else { | ||
1204 | data->block7[nr].max = LM93_IN_TO_REG(nr,val); | ||
1205 | lm93_write_byte(client, LM93_REG_IN_MAX(nr), | ||
1206 | data->block7[nr].max); | ||
1207 | } | ||
1208 | mutex_unlock(&data->update_lock); | ||
1209 | return count; | ||
1210 | } | ||
1211 | |||
1212 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, | ||
1213 | show_in_max, store_in_max, 0); | ||
1214 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, | ||
1215 | show_in_max, store_in_max, 1); | ||
1216 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, | ||
1217 | show_in_max, store_in_max, 2); | ||
1218 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, | ||
1219 | show_in_max, store_in_max, 3); | ||
1220 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, | ||
1221 | show_in_max, store_in_max, 4); | ||
1222 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, | ||
1223 | show_in_max, store_in_max, 5); | ||
1224 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, | ||
1225 | show_in_max, store_in_max, 6); | ||
1226 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, | ||
1227 | show_in_max, store_in_max, 7); | ||
1228 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, | ||
1229 | show_in_max, store_in_max, 8); | ||
1230 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, | ||
1231 | show_in_max, store_in_max, 9); | ||
1232 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, | ||
1233 | show_in_max, store_in_max, 10); | ||
1234 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, | ||
1235 | show_in_max, store_in_max, 11); | ||
1236 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, | ||
1237 | show_in_max, store_in_max, 12); | ||
1238 | static SENSOR_DEVICE_ATTR(in14_max, S_IWUSR | S_IRUGO, | ||
1239 | show_in_max, store_in_max, 13); | ||
1240 | static SENSOR_DEVICE_ATTR(in15_max, S_IWUSR | S_IRUGO, | ||
1241 | show_in_max, store_in_max, 14); | ||
1242 | static SENSOR_DEVICE_ATTR(in16_max, S_IWUSR | S_IRUGO, | ||
1243 | show_in_max, store_in_max, 15); | ||
1244 | |||
1245 | static ssize_t show_temp(struct device *dev, | ||
1246 | struct device_attribute *attr, char *buf) | ||
1247 | { | ||
1248 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1249 | struct lm93_data *data = lm93_update_device(dev); | ||
1250 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block2[nr])); | ||
1251 | } | ||
1252 | |||
1253 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
1254 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
1255 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
1256 | |||
1257 | static ssize_t show_temp_min(struct device *dev, | ||
1258 | struct device_attribute *attr, char *buf) | ||
1259 | { | ||
1260 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1261 | struct lm93_data *data = lm93_update_device(dev); | ||
1262 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].min)); | ||
1263 | } | ||
1264 | |||
1265 | static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, | ||
1266 | const char *buf, size_t count) | ||
1267 | { | ||
1268 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1269 | struct i2c_client *client = to_i2c_client(dev); | ||
1270 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1271 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1272 | |||
1273 | mutex_lock(&data->update_lock); | ||
1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); | ||
1275 | lm93_write_byte(client, LM93_REG_TEMP_MIN(nr), data->temp_lim[nr].min); | ||
1276 | mutex_unlock(&data->update_lock); | ||
1277 | return count; | ||
1278 | } | ||
1279 | |||
1280 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
1281 | show_temp_min, store_temp_min, 0); | ||
1282 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, | ||
1283 | show_temp_min, store_temp_min, 1); | ||
1284 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, | ||
1285 | show_temp_min, store_temp_min, 2); | ||
1286 | |||
1287 | static ssize_t show_temp_max(struct device *dev, | ||
1288 | struct device_attribute *attr, char *buf) | ||
1289 | { | ||
1290 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1291 | struct lm93_data *data = lm93_update_device(dev); | ||
1292 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].max)); | ||
1293 | } | ||
1294 | |||
1295 | static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, | ||
1296 | const char *buf, size_t count) | ||
1297 | { | ||
1298 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1299 | struct i2c_client *client = to_i2c_client(dev); | ||
1300 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1301 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1302 | |||
1303 | mutex_lock(&data->update_lock); | ||
1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); | ||
1305 | lm93_write_byte(client, LM93_REG_TEMP_MAX(nr), data->temp_lim[nr].max); | ||
1306 | mutex_unlock(&data->update_lock); | ||
1307 | return count; | ||
1308 | } | ||
1309 | |||
1310 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
1311 | show_temp_max, store_temp_max, 0); | ||
1312 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, | ||
1313 | show_temp_max, store_temp_max, 1); | ||
1314 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, | ||
1315 | show_temp_max, store_temp_max, 2); | ||
1316 | |||
1317 | static ssize_t show_temp_auto_base(struct device *dev, | ||
1318 | struct device_attribute *attr, char *buf) | ||
1319 | { | ||
1320 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1321 | struct lm93_data *data = lm93_update_device(dev); | ||
1322 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block10.base[nr])); | ||
1323 | } | ||
1324 | |||
1325 | static ssize_t store_temp_auto_base(struct device *dev, | ||
1326 | struct device_attribute *attr, | ||
1327 | const char *buf, size_t count) | ||
1328 | { | ||
1329 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1330 | struct i2c_client *client = to_i2c_client(dev); | ||
1331 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1332 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1333 | |||
1334 | mutex_lock(&data->update_lock); | ||
1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); | ||
1336 | lm93_write_byte(client, LM93_REG_TEMP_BASE(nr), data->block10.base[nr]); | ||
1337 | mutex_unlock(&data->update_lock); | ||
1338 | return count; | ||
1339 | } | ||
1340 | |||
1341 | static SENSOR_DEVICE_ATTR(temp1_auto_base, S_IWUSR | S_IRUGO, | ||
1342 | show_temp_auto_base, store_temp_auto_base, 0); | ||
1343 | static SENSOR_DEVICE_ATTR(temp2_auto_base, S_IWUSR | S_IRUGO, | ||
1344 | show_temp_auto_base, store_temp_auto_base, 1); | ||
1345 | static SENSOR_DEVICE_ATTR(temp3_auto_base, S_IWUSR | S_IRUGO, | ||
1346 | show_temp_auto_base, store_temp_auto_base, 2); | ||
1347 | |||
1348 | static ssize_t show_temp_auto_boost(struct device *dev, | ||
1349 | struct device_attribute *attr,char *buf) | ||
1350 | { | ||
1351 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1352 | struct lm93_data *data = lm93_update_device(dev); | ||
1353 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->boost[nr])); | ||
1354 | } | ||
1355 | |||
1356 | static ssize_t store_temp_auto_boost(struct device *dev, | ||
1357 | struct device_attribute *attr, | ||
1358 | const char *buf, size_t count) | ||
1359 | { | ||
1360 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1361 | struct i2c_client *client = to_i2c_client(dev); | ||
1362 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1363 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1364 | |||
1365 | mutex_lock(&data->update_lock); | ||
1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); | ||
1367 | lm93_write_byte(client, LM93_REG_BOOST(nr), data->boost[nr]); | ||
1368 | mutex_unlock(&data->update_lock); | ||
1369 | return count; | ||
1370 | } | ||
1371 | |||
1372 | static SENSOR_DEVICE_ATTR(temp1_auto_boost, S_IWUSR | S_IRUGO, | ||
1373 | show_temp_auto_boost, store_temp_auto_boost, 0); | ||
1374 | static SENSOR_DEVICE_ATTR(temp2_auto_boost, S_IWUSR | S_IRUGO, | ||
1375 | show_temp_auto_boost, store_temp_auto_boost, 1); | ||
1376 | static SENSOR_DEVICE_ATTR(temp3_auto_boost, S_IWUSR | S_IRUGO, | ||
1377 | show_temp_auto_boost, store_temp_auto_boost, 2); | ||
1378 | |||
1379 | static ssize_t show_temp_auto_boost_hyst(struct device *dev, | ||
1380 | struct device_attribute *attr, | ||
1381 | char *buf) | ||
1382 | { | ||
1383 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1384 | struct lm93_data *data = lm93_update_device(dev); | ||
1385 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
1386 | return sprintf(buf,"%d\n", | ||
1387 | LM93_AUTO_BOOST_HYST_FROM_REGS(data, nr, mode)); | ||
1388 | } | ||
1389 | |||
1390 | static ssize_t store_temp_auto_boost_hyst(struct device *dev, | ||
1391 | struct device_attribute *attr, | ||
1392 | const char *buf, size_t count) | ||
1393 | { | ||
1394 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1395 | struct i2c_client *client = to_i2c_client(dev); | ||
1396 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1397 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1398 | |||
1399 | mutex_lock(&data->update_lock); | ||
1400 | /* force 0.5C/bit mode */ | ||
1401 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
1402 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
1403 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
1404 | data->boost_hyst[nr/2] = LM93_AUTO_BOOST_HYST_TO_REG(data, val, nr, 1); | ||
1405 | lm93_write_byte(client, LM93_REG_BOOST_HYST(nr), | ||
1406 | data->boost_hyst[nr/2]); | ||
1407 | mutex_unlock(&data->update_lock); | ||
1408 | return count; | ||
1409 | } | ||
1410 | |||
1411 | static SENSOR_DEVICE_ATTR(temp1_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
1412 | show_temp_auto_boost_hyst, | ||
1413 | store_temp_auto_boost_hyst, 0); | ||
1414 | static SENSOR_DEVICE_ATTR(temp2_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
1415 | show_temp_auto_boost_hyst, | ||
1416 | store_temp_auto_boost_hyst, 1); | ||
1417 | static SENSOR_DEVICE_ATTR(temp3_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
1418 | show_temp_auto_boost_hyst, | ||
1419 | store_temp_auto_boost_hyst, 2); | ||
1420 | |||
1421 | static ssize_t show_temp_auto_offset(struct device *dev, | ||
1422 | struct device_attribute *attr, char *buf) | ||
1423 | { | ||
1424 | struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); | ||
1425 | int nr = s_attr->index; | ||
1426 | int ofs = s_attr->nr; | ||
1427 | struct lm93_data *data = lm93_update_device(dev); | ||
1428 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
1429 | return sprintf(buf,"%d\n", | ||
1430 | LM93_TEMP_AUTO_OFFSET_FROM_REG(data->block10.offset[ofs], | ||
1431 | nr,mode)); | ||
1432 | } | ||
1433 | |||
1434 | static ssize_t store_temp_auto_offset(struct device *dev, | ||
1435 | struct device_attribute *attr, | ||
1436 | const char *buf, size_t count) | ||
1437 | { | ||
1438 | struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); | ||
1439 | int nr = s_attr->index; | ||
1440 | int ofs = s_attr->nr; | ||
1441 | struct i2c_client *client = to_i2c_client(dev); | ||
1442 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1443 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1444 | |||
1445 | mutex_lock(&data->update_lock); | ||
1446 | /* force 0.5C/bit mode */ | ||
1447 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
1448 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
1449 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
1450 | data->block10.offset[ofs] = LM93_TEMP_AUTO_OFFSET_TO_REG( | ||
1451 | data->block10.offset[ofs], val, nr, 1); | ||
1452 | lm93_write_byte(client, LM93_REG_TEMP_OFFSET(ofs), | ||
1453 | data->block10.offset[ofs]); | ||
1454 | mutex_unlock(&data->update_lock); | ||
1455 | return count; | ||
1456 | } | ||
1457 | |||
1458 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset1, S_IWUSR | S_IRUGO, | ||
1459 | show_temp_auto_offset, store_temp_auto_offset, 0, 0); | ||
1460 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset2, S_IWUSR | S_IRUGO, | ||
1461 | show_temp_auto_offset, store_temp_auto_offset, 1, 0); | ||
1462 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset3, S_IWUSR | S_IRUGO, | ||
1463 | show_temp_auto_offset, store_temp_auto_offset, 2, 0); | ||
1464 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset4, S_IWUSR | S_IRUGO, | ||
1465 | show_temp_auto_offset, store_temp_auto_offset, 3, 0); | ||
1466 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset5, S_IWUSR | S_IRUGO, | ||
1467 | show_temp_auto_offset, store_temp_auto_offset, 4, 0); | ||
1468 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset6, S_IWUSR | S_IRUGO, | ||
1469 | show_temp_auto_offset, store_temp_auto_offset, 5, 0); | ||
1470 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset7, S_IWUSR | S_IRUGO, | ||
1471 | show_temp_auto_offset, store_temp_auto_offset, 6, 0); | ||
1472 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset8, S_IWUSR | S_IRUGO, | ||
1473 | show_temp_auto_offset, store_temp_auto_offset, 7, 0); | ||
1474 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset9, S_IWUSR | S_IRUGO, | ||
1475 | show_temp_auto_offset, store_temp_auto_offset, 8, 0); | ||
1476 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset10, S_IWUSR | S_IRUGO, | ||
1477 | show_temp_auto_offset, store_temp_auto_offset, 9, 0); | ||
1478 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset11, S_IWUSR | S_IRUGO, | ||
1479 | show_temp_auto_offset, store_temp_auto_offset, 10, 0); | ||
1480 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset12, S_IWUSR | S_IRUGO, | ||
1481 | show_temp_auto_offset, store_temp_auto_offset, 11, 0); | ||
1482 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset1, S_IWUSR | S_IRUGO, | ||
1483 | show_temp_auto_offset, store_temp_auto_offset, 0, 1); | ||
1484 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset2, S_IWUSR | S_IRUGO, | ||
1485 | show_temp_auto_offset, store_temp_auto_offset, 1, 1); | ||
1486 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset3, S_IWUSR | S_IRUGO, | ||
1487 | show_temp_auto_offset, store_temp_auto_offset, 2, 1); | ||
1488 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset4, S_IWUSR | S_IRUGO, | ||
1489 | show_temp_auto_offset, store_temp_auto_offset, 3, 1); | ||
1490 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset5, S_IWUSR | S_IRUGO, | ||
1491 | show_temp_auto_offset, store_temp_auto_offset, 4, 1); | ||
1492 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset6, S_IWUSR | S_IRUGO, | ||
1493 | show_temp_auto_offset, store_temp_auto_offset, 5, 1); | ||
1494 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset7, S_IWUSR | S_IRUGO, | ||
1495 | show_temp_auto_offset, store_temp_auto_offset, 6, 1); | ||
1496 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset8, S_IWUSR | S_IRUGO, | ||
1497 | show_temp_auto_offset, store_temp_auto_offset, 7, 1); | ||
1498 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset9, S_IWUSR | S_IRUGO, | ||
1499 | show_temp_auto_offset, store_temp_auto_offset, 8, 1); | ||
1500 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset10, S_IWUSR | S_IRUGO, | ||
1501 | show_temp_auto_offset, store_temp_auto_offset, 9, 1); | ||
1502 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset11, S_IWUSR | S_IRUGO, | ||
1503 | show_temp_auto_offset, store_temp_auto_offset, 10, 1); | ||
1504 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset12, S_IWUSR | S_IRUGO, | ||
1505 | show_temp_auto_offset, store_temp_auto_offset, 11, 1); | ||
1506 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset1, S_IWUSR | S_IRUGO, | ||
1507 | show_temp_auto_offset, store_temp_auto_offset, 0, 2); | ||
1508 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset2, S_IWUSR | S_IRUGO, | ||
1509 | show_temp_auto_offset, store_temp_auto_offset, 1, 2); | ||
1510 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset3, S_IWUSR | S_IRUGO, | ||
1511 | show_temp_auto_offset, store_temp_auto_offset, 2, 2); | ||
1512 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset4, S_IWUSR | S_IRUGO, | ||
1513 | show_temp_auto_offset, store_temp_auto_offset, 3, 2); | ||
1514 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset5, S_IWUSR | S_IRUGO, | ||
1515 | show_temp_auto_offset, store_temp_auto_offset, 4, 2); | ||
1516 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset6, S_IWUSR | S_IRUGO, | ||
1517 | show_temp_auto_offset, store_temp_auto_offset, 5, 2); | ||
1518 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset7, S_IWUSR | S_IRUGO, | ||
1519 | show_temp_auto_offset, store_temp_auto_offset, 6, 2); | ||
1520 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset8, S_IWUSR | S_IRUGO, | ||
1521 | show_temp_auto_offset, store_temp_auto_offset, 7, 2); | ||
1522 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset9, S_IWUSR | S_IRUGO, | ||
1523 | show_temp_auto_offset, store_temp_auto_offset, 8, 2); | ||
1524 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset10, S_IWUSR | S_IRUGO, | ||
1525 | show_temp_auto_offset, store_temp_auto_offset, 9, 2); | ||
1526 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset11, S_IWUSR | S_IRUGO, | ||
1527 | show_temp_auto_offset, store_temp_auto_offset, 10, 2); | ||
1528 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset12, S_IWUSR | S_IRUGO, | ||
1529 | show_temp_auto_offset, store_temp_auto_offset, 11, 2); | ||
1530 | |||
1531 | static ssize_t show_temp_auto_pwm_min(struct device *dev, | ||
1532 | struct device_attribute *attr, char *buf) | ||
1533 | { | ||
1534 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1535 | u8 reg, ctl4; | ||
1536 | struct lm93_data *data = lm93_update_device(dev); | ||
1537 | reg = data->auto_pwm_min_hyst[nr/2] >> 4 & 0x0f; | ||
1538 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
1539 | return sprintf(buf,"%d\n",LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ? | ||
1540 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); | ||
1541 | } | ||
1542 | |||
1543 | static ssize_t store_temp_auto_pwm_min(struct device *dev, | ||
1544 | struct device_attribute *attr, | ||
1545 | const char *buf, size_t count) | ||
1546 | { | ||
1547 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1548 | struct i2c_client *client = to_i2c_client(dev); | ||
1549 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1550 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1551 | u8 reg, ctl4; | ||
1552 | |||
1553 | mutex_lock(&data->update_lock); | ||
1554 | reg = lm93_read_byte(client, LM93_REG_PWM_MIN_HYST(nr)); | ||
1555 | ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
1556 | reg = (reg & 0x0f) | | ||
1557 | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? | ||
1558 | LM93_PWM_MAP_LO_FREQ : | ||
1559 | LM93_PWM_MAP_HI_FREQ) << 4; | ||
1560 | data->auto_pwm_min_hyst[nr/2] = reg; | ||
1561 | lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); | ||
1562 | mutex_unlock(&data->update_lock); | ||
1563 | return count; | ||
1564 | } | ||
1565 | |||
1566 | static SENSOR_DEVICE_ATTR(temp1_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
1567 | show_temp_auto_pwm_min, | ||
1568 | store_temp_auto_pwm_min, 0); | ||
1569 | static SENSOR_DEVICE_ATTR(temp2_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
1570 | show_temp_auto_pwm_min, | ||
1571 | store_temp_auto_pwm_min, 1); | ||
1572 | static SENSOR_DEVICE_ATTR(temp3_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
1573 | show_temp_auto_pwm_min, | ||
1574 | store_temp_auto_pwm_min, 2); | ||
1575 | |||
1576 | static ssize_t show_temp_auto_offset_hyst(struct device *dev, | ||
1577 | struct device_attribute *attr, char *buf) | ||
1578 | { | ||
1579 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1580 | struct lm93_data *data = lm93_update_device(dev); | ||
1581 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
1582 | return sprintf(buf,"%d\n",LM93_TEMP_OFFSET_FROM_REG( | ||
1583 | data->auto_pwm_min_hyst[nr/2], mode)); | ||
1584 | } | ||
1585 | |||
1586 | static ssize_t store_temp_auto_offset_hyst(struct device *dev, | ||
1587 | struct device_attribute *attr, | ||
1588 | const char *buf, size_t count) | ||
1589 | { | ||
1590 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1591 | struct i2c_client *client = to_i2c_client(dev); | ||
1592 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1593 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1594 | u8 reg; | ||
1595 | |||
1596 | mutex_lock(&data->update_lock); | ||
1597 | /* force 0.5C/bit mode */ | ||
1598 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
1599 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
1600 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
1601 | reg = data->auto_pwm_min_hyst[nr/2]; | ||
1602 | reg = (reg & 0xf0) | (LM93_TEMP_OFFSET_TO_REG(val, 1) & 0x0f); | ||
1603 | data->auto_pwm_min_hyst[nr/2] = reg; | ||
1604 | lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); | ||
1605 | mutex_unlock(&data->update_lock); | ||
1606 | return count; | ||
1607 | } | ||
1608 | |||
1609 | static SENSOR_DEVICE_ATTR(temp1_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
1610 | show_temp_auto_offset_hyst, | ||
1611 | store_temp_auto_offset_hyst, 0); | ||
1612 | static SENSOR_DEVICE_ATTR(temp2_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
1613 | show_temp_auto_offset_hyst, | ||
1614 | store_temp_auto_offset_hyst, 1); | ||
1615 | static SENSOR_DEVICE_ATTR(temp3_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
1616 | show_temp_auto_offset_hyst, | ||
1617 | store_temp_auto_offset_hyst, 2); | ||
1618 | |||
1619 | static ssize_t show_fan_input(struct device *dev, | ||
1620 | struct device_attribute *attr, char *buf) | ||
1621 | { | ||
1622 | struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); | ||
1623 | int nr = s_attr->index; | ||
1624 | struct lm93_data *data = lm93_update_device(dev); | ||
1625 | |||
1626 | return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block5[nr])); | ||
1627 | } | ||
1628 | |||
1629 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); | ||
1630 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); | ||
1631 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2); | ||
1632 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3); | ||
1633 | |||
1634 | static ssize_t show_fan_min(struct device *dev, | ||
1635 | struct device_attribute *attr, char *buf) | ||
1636 | { | ||
1637 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1638 | struct lm93_data *data = lm93_update_device(dev); | ||
1639 | |||
1640 | return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block8[nr])); | ||
1641 | } | ||
1642 | |||
1643 | static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, | ||
1644 | const char *buf, size_t count) | ||
1645 | { | ||
1646 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1647 | struct i2c_client *client = to_i2c_client(dev); | ||
1648 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1649 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1650 | |||
1651 | mutex_lock(&data->update_lock); | ||
1652 | data->block8[nr] = LM93_FAN_TO_REG(val); | ||
1653 | lm93_write_word(client,LM93_REG_FAN_MIN(nr),data->block8[nr]); | ||
1654 | mutex_unlock(&data->update_lock); | ||
1655 | return count; | ||
1656 | } | ||
1657 | |||
1658 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, | ||
1659 | show_fan_min, store_fan_min, 0); | ||
1660 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, | ||
1661 | show_fan_min, store_fan_min, 1); | ||
1662 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, | ||
1663 | show_fan_min, store_fan_min, 2); | ||
1664 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, | ||
1665 | show_fan_min, store_fan_min, 3); | ||
1666 | |||
1667 | /* some tedious bit-twiddling here to deal with the register format: | ||
1668 | |||
1669 | data->sf_tach_to_pwm: (tach to pwm mapping bits) | ||
1670 | |||
1671 | bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
1672 | T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 | ||
1673 | |||
1674 | data->sfc2: (enable bits) | ||
1675 | |||
1676 | bit | 3 | 2 | 1 | 0 | ||
1677 | T4 T3 T2 T1 | ||
1678 | */ | ||
1679 | |||
1680 | static ssize_t show_fan_smart_tach(struct device *dev, | ||
1681 | struct device_attribute *attr, char *buf) | ||
1682 | { | ||
1683 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1684 | struct lm93_data *data = lm93_update_device(dev); | ||
1685 | long rc = 0; | ||
1686 | int mapping; | ||
1687 | |||
1688 | /* extract the relevant mapping */ | ||
1689 | mapping = (data->sf_tach_to_pwm >> (nr * 2)) & 0x03; | ||
1690 | |||
1691 | /* if there's a mapping and it's enabled */ | ||
1692 | if (mapping && ((data->sfc2 >> nr) & 0x01)) | ||
1693 | rc = mapping; | ||
1694 | return sprintf(buf,"%ld\n",rc); | ||
1695 | } | ||
1696 | |||
1697 | /* helper function - must grab data->update_lock before calling | ||
1698 | fan is 0-3, indicating fan1-fan4 */ | ||
1699 | static void lm93_write_fan_smart_tach(struct i2c_client *client, | ||
1700 | struct lm93_data *data, int fan, long value) | ||
1701 | { | ||
1702 | /* insert the new mapping and write it out */ | ||
1703 | data->sf_tach_to_pwm = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); | ||
1704 | data->sf_tach_to_pwm &= ~(0x3 << fan * 2); | ||
1705 | data->sf_tach_to_pwm |= value << fan * 2; | ||
1706 | lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, data->sf_tach_to_pwm); | ||
1707 | |||
1708 | /* insert the enable bit and write it out */ | ||
1709 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
1710 | if (value) | ||
1711 | data->sfc2 |= 1 << fan; | ||
1712 | else | ||
1713 | data->sfc2 &= ~(1 << fan); | ||
1714 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
1715 | } | ||
1716 | |||
1717 | static ssize_t store_fan_smart_tach(struct device *dev, | ||
1718 | struct device_attribute *attr, | ||
1719 | const char *buf, size_t count) | ||
1720 | { | ||
1721 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1722 | struct i2c_client *client = to_i2c_client(dev); | ||
1723 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1724 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1725 | |||
1726 | mutex_lock(&data->update_lock); | ||
1727 | /* sanity test, ignore the write otherwise */ | ||
1728 | if (0 <= val && val <= 2) { | ||
1729 | /* can't enable if pwm freq is 22.5KHz */ | ||
1730 | if (val) { | ||
1731 | u8 ctl4 = lm93_read_byte(client, | ||
1732 | LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4)); | ||
1733 | if ((ctl4 & 0x07) == 0) | ||
1734 | val = 0; | ||
1735 | } | ||
1736 | lm93_write_fan_smart_tach(client, data, nr, val); | ||
1737 | } | ||
1738 | mutex_unlock(&data->update_lock); | ||
1739 | return count; | ||
1740 | } | ||
1741 | |||
1742 | static SENSOR_DEVICE_ATTR(fan1_smart_tach, S_IWUSR | S_IRUGO, | ||
1743 | show_fan_smart_tach, store_fan_smart_tach, 0); | ||
1744 | static SENSOR_DEVICE_ATTR(fan2_smart_tach, S_IWUSR | S_IRUGO, | ||
1745 | show_fan_smart_tach, store_fan_smart_tach, 1); | ||
1746 | static SENSOR_DEVICE_ATTR(fan3_smart_tach, S_IWUSR | S_IRUGO, | ||
1747 | show_fan_smart_tach, store_fan_smart_tach, 2); | ||
1748 | static SENSOR_DEVICE_ATTR(fan4_smart_tach, S_IWUSR | S_IRUGO, | ||
1749 | show_fan_smart_tach, store_fan_smart_tach, 3); | ||
1750 | |||
1751 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
1752 | char *buf) | ||
1753 | { | ||
1754 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1755 | struct lm93_data *data = lm93_update_device(dev); | ||
1756 | u8 ctl2, ctl4; | ||
1757 | long rc; | ||
1758 | |||
1759 | ctl2 = data->block9[nr][LM93_PWM_CTL2]; | ||
1760 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
1761 | if (ctl2 & 0x01) /* show user commanded value if enabled */ | ||
1762 | rc = data->pwm_override[nr]; | ||
1763 | else /* show present h/w value if manual pwm disabled */ | ||
1764 | rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? | ||
1765 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); | ||
1766 | return sprintf(buf,"%ld\n",rc); | ||
1767 | } | ||
1768 | |||
1769 | static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, | ||
1770 | const char *buf, size_t count) | ||
1771 | { | ||
1772 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1773 | struct i2c_client *client = to_i2c_client(dev); | ||
1774 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1775 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1776 | u8 ctl2, ctl4; | ||
1777 | |||
1778 | mutex_lock(&data->update_lock); | ||
1779 | ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); | ||
1780 | ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
1781 | ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val,(ctl4 & 0x07) ? | ||
1782 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4; | ||
1783 | /* save user commanded value */ | ||
1784 | data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4, | ||
1785 | (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : | ||
1786 | LM93_PWM_MAP_HI_FREQ); | ||
1787 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); | ||
1788 | mutex_unlock(&data->update_lock); | ||
1789 | return count; | ||
1790 | } | ||
1791 | |||
1792 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); | ||
1793 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); | ||
1794 | |||
1795 | static ssize_t show_pwm_enable(struct device *dev, | ||
1796 | struct device_attribute *attr, char *buf) | ||
1797 | { | ||
1798 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1799 | struct lm93_data *data = lm93_update_device(dev); | ||
1800 | u8 ctl2; | ||
1801 | long rc; | ||
1802 | |||
1803 | ctl2 = data->block9[nr][LM93_PWM_CTL2]; | ||
1804 | if (ctl2 & 0x01) /* manual override enabled ? */ | ||
1805 | rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1; | ||
1806 | else | ||
1807 | rc = 2; | ||
1808 | return sprintf(buf,"%ld\n",rc); | ||
1809 | } | ||
1810 | |||
1811 | static ssize_t store_pwm_enable(struct device *dev, | ||
1812 | struct device_attribute *attr, | ||
1813 | const char *buf, size_t count) | ||
1814 | { | ||
1815 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1816 | struct i2c_client *client = to_i2c_client(dev); | ||
1817 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1818 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1819 | u8 ctl2; | ||
1820 | |||
1821 | mutex_lock(&data->update_lock); | ||
1822 | ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); | ||
1823 | |||
1824 | switch (val) { | ||
1825 | case 0: | ||
1826 | ctl2 |= 0xF1; /* enable manual override, set PWM to max */ | ||
1827 | break; | ||
1828 | case 1: ctl2 |= 0x01; /* enable manual override */ | ||
1829 | break; | ||
1830 | case 2: ctl2 &= ~0x01; /* disable manual override */ | ||
1831 | break; | ||
1832 | default: | ||
1833 | mutex_unlock(&data->update_lock); | ||
1834 | return -EINVAL; | ||
1835 | } | ||
1836 | |||
1837 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); | ||
1838 | mutex_unlock(&data->update_lock); | ||
1839 | return count; | ||
1840 | } | ||
1841 | |||
1842 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
1843 | show_pwm_enable, store_pwm_enable, 0); | ||
1844 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, | ||
1845 | show_pwm_enable, store_pwm_enable, 1); | ||
1846 | |||
1847 | static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, | ||
1848 | char *buf) | ||
1849 | { | ||
1850 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1851 | struct lm93_data *data = lm93_update_device(dev); | ||
1852 | u8 ctl4; | ||
1853 | |||
1854 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
1855 | return sprintf(buf,"%d\n",LM93_PWM_FREQ_FROM_REG(ctl4)); | ||
1856 | } | ||
1857 | |||
1858 | /* helper function - must grab data->update_lock before calling | ||
1859 | pwm is 0-1, indicating pwm1-pwm2 | ||
1860 | this disables smart tach for all tach channels bound to the given pwm */ | ||
1861 | static void lm93_disable_fan_smart_tach(struct i2c_client *client, | ||
1862 | struct lm93_data *data, int pwm) | ||
1863 | { | ||
1864 | int mapping = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); | ||
1865 | int mask; | ||
1866 | |||
1867 | /* collapse the mapping into a mask of enable bits */ | ||
1868 | mapping = (mapping >> pwm) & 0x55; | ||
1869 | mask = mapping & 0x01; | ||
1870 | mask |= (mapping & 0x04) >> 1; | ||
1871 | mask |= (mapping & 0x10) >> 2; | ||
1872 | mask |= (mapping & 0x40) >> 3; | ||
1873 | |||
1874 | /* disable smart tach according to the mask */ | ||
1875 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
1876 | data->sfc2 &= ~mask; | ||
1877 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
1878 | } | ||
1879 | |||
1880 | static ssize_t store_pwm_freq(struct device *dev, | ||
1881 | struct device_attribute *attr, | ||
1882 | const char *buf, size_t count) | ||
1883 | { | ||
1884 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1885 | struct i2c_client *client = to_i2c_client(dev); | ||
1886 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1887 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1888 | u8 ctl4; | ||
1889 | |||
1890 | mutex_lock(&data->update_lock); | ||
1891 | ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
1892 | ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val); | ||
1893 | data->block9[nr][LM93_PWM_CTL4] = ctl4; | ||
1894 | /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ | ||
1895 | if (!ctl4) | ||
1896 | lm93_disable_fan_smart_tach(client, data, nr); | ||
1897 | lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4); | ||
1898 | mutex_unlock(&data->update_lock); | ||
1899 | return count; | ||
1900 | } | ||
1901 | |||
1902 | static SENSOR_DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO, | ||
1903 | show_pwm_freq, store_pwm_freq, 0); | ||
1904 | static SENSOR_DEVICE_ATTR(pwm2_freq, S_IWUSR | S_IRUGO, | ||
1905 | show_pwm_freq, store_pwm_freq, 1); | ||
1906 | |||
1907 | static ssize_t show_pwm_auto_channels(struct device *dev, | ||
1908 | struct device_attribute *attr, char *buf) | ||
1909 | { | ||
1910 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1911 | struct lm93_data *data = lm93_update_device(dev); | ||
1912 | return sprintf(buf,"%d\n",data->block9[nr][LM93_PWM_CTL1]); | ||
1913 | } | ||
1914 | |||
1915 | static ssize_t store_pwm_auto_channels(struct device *dev, | ||
1916 | struct device_attribute *attr, | ||
1917 | const char *buf, size_t count) | ||
1918 | { | ||
1919 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1920 | struct i2c_client *client = to_i2c_client(dev); | ||
1921 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1922 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1923 | |||
1924 | mutex_lock(&data->update_lock); | ||
1925 | data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255); | ||
1926 | lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL1), | ||
1927 | data->block9[nr][LM93_PWM_CTL1]); | ||
1928 | mutex_unlock(&data->update_lock); | ||
1929 | return count; | ||
1930 | } | ||
1931 | |||
1932 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels, S_IWUSR | S_IRUGO, | ||
1933 | show_pwm_auto_channels, store_pwm_auto_channels, 0); | ||
1934 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO, | ||
1935 | show_pwm_auto_channels, store_pwm_auto_channels, 1); | ||
1936 | |||
1937 | static ssize_t show_pwm_auto_spinup_min(struct device *dev, | ||
1938 | struct device_attribute *attr,char *buf) | ||
1939 | { | ||
1940 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1941 | struct lm93_data *data = lm93_update_device(dev); | ||
1942 | u8 ctl3, ctl4; | ||
1943 | |||
1944 | ctl3 = data->block9[nr][LM93_PWM_CTL3]; | ||
1945 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
1946 | return sprintf(buf,"%d\n", | ||
1947 | LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ? | ||
1948 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); | ||
1949 | } | ||
1950 | |||
1951 | static ssize_t store_pwm_auto_spinup_min(struct device *dev, | ||
1952 | struct device_attribute *attr, | ||
1953 | const char *buf, size_t count) | ||
1954 | { | ||
1955 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1956 | struct i2c_client *client = to_i2c_client(dev); | ||
1957 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1958 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1959 | u8 ctl3, ctl4; | ||
1960 | |||
1961 | mutex_lock(&data->update_lock); | ||
1962 | ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); | ||
1963 | ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); | ||
1964 | ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? | ||
1965 | LM93_PWM_MAP_LO_FREQ : | ||
1966 | LM93_PWM_MAP_HI_FREQ); | ||
1967 | data->block9[nr][LM93_PWM_CTL3] = ctl3; | ||
1968 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); | ||
1969 | mutex_unlock(&data->update_lock); | ||
1970 | return count; | ||
1971 | } | ||
1972 | |||
1973 | static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_min, S_IWUSR | S_IRUGO, | ||
1974 | show_pwm_auto_spinup_min, | ||
1975 | store_pwm_auto_spinup_min, 0); | ||
1976 | static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_min, S_IWUSR | S_IRUGO, | ||
1977 | show_pwm_auto_spinup_min, | ||
1978 | store_pwm_auto_spinup_min, 1); | ||
1979 | |||
1980 | static ssize_t show_pwm_auto_spinup_time(struct device *dev, | ||
1981 | struct device_attribute *attr, char *buf) | ||
1982 | { | ||
1983 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1984 | struct lm93_data *data = lm93_update_device(dev); | ||
1985 | return sprintf(buf,"%d\n",LM93_SPINUP_TIME_FROM_REG( | ||
1986 | data->block9[nr][LM93_PWM_CTL3])); | ||
1987 | } | ||
1988 | |||
1989 | static ssize_t store_pwm_auto_spinup_time(struct device *dev, | ||
1990 | struct device_attribute *attr, | ||
1991 | const char *buf, size_t count) | ||
1992 | { | ||
1993 | int nr = (to_sensor_dev_attr(attr))->index; | ||
1994 | struct i2c_client *client = to_i2c_client(dev); | ||
1995 | struct lm93_data *data = i2c_get_clientdata(client); | ||
1996 | u32 val = simple_strtoul(buf, NULL, 10); | ||
1997 | u8 ctl3; | ||
1998 | |||
1999 | mutex_lock(&data->update_lock); | ||
2000 | ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); | ||
2001 | ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0); | ||
2002 | data->block9[nr][LM93_PWM_CTL3] = ctl3; | ||
2003 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); | ||
2004 | mutex_unlock(&data->update_lock); | ||
2005 | return count; | ||
2006 | } | ||
2007 | |||
2008 | static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_time, S_IWUSR | S_IRUGO, | ||
2009 | show_pwm_auto_spinup_time, | ||
2010 | store_pwm_auto_spinup_time, 0); | ||
2011 | static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_time, S_IWUSR | S_IRUGO, | ||
2012 | show_pwm_auto_spinup_time, | ||
2013 | store_pwm_auto_spinup_time, 1); | ||
2014 | |||
2015 | static ssize_t show_pwm_auto_prochot_ramp(struct device *dev, | ||
2016 | struct device_attribute *attr, char *buf) | ||
2017 | { | ||
2018 | struct lm93_data *data = lm93_update_device(dev); | ||
2019 | return sprintf(buf,"%d\n", | ||
2020 | LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f)); | ||
2021 | } | ||
2022 | |||
2023 | static ssize_t store_pwm_auto_prochot_ramp(struct device *dev, | ||
2024 | struct device_attribute *attr, | ||
2025 | const char *buf, size_t count) | ||
2026 | { | ||
2027 | struct i2c_client *client = to_i2c_client(dev); | ||
2028 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2029 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2030 | u8 ramp; | ||
2031 | |||
2032 | mutex_lock(&data->update_lock); | ||
2033 | ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
2034 | ramp = (ramp & 0x0f) | (LM93_RAMP_TO_REG(val) << 4 & 0xf0); | ||
2035 | lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); | ||
2036 | mutex_unlock(&data->update_lock); | ||
2037 | return count; | ||
2038 | } | ||
2039 | |||
2040 | static DEVICE_ATTR(pwm_auto_prochot_ramp, S_IRUGO | S_IWUSR, | ||
2041 | show_pwm_auto_prochot_ramp, | ||
2042 | store_pwm_auto_prochot_ramp); | ||
2043 | |||
2044 | static ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev, | ||
2045 | struct device_attribute *attr, char *buf) | ||
2046 | { | ||
2047 | struct lm93_data *data = lm93_update_device(dev); | ||
2048 | return sprintf(buf,"%d\n", | ||
2049 | LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f)); | ||
2050 | } | ||
2051 | |||
2052 | static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev, | ||
2053 | struct device_attribute *attr, | ||
2054 | const char *buf, size_t count) | ||
2055 | { | ||
2056 | struct i2c_client *client = to_i2c_client(dev); | ||
2057 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2058 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2059 | u8 ramp; | ||
2060 | |||
2061 | mutex_lock(&data->update_lock); | ||
2062 | ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
2063 | ramp = (ramp & 0xf0) | (LM93_RAMP_TO_REG(val) & 0x0f); | ||
2064 | lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); | ||
2065 | mutex_unlock(&data->update_lock); | ||
2066 | return 0; | ||
2067 | } | ||
2068 | |||
2069 | static DEVICE_ATTR(pwm_auto_vrdhot_ramp, S_IRUGO | S_IWUSR, | ||
2070 | show_pwm_auto_vrdhot_ramp, | ||
2071 | store_pwm_auto_vrdhot_ramp); | ||
2072 | |||
2073 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | ||
2074 | char *buf) | ||
2075 | { | ||
2076 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2077 | struct lm93_data *data = lm93_update_device(dev); | ||
2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); | ||
2079 | } | ||
2080 | |||
2081 | static SENSOR_DEVICE_ATTR(vid1, S_IRUGO, show_vid, NULL, 0); | ||
2082 | static SENSOR_DEVICE_ATTR(vid2, S_IRUGO, show_vid, NULL, 1); | ||
2083 | |||
2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, | ||
2085 | char *buf) | ||
2086 | { | ||
2087 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2088 | struct lm93_data *data = lm93_update_device(dev); | ||
2089 | return sprintf(buf,"%d\n",data->block4[nr].cur); | ||
2090 | } | ||
2091 | |||
2092 | static SENSOR_DEVICE_ATTR(prochot1, S_IRUGO, show_prochot, NULL, 0); | ||
2093 | static SENSOR_DEVICE_ATTR(prochot2, S_IRUGO, show_prochot, NULL, 1); | ||
2094 | |||
2095 | static ssize_t show_prochot_avg(struct device *dev, | ||
2096 | struct device_attribute *attr, char *buf) | ||
2097 | { | ||
2098 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2099 | struct lm93_data *data = lm93_update_device(dev); | ||
2100 | return sprintf(buf,"%d\n",data->block4[nr].avg); | ||
2101 | } | ||
2102 | |||
2103 | static SENSOR_DEVICE_ATTR(prochot1_avg, S_IRUGO, show_prochot_avg, NULL, 0); | ||
2104 | static SENSOR_DEVICE_ATTR(prochot2_avg, S_IRUGO, show_prochot_avg, NULL, 1); | ||
2105 | |||
2106 | static ssize_t show_prochot_max(struct device *dev, | ||
2107 | struct device_attribute *attr, char *buf) | ||
2108 | { | ||
2109 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2110 | struct lm93_data *data = lm93_update_device(dev); | ||
2111 | return sprintf(buf,"%d\n",data->prochot_max[nr]); | ||
2112 | } | ||
2113 | |||
2114 | static ssize_t store_prochot_max(struct device *dev, | ||
2115 | struct device_attribute *attr, | ||
2116 | const char *buf, size_t count) | ||
2117 | { | ||
2118 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2119 | struct i2c_client *client = to_i2c_client(dev); | ||
2120 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2121 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2122 | |||
2123 | mutex_lock(&data->update_lock); | ||
2124 | data->prochot_max[nr] = LM93_PROCHOT_TO_REG(val); | ||
2125 | lm93_write_byte(client, LM93_REG_PROCHOT_MAX(nr), | ||
2126 | data->prochot_max[nr]); | ||
2127 | mutex_unlock(&data->update_lock); | ||
2128 | return count; | ||
2129 | } | ||
2130 | |||
2131 | static SENSOR_DEVICE_ATTR(prochot1_max, S_IWUSR | S_IRUGO, | ||
2132 | show_prochot_max, store_prochot_max, 0); | ||
2133 | static SENSOR_DEVICE_ATTR(prochot2_max, S_IWUSR | S_IRUGO, | ||
2134 | show_prochot_max, store_prochot_max, 1); | ||
2135 | |||
2136 | static const u8 prochot_override_mask[] = { 0x80, 0x40 }; | ||
2137 | |||
2138 | static ssize_t show_prochot_override(struct device *dev, | ||
2139 | struct device_attribute *attr, char *buf) | ||
2140 | { | ||
2141 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2142 | struct lm93_data *data = lm93_update_device(dev); | ||
2143 | return sprintf(buf,"%d\n", | ||
2144 | (data->prochot_override & prochot_override_mask[nr]) ? 1 : 0); | ||
2145 | } | ||
2146 | |||
2147 | static ssize_t store_prochot_override(struct device *dev, | ||
2148 | struct device_attribute *attr, | ||
2149 | const char *buf, size_t count) | ||
2150 | { | ||
2151 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2152 | struct i2c_client *client = to_i2c_client(dev); | ||
2153 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2154 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2155 | |||
2156 | mutex_lock(&data->update_lock); | ||
2157 | if (val) | ||
2158 | data->prochot_override |= prochot_override_mask[nr]; | ||
2159 | else | ||
2160 | data->prochot_override &= (~prochot_override_mask[nr]); | ||
2161 | lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, | ||
2162 | data->prochot_override); | ||
2163 | mutex_unlock(&data->update_lock); | ||
2164 | return count; | ||
2165 | } | ||
2166 | |||
2167 | static SENSOR_DEVICE_ATTR(prochot1_override, S_IWUSR | S_IRUGO, | ||
2168 | show_prochot_override, store_prochot_override, 0); | ||
2169 | static SENSOR_DEVICE_ATTR(prochot2_override, S_IWUSR | S_IRUGO, | ||
2170 | show_prochot_override, store_prochot_override, 1); | ||
2171 | |||
2172 | static ssize_t show_prochot_interval(struct device *dev, | ||
2173 | struct device_attribute *attr, char *buf) | ||
2174 | { | ||
2175 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2176 | struct lm93_data *data = lm93_update_device(dev); | ||
2177 | u8 tmp; | ||
2178 | if (nr==1) | ||
2179 | tmp = (data->prochot_interval & 0xf0) >> 4; | ||
2180 | else | ||
2181 | tmp = data->prochot_interval & 0x0f; | ||
2182 | return sprintf(buf,"%d\n",LM93_INTERVAL_FROM_REG(tmp)); | ||
2183 | } | ||
2184 | |||
2185 | static ssize_t store_prochot_interval(struct device *dev, | ||
2186 | struct device_attribute *attr, | ||
2187 | const char *buf, size_t count) | ||
2188 | { | ||
2189 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2190 | struct i2c_client *client = to_i2c_client(dev); | ||
2191 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2192 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2193 | u8 tmp; | ||
2194 | |||
2195 | mutex_lock(&data->update_lock); | ||
2196 | tmp = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL); | ||
2197 | if (nr==1) | ||
2198 | tmp = (tmp & 0x0f) | (LM93_INTERVAL_TO_REG(val) << 4); | ||
2199 | else | ||
2200 | tmp = (tmp & 0xf0) | LM93_INTERVAL_TO_REG(val); | ||
2201 | data->prochot_interval = tmp; | ||
2202 | lm93_write_byte(client, LM93_REG_PROCHOT_INTERVAL, tmp); | ||
2203 | mutex_unlock(&data->update_lock); | ||
2204 | return count; | ||
2205 | } | ||
2206 | |||
2207 | static SENSOR_DEVICE_ATTR(prochot1_interval, S_IWUSR | S_IRUGO, | ||
2208 | show_prochot_interval, store_prochot_interval, 0); | ||
2209 | static SENSOR_DEVICE_ATTR(prochot2_interval, S_IWUSR | S_IRUGO, | ||
2210 | show_prochot_interval, store_prochot_interval, 1); | ||
2211 | |||
2212 | static ssize_t show_prochot_override_duty_cycle(struct device *dev, | ||
2213 | struct device_attribute *attr, | ||
2214 | char *buf) | ||
2215 | { | ||
2216 | struct lm93_data *data = lm93_update_device(dev); | ||
2217 | return sprintf(buf,"%d\n",data->prochot_override & 0x0f); | ||
2218 | } | ||
2219 | |||
2220 | static ssize_t store_prochot_override_duty_cycle(struct device *dev, | ||
2221 | struct device_attribute *attr, | ||
2222 | const char *buf, size_t count) | ||
2223 | { | ||
2224 | struct i2c_client *client = to_i2c_client(dev); | ||
2225 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2226 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2227 | |||
2228 | mutex_lock(&data->update_lock); | ||
2229 | data->prochot_override = (data->prochot_override & 0xf0) | | ||
2230 | SENSORS_LIMIT(val, 0, 15); | ||
2231 | lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, | ||
2232 | data->prochot_override); | ||
2233 | mutex_unlock(&data->update_lock); | ||
2234 | return count; | ||
2235 | } | ||
2236 | |||
2237 | static DEVICE_ATTR(prochot_override_duty_cycle, S_IRUGO | S_IWUSR, | ||
2238 | show_prochot_override_duty_cycle, | ||
2239 | store_prochot_override_duty_cycle); | ||
2240 | |||
2241 | static ssize_t show_prochot_short(struct device *dev, | ||
2242 | struct device_attribute *attr, char *buf) | ||
2243 | { | ||
2244 | struct lm93_data *data = lm93_update_device(dev); | ||
2245 | return sprintf(buf,"%d\n",(data->config & 0x10) ? 1 : 0); | ||
2246 | } | ||
2247 | |||
2248 | static ssize_t store_prochot_short(struct device *dev, | ||
2249 | struct device_attribute *attr, | ||
2250 | const char *buf, size_t count) | ||
2251 | { | ||
2252 | struct i2c_client *client = to_i2c_client(dev); | ||
2253 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2254 | u32 val = simple_strtoul(buf, NULL, 10); | ||
2255 | |||
2256 | mutex_lock(&data->update_lock); | ||
2257 | if (val) | ||
2258 | data->config |= 0x10; | ||
2259 | else | ||
2260 | data->config &= ~0x10; | ||
2261 | lm93_write_byte(client, LM93_REG_CONFIG, data->config); | ||
2262 | mutex_unlock(&data->update_lock); | ||
2263 | return count; | ||
2264 | } | ||
2265 | |||
2266 | static DEVICE_ATTR(prochot_short, S_IRUGO | S_IWUSR, | ||
2267 | show_prochot_short, store_prochot_short); | ||
2268 | |||
2269 | static ssize_t show_vrdhot(struct device *dev, struct device_attribute *attr, | ||
2270 | char *buf) | ||
2271 | { | ||
2272 | int nr = (to_sensor_dev_attr(attr))->index; | ||
2273 | struct lm93_data *data = lm93_update_device(dev); | ||
2274 | return sprintf(buf,"%d\n", | ||
2275 | data->block1.host_status_1 & (1 << (nr+4)) ? 1 : 0); | ||
2276 | } | ||
2277 | |||
2278 | static SENSOR_DEVICE_ATTR(vrdhot1, S_IRUGO, show_vrdhot, NULL, 0); | ||
2279 | static SENSOR_DEVICE_ATTR(vrdhot2, S_IRUGO, show_vrdhot, NULL, 1); | ||
2280 | |||
2281 | static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, | ||
2282 | char *buf) | ||
2283 | { | ||
2284 | struct lm93_data *data = lm93_update_device(dev); | ||
2285 | return sprintf(buf,"%d\n",LM93_GPI_FROM_REG(data->gpi)); | ||
2286 | } | ||
2287 | |||
2288 | static DEVICE_ATTR(gpio, S_IRUGO, show_gpio, NULL); | ||
2289 | |||
2290 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | ||
2291 | char *buf) | ||
2292 | { | ||
2293 | struct lm93_data *data = lm93_update_device(dev); | ||
2294 | return sprintf(buf,"%d\n",LM93_ALARMS_FROM_REG(data->block1)); | ||
2295 | } | ||
2296 | |||
2297 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
2298 | |||
2299 | static struct attribute *lm93_attrs[] = { | ||
2300 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
2301 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
2302 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
2303 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
2304 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
2305 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
2306 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
2307 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
2308 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
2309 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
2310 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
2311 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
2312 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
2313 | &sensor_dev_attr_in14_input.dev_attr.attr, | ||
2314 | &sensor_dev_attr_in15_input.dev_attr.attr, | ||
2315 | &sensor_dev_attr_in16_input.dev_attr.attr, | ||
2316 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
2317 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
2318 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
2319 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
2320 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
2321 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
2322 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
2323 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
2324 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
2325 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
2326 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
2327 | &sensor_dev_attr_in12_min.dev_attr.attr, | ||
2328 | &sensor_dev_attr_in13_min.dev_attr.attr, | ||
2329 | &sensor_dev_attr_in14_min.dev_attr.attr, | ||
2330 | &sensor_dev_attr_in15_min.dev_attr.attr, | ||
2331 | &sensor_dev_attr_in16_min.dev_attr.attr, | ||
2332 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
2333 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
2334 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
2335 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
2336 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
2337 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
2338 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
2339 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
2340 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
2341 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
2342 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
2343 | &sensor_dev_attr_in12_max.dev_attr.attr, | ||
2344 | &sensor_dev_attr_in13_max.dev_attr.attr, | ||
2345 | &sensor_dev_attr_in14_max.dev_attr.attr, | ||
2346 | &sensor_dev_attr_in15_max.dev_attr.attr, | ||
2347 | &sensor_dev_attr_in16_max.dev_attr.attr, | ||
2348 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
2349 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
2350 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
2351 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
2352 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
2353 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
2354 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
2355 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
2356 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
2357 | &sensor_dev_attr_temp1_auto_base.dev_attr.attr, | ||
2358 | &sensor_dev_attr_temp2_auto_base.dev_attr.attr, | ||
2359 | &sensor_dev_attr_temp3_auto_base.dev_attr.attr, | ||
2360 | &sensor_dev_attr_temp1_auto_boost.dev_attr.attr, | ||
2361 | &sensor_dev_attr_temp2_auto_boost.dev_attr.attr, | ||
2362 | &sensor_dev_attr_temp3_auto_boost.dev_attr.attr, | ||
2363 | &sensor_dev_attr_temp1_auto_boost_hyst.dev_attr.attr, | ||
2364 | &sensor_dev_attr_temp2_auto_boost_hyst.dev_attr.attr, | ||
2365 | &sensor_dev_attr_temp3_auto_boost_hyst.dev_attr.attr, | ||
2366 | &sensor_dev_attr_temp1_auto_offset1.dev_attr.attr, | ||
2367 | &sensor_dev_attr_temp1_auto_offset2.dev_attr.attr, | ||
2368 | &sensor_dev_attr_temp1_auto_offset3.dev_attr.attr, | ||
2369 | &sensor_dev_attr_temp1_auto_offset4.dev_attr.attr, | ||
2370 | &sensor_dev_attr_temp1_auto_offset5.dev_attr.attr, | ||
2371 | &sensor_dev_attr_temp1_auto_offset6.dev_attr.attr, | ||
2372 | &sensor_dev_attr_temp1_auto_offset7.dev_attr.attr, | ||
2373 | &sensor_dev_attr_temp1_auto_offset8.dev_attr.attr, | ||
2374 | &sensor_dev_attr_temp1_auto_offset9.dev_attr.attr, | ||
2375 | &sensor_dev_attr_temp1_auto_offset10.dev_attr.attr, | ||
2376 | &sensor_dev_attr_temp1_auto_offset11.dev_attr.attr, | ||
2377 | &sensor_dev_attr_temp1_auto_offset12.dev_attr.attr, | ||
2378 | &sensor_dev_attr_temp2_auto_offset1.dev_attr.attr, | ||
2379 | &sensor_dev_attr_temp2_auto_offset2.dev_attr.attr, | ||
2380 | &sensor_dev_attr_temp2_auto_offset3.dev_attr.attr, | ||
2381 | &sensor_dev_attr_temp2_auto_offset4.dev_attr.attr, | ||
2382 | &sensor_dev_attr_temp2_auto_offset5.dev_attr.attr, | ||
2383 | &sensor_dev_attr_temp2_auto_offset6.dev_attr.attr, | ||
2384 | &sensor_dev_attr_temp2_auto_offset7.dev_attr.attr, | ||
2385 | &sensor_dev_attr_temp2_auto_offset8.dev_attr.attr, | ||
2386 | &sensor_dev_attr_temp2_auto_offset9.dev_attr.attr, | ||
2387 | &sensor_dev_attr_temp2_auto_offset10.dev_attr.attr, | ||
2388 | &sensor_dev_attr_temp2_auto_offset11.dev_attr.attr, | ||
2389 | &sensor_dev_attr_temp2_auto_offset12.dev_attr.attr, | ||
2390 | &sensor_dev_attr_temp3_auto_offset1.dev_attr.attr, | ||
2391 | &sensor_dev_attr_temp3_auto_offset2.dev_attr.attr, | ||
2392 | &sensor_dev_attr_temp3_auto_offset3.dev_attr.attr, | ||
2393 | &sensor_dev_attr_temp3_auto_offset4.dev_attr.attr, | ||
2394 | &sensor_dev_attr_temp3_auto_offset5.dev_attr.attr, | ||
2395 | &sensor_dev_attr_temp3_auto_offset6.dev_attr.attr, | ||
2396 | &sensor_dev_attr_temp3_auto_offset7.dev_attr.attr, | ||
2397 | &sensor_dev_attr_temp3_auto_offset8.dev_attr.attr, | ||
2398 | &sensor_dev_attr_temp3_auto_offset9.dev_attr.attr, | ||
2399 | &sensor_dev_attr_temp3_auto_offset10.dev_attr.attr, | ||
2400 | &sensor_dev_attr_temp3_auto_offset11.dev_attr.attr, | ||
2401 | &sensor_dev_attr_temp3_auto_offset12.dev_attr.attr, | ||
2402 | &sensor_dev_attr_temp1_auto_pwm_min.dev_attr.attr, | ||
2403 | &sensor_dev_attr_temp2_auto_pwm_min.dev_attr.attr, | ||
2404 | &sensor_dev_attr_temp3_auto_pwm_min.dev_attr.attr, | ||
2405 | &sensor_dev_attr_temp1_auto_offset_hyst.dev_attr.attr, | ||
2406 | &sensor_dev_attr_temp2_auto_offset_hyst.dev_attr.attr, | ||
2407 | &sensor_dev_attr_temp3_auto_offset_hyst.dev_attr.attr, | ||
2408 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
2409 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
2410 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
2411 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
2412 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
2413 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
2414 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
2415 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
2416 | &sensor_dev_attr_fan1_smart_tach.dev_attr.attr, | ||
2417 | &sensor_dev_attr_fan2_smart_tach.dev_attr.attr, | ||
2418 | &sensor_dev_attr_fan3_smart_tach.dev_attr.attr, | ||
2419 | &sensor_dev_attr_fan4_smart_tach.dev_attr.attr, | ||
2420 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
2421 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
2422 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
2423 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
2424 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | ||
2425 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | ||
2426 | &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, | ||
2427 | &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, | ||
2428 | &sensor_dev_attr_pwm1_auto_spinup_min.dev_attr.attr, | ||
2429 | &sensor_dev_attr_pwm2_auto_spinup_min.dev_attr.attr, | ||
2430 | &sensor_dev_attr_pwm1_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, | ||
2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, | ||
2434 | &sensor_dev_attr_vid1.dev_attr.attr, | ||
2435 | &sensor_dev_attr_vid2.dev_attr.attr, | ||
2436 | &sensor_dev_attr_prochot1.dev_attr.attr, | ||
2437 | &sensor_dev_attr_prochot2.dev_attr.attr, | ||
2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, | ||
2439 | &sensor_dev_attr_prochot2_avg.dev_attr.attr, | ||
2440 | &sensor_dev_attr_prochot1_max.dev_attr.attr, | ||
2441 | &sensor_dev_attr_prochot2_max.dev_attr.attr, | ||
2442 | &sensor_dev_attr_prochot1_override.dev_attr.attr, | ||
2443 | &sensor_dev_attr_prochot2_override.dev_attr.attr, | ||
2444 | &sensor_dev_attr_prochot1_interval.dev_attr.attr, | ||
2445 | &sensor_dev_attr_prochot2_interval.dev_attr.attr, | ||
2446 | &dev_attr_prochot_override_duty_cycle.attr, | ||
2447 | &dev_attr_prochot_short.attr, | ||
2448 | &sensor_dev_attr_vrdhot1.dev_attr.attr, | ||
2449 | &sensor_dev_attr_vrdhot2.dev_attr.attr, | ||
2450 | &dev_attr_gpio.attr, | ||
2451 | &dev_attr_alarms.attr, | ||
2452 | NULL | ||
2453 | }; | ||
2454 | |||
2455 | static struct attribute_group lm93_attr_grp = { | ||
2456 | .attrs = lm93_attrs, | ||
2457 | }; | ||
2458 | |||
2459 | static void lm93_init_client(struct i2c_client *client) | ||
2460 | { | ||
2461 | int i; | ||
2462 | u8 reg; | ||
2463 | |||
2464 | /* configure VID pin input thresholds */ | ||
2465 | reg = lm93_read_byte(client, LM93_REG_GPI_VID_CTL); | ||
2466 | lm93_write_byte(client, LM93_REG_GPI_VID_CTL, | ||
2467 | reg | (vid_agtl ? 0x03 : 0x00)); | ||
2468 | |||
2469 | if (init) { | ||
2470 | /* enable #ALERT pin */ | ||
2471 | reg = lm93_read_byte(client, LM93_REG_CONFIG); | ||
2472 | lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x08); | ||
2473 | |||
2474 | /* enable ASF mode for BMC status registers */ | ||
2475 | reg = lm93_read_byte(client, LM93_REG_STATUS_CONTROL); | ||
2476 | lm93_write_byte(client, LM93_REG_STATUS_CONTROL, reg | 0x02); | ||
2477 | |||
2478 | /* set sleep state to S0 */ | ||
2479 | lm93_write_byte(client, LM93_REG_SLEEP_CONTROL, 0); | ||
2480 | |||
2481 | /* unmask #VRDHOT and dynamic VCCP (if nec) error events */ | ||
2482 | reg = lm93_read_byte(client, LM93_REG_MISC_ERR_MASK); | ||
2483 | reg &= ~0x03; | ||
2484 | reg &= ~(vccp_limit_type[0] ? 0x10 : 0); | ||
2485 | reg &= ~(vccp_limit_type[1] ? 0x20 : 0); | ||
2486 | lm93_write_byte(client, LM93_REG_MISC_ERR_MASK, reg); | ||
2487 | } | ||
2488 | |||
2489 | /* start monitoring */ | ||
2490 | reg = lm93_read_byte(client, LM93_REG_CONFIG); | ||
2491 | lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x01); | ||
2492 | |||
2493 | /* spin until ready */ | ||
2494 | for (i=0; i<20; i++) { | ||
2495 | msleep(10); | ||
2496 | if ((lm93_read_byte(client, LM93_REG_CONFIG) & 0x80) == 0x80) | ||
2497 | return; | ||
2498 | } | ||
2499 | |||
2500 | dev_warn(&client->dev,"timed out waiting for sensor " | ||
2501 | "chip to signal ready!\n"); | ||
2502 | } | ||
2503 | |||
2504 | static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) | ||
2505 | { | ||
2506 | struct lm93_data *data; | ||
2507 | struct i2c_client *client; | ||
2508 | |||
2509 | int err = -ENODEV, func; | ||
2510 | void (*update)(struct lm93_data *, struct i2c_client *); | ||
2511 | |||
2512 | /* choose update routine based on bus capabilities */ | ||
2513 | func = i2c_get_functionality(adapter); | ||
2514 | if ( ((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) && | ||
2515 | (!disable_block) ) { | ||
2516 | dev_dbg(&adapter->dev,"using SMBus block data transactions\n"); | ||
2517 | update = lm93_update_client_full; | ||
2518 | } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { | ||
2519 | dev_dbg(&adapter->dev,"disabled SMBus block data " | ||
2520 | "transactions\n"); | ||
2521 | update = lm93_update_client_min; | ||
2522 | } else { | ||
2523 | dev_dbg(&adapter->dev,"detect failed, " | ||
2524 | "smbus byte and/or word data not supported!\n"); | ||
2525 | goto err_out; | ||
2526 | } | ||
2527 | |||
2528 | /* OK. For now, we presume we have a valid client. We now create the | ||
2529 | client structure, even though we cannot fill it completely yet. | ||
2530 | But it allows us to access lm78_{read,write}_value. */ | ||
2531 | |||
2532 | if ( !(data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL))) { | ||
2533 | dev_dbg(&adapter->dev,"out of memory!\n"); | ||
2534 | err = -ENOMEM; | ||
2535 | goto err_out; | ||
2536 | } | ||
2537 | |||
2538 | client = &data->client; | ||
2539 | i2c_set_clientdata(client, data); | ||
2540 | client->addr = address; | ||
2541 | client->adapter = adapter; | ||
2542 | client->driver = &lm93_driver; | ||
2543 | |||
2544 | /* detection */ | ||
2545 | if (kind < 0) { | ||
2546 | int mfr = lm93_read_byte(client, LM93_REG_MFR_ID); | ||
2547 | |||
2548 | if (mfr != 0x01) { | ||
2549 | dev_dbg(&adapter->dev,"detect failed, " | ||
2550 | "bad manufacturer id 0x%02x!\n", mfr); | ||
2551 | goto err_free; | ||
2552 | } | ||
2553 | } | ||
2554 | |||
2555 | if (kind <= 0) { | ||
2556 | int ver = lm93_read_byte(client, LM93_REG_VER); | ||
2557 | |||
2558 | if ((ver == LM93_MFR_ID) || (ver == LM93_MFR_ID_PROTOTYPE)) { | ||
2559 | kind = lm93; | ||
2560 | } else { | ||
2561 | dev_dbg(&adapter->dev,"detect failed, " | ||
2562 | "bad version id 0x%02x!\n", ver); | ||
2563 | if (kind == 0) | ||
2564 | dev_dbg(&adapter->dev, | ||
2565 | "(ignored 'force' parameter)\n"); | ||
2566 | goto err_free; | ||
2567 | } | ||
2568 | } | ||
2569 | |||
2570 | /* fill in remaining client fields */ | ||
2571 | strlcpy(client->name, "lm93", I2C_NAME_SIZE); | ||
2572 | dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n", | ||
2573 | client->name, i2c_adapter_id(client->adapter), | ||
2574 | client->addr); | ||
2575 | |||
2576 | /* housekeeping */ | ||
2577 | data->valid = 0; | ||
2578 | data->update = update; | ||
2579 | mutex_init(&data->update_lock); | ||
2580 | |||
2581 | /* tell the I2C layer a new client has arrived */ | ||
2582 | if ((err = i2c_attach_client(client))) | ||
2583 | goto err_free; | ||
2584 | |||
2585 | /* initialize the chip */ | ||
2586 | lm93_init_client(client); | ||
2587 | |||
2588 | err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp); | ||
2589 | if (err) | ||
2590 | goto err_detach; | ||
2591 | |||
2592 | /* Register hwmon driver class */ | ||
2593 | data->class_dev = hwmon_device_register(&client->dev); | ||
2594 | if ( !IS_ERR(data->class_dev)) | ||
2595 | return 0; | ||
2596 | |||
2597 | err = PTR_ERR(data->class_dev); | ||
2598 | dev_err(&client->dev, "error registering hwmon device.\n"); | ||
2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | ||
2600 | err_detach: | ||
2601 | i2c_detach_client(client); | ||
2602 | err_free: | ||
2603 | kfree(data); | ||
2604 | err_out: | ||
2605 | return err; | ||
2606 | } | ||
2607 | |||
2608 | /* This function is called when: | ||
2609 | * lm93_driver is inserted (when this module is loaded), for each | ||
2610 | available adapter | ||
2611 | * when a new adapter is inserted (and lm93_driver is still present) */ | ||
2612 | static int lm93_attach_adapter(struct i2c_adapter *adapter) | ||
2613 | { | ||
2614 | return i2c_probe(adapter, &addr_data, lm93_detect); | ||
2615 | } | ||
2616 | |||
2617 | static int lm93_detach_client(struct i2c_client *client) | ||
2618 | { | ||
2619 | struct lm93_data *data = i2c_get_clientdata(client); | ||
2620 | int err = 0; | ||
2621 | |||
2622 | hwmon_device_unregister(data->class_dev); | ||
2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | ||
2624 | |||
2625 | err = i2c_detach_client(client); | ||
2626 | if (!err) | ||
2627 | kfree(data); | ||
2628 | return err; | ||
2629 | } | ||
2630 | |||
2631 | static struct i2c_driver lm93_driver = { | ||
2632 | .driver = { | ||
2633 | .name = "lm93", | ||
2634 | }, | ||
2635 | .attach_adapter = lm93_attach_adapter, | ||
2636 | .detach_client = lm93_detach_client, | ||
2637 | }; | ||
2638 | |||
2639 | static int __init lm93_init(void) | ||
2640 | { | ||
2641 | return i2c_add_driver(&lm93_driver); | ||
2642 | } | ||
2643 | |||
2644 | static void __exit lm93_exit(void) | ||
2645 | { | ||
2646 | i2c_del_driver(&lm93_driver); | ||
2647 | } | ||
2648 | |||
2649 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " | ||
2650 | "Hans J. Koch <hjk@linutronix.de"); | ||
2651 | MODULE_DESCRIPTION("LM93 driver"); | ||
2652 | MODULE_LICENSE("GPL"); | ||
2653 | |||
2654 | module_init(lm93_init); | ||
2655 | module_exit(lm93_exit); | ||
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index c8a21be09d87..cb72526c346a 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * pc87360.c - Part of lm_sensors, Linux kernel modules | 2 | * pc87360.c - Part of lm_sensors, Linux kernel modules |
3 | * for hardware monitoring | 3 | * for hardware monitoring |
4 | * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2004, 2007 Jean Delvare <khali@linux-fr.org> |
5 | * | 5 | * |
6 | * Copied from smsc47m1.c: | 6 | * Copied from smsc47m1.c: |
7 | * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | 7 | * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> |
@@ -37,8 +37,7 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/i2c-isa.h> | ||
42 | #include <linux/hwmon.h> | 41 | #include <linux/hwmon.h> |
43 | #include <linux/hwmon-sysfs.h> | 42 | #include <linux/hwmon-sysfs.h> |
44 | #include <linux/hwmon-vid.h> | 43 | #include <linux/hwmon-vid.h> |
@@ -47,12 +46,10 @@ | |||
47 | #include <asm/io.h> | 46 | #include <asm/io.h> |
48 | 47 | ||
49 | static u8 devid; | 48 | static u8 devid; |
50 | static unsigned short address; | 49 | static struct platform_device *pdev; |
51 | static unsigned short extra_isa[3]; | 50 | static unsigned short extra_isa[3]; |
52 | static u8 confreg[4]; | 51 | static u8 confreg[4]; |
53 | 52 | ||
54 | enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 }; | ||
55 | |||
56 | static int init = 1; | 53 | static int init = 1; |
57 | module_param(init, int, 0); | 54 | module_param(init, int, 0); |
58 | MODULE_PARM_DESC(init, | 55 | MODULE_PARM_DESC(init, |
@@ -178,11 +175,11 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
178 | ((val) + 500) / 1000) | 175 | ((val) + 500) / 1000) |
179 | 176 | ||
180 | /* | 177 | /* |
181 | * Client data (each client gets its own) | 178 | * Device data |
182 | */ | 179 | */ |
183 | 180 | ||
184 | struct pc87360_data { | 181 | struct pc87360_data { |
185 | struct i2c_client client; | 182 | const char *name; |
186 | struct class_device *class_dev; | 183 | struct class_device *class_dev; |
187 | struct mutex lock; | 184 | struct mutex lock; |
188 | struct mutex update_lock; | 185 | struct mutex update_lock; |
@@ -222,27 +219,28 @@ struct pc87360_data { | |||
222 | * Functions declaration | 219 | * Functions declaration |
223 | */ | 220 | */ |
224 | 221 | ||
225 | static int pc87360_detect(struct i2c_adapter *adapter); | 222 | static int pc87360_probe(struct platform_device *pdev); |
226 | static int pc87360_detach_client(struct i2c_client *client); | 223 | static int pc87360_remove(struct platform_device *pdev); |
227 | 224 | ||
228 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, | 225 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, |
229 | u8 reg); | 226 | u8 reg); |
230 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | 227 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, |
231 | u8 reg, u8 value); | 228 | u8 reg, u8 value); |
232 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors); | 229 | static void pc87360_init_device(struct platform_device *pdev, |
230 | int use_thermistors); | ||
233 | static struct pc87360_data *pc87360_update_device(struct device *dev); | 231 | static struct pc87360_data *pc87360_update_device(struct device *dev); |
234 | 232 | ||
235 | /* | 233 | /* |
236 | * Driver data (common to all clients) | 234 | * Driver data |
237 | */ | 235 | */ |
238 | 236 | ||
239 | static struct i2c_driver pc87360_driver = { | 237 | static struct platform_driver pc87360_driver = { |
240 | .driver = { | 238 | .driver = { |
241 | .owner = THIS_MODULE, | 239 | .owner = THIS_MODULE, |
242 | .name = "pc87360", | 240 | .name = "pc87360", |
243 | }, | 241 | }, |
244 | .attach_adapter = pc87360_detect, | 242 | .probe = pc87360_probe, |
245 | .detach_client = pc87360_detach_client, | 243 | .remove = __devexit_p(pc87360_remove), |
246 | }; | 244 | }; |
247 | 245 | ||
248 | /* | 246 | /* |
@@ -281,8 +279,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, | |||
281 | size_t count) | 279 | size_t count) |
282 | { | 280 | { |
283 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 281 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
284 | struct i2c_client *client = to_i2c_client(dev); | 282 | struct pc87360_data *data = dev_get_drvdata(dev); |
285 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
286 | long fan_min = simple_strtol(buf, NULL, 10); | 283 | long fan_min = simple_strtol(buf, NULL, 10); |
287 | 284 | ||
288 | mutex_lock(&data->update_lock); | 285 | mutex_lock(&data->update_lock); |
@@ -347,8 +344,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, con | |||
347 | size_t count) | 344 | size_t count) |
348 | { | 345 | { |
349 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 346 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
350 | struct i2c_client *client = to_i2c_client(dev); | 347 | struct pc87360_data *data = dev_get_drvdata(dev); |
351 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
352 | long val = simple_strtol(buf, NULL, 10); | 348 | long val = simple_strtol(buf, NULL, 10); |
353 | 349 | ||
354 | mutex_lock(&data->update_lock); | 350 | mutex_lock(&data->update_lock); |
@@ -410,8 +406,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, | |||
410 | size_t count) | 406 | size_t count) |
411 | { | 407 | { |
412 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 408 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
413 | struct i2c_client *client = to_i2c_client(dev); | 409 | struct pc87360_data *data = dev_get_drvdata(dev); |
414 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
415 | long val = simple_strtol(buf, NULL, 10); | 410 | long val = simple_strtol(buf, NULL, 10); |
416 | 411 | ||
417 | mutex_lock(&data->update_lock); | 412 | mutex_lock(&data->update_lock); |
@@ -425,8 +420,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, | |||
425 | size_t count) | 420 | size_t count) |
426 | { | 421 | { |
427 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 422 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
428 | struct i2c_client *client = to_i2c_client(dev); | 423 | struct pc87360_data *data = dev_get_drvdata(dev); |
429 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
430 | long val = simple_strtol(buf, NULL, 10); | 424 | long val = simple_strtol(buf, NULL, 10); |
431 | 425 | ||
432 | mutex_lock(&data->update_lock); | 426 | mutex_lock(&data->update_lock); |
@@ -511,8 +505,7 @@ static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char | |||
511 | } | 505 | } |
512 | 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) |
513 | { | 507 | { |
514 | struct i2c_client *client = to_i2c_client(dev); | 508 | struct pc87360_data *data = dev_get_drvdata(dev); |
515 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
516 | data->vrm = simple_strtoul(buf, NULL, 10); | 509 | data->vrm = simple_strtoul(buf, NULL, 10); |
517 | return count; | 510 | return count; |
518 | } | 511 | } |
@@ -584,8 +577,7 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt | |||
584 | size_t count) | 577 | size_t count) |
585 | { | 578 | { |
586 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 579 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
587 | struct i2c_client *client = to_i2c_client(dev); | 580 | struct pc87360_data *data = dev_get_drvdata(dev); |
588 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
589 | long val = simple_strtol(buf, NULL, 10); | 581 | long val = simple_strtol(buf, NULL, 10); |
590 | 582 | ||
591 | mutex_lock(&data->update_lock); | 583 | mutex_lock(&data->update_lock); |
@@ -599,8 +591,7 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt | |||
599 | size_t count) | 591 | size_t count) |
600 | { | 592 | { |
601 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 593 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
602 | struct i2c_client *client = to_i2c_client(dev); | 594 | struct pc87360_data *data = dev_get_drvdata(dev); |
603 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
604 | long val = simple_strtol(buf, NULL, 10); | 595 | long val = simple_strtol(buf, NULL, 10); |
605 | 596 | ||
606 | mutex_lock(&data->update_lock); | 597 | mutex_lock(&data->update_lock); |
@@ -614,8 +605,7 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat | |||
614 | size_t count) | 605 | size_t count) |
615 | { | 606 | { |
616 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 607 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
617 | struct i2c_client *client = to_i2c_client(dev); | 608 | struct pc87360_data *data = dev_get_drvdata(dev); |
618 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
619 | long val = simple_strtol(buf, NULL, 10); | 609 | long val = simple_strtol(buf, NULL, 10); |
620 | 610 | ||
621 | mutex_lock(&data->update_lock); | 611 | mutex_lock(&data->update_lock); |
@@ -715,8 +705,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr | |||
715 | size_t count) | 705 | size_t count) |
716 | { | 706 | { |
717 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 707 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
718 | struct i2c_client *client = to_i2c_client(dev); | 708 | struct pc87360_data *data = dev_get_drvdata(dev); |
719 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
720 | long val = simple_strtol(buf, NULL, 10); | 709 | long val = simple_strtol(buf, NULL, 10); |
721 | 710 | ||
722 | mutex_lock(&data->update_lock); | 711 | mutex_lock(&data->update_lock); |
@@ -730,8 +719,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr | |||
730 | size_t count) | 719 | size_t count) |
731 | { | 720 | { |
732 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 721 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
733 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct pc87360_data *data = dev_get_drvdata(dev); |
734 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
735 | long val = simple_strtol(buf, NULL, 10); | 723 | long val = simple_strtol(buf, NULL, 10); |
736 | 724 | ||
737 | mutex_lock(&data->update_lock); | 725 | mutex_lock(&data->update_lock); |
@@ -745,8 +733,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devatt | |||
745 | size_t count) | 733 | size_t count) |
746 | { | 734 | { |
747 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 735 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
748 | struct i2c_client *client = to_i2c_client(dev); | 736 | struct pc87360_data *data = dev_get_drvdata(dev); |
749 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
750 | long val = simple_strtol(buf, NULL, 10); | 737 | long val = simple_strtol(buf, NULL, 10); |
751 | 738 | ||
752 | mutex_lock(&data->update_lock); | 739 | mutex_lock(&data->update_lock); |
@@ -818,6 +805,14 @@ static const struct attribute_group pc8736x_temp_group = { | |||
818 | .attrs = pc8736x_temp_attr_array, | 805 | .attrs = pc8736x_temp_attr_array, |
819 | }; | 806 | }; |
820 | 807 | ||
808 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
809 | *devattr, char *buf) | ||
810 | { | ||
811 | struct pc87360_data *data = dev_get_drvdata(dev); | ||
812 | return sprintf(buf, "%s\n", data->name); | ||
813 | } | ||
814 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
815 | |||
821 | /* | 816 | /* |
822 | * Device detection, registration and update | 817 | * Device detection, registration and update |
823 | */ | 818 | */ |
@@ -912,28 +907,18 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses | |||
912 | return 0; | 907 | return 0; |
913 | } | 908 | } |
914 | 909 | ||
915 | static int pc87360_detect(struct i2c_adapter *adapter) | 910 | static int __devinit pc87360_probe(struct platform_device *pdev) |
916 | { | 911 | { |
917 | int i; | 912 | int i; |
918 | struct i2c_client *client; | ||
919 | struct pc87360_data *data; | 913 | struct pc87360_data *data; |
920 | int err = 0; | 914 | int err = 0; |
921 | const char *name = "pc87360"; | 915 | const char *name = "pc87360"; |
922 | int use_thermistors = 0; | 916 | int use_thermistors = 0; |
923 | struct device *dev; | 917 | struct device *dev = &pdev->dev; |
924 | 918 | ||
925 | if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) | 919 | if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) |
926 | return -ENOMEM; | 920 | return -ENOMEM; |
927 | 921 | ||
928 | client = &data->client; | ||
929 | dev = &client->dev; | ||
930 | i2c_set_clientdata(client, data); | ||
931 | client->addr = address; | ||
932 | mutex_init(&data->lock); | ||
933 | client->adapter = adapter; | ||
934 | client->driver = &pc87360_driver; | ||
935 | client->flags = 0; | ||
936 | |||
937 | data->fannr = 2; | 922 | data->fannr = 2; |
938 | data->innr = 0; | 923 | data->innr = 0; |
939 | data->tempnr = 0; | 924 | data->tempnr = 0; |
@@ -960,15 +945,17 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
960 | break; | 945 | break; |
961 | } | 946 | } |
962 | 947 | ||
963 | strlcpy(client->name, name, sizeof(client->name)); | 948 | data->name = name; |
964 | data->valid = 0; | 949 | data->valid = 0; |
950 | mutex_init(&data->lock); | ||
965 | mutex_init(&data->update_lock); | 951 | mutex_init(&data->update_lock); |
952 | platform_set_drvdata(pdev, data); | ||
966 | 953 | ||
967 | for (i = 0; i < 3; i++) { | 954 | for (i = 0; i < 3; i++) { |
968 | if (((data->address[i] = extra_isa[i])) | 955 | if (((data->address[i] = extra_isa[i])) |
969 | && !request_region(extra_isa[i], PC87360_EXTENT, | 956 | && !request_region(extra_isa[i], PC87360_EXTENT, |
970 | pc87360_driver.driver.name)) { | 957 | pc87360_driver.driver.name)) { |
971 | dev_err(&client->dev, "Region 0x%x-0x%x already " | 958 | dev_err(dev, "Region 0x%x-0x%x already " |
972 | "in use!\n", extra_isa[i], | 959 | "in use!\n", extra_isa[i], |
973 | extra_isa[i]+PC87360_EXTENT-1); | 960 | extra_isa[i]+PC87360_EXTENT-1); |
974 | for (i--; i >= 0; i--) | 961 | for (i--; i >= 0; i--) |
@@ -982,9 +969,6 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
982 | if (data->fannr) | 969 | if (data->fannr) |
983 | data->fan_conf = confreg[0] | (confreg[1] << 8); | 970 | data->fan_conf = confreg[0] | (confreg[1] << 8); |
984 | 971 | ||
985 | if ((err = i2c_attach_client(client))) | ||
986 | goto ERROR2; | ||
987 | |||
988 | /* Use the correct reference voltage | 972 | /* Use the correct reference voltage |
989 | Unless both the VLM and the TMS logical devices agree to | 973 | Unless both the VLM and the TMS logical devices agree to |
990 | use an external Vref, the internal one is used. */ | 974 | use an external Vref, the internal one is used. */ |
@@ -996,7 +980,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
996 | PC87365_REG_TEMP_CONFIG); | 980 | PC87365_REG_TEMP_CONFIG); |
997 | } | 981 | } |
998 | data->in_vref = (i&0x02) ? 3025 : 2966; | 982 | data->in_vref = (i&0x02) ? 3025 : 2966; |
999 | dev_dbg(&client->dev, "Using %s reference voltage\n", | 983 | dev_dbg(dev, "Using %s reference voltage\n", |
1000 | (i&0x02) ? "external" : "internal"); | 984 | (i&0x02) ? "external" : "internal"); |
1001 | 985 | ||
1002 | data->vid_conf = confreg[3]; | 986 | data->vid_conf = confreg[3]; |
@@ -1015,18 +999,18 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
1015 | if (devid == 0xe9 && data->address[1]) /* PC87366 */ | 999 | if (devid == 0xe9 && data->address[1]) /* PC87366 */ |
1016 | use_thermistors = confreg[2] & 0x40; | 1000 | use_thermistors = confreg[2] & 0x40; |
1017 | 1001 | ||
1018 | pc87360_init_client(client, use_thermistors); | 1002 | pc87360_init_device(pdev, use_thermistors); |
1019 | } | 1003 | } |
1020 | 1004 | ||
1021 | /* Register all-or-nothing sysfs groups */ | 1005 | /* Register all-or-nothing sysfs groups */ |
1022 | 1006 | ||
1023 | if (data->innr && | 1007 | if (data->innr && |
1024 | (err = sysfs_create_group(&client->dev.kobj, | 1008 | (err = sysfs_create_group(&dev->kobj, |
1025 | &pc8736x_vin_group))) | 1009 | &pc8736x_vin_group))) |
1026 | goto ERROR3; | 1010 | goto ERROR3; |
1027 | 1011 | ||
1028 | if (data->innr == 14 && | 1012 | if (data->innr == 14 && |
1029 | (err = sysfs_create_group(&client->dev.kobj, | 1013 | (err = sysfs_create_group(&dev->kobj, |
1030 | &pc8736x_therm_group))) | 1014 | &pc8736x_therm_group))) |
1031 | goto ERROR3; | 1015 | goto ERROR3; |
1032 | 1016 | ||
@@ -1067,7 +1051,10 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
1067 | goto ERROR3; | 1051 | goto ERROR3; |
1068 | } | 1052 | } |
1069 | 1053 | ||
1070 | data->class_dev = hwmon_device_register(&client->dev); | 1054 | if ((err = device_create_file(dev, &dev_attr_name))) |
1055 | goto ERROR3; | ||
1056 | |||
1057 | data->class_dev = hwmon_device_register(dev); | ||
1071 | if (IS_ERR(data->class_dev)) { | 1058 | if (IS_ERR(data->class_dev)) { |
1072 | err = PTR_ERR(data->class_dev); | 1059 | err = PTR_ERR(data->class_dev); |
1073 | goto ERROR3; | 1060 | goto ERROR3; |
@@ -1075,14 +1062,12 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
1075 | return 0; | 1062 | return 0; |
1076 | 1063 | ||
1077 | ERROR3: | 1064 | ERROR3: |
1065 | device_remove_file(dev, &dev_attr_name); | ||
1078 | /* can still remove groups whose members were added individually */ | 1066 | /* can still remove groups whose members were added individually */ |
1079 | sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); | 1067 | sysfs_remove_group(&dev->kobj, &pc8736x_temp_group); |
1080 | sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); | 1068 | sysfs_remove_group(&dev->kobj, &pc8736x_fan_group); |
1081 | sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); | 1069 | sysfs_remove_group(&dev->kobj, &pc8736x_therm_group); |
1082 | sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); | 1070 | sysfs_remove_group(&dev->kobj, &pc8736x_vin_group); |
1083 | |||
1084 | i2c_detach_client(client); | ||
1085 | ERROR2: | ||
1086 | for (i = 0; i < 3; i++) { | 1071 | for (i = 0; i < 3; i++) { |
1087 | if (data->address[i]) { | 1072 | if (data->address[i]) { |
1088 | release_region(data->address[i], PC87360_EXTENT); | 1073 | release_region(data->address[i], PC87360_EXTENT); |
@@ -1093,20 +1078,18 @@ ERROR1: | |||
1093 | return err; | 1078 | return err; |
1094 | } | 1079 | } |
1095 | 1080 | ||
1096 | static int pc87360_detach_client(struct i2c_client *client) | 1081 | static int __devexit pc87360_remove(struct platform_device *pdev) |
1097 | { | 1082 | { |
1098 | struct pc87360_data *data = i2c_get_clientdata(client); | 1083 | struct pc87360_data *data = platform_get_drvdata(pdev); |
1099 | int i; | 1084 | int i; |
1100 | 1085 | ||
1101 | hwmon_device_unregister(data->class_dev); | 1086 | hwmon_device_unregister(data->class_dev); |
1102 | 1087 | ||
1103 | sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); | 1088 | device_remove_file(&pdev->dev, &dev_attr_name); |
1104 | sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); | 1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); |
1105 | sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); | 1090 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group); |
1106 | sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); | 1091 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group); |
1107 | 1092 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group); | |
1108 | if ((i = i2c_detach_client(client))) | ||
1109 | return i; | ||
1110 | 1093 | ||
1111 | for (i = 0; i < 3; i++) { | 1094 | for (i = 0; i < 3; i++) { |
1112 | if (data->address[i]) { | 1095 | if (data->address[i]) { |
@@ -1144,9 +1127,10 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
1144 | mutex_unlock(&(data->lock)); | 1127 | mutex_unlock(&(data->lock)); |
1145 | } | 1128 | } |
1146 | 1129 | ||
1147 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | 1130 | static void pc87360_init_device(struct platform_device *pdev, |
1131 | int use_thermistors) | ||
1148 | { | 1132 | { |
1149 | struct pc87360_data *data = i2c_get_clientdata(client); | 1133 | struct pc87360_data *data = platform_get_drvdata(pdev); |
1150 | int i, nr; | 1134 | int i, nr; |
1151 | const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; | 1135 | const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; |
1152 | const u8 init_temp[3] = { 2, 2, 1 }; | 1136 | const u8 init_temp[3] = { 2, 2, 1 }; |
@@ -1155,7 +1139,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1155 | if (init >= 2 && data->innr) { | 1139 | if (init >= 2 && data->innr) { |
1156 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1140 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1157 | PC87365_REG_IN_CONVRATE); | 1141 | PC87365_REG_IN_CONVRATE); |
1158 | dev_info(&client->dev, "VLM conversion set to " | 1142 | dev_info(&pdev->dev, "VLM conversion set to " |
1159 | "1s period, 160us delay\n"); | 1143 | "1s period, 160us delay\n"); |
1160 | pc87360_write_value(data, LD_IN, NO_BANK, | 1144 | pc87360_write_value(data, LD_IN, NO_BANK, |
1161 | PC87365_REG_IN_CONVRATE, | 1145 | PC87365_REG_IN_CONVRATE, |
@@ -1169,7 +1153,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1169 | reg = pc87360_read_value(data, LD_IN, i, | 1153 | reg = pc87360_read_value(data, LD_IN, i, |
1170 | PC87365_REG_IN_STATUS); | 1154 | PC87365_REG_IN_STATUS); |
1171 | if (!(reg & 0x01)) { | 1155 | if (!(reg & 0x01)) { |
1172 | dev_dbg(&client->dev, "Forcibly " | 1156 | dev_dbg(&pdev->dev, "Forcibly " |
1173 | "enabling in%d\n", i); | 1157 | "enabling in%d\n", i); |
1174 | pc87360_write_value(data, LD_IN, i, | 1158 | pc87360_write_value(data, LD_IN, i, |
1175 | PC87365_REG_IN_STATUS, | 1159 | PC87365_REG_IN_STATUS, |
@@ -1193,7 +1177,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1193 | reg = pc87360_read_value(data, LD_TEMP, i, | 1177 | reg = pc87360_read_value(data, LD_TEMP, i, |
1194 | PC87365_REG_TEMP_STATUS); | 1178 | PC87365_REG_TEMP_STATUS); |
1195 | if (!(reg & 0x01)) { | 1179 | if (!(reg & 0x01)) { |
1196 | dev_dbg(&client->dev, "Forcibly " | 1180 | dev_dbg(&pdev->dev, "Forcibly " |
1197 | "enabling temp%d\n", i+1); | 1181 | "enabling temp%d\n", i+1); |
1198 | pc87360_write_value(data, LD_TEMP, i, | 1182 | pc87360_write_value(data, LD_TEMP, i, |
1199 | PC87365_REG_TEMP_STATUS, | 1183 | PC87365_REG_TEMP_STATUS, |
@@ -1210,7 +1194,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1210 | reg = pc87360_read_value(data, LD_TEMP, | 1194 | reg = pc87360_read_value(data, LD_TEMP, |
1211 | (i-11)/2, PC87365_REG_TEMP_STATUS); | 1195 | (i-11)/2, PC87365_REG_TEMP_STATUS); |
1212 | if (reg & 0x01) { | 1196 | if (reg & 0x01) { |
1213 | dev_dbg(&client->dev, "Skipping " | 1197 | dev_dbg(&pdev->dev, "Skipping " |
1214 | "temp%d, pin already in use " | 1198 | "temp%d, pin already in use " |
1215 | "by temp%d\n", i-7, (i-11)/2); | 1199 | "by temp%d\n", i-7, (i-11)/2); |
1216 | continue; | 1200 | continue; |
@@ -1220,7 +1204,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1220 | reg = pc87360_read_value(data, LD_IN, i, | 1204 | reg = pc87360_read_value(data, LD_IN, i, |
1221 | PC87365_REG_IN_STATUS); | 1205 | PC87365_REG_IN_STATUS); |
1222 | if (!(reg & 0x01)) { | 1206 | if (!(reg & 0x01)) { |
1223 | dev_dbg(&client->dev, "Forcibly " | 1207 | dev_dbg(&pdev->dev, "Forcibly " |
1224 | "enabling temp%d\n", i-7); | 1208 | "enabling temp%d\n", i-7); |
1225 | pc87360_write_value(data, LD_IN, i, | 1209 | pc87360_write_value(data, LD_IN, i, |
1226 | PC87365_REG_TEMP_STATUS, | 1210 | PC87365_REG_TEMP_STATUS, |
@@ -1234,7 +1218,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1234 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1218 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1235 | PC87365_REG_IN_CONFIG); | 1219 | PC87365_REG_IN_CONFIG); |
1236 | if (reg & 0x01) { | 1220 | if (reg & 0x01) { |
1237 | dev_dbg(&client->dev, "Forcibly " | 1221 | dev_dbg(&pdev->dev, "Forcibly " |
1238 | "enabling monitoring (VLM)\n"); | 1222 | "enabling monitoring (VLM)\n"); |
1239 | pc87360_write_value(data, LD_IN, NO_BANK, | 1223 | pc87360_write_value(data, LD_IN, NO_BANK, |
1240 | PC87365_REG_IN_CONFIG, | 1224 | PC87365_REG_IN_CONFIG, |
@@ -1246,7 +1230,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1246 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, | 1230 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, |
1247 | PC87365_REG_TEMP_CONFIG); | 1231 | PC87365_REG_TEMP_CONFIG); |
1248 | if (reg & 0x01) { | 1232 | if (reg & 0x01) { |
1249 | dev_dbg(&client->dev, "Forcibly enabling " | 1233 | dev_dbg(&pdev->dev, "Forcibly enabling " |
1250 | "monitoring (TMS)\n"); | 1234 | "monitoring (TMS)\n"); |
1251 | pc87360_write_value(data, LD_TEMP, NO_BANK, | 1235 | pc87360_write_value(data, LD_TEMP, NO_BANK, |
1252 | PC87365_REG_TEMP_CONFIG, | 1236 | PC87365_REG_TEMP_CONFIG, |
@@ -1268,9 +1252,9 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1268 | } | 1252 | } |
1269 | } | 1253 | } |
1270 | 1254 | ||
1271 | static void pc87360_autodiv(struct i2c_client *client, int nr) | 1255 | static void pc87360_autodiv(struct device *dev, int nr) |
1272 | { | 1256 | { |
1273 | struct pc87360_data *data = i2c_get_clientdata(client); | 1257 | struct pc87360_data *data = dev_get_drvdata(dev); |
1274 | u8 old_min = data->fan_min[nr]; | 1258 | u8 old_min = data->fan_min[nr]; |
1275 | 1259 | ||
1276 | /* Increase clock divider if needed and possible */ | 1260 | /* Increase clock divider if needed and possible */ |
@@ -1280,7 +1264,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
1280 | data->fan_status[nr] += 0x20; | 1264 | data->fan_status[nr] += 0x20; |
1281 | data->fan_min[nr] >>= 1; | 1265 | data->fan_min[nr] >>= 1; |
1282 | data->fan[nr] >>= 1; | 1266 | data->fan[nr] >>= 1; |
1283 | dev_dbg(&client->dev, "Increasing " | 1267 | dev_dbg(dev, "Increasing " |
1284 | "clock divider to %d for fan %d\n", | 1268 | "clock divider to %d for fan %d\n", |
1285 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); | 1269 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); |
1286 | } | 1270 | } |
@@ -1292,7 +1276,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
1292 | data->fan_status[nr] -= 0x20; | 1276 | data->fan_status[nr] -= 0x20; |
1293 | data->fan_min[nr] <<= 1; | 1277 | data->fan_min[nr] <<= 1; |
1294 | data->fan[nr] <<= 1; | 1278 | data->fan[nr] <<= 1; |
1295 | dev_dbg(&client->dev, "Decreasing " | 1279 | dev_dbg(dev, "Decreasing " |
1296 | "clock divider to %d for fan %d\n", | 1280 | "clock divider to %d for fan %d\n", |
1297 | FAN_DIV_FROM_REG(data->fan_status[nr]), | 1281 | FAN_DIV_FROM_REG(data->fan_status[nr]), |
1298 | nr+1); | 1282 | nr+1); |
@@ -1309,14 +1293,13 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
1309 | 1293 | ||
1310 | static struct pc87360_data *pc87360_update_device(struct device *dev) | 1294 | static struct pc87360_data *pc87360_update_device(struct device *dev) |
1311 | { | 1295 | { |
1312 | struct i2c_client *client = to_i2c_client(dev); | 1296 | struct pc87360_data *data = dev_get_drvdata(dev); |
1313 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
1314 | u8 i; | 1297 | u8 i; |
1315 | 1298 | ||
1316 | mutex_lock(&data->update_lock); | 1299 | mutex_lock(&data->update_lock); |
1317 | 1300 | ||
1318 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 1301 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
1319 | dev_dbg(&client->dev, "Data update\n"); | 1302 | dev_dbg(dev, "Data update\n"); |
1320 | 1303 | ||
1321 | /* Fans */ | 1304 | /* Fans */ |
1322 | for (i = 0; i < data->fannr; i++) { | 1305 | for (i = 0; i < data->fannr; i++) { |
@@ -1330,7 +1313,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1330 | LD_FAN, NO_BANK, | 1313 | LD_FAN, NO_BANK, |
1331 | PC87360_REG_FAN_MIN(i)); | 1314 | PC87360_REG_FAN_MIN(i)); |
1332 | /* Change clock divider if needed */ | 1315 | /* Change clock divider if needed */ |
1333 | pc87360_autodiv(client, i); | 1316 | pc87360_autodiv(dev, i); |
1334 | /* Clear bits and write new divider */ | 1317 | /* Clear bits and write new divider */ |
1335 | pc87360_write_value(data, LD_FAN, NO_BANK, | 1318 | pc87360_write_value(data, LD_FAN, NO_BANK, |
1336 | PC87360_REG_FAN_STATUS(i), | 1319 | PC87360_REG_FAN_STATUS(i), |
@@ -1418,9 +1401,53 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1418 | return data; | 1401 | return data; |
1419 | } | 1402 | } |
1420 | 1403 | ||
1404 | static int __init pc87360_device_add(unsigned short address) | ||
1405 | { | ||
1406 | struct resource res = { | ||
1407 | .name = "pc87360", | ||
1408 | .flags = IORESOURCE_IO, | ||
1409 | }; | ||
1410 | int err, i; | ||
1411 | |||
1412 | pdev = platform_device_alloc("pc87360", address); | ||
1413 | if (!pdev) { | ||
1414 | err = -ENOMEM; | ||
1415 | printk(KERN_ERR "pc87360: Device allocation failed\n"); | ||
1416 | goto exit; | ||
1417 | } | ||
1418 | |||
1419 | for (i = 0; i < 3; i++) { | ||
1420 | if (!extra_isa[i]) | ||
1421 | continue; | ||
1422 | res.start = extra_isa[i]; | ||
1423 | res.end = extra_isa[i] + PC87360_EXTENT - 1; | ||
1424 | err = platform_device_add_resources(pdev, &res, 1); | ||
1425 | if (err) { | ||
1426 | printk(KERN_ERR "pc87360: Device resource[%d] " | ||
1427 | "addition failed (%d)\n", i, err); | ||
1428 | goto exit_device_put; | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | err = platform_device_add(pdev); | ||
1433 | if (err) { | ||
1434 | printk(KERN_ERR "pc87360: Device addition failed (%d)\n", | ||
1435 | err); | ||
1436 | goto exit_device_put; | ||
1437 | } | ||
1438 | |||
1439 | return 0; | ||
1440 | |||
1441 | exit_device_put: | ||
1442 | platform_device_put(pdev); | ||
1443 | exit: | ||
1444 | return err; | ||
1445 | } | ||
1446 | |||
1421 | static int __init pc87360_init(void) | 1447 | static int __init pc87360_init(void) |
1422 | { | 1448 | { |
1423 | int i; | 1449 | int err, i; |
1450 | unsigned short address = 0; | ||
1424 | 1451 | ||
1425 | if (pc87360_find(0x2e, &devid, extra_isa) | 1452 | if (pc87360_find(0x2e, &devid, extra_isa) |
1426 | && pc87360_find(0x4e, &devid, extra_isa)) { | 1453 | && pc87360_find(0x4e, &devid, extra_isa)) { |
@@ -1443,12 +1470,27 @@ static int __init pc87360_init(void) | |||
1443 | return -ENODEV; | 1470 | return -ENODEV; |
1444 | } | 1471 | } |
1445 | 1472 | ||
1446 | return i2c_isa_add_driver(&pc87360_driver); | 1473 | err = platform_driver_register(&pc87360_driver); |
1474 | if (err) | ||
1475 | goto exit; | ||
1476 | |||
1477 | /* Sets global pdev as a side effect */ | ||
1478 | err = pc87360_device_add(address); | ||
1479 | if (err) | ||
1480 | goto exit_driver; | ||
1481 | |||
1482 | return 0; | ||
1483 | |||
1484 | exit_driver: | ||
1485 | platform_driver_unregister(&pc87360_driver); | ||
1486 | exit: | ||
1487 | return err; | ||
1447 | } | 1488 | } |
1448 | 1489 | ||
1449 | static void __exit pc87360_exit(void) | 1490 | static void __exit pc87360_exit(void) |
1450 | { | 1491 | { |
1451 | i2c_isa_del_driver(&pc87360_driver); | 1492 | platform_device_unregister(pdev); |
1493 | platform_driver_unregister(&pc87360_driver); | ||
1452 | } | 1494 | } |
1453 | 1495 | ||
1454 | 1496 | ||
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 29354fa26f81..2915bc4ad0d5 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -484,7 +484,6 @@ 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 | platform_set_drvdata(pdev, NULL); | ||
488 | hwmon_device_unregister(data->class_dev); | 487 | hwmon_device_unregister(data->class_dev); |
489 | device_remove_file(&pdev->dev, &dev_attr_name); | 488 | device_remove_file(&pdev->dev, &dev_attr_name); |
490 | for (i = 0; i < 8; i++) { | 489 | for (i = 0; i < 8; i++) { |
@@ -492,6 +491,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
492 | continue; | 491 | continue; |
493 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); | 492 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); |
494 | } | 493 | } |
494 | platform_set_drvdata(pdev, NULL); | ||
495 | kfree(data); | 495 | kfree(data); |
496 | 496 | ||
497 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 497 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 3f400263fc0f..83321b28cf0e 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -54,9 +54,9 @@ | |||
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/ioport.h> | 55 | #include <linux/ioport.h> |
56 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
57 | #include <linux/i2c.h> | 57 | #include <linux/platform_device.h> |
58 | #include <linux/i2c-isa.h> | ||
59 | #include <linux/hwmon.h> | 58 | #include <linux/hwmon.h> |
59 | #include <linux/hwmon-sysfs.h> | ||
60 | #include <linux/err.h> | 60 | #include <linux/err.h> |
61 | #include <linux/init.h> | 61 | #include <linux/init.h> |
62 | #include <linux/jiffies.h> | 62 | #include <linux/jiffies.h> |
@@ -72,17 +72,13 @@ module_param(force_addr, ushort, 0); | |||
72 | MODULE_PARM_DESC(force_addr, | 72 | MODULE_PARM_DESC(force_addr, |
73 | "Initialize the base address of the sensors"); | 73 | "Initialize the base address of the sensors"); |
74 | 74 | ||
75 | /* Device address | 75 | static struct platform_device *pdev; |
76 | Note that we can't determine the ISA address until we have initialized | ||
77 | our module */ | ||
78 | static unsigned short address; | ||
79 | 76 | ||
80 | /* Many SIS5595 constants specified below */ | 77 | /* Many SIS5595 constants specified below */ |
81 | 78 | ||
82 | /* Length of ISA address segment */ | 79 | /* Length of ISA address segment */ |
83 | #define SIS5595_EXTENT 8 | 80 | #define SIS5595_EXTENT 8 |
84 | /* PCI Config Registers */ | 81 | /* PCI Config Registers */ |
85 | #define SIS5595_REVISION_REG 0x08 | ||
86 | #define SIS5595_BASE_REG 0x68 | 82 | #define SIS5595_BASE_REG 0x68 |
87 | #define SIS5595_PIN_REG 0x7A | 83 | #define SIS5595_PIN_REG 0x7A |
88 | #define SIS5595_ENABLE_REG 0x7B | 84 | #define SIS5595_ENABLE_REG 0x7B |
@@ -165,7 +161,8 @@ static inline u8 DIV_TO_REG(int val) | |||
165 | /* For each registered chip, we need to keep some data in memory. | 161 | /* For each registered chip, we need to keep some data in memory. |
166 | The structure is dynamically allocated. */ | 162 | The structure is dynamically allocated. */ |
167 | struct sis5595_data { | 163 | struct sis5595_data { |
168 | struct i2c_client client; | 164 | unsigned short addr; |
165 | const char *name; | ||
169 | struct class_device *class_dev; | 166 | struct class_device *class_dev; |
170 | struct mutex lock; | 167 | struct mutex lock; |
171 | 168 | ||
@@ -189,102 +186,88 @@ struct sis5595_data { | |||
189 | 186 | ||
190 | static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ | 187 | static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ |
191 | 188 | ||
192 | static int sis5595_detect(struct i2c_adapter *adapter); | 189 | static int sis5595_probe(struct platform_device *pdev); |
193 | static int sis5595_detach_client(struct i2c_client *client); | 190 | static int sis5595_remove(struct platform_device *pdev); |
194 | 191 | ||
195 | static int sis5595_read_value(struct i2c_client *client, u8 reg); | 192 | static int sis5595_read_value(struct sis5595_data *data, u8 reg); |
196 | static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value); | 193 | static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value); |
197 | static struct sis5595_data *sis5595_update_device(struct device *dev); | 194 | static struct sis5595_data *sis5595_update_device(struct device *dev); |
198 | static void sis5595_init_client(struct i2c_client *client); | 195 | static void sis5595_init_device(struct sis5595_data *data); |
199 | 196 | ||
200 | static struct i2c_driver sis5595_driver = { | 197 | static struct platform_driver sis5595_driver = { |
201 | .driver = { | 198 | .driver = { |
202 | .owner = THIS_MODULE, | 199 | .owner = THIS_MODULE, |
203 | .name = "sis5595", | 200 | .name = "sis5595", |
204 | }, | 201 | }, |
205 | .attach_adapter = sis5595_detect, | 202 | .probe = sis5595_probe, |
206 | .detach_client = sis5595_detach_client, | 203 | .remove = __devexit_p(sis5595_remove), |
207 | }; | 204 | }; |
208 | 205 | ||
209 | /* 4 Voltages */ | 206 | /* 4 Voltages */ |
210 | static ssize_t show_in(struct device *dev, char *buf, int nr) | 207 | static ssize_t show_in(struct device *dev, struct device_attribute *da, |
208 | char *buf) | ||
211 | { | 209 | { |
212 | struct sis5595_data *data = sis5595_update_device(dev); | 210 | struct sis5595_data *data = sis5595_update_device(dev); |
211 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
212 | int nr = attr->index; | ||
213 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); | 213 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); |
214 | } | 214 | } |
215 | 215 | ||
216 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) | 216 | static ssize_t show_in_min(struct device *dev, struct device_attribute *da, |
217 | char *buf) | ||
217 | { | 218 | { |
218 | struct sis5595_data *data = sis5595_update_device(dev); | 219 | struct sis5595_data *data = sis5595_update_device(dev); |
220 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
221 | int nr = attr->index; | ||
219 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); | 222 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); |
220 | } | 223 | } |
221 | 224 | ||
222 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) | 225 | static ssize_t show_in_max(struct device *dev, struct device_attribute *da, |
226 | char *buf) | ||
223 | { | 227 | { |
224 | struct sis5595_data *data = sis5595_update_device(dev); | 228 | struct sis5595_data *data = sis5595_update_device(dev); |
229 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
230 | int nr = attr->index; | ||
225 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); | 231 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); |
226 | } | 232 | } |
227 | 233 | ||
228 | static ssize_t set_in_min(struct device *dev, const char *buf, | 234 | static ssize_t set_in_min(struct device *dev, struct device_attribute *da, |
229 | size_t count, int nr) | 235 | const char *buf, size_t count) |
230 | { | 236 | { |
231 | struct i2c_client *client = to_i2c_client(dev); | 237 | struct sis5595_data *data = dev_get_drvdata(dev); |
232 | struct sis5595_data *data = i2c_get_clientdata(client); | 238 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
239 | int nr = attr->index; | ||
233 | unsigned long val = simple_strtoul(buf, NULL, 10); | 240 | unsigned long val = simple_strtoul(buf, NULL, 10); |
234 | 241 | ||
235 | mutex_lock(&data->update_lock); | 242 | mutex_lock(&data->update_lock); |
236 | data->in_min[nr] = IN_TO_REG(val); | 243 | data->in_min[nr] = IN_TO_REG(val); |
237 | sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); | 244 | sis5595_write_value(data, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); |
238 | mutex_unlock(&data->update_lock); | 245 | mutex_unlock(&data->update_lock); |
239 | return count; | 246 | return count; |
240 | } | 247 | } |
241 | 248 | ||
242 | static ssize_t set_in_max(struct device *dev, const char *buf, | 249 | static ssize_t set_in_max(struct device *dev, struct device_attribute *da, |
243 | size_t count, int nr) | 250 | const char *buf, size_t count) |
244 | { | 251 | { |
245 | struct i2c_client *client = to_i2c_client(dev); | 252 | struct sis5595_data *data = dev_get_drvdata(dev); |
246 | struct sis5595_data *data = i2c_get_clientdata(client); | 253 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
254 | int nr = attr->index; | ||
247 | unsigned long val = simple_strtoul(buf, NULL, 10); | 255 | unsigned long val = simple_strtoul(buf, NULL, 10); |
248 | 256 | ||
249 | mutex_lock(&data->update_lock); | 257 | mutex_lock(&data->update_lock); |
250 | data->in_max[nr] = IN_TO_REG(val); | 258 | data->in_max[nr] = IN_TO_REG(val); |
251 | sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); | 259 | sis5595_write_value(data, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); |
252 | mutex_unlock(&data->update_lock); | 260 | mutex_unlock(&data->update_lock); |
253 | return count; | 261 | return count; |
254 | } | 262 | } |
255 | 263 | ||
256 | #define show_in_offset(offset) \ | 264 | #define show_in_offset(offset) \ |
257 | static ssize_t \ | 265 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
258 | show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 266 | show_in, NULL, offset); \ |
259 | { \ | 267 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
260 | return show_in(dev, buf, offset); \ | 268 | show_in_min, set_in_min, offset); \ |
261 | } \ | 269 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
262 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | 270 | show_in_max, set_in_max, offset); |
263 | show_in##offset, NULL); \ | ||
264 | static ssize_t \ | ||
265 | show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
266 | { \ | ||
267 | return show_in_min(dev, buf, offset); \ | ||
268 | } \ | ||
269 | static ssize_t \ | ||
270 | show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
271 | { \ | ||
272 | return show_in_max(dev, buf, offset); \ | ||
273 | } \ | ||
274 | static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
275 | const char *buf, size_t count) \ | ||
276 | { \ | ||
277 | return set_in_min(dev, buf, count, offset); \ | ||
278 | } \ | ||
279 | static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
280 | const char *buf, size_t count) \ | ||
281 | { \ | ||
282 | return set_in_max(dev, buf, count, offset); \ | ||
283 | } \ | ||
284 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
285 | show_in##offset##_min, set_in##offset##_min); \ | ||
286 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
287 | show_in##offset##_max, set_in##offset##_max); | ||
288 | 271 | ||
289 | show_in_offset(0); | 272 | show_in_offset(0); |
290 | show_in_offset(1); | 273 | show_in_offset(1); |
@@ -307,13 +290,12 @@ static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, | |||
307 | 290 | ||
308 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 291 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
309 | { | 292 | { |
310 | struct i2c_client *client = to_i2c_client(dev); | 293 | struct sis5595_data *data = dev_get_drvdata(dev); |
311 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
312 | long val = simple_strtol(buf, NULL, 10); | 294 | long val = simple_strtol(buf, NULL, 10); |
313 | 295 | ||
314 | mutex_lock(&data->update_lock); | 296 | mutex_lock(&data->update_lock); |
315 | data->temp_over = TEMP_TO_REG(val); | 297 | data->temp_over = TEMP_TO_REG(val); |
316 | sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over); | 298 | sis5595_write_value(data, SIS5595_REG_TEMP_OVER, data->temp_over); |
317 | mutex_unlock(&data->update_lock); | 299 | mutex_unlock(&data->update_lock); |
318 | return count; | 300 | return count; |
319 | } | 301 | } |
@@ -326,13 +308,12 @@ static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, | |||
326 | 308 | ||
327 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 309 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
328 | { | 310 | { |
329 | struct i2c_client *client = to_i2c_client(dev); | 311 | struct sis5595_data *data = dev_get_drvdata(dev); |
330 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
331 | long val = simple_strtol(buf, NULL, 10); | 312 | long val = simple_strtol(buf, NULL, 10); |
332 | 313 | ||
333 | mutex_lock(&data->update_lock); | 314 | mutex_lock(&data->update_lock); |
334 | data->temp_hyst = TEMP_TO_REG(val); | 315 | data->temp_hyst = TEMP_TO_REG(val); |
335 | sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst); | 316 | sis5595_write_value(data, SIS5595_REG_TEMP_HYST, data->temp_hyst); |
336 | mutex_unlock(&data->update_lock); | 317 | mutex_unlock(&data->update_lock); |
337 | return count; | 318 | return count; |
338 | } | 319 | } |
@@ -344,37 +325,47 @@ static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, | |||
344 | show_temp_hyst, set_temp_hyst); | 325 | show_temp_hyst, set_temp_hyst); |
345 | 326 | ||
346 | /* 2 Fans */ | 327 | /* 2 Fans */ |
347 | static ssize_t show_fan(struct device *dev, char *buf, int nr) | 328 | static ssize_t show_fan(struct device *dev, struct device_attribute *da, |
329 | char *buf) | ||
348 | { | 330 | { |
349 | struct sis5595_data *data = sis5595_update_device(dev); | 331 | struct sis5595_data *data = sis5595_update_device(dev); |
332 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
333 | int nr = attr->index; | ||
350 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 334 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], |
351 | DIV_FROM_REG(data->fan_div[nr])) ); | 335 | DIV_FROM_REG(data->fan_div[nr])) ); |
352 | } | 336 | } |
353 | 337 | ||
354 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) | 338 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, |
339 | char *buf) | ||
355 | { | 340 | { |
356 | struct sis5595_data *data = sis5595_update_device(dev); | 341 | struct sis5595_data *data = sis5595_update_device(dev); |
342 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
343 | int nr = attr->index; | ||
357 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], | 344 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], |
358 | DIV_FROM_REG(data->fan_div[nr])) ); | 345 | DIV_FROM_REG(data->fan_div[nr])) ); |
359 | } | 346 | } |
360 | 347 | ||
361 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 348 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, |
362 | size_t count, int nr) | 349 | const char *buf, size_t count) |
363 | { | 350 | { |
364 | struct i2c_client *client = to_i2c_client(dev); | 351 | struct sis5595_data *data = dev_get_drvdata(dev); |
365 | struct sis5595_data *data = i2c_get_clientdata(client); | 352 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
353 | int nr = attr->index; | ||
366 | unsigned long val = simple_strtoul(buf, NULL, 10); | 354 | unsigned long val = simple_strtoul(buf, NULL, 10); |
367 | 355 | ||
368 | mutex_lock(&data->update_lock); | 356 | mutex_lock(&data->update_lock); |
369 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 357 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
370 | sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); | 358 | sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); |
371 | mutex_unlock(&data->update_lock); | 359 | mutex_unlock(&data->update_lock); |
372 | return count; | 360 | return count; |
373 | } | 361 | } |
374 | 362 | ||
375 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) | 363 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, |
364 | char *buf) | ||
376 | { | 365 | { |
377 | struct sis5595_data *data = sis5595_update_device(dev); | 366 | struct sis5595_data *data = sis5595_update_device(dev); |
367 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
368 | int nr = attr->index; | ||
378 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); | 369 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); |
379 | } | 370 | } |
380 | 371 | ||
@@ -382,11 +373,12 @@ static ssize_t show_fan_div(struct device *dev, char *buf, int nr) | |||
382 | determined in part by the fan divisor. This follows the principle of | 373 | determined in part by the fan divisor. This follows the principle of |
383 | least surprise; the user doesn't expect the fan minimum to change just | 374 | least surprise; the user doesn't expect the fan minimum to change just |
384 | because the divisor changed. */ | 375 | because the divisor changed. */ |
385 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 376 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, |
386 | size_t count, int nr) | 377 | const char *buf, size_t count) |
387 | { | 378 | { |
388 | struct i2c_client *client = to_i2c_client(dev); | 379 | struct sis5595_data *data = dev_get_drvdata(dev); |
389 | struct sis5595_data *data = i2c_get_clientdata(client); | 380 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
381 | int nr = attr->index; | ||
390 | unsigned long min; | 382 | unsigned long min; |
391 | unsigned long val = simple_strtoul(buf, NULL, 10); | 383 | unsigned long val = simple_strtoul(buf, NULL, 10); |
392 | int reg; | 384 | int reg; |
@@ -394,7 +386,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
394 | mutex_lock(&data->update_lock); | 386 | mutex_lock(&data->update_lock); |
395 | min = FAN_FROM_REG(data->fan_min[nr], | 387 | min = FAN_FROM_REG(data->fan_min[nr], |
396 | DIV_FROM_REG(data->fan_div[nr])); | 388 | DIV_FROM_REG(data->fan_div[nr])); |
397 | reg = sis5595_read_value(client, SIS5595_REG_FANDIV); | 389 | reg = sis5595_read_value(data, SIS5595_REG_FANDIV); |
398 | 390 | ||
399 | switch (val) { | 391 | switch (val) { |
400 | case 1: data->fan_div[nr] = 0; break; | 392 | case 1: data->fan_div[nr] = 0; break; |
@@ -402,7 +394,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
402 | case 4: data->fan_div[nr] = 2; break; | 394 | case 4: data->fan_div[nr] = 2; break; |
403 | case 8: data->fan_div[nr] = 3; break; | 395 | case 8: data->fan_div[nr] = 3; break; |
404 | default: | 396 | default: |
405 | dev_err(&client->dev, "fan_div value %ld not " | 397 | dev_err(dev, "fan_div value %ld not " |
406 | "supported. Choose one of 1, 2, 4 or 8!\n", val); | 398 | "supported. Choose one of 1, 2, 4 or 8!\n", val); |
407 | mutex_unlock(&data->update_lock); | 399 | mutex_unlock(&data->update_lock); |
408 | return -EINVAL; | 400 | return -EINVAL; |
@@ -416,55 +408,25 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
416 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); | 408 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); |
417 | break; | 409 | break; |
418 | } | 410 | } |
419 | sis5595_write_value(client, SIS5595_REG_FANDIV, reg); | 411 | sis5595_write_value(data, SIS5595_REG_FANDIV, reg); |
420 | data->fan_min[nr] = | 412 | data->fan_min[nr] = |
421 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 413 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
422 | sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); | 414 | sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); |
423 | mutex_unlock(&data->update_lock); | 415 | mutex_unlock(&data->update_lock); |
424 | return count; | 416 | return count; |
425 | } | 417 | } |
426 | 418 | ||
427 | #define show_fan_offset(offset) \ | 419 | #define show_fan_offset(offset) \ |
428 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 420 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
429 | { \ | 421 | show_fan, NULL, offset - 1); \ |
430 | return show_fan(dev, buf, offset - 1); \ | 422 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
431 | } \ | 423 | show_fan_min, set_fan_min, offset - 1); \ |
432 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 424 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
433 | { \ | 425 | show_fan_div, set_fan_div, offset - 1); |
434 | return show_fan_min(dev, buf, offset - 1); \ | ||
435 | } \ | ||
436 | static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
437 | { \ | ||
438 | return show_fan_div(dev, buf, offset - 1); \ | ||
439 | } \ | ||
440 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
441 | const char *buf, size_t count) \ | ||
442 | { \ | ||
443 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
444 | } \ | ||
445 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ | ||
446 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
447 | show_fan_##offset##_min, set_fan_##offset##_min); | ||
448 | 426 | ||
449 | show_fan_offset(1); | 427 | show_fan_offset(1); |
450 | show_fan_offset(2); | 428 | show_fan_offset(2); |
451 | 429 | ||
452 | static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf, | ||
453 | size_t count) | ||
454 | { | ||
455 | return set_fan_div(dev, buf, count, 0) ; | ||
456 | } | ||
457 | |||
458 | static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf, | ||
459 | size_t count) | ||
460 | { | ||
461 | return set_fan_div(dev, buf, count, 1) ; | ||
462 | } | ||
463 | static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, | ||
464 | show_fan_1_div, set_fan_1_div); | ||
465 | static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, | ||
466 | show_fan_2_div, set_fan_2_div); | ||
467 | |||
468 | /* Alarms */ | 430 | /* Alarms */ |
469 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 431 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) |
470 | { | 432 | { |
@@ -473,28 +435,37 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
473 | } | 435 | } |
474 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 436 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
475 | 437 | ||
438 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
439 | char *buf) | ||
440 | { | ||
441 | struct sis5595_data *data = dev_get_drvdata(dev); | ||
442 | return sprintf(buf, "%s\n", data->name); | ||
443 | } | ||
444 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
445 | |||
476 | static struct attribute *sis5595_attributes[] = { | 446 | static struct attribute *sis5595_attributes[] = { |
477 | &dev_attr_in0_input.attr, | 447 | &sensor_dev_attr_in0_input.dev_attr.attr, |
478 | &dev_attr_in0_min.attr, | 448 | &sensor_dev_attr_in0_min.dev_attr.attr, |
479 | &dev_attr_in0_max.attr, | 449 | &sensor_dev_attr_in0_max.dev_attr.attr, |
480 | &dev_attr_in1_input.attr, | 450 | &sensor_dev_attr_in1_input.dev_attr.attr, |
481 | &dev_attr_in1_min.attr, | 451 | &sensor_dev_attr_in1_min.dev_attr.attr, |
482 | &dev_attr_in1_max.attr, | 452 | &sensor_dev_attr_in1_max.dev_attr.attr, |
483 | &dev_attr_in2_input.attr, | 453 | &sensor_dev_attr_in2_input.dev_attr.attr, |
484 | &dev_attr_in2_min.attr, | 454 | &sensor_dev_attr_in2_min.dev_attr.attr, |
485 | &dev_attr_in2_max.attr, | 455 | &sensor_dev_attr_in2_max.dev_attr.attr, |
486 | &dev_attr_in3_input.attr, | 456 | &sensor_dev_attr_in3_input.dev_attr.attr, |
487 | &dev_attr_in3_min.attr, | 457 | &sensor_dev_attr_in3_min.dev_attr.attr, |
488 | &dev_attr_in3_max.attr, | 458 | &sensor_dev_attr_in3_max.dev_attr.attr, |
489 | 459 | ||
490 | &dev_attr_fan1_input.attr, | 460 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
491 | &dev_attr_fan1_min.attr, | 461 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
492 | &dev_attr_fan1_div.attr, | 462 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
493 | &dev_attr_fan2_input.attr, | 463 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
494 | &dev_attr_fan2_min.attr, | 464 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
495 | &dev_attr_fan2_div.attr, | 465 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
496 | 466 | ||
497 | &dev_attr_alarms.attr, | 467 | &dev_attr_alarms.attr, |
468 | &dev_attr_name.attr, | ||
498 | NULL | 469 | NULL |
499 | }; | 470 | }; |
500 | 471 | ||
@@ -503,9 +474,9 @@ static const struct attribute_group sis5595_group = { | |||
503 | }; | 474 | }; |
504 | 475 | ||
505 | static struct attribute *sis5595_attributes_opt[] = { | 476 | static struct attribute *sis5595_attributes_opt[] = { |
506 | &dev_attr_in4_input.attr, | 477 | &sensor_dev_attr_in4_input.dev_attr.attr, |
507 | &dev_attr_in4_min.attr, | 478 | &sensor_dev_attr_in4_min.dev_attr.attr, |
508 | &dev_attr_in4_max.attr, | 479 | &sensor_dev_attr_in4_max.dev_attr.attr, |
509 | 480 | ||
510 | &dev_attr_temp1_input.attr, | 481 | &dev_attr_temp1_input.attr, |
511 | &dev_attr_temp1_max.attr, | 482 | &dev_attr_temp1_max.attr, |
@@ -518,68 +489,35 @@ static const struct attribute_group sis5595_group_opt = { | |||
518 | }; | 489 | }; |
519 | 490 | ||
520 | /* This is called when the module is loaded */ | 491 | /* This is called when the module is loaded */ |
521 | static int sis5595_detect(struct i2c_adapter *adapter) | 492 | static int __devinit sis5595_probe(struct platform_device *pdev) |
522 | { | 493 | { |
523 | int err = 0; | 494 | int err = 0; |
524 | int i; | 495 | int i; |
525 | struct i2c_client *new_client; | ||
526 | struct sis5595_data *data; | 496 | struct sis5595_data *data; |
497 | struct resource *res; | ||
527 | char val; | 498 | char val; |
528 | u16 a; | ||
529 | 499 | ||
530 | if (force_addr) | ||
531 | address = force_addr & ~(SIS5595_EXTENT - 1); | ||
532 | /* Reserve the ISA region */ | 500 | /* Reserve the ISA region */ |
533 | if (!request_region(address, SIS5595_EXTENT, | 501 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
502 | if (!request_region(res->start, SIS5595_EXTENT, | ||
534 | sis5595_driver.driver.name)) { | 503 | sis5595_driver.driver.name)) { |
535 | err = -EBUSY; | 504 | err = -EBUSY; |
536 | goto exit; | 505 | goto exit; |
537 | } | 506 | } |
538 | if (force_addr) { | ||
539 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address); | ||
540 | if (PCIBIOS_SUCCESSFUL != | ||
541 | pci_write_config_word(s_bridge, SIS5595_BASE_REG, address)) | ||
542 | goto exit_release; | ||
543 | if (PCIBIOS_SUCCESSFUL != | ||
544 | pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a)) | ||
545 | goto exit_release; | ||
546 | if ((a & ~(SIS5595_EXTENT - 1)) != address) | ||
547 | /* doesn't work for some chips? */ | ||
548 | goto exit_release; | ||
549 | } | ||
550 | |||
551 | if (PCIBIOS_SUCCESSFUL != | ||
552 | pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) { | ||
553 | goto exit_release; | ||
554 | } | ||
555 | if ((val & 0x80) == 0) { | ||
556 | if (PCIBIOS_SUCCESSFUL != | ||
557 | pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG, | ||
558 | val | 0x80)) | ||
559 | goto exit_release; | ||
560 | if (PCIBIOS_SUCCESSFUL != | ||
561 | pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) | ||
562 | goto exit_release; | ||
563 | if ((val & 0x80) == 0) | ||
564 | /* doesn't work for some chips! */ | ||
565 | goto exit_release; | ||
566 | } | ||
567 | 507 | ||
568 | if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { | 508 | if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { |
569 | err = -ENOMEM; | 509 | err = -ENOMEM; |
570 | goto exit_release; | 510 | goto exit_release; |
571 | } | 511 | } |
572 | 512 | ||
573 | new_client = &data->client; | ||
574 | new_client->addr = address; | ||
575 | mutex_init(&data->lock); | 513 | mutex_init(&data->lock); |
576 | i2c_set_clientdata(new_client, data); | 514 | mutex_init(&data->update_lock); |
577 | new_client->adapter = adapter; | 515 | data->addr = res->start; |
578 | new_client->driver = &sis5595_driver; | 516 | data->name = "sis5595"; |
579 | new_client->flags = 0; | 517 | platform_set_drvdata(pdev, data); |
580 | 518 | ||
581 | /* 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 */ |
582 | pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision)); | 520 | pci_read_config_byte(s_bridge, PCI_REVISION_ID, &data->revision); |
583 | /* 4 voltages, 1 temp */ | 521 | /* 4 voltages, 1 temp */ |
584 | data->maxins = 3; | 522 | data->maxins = 3; |
585 | if (data->revision >= REV2MIN) { | 523 | if (data->revision >= REV2MIN) { |
@@ -589,47 +527,37 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
589 | data->maxins = 4; | 527 | data->maxins = 4; |
590 | } | 528 | } |
591 | 529 | ||
592 | /* Fill in the remaining client fields and put it into the global list */ | ||
593 | strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE); | ||
594 | |||
595 | data->valid = 0; | ||
596 | mutex_init(&data->update_lock); | ||
597 | |||
598 | /* Tell the I2C layer a new client has arrived */ | ||
599 | if ((err = i2c_attach_client(new_client))) | ||
600 | goto exit_free; | ||
601 | |||
602 | /* Initialize the SIS5595 chip */ | 530 | /* Initialize the SIS5595 chip */ |
603 | sis5595_init_client(new_client); | 531 | sis5595_init_device(data); |
604 | 532 | ||
605 | /* A few vars need to be filled upon startup */ | 533 | /* A few vars need to be filled upon startup */ |
606 | for (i = 0; i < 2; i++) { | 534 | for (i = 0; i < 2; i++) { |
607 | data->fan_min[i] = sis5595_read_value(new_client, | 535 | data->fan_min[i] = sis5595_read_value(data, |
608 | SIS5595_REG_FAN_MIN(i)); | 536 | SIS5595_REG_FAN_MIN(i)); |
609 | } | 537 | } |
610 | 538 | ||
611 | /* Register sysfs hooks */ | 539 | /* Register sysfs hooks */ |
612 | if ((err = sysfs_create_group(&new_client->dev.kobj, &sis5595_group))) | 540 | if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) |
613 | goto exit_detach; | 541 | goto exit_free; |
614 | if (data->maxins == 4) { | 542 | if (data->maxins == 4) { |
615 | if ((err = device_create_file(&new_client->dev, | 543 | if ((err = device_create_file(&pdev->dev, |
616 | &dev_attr_in4_input)) | 544 | &sensor_dev_attr_in4_input.dev_attr)) |
617 | || (err = device_create_file(&new_client->dev, | 545 | || (err = device_create_file(&pdev->dev, |
618 | &dev_attr_in4_min)) | 546 | &sensor_dev_attr_in4_min.dev_attr)) |
619 | || (err = device_create_file(&new_client->dev, | 547 | || (err = device_create_file(&pdev->dev, |
620 | &dev_attr_in4_max))) | 548 | &sensor_dev_attr_in4_max.dev_attr))) |
621 | goto exit_remove_files; | 549 | goto exit_remove_files; |
622 | } else { | 550 | } else { |
623 | if ((err = device_create_file(&new_client->dev, | 551 | if ((err = device_create_file(&pdev->dev, |
624 | &dev_attr_temp1_input)) | 552 | &dev_attr_temp1_input)) |
625 | || (err = device_create_file(&new_client->dev, | 553 | || (err = device_create_file(&pdev->dev, |
626 | &dev_attr_temp1_max)) | 554 | &dev_attr_temp1_max)) |
627 | || (err = device_create_file(&new_client->dev, | 555 | || (err = device_create_file(&pdev->dev, |
628 | &dev_attr_temp1_max_hyst))) | 556 | &dev_attr_temp1_max_hyst))) |
629 | goto exit_remove_files; | 557 | goto exit_remove_files; |
630 | } | 558 | } |
631 | 559 | ||
632 | data->class_dev = hwmon_device_register(&new_client->dev); | 560 | data->class_dev = hwmon_device_register(&pdev->dev); |
633 | if (IS_ERR(data->class_dev)) { | 561 | if (IS_ERR(data->class_dev)) { |
634 | err = PTR_ERR(data->class_dev); | 562 | err = PTR_ERR(data->class_dev); |
635 | goto exit_remove_files; | 563 | goto exit_remove_files; |
@@ -638,32 +566,26 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
638 | return 0; | 566 | return 0; |
639 | 567 | ||
640 | exit_remove_files: | 568 | exit_remove_files: |
641 | sysfs_remove_group(&new_client->dev.kobj, &sis5595_group); | 569 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
642 | sysfs_remove_group(&new_client->dev.kobj, &sis5595_group_opt); | 570 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
643 | exit_detach: | ||
644 | i2c_detach_client(new_client); | ||
645 | exit_free: | 571 | exit_free: |
646 | kfree(data); | 572 | kfree(data); |
647 | exit_release: | 573 | exit_release: |
648 | release_region(address, SIS5595_EXTENT); | 574 | release_region(res->start, SIS5595_EXTENT); |
649 | exit: | 575 | exit: |
650 | return err; | 576 | return err; |
651 | } | 577 | } |
652 | 578 | ||
653 | static int sis5595_detach_client(struct i2c_client *client) | 579 | static int __devexit sis5595_remove(struct platform_device *pdev) |
654 | { | 580 | { |
655 | struct sis5595_data *data = i2c_get_clientdata(client); | 581 | struct sis5595_data *data = platform_get_drvdata(pdev); |
656 | int err; | ||
657 | 582 | ||
658 | hwmon_device_unregister(data->class_dev); | 583 | hwmon_device_unregister(data->class_dev); |
659 | sysfs_remove_group(&client->dev.kobj, &sis5595_group); | 584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
660 | sysfs_remove_group(&client->dev.kobj, &sis5595_group_opt); | 585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
661 | |||
662 | if ((err = i2c_detach_client(client))) | ||
663 | return err; | ||
664 | |||
665 | release_region(client->addr, SIS5595_EXTENT); | ||
666 | 586 | ||
587 | release_region(data->addr, SIS5595_EXTENT); | ||
588 | platform_set_drvdata(pdev, NULL); | ||
667 | kfree(data); | 589 | kfree(data); |
668 | 590 | ||
669 | return 0; | 591 | return 0; |
@@ -671,41 +593,37 @@ static int sis5595_detach_client(struct i2c_client *client) | |||
671 | 593 | ||
672 | 594 | ||
673 | /* ISA access must be locked explicitly. */ | 595 | /* ISA access must be locked explicitly. */ |
674 | static int sis5595_read_value(struct i2c_client *client, u8 reg) | 596 | static int sis5595_read_value(struct sis5595_data *data, u8 reg) |
675 | { | 597 | { |
676 | int res; | 598 | int res; |
677 | 599 | ||
678 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
679 | mutex_lock(&data->lock); | 600 | mutex_lock(&data->lock); |
680 | outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); | 601 | outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET); |
681 | res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET); | 602 | res = inb_p(data->addr + SIS5595_DATA_REG_OFFSET); |
682 | mutex_unlock(&data->lock); | 603 | mutex_unlock(&data->lock); |
683 | return res; | 604 | return res; |
684 | } | 605 | } |
685 | 606 | ||
686 | static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) | 607 | static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value) |
687 | { | 608 | { |
688 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
689 | mutex_lock(&data->lock); | 609 | mutex_lock(&data->lock); |
690 | outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); | 610 | outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET); |
691 | outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET); | 611 | outb_p(value, data->addr + SIS5595_DATA_REG_OFFSET); |
692 | mutex_unlock(&data->lock); | 612 | mutex_unlock(&data->lock); |
693 | return 0; | ||
694 | } | 613 | } |
695 | 614 | ||
696 | /* Called when we have found a new SIS5595. */ | 615 | /* Called when we have found a new SIS5595. */ |
697 | static void sis5595_init_client(struct i2c_client *client) | 616 | static void __devinit sis5595_init_device(struct sis5595_data *data) |
698 | { | 617 | { |
699 | u8 config = sis5595_read_value(client, SIS5595_REG_CONFIG); | 618 | u8 config = sis5595_read_value(data, SIS5595_REG_CONFIG); |
700 | if (!(config & 0x01)) | 619 | if (!(config & 0x01)) |
701 | sis5595_write_value(client, SIS5595_REG_CONFIG, | 620 | sis5595_write_value(data, SIS5595_REG_CONFIG, |
702 | (config & 0xf7) | 0x01); | 621 | (config & 0xf7) | 0x01); |
703 | } | 622 | } |
704 | 623 | ||
705 | static struct sis5595_data *sis5595_update_device(struct device *dev) | 624 | static struct sis5595_data *sis5595_update_device(struct device *dev) |
706 | { | 625 | { |
707 | struct i2c_client *client = to_i2c_client(dev); | 626 | struct sis5595_data *data = dev_get_drvdata(dev); |
708 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
709 | int i; | 627 | int i; |
710 | 628 | ||
711 | mutex_lock(&data->update_lock); | 629 | mutex_lock(&data->update_lock); |
@@ -715,35 +633,35 @@ static struct sis5595_data *sis5595_update_device(struct device *dev) | |||
715 | 633 | ||
716 | for (i = 0; i <= data->maxins; i++) { | 634 | for (i = 0; i <= data->maxins; i++) { |
717 | data->in[i] = | 635 | data->in[i] = |
718 | sis5595_read_value(client, SIS5595_REG_IN(i)); | 636 | sis5595_read_value(data, SIS5595_REG_IN(i)); |
719 | data->in_min[i] = | 637 | data->in_min[i] = |
720 | sis5595_read_value(client, | 638 | sis5595_read_value(data, |
721 | SIS5595_REG_IN_MIN(i)); | 639 | SIS5595_REG_IN_MIN(i)); |
722 | data->in_max[i] = | 640 | data->in_max[i] = |
723 | sis5595_read_value(client, | 641 | sis5595_read_value(data, |
724 | SIS5595_REG_IN_MAX(i)); | 642 | SIS5595_REG_IN_MAX(i)); |
725 | } | 643 | } |
726 | for (i = 0; i < 2; i++) { | 644 | for (i = 0; i < 2; i++) { |
727 | data->fan[i] = | 645 | data->fan[i] = |
728 | sis5595_read_value(client, SIS5595_REG_FAN(i)); | 646 | sis5595_read_value(data, SIS5595_REG_FAN(i)); |
729 | data->fan_min[i] = | 647 | data->fan_min[i] = |
730 | sis5595_read_value(client, | 648 | sis5595_read_value(data, |
731 | SIS5595_REG_FAN_MIN(i)); | 649 | SIS5595_REG_FAN_MIN(i)); |
732 | } | 650 | } |
733 | if (data->maxins == 3) { | 651 | if (data->maxins == 3) { |
734 | data->temp = | 652 | data->temp = |
735 | sis5595_read_value(client, SIS5595_REG_TEMP); | 653 | sis5595_read_value(data, SIS5595_REG_TEMP); |
736 | data->temp_over = | 654 | data->temp_over = |
737 | sis5595_read_value(client, SIS5595_REG_TEMP_OVER); | 655 | sis5595_read_value(data, SIS5595_REG_TEMP_OVER); |
738 | data->temp_hyst = | 656 | data->temp_hyst = |
739 | sis5595_read_value(client, SIS5595_REG_TEMP_HYST); | 657 | sis5595_read_value(data, SIS5595_REG_TEMP_HYST); |
740 | } | 658 | } |
741 | i = sis5595_read_value(client, SIS5595_REG_FANDIV); | 659 | i = sis5595_read_value(data, SIS5595_REG_FANDIV); |
742 | data->fan_div[0] = (i >> 4) & 0x03; | 660 | data->fan_div[0] = (i >> 4) & 0x03; |
743 | data->fan_div[1] = i >> 6; | 661 | data->fan_div[1] = i >> 6; |
744 | data->alarms = | 662 | data->alarms = |
745 | sis5595_read_value(client, SIS5595_REG_ALARM1) | | 663 | sis5595_read_value(data, SIS5595_REG_ALARM1) | |
746 | (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8); | 664 | (sis5595_read_value(data, SIS5595_REG_ALARM2) << 8); |
747 | data->last_updated = jiffies; | 665 | data->last_updated = jiffies; |
748 | data->valid = 1; | 666 | data->valid = 1; |
749 | } | 667 | } |
@@ -774,10 +692,50 @@ static int blacklist[] __devinitdata = { | |||
774 | PCI_DEVICE_ID_SI_5598, | 692 | PCI_DEVICE_ID_SI_5598, |
775 | 0 }; | 693 | 0 }; |
776 | 694 | ||
695 | static int __devinit sis5595_device_add(unsigned short address) | ||
696 | { | ||
697 | struct resource res = { | ||
698 | .start = address, | ||
699 | .end = address + SIS5595_EXTENT - 1, | ||
700 | .name = "sis5595", | ||
701 | .flags = IORESOURCE_IO, | ||
702 | }; | ||
703 | int err; | ||
704 | |||
705 | pdev = platform_device_alloc("sis5595", address); | ||
706 | if (!pdev) { | ||
707 | err = -ENOMEM; | ||
708 | printk(KERN_ERR "sis5595: Device allocation failed\n"); | ||
709 | goto exit; | ||
710 | } | ||
711 | |||
712 | err = platform_device_add_resources(pdev, &res, 1); | ||
713 | if (err) { | ||
714 | printk(KERN_ERR "sis5595: Device resource addition failed " | ||
715 | "(%d)\n", err); | ||
716 | goto exit_device_put; | ||
717 | } | ||
718 | |||
719 | err = platform_device_add(pdev); | ||
720 | if (err) { | ||
721 | printk(KERN_ERR "sis5595: Device addition failed (%d)\n", | ||
722 | err); | ||
723 | goto exit_device_put; | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | |||
728 | exit_device_put: | ||
729 | platform_device_put(pdev); | ||
730 | exit: | ||
731 | return err; | ||
732 | } | ||
733 | |||
777 | static int __devinit sis5595_pci_probe(struct pci_dev *dev, | 734 | static int __devinit sis5595_pci_probe(struct pci_dev *dev, |
778 | const struct pci_device_id *id) | 735 | const struct pci_device_id *id) |
779 | { | 736 | { |
780 | u16 val; | 737 | u16 address; |
738 | u8 enable; | ||
781 | int *i; | 739 | int *i; |
782 | 740 | ||
783 | for (i = blacklist; *i != 0; i++) { | 741 | for (i = blacklist; *i != 0; i++) { |
@@ -790,27 +748,68 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, | |||
790 | } | 748 | } |
791 | } | 749 | } |
792 | 750 | ||
751 | force_addr &= ~(SIS5595_EXTENT - 1); | ||
752 | if (force_addr) { | ||
753 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", force_addr); | ||
754 | pci_write_config_word(dev, SIS5595_BASE_REG, force_addr); | ||
755 | } | ||
756 | |||
793 | if (PCIBIOS_SUCCESSFUL != | 757 | if (PCIBIOS_SUCCESSFUL != |
794 | pci_read_config_word(dev, SIS5595_BASE_REG, &val)) | 758 | pci_read_config_word(dev, SIS5595_BASE_REG, &address)) { |
759 | dev_err(&dev->dev, "Failed to read ISA address\n"); | ||
795 | return -ENODEV; | 760 | return -ENODEV; |
761 | } | ||
796 | 762 | ||
797 | address = val & ~(SIS5595_EXTENT - 1); | 763 | address &= ~(SIS5595_EXTENT - 1); |
798 | if (address == 0 && force_addr == 0) { | 764 | if (!address) { |
799 | dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); | 765 | dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); |
800 | return -ENODEV; | 766 | return -ENODEV; |
801 | } | 767 | } |
768 | if (force_addr && address != force_addr) { | ||
769 | /* doesn't work for some chips? */ | ||
770 | dev_err(&dev->dev, "Failed to force ISA address\n"); | ||
771 | return -ENODEV; | ||
772 | } | ||
802 | 773 | ||
803 | s_bridge = pci_dev_get(dev); | 774 | if (PCIBIOS_SUCCESSFUL != |
804 | if (i2c_isa_add_driver(&sis5595_driver)) { | 775 | pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable)) { |
805 | pci_dev_put(s_bridge); | 776 | dev_err(&dev->dev, "Failed to read enable register\n"); |
806 | s_bridge = NULL; | 777 | return -ENODEV; |
778 | } | ||
779 | if (!(enable & 0x80)) { | ||
780 | if ((PCIBIOS_SUCCESSFUL != | ||
781 | pci_write_config_byte(dev, SIS5595_ENABLE_REG, | ||
782 | enable | 0x80)) | ||
783 | || (PCIBIOS_SUCCESSFUL != | ||
784 | pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable)) | ||
785 | || (!(enable & 0x80))) { | ||
786 | /* doesn't work for some chips! */ | ||
787 | dev_err(&dev->dev, "Failed to enable HWM device\n"); | ||
788 | return -ENODEV; | ||
789 | } | ||
807 | } | 790 | } |
808 | 791 | ||
792 | if (platform_driver_register(&sis5595_driver)) { | ||
793 | dev_dbg(&dev->dev, "Failed to register sis5595 driver\n"); | ||
794 | goto exit; | ||
795 | } | ||
796 | |||
797 | s_bridge = pci_dev_get(dev); | ||
798 | /* Sets global pdev as a side effect */ | ||
799 | if (sis5595_device_add(address)) | ||
800 | goto exit_unregister; | ||
801 | |||
809 | /* Always return failure here. This is to allow other drivers to bind | 802 | /* Always return failure here. This is to allow other drivers to bind |
810 | * to this pci device. We don't really want to have control over the | 803 | * to this pci device. We don't really want to have control over the |
811 | * pci device, we only wanted to read as few register values from it. | 804 | * pci device, we only wanted to read as few register values from it. |
812 | */ | 805 | */ |
813 | return -ENODEV; | 806 | return -ENODEV; |
807 | |||
808 | exit_unregister: | ||
809 | pci_dev_put(dev); | ||
810 | platform_driver_unregister(&sis5595_driver); | ||
811 | exit: | ||
812 | return -ENODEV; | ||
814 | } | 813 | } |
815 | 814 | ||
816 | static struct pci_driver sis5595_pci_driver = { | 815 | static struct pci_driver sis5595_pci_driver = { |
@@ -828,7 +827,8 @@ static void __exit sm_sis5595_exit(void) | |||
828 | { | 827 | { |
829 | pci_unregister_driver(&sis5595_pci_driver); | 828 | pci_unregister_driver(&sis5595_pci_driver); |
830 | if (s_bridge != NULL) { | 829 | if (s_bridge != NULL) { |
831 | i2c_isa_del_driver(&sis5595_driver); | 830 | platform_device_unregister(pdev); |
831 | platform_driver_unregister(&sis5595_driver); | ||
832 | pci_dev_put(s_bridge); | 832 | pci_dev_put(s_bridge); |
833 | s_bridge = NULL; | 833 | s_bridge = NULL; |
834 | } | 834 | } |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 943abbd95ab5..45266b30ce1d 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -174,6 +174,8 @@ static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | |||
174 | REG: count of 90kHz pulses / revolution */ | 174 | REG: count of 90kHz pulses / revolution */ |
175 | static int fan_from_reg(u16 reg) | 175 | static int fan_from_reg(u16 reg) |
176 | { | 176 | { |
177 | if (reg == 0 || reg == 0xffff) | ||
178 | return 0; | ||
177 | return 90000 * 60 / reg; | 179 | return 90000 * 60 / reg; |
178 | } | 180 | } |
179 | 181 | ||
@@ -333,7 +335,7 @@ static int __init smsc47b397_find(unsigned short *addr) | |||
333 | superio_enter(); | 335 | superio_enter(); |
334 | id = superio_inb(SUPERIO_REG_DEVID); | 336 | id = superio_inb(SUPERIO_REG_DEVID); |
335 | 337 | ||
336 | if ((id != 0x6f) && (id != 0x81)) { | 338 | if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) { |
337 | superio_exit(); | 339 | superio_exit(); |
338 | return -ENODEV; | 340 | return -ENODEV; |
339 | } | 341 | } |
@@ -346,7 +348,8 @@ static int __init smsc47b397_find(unsigned short *addr) | |||
346 | 348 | ||
347 | printk(KERN_INFO DRVNAME ": found SMSC %s " | 349 | printk(KERN_INFO DRVNAME ": found SMSC %s " |
348 | "(base address 0x%04x, revision %u)\n", | 350 | "(base address 0x%04x, revision %u)\n", |
349 | id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); | 351 | id == 0x81 ? "SCH5307-NS" : id == 0x85 ? "SCH5317" : |
352 | "LPC47B397-NC", *addr, rev); | ||
350 | 353 | ||
351 | superio_exit(); | 354 | superio_exit(); |
352 | return 0; | 355 | return 0; |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 1e21c8cc948f..1de2f2be8708 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -597,6 +597,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
597 | error_remove_files: | 597 | error_remove_files: |
598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); | 598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); |
599 | error_free: | 599 | error_free: |
600 | platform_set_drvdata(pdev, NULL); | ||
600 | kfree(data); | 601 | kfree(data); |
601 | error_release: | 602 | error_release: |
602 | release_region(res->start, SMSC_EXTENT); | 603 | release_region(res->start, SMSC_EXTENT); |
@@ -608,12 +609,12 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev) | |||
608 | struct smsc47m1_data *data = platform_get_drvdata(pdev); | 609 | struct smsc47m1_data *data = platform_get_drvdata(pdev); |
609 | struct resource *res; | 610 | struct resource *res; |
610 | 611 | ||
611 | platform_set_drvdata(pdev, NULL); | ||
612 | hwmon_device_unregister(data->class_dev); | 612 | hwmon_device_unregister(data->class_dev); |
613 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); | 613 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); |
614 | 614 | ||
615 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 615 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
616 | release_region(res->start, SMSC_EXTENT); | 616 | release_region(res->start, SMSC_EXTENT); |
617 | platform_set_drvdata(pdev, NULL); | ||
617 | kfree(data); | 618 | kfree(data); |
618 | 619 | ||
619 | return 0; | 620 | return 0; |
@@ -693,15 +694,12 @@ static int __init smsc47m1_device_add(unsigned short address, | |||
693 | goto exit_device_put; | 694 | goto exit_device_put; |
694 | } | 695 | } |
695 | 696 | ||
696 | pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data), | 697 | err = platform_device_add_data(pdev, sio_data, |
697 | GFP_KERNEL); | 698 | sizeof(struct smsc47m1_sio_data)); |
698 | if (!pdev->dev.platform_data) { | 699 | if (err) { |
699 | err = -ENOMEM; | ||
700 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 700 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
701 | goto exit_device_put; | 701 | goto exit_device_put; |
702 | } | 702 | } |
703 | memcpy(pdev->dev.platform_data, sio_data, | ||
704 | sizeof(struct smsc47m1_sio_data)); | ||
705 | 703 | ||
706 | err = platform_device_add(pdev); | 704 | err = platform_device_add(pdev); |
707 | if (err) { | 705 | if (err) { |
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index a012f396f354..d3a3ba04cb0f 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/hwmon-vid.h> | 31 | #include <linux/hwmon-vid.h> |
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
34 | #include <linux/mutex.h> | ||
34 | 35 | ||
35 | /* Addresses to scan */ | 36 | /* Addresses to scan */ |
36 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; | 37 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; |
@@ -97,7 +98,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
97 | struct smsc47m192_data { | 98 | struct smsc47m192_data { |
98 | struct i2c_client client; | 99 | struct i2c_client client; |
99 | struct class_device *class_dev; | 100 | struct class_device *class_dev; |
100 | struct semaphore update_lock; | 101 | struct mutex update_lock; |
101 | char valid; /* !=0 if following fields are valid */ | 102 | char valid; /* !=0 if following fields are valid */ |
102 | unsigned long last_updated; /* In jiffies */ | 103 | unsigned long last_updated; /* In jiffies */ |
103 | 104 | ||
@@ -164,11 +165,11 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
164 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 165 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
165 | unsigned long val = simple_strtoul(buf, NULL, 10); | 166 | unsigned long val = simple_strtoul(buf, NULL, 10); |
166 | 167 | ||
167 | down(&data->update_lock); | 168 | mutex_lock(&data->update_lock); |
168 | data->in_min[nr] = IN_TO_REG(val, nr); | 169 | data->in_min[nr] = IN_TO_REG(val, nr); |
169 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), | 170 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), |
170 | data->in_min[nr]); | 171 | data->in_min[nr]); |
171 | up(&data->update_lock); | 172 | mutex_unlock(&data->update_lock); |
172 | return count; | 173 | return count; |
173 | } | 174 | } |
174 | 175 | ||
@@ -181,11 +182,11 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
181 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 182 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
182 | unsigned long val = simple_strtoul(buf, NULL, 10); | 183 | unsigned long val = simple_strtoul(buf, NULL, 10); |
183 | 184 | ||
184 | down(&data->update_lock); | 185 | mutex_lock(&data->update_lock); |
185 | data->in_max[nr] = IN_TO_REG(val, nr); | 186 | data->in_max[nr] = IN_TO_REG(val, nr); |
186 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), | 187 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), |
187 | data->in_max[nr]); | 188 | data->in_max[nr]); |
188 | up(&data->update_lock); | 189 | mutex_unlock(&data->update_lock); |
189 | return count; | 190 | return count; |
190 | } | 191 | } |
191 | 192 | ||
@@ -243,11 +244,11 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
243 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 244 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
244 | long val = simple_strtol(buf, NULL, 10); | 245 | long val = simple_strtol(buf, NULL, 10); |
245 | 246 | ||
246 | down(&data->update_lock); | 247 | mutex_lock(&data->update_lock); |
247 | data->temp_min[nr] = TEMP_TO_REG(val); | 248 | data->temp_min[nr] = TEMP_TO_REG(val); |
248 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], | 249 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], |
249 | data->temp_min[nr]); | 250 | data->temp_min[nr]); |
250 | up(&data->update_lock); | 251 | mutex_unlock(&data->update_lock); |
251 | return count; | 252 | return count; |
252 | } | 253 | } |
253 | 254 | ||
@@ -260,11 +261,11 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
260 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 261 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
261 | long val = simple_strtol(buf, NULL, 10); | 262 | long val = simple_strtol(buf, NULL, 10); |
262 | 263 | ||
263 | down(&data->update_lock); | 264 | mutex_lock(&data->update_lock); |
264 | data->temp_max[nr] = TEMP_TO_REG(val); | 265 | data->temp_max[nr] = TEMP_TO_REG(val); |
265 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], | 266 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], |
266 | data->temp_max[nr]); | 267 | data->temp_max[nr]); |
267 | up(&data->update_lock); | 268 | mutex_unlock(&data->update_lock); |
268 | return count; | 269 | return count; |
269 | } | 270 | } |
270 | 271 | ||
@@ -287,7 +288,7 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute | |||
287 | u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); | 288 | u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); |
288 | long val = simple_strtol(buf, NULL, 10); | 289 | long val = simple_strtol(buf, NULL, 10); |
289 | 290 | ||
290 | down(&data->update_lock); | 291 | mutex_lock(&data->update_lock); |
291 | data->temp_offset[nr] = TEMP_TO_REG(val); | 292 | data->temp_offset[nr] = TEMP_TO_REG(val); |
292 | if (nr>1) | 293 | if (nr>1) |
293 | i2c_smbus_write_byte_data(client, | 294 | i2c_smbus_write_byte_data(client, |
@@ -303,7 +304,7 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute | |||
303 | } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) | 304 | } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) |
304 | i2c_smbus_write_byte_data(client, | 305 | i2c_smbus_write_byte_data(client, |
305 | SMSC47M192_REG_TEMP_OFFSET(nr), 0); | 306 | SMSC47M192_REG_TEMP_OFFSET(nr), 0); |
306 | up(&data->update_lock); | 307 | mutex_unlock(&data->update_lock); |
307 | return count; | 308 | return count; |
308 | } | 309 | } |
309 | 310 | ||
@@ -360,8 +361,8 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
360 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); | 361 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); |
361 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); | 362 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); |
362 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); | 363 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); |
363 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000); | 364 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 0x4000); |
364 | static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000); | 365 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 0x8000); |
365 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); | 366 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); |
366 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); | 367 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); |
367 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); | 368 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); |
@@ -411,13 +412,13 @@ static struct attribute *smsc47m192_attributes[] = { | |||
411 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 412 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
412 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 413 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
413 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 414 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
414 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 415 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
415 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 416 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
416 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 417 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
417 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 418 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
418 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 419 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
419 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 420 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
420 | &sensor_dev_attr_temp3_input_fault.dev_attr.attr, | 421 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
421 | 422 | ||
422 | &dev_attr_cpu0_vid.attr, | 423 | &dev_attr_cpu0_vid.attr, |
423 | &dev_attr_vrm.attr, | 424 | &dev_attr_vrm.attr, |
@@ -531,7 +532,7 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
531 | /* Fill in the remaining client fields and put into the global list */ | 532 | /* Fill in the remaining client fields and put into the global list */ |
532 | strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); | 533 | strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); |
533 | data->vrm = vid_which_vrm(); | 534 | data->vrm = vid_which_vrm(); |
534 | init_MUTEX(&data->update_lock); | 535 | mutex_init(&data->update_lock); |
535 | 536 | ||
536 | /* Tell the I2C layer a new client has arrived */ | 537 | /* Tell the I2C layer a new client has arrived */ |
537 | if ((err = i2c_attach_client(client))) | 538 | if ((err = i2c_attach_client(client))) |
@@ -594,7 +595,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) | |||
594 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 595 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
595 | int i, config; | 596 | int i, config; |
596 | 597 | ||
597 | down(&data->update_lock); | 598 | mutex_lock(&data->update_lock); |
598 | 599 | ||
599 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 600 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
600 | || !data->valid) { | 601 | || !data->valid) { |
@@ -645,7 +646,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) | |||
645 | data->valid = 1; | 646 | data->valid = 1; |
646 | } | 647 | } |
647 | 648 | ||
648 | up(&data->update_lock); | 649 | mutex_unlock(&data->update_lock); |
649 | 650 | ||
650 | return data; | 651 | return data; |
651 | } | 652 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 9a440c8cc520..24a6851491d0 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -34,9 +34,9 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/jiffies.h> | 36 | #include <linux/jiffies.h> |
37 | #include <linux/i2c.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/i2c-isa.h> | ||
39 | #include <linux/hwmon.h> | 38 | #include <linux/hwmon.h> |
39 | #include <linux/hwmon-sysfs.h> | ||
40 | #include <linux/err.h> | 40 | #include <linux/err.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
@@ -51,10 +51,7 @@ module_param(force_addr, ushort, 0); | |||
51 | MODULE_PARM_DESC(force_addr, | 51 | MODULE_PARM_DESC(force_addr, |
52 | "Initialize the base address of the sensors"); | 52 | "Initialize the base address of the sensors"); |
53 | 53 | ||
54 | /* Device address | 54 | static struct platform_device *pdev; |
55 | Note that we can't determine the ISA address until we have initialized | ||
56 | our module */ | ||
57 | static unsigned short address; | ||
58 | 55 | ||
59 | /* | 56 | /* |
60 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. | 57 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. |
@@ -295,7 +292,8 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
295 | /* For each registered chip, we need to keep some data in memory. | 292 | /* For each registered chip, we need to keep some data in memory. |
296 | The structure is dynamically allocated. */ | 293 | The structure is dynamically allocated. */ |
297 | struct via686a_data { | 294 | struct via686a_data { |
298 | struct i2c_client client; | 295 | unsigned short addr; |
296 | const char *name; | ||
299 | struct class_device *class_dev; | 297 | struct class_device *class_dev; |
300 | struct mutex update_lock; | 298 | struct mutex update_lock; |
301 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
@@ -315,98 +313,85 @@ struct via686a_data { | |||
315 | 313 | ||
316 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ | 314 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ |
317 | 315 | ||
318 | static int via686a_detect(struct i2c_adapter *adapter); | 316 | static int via686a_probe(struct platform_device *pdev); |
319 | static int via686a_detach_client(struct i2c_client *client); | 317 | static int via686a_remove(struct platform_device *pdev); |
320 | 318 | ||
321 | static inline int via686a_read_value(struct i2c_client *client, u8 reg) | 319 | static inline int via686a_read_value(struct via686a_data *data, u8 reg) |
322 | { | 320 | { |
323 | return (inb_p(client->addr + reg)); | 321 | return inb_p(data->addr + reg); |
324 | } | 322 | } |
325 | 323 | ||
326 | static inline void via686a_write_value(struct i2c_client *client, u8 reg, | 324 | static inline void via686a_write_value(struct via686a_data *data, u8 reg, |
327 | u8 value) | 325 | u8 value) |
328 | { | 326 | { |
329 | outb_p(value, client->addr + reg); | 327 | outb_p(value, data->addr + reg); |
330 | } | 328 | } |
331 | 329 | ||
332 | static struct via686a_data *via686a_update_device(struct device *dev); | 330 | static struct via686a_data *via686a_update_device(struct device *dev); |
333 | static void via686a_init_client(struct i2c_client *client); | 331 | static void via686a_init_device(struct via686a_data *data); |
334 | 332 | ||
335 | /* following are the sysfs callback functions */ | 333 | /* following are the sysfs callback functions */ |
336 | 334 | ||
337 | /* 7 voltage sensors */ | 335 | /* 7 voltage sensors */ |
338 | static ssize_t show_in(struct device *dev, char *buf, int nr) { | 336 | static ssize_t show_in(struct device *dev, struct device_attribute *da, |
337 | char *buf) { | ||
339 | struct via686a_data *data = via686a_update_device(dev); | 338 | struct via686a_data *data = via686a_update_device(dev); |
339 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
340 | int nr = attr->index; | ||
340 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); | 341 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); |
341 | } | 342 | } |
342 | 343 | ||
343 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) { | 344 | static ssize_t show_in_min(struct device *dev, struct device_attribute *da, |
345 | char *buf) { | ||
344 | struct via686a_data *data = via686a_update_device(dev); | 346 | struct via686a_data *data = via686a_update_device(dev); |
347 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
348 | int nr = attr->index; | ||
345 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); | 349 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); |
346 | } | 350 | } |
347 | 351 | ||
348 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) { | 352 | static ssize_t show_in_max(struct device *dev, struct device_attribute *da, |
353 | char *buf) { | ||
349 | struct via686a_data *data = via686a_update_device(dev); | 354 | struct via686a_data *data = via686a_update_device(dev); |
355 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
356 | int nr = attr->index; | ||
350 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); | 357 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); |
351 | } | 358 | } |
352 | 359 | ||
353 | static ssize_t set_in_min(struct device *dev, const char *buf, | 360 | static ssize_t set_in_min(struct device *dev, struct device_attribute *da, |
354 | size_t count, int nr) { | 361 | const char *buf, size_t count) { |
355 | struct i2c_client *client = to_i2c_client(dev); | 362 | struct via686a_data *data = dev_get_drvdata(dev); |
356 | struct via686a_data *data = i2c_get_clientdata(client); | 363 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
364 | int nr = attr->index; | ||
357 | unsigned long val = simple_strtoul(buf, NULL, 10); | 365 | unsigned long val = simple_strtoul(buf, NULL, 10); |
358 | 366 | ||
359 | mutex_lock(&data->update_lock); | 367 | mutex_lock(&data->update_lock); |
360 | data->in_min[nr] = IN_TO_REG(val, nr); | 368 | data->in_min[nr] = IN_TO_REG(val, nr); |
361 | via686a_write_value(client, VIA686A_REG_IN_MIN(nr), | 369 | via686a_write_value(data, VIA686A_REG_IN_MIN(nr), |
362 | data->in_min[nr]); | 370 | data->in_min[nr]); |
363 | mutex_unlock(&data->update_lock); | 371 | mutex_unlock(&data->update_lock); |
364 | return count; | 372 | return count; |
365 | } | 373 | } |
366 | static ssize_t set_in_max(struct device *dev, const char *buf, | 374 | static ssize_t set_in_max(struct device *dev, struct device_attribute *da, |
367 | size_t count, int nr) { | 375 | const char *buf, size_t count) { |
368 | struct i2c_client *client = to_i2c_client(dev); | 376 | struct via686a_data *data = dev_get_drvdata(dev); |
369 | struct via686a_data *data = i2c_get_clientdata(client); | 377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
378 | int nr = attr->index; | ||
370 | unsigned long val = simple_strtoul(buf, NULL, 10); | 379 | unsigned long val = simple_strtoul(buf, NULL, 10); |
371 | 380 | ||
372 | mutex_lock(&data->update_lock); | 381 | mutex_lock(&data->update_lock); |
373 | data->in_max[nr] = IN_TO_REG(val, nr); | 382 | data->in_max[nr] = IN_TO_REG(val, nr); |
374 | via686a_write_value(client, VIA686A_REG_IN_MAX(nr), | 383 | via686a_write_value(data, VIA686A_REG_IN_MAX(nr), |
375 | data->in_max[nr]); | 384 | data->in_max[nr]); |
376 | mutex_unlock(&data->update_lock); | 385 | mutex_unlock(&data->update_lock); |
377 | return count; | 386 | return count; |
378 | } | 387 | } |
379 | #define show_in_offset(offset) \ | 388 | #define show_in_offset(offset) \ |
380 | static ssize_t \ | 389 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
381 | show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 390 | show_in, NULL, offset); \ |
382 | { \ | 391 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
383 | return show_in(dev, buf, offset); \ | 392 | show_in_min, set_in_min, offset); \ |
384 | } \ | 393 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
385 | static ssize_t \ | 394 | show_in_max, set_in_max, offset); |
386 | show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
387 | { \ | ||
388 | return show_in_min(dev, buf, offset); \ | ||
389 | } \ | ||
390 | static ssize_t \ | ||
391 | show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
392 | { \ | ||
393 | return show_in_max(dev, buf, offset); \ | ||
394 | } \ | ||
395 | static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
396 | const char *buf, size_t count) \ | ||
397 | { \ | ||
398 | return set_in_min(dev, buf, count, offset); \ | ||
399 | } \ | ||
400 | static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
401 | const char *buf, size_t count) \ | ||
402 | { \ | ||
403 | return set_in_max(dev, buf, count, offset); \ | ||
404 | } \ | ||
405 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\ | ||
406 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
407 | show_in##offset##_min, set_in##offset##_min); \ | ||
408 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
409 | show_in##offset##_max, set_in##offset##_max); | ||
410 | 395 | ||
411 | show_in_offset(0); | 396 | show_in_offset(0); |
412 | show_in_offset(1); | 397 | show_in_offset(1); |
@@ -415,150 +400,128 @@ show_in_offset(3); | |||
415 | show_in_offset(4); | 400 | show_in_offset(4); |
416 | 401 | ||
417 | /* 3 temperatures */ | 402 | /* 3 temperatures */ |
418 | static ssize_t show_temp(struct device *dev, char *buf, int nr) { | 403 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
404 | char *buf) { | ||
419 | struct via686a_data *data = via686a_update_device(dev); | 405 | struct via686a_data *data = via686a_update_device(dev); |
406 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
407 | int nr = attr->index; | ||
420 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); | 408 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); |
421 | } | 409 | } |
422 | static ssize_t show_temp_over(struct device *dev, char *buf, int nr) { | 410 | static ssize_t show_temp_over(struct device *dev, struct device_attribute *da, |
411 | char *buf) { | ||
423 | struct via686a_data *data = via686a_update_device(dev); | 412 | struct via686a_data *data = via686a_update_device(dev); |
413 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
414 | int nr = attr->index; | ||
424 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); | 415 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); |
425 | } | 416 | } |
426 | static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { | 417 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da, |
418 | char *buf) { | ||
427 | struct via686a_data *data = via686a_update_device(dev); | 419 | struct via686a_data *data = via686a_update_device(dev); |
420 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
421 | int nr = attr->index; | ||
428 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); | 422 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); |
429 | } | 423 | } |
430 | static ssize_t set_temp_over(struct device *dev, const char *buf, | 424 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, |
431 | size_t count, int nr) { | 425 | const char *buf, size_t count) { |
432 | struct i2c_client *client = to_i2c_client(dev); | 426 | struct via686a_data *data = dev_get_drvdata(dev); |
433 | struct via686a_data *data = i2c_get_clientdata(client); | 427 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
428 | int nr = attr->index; | ||
434 | int val = simple_strtol(buf, NULL, 10); | 429 | int val = simple_strtol(buf, NULL, 10); |
435 | 430 | ||
436 | mutex_lock(&data->update_lock); | 431 | mutex_lock(&data->update_lock); |
437 | data->temp_over[nr] = TEMP_TO_REG(val); | 432 | data->temp_over[nr] = TEMP_TO_REG(val); |
438 | via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr], | 433 | via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr], |
439 | data->temp_over[nr]); | 434 | data->temp_over[nr]); |
440 | mutex_unlock(&data->update_lock); | 435 | mutex_unlock(&data->update_lock); |
441 | return count; | 436 | return count; |
442 | } | 437 | } |
443 | static ssize_t set_temp_hyst(struct device *dev, const char *buf, | 438 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, |
444 | size_t count, int nr) { | 439 | const char *buf, size_t count) { |
445 | struct i2c_client *client = to_i2c_client(dev); | 440 | struct via686a_data *data = dev_get_drvdata(dev); |
446 | struct via686a_data *data = i2c_get_clientdata(client); | 441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
442 | int nr = attr->index; | ||
447 | int val = simple_strtol(buf, NULL, 10); | 443 | int val = simple_strtol(buf, NULL, 10); |
448 | 444 | ||
449 | mutex_lock(&data->update_lock); | 445 | mutex_lock(&data->update_lock); |
450 | data->temp_hyst[nr] = TEMP_TO_REG(val); | 446 | data->temp_hyst[nr] = TEMP_TO_REG(val); |
451 | via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr], | 447 | via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr], |
452 | data->temp_hyst[nr]); | 448 | data->temp_hyst[nr]); |
453 | mutex_unlock(&data->update_lock); | 449 | mutex_unlock(&data->update_lock); |
454 | return count; | 450 | return count; |
455 | } | 451 | } |
456 | #define show_temp_offset(offset) \ | 452 | #define show_temp_offset(offset) \ |
457 | static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 453 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
458 | { \ | 454 | show_temp, NULL, offset - 1); \ |
459 | return show_temp(dev, buf, offset - 1); \ | 455 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
460 | } \ | 456 | show_temp_over, set_temp_over, offset - 1); \ |
461 | static ssize_t \ | 457 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ |
462 | show_temp_##offset##_over (struct device *dev, struct device_attribute *attr, char *buf) \ | 458 | show_temp_hyst, set_temp_hyst, offset - 1); |
463 | { \ | ||
464 | return show_temp_over(dev, buf, offset - 1); \ | ||
465 | } \ | ||
466 | static ssize_t \ | ||
467 | show_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
468 | { \ | ||
469 | return show_temp_hyst(dev, buf, offset - 1); \ | ||
470 | } \ | ||
471 | static ssize_t set_temp_##offset##_over (struct device *dev, struct device_attribute *attr, \ | ||
472 | const char *buf, size_t count) \ | ||
473 | { \ | ||
474 | return set_temp_over(dev, buf, count, offset - 1); \ | ||
475 | } \ | ||
476 | static ssize_t set_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, \ | ||
477 | const char *buf, size_t count) \ | ||
478 | { \ | ||
479 | return set_temp_hyst(dev, buf, count, offset - 1); \ | ||
480 | } \ | ||
481 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\ | ||
482 | static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
483 | show_temp_##offset##_over, set_temp_##offset##_over); \ | ||
484 | static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
485 | show_temp_##offset##_hyst, set_temp_##offset##_hyst); | ||
486 | 459 | ||
487 | show_temp_offset(1); | 460 | show_temp_offset(1); |
488 | show_temp_offset(2); | 461 | show_temp_offset(2); |
489 | show_temp_offset(3); | 462 | show_temp_offset(3); |
490 | 463 | ||
491 | /* 2 Fans */ | 464 | /* 2 Fans */ |
492 | static ssize_t show_fan(struct device *dev, char *buf, int nr) { | 465 | static ssize_t show_fan(struct device *dev, struct device_attribute *da, |
466 | char *buf) { | ||
493 | struct via686a_data *data = via686a_update_device(dev); | 467 | struct via686a_data *data = via686a_update_device(dev); |
468 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
469 | int nr = attr->index; | ||
494 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 470 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], |
495 | DIV_FROM_REG(data->fan_div[nr])) ); | 471 | DIV_FROM_REG(data->fan_div[nr])) ); |
496 | } | 472 | } |
497 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) { | 473 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, |
474 | char *buf) { | ||
498 | struct via686a_data *data = via686a_update_device(dev); | 475 | struct via686a_data *data = via686a_update_device(dev); |
476 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
477 | int nr = attr->index; | ||
499 | return sprintf(buf, "%d\n", | 478 | return sprintf(buf, "%d\n", |
500 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); | 479 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); |
501 | } | 480 | } |
502 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) { | 481 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, |
482 | char *buf) { | ||
503 | struct via686a_data *data = via686a_update_device(dev); | 483 | struct via686a_data *data = via686a_update_device(dev); |
484 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
485 | int nr = attr->index; | ||
504 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); | 486 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); |
505 | } | 487 | } |
506 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 488 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, |
507 | size_t count, int nr) { | 489 | const char *buf, size_t count) { |
508 | struct i2c_client *client = to_i2c_client(dev); | 490 | struct via686a_data *data = dev_get_drvdata(dev); |
509 | struct via686a_data *data = i2c_get_clientdata(client); | 491 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
492 | int nr = attr->index; | ||
510 | int val = simple_strtol(buf, NULL, 10); | 493 | int val = simple_strtol(buf, NULL, 10); |
511 | 494 | ||
512 | mutex_lock(&data->update_lock); | 495 | mutex_lock(&data->update_lock); |
513 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 496 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
514 | via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 497 | via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
515 | mutex_unlock(&data->update_lock); | 498 | mutex_unlock(&data->update_lock); |
516 | return count; | 499 | return count; |
517 | } | 500 | } |
518 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 501 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, |
519 | size_t count, int nr) { | 502 | const char *buf, size_t count) { |
520 | struct i2c_client *client = to_i2c_client(dev); | 503 | struct via686a_data *data = dev_get_drvdata(dev); |
521 | struct via686a_data *data = i2c_get_clientdata(client); | 504 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
505 | int nr = attr->index; | ||
522 | int val = simple_strtol(buf, NULL, 10); | 506 | int val = simple_strtol(buf, NULL, 10); |
523 | int old; | 507 | int old; |
524 | 508 | ||
525 | mutex_lock(&data->update_lock); | 509 | mutex_lock(&data->update_lock); |
526 | old = via686a_read_value(client, VIA686A_REG_FANDIV); | 510 | old = via686a_read_value(data, VIA686A_REG_FANDIV); |
527 | data->fan_div[nr] = DIV_TO_REG(val); | 511 | data->fan_div[nr] = DIV_TO_REG(val); |
528 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 512 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
529 | via686a_write_value(client, VIA686A_REG_FANDIV, old); | 513 | via686a_write_value(data, VIA686A_REG_FANDIV, old); |
530 | mutex_unlock(&data->update_lock); | 514 | mutex_unlock(&data->update_lock); |
531 | return count; | 515 | return count; |
532 | } | 516 | } |
533 | 517 | ||
534 | #define show_fan_offset(offset) \ | 518 | #define show_fan_offset(offset) \ |
535 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 519 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
536 | { \ | 520 | show_fan, NULL, offset - 1); \ |
537 | return show_fan(dev, buf, offset - 1); \ | 521 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
538 | } \ | 522 | show_fan_min, set_fan_min, offset - 1); \ |
539 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 523 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
540 | { \ | 524 | show_fan_div, set_fan_div, offset - 1); |
541 | return show_fan_min(dev, buf, offset - 1); \ | ||
542 | } \ | ||
543 | static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
544 | { \ | ||
545 | return show_fan_div(dev, buf, offset - 1); \ | ||
546 | } \ | ||
547 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
548 | const char *buf, size_t count) \ | ||
549 | { \ | ||
550 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
551 | } \ | ||
552 | static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \ | ||
553 | const char *buf, size_t count) \ | ||
554 | { \ | ||
555 | return set_fan_div(dev, buf, count, offset - 1); \ | ||
556 | } \ | ||
557 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ | ||
558 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
559 | show_fan_##offset##_min, set_fan_##offset##_min); \ | ||
560 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
561 | show_fan_##offset##_div, set_fan_##offset##_div); | ||
562 | 525 | ||
563 | show_fan_offset(1); | 526 | show_fan_offset(1); |
564 | show_fan_offset(2); | 527 | show_fan_offset(2); |
@@ -570,41 +533,50 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
570 | } | 533 | } |
571 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 534 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
572 | 535 | ||
536 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
537 | *devattr, char *buf) | ||
538 | { | ||
539 | struct via686a_data *data = dev_get_drvdata(dev); | ||
540 | return sprintf(buf, "%s\n", data->name); | ||
541 | } | ||
542 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
543 | |||
573 | static struct attribute *via686a_attributes[] = { | 544 | static struct attribute *via686a_attributes[] = { |
574 | &dev_attr_in0_input.attr, | 545 | &sensor_dev_attr_in0_input.dev_attr.attr, |
575 | &dev_attr_in1_input.attr, | 546 | &sensor_dev_attr_in1_input.dev_attr.attr, |
576 | &dev_attr_in2_input.attr, | 547 | &sensor_dev_attr_in2_input.dev_attr.attr, |
577 | &dev_attr_in3_input.attr, | 548 | &sensor_dev_attr_in3_input.dev_attr.attr, |
578 | &dev_attr_in4_input.attr, | 549 | &sensor_dev_attr_in4_input.dev_attr.attr, |
579 | &dev_attr_in0_min.attr, | 550 | &sensor_dev_attr_in0_min.dev_attr.attr, |
580 | &dev_attr_in1_min.attr, | 551 | &sensor_dev_attr_in1_min.dev_attr.attr, |
581 | &dev_attr_in2_min.attr, | 552 | &sensor_dev_attr_in2_min.dev_attr.attr, |
582 | &dev_attr_in3_min.attr, | 553 | &sensor_dev_attr_in3_min.dev_attr.attr, |
583 | &dev_attr_in4_min.attr, | 554 | &sensor_dev_attr_in4_min.dev_attr.attr, |
584 | &dev_attr_in0_max.attr, | 555 | &sensor_dev_attr_in0_max.dev_attr.attr, |
585 | &dev_attr_in1_max.attr, | 556 | &sensor_dev_attr_in1_max.dev_attr.attr, |
586 | &dev_attr_in2_max.attr, | 557 | &sensor_dev_attr_in2_max.dev_attr.attr, |
587 | &dev_attr_in3_max.attr, | 558 | &sensor_dev_attr_in3_max.dev_attr.attr, |
588 | &dev_attr_in4_max.attr, | 559 | &sensor_dev_attr_in4_max.dev_attr.attr, |
589 | 560 | ||
590 | &dev_attr_temp1_input.attr, | 561 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
591 | &dev_attr_temp2_input.attr, | 562 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
592 | &dev_attr_temp3_input.attr, | 563 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
593 | &dev_attr_temp1_max.attr, | 564 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
594 | &dev_attr_temp2_max.attr, | 565 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
595 | &dev_attr_temp3_max.attr, | 566 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
596 | &dev_attr_temp1_max_hyst.attr, | 567 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
597 | &dev_attr_temp2_max_hyst.attr, | 568 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
598 | &dev_attr_temp3_max_hyst.attr, | 569 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
599 | 570 | ||
600 | &dev_attr_fan1_input.attr, | 571 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
601 | &dev_attr_fan2_input.attr, | 572 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
602 | &dev_attr_fan1_min.attr, | 573 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
603 | &dev_attr_fan2_min.attr, | 574 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
604 | &dev_attr_fan1_div.attr, | 575 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
605 | &dev_attr_fan2_div.attr, | 576 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
606 | 577 | ||
607 | &dev_attr_alarms.attr, | 578 | &dev_attr_alarms.attr, |
579 | &dev_attr_name.attr, | ||
608 | NULL | 580 | NULL |
609 | }; | 581 | }; |
610 | 582 | ||
@@ -612,58 +584,29 @@ static const struct attribute_group via686a_group = { | |||
612 | .attrs = via686a_attributes, | 584 | .attrs = via686a_attributes, |
613 | }; | 585 | }; |
614 | 586 | ||
615 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 587 | static struct platform_driver via686a_driver = { |
616 | smbus_driver and isa_driver, and clients could be of either kind */ | ||
617 | static struct i2c_driver via686a_driver = { | ||
618 | .driver = { | 588 | .driver = { |
619 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
620 | .name = "via686a", | 590 | .name = "via686a", |
621 | }, | 591 | }, |
622 | .attach_adapter = via686a_detect, | 592 | .probe = via686a_probe, |
623 | .detach_client = via686a_detach_client, | 593 | .remove = __devexit_p(via686a_remove), |
624 | }; | 594 | }; |
625 | 595 | ||
626 | 596 | ||
627 | /* This is called when the module is loaded */ | 597 | /* This is called when the module is loaded */ |
628 | static int via686a_detect(struct i2c_adapter *adapter) | 598 | static int __devinit via686a_probe(struct platform_device *pdev) |
629 | { | 599 | { |
630 | struct i2c_client *new_client; | ||
631 | struct via686a_data *data; | 600 | struct via686a_data *data; |
632 | int err = 0; | 601 | struct resource *res; |
633 | const char client_name[] = "via686a"; | 602 | int err; |
634 | u16 val; | ||
635 | |||
636 | /* 8231 requires multiple of 256, we enforce that on 686 as well */ | ||
637 | if (force_addr) { | ||
638 | address = force_addr & 0xFF00; | ||
639 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
640 | address); | ||
641 | if (PCIBIOS_SUCCESSFUL != | ||
642 | pci_write_config_word(s_bridge, VIA686A_BASE_REG, address)) | ||
643 | return -ENODEV; | ||
644 | } | ||
645 | if (PCIBIOS_SUCCESSFUL != | ||
646 | pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) | ||
647 | return -ENODEV; | ||
648 | if (!(val & 0x0001)) { | ||
649 | if (force_addr) { | ||
650 | dev_info(&adapter->dev, "enabling sensors\n"); | ||
651 | if (PCIBIOS_SUCCESSFUL != | ||
652 | pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, | ||
653 | val | 0x0001)) | ||
654 | return -ENODEV; | ||
655 | } else { | ||
656 | dev_warn(&adapter->dev, "sensors disabled - enable " | ||
657 | "with force_addr=0x%x\n", address); | ||
658 | return -ENODEV; | ||
659 | } | ||
660 | } | ||
661 | 603 | ||
662 | /* Reserve the ISA region */ | 604 | /* Reserve the ISA region */ |
663 | if (!request_region(address, VIA686A_EXTENT, | 605 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
606 | if (!request_region(res->start, VIA686A_EXTENT, | ||
664 | via686a_driver.driver.name)) { | 607 | via686a_driver.driver.name)) { |
665 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 608 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
666 | address); | 609 | (unsigned long)res->start, (unsigned long)res->end); |
667 | return -ENODEV; | 610 | return -ENODEV; |
668 | } | 611 | } |
669 | 612 | ||
@@ -672,30 +615,19 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
672 | goto exit_release; | 615 | goto exit_release; |
673 | } | 616 | } |
674 | 617 | ||
675 | new_client = &data->client; | 618 | platform_set_drvdata(pdev, data); |
676 | i2c_set_clientdata(new_client, data); | 619 | data->addr = res->start; |
677 | new_client->addr = address; | 620 | data->name = "via686a"; |
678 | new_client->adapter = adapter; | ||
679 | new_client->driver = &via686a_driver; | ||
680 | new_client->flags = 0; | ||
681 | |||
682 | /* Fill in the remaining client fields and put into the global list */ | ||
683 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); | ||
684 | |||
685 | data->valid = 0; | ||
686 | mutex_init(&data->update_lock); | 621 | mutex_init(&data->update_lock); |
687 | /* Tell the I2C layer a new client has arrived */ | ||
688 | if ((err = i2c_attach_client(new_client))) | ||
689 | goto exit_free; | ||
690 | 622 | ||
691 | /* Initialize the VIA686A chip */ | 623 | /* Initialize the VIA686A chip */ |
692 | via686a_init_client(new_client); | 624 | via686a_init_device(data); |
693 | 625 | ||
694 | /* Register sysfs hooks */ | 626 | /* Register sysfs hooks */ |
695 | if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group))) | 627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
696 | goto exit_detach; | 628 | goto exit_free; |
697 | 629 | ||
698 | data->class_dev = hwmon_device_register(&new_client->dev); | 630 | data->class_dev = hwmon_device_register(&pdev->dev); |
699 | if (IS_ERR(data->class_dev)) { | 631 | if (IS_ERR(data->class_dev)) { |
700 | err = PTR_ERR(data->class_dev); | 632 | err = PTR_ERR(data->class_dev); |
701 | goto exit_remove_files; | 633 | goto exit_remove_files; |
@@ -704,51 +636,46 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
704 | return 0; | 636 | return 0; |
705 | 637 | ||
706 | exit_remove_files: | 638 | exit_remove_files: |
707 | sysfs_remove_group(&new_client->dev.kobj, &via686a_group); | 639 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
708 | exit_detach: | ||
709 | i2c_detach_client(new_client); | ||
710 | exit_free: | 640 | exit_free: |
711 | kfree(data); | 641 | kfree(data); |
712 | exit_release: | 642 | exit_release: |
713 | release_region(address, VIA686A_EXTENT); | 643 | release_region(res->start, VIA686A_EXTENT); |
714 | return err; | 644 | return err; |
715 | } | 645 | } |
716 | 646 | ||
717 | static int via686a_detach_client(struct i2c_client *client) | 647 | static int __devexit via686a_remove(struct platform_device *pdev) |
718 | { | 648 | { |
719 | struct via686a_data *data = i2c_get_clientdata(client); | 649 | struct via686a_data *data = platform_get_drvdata(pdev); |
720 | int err; | ||
721 | 650 | ||
722 | hwmon_device_unregister(data->class_dev); | 651 | hwmon_device_unregister(data->class_dev); |
723 | sysfs_remove_group(&client->dev.kobj, &via686a_group); | 652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
724 | 653 | ||
725 | if ((err = i2c_detach_client(client))) | 654 | release_region(data->addr, VIA686A_EXTENT); |
726 | return err; | 655 | platform_set_drvdata(pdev, NULL); |
727 | |||
728 | release_region(client->addr, VIA686A_EXTENT); | ||
729 | kfree(data); | 656 | kfree(data); |
730 | 657 | ||
731 | return 0; | 658 | return 0; |
732 | } | 659 | } |
733 | 660 | ||
734 | static void via686a_init_client(struct i2c_client *client) | 661 | static void __devinit via686a_init_device(struct via686a_data *data) |
735 | { | 662 | { |
736 | u8 reg; | 663 | u8 reg; |
737 | 664 | ||
738 | /* Start monitoring */ | 665 | /* Start monitoring */ |
739 | reg = via686a_read_value(client, VIA686A_REG_CONFIG); | 666 | reg = via686a_read_value(data, VIA686A_REG_CONFIG); |
740 | via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F); | 667 | via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F); |
741 | 668 | ||
742 | /* Configure temp interrupt mode for continuous-interrupt operation */ | 669 | /* Configure temp interrupt mode for continuous-interrupt operation */ |
743 | via686a_write_value(client, VIA686A_REG_TEMP_MODE, | 670 | reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE); |
744 | via686a_read_value(client, VIA686A_REG_TEMP_MODE) & | 671 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, |
745 | !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS)); | 672 | (reg & ~VIA686A_TEMP_MODE_MASK) |
673 | | VIA686A_TEMP_MODE_CONTINUOUS); | ||
746 | } | 674 | } |
747 | 675 | ||
748 | static struct via686a_data *via686a_update_device(struct device *dev) | 676 | static struct via686a_data *via686a_update_device(struct device *dev) |
749 | { | 677 | { |
750 | struct i2c_client *client = to_i2c_client(dev); | 678 | struct via686a_data *data = dev_get_drvdata(dev); |
751 | struct via686a_data *data = i2c_get_clientdata(client); | ||
752 | int i; | 679 | int i; |
753 | 680 | ||
754 | mutex_lock(&data->update_lock); | 681 | mutex_lock(&data->update_lock); |
@@ -757,27 +684,27 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
757 | || !data->valid) { | 684 | || !data->valid) { |
758 | for (i = 0; i <= 4; i++) { | 685 | for (i = 0; i <= 4; i++) { |
759 | data->in[i] = | 686 | data->in[i] = |
760 | via686a_read_value(client, VIA686A_REG_IN(i)); | 687 | via686a_read_value(data, VIA686A_REG_IN(i)); |
761 | data->in_min[i] = via686a_read_value(client, | 688 | data->in_min[i] = via686a_read_value(data, |
762 | VIA686A_REG_IN_MIN | 689 | VIA686A_REG_IN_MIN |
763 | (i)); | 690 | (i)); |
764 | data->in_max[i] = | 691 | data->in_max[i] = |
765 | via686a_read_value(client, VIA686A_REG_IN_MAX(i)); | 692 | via686a_read_value(data, VIA686A_REG_IN_MAX(i)); |
766 | } | 693 | } |
767 | for (i = 1; i <= 2; i++) { | 694 | for (i = 1; i <= 2; i++) { |
768 | data->fan[i - 1] = | 695 | data->fan[i - 1] = |
769 | via686a_read_value(client, VIA686A_REG_FAN(i)); | 696 | via686a_read_value(data, VIA686A_REG_FAN(i)); |
770 | data->fan_min[i - 1] = via686a_read_value(client, | 697 | data->fan_min[i - 1] = via686a_read_value(data, |
771 | VIA686A_REG_FAN_MIN(i)); | 698 | VIA686A_REG_FAN_MIN(i)); |
772 | } | 699 | } |
773 | for (i = 0; i <= 2; i++) { | 700 | for (i = 0; i <= 2; i++) { |
774 | data->temp[i] = via686a_read_value(client, | 701 | data->temp[i] = via686a_read_value(data, |
775 | VIA686A_REG_TEMP[i]) << 2; | 702 | VIA686A_REG_TEMP[i]) << 2; |
776 | data->temp_over[i] = | 703 | data->temp_over[i] = |
777 | via686a_read_value(client, | 704 | via686a_read_value(data, |
778 | VIA686A_REG_TEMP_OVER[i]); | 705 | VIA686A_REG_TEMP_OVER[i]); |
779 | data->temp_hyst[i] = | 706 | data->temp_hyst[i] = |
780 | via686a_read_value(client, | 707 | via686a_read_value(data, |
781 | VIA686A_REG_TEMP_HYST[i]); | 708 | VIA686A_REG_TEMP_HYST[i]); |
782 | } | 709 | } |
783 | /* add in lower 2 bits | 710 | /* add in lower 2 bits |
@@ -785,23 +712,23 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
785 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 | 712 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 |
786 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 | 713 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 |
787 | */ | 714 | */ |
788 | data->temp[0] |= (via686a_read_value(client, | 715 | data->temp[0] |= (via686a_read_value(data, |
789 | VIA686A_REG_TEMP_LOW1) | 716 | VIA686A_REG_TEMP_LOW1) |
790 | & 0xc0) >> 6; | 717 | & 0xc0) >> 6; |
791 | data->temp[1] |= | 718 | data->temp[1] |= |
792 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 719 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
793 | 0x30) >> 4; | 720 | 0x30) >> 4; |
794 | data->temp[2] |= | 721 | data->temp[2] |= |
795 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 722 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
796 | 0xc0) >> 6; | 723 | 0xc0) >> 6; |
797 | 724 | ||
798 | i = via686a_read_value(client, VIA686A_REG_FANDIV); | 725 | i = via686a_read_value(data, VIA686A_REG_FANDIV); |
799 | data->fan_div[0] = (i >> 4) & 0x03; | 726 | data->fan_div[0] = (i >> 4) & 0x03; |
800 | data->fan_div[1] = i >> 6; | 727 | data->fan_div[1] = i >> 6; |
801 | data->alarms = | 728 | data->alarms = |
802 | via686a_read_value(client, | 729 | via686a_read_value(data, |
803 | VIA686A_REG_ALARM1) | | 730 | VIA686A_REG_ALARM1) | |
804 | (via686a_read_value(client, VIA686A_REG_ALARM2) << 8); | 731 | (via686a_read_value(data, VIA686A_REG_ALARM2) << 8); |
805 | data->last_updated = jiffies; | 732 | data->last_updated = jiffies; |
806 | data->valid = 1; | 733 | data->valid = 1; |
807 | } | 734 | } |
@@ -818,32 +745,102 @@ static struct pci_device_id via686a_pci_ids[] = { | |||
818 | 745 | ||
819 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); | 746 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
820 | 747 | ||
748 | static int __devinit via686a_device_add(unsigned short address) | ||
749 | { | ||
750 | struct resource res = { | ||
751 | .start = address, | ||
752 | .end = address + VIA686A_EXTENT - 1, | ||
753 | .name = "via686a", | ||
754 | .flags = IORESOURCE_IO, | ||
755 | }; | ||
756 | int err; | ||
757 | |||
758 | pdev = platform_device_alloc("via686a", address); | ||
759 | if (!pdev) { | ||
760 | err = -ENOMEM; | ||
761 | printk(KERN_ERR "via686a: Device allocation failed\n"); | ||
762 | goto exit; | ||
763 | } | ||
764 | |||
765 | err = platform_device_add_resources(pdev, &res, 1); | ||
766 | if (err) { | ||
767 | printk(KERN_ERR "via686a: Device resource addition failed " | ||
768 | "(%d)\n", err); | ||
769 | goto exit_device_put; | ||
770 | } | ||
771 | |||
772 | err = platform_device_add(pdev); | ||
773 | if (err) { | ||
774 | printk(KERN_ERR "via686a: Device addition failed (%d)\n", | ||
775 | err); | ||
776 | goto exit_device_put; | ||
777 | } | ||
778 | |||
779 | return 0; | ||
780 | |||
781 | exit_device_put: | ||
782 | platform_device_put(pdev); | ||
783 | exit: | ||
784 | return err; | ||
785 | } | ||
786 | |||
821 | static int __devinit via686a_pci_probe(struct pci_dev *dev, | 787 | static int __devinit via686a_pci_probe(struct pci_dev *dev, |
822 | const struct pci_device_id *id) | 788 | const struct pci_device_id *id) |
823 | { | 789 | { |
824 | u16 val; | 790 | u16 address, val; |
825 | 791 | ||
792 | if (force_addr) { | ||
793 | address = force_addr & ~(VIA686A_EXTENT - 1); | ||
794 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address); | ||
795 | if (PCIBIOS_SUCCESSFUL != | ||
796 | pci_write_config_word(dev, VIA686A_BASE_REG, address | 1)) | ||
797 | return -ENODEV; | ||
798 | } | ||
826 | if (PCIBIOS_SUCCESSFUL != | 799 | if (PCIBIOS_SUCCESSFUL != |
827 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) | 800 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) |
828 | return -ENODEV; | 801 | return -ENODEV; |
829 | 802 | ||
830 | address = val & ~(VIA686A_EXTENT - 1); | 803 | address = val & ~(VIA686A_EXTENT - 1); |
831 | if (address == 0 && force_addr == 0) { | 804 | if (address == 0) { |
832 | dev_err(&dev->dev, "base address not set - upgrade BIOS " | 805 | dev_err(&dev->dev, "base address not set - upgrade BIOS " |
833 | "or use force_addr=0xaddr\n"); | 806 | "or use force_addr=0xaddr\n"); |
834 | return -ENODEV; | 807 | return -ENODEV; |
835 | } | 808 | } |
836 | 809 | ||
837 | s_bridge = pci_dev_get(dev); | 810 | if (PCIBIOS_SUCCESSFUL != |
838 | if (i2c_isa_add_driver(&via686a_driver)) { | 811 | pci_read_config_word(dev, VIA686A_ENABLE_REG, &val)) |
839 | pci_dev_put(s_bridge); | 812 | return -ENODEV; |
840 | s_bridge = NULL; | 813 | if (!(val & 0x0001)) { |
814 | if (!force_addr) { | ||
815 | dev_warn(&dev->dev, "Sensors disabled, enable " | ||
816 | "with force_addr=0x%x\n", address); | ||
817 | return -ENODEV; | ||
818 | } | ||
819 | |||
820 | dev_warn(&dev->dev, "Enabling sensors\n"); | ||
821 | if (PCIBIOS_SUCCESSFUL != | ||
822 | pci_write_config_word(dev, VIA686A_ENABLE_REG, | ||
823 | val | 0x0001)) | ||
824 | return -ENODEV; | ||
841 | } | 825 | } |
842 | 826 | ||
827 | if (platform_driver_register(&via686a_driver)) | ||
828 | goto exit; | ||
829 | |||
830 | /* Sets global pdev as a side effect */ | ||
831 | if (via686a_device_add(address)) | ||
832 | goto exit_unregister; | ||
833 | |||
843 | /* Always return failure here. This is to allow other drivers to bind | 834 | /* Always return failure here. This is to allow other drivers to bind |
844 | * to this pci device. We don't really want to have control over the | 835 | * to this pci device. We don't really want to have control over the |
845 | * pci device, we only wanted to read as few register values from it. | 836 | * pci device, we only wanted to read as few register values from it. |
846 | */ | 837 | */ |
838 | s_bridge = pci_dev_get(dev); | ||
839 | return -ENODEV; | ||
840 | |||
841 | exit_unregister: | ||
842 | platform_driver_unregister(&via686a_driver); | ||
843 | exit: | ||
847 | return -ENODEV; | 844 | return -ENODEV; |
848 | } | 845 | } |
849 | 846 | ||
@@ -862,7 +859,8 @@ static void __exit sm_via686a_exit(void) | |||
862 | { | 859 | { |
863 | pci_unregister_driver(&via686a_pci_driver); | 860 | pci_unregister_driver(&via686a_pci_driver); |
864 | if (s_bridge != NULL) { | 861 | if (s_bridge != NULL) { |
865 | i2c_isa_del_driver(&via686a_driver); | 862 | platform_device_unregister(pdev); |
863 | platform_driver_unregister(&via686a_driver); | ||
866 | pci_dev_put(s_bridge); | 864 | pci_dev_put(s_bridge); |
867 | s_bridge = NULL; | 865 | s_bridge = NULL; |
868 | } | 866 | } |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index a6a4aa0eee16..c604972f0186 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -29,8 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/i2c-isa.h> | ||
34 | #include <linux/hwmon.h> | 33 | #include <linux/hwmon.h> |
35 | #include <linux/hwmon-sysfs.h> | 34 | #include <linux/hwmon-sysfs.h> |
36 | #include <linux/hwmon-vid.h> | 35 | #include <linux/hwmon-vid.h> |
@@ -42,10 +41,7 @@ static int force_addr; | |||
42 | module_param(force_addr, int, 0); | 41 | module_param(force_addr, int, 0); |
43 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); | 42 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); |
44 | 43 | ||
45 | /* Device address | 44 | static struct platform_device *pdev; |
46 | Note that we can't determine the ISA address until we have initialized | ||
47 | our module */ | ||
48 | static unsigned short isa_address; | ||
49 | 45 | ||
50 | #define VT8231_EXTENT 0x80 | 46 | #define VT8231_EXTENT 0x80 |
51 | #define VT8231_BASE_REG 0x70 | 47 | #define VT8231_BASE_REG 0x70 |
@@ -148,7 +144,9 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
148 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) | 144 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) |
149 | 145 | ||
150 | struct vt8231_data { | 146 | struct vt8231_data { |
151 | struct i2c_client client; | 147 | unsigned short addr; |
148 | const char *name; | ||
149 | |||
152 | struct mutex update_lock; | 150 | struct mutex update_lock; |
153 | struct class_device *class_dev; | 151 | struct class_device *class_dev; |
154 | char valid; /* !=0 if following fields are valid */ | 152 | char valid; /* !=0 if following fields are valid */ |
@@ -168,20 +166,20 @@ struct vt8231_data { | |||
168 | }; | 166 | }; |
169 | 167 | ||
170 | static struct pci_dev *s_bridge; | 168 | static struct pci_dev *s_bridge; |
171 | static int vt8231_detect(struct i2c_adapter *adapter); | 169 | static int vt8231_probe(struct platform_device *pdev); |
172 | static int vt8231_detach_client(struct i2c_client *client); | 170 | static int vt8231_remove(struct platform_device *pdev); |
173 | static struct vt8231_data *vt8231_update_device(struct device *dev); | 171 | static struct vt8231_data *vt8231_update_device(struct device *dev); |
174 | static void vt8231_init_client(struct i2c_client *client); | 172 | static void vt8231_init_device(struct vt8231_data *data); |
175 | 173 | ||
176 | static inline int vt8231_read_value(struct i2c_client *client, u8 reg) | 174 | static inline int vt8231_read_value(struct vt8231_data *data, u8 reg) |
177 | { | 175 | { |
178 | return inb_p(client->addr + reg); | 176 | return inb_p(data->addr + reg); |
179 | } | 177 | } |
180 | 178 | ||
181 | static inline void vt8231_write_value(struct i2c_client *client, u8 reg, | 179 | static inline void vt8231_write_value(struct vt8231_data *data, u8 reg, |
182 | u8 value) | 180 | u8 value) |
183 | { | 181 | { |
184 | outb_p(value, client->addr + reg); | 182 | outb_p(value, data->addr + reg); |
185 | } | 183 | } |
186 | 184 | ||
187 | /* following are the sysfs callback functions */ | 185 | /* following are the sysfs callback functions */ |
@@ -220,13 +218,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
220 | { | 218 | { |
221 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 219 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
222 | int nr = sensor_attr->index; | 220 | int nr = sensor_attr->index; |
223 | struct i2c_client *client = to_i2c_client(dev); | 221 | struct vt8231_data *data = dev_get_drvdata(dev); |
224 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
225 | unsigned long val = simple_strtoul(buf, NULL, 10); | 222 | unsigned long val = simple_strtoul(buf, NULL, 10); |
226 | 223 | ||
227 | mutex_lock(&data->update_lock); | 224 | mutex_lock(&data->update_lock); |
228 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | 225 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); |
229 | vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]); | 226 | vt8231_write_value(data, regvoltmin[nr], data->in_min[nr]); |
230 | mutex_unlock(&data->update_lock); | 227 | mutex_unlock(&data->update_lock); |
231 | return count; | 228 | return count; |
232 | } | 229 | } |
@@ -236,13 +233,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
236 | { | 233 | { |
237 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 234 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
238 | int nr = sensor_attr->index; | 235 | int nr = sensor_attr->index; |
239 | struct i2c_client *client = to_i2c_client(dev); | 236 | struct vt8231_data *data = dev_get_drvdata(dev); |
240 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
241 | unsigned long val = simple_strtoul(buf, NULL, 10); | 237 | unsigned long val = simple_strtoul(buf, NULL, 10); |
242 | 238 | ||
243 | mutex_lock(&data->update_lock); | 239 | mutex_lock(&data->update_lock); |
244 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | 240 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); |
245 | vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]); | 241 | vt8231_write_value(data, regvoltmax[nr], data->in_max[nr]); |
246 | mutex_unlock(&data->update_lock); | 242 | mutex_unlock(&data->update_lock); |
247 | return count; | 243 | return count; |
248 | } | 244 | } |
@@ -278,14 +274,13 @@ static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr, | |||
278 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | 274 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, |
279 | const char *buf, size_t count) | 275 | const char *buf, size_t count) |
280 | { | 276 | { |
281 | struct i2c_client *client = to_i2c_client(dev); | 277 | struct vt8231_data *data = dev_get_drvdata(dev); |
282 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
283 | unsigned long val = simple_strtoul(buf, NULL, 10); | 278 | unsigned long val = simple_strtoul(buf, NULL, 10); |
284 | 279 | ||
285 | mutex_lock(&data->update_lock); | 280 | mutex_lock(&data->update_lock); |
286 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | 281 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, |
287 | 0, 255); | 282 | 0, 255); |
288 | vt8231_write_value(client, regvoltmin[5], data->in_min[5]); | 283 | vt8231_write_value(data, regvoltmin[5], data->in_min[5]); |
289 | mutex_unlock(&data->update_lock); | 284 | mutex_unlock(&data->update_lock); |
290 | return count; | 285 | return count; |
291 | } | 286 | } |
@@ -293,14 +288,13 @@ static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | |||
293 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, | 288 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, |
294 | const char *buf, size_t count) | 289 | const char *buf, size_t count) |
295 | { | 290 | { |
296 | struct i2c_client *client = to_i2c_client(dev); | 291 | struct vt8231_data *data = dev_get_drvdata(dev); |
297 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
298 | unsigned long val = simple_strtoul(buf, NULL, 10); | 292 | unsigned long val = simple_strtoul(buf, NULL, 10); |
299 | 293 | ||
300 | mutex_lock(&data->update_lock); | 294 | mutex_lock(&data->update_lock); |
301 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | 295 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, |
302 | 0, 255); | 296 | 0, 255); |
303 | vt8231_write_value(client, regvoltmax[5], data->in_max[5]); | 297 | vt8231_write_value(data, regvoltmax[5], data->in_max[5]); |
304 | mutex_unlock(&data->update_lock); | 298 | mutex_unlock(&data->update_lock); |
305 | return count; | 299 | return count; |
306 | } | 300 | } |
@@ -348,26 +342,24 @@ static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr, | |||
348 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, | 342 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, |
349 | const char *buf, size_t count) | 343 | const char *buf, size_t count) |
350 | { | 344 | { |
351 | struct i2c_client *client = to_i2c_client(dev); | 345 | struct vt8231_data *data = dev_get_drvdata(dev); |
352 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
353 | int val = simple_strtol(buf, NULL, 10); | 346 | int val = simple_strtol(buf, NULL, 10); |
354 | 347 | ||
355 | mutex_lock(&data->update_lock); | 348 | mutex_lock(&data->update_lock); |
356 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | 349 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); |
357 | vt8231_write_value(client, regtempmax[0], data->temp_max[0]); | 350 | vt8231_write_value(data, regtempmax[0], data->temp_max[0]); |
358 | mutex_unlock(&data->update_lock); | 351 | mutex_unlock(&data->update_lock); |
359 | return count; | 352 | return count; |
360 | } | 353 | } |
361 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, | 354 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, |
362 | const char *buf, size_t count) | 355 | const char *buf, size_t count) |
363 | { | 356 | { |
364 | struct i2c_client *client = to_i2c_client(dev); | 357 | struct vt8231_data *data = dev_get_drvdata(dev); |
365 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
366 | int val = simple_strtol(buf, NULL, 10); | 358 | int val = simple_strtol(buf, NULL, 10); |
367 | 359 | ||
368 | mutex_lock(&data->update_lock); | 360 | mutex_lock(&data->update_lock); |
369 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | 361 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); |
370 | vt8231_write_value(client, regtempmin[0], data->temp_min[0]); | 362 | vt8231_write_value(data, regtempmin[0], data->temp_min[0]); |
371 | mutex_unlock(&data->update_lock); | 363 | mutex_unlock(&data->update_lock); |
372 | return count; | 364 | return count; |
373 | } | 365 | } |
@@ -404,13 +396,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
404 | { | 396 | { |
405 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 397 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
406 | int nr = sensor_attr->index; | 398 | int nr = sensor_attr->index; |
407 | struct i2c_client *client = to_i2c_client(dev); | 399 | struct vt8231_data *data = dev_get_drvdata(dev); |
408 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
409 | int val = simple_strtol(buf, NULL, 10); | 400 | int val = simple_strtol(buf, NULL, 10); |
410 | 401 | ||
411 | mutex_lock(&data->update_lock); | 402 | mutex_lock(&data->update_lock); |
412 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | 403 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); |
413 | vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]); | 404 | vt8231_write_value(data, regtempmax[nr], data->temp_max[nr]); |
414 | mutex_unlock(&data->update_lock); | 405 | mutex_unlock(&data->update_lock); |
415 | return count; | 406 | return count; |
416 | } | 407 | } |
@@ -419,13 +410,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
419 | { | 410 | { |
420 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 411 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
421 | int nr = sensor_attr->index; | 412 | int nr = sensor_attr->index; |
422 | struct i2c_client *client = to_i2c_client(dev); | 413 | struct vt8231_data *data = dev_get_drvdata(dev); |
423 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
424 | int val = simple_strtol(buf, NULL, 10); | 414 | int val = simple_strtol(buf, NULL, 10); |
425 | 415 | ||
426 | mutex_lock(&data->update_lock); | 416 | mutex_lock(&data->update_lock); |
427 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | 417 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); |
428 | vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]); | 418 | vt8231_write_value(data, regtempmin[nr], data->temp_min[nr]); |
429 | mutex_unlock(&data->update_lock); | 419 | mutex_unlock(&data->update_lock); |
430 | return count; | 420 | return count; |
431 | } | 421 | } |
@@ -486,13 +476,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
486 | { | 476 | { |
487 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 477 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
488 | int nr = sensor_attr->index; | 478 | int nr = sensor_attr->index; |
489 | struct i2c_client *client = to_i2c_client(dev); | 479 | struct vt8231_data *data = dev_get_drvdata(dev); |
490 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
491 | int val = simple_strtoul(buf, NULL, 10); | 480 | int val = simple_strtoul(buf, NULL, 10); |
492 | 481 | ||
493 | mutex_lock(&data->update_lock); | 482 | mutex_lock(&data->update_lock); |
494 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 483 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
495 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | 484 | vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); |
496 | mutex_unlock(&data->update_lock); | 485 | mutex_unlock(&data->update_lock); |
497 | return count; | 486 | return count; |
498 | } | 487 | } |
@@ -500,12 +489,11 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
500 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | 489 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, |
501 | const char *buf, size_t count) | 490 | const char *buf, size_t count) |
502 | { | 491 | { |
503 | struct i2c_client *client = to_i2c_client(dev); | 492 | struct vt8231_data *data = dev_get_drvdata(dev); |
504 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
505 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 493 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
506 | unsigned long val = simple_strtoul(buf, NULL, 10); | 494 | unsigned long val = simple_strtoul(buf, NULL, 10); |
507 | int nr = sensor_attr->index; | 495 | int nr = sensor_attr->index; |
508 | int old = vt8231_read_value(client, VT8231_REG_FANDIV); | 496 | int old = vt8231_read_value(data, VT8231_REG_FANDIV); |
509 | long min = FAN_FROM_REG(data->fan_min[nr], | 497 | long min = FAN_FROM_REG(data->fan_min[nr], |
510 | DIV_FROM_REG(data->fan_div[nr])); | 498 | DIV_FROM_REG(data->fan_div[nr])); |
511 | 499 | ||
@@ -516,7 +504,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
516 | case 4: data->fan_div[nr] = 2; break; | 504 | case 4: data->fan_div[nr] = 2; break; |
517 | case 8: data->fan_div[nr] = 3; break; | 505 | case 8: data->fan_div[nr] = 3; break; |
518 | default: | 506 | default: |
519 | dev_err(&client->dev, "fan_div value %ld not supported." | 507 | dev_err(dev, "fan_div value %ld not supported." |
520 | "Choose one of 1, 2, 4 or 8!\n", val); | 508 | "Choose one of 1, 2, 4 or 8!\n", val); |
521 | mutex_unlock(&data->update_lock); | 509 | mutex_unlock(&data->update_lock); |
522 | return -EINVAL; | 510 | return -EINVAL; |
@@ -524,10 +512,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
524 | 512 | ||
525 | /* Correct the fan minimum speed */ | 513 | /* Correct the fan minimum speed */ |
526 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 514 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
527 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | 515 | vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); |
528 | 516 | ||
529 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 517 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
530 | vt8231_write_value(client, VT8231_REG_FANDIV, old); | 518 | vt8231_write_value(data, VT8231_REG_FANDIV, old); |
531 | mutex_unlock(&data->update_lock); | 519 | mutex_unlock(&data->update_lock); |
532 | return count; | 520 | return count; |
533 | } | 521 | } |
@@ -551,9 +539,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | |||
551 | struct vt8231_data *data = vt8231_update_device(dev); | 539 | struct vt8231_data *data = vt8231_update_device(dev); |
552 | return sprintf(buf, "%d\n", data->alarms); | 540 | return sprintf(buf, "%d\n", data->alarms); |
553 | } | 541 | } |
554 | |||
555 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 542 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
556 | 543 | ||
544 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
545 | *devattr, char *buf) | ||
546 | { | ||
547 | struct vt8231_data *data = dev_get_drvdata(dev); | ||
548 | return sprintf(buf, "%s\n", data->name); | ||
549 | } | ||
550 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
551 | |||
557 | static struct attribute *vt8231_attributes_temps[6][4] = { | 552 | static struct attribute *vt8231_attributes_temps[6][4] = { |
558 | { | 553 | { |
559 | &dev_attr_temp1_input.attr, | 554 | &dev_attr_temp1_input.attr, |
@@ -648,6 +643,7 @@ static struct attribute *vt8231_attributes[] = { | |||
648 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 643 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
649 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 644 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
650 | &dev_attr_alarms.attr, | 645 | &dev_attr_alarms.attr, |
646 | &dev_attr_name.attr, | ||
651 | NULL | 647 | NULL |
652 | }; | 648 | }; |
653 | 649 | ||
@@ -655,13 +651,13 @@ static const struct attribute_group vt8231_group = { | |||
655 | .attrs = vt8231_attributes, | 651 | .attrs = vt8231_attributes, |
656 | }; | 652 | }; |
657 | 653 | ||
658 | static struct i2c_driver vt8231_driver = { | 654 | static struct platform_driver vt8231_driver = { |
659 | .driver = { | 655 | .driver = { |
660 | .owner = THIS_MODULE, | 656 | .owner = THIS_MODULE, |
661 | .name = "vt8231", | 657 | .name = "vt8231", |
662 | }, | 658 | }, |
663 | .attach_adapter = vt8231_detect, | 659 | .probe = vt8231_probe, |
664 | .detach_client = vt8231_detach_client, | 660 | .remove = __devexit_p(vt8231_remove), |
665 | }; | 661 | }; |
666 | 662 | ||
667 | static struct pci_device_id vt8231_pci_ids[] = { | 663 | static struct pci_device_id vt8231_pci_ids[] = { |
@@ -680,40 +676,18 @@ static struct pci_driver vt8231_pci_driver = { | |||
680 | .probe = vt8231_pci_probe, | 676 | .probe = vt8231_pci_probe, |
681 | }; | 677 | }; |
682 | 678 | ||
683 | int vt8231_detect(struct i2c_adapter *adapter) | 679 | int vt8231_probe(struct platform_device *pdev) |
684 | { | 680 | { |
685 | struct i2c_client *client; | 681 | struct resource *res; |
686 | struct vt8231_data *data; | 682 | struct vt8231_data *data; |
687 | int err = 0, i; | 683 | int err = 0, i; |
688 | u16 val; | ||
689 | |||
690 | /* 8231 requires multiple of 256 */ | ||
691 | if (force_addr) { | ||
692 | isa_address = force_addr & 0xFF00; | ||
693 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
694 | isa_address); | ||
695 | if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge, | ||
696 | VT8231_BASE_REG, isa_address)) | ||
697 | return -ENODEV; | ||
698 | } | ||
699 | |||
700 | if (PCIBIOS_SUCCESSFUL != | ||
701 | pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val)) | ||
702 | return -ENODEV; | ||
703 | |||
704 | if (!(val & 0x0001)) { | ||
705 | dev_warn(&adapter->dev, "enabling sensors\n"); | ||
706 | if (PCIBIOS_SUCCESSFUL != | ||
707 | pci_write_config_word(s_bridge, VT8231_ENABLE_REG, | ||
708 | val | 0x0001)) | ||
709 | return -ENODEV; | ||
710 | } | ||
711 | 684 | ||
712 | /* Reserve the ISA region */ | 685 | /* Reserve the ISA region */ |
713 | if (!request_region(isa_address, VT8231_EXTENT, | 686 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
714 | vt8231_pci_driver.name)) { | 687 | if (!request_region(res->start, VT8231_EXTENT, |
715 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 688 | vt8231_driver.driver.name)) { |
716 | isa_address); | 689 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
690 | (unsigned long)res->start, (unsigned long)res->end); | ||
717 | return -ENODEV; | 691 | return -ENODEV; |
718 | } | 692 | } |
719 | 693 | ||
@@ -722,33 +696,23 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
722 | goto exit_release; | 696 | goto exit_release; |
723 | } | 697 | } |
724 | 698 | ||
725 | client = &data->client; | 699 | platform_set_drvdata(pdev, data); |
726 | i2c_set_clientdata(client, data); | 700 | data->addr = res->start; |
727 | client->addr = isa_address; | 701 | data->name = "vt8231"; |
728 | client->adapter = adapter; | ||
729 | client->driver = &vt8231_driver; | ||
730 | |||
731 | /* Fill in the remaining client fields and put into the global list */ | ||
732 | strlcpy(client->name, "vt8231", I2C_NAME_SIZE); | ||
733 | 702 | ||
734 | mutex_init(&data->update_lock); | 703 | mutex_init(&data->update_lock); |
735 | 704 | vt8231_init_device(data); | |
736 | /* Tell the I2C layer a new client has arrived */ | ||
737 | if ((err = i2c_attach_client(client))) | ||
738 | goto exit_free; | ||
739 | |||
740 | vt8231_init_client(client); | ||
741 | 705 | ||
742 | /* Register sysfs hooks */ | 706 | /* Register sysfs hooks */ |
743 | if ((err = sysfs_create_group(&client->dev.kobj, &vt8231_group))) | 707 | if ((err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group))) |
744 | goto exit_detach; | 708 | goto exit_free; |
745 | 709 | ||
746 | /* Must update device information to find out the config field */ | 710 | /* Must update device information to find out the config field */ |
747 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); | 711 | data->uch_config = vt8231_read_value(data, VT8231_REG_UCH_CONFIG); |
748 | 712 | ||
749 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { | 713 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { |
750 | if (ISTEMP(i, data->uch_config)) { | 714 | if (ISTEMP(i, data->uch_config)) { |
751 | if ((err = sysfs_create_group(&client->dev.kobj, | 715 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
752 | &vt8231_group_temps[i]))) | 716 | &vt8231_group_temps[i]))) |
753 | goto exit_remove_files; | 717 | goto exit_remove_files; |
754 | } | 718 | } |
@@ -756,13 +720,13 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
756 | 720 | ||
757 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { | 721 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { |
758 | if (ISVOLT(i, data->uch_config)) { | 722 | if (ISVOLT(i, data->uch_config)) { |
759 | if ((err = sysfs_create_group(&client->dev.kobj, | 723 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
760 | &vt8231_group_volts[i]))) | 724 | &vt8231_group_volts[i]))) |
761 | goto exit_remove_files; | 725 | goto exit_remove_files; |
762 | } | 726 | } |
763 | } | 727 | } |
764 | 728 | ||
765 | data->class_dev = hwmon_device_register(&client->dev); | 729 | data->class_dev = hwmon_device_register(&pdev->dev); |
766 | if (IS_ERR(data->class_dev)) { | 730 | if (IS_ERR(data->class_dev)) { |
767 | err = PTR_ERR(data->class_dev); | 731 | err = PTR_ERR(data->class_dev); |
768 | goto exit_remove_files; | 732 | goto exit_remove_files; |
@@ -771,56 +735,52 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
771 | 735 | ||
772 | exit_remove_files: | 736 | exit_remove_files: |
773 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 737 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
774 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | 738 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
775 | 739 | ||
776 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | 740 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) |
777 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | 741 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]); |
742 | |||
743 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); | ||
778 | 744 | ||
779 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | ||
780 | exit_detach: | ||
781 | i2c_detach_client(client); | ||
782 | exit_free: | 745 | exit_free: |
746 | platform_set_drvdata(pdev, NULL); | ||
783 | kfree(data); | 747 | kfree(data); |
748 | |||
784 | exit_release: | 749 | exit_release: |
785 | release_region(isa_address, VT8231_EXTENT); | 750 | release_region(res->start, VT8231_EXTENT); |
786 | return err; | 751 | return err; |
787 | } | 752 | } |
788 | 753 | ||
789 | static int vt8231_detach_client(struct i2c_client *client) | 754 | static int vt8231_remove(struct platform_device *pdev) |
790 | { | 755 | { |
791 | struct vt8231_data *data = i2c_get_clientdata(client); | 756 | struct vt8231_data *data = platform_get_drvdata(pdev); |
792 | int err, i; | 757 | int i; |
793 | 758 | ||
794 | hwmon_device_unregister(data->class_dev); | 759 | hwmon_device_unregister(data->class_dev); |
795 | 760 | ||
796 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
797 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | 762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
798 | 763 | ||
799 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | 764 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) |
800 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | 765 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]); |
801 | 766 | ||
802 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | 767 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); |
803 | 768 | ||
804 | if ((err = i2c_detach_client(client))) { | 769 | release_region(data->addr, VT8231_EXTENT); |
805 | return err; | 770 | platform_set_drvdata(pdev, NULL); |
806 | } | ||
807 | |||
808 | release_region(client->addr, VT8231_EXTENT); | ||
809 | kfree(data); | 771 | kfree(data); |
810 | |||
811 | return 0; | 772 | return 0; |
812 | } | 773 | } |
813 | 774 | ||
814 | static void vt8231_init_client(struct i2c_client *client) | 775 | static void vt8231_init_device(struct vt8231_data *data) |
815 | { | 776 | { |
816 | vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0); | 777 | vt8231_write_value(data, VT8231_REG_TEMP1_CONFIG, 0); |
817 | vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0); | 778 | vt8231_write_value(data, VT8231_REG_TEMP2_CONFIG, 0); |
818 | } | 779 | } |
819 | 780 | ||
820 | static struct vt8231_data *vt8231_update_device(struct device *dev) | 781 | static struct vt8231_data *vt8231_update_device(struct device *dev) |
821 | { | 782 | { |
822 | struct i2c_client *client = to_i2c_client(dev); | 783 | struct vt8231_data *data = dev_get_drvdata(dev); |
823 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
824 | int i; | 784 | int i; |
825 | u16 low; | 785 | u16 low; |
826 | 786 | ||
@@ -830,41 +790,41 @@ static struct vt8231_data *vt8231_update_device(struct device *dev) | |||
830 | || !data->valid) { | 790 | || !data->valid) { |
831 | for (i = 0; i < 6; i++) { | 791 | for (i = 0; i < 6; i++) { |
832 | if (ISVOLT(i, data->uch_config)) { | 792 | if (ISVOLT(i, data->uch_config)) { |
833 | data->in[i] = vt8231_read_value(client, | 793 | data->in[i] = vt8231_read_value(data, |
834 | regvolt[i]); | 794 | regvolt[i]); |
835 | data->in_min[i] = vt8231_read_value(client, | 795 | data->in_min[i] = vt8231_read_value(data, |
836 | regvoltmin[i]); | 796 | regvoltmin[i]); |
837 | data->in_max[i] = vt8231_read_value(client, | 797 | data->in_max[i] = vt8231_read_value(data, |
838 | regvoltmax[i]); | 798 | regvoltmax[i]); |
839 | } | 799 | } |
840 | } | 800 | } |
841 | for (i = 0; i < 2; i++) { | 801 | for (i = 0; i < 2; i++) { |
842 | data->fan[i] = vt8231_read_value(client, | 802 | data->fan[i] = vt8231_read_value(data, |
843 | VT8231_REG_FAN(i)); | 803 | VT8231_REG_FAN(i)); |
844 | data->fan_min[i] = vt8231_read_value(client, | 804 | data->fan_min[i] = vt8231_read_value(data, |
845 | VT8231_REG_FAN_MIN(i)); | 805 | VT8231_REG_FAN_MIN(i)); |
846 | } | 806 | } |
847 | 807 | ||
848 | low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01); | 808 | low = vt8231_read_value(data, VT8231_REG_TEMP_LOW01); |
849 | low = (low >> 6) | ((low & 0x30) >> 2) | 809 | low = (low >> 6) | ((low & 0x30) >> 2) |
850 | | (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4); | 810 | | (vt8231_read_value(data, VT8231_REG_TEMP_LOW25) << 4); |
851 | for (i = 0; i < 6; i++) { | 811 | for (i = 0; i < 6; i++) { |
852 | if (ISTEMP(i, data->uch_config)) { | 812 | if (ISTEMP(i, data->uch_config)) { |
853 | data->temp[i] = (vt8231_read_value(client, | 813 | data->temp[i] = (vt8231_read_value(data, |
854 | regtemp[i]) << 2) | 814 | regtemp[i]) << 2) |
855 | | ((low >> (2 * i)) & 0x03); | 815 | | ((low >> (2 * i)) & 0x03); |
856 | data->temp_max[i] = vt8231_read_value(client, | 816 | data->temp_max[i] = vt8231_read_value(data, |
857 | regtempmax[i]); | 817 | regtempmax[i]); |
858 | data->temp_min[i] = vt8231_read_value(client, | 818 | data->temp_min[i] = vt8231_read_value(data, |
859 | regtempmin[i]); | 819 | regtempmin[i]); |
860 | } | 820 | } |
861 | } | 821 | } |
862 | 822 | ||
863 | i = vt8231_read_value(client, VT8231_REG_FANDIV); | 823 | i = vt8231_read_value(data, VT8231_REG_FANDIV); |
864 | data->fan_div[0] = (i >> 4) & 0x03; | 824 | data->fan_div[0] = (i >> 4) & 0x03; |
865 | data->fan_div[1] = i >> 6; | 825 | data->fan_div[1] = i >> 6; |
866 | data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) | | 826 | data->alarms = vt8231_read_value(data, VT8231_REG_ALARM1) | |
867 | (vt8231_read_value(client, VT8231_REG_ALARM2) << 8); | 827 | (vt8231_read_value(data, VT8231_REG_ALARM2) << 8); |
868 | 828 | ||
869 | /* Set alarm flags correctly */ | 829 | /* Set alarm flags correctly */ |
870 | if (!data->fan[0] && data->fan_min[0]) { | 830 | if (!data->fan[0] && data->fan_min[0]) { |
@@ -888,33 +848,102 @@ static struct vt8231_data *vt8231_update_device(struct device *dev) | |||
888 | return data; | 848 | return data; |
889 | } | 849 | } |
890 | 850 | ||
851 | static int __devinit vt8231_device_add(unsigned short address) | ||
852 | { | ||
853 | struct resource res = { | ||
854 | .start = address, | ||
855 | .end = address + VT8231_EXTENT - 1, | ||
856 | .name = "vt8231", | ||
857 | .flags = IORESOURCE_IO, | ||
858 | }; | ||
859 | int err; | ||
860 | |||
861 | pdev = platform_device_alloc("vt8231", address); | ||
862 | if (!pdev) { | ||
863 | err = -ENOMEM; | ||
864 | printk(KERN_ERR "vt8231: Device allocation failed\n"); | ||
865 | goto exit; | ||
866 | } | ||
867 | |||
868 | err = platform_device_add_resources(pdev, &res, 1); | ||
869 | if (err) { | ||
870 | printk(KERN_ERR "vt8231: Device resource addition failed " | ||
871 | "(%d)\n", err); | ||
872 | goto exit_device_put; | ||
873 | } | ||
874 | |||
875 | err = platform_device_add(pdev); | ||
876 | if (err) { | ||
877 | printk(KERN_ERR "vt8231: Device addition failed (%d)\n", | ||
878 | err); | ||
879 | goto exit_device_put; | ||
880 | } | ||
881 | |||
882 | return 0; | ||
883 | |||
884 | exit_device_put: | ||
885 | platform_device_put(pdev); | ||
886 | exit: | ||
887 | return err; | ||
888 | } | ||
889 | |||
891 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | 890 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, |
892 | const struct pci_device_id *id) | 891 | const struct pci_device_id *id) |
893 | { | 892 | { |
894 | u16 val; | 893 | u16 address, val; |
894 | if (force_addr) { | ||
895 | address = force_addr & 0xff00; | ||
896 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", | ||
897 | address); | ||
898 | |||
899 | if (PCIBIOS_SUCCESSFUL != | ||
900 | pci_write_config_word(dev, VT8231_BASE_REG, address | 1)) | ||
901 | return -ENODEV; | ||
902 | } | ||
895 | 903 | ||
896 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, | 904 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, |
897 | &val)) | 905 | &val)) |
898 | return -ENODEV; | 906 | return -ENODEV; |
899 | 907 | ||
900 | isa_address = val & ~(VT8231_EXTENT - 1); | 908 | address = val & ~(VT8231_EXTENT - 1); |
901 | if (isa_address == 0 && force_addr == 0) { | 909 | if (address == 0) { |
902 | dev_err(&dev->dev, "base address not set -\ | 910 | dev_err(&dev->dev, "base address not set -\ |
903 | upgrade BIOS or use force_addr=0xaddr\n"); | 911 | upgrade BIOS or use force_addr=0xaddr\n"); |
904 | return -ENODEV; | 912 | return -ENODEV; |
905 | } | 913 | } |
906 | 914 | ||
907 | s_bridge = pci_dev_get(dev); | 915 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_ENABLE_REG, |
916 | &val)) | ||
917 | return -ENODEV; | ||
908 | 918 | ||
909 | if (i2c_isa_add_driver(&vt8231_driver)) { | 919 | if (!(val & 0x0001)) { |
910 | pci_dev_put(s_bridge); | 920 | dev_warn(&dev->dev, "enabling sensors\n"); |
911 | s_bridge = NULL; | 921 | if (PCIBIOS_SUCCESSFUL != |
922 | pci_write_config_word(dev, VT8231_ENABLE_REG, | ||
923 | val | 0x0001)) | ||
924 | return -ENODEV; | ||
912 | } | 925 | } |
913 | 926 | ||
927 | if (platform_driver_register(&vt8231_driver)) | ||
928 | goto exit; | ||
929 | |||
930 | /* Sets global pdev as a side effect */ | ||
931 | if (vt8231_device_add(address)) | ||
932 | goto exit_unregister; | ||
933 | |||
914 | /* Always return failure here. This is to allow other drivers to bind | 934 | /* Always return failure here. This is to allow other drivers to bind |
915 | * to this pci device. We don't really want to have control over the | 935 | * to this pci device. We don't really want to have control over the |
916 | * pci device, we only wanted to read as few register values from it. | 936 | * pci device, we only wanted to read as few register values from it. |
917 | */ | 937 | */ |
938 | |||
939 | /* We do, however, mark ourselves as using the PCI device to stop it | ||
940 | getting unloaded. */ | ||
941 | s_bridge = pci_dev_get(dev); | ||
942 | return -ENODEV; | ||
943 | |||
944 | exit_unregister: | ||
945 | platform_driver_unregister(&vt8231_driver); | ||
946 | exit: | ||
918 | return -ENODEV; | 947 | return -ENODEV; |
919 | } | 948 | } |
920 | 949 | ||
@@ -927,7 +956,8 @@ static void __exit sm_vt8231_exit(void) | |||
927 | { | 956 | { |
928 | pci_unregister_driver(&vt8231_pci_driver); | 957 | pci_unregister_driver(&vt8231_pci_driver); |
929 | if (s_bridge != NULL) { | 958 | if (s_bridge != NULL) { |
930 | i2c_isa_del_driver(&vt8231_driver); | 959 | platform_device_unregister(pdev); |
960 | platform_driver_unregister(&vt8231_driver); | ||
931 | pci_dev_put(s_bridge); | 961 | pci_dev_put(s_bridge); |
932 | s_bridge = NULL; | 962 | s_bridge = NULL; |
933 | } | 963 | } |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 30a76404f0af..c51ae2e17758 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -41,41 +41,39 @@ | |||
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/i2c.h> | 44 | #include <linux/jiffies.h> |
45 | #include <linux/i2c-isa.h> | 45 | #include <linux/platform_device.h> |
46 | #include <linux/hwmon.h> | 46 | #include <linux/hwmon.h> |
47 | #include <linux/hwmon-sysfs.h> | 47 | #include <linux/hwmon-sysfs.h> |
48 | #include <linux/hwmon-vid.h> | ||
48 | #include <linux/err.h> | 49 | #include <linux/err.h> |
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
51 | #include "lm75.h" | 52 | #include "lm75.h" |
52 | 53 | ||
53 | /* The actual ISA address is read from Super-I/O configuration space */ | 54 | enum kinds { w83627ehf, w83627dhg }; |
54 | static unsigned short address; | ||
55 | 55 | ||
56 | /* | 56 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
57 | * Super-I/O constants and functions | 57 | static const char * w83627ehf_device_names[] = { |
58 | */ | 58 | "w83627ehf", |
59 | "w83627dhg", | ||
60 | }; | ||
61 | |||
62 | #define DRVNAME "w83627ehf" | ||
59 | 63 | ||
60 | /* | 64 | /* |
61 | * The three following globals are initialized in w83627ehf_find(), before | 65 | * Super-I/O constants and functions |
62 | * the i2c-isa device is created. Otherwise, they could be stored in | ||
63 | * w83627ehf_data. This is ugly, but necessary, and when the driver is next | ||
64 | * updated to become a platform driver, the globals will disappear. | ||
65 | */ | 66 | */ |
66 | static int REG; /* The register to read/write */ | ||
67 | static int VAL; /* The value to read/write */ | ||
68 | /* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This | ||
69 | * value is also used in w83627ehf_detect() to export a device name in sysfs | ||
70 | * (e.g. w83627ehf or w83627dhg) */ | ||
71 | static int w83627ehf_num_in; | ||
72 | 67 | ||
73 | #define W83627EHF_LD_HWM 0x0b | 68 | #define W83627EHF_LD_HWM 0x0b |
74 | 69 | ||
75 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | 70 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ |
76 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | 71 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ |
72 | #define SIO_REG_EN_VRM10 0x2C /* GPIO3, GPIO4 selection */ | ||
77 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | 73 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ |
78 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 74 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
75 | #define SIO_REG_VID_CTRL 0xF0 /* VID control */ | ||
76 | #define SIO_REG_VID_DATA 0xF1 /* VID data */ | ||
79 | 77 | ||
80 | #define SIO_W83627EHF_ID 0x8850 | 78 | #define SIO_W83627EHF_ID 0x8850 |
81 | #define SIO_W83627EHG_ID 0x8860 | 79 | #define SIO_W83627EHG_ID 0x8860 |
@@ -83,38 +81,38 @@ static int w83627ehf_num_in; | |||
83 | #define SIO_ID_MASK 0xFFF0 | 81 | #define SIO_ID_MASK 0xFFF0 |
84 | 82 | ||
85 | static inline void | 83 | static inline void |
86 | superio_outb(int reg, int val) | 84 | superio_outb(int ioreg, int reg, int val) |
87 | { | 85 | { |
88 | outb(reg, REG); | 86 | outb(reg, ioreg); |
89 | outb(val, VAL); | 87 | outb(val, ioreg + 1); |
90 | } | 88 | } |
91 | 89 | ||
92 | static inline int | 90 | static inline int |
93 | superio_inb(int reg) | 91 | superio_inb(int ioreg, int reg) |
94 | { | 92 | { |
95 | outb(reg, REG); | 93 | outb(reg, ioreg); |
96 | return inb(VAL); | 94 | return inb(ioreg + 1); |
97 | } | 95 | } |
98 | 96 | ||
99 | static inline void | 97 | static inline void |
100 | superio_select(int ld) | 98 | superio_select(int ioreg, int ld) |
101 | { | 99 | { |
102 | outb(SIO_REG_LDSEL, REG); | 100 | outb(SIO_REG_LDSEL, ioreg); |
103 | outb(ld, VAL); | 101 | outb(ld, ioreg + 1); |
104 | } | 102 | } |
105 | 103 | ||
106 | static inline void | 104 | static inline void |
107 | superio_enter(void) | 105 | superio_enter(int ioreg) |
108 | { | 106 | { |
109 | outb(0x87, REG); | 107 | outb(0x87, ioreg); |
110 | outb(0x87, REG); | 108 | outb(0x87, ioreg); |
111 | } | 109 | } |
112 | 110 | ||
113 | static inline void | 111 | static inline void |
114 | superio_exit(void) | 112 | superio_exit(int ioreg) |
115 | { | 113 | { |
116 | outb(0x02, REG); | 114 | outb(0x02, ioreg); |
117 | outb(0x02, VAL); | 115 | outb(0x02, ioreg + 1); |
118 | } | 116 | } |
119 | 117 | ||
120 | /* | 118 | /* |
@@ -124,8 +122,8 @@ superio_exit(void) | |||
124 | #define IOREGION_ALIGNMENT ~7 | 122 | #define IOREGION_ALIGNMENT ~7 |
125 | #define IOREGION_OFFSET 5 | 123 | #define IOREGION_OFFSET 5 |
126 | #define IOREGION_LENGTH 2 | 124 | #define IOREGION_LENGTH 2 |
127 | #define ADDR_REG_OFFSET 5 | 125 | #define ADDR_REG_OFFSET 0 |
128 | #define DATA_REG_OFFSET 6 | 126 | #define DATA_REG_OFFSET 1 |
129 | 127 | ||
130 | #define W83627EHF_REG_BANK 0x4E | 128 | #define W83627EHF_REG_BANK 0x4E |
131 | #define W83627EHF_REG_CONFIG 0x40 | 129 | #define W83627EHF_REG_CONFIG 0x40 |
@@ -255,7 +253,9 @@ static inline u8 in_to_reg(u32 val, u8 nr) | |||
255 | */ | 253 | */ |
256 | 254 | ||
257 | struct w83627ehf_data { | 255 | struct w83627ehf_data { |
258 | struct i2c_client client; | 256 | int addr; /* IO base of hw monitor block */ |
257 | const char *name; | ||
258 | |||
259 | struct class_device *class_dev; | 259 | struct class_device *class_dev; |
260 | struct mutex lock; | 260 | struct mutex lock; |
261 | 261 | ||
@@ -264,6 +264,7 @@ struct w83627ehf_data { | |||
264 | unsigned long last_updated; /* In jiffies */ | 264 | unsigned long last_updated; /* In jiffies */ |
265 | 265 | ||
266 | /* Register values */ | 266 | /* Register values */ |
267 | u8 in_num; /* number of in inputs we have */ | ||
267 | u8 in[10]; /* Register value */ | 268 | u8 in[10]; /* Register value */ |
268 | u8 in_max[10]; /* Register value */ | 269 | u8 in_max[10]; /* Register value */ |
269 | u8 in_min[10]; /* Register value */ | 270 | u8 in_min[10]; /* Register value */ |
@@ -271,6 +272,7 @@ struct w83627ehf_data { | |||
271 | u8 fan_min[5]; | 272 | u8 fan_min[5]; |
272 | u8 fan_div[5]; | 273 | u8 fan_div[5]; |
273 | u8 has_fan; /* some fan inputs can be disabled */ | 274 | u8 has_fan; /* some fan inputs can be disabled */ |
275 | u8 temp_type[3]; | ||
274 | s8 temp1; | 276 | s8 temp1; |
275 | s8 temp1_max; | 277 | s8 temp1_max; |
276 | s8 temp1_max_hyst; | 278 | s8 temp1_max_hyst; |
@@ -288,6 +290,14 @@ struct w83627ehf_data { | |||
288 | 290 | ||
289 | u8 fan_min_output[4]; /* minimum fan speed */ | 291 | u8 fan_min_output[4]; /* minimum fan speed */ |
290 | u8 fan_stop_time[4]; | 292 | u8 fan_stop_time[4]; |
293 | |||
294 | u8 vid; | ||
295 | u8 vrm; | ||
296 | }; | ||
297 | |||
298 | struct w83627ehf_sio_data { | ||
299 | int sioreg; | ||
300 | enum kinds kind; | ||
291 | }; | 301 | }; |
292 | 302 | ||
293 | static inline int is_word_sized(u16 reg) | 303 | static inline int is_word_sized(u16 reg) |
@@ -303,156 +313,152 @@ static inline int is_word_sized(u16 reg) | |||
303 | nothing for registers which live in bank 0. For others, they respectively | 313 | nothing for registers which live in bank 0. For others, they respectively |
304 | set the bank register to the correct value (before the register is | 314 | set the bank register to the correct value (before the register is |
305 | accessed), and back to 0 (afterwards). */ | 315 | accessed), and back to 0 (afterwards). */ |
306 | static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg) | 316 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
307 | { | 317 | { |
308 | if (reg & 0xff00) { | 318 | if (reg & 0xff00) { |
309 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 319 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
310 | outb_p(reg >> 8, client->addr + DATA_REG_OFFSET); | 320 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); |
311 | } | 321 | } |
312 | } | 322 | } |
313 | 323 | ||
314 | static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg) | 324 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) |
315 | { | 325 | { |
316 | if (reg & 0xff00) { | 326 | if (reg & 0xff00) { |
317 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 327 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
318 | outb_p(0, client->addr + DATA_REG_OFFSET); | 328 | outb_p(0, data->addr + DATA_REG_OFFSET); |
319 | } | 329 | } |
320 | } | 330 | } |
321 | 331 | ||
322 | static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) | 332 | static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg) |
323 | { | 333 | { |
324 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
325 | int res, word_sized = is_word_sized(reg); | 334 | int res, word_sized = is_word_sized(reg); |
326 | 335 | ||
327 | mutex_lock(&data->lock); | 336 | mutex_lock(&data->lock); |
328 | 337 | ||
329 | w83627ehf_set_bank(client, reg); | 338 | w83627ehf_set_bank(data, reg); |
330 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 339 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
331 | res = inb_p(client->addr + DATA_REG_OFFSET); | 340 | res = inb_p(data->addr + DATA_REG_OFFSET); |
332 | if (word_sized) { | 341 | if (word_sized) { |
333 | outb_p((reg & 0xff) + 1, | 342 | outb_p((reg & 0xff) + 1, |
334 | client->addr + ADDR_REG_OFFSET); | 343 | data->addr + ADDR_REG_OFFSET); |
335 | res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET); | 344 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); |
336 | } | 345 | } |
337 | w83627ehf_reset_bank(client, reg); | 346 | w83627ehf_reset_bank(data, reg); |
338 | 347 | ||
339 | mutex_unlock(&data->lock); | 348 | mutex_unlock(&data->lock); |
340 | 349 | ||
341 | return res; | 350 | return res; |
342 | } | 351 | } |
343 | 352 | ||
344 | static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) | 353 | static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, u16 value) |
345 | { | 354 | { |
346 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
347 | int word_sized = is_word_sized(reg); | 355 | int word_sized = is_word_sized(reg); |
348 | 356 | ||
349 | mutex_lock(&data->lock); | 357 | mutex_lock(&data->lock); |
350 | 358 | ||
351 | w83627ehf_set_bank(client, reg); | 359 | w83627ehf_set_bank(data, reg); |
352 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 360 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
353 | if (word_sized) { | 361 | if (word_sized) { |
354 | outb_p(value >> 8, client->addr + DATA_REG_OFFSET); | 362 | outb_p(value >> 8, data->addr + DATA_REG_OFFSET); |
355 | outb_p((reg & 0xff) + 1, | 363 | outb_p((reg & 0xff) + 1, |
356 | client->addr + ADDR_REG_OFFSET); | 364 | data->addr + ADDR_REG_OFFSET); |
357 | } | 365 | } |
358 | outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); | 366 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); |
359 | w83627ehf_reset_bank(client, reg); | 367 | w83627ehf_reset_bank(data, reg); |
360 | 368 | ||
361 | mutex_unlock(&data->lock); | 369 | mutex_unlock(&data->lock); |
362 | return 0; | 370 | return 0; |
363 | } | 371 | } |
364 | 372 | ||
365 | /* This function assumes that the caller holds data->update_lock */ | 373 | /* This function assumes that the caller holds data->update_lock */ |
366 | static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | 374 | static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) |
367 | { | 375 | { |
368 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
369 | u8 reg; | 376 | u8 reg; |
370 | 377 | ||
371 | switch (nr) { | 378 | switch (nr) { |
372 | case 0: | 379 | case 0: |
373 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | 380 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0xcf) |
374 | | ((data->fan_div[0] & 0x03) << 4); | 381 | | ((data->fan_div[0] & 0x03) << 4); |
375 | /* fan5 input control bit is write only, compute the value */ | 382 | /* fan5 input control bit is write only, compute the value */ |
376 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 383 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
377 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 384 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
378 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | 385 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xdf) |
379 | | ((data->fan_div[0] & 0x04) << 3); | 386 | | ((data->fan_div[0] & 0x04) << 3); |
380 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 387 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
381 | break; | 388 | break; |
382 | case 1: | 389 | case 1: |
383 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | 390 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0x3f) |
384 | | ((data->fan_div[1] & 0x03) << 6); | 391 | | ((data->fan_div[1] & 0x03) << 6); |
385 | /* fan5 input control bit is write only, compute the value */ | 392 | /* fan5 input control bit is write only, compute the value */ |
386 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 393 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
387 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 394 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
388 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | 395 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xbf) |
389 | | ((data->fan_div[1] & 0x04) << 4); | 396 | | ((data->fan_div[1] & 0x04) << 4); |
390 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 397 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
391 | break; | 398 | break; |
392 | case 2: | 399 | case 2: |
393 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f) | 400 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV2) & 0x3f) |
394 | | ((data->fan_div[2] & 0x03) << 6); | 401 | | ((data->fan_div[2] & 0x03) << 6); |
395 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg); | 402 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV2, reg); |
396 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f) | 403 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0x7f) |
397 | | ((data->fan_div[2] & 0x04) << 5); | 404 | | ((data->fan_div[2] & 0x04) << 5); |
398 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 405 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
399 | break; | 406 | break; |
400 | case 3: | 407 | case 3: |
401 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc) | 408 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0xfc) |
402 | | (data->fan_div[3] & 0x03); | 409 | | (data->fan_div[3] & 0x03); |
403 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 410 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
404 | reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f) | 411 | reg = (w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT) & 0x7f) |
405 | | ((data->fan_div[3] & 0x04) << 5); | 412 | | ((data->fan_div[3] & 0x04) << 5); |
406 | w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg); | 413 | w83627ehf_write_value(data, W83627EHF_REG_SMI_OVT, reg); |
407 | break; | 414 | break; |
408 | case 4: | 415 | case 4: |
409 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73) | 416 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0x73) |
410 | | ((data->fan_div[4] & 0x03) << 2) | 417 | | ((data->fan_div[4] & 0x03) << 2) |
411 | | ((data->fan_div[4] & 0x04) << 5); | 418 | | ((data->fan_div[4] & 0x04) << 5); |
412 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 419 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
413 | break; | 420 | break; |
414 | } | 421 | } |
415 | } | 422 | } |
416 | 423 | ||
417 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | 424 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
418 | { | 425 | { |
419 | struct i2c_client *client = to_i2c_client(dev); | 426 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
420 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
421 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ | 427 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ |
422 | int i; | 428 | int i; |
423 | 429 | ||
424 | mutex_lock(&data->update_lock); | 430 | mutex_lock(&data->update_lock); |
425 | 431 | ||
426 | if (time_after(jiffies, data->last_updated + HZ) | 432 | if (time_after(jiffies, data->last_updated + HZ + HZ/2) |
427 | || !data->valid) { | 433 | || !data->valid) { |
428 | /* Fan clock dividers */ | 434 | /* Fan clock dividers */ |
429 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 435 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
430 | data->fan_div[0] = (i >> 4) & 0x03; | 436 | data->fan_div[0] = (i >> 4) & 0x03; |
431 | data->fan_div[1] = (i >> 6) & 0x03; | 437 | data->fan_div[1] = (i >> 6) & 0x03; |
432 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2); | 438 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); |
433 | data->fan_div[2] = (i >> 6) & 0x03; | 439 | data->fan_div[2] = (i >> 6) & 0x03; |
434 | i = w83627ehf_read_value(client, W83627EHF_REG_VBAT); | 440 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); |
435 | data->fan_div[0] |= (i >> 3) & 0x04; | 441 | data->fan_div[0] |= (i >> 3) & 0x04; |
436 | data->fan_div[1] |= (i >> 4) & 0x04; | 442 | data->fan_div[1] |= (i >> 4) & 0x04; |
437 | data->fan_div[2] |= (i >> 5) & 0x04; | 443 | data->fan_div[2] |= (i >> 5) & 0x04; |
438 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | 444 | if (data->has_fan & ((1 << 3) | (1 << 4))) { |
439 | i = w83627ehf_read_value(client, W83627EHF_REG_DIODE); | 445 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); |
440 | data->fan_div[3] = i & 0x03; | 446 | data->fan_div[3] = i & 0x03; |
441 | data->fan_div[4] = ((i >> 2) & 0x03) | 447 | data->fan_div[4] = ((i >> 2) & 0x03) |
442 | | ((i >> 5) & 0x04); | 448 | | ((i >> 5) & 0x04); |
443 | } | 449 | } |
444 | if (data->has_fan & (1 << 3)) { | 450 | if (data->has_fan & (1 << 3)) { |
445 | i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT); | 451 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); |
446 | data->fan_div[3] |= (i >> 5) & 0x04; | 452 | data->fan_div[3] |= (i >> 5) & 0x04; |
447 | } | 453 | } |
448 | 454 | ||
449 | /* Measured voltages and limits */ | 455 | /* Measured voltages and limits */ |
450 | for (i = 0; i < w83627ehf_num_in; i++) { | 456 | for (i = 0; i < data->in_num; i++) { |
451 | data->in[i] = w83627ehf_read_value(client, | 457 | data->in[i] = w83627ehf_read_value(data, |
452 | W83627EHF_REG_IN(i)); | 458 | W83627EHF_REG_IN(i)); |
453 | data->in_min[i] = w83627ehf_read_value(client, | 459 | data->in_min[i] = w83627ehf_read_value(data, |
454 | W83627EHF_REG_IN_MIN(i)); | 460 | W83627EHF_REG_IN_MIN(i)); |
455 | data->in_max[i] = w83627ehf_read_value(client, | 461 | data->in_max[i] = w83627ehf_read_value(data, |
456 | W83627EHF_REG_IN_MAX(i)); | 462 | W83627EHF_REG_IN_MAX(i)); |
457 | } | 463 | } |
458 | 464 | ||
@@ -461,9 +467,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
461 | if (!(data->has_fan & (1 << i))) | 467 | if (!(data->has_fan & (1 << i))) |
462 | continue; | 468 | continue; |
463 | 469 | ||
464 | data->fan[i] = w83627ehf_read_value(client, | 470 | data->fan[i] = w83627ehf_read_value(data, |
465 | W83627EHF_REG_FAN[i]); | 471 | W83627EHF_REG_FAN[i]); |
466 | data->fan_min[i] = w83627ehf_read_value(client, | 472 | data->fan_min[i] = w83627ehf_read_value(data, |
467 | W83627EHF_REG_FAN_MIN[i]); | 473 | W83627EHF_REG_FAN_MIN[i]); |
468 | 474 | ||
469 | /* If we failed to measure the fan speed and clock | 475 | /* If we failed to measure the fan speed and clock |
@@ -471,16 +477,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
471 | time */ | 477 | time */ |
472 | if (data->fan[i] == 0xff | 478 | if (data->fan[i] == 0xff |
473 | && data->fan_div[i] < 0x07) { | 479 | && data->fan_div[i] < 0x07) { |
474 | dev_dbg(&client->dev, "Increasing fan%d " | 480 | dev_dbg(dev, "Increasing fan%d " |
475 | "clock divider from %u to %u\n", | 481 | "clock divider from %u to %u\n", |
476 | i + 1, div_from_reg(data->fan_div[i]), | 482 | i + 1, div_from_reg(data->fan_div[i]), |
477 | div_from_reg(data->fan_div[i] + 1)); | 483 | div_from_reg(data->fan_div[i] + 1)); |
478 | data->fan_div[i]++; | 484 | data->fan_div[i]++; |
479 | w83627ehf_write_fan_div(client, i); | 485 | w83627ehf_write_fan_div(data, i); |
480 | /* Preserve min limit if possible */ | 486 | /* Preserve min limit if possible */ |
481 | if (data->fan_min[i] >= 2 | 487 | if (data->fan_min[i] >= 2 |
482 | && data->fan_min[i] != 255) | 488 | && data->fan_min[i] != 255) |
483 | w83627ehf_write_value(client, | 489 | w83627ehf_write_value(data, |
484 | W83627EHF_REG_FAN_MIN[i], | 490 | W83627EHF_REG_FAN_MIN[i], |
485 | (data->fan_min[i] /= 2)); | 491 | (data->fan_min[i] /= 2)); |
486 | } | 492 | } |
@@ -489,9 +495,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
489 | for (i = 0; i < 4; i++) { | 495 | for (i = 0; i < 4; i++) { |
490 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ | 496 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ |
491 | if (i != 1) { | 497 | if (i != 1) { |
492 | pwmcfg = w83627ehf_read_value(client, | 498 | pwmcfg = w83627ehf_read_value(data, |
493 | W83627EHF_REG_PWM_ENABLE[i]); | 499 | W83627EHF_REG_PWM_ENABLE[i]); |
494 | tolerance = w83627ehf_read_value(client, | 500 | tolerance = w83627ehf_read_value(data, |
495 | W83627EHF_REG_TOLERANCE[i]); | 501 | W83627EHF_REG_TOLERANCE[i]); |
496 | } | 502 | } |
497 | data->pwm_mode[i] = | 503 | data->pwm_mode[i] = |
@@ -500,14 +506,14 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
500 | data->pwm_enable[i] = | 506 | data->pwm_enable[i] = |
501 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) | 507 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) |
502 | & 3) + 1; | 508 | & 3) + 1; |
503 | data->pwm[i] = w83627ehf_read_value(client, | 509 | data->pwm[i] = w83627ehf_read_value(data, |
504 | W83627EHF_REG_PWM[i]); | 510 | W83627EHF_REG_PWM[i]); |
505 | data->fan_min_output[i] = w83627ehf_read_value(client, | 511 | data->fan_min_output[i] = w83627ehf_read_value(data, |
506 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); | 512 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); |
507 | data->fan_stop_time[i] = w83627ehf_read_value(client, | 513 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
508 | W83627EHF_REG_FAN_STOP_TIME[i]); | 514 | W83627EHF_REG_FAN_STOP_TIME[i]); |
509 | data->target_temp[i] = | 515 | data->target_temp[i] = |
510 | w83627ehf_read_value(client, | 516 | w83627ehf_read_value(data, |
511 | W83627EHF_REG_TARGET[i]) & | 517 | W83627EHF_REG_TARGET[i]) & |
512 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); | 518 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); |
513 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) | 519 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) |
@@ -515,26 +521,26 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
515 | } | 521 | } |
516 | 522 | ||
517 | /* Measured temperatures and limits */ | 523 | /* Measured temperatures and limits */ |
518 | data->temp1 = w83627ehf_read_value(client, | 524 | data->temp1 = w83627ehf_read_value(data, |
519 | W83627EHF_REG_TEMP1); | 525 | W83627EHF_REG_TEMP1); |
520 | data->temp1_max = w83627ehf_read_value(client, | 526 | data->temp1_max = w83627ehf_read_value(data, |
521 | W83627EHF_REG_TEMP1_OVER); | 527 | W83627EHF_REG_TEMP1_OVER); |
522 | data->temp1_max_hyst = w83627ehf_read_value(client, | 528 | data->temp1_max_hyst = w83627ehf_read_value(data, |
523 | W83627EHF_REG_TEMP1_HYST); | 529 | W83627EHF_REG_TEMP1_HYST); |
524 | for (i = 0; i < 2; i++) { | 530 | for (i = 0; i < 2; i++) { |
525 | data->temp[i] = w83627ehf_read_value(client, | 531 | data->temp[i] = w83627ehf_read_value(data, |
526 | W83627EHF_REG_TEMP[i]); | 532 | W83627EHF_REG_TEMP[i]); |
527 | data->temp_max[i] = w83627ehf_read_value(client, | 533 | data->temp_max[i] = w83627ehf_read_value(data, |
528 | W83627EHF_REG_TEMP_OVER[i]); | 534 | W83627EHF_REG_TEMP_OVER[i]); |
529 | data->temp_max_hyst[i] = w83627ehf_read_value(client, | 535 | data->temp_max_hyst[i] = w83627ehf_read_value(data, |
530 | W83627EHF_REG_TEMP_HYST[i]); | 536 | W83627EHF_REG_TEMP_HYST[i]); |
531 | } | 537 | } |
532 | 538 | ||
533 | data->alarms = w83627ehf_read_value(client, | 539 | data->alarms = w83627ehf_read_value(data, |
534 | W83627EHF_REG_ALARM1) | | 540 | W83627EHF_REG_ALARM1) | |
535 | (w83627ehf_read_value(client, | 541 | (w83627ehf_read_value(data, |
536 | W83627EHF_REG_ALARM2) << 8) | | 542 | W83627EHF_REG_ALARM2) << 8) | |
537 | (w83627ehf_read_value(client, | 543 | (w83627ehf_read_value(data, |
538 | W83627EHF_REG_ALARM3) << 16); | 544 | W83627EHF_REG_ALARM3) << 16); |
539 | 545 | ||
540 | data->last_updated = jiffies; | 546 | data->last_updated = jiffies; |
@@ -567,15 +573,14 @@ static ssize_t \ | |||
567 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ | 573 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ |
568 | const char *buf, size_t count) \ | 574 | const char *buf, size_t count) \ |
569 | { \ | 575 | { \ |
570 | struct i2c_client *client = to_i2c_client(dev); \ | 576 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
571 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
572 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 577 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
573 | int nr = sensor_attr->index; \ | 578 | int nr = sensor_attr->index; \ |
574 | u32 val = simple_strtoul(buf, NULL, 10); \ | 579 | u32 val = simple_strtoul(buf, NULL, 10); \ |
575 | \ | 580 | \ |
576 | mutex_lock(&data->update_lock); \ | 581 | mutex_lock(&data->update_lock); \ |
577 | data->in_##reg[nr] = in_to_reg(val, nr); \ | 582 | data->in_##reg[nr] = in_to_reg(val, nr); \ |
578 | w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ | 583 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ |
579 | data->in_##reg[nr]); \ | 584 | data->in_##reg[nr]); \ |
580 | mutex_unlock(&data->update_lock); \ | 585 | mutex_unlock(&data->update_lock); \ |
581 | return count; \ | 586 | return count; \ |
@@ -673,8 +678,7 @@ static ssize_t | |||
673 | store_fan_min(struct device *dev, struct device_attribute *attr, | 678 | store_fan_min(struct device *dev, struct device_attribute *attr, |
674 | const char *buf, size_t count) | 679 | const char *buf, size_t count) |
675 | { | 680 | { |
676 | struct i2c_client *client = to_i2c_client(dev); | 681 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
677 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
678 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 682 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
679 | int nr = sensor_attr->index; | 683 | int nr = sensor_attr->index; |
680 | unsigned int val = simple_strtoul(buf, NULL, 10); | 684 | unsigned int val = simple_strtoul(buf, NULL, 10); |
@@ -716,18 +720,25 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
716 | /* Write both the fan clock divider (if it changed) and the new | 720 | /* Write both the fan clock divider (if it changed) and the new |
717 | fan min (unconditionally) */ | 721 | fan min (unconditionally) */ |
718 | if (new_div != data->fan_div[nr]) { | 722 | if (new_div != data->fan_div[nr]) { |
719 | if (new_div > data->fan_div[nr]) | 723 | /* Preserve the fan speed reading */ |
720 | data->fan[nr] >>= (data->fan_div[nr] - new_div); | 724 | if (data->fan[nr] != 0xff) { |
721 | else | 725 | if (new_div > data->fan_div[nr]) |
722 | data->fan[nr] <<= (new_div - data->fan_div[nr]); | 726 | data->fan[nr] >>= new_div - data->fan_div[nr]; |
727 | else if (data->fan[nr] & 0x80) | ||
728 | data->fan[nr] = 0xff; | ||
729 | else | ||
730 | data->fan[nr] <<= data->fan_div[nr] - new_div; | ||
731 | } | ||
723 | 732 | ||
724 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | 733 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", |
725 | nr + 1, div_from_reg(data->fan_div[nr]), | 734 | nr + 1, div_from_reg(data->fan_div[nr]), |
726 | div_from_reg(new_div)); | 735 | div_from_reg(new_div)); |
727 | data->fan_div[nr] = new_div; | 736 | data->fan_div[nr] = new_div; |
728 | w83627ehf_write_fan_div(client, nr); | 737 | w83627ehf_write_fan_div(data, nr); |
738 | /* Give the chip time to sample a new speed value */ | ||
739 | data->last_updated = jiffies; | ||
729 | } | 740 | } |
730 | w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], | 741 | w83627ehf_write_value(data, W83627EHF_REG_FAN_MIN[nr], |
731 | data->fan_min[nr]); | 742 | data->fan_min[nr]); |
732 | mutex_unlock(&data->update_lock); | 743 | mutex_unlock(&data->update_lock); |
733 | 744 | ||
@@ -788,13 +799,12 @@ static ssize_t \ | |||
788 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | 799 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ |
789 | const char *buf, size_t count) \ | 800 | const char *buf, size_t count) \ |
790 | { \ | 801 | { \ |
791 | struct i2c_client *client = to_i2c_client(dev); \ | 802 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
792 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
793 | u32 val = simple_strtoul(buf, NULL, 10); \ | 803 | u32 val = simple_strtoul(buf, NULL, 10); \ |
794 | \ | 804 | \ |
795 | mutex_lock(&data->update_lock); \ | 805 | mutex_lock(&data->update_lock); \ |
796 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 806 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
797 | w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ | 807 | w83627ehf_write_value(data, W83627EHF_REG_TEMP1_##REG, \ |
798 | data->temp1_##reg); \ | 808 | data->temp1_##reg); \ |
799 | mutex_unlock(&data->update_lock); \ | 809 | mutex_unlock(&data->update_lock); \ |
800 | return count; \ | 810 | return count; \ |
@@ -822,15 +832,14 @@ static ssize_t \ | |||
822 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 832 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
823 | const char *buf, size_t count) \ | 833 | const char *buf, size_t count) \ |
824 | { \ | 834 | { \ |
825 | struct i2c_client *client = to_i2c_client(dev); \ | 835 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
826 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
827 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 836 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
828 | int nr = sensor_attr->index; \ | 837 | int nr = sensor_attr->index; \ |
829 | u32 val = simple_strtoul(buf, NULL, 10); \ | 838 | u32 val = simple_strtoul(buf, NULL, 10); \ |
830 | \ | 839 | \ |
831 | mutex_lock(&data->update_lock); \ | 840 | mutex_lock(&data->update_lock); \ |
832 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 841 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
833 | w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ | 842 | w83627ehf_write_value(data, W83627EHF_REG_TEMP_##REG[nr], \ |
834 | data->reg[nr]); \ | 843 | data->reg[nr]); \ |
835 | mutex_unlock(&data->update_lock); \ | 844 | mutex_unlock(&data->update_lock); \ |
836 | return count; \ | 845 | return count; \ |
@@ -838,6 +847,15 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
838 | store_temp_reg(OVER, temp_max); | 847 | store_temp_reg(OVER, temp_max); |
839 | store_temp_reg(HYST, temp_max_hyst); | 848 | store_temp_reg(HYST, temp_max_hyst); |
840 | 849 | ||
850 | static ssize_t | ||
851 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
852 | { | ||
853 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
854 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
855 | int nr = sensor_attr->index; | ||
856 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); | ||
857 | } | ||
858 | |||
841 | static struct sensor_device_attribute sda_temp[] = { | 859 | static struct sensor_device_attribute sda_temp[] = { |
842 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), | 860 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), |
843 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), | 861 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), |
@@ -857,6 +875,9 @@ static struct sensor_device_attribute sda_temp[] = { | |||
857 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), | 875 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), |
858 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), | 876 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), |
859 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), | 877 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), |
878 | SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), | ||
879 | SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), | ||
880 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | ||
860 | }; | 881 | }; |
861 | 882 | ||
862 | #define show_pwm_reg(reg) \ | 883 | #define show_pwm_reg(reg) \ |
@@ -877,8 +898,7 @@ static ssize_t | |||
877 | store_pwm_mode(struct device *dev, struct device_attribute *attr, | 898 | store_pwm_mode(struct device *dev, struct device_attribute *attr, |
878 | const char *buf, size_t count) | 899 | const char *buf, size_t count) |
879 | { | 900 | { |
880 | struct i2c_client *client = to_i2c_client(dev); | 901 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
881 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
882 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 902 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
883 | int nr = sensor_attr->index; | 903 | int nr = sensor_attr->index; |
884 | u32 val = simple_strtoul(buf, NULL, 10); | 904 | u32 val = simple_strtoul(buf, NULL, 10); |
@@ -887,12 +907,12 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
887 | if (val > 1) | 907 | if (val > 1) |
888 | return -EINVAL; | 908 | return -EINVAL; |
889 | mutex_lock(&data->update_lock); | 909 | mutex_lock(&data->update_lock); |
890 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 910 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
891 | data->pwm_mode[nr] = val; | 911 | data->pwm_mode[nr] = val; |
892 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); | 912 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); |
893 | if (!val) | 913 | if (!val) |
894 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; | 914 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; |
895 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 915 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
896 | mutex_unlock(&data->update_lock); | 916 | mutex_unlock(&data->update_lock); |
897 | return count; | 917 | return count; |
898 | } | 918 | } |
@@ -901,15 +921,14 @@ static ssize_t | |||
901 | store_pwm(struct device *dev, struct device_attribute *attr, | 921 | store_pwm(struct device *dev, struct device_attribute *attr, |
902 | const char *buf, size_t count) | 922 | const char *buf, size_t count) |
903 | { | 923 | { |
904 | struct i2c_client *client = to_i2c_client(dev); | 924 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
905 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
906 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 925 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
907 | int nr = sensor_attr->index; | 926 | int nr = sensor_attr->index; |
908 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); | 927 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); |
909 | 928 | ||
910 | mutex_lock(&data->update_lock); | 929 | mutex_lock(&data->update_lock); |
911 | data->pwm[nr] = val; | 930 | data->pwm[nr] = val; |
912 | w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val); | 931 | w83627ehf_write_value(data, W83627EHF_REG_PWM[nr], val); |
913 | mutex_unlock(&data->update_lock); | 932 | mutex_unlock(&data->update_lock); |
914 | return count; | 933 | return count; |
915 | } | 934 | } |
@@ -918,8 +937,7 @@ static ssize_t | |||
918 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | 937 | store_pwm_enable(struct device *dev, struct device_attribute *attr, |
919 | const char *buf, size_t count) | 938 | const char *buf, size_t count) |
920 | { | 939 | { |
921 | struct i2c_client *client = to_i2c_client(dev); | 940 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
922 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
923 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 941 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
924 | int nr = sensor_attr->index; | 942 | int nr = sensor_attr->index; |
925 | u32 val = simple_strtoul(buf, NULL, 10); | 943 | u32 val = simple_strtoul(buf, NULL, 10); |
@@ -928,11 +946,11 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
928 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | 946 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ |
929 | return -EINVAL; | 947 | return -EINVAL; |
930 | mutex_lock(&data->update_lock); | 948 | mutex_lock(&data->update_lock); |
931 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 949 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
932 | data->pwm_enable[nr] = val; | 950 | data->pwm_enable[nr] = val; |
933 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); | 951 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); |
934 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; | 952 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; |
935 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 953 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
936 | mutex_unlock(&data->update_lock); | 954 | mutex_unlock(&data->update_lock); |
937 | return count; | 955 | return count; |
938 | } | 956 | } |
@@ -955,15 +973,14 @@ static ssize_t | |||
955 | store_target_temp(struct device *dev, struct device_attribute *attr, | 973 | store_target_temp(struct device *dev, struct device_attribute *attr, |
956 | const char *buf, size_t count) | 974 | const char *buf, size_t count) |
957 | { | 975 | { |
958 | struct i2c_client *client = to_i2c_client(dev); | 976 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
959 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
960 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
961 | int nr = sensor_attr->index; | 978 | int nr = sensor_attr->index; |
962 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); | 979 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); |
963 | 980 | ||
964 | mutex_lock(&data->update_lock); | 981 | mutex_lock(&data->update_lock); |
965 | data->target_temp[nr] = val; | 982 | data->target_temp[nr] = val; |
966 | w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val); | 983 | w83627ehf_write_value(data, W83627EHF_REG_TARGET[nr], val); |
967 | mutex_unlock(&data->update_lock); | 984 | mutex_unlock(&data->update_lock); |
968 | return count; | 985 | return count; |
969 | } | 986 | } |
@@ -972,8 +989,7 @@ static ssize_t | |||
972 | store_tolerance(struct device *dev, struct device_attribute *attr, | 989 | store_tolerance(struct device *dev, struct device_attribute *attr, |
973 | const char *buf, size_t count) | 990 | const char *buf, size_t count) |
974 | { | 991 | { |
975 | struct i2c_client *client = to_i2c_client(dev); | 992 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
976 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 993 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
978 | int nr = sensor_attr->index; | 994 | int nr = sensor_attr->index; |
979 | u16 reg; | 995 | u16 reg; |
@@ -981,13 +997,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr, | |||
981 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); | 997 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); |
982 | 998 | ||
983 | mutex_lock(&data->update_lock); | 999 | mutex_lock(&data->update_lock); |
984 | reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]); | 1000 | reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]); |
985 | data->tolerance[nr] = val; | 1001 | data->tolerance[nr] = val; |
986 | if (nr == 1) | 1002 | if (nr == 1) |
987 | reg = (reg & 0x0f) | (val << 4); | 1003 | reg = (reg & 0x0f) | (val << 4); |
988 | else | 1004 | else |
989 | reg = (reg & 0xf0) | val; | 1005 | reg = (reg & 0xf0) | val; |
990 | w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg); | 1006 | w83627ehf_write_value(data, W83627EHF_REG_TOLERANCE[nr], reg); |
991 | mutex_unlock(&data->update_lock); | 1007 | mutex_unlock(&data->update_lock); |
992 | return count; | 1008 | return count; |
993 | } | 1009 | } |
@@ -1058,14 +1074,13 @@ static ssize_t \ | |||
1058 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1074 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
1059 | const char *buf, size_t count) \ | 1075 | const char *buf, size_t count) \ |
1060 | {\ | 1076 | {\ |
1061 | struct i2c_client *client = to_i2c_client(dev); \ | 1077 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
1062 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
1063 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1078 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
1064 | int nr = sensor_attr->index; \ | 1079 | int nr = sensor_attr->index; \ |
1065 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ | 1080 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ |
1066 | mutex_lock(&data->update_lock); \ | 1081 | mutex_lock(&data->update_lock); \ |
1067 | data->reg[nr] = val; \ | 1082 | data->reg[nr] = val; \ |
1068 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1083 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
1069 | mutex_unlock(&data->update_lock); \ | 1084 | mutex_unlock(&data->update_lock); \ |
1070 | return count; \ | 1085 | return count; \ |
1071 | } | 1086 | } |
@@ -1087,21 +1102,28 @@ static ssize_t \ | |||
1087 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1102 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
1088 | const char *buf, size_t count) \ | 1103 | const char *buf, size_t count) \ |
1089 | { \ | 1104 | { \ |
1090 | struct i2c_client *client = to_i2c_client(dev); \ | 1105 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
1091 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
1092 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1106 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
1093 | int nr = sensor_attr->index; \ | 1107 | int nr = sensor_attr->index; \ |
1094 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ | 1108 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ |
1095 | data->pwm_mode[nr]); \ | 1109 | data->pwm_mode[nr]); \ |
1096 | mutex_lock(&data->update_lock); \ | 1110 | mutex_lock(&data->update_lock); \ |
1097 | data->reg[nr] = val; \ | 1111 | data->reg[nr] = val; \ |
1098 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1112 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
1099 | mutex_unlock(&data->update_lock); \ | 1113 | mutex_unlock(&data->update_lock); \ |
1100 | return count; \ | 1114 | return count; \ |
1101 | } \ | 1115 | } \ |
1102 | 1116 | ||
1103 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) | 1117 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) |
1104 | 1118 | ||
1119 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
1120 | char *buf) | ||
1121 | { | ||
1122 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1123 | |||
1124 | return sprintf(buf, "%s\n", data->name); | ||
1125 | } | ||
1126 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
1105 | 1127 | ||
1106 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | 1128 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
1107 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1129 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
@@ -1125,8 +1147,16 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
1125 | store_fan_min_output, 2), | 1147 | store_fan_min_output, 2), |
1126 | }; | 1148 | }; |
1127 | 1149 | ||
1150 | static ssize_t | ||
1151 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) | ||
1152 | { | ||
1153 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1154 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
1155 | } | ||
1156 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
1157 | |||
1128 | /* | 1158 | /* |
1129 | * Driver and client management | 1159 | * Driver and device management |
1130 | */ | 1160 | */ |
1131 | 1161 | ||
1132 | static void w83627ehf_device_remove_files(struct device *dev) | 1162 | static void w83627ehf_device_remove_files(struct device *dev) |
@@ -1134,12 +1164,13 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1134 | /* some entries in the following arrays may not have been used in | 1164 | /* some entries in the following arrays may not have been used in |
1135 | * device_create_file(), but device_remove_file() will ignore them */ | 1165 | * device_create_file(), but device_remove_file() will ignore them */ |
1136 | int i; | 1166 | int i; |
1167 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1137 | 1168 | ||
1138 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1169 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
1139 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1170 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
1140 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1171 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
1141 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1172 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
1142 | for (i = 0; i < w83627ehf_num_in; i++) { | 1173 | for (i = 0; i < data->in_num; i++) { |
1143 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1174 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
1144 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1175 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
1145 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1176 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
@@ -1160,43 +1191,64 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1160 | } | 1191 | } |
1161 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | 1192 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) |
1162 | device_remove_file(dev, &sda_temp[i].dev_attr); | 1193 | device_remove_file(dev, &sda_temp[i].dev_attr); |
1163 | } | ||
1164 | 1194 | ||
1165 | static struct i2c_driver w83627ehf_driver; | 1195 | device_remove_file(dev, &dev_attr_name); |
1196 | if (data->vid != 0x3f) | ||
1197 | device_remove_file(dev, &dev_attr_cpu0_vid); | ||
1198 | } | ||
1166 | 1199 | ||
1167 | static void w83627ehf_init_client(struct i2c_client *client) | 1200 | /* Get the monitoring functions started */ |
1201 | static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) | ||
1168 | { | 1202 | { |
1169 | int i; | 1203 | int i; |
1170 | u8 tmp; | 1204 | u8 tmp, diode; |
1171 | 1205 | ||
1172 | /* Start monitoring is needed */ | 1206 | /* Start monitoring is needed */ |
1173 | tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG); | 1207 | tmp = w83627ehf_read_value(data, W83627EHF_REG_CONFIG); |
1174 | if (!(tmp & 0x01)) | 1208 | if (!(tmp & 0x01)) |
1175 | w83627ehf_write_value(client, W83627EHF_REG_CONFIG, | 1209 | w83627ehf_write_value(data, W83627EHF_REG_CONFIG, |
1176 | tmp | 0x01); | 1210 | tmp | 0x01); |
1177 | 1211 | ||
1178 | /* Enable temp2 and temp3 if needed */ | 1212 | /* Enable temp2 and temp3 if needed */ |
1179 | for (i = 0; i < 2; i++) { | 1213 | for (i = 0; i < 2; i++) { |
1180 | tmp = w83627ehf_read_value(client, | 1214 | tmp = w83627ehf_read_value(data, |
1181 | W83627EHF_REG_TEMP_CONFIG[i]); | 1215 | W83627EHF_REG_TEMP_CONFIG[i]); |
1182 | if (tmp & 0x01) | 1216 | if (tmp & 0x01) |
1183 | w83627ehf_write_value(client, | 1217 | w83627ehf_write_value(data, |
1184 | W83627EHF_REG_TEMP_CONFIG[i], | 1218 | W83627EHF_REG_TEMP_CONFIG[i], |
1185 | tmp & 0xfe); | 1219 | tmp & 0xfe); |
1186 | } | 1220 | } |
1221 | |||
1222 | /* Enable VBAT monitoring if needed */ | ||
1223 | tmp = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
1224 | if (!(tmp & 0x01)) | ||
1225 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01); | ||
1226 | |||
1227 | /* Get thermal sensor types */ | ||
1228 | diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | ||
1229 | for (i = 0; i < 3; i++) { | ||
1230 | if ((tmp & (0x02 << i))) | ||
1231 | data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2; | ||
1232 | else | ||
1233 | data->temp_type[i] = 4; /* thermistor */ | ||
1234 | } | ||
1187 | } | 1235 | } |
1188 | 1236 | ||
1189 | static int w83627ehf_detect(struct i2c_adapter *adapter) | 1237 | static int __devinit w83627ehf_probe(struct platform_device *pdev) |
1190 | { | 1238 | { |
1191 | struct i2c_client *client; | 1239 | struct device *dev = &pdev->dev; |
1240 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
1192 | struct w83627ehf_data *data; | 1241 | struct w83627ehf_data *data; |
1193 | struct device *dev; | 1242 | struct resource *res; |
1194 | u8 fan4pin, fan5pin; | 1243 | u8 fan4pin, fan5pin, en_vrm10; |
1195 | int i, err = 0; | 1244 | int i, err = 0; |
1196 | 1245 | ||
1197 | if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH, | 1246 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1198 | w83627ehf_driver.driver.name)) { | 1247 | if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) { |
1199 | err = -EBUSY; | 1248 | err = -EBUSY; |
1249 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
1250 | (unsigned long)res->start, | ||
1251 | (unsigned long)res->start + IOREGION_LENGTH - 1); | ||
1200 | goto exit; | 1252 | goto exit; |
1201 | } | 1253 | } |
1202 | 1254 | ||
@@ -1205,41 +1257,47 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1205 | goto exit_release; | 1257 | goto exit_release; |
1206 | } | 1258 | } |
1207 | 1259 | ||
1208 | client = &data->client; | 1260 | data->addr = res->start; |
1209 | i2c_set_clientdata(client, data); | ||
1210 | client->addr = address; | ||
1211 | mutex_init(&data->lock); | 1261 | mutex_init(&data->lock); |
1212 | client->adapter = adapter; | ||
1213 | client->driver = &w83627ehf_driver; | ||
1214 | client->flags = 0; | ||
1215 | dev = &client->dev; | ||
1216 | |||
1217 | if (w83627ehf_num_in == 9) | ||
1218 | strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); | ||
1219 | else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ | ||
1220 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | ||
1221 | |||
1222 | data->valid = 0; | ||
1223 | mutex_init(&data->update_lock); | 1262 | mutex_init(&data->update_lock); |
1263 | data->name = w83627ehf_device_names[sio_data->kind]; | ||
1264 | platform_set_drvdata(pdev, data); | ||
1224 | 1265 | ||
1225 | /* Tell the i2c layer a new client has arrived */ | 1266 | /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ |
1226 | if ((err = i2c_attach_client(client))) | 1267 | data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; |
1227 | goto exit_free; | ||
1228 | 1268 | ||
1229 | /* Initialize the chip */ | 1269 | /* Initialize the chip */ |
1230 | w83627ehf_init_client(client); | 1270 | w83627ehf_init_device(data); |
1231 | 1271 | ||
1232 | /* A few vars need to be filled upon startup */ | 1272 | data->vrm = vid_which_vrm(); |
1233 | for (i = 0; i < 5; i++) | 1273 | superio_enter(sio_data->sioreg); |
1234 | data->fan_min[i] = w83627ehf_read_value(client, | 1274 | /* Set VID input sensibility if needed. In theory the BIOS should |
1235 | W83627EHF_REG_FAN_MIN[i]); | 1275 | have set it, but in practice it's not always the case. */ |
1276 | en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); | ||
1277 | if ((en_vrm10 & 0x08) && data->vrm != 100) { | ||
1278 | dev_warn(dev, "Setting VID input voltage to TTL\n"); | ||
1279 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
1280 | en_vrm10 & ~0x08); | ||
1281 | } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { | ||
1282 | dev_warn(dev, "Setting VID input voltage to VRM10\n"); | ||
1283 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
1284 | en_vrm10 | 0x08); | ||
1285 | } | ||
1286 | /* Read VID value */ | ||
1287 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | ||
1288 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) | ||
1289 | data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f; | ||
1290 | else { | ||
1291 | dev_info(dev, "VID pins in output mode, CPU VID not " | ||
1292 | "available\n"); | ||
1293 | data->vid = 0x3f; | ||
1294 | } | ||
1236 | 1295 | ||
1237 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 1296 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
1238 | 1297 | ||
1239 | superio_enter(); | 1298 | fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; |
1240 | fan5pin = superio_inb(0x24) & 0x2; | 1299 | fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; |
1241 | fan4pin = superio_inb(0x29) & 0x6; | 1300 | superio_exit(sio_data->sioreg); |
1242 | superio_exit(); | ||
1243 | 1301 | ||
1244 | /* It looks like fan4 and fan5 pins can be alternatively used | 1302 | /* It looks like fan4 and fan5 pins can be alternatively used |
1245 | as fan on/off switches, but fan5 control is write only :/ | 1303 | as fan on/off switches, but fan5 control is write only :/ |
@@ -1248,7 +1306,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1248 | is not the default. */ | 1306 | is not the default. */ |
1249 | 1307 | ||
1250 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ | 1308 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ |
1251 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 1309 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
1252 | if ((i & (1 << 2)) && (!fan4pin)) | 1310 | if ((i & (1 << 2)) && (!fan4pin)) |
1253 | data->has_fan |= (1 << 3); | 1311 | data->has_fan |= (1 << 3); |
1254 | if (!(i & (1 << 1)) && (!fan5pin)) | 1312 | if (!(i & (1 << 1)) && (!fan5pin)) |
@@ -1268,7 +1326,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1268 | goto exit_remove; | 1326 | goto exit_remove; |
1269 | } | 1327 | } |
1270 | 1328 | ||
1271 | for (i = 0; i < w83627ehf_num_in; i++) | 1329 | for (i = 0; i < data->in_num; i++) |
1272 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1330 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
1273 | || (err = device_create_file(dev, | 1331 | || (err = device_create_file(dev, |
1274 | &sda_in_alarm[i].dev_attr)) | 1332 | &sda_in_alarm[i].dev_attr)) |
@@ -1308,6 +1366,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1308 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) | 1366 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) |
1309 | goto exit_remove; | 1367 | goto exit_remove; |
1310 | 1368 | ||
1369 | err = device_create_file(dev, &dev_attr_name); | ||
1370 | if (err) | ||
1371 | goto exit_remove; | ||
1372 | |||
1373 | if (data->vid != 0x3f) { | ||
1374 | err = device_create_file(dev, &dev_attr_cpu0_vid); | ||
1375 | if (err) | ||
1376 | goto exit_remove; | ||
1377 | } | ||
1378 | |||
1311 | data->class_dev = hwmon_device_register(dev); | 1379 | data->class_dev = hwmon_device_register(dev); |
1312 | if (IS_ERR(data->class_dev)) { | 1380 | if (IS_ERR(data->class_dev)) { |
1313 | err = PTR_ERR(data->class_dev); | 1381 | err = PTR_ERR(data->class_dev); |
@@ -1318,95 +1386,172 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1318 | 1386 | ||
1319 | exit_remove: | 1387 | exit_remove: |
1320 | w83627ehf_device_remove_files(dev); | 1388 | w83627ehf_device_remove_files(dev); |
1321 | i2c_detach_client(client); | ||
1322 | exit_free: | ||
1323 | kfree(data); | 1389 | kfree(data); |
1390 | platform_set_drvdata(pdev, NULL); | ||
1324 | exit_release: | 1391 | exit_release: |
1325 | release_region(address + IOREGION_OFFSET, IOREGION_LENGTH); | 1392 | release_region(res->start, IOREGION_LENGTH); |
1326 | exit: | 1393 | exit: |
1327 | return err; | 1394 | return err; |
1328 | } | 1395 | } |
1329 | 1396 | ||
1330 | static int w83627ehf_detach_client(struct i2c_client *client) | 1397 | static int __devexit w83627ehf_remove(struct platform_device *pdev) |
1331 | { | 1398 | { |
1332 | struct w83627ehf_data *data = i2c_get_clientdata(client); | 1399 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
1333 | int err; | ||
1334 | 1400 | ||
1335 | hwmon_device_unregister(data->class_dev); | 1401 | hwmon_device_unregister(data->class_dev); |
1336 | w83627ehf_device_remove_files(&client->dev); | 1402 | w83627ehf_device_remove_files(&pdev->dev); |
1337 | 1403 | release_region(data->addr, IOREGION_LENGTH); | |
1338 | if ((err = i2c_detach_client(client))) | 1404 | platform_set_drvdata(pdev, NULL); |
1339 | return err; | ||
1340 | release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH); | ||
1341 | kfree(data); | 1405 | kfree(data); |
1342 | 1406 | ||
1343 | return 0; | 1407 | return 0; |
1344 | } | 1408 | } |
1345 | 1409 | ||
1346 | static struct i2c_driver w83627ehf_driver = { | 1410 | static struct platform_driver w83627ehf_driver = { |
1347 | .driver = { | 1411 | .driver = { |
1348 | .owner = THIS_MODULE, | 1412 | .owner = THIS_MODULE, |
1349 | .name = "w83627ehf", | 1413 | .name = DRVNAME, |
1350 | }, | 1414 | }, |
1351 | .attach_adapter = w83627ehf_detect, | 1415 | .probe = w83627ehf_probe, |
1352 | .detach_client = w83627ehf_detach_client, | 1416 | .remove = __devexit_p(w83627ehf_remove), |
1353 | }; | 1417 | }; |
1354 | 1418 | ||
1355 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | 1419 | /* w83627ehf_find() looks for a '627 in the Super-I/O config space */ |
1420 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | ||
1421 | struct w83627ehf_sio_data *sio_data) | ||
1356 | { | 1422 | { |
1423 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | ||
1424 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | ||
1425 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | ||
1426 | |||
1357 | u16 val; | 1427 | u16 val; |
1428 | const char *sio_name; | ||
1358 | 1429 | ||
1359 | REG = sioaddr; | 1430 | superio_enter(sioaddr); |
1360 | VAL = sioaddr + 1; | ||
1361 | superio_enter(); | ||
1362 | 1431 | ||
1363 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1432 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
1364 | | superio_inb(SIO_REG_DEVID + 1); | 1433 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); |
1365 | switch (val & SIO_ID_MASK) { | 1434 | switch (val & SIO_ID_MASK) { |
1366 | case SIO_W83627DHG_ID: | ||
1367 | w83627ehf_num_in = 9; | ||
1368 | break; | ||
1369 | case SIO_W83627EHF_ID: | 1435 | case SIO_W83627EHF_ID: |
1436 | sio_data->kind = w83627ehf; | ||
1437 | sio_name = sio_name_W83627EHF; | ||
1438 | break; | ||
1370 | case SIO_W83627EHG_ID: | 1439 | case SIO_W83627EHG_ID: |
1371 | w83627ehf_num_in = 10; | 1440 | sio_data->kind = w83627ehf; |
1441 | sio_name = sio_name_W83627EHG; | ||
1442 | break; | ||
1443 | case SIO_W83627DHG_ID: | ||
1444 | sio_data->kind = w83627dhg; | ||
1445 | sio_name = sio_name_W83627DHG; | ||
1372 | break; | 1446 | break; |
1373 | default: | 1447 | default: |
1374 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | 1448 | if (val != 0xffff) |
1375 | val); | 1449 | pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", |
1376 | superio_exit(); | 1450 | val); |
1451 | superio_exit(sioaddr); | ||
1377 | return -ENODEV; | 1452 | return -ENODEV; |
1378 | } | 1453 | } |
1379 | 1454 | ||
1380 | superio_select(W83627EHF_LD_HWM); | 1455 | /* We have a known chip, find the HWM I/O address */ |
1381 | val = (superio_inb(SIO_REG_ADDR) << 8) | 1456 | superio_select(sioaddr, W83627EHF_LD_HWM); |
1382 | | superio_inb(SIO_REG_ADDR + 1); | 1457 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) |
1458 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
1383 | *addr = val & IOREGION_ALIGNMENT; | 1459 | *addr = val & IOREGION_ALIGNMENT; |
1384 | if (*addr == 0) { | 1460 | if (*addr == 0) { |
1385 | superio_exit(); | 1461 | printk(KERN_ERR DRVNAME ": Refusing to enable a Super-I/O " |
1462 | "device with a base I/O port 0.\n"); | ||
1463 | superio_exit(sioaddr); | ||
1386 | return -ENODEV; | 1464 | return -ENODEV; |
1387 | } | 1465 | } |
1388 | 1466 | ||
1389 | /* Activate logical device if needed */ | 1467 | /* Activate logical device if needed */ |
1390 | val = superio_inb(SIO_REG_ENABLE); | 1468 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
1391 | if (!(val & 0x01)) | 1469 | if (!(val & 0x01)) { |
1392 | superio_outb(SIO_REG_ENABLE, val | 0x01); | 1470 | printk(KERN_WARNING DRVNAME ": Forcibly enabling Super-I/O. " |
1471 | "Sensor is probably unusable.\n"); | ||
1472 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | ||
1473 | } | ||
1474 | |||
1475 | superio_exit(sioaddr); | ||
1476 | pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr); | ||
1477 | sio_data->sioreg = sioaddr; | ||
1393 | 1478 | ||
1394 | superio_exit(); | ||
1395 | return 0; | 1479 | return 0; |
1396 | } | 1480 | } |
1397 | 1481 | ||
1482 | /* when Super-I/O functions move to a separate file, the Super-I/O | ||
1483 | * bus will manage the lifetime of the device and this module will only keep | ||
1484 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | ||
1485 | * must keep track of the device */ | ||
1486 | static struct platform_device *pdev; | ||
1487 | |||
1398 | static int __init sensors_w83627ehf_init(void) | 1488 | static int __init sensors_w83627ehf_init(void) |
1399 | { | 1489 | { |
1400 | if (w83627ehf_find(0x2e, &address) | 1490 | int err; |
1401 | && w83627ehf_find(0x4e, &address)) | 1491 | unsigned short address; |
1492 | struct resource res; | ||
1493 | struct w83627ehf_sio_data sio_data; | ||
1494 | |||
1495 | /* initialize sio_data->kind and sio_data->sioreg. | ||
1496 | * | ||
1497 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
1498 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
1499 | * w83627ehf hardware monitor, and call probe() */ | ||
1500 | if (w83627ehf_find(0x2e, &address, &sio_data) && | ||
1501 | w83627ehf_find(0x4e, &address, &sio_data)) | ||
1402 | return -ENODEV; | 1502 | return -ENODEV; |
1403 | 1503 | ||
1404 | return i2c_isa_add_driver(&w83627ehf_driver); | 1504 | err = platform_driver_register(&w83627ehf_driver); |
1505 | if (err) | ||
1506 | goto exit; | ||
1507 | |||
1508 | if (!(pdev = platform_device_alloc(DRVNAME, address))) { | ||
1509 | err = -ENOMEM; | ||
1510 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
1511 | goto exit_unregister; | ||
1512 | } | ||
1513 | |||
1514 | err = platform_device_add_data(pdev, &sio_data, | ||
1515 | sizeof(struct w83627ehf_sio_data)); | ||
1516 | if (err) { | ||
1517 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
1518 | goto exit_device_put; | ||
1519 | } | ||
1520 | |||
1521 | memset(&res, 0, sizeof(res)); | ||
1522 | res.name = DRVNAME; | ||
1523 | res.start = address + IOREGION_OFFSET; | ||
1524 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
1525 | res.flags = IORESOURCE_IO; | ||
1526 | err = platform_device_add_resources(pdev, &res, 1); | ||
1527 | if (err) { | ||
1528 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
1529 | "(%d)\n", err); | ||
1530 | goto exit_device_put; | ||
1531 | } | ||
1532 | |||
1533 | /* platform_device_add calls probe() */ | ||
1534 | err = platform_device_add(pdev); | ||
1535 | if (err) { | ||
1536 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
1537 | err); | ||
1538 | goto exit_device_put; | ||
1539 | } | ||
1540 | |||
1541 | return 0; | ||
1542 | |||
1543 | exit_device_put: | ||
1544 | platform_device_put(pdev); | ||
1545 | exit_unregister: | ||
1546 | platform_driver_unregister(&w83627ehf_driver); | ||
1547 | exit: | ||
1548 | return err; | ||
1405 | } | 1549 | } |
1406 | 1550 | ||
1407 | static void __exit sensors_w83627ehf_exit(void) | 1551 | static void __exit sensors_w83627ehf_exit(void) |
1408 | { | 1552 | { |
1409 | i2c_isa_del_driver(&w83627ehf_driver); | 1553 | platform_device_unregister(pdev); |
1554 | platform_driver_unregister(&w83627ehf_driver); | ||
1410 | } | 1555 | } |
1411 | 1556 | ||
1412 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 1557 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 12cb40a975de..1ce78179b005 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -220,6 +220,18 @@ static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, | |||
220 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ | 220 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ |
221 | regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) | 221 | regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) |
222 | 222 | ||
223 | #define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ | ||
224 | |||
225 | #define W83637HF_REG_PWM_FREQ1 0x00 /* 697HF/687THF too */ | ||
226 | #define W83637HF_REG_PWM_FREQ2 0x02 /* 697HF/687THF too */ | ||
227 | #define W83637HF_REG_PWM_FREQ3 0x10 /* 687THF too */ | ||
228 | |||
229 | static const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1, | ||
230 | W83637HF_REG_PWM_FREQ2, | ||
231 | W83637HF_REG_PWM_FREQ3 }; | ||
232 | |||
233 | #define W83627HF_BASE_PWM_FREQ 46870 | ||
234 | |||
223 | #define W83781D_REG_I2C_ADDR 0x48 | 235 | #define W83781D_REG_I2C_ADDR 0x48 |
224 | #define W83781D_REG_I2C_SUBADDR 0x4A | 236 | #define W83781D_REG_I2C_SUBADDR 0x4A |
225 | 237 | ||
@@ -267,6 +279,49 @@ static int TEMP_FROM_REG(u8 reg) | |||
267 | 279 | ||
268 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) | 280 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) |
269 | 281 | ||
282 | static inline unsigned long pwm_freq_from_reg_627hf(u8 reg) | ||
283 | { | ||
284 | unsigned long freq; | ||
285 | freq = W83627HF_BASE_PWM_FREQ >> reg; | ||
286 | return freq; | ||
287 | } | ||
288 | static inline u8 pwm_freq_to_reg_627hf(unsigned long val) | ||
289 | { | ||
290 | u8 i; | ||
291 | /* Only 5 dividers (1 2 4 8 16) | ||
292 | Search for the nearest available frequency */ | ||
293 | for (i = 0; i < 4; i++) { | ||
294 | if (val > (((W83627HF_BASE_PWM_FREQ >> i) + | ||
295 | (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2)) | ||
296 | break; | ||
297 | } | ||
298 | return i; | ||
299 | } | ||
300 | |||
301 | static inline unsigned long pwm_freq_from_reg(u8 reg) | ||
302 | { | ||
303 | /* Clock bit 8 -> 180 kHz or 24 MHz */ | ||
304 | unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL; | ||
305 | |||
306 | reg &= 0x7f; | ||
307 | /* This should not happen but anyway... */ | ||
308 | if (reg == 0) | ||
309 | reg++; | ||
310 | return (clock / (reg << 8)); | ||
311 | } | ||
312 | static inline u8 pwm_freq_to_reg(unsigned long val) | ||
313 | { | ||
314 | /* Minimum divider value is 0x01 and maximum is 0x7F */ | ||
315 | if (val >= 93750) /* The highest we can do */ | ||
316 | return 0x01; | ||
317 | if (val >= 720) /* Use 24 MHz clock */ | ||
318 | return (24000000UL / (val << 8)); | ||
319 | if (val < 6) /* The lowest we can do */ | ||
320 | return 0xFF; | ||
321 | else /* Use 180 kHz clock */ | ||
322 | return (0x80 | (180000UL / (val << 8))); | ||
323 | } | ||
324 | |||
270 | #define BEEP_MASK_FROM_REG(val) (val) | 325 | #define BEEP_MASK_FROM_REG(val) (val) |
271 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) | 326 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) |
272 | #define BEEP_ENABLE_TO_REG(val) ((val)?1:0) | 327 | #define BEEP_ENABLE_TO_REG(val) ((val)?1:0) |
@@ -316,6 +371,7 @@ struct w83627hf_data { | |||
316 | u32 beep_mask; /* Register encoding, combined */ | 371 | u32 beep_mask; /* Register encoding, combined */ |
317 | u8 beep_enable; /* Boolean */ | 372 | u8 beep_enable; /* Boolean */ |
318 | u8 pwm[3]; /* Register value */ | 373 | u8 pwm[3]; /* Register value */ |
374 | u8 pwm_freq[3]; /* Register value */ | ||
319 | u16 sens[3]; /* 782D/783S only. | 375 | u16 sens[3]; /* 782D/783S only. |
320 | 1 = pentium diode; 2 = 3904 diode; | 376 | 1 = pentium diode; 2 = 3904 diode; |
321 | 3000-5000 = thermistor beta. | 377 | 3000-5000 = thermistor beta. |
@@ -852,6 +908,64 @@ sysfs_pwm(2); | |||
852 | sysfs_pwm(3); | 908 | sysfs_pwm(3); |
853 | 909 | ||
854 | static ssize_t | 910 | static ssize_t |
911 | show_pwm_freq_reg(struct device *dev, char *buf, int nr) | ||
912 | { | ||
913 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
914 | if (data->type == w83627hf) | ||
915 | return sprintf(buf, "%ld\n", | ||
916 | pwm_freq_from_reg_627hf(data->pwm_freq[nr - 1])); | ||
917 | else | ||
918 | return sprintf(buf, "%ld\n", | ||
919 | pwm_freq_from_reg(data->pwm_freq[nr - 1])); | ||
920 | } | ||
921 | |||
922 | static ssize_t | ||
923 | store_pwm_freq_reg(struct device *dev, const char *buf, size_t count, int nr) | ||
924 | { | ||
925 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
926 | static const u8 mask[]={0xF8, 0x8F}; | ||
927 | u32 val; | ||
928 | |||
929 | val = simple_strtoul(buf, NULL, 10); | ||
930 | |||
931 | mutex_lock(&data->update_lock); | ||
932 | |||
933 | if (data->type == w83627hf) { | ||
934 | data->pwm_freq[nr - 1] = pwm_freq_to_reg_627hf(val); | ||
935 | w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, | ||
936 | (data->pwm_freq[nr - 1] << ((nr - 1)*4)) | | ||
937 | (w83627hf_read_value(data, | ||
938 | W83627HF_REG_PWM_FREQ) & mask[nr - 1])); | ||
939 | } else { | ||
940 | data->pwm_freq[nr - 1] = pwm_freq_to_reg(val); | ||
941 | w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr - 1], | ||
942 | data->pwm_freq[nr - 1]); | ||
943 | } | ||
944 | |||
945 | mutex_unlock(&data->update_lock); | ||
946 | return count; | ||
947 | } | ||
948 | |||
949 | #define sysfs_pwm_freq(offset) \ | ||
950 | static ssize_t show_regs_pwm_freq_##offset(struct device *dev, \ | ||
951 | struct device_attribute *attr, char *buf) \ | ||
952 | { \ | ||
953 | return show_pwm_freq_reg(dev, buf, offset); \ | ||
954 | } \ | ||
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 | |||
968 | static ssize_t | ||
855 | show_sensor_reg(struct device *dev, char *buf, int nr) | 969 | show_sensor_reg(struct device *dev, char *buf, int nr) |
856 | { | 970 | { |
857 | struct w83627hf_data *data = w83627hf_update_device(dev); | 971 | struct w83627hf_data *data = w83627hf_update_device(dev); |
@@ -1077,6 +1191,9 @@ static struct attribute *w83627hf_attributes_opt[] = { | |||
1077 | 1191 | ||
1078 | &dev_attr_pwm3.attr, | 1192 | &dev_attr_pwm3.attr, |
1079 | 1193 | ||
1194 | &dev_attr_pwm1_freq.attr, | ||
1195 | &dev_attr_pwm2_freq.attr, | ||
1196 | &dev_attr_pwm3_freq.attr, | ||
1080 | NULL | 1197 | NULL |
1081 | }; | 1198 | }; |
1082 | 1199 | ||
@@ -1139,7 +1256,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1139 | || (err = device_create_file(dev, &dev_attr_in5_max)) | 1256 | || (err = device_create_file(dev, &dev_attr_in5_max)) |
1140 | || (err = device_create_file(dev, &dev_attr_in6_input)) | 1257 | || (err = device_create_file(dev, &dev_attr_in6_input)) |
1141 | || (err = device_create_file(dev, &dev_attr_in6_min)) | 1258 | || (err = device_create_file(dev, &dev_attr_in6_min)) |
1142 | || (err = device_create_file(dev, &dev_attr_in6_max))) | 1259 | || (err = device_create_file(dev, &dev_attr_in6_max)) |
1260 | || (err = device_create_file(dev, &dev_attr_pwm1_freq)) | ||
1261 | || (err = device_create_file(dev, &dev_attr_pwm2_freq))) | ||
1143 | goto ERROR4; | 1262 | goto ERROR4; |
1144 | 1263 | ||
1145 | if (data->type != w83697hf) | 1264 | if (data->type != w83697hf) |
@@ -1169,6 +1288,12 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1169 | if ((err = device_create_file(dev, &dev_attr_pwm3))) | 1288 | if ((err = device_create_file(dev, &dev_attr_pwm3))) |
1170 | goto ERROR4; | 1289 | goto ERROR4; |
1171 | 1290 | ||
1291 | if (data->type == w83637hf || data->type == w83687thf) | ||
1292 | if ((err = device_create_file(dev, &dev_attr_pwm1_freq)) | ||
1293 | || (err = device_create_file(dev, &dev_attr_pwm2_freq)) | ||
1294 | || (err = device_create_file(dev, &dev_attr_pwm3_freq))) | ||
1295 | goto ERROR4; | ||
1296 | |||
1172 | data->class_dev = hwmon_device_register(dev); | 1297 | data->class_dev = hwmon_device_register(dev); |
1173 | if (IS_ERR(data->class_dev)) { | 1298 | if (IS_ERR(data->class_dev)) { |
1174 | err = PTR_ERR(data->class_dev); | 1299 | err = PTR_ERR(data->class_dev); |
@@ -1181,6 +1306,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1181 | sysfs_remove_group(&dev->kobj, &w83627hf_group); | 1306 | sysfs_remove_group(&dev->kobj, &w83627hf_group); |
1182 | sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); | 1307 | sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); |
1183 | ERROR3: | 1308 | ERROR3: |
1309 | platform_set_drvdata(pdev, NULL); | ||
1184 | kfree(data); | 1310 | kfree(data); |
1185 | ERROR1: | 1311 | ERROR1: |
1186 | release_region(res->start, WINB_REGION_SIZE); | 1312 | release_region(res->start, WINB_REGION_SIZE); |
@@ -1193,11 +1319,11 @@ static int __devexit w83627hf_remove(struct platform_device *pdev) | |||
1193 | struct w83627hf_data *data = platform_get_drvdata(pdev); | 1319 | struct w83627hf_data *data = platform_get_drvdata(pdev); |
1194 | struct resource *res; | 1320 | struct resource *res; |
1195 | 1321 | ||
1196 | platform_set_drvdata(pdev, NULL); | ||
1197 | hwmon_device_unregister(data->class_dev); | 1322 | hwmon_device_unregister(data->class_dev); |
1198 | 1323 | ||
1199 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); | 1324 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); |
1200 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); | 1325 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); |
1326 | platform_set_drvdata(pdev, NULL); | ||
1201 | kfree(data); | 1327 | kfree(data); |
1202 | 1328 | ||
1203 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1329 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
@@ -1472,6 +1598,20 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1472 | (data->type == w83627hf || data->type == w83697hf)) | 1598 | (data->type == w83627hf || data->type == w83697hf)) |
1473 | break; | 1599 | break; |
1474 | } | 1600 | } |
1601 | if (data->type == w83627hf) { | ||
1602 | u8 tmp = w83627hf_read_value(data, | ||
1603 | W83627HF_REG_PWM_FREQ); | ||
1604 | data->pwm_freq[0] = tmp & 0x07; | ||
1605 | data->pwm_freq[1] = (tmp >> 4) & 0x07; | ||
1606 | } else if (data->type != w83627thf) { | ||
1607 | for (i = 1; i <= 3; i++) { | ||
1608 | data->pwm_freq[i - 1] = | ||
1609 | w83627hf_read_value(data, | ||
1610 | W83637HF_REG_PWM_FREQ[i - 1]); | ||
1611 | if (i == 2 && (data->type == w83697hf)) | ||
1612 | break; | ||
1613 | } | ||
1614 | } | ||
1475 | 1615 | ||
1476 | data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); | 1616 | data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); |
1477 | data->temp_max = | 1617 | data->temp_max = |
@@ -1548,15 +1688,12 @@ static int __init w83627hf_device_add(unsigned short address, | |||
1548 | goto exit_device_put; | 1688 | goto exit_device_put; |
1549 | } | 1689 | } |
1550 | 1690 | ||
1551 | pdev->dev.platform_data = kmalloc(sizeof(struct w83627hf_sio_data), | 1691 | err = platform_device_add_data(pdev, sio_data, |
1552 | GFP_KERNEL); | 1692 | sizeof(struct w83627hf_sio_data)); |
1553 | if (!pdev->dev.platform_data) { | 1693 | if (err) { |
1554 | err = -ENOMEM; | ||
1555 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 1694 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
1556 | goto exit_device_put; | 1695 | goto exit_device_put; |
1557 | } | 1696 | } |
1558 | memcpy(pdev->dev.platform_data, sio_data, | ||
1559 | sizeof(struct w83627hf_sio_data)); | ||
1560 | 1697 | ||
1561 | err = platform_device_add(pdev); | 1698 | err = platform_device_add(pdev); |
1562 | if (err) { | 1699 | if (err) { |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1c77e14480dc..da1647869f91 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -237,9 +237,6 @@ config I2C_IOP3XX | |||
237 | This driver can also be built as a module. If so, the module | 237 | This driver can also be built as a module. If so, the module |
238 | will be called i2c-iop3xx. | 238 | will be called i2c-iop3xx. |
239 | 239 | ||
240 | config I2C_ISA | ||
241 | tristate | ||
242 | |||
243 | config I2C_IXP4XX | 240 | config I2C_IXP4XX |
244 | tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" | 241 | tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" |
245 | depends on ARCH_IXP4XX | 242 | depends on ARCH_IXP4XX |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index a6db4e38bda8..5b752e4e1918 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -18,7 +18,6 @@ obj-$(CONFIG_I2C_I801) += i2c-i801.o | |||
18 | obj-$(CONFIG_I2C_I810) += i2c-i810.o | 18 | obj-$(CONFIG_I2C_I810) += i2c-i810.o |
19 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o | 19 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o |
20 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o | 20 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o |
21 | obj-$(CONFIG_I2C_ISA) += i2c-isa.o | ||
22 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 21 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
23 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o | 22 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o |
24 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o | 23 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o |
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c deleted file mode 100644 index b0e1370075de..000000000000 --- a/drivers/i2c/busses/i2c-isa.c +++ /dev/null | |||
@@ -1,192 +0,0 @@ | |||
1 | /* | ||
2 | i2c-isa.c - an i2c-core-like thing for ISA hardware monitoring chips | ||
3 | Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
4 | |||
5 | Based on the i2c-isa pseudo-adapter from the lm_sensors project | ||
6 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | /* This implements an i2c-core-like thing for ISA hardware monitoring | ||
24 | chips. Such chips are linked to the i2c subsystem for historical | ||
25 | reasons (because the early ISA hardware monitoring chips such as the | ||
26 | LM78 had both an I2C and an ISA interface). They used to be | ||
27 | registered with the main i2c-core, but as a first step in the | ||
28 | direction of a clean separation between I2C and ISA chip drivers, | ||
29 | we now have this separate core for ISA ones. It is significantly | ||
30 | more simple than the real one, of course, because we don't have to | ||
31 | handle multiple busses: there is only one (fake) ISA adapter. | ||
32 | It is worth noting that we still rely on i2c-core for some things | ||
33 | at the moment - but hopefully this won't last. */ | ||
34 | |||
35 | #include <linux/init.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/errno.h> | ||
39 | #include <linux/i2c.h> | ||
40 | #include <linux/i2c-isa.h> | ||
41 | #include <linux/platform_device.h> | ||
42 | #include <linux/completion.h> | ||
43 | |||
44 | /* Exported by i2c-core for i2c-isa only */ | ||
45 | extern void i2c_adapter_dev_release(struct device *dev); | ||
46 | extern struct class i2c_adapter_class; | ||
47 | |||
48 | static u32 isa_func(struct i2c_adapter *adapter); | ||
49 | |||
50 | /* This is the actual algorithm we define */ | ||
51 | static const struct i2c_algorithm isa_algorithm = { | ||
52 | .functionality = isa_func, | ||
53 | }; | ||
54 | |||
55 | /* There can only be one... */ | ||
56 | static struct i2c_adapter isa_adapter = { | ||
57 | .owner = THIS_MODULE, | ||
58 | .id = I2C_HW_ISA, | ||
59 | .class = I2C_CLASS_HWMON, | ||
60 | .algo = &isa_algorithm, | ||
61 | .name = "ISA main adapter", | ||
62 | }; | ||
63 | |||
64 | /* We can't do a thing... */ | ||
65 | static u32 isa_func(struct i2c_adapter *adapter) | ||
66 | { | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | |||
71 | /* We implement an interface which resembles i2c_{add,del}_driver, | ||
72 | but for i2c-isa drivers. We don't have to remember and handle lists | ||
73 | of drivers and adapters so this is much more simple, of course. */ | ||
74 | |||
75 | int i2c_isa_add_driver(struct i2c_driver *driver) | ||
76 | { | ||
77 | int res; | ||
78 | |||
79 | /* Add the driver to the list of i2c drivers in the driver core */ | ||
80 | driver->driver.bus = &i2c_bus_type; | ||
81 | res = driver_register(&driver->driver); | ||
82 | if (res) | ||
83 | return res; | ||
84 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name); | ||
85 | |||
86 | /* Now look for clients */ | ||
87 | res = driver->attach_adapter(&isa_adapter); | ||
88 | if (res) { | ||
89 | dev_dbg(&isa_adapter.dev, | ||
90 | "Driver %s failed to attach adapter, unregistering\n", | ||
91 | driver->driver.name); | ||
92 | driver_unregister(&driver->driver); | ||
93 | } | ||
94 | return res; | ||
95 | } | ||
96 | |||
97 | int i2c_isa_del_driver(struct i2c_driver *driver) | ||
98 | { | ||
99 | struct list_head *item, *_n; | ||
100 | struct i2c_client *client; | ||
101 | int res; | ||
102 | |||
103 | /* Detach all clients belonging to this one driver */ | ||
104 | list_for_each_safe(item, _n, &isa_adapter.clients) { | ||
105 | client = list_entry(item, struct i2c_client, list); | ||
106 | if (client->driver != driver) | ||
107 | continue; | ||
108 | dev_dbg(&isa_adapter.dev, "Detaching client %s at 0x%x\n", | ||
109 | client->name, client->addr); | ||
110 | if ((res = driver->detach_client(client))) { | ||
111 | dev_err(&isa_adapter.dev, "Failed, driver " | ||
112 | "%s not unregistered!\n", | ||
113 | driver->driver.name); | ||
114 | return res; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | /* Get the driver off the core list */ | ||
119 | driver_unregister(&driver->driver); | ||
120 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | |||
126 | static int __init i2c_isa_init(void) | ||
127 | { | ||
128 | int err; | ||
129 | |||
130 | mutex_init(&isa_adapter.clist_lock); | ||
131 | INIT_LIST_HEAD(&isa_adapter.clients); | ||
132 | |||
133 | isa_adapter.nr = ANY_I2C_ISA_BUS; | ||
134 | isa_adapter.dev.parent = &platform_bus; | ||
135 | sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); | ||
136 | isa_adapter.dev.release = &i2c_adapter_dev_release; | ||
137 | isa_adapter.dev.class = &i2c_adapter_class; | ||
138 | err = device_register(&isa_adapter.dev); | ||
139 | if (err) { | ||
140 | printk(KERN_ERR "i2c-isa: Failed to register device\n"); | ||
141 | goto exit; | ||
142 | } | ||
143 | |||
144 | dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); | ||
145 | |||
146 | return 0; | ||
147 | |||
148 | exit: | ||
149 | return err; | ||
150 | } | ||
151 | |||
152 | static void __exit i2c_isa_exit(void) | ||
153 | { | ||
154 | #ifdef DEBUG | ||
155 | struct list_head *item, *_n; | ||
156 | struct i2c_client *client = NULL; | ||
157 | #endif | ||
158 | |||
159 | /* There should be no more active client */ | ||
160 | #ifdef DEBUG | ||
161 | dev_dbg(&isa_adapter.dev, "Looking for clients\n"); | ||
162 | list_for_each_safe(item, _n, &isa_adapter.clients) { | ||
163 | client = list_entry(item, struct i2c_client, list); | ||
164 | dev_err(&isa_adapter.dev, "Driver %s still has an active " | ||
165 | "ISA client at 0x%x\n", client->driver->driver.name, | ||
166 | client->addr); | ||
167 | } | ||
168 | if (client != NULL) | ||
169 | return; | ||
170 | #endif | ||
171 | |||
172 | /* Clean up the sysfs representation */ | ||
173 | dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n"); | ||
174 | init_completion(&isa_adapter.dev_released); | ||
175 | device_unregister(&isa_adapter.dev); | ||
176 | |||
177 | /* Wait for sysfs to drop all references */ | ||
178 | dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n"); | ||
179 | wait_for_completion(&isa_adapter.dev_released); | ||
180 | |||
181 | dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name); | ||
182 | } | ||
183 | |||
184 | EXPORT_SYMBOL(i2c_isa_add_driver); | ||
185 | EXPORT_SYMBOL(i2c_isa_del_driver); | ||
186 | |||
187 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | ||
188 | MODULE_DESCRIPTION("ISA bus access through i2c"); | ||
189 | MODULE_LICENSE("GPL"); | ||
190 | |||
191 | module_init(i2c_isa_init); | ||
192 | module_exit(i2c_isa_exit); | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6971a62397db..d663e6960d93 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -288,7 +288,6 @@ void i2c_adapter_dev_release(struct device *dev) | |||
288 | struct i2c_adapter *adap = to_i2c_adapter(dev); | 288 | struct i2c_adapter *adap = to_i2c_adapter(dev); |
289 | complete(&adap->dev_released); | 289 | complete(&adap->dev_released); |
290 | } | 290 | } |
291 | EXPORT_SYMBOL_GPL(i2c_adapter_dev_release); /* exported to i2c-isa */ | ||
292 | 291 | ||
293 | static ssize_t | 292 | static ssize_t |
294 | show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) | 293 | show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -307,7 +306,6 @@ struct class i2c_adapter_class = { | |||
307 | .name = "i2c-adapter", | 306 | .name = "i2c-adapter", |
308 | .dev_attrs = i2c_adapter_attrs, | 307 | .dev_attrs = i2c_adapter_attrs, |
309 | }; | 308 | }; |
310 | EXPORT_SYMBOL_GPL(i2c_adapter_class); /* exported to i2c-isa */ | ||
311 | 309 | ||
312 | static void i2c_scan_static_board_info(struct i2c_adapter *adapter) | 310 | static void i2c_scan_static_board_info(struct i2c_adapter *adapter) |
313 | { | 311 | { |
diff --git a/include/linux/i2c-isa.h b/include/linux/i2c-isa.h deleted file mode 100644 index 67e3598c4cec..000000000000 --- a/include/linux/i2c-isa.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * i2c-isa.h - definitions for the i2c-isa pseudo-i2c-adapter interface | ||
3 | * | ||
4 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _LINUX_I2C_ISA_H | ||
22 | #define _LINUX_I2C_ISA_H | ||
23 | |||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | extern int i2c_isa_add_driver(struct i2c_driver *driver); | ||
27 | extern int i2c_isa_del_driver(struct i2c_driver *driver); | ||
28 | |||
29 | /* Detect whether we are on the isa bus. This is only useful to hybrid | ||
30 | (i2c+isa) drivers. */ | ||
31 | #define i2c_is_isa_adapter(adapptr) \ | ||
32 | ((adapptr)->id == I2C_HW_ISA) | ||
33 | #define i2c_is_isa_client(clientptr) \ | ||
34 | i2c_is_isa_adapter((clientptr)->adapter) | ||
35 | |||
36 | #endif /* _LINUX_I2C_ISA_H */ | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 2eaba21b9b1a..0c37a737a2b2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -368,7 +368,6 @@ struct i2c_client_address_data { | |||
368 | 368 | ||
369 | /* The numbers to use to set I2C bus address */ | 369 | /* The numbers to use to set I2C bus address */ |
370 | #define ANY_I2C_BUS 0xffff | 370 | #define ANY_I2C_BUS 0xffff |
371 | #define ANY_I2C_ISA_BUS 9191 | ||
372 | 371 | ||
373 | 372 | ||
374 | /* ----- functions exported by i2c.o */ | 373 | /* ----- functions exported by i2c.o */ |