Commit 41e9a062361de204d3710038925ae7f356ebb40d
Committed by
Linus Torvalds
1 parent
e40d6eaa79
Exists in
master
and in
39 other branches
hwmon: w83627ehf updates
Add control of fan minimum turn-on output levels, decoupling it from the fan turn-off output level. Add control of rate of change of fan output level. These in turn allow lower turn-off rotor speed and smoother transitions for better thermal and acoustic control authority. Add support for constant fan speed and proportional-response operations modes. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Daniel J Blueman <daniel.blueman@gmail.com> Cc: Jean Delvare <khali@linux-fr.org> Cc: David Hubbard <david.c.hubbard@gmail.com> Cc: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 61 additions and 21 deletions Side-by-side Diff
Documentation/hwmon/w83627ehf
... | ... | @@ -81,8 +81,14 @@ |
81 | 81 | 0 (stop) to 255 (full) |
82 | 82 | |
83 | 83 | pwm[1-4]_enable - this file controls mode of fan/temperature control: |
84 | - * 1 Manual Mode, write to pwm file any value 0-255 (full speed) | |
85 | - * 2 Thermal Cruise | |
84 | + * 1 Manual mode, write to pwm file any value 0-255 (full speed) | |
85 | + * 2 "Thermal Cruise" mode | |
86 | + * 3 "Fan Speed Cruise" mode | |
87 | + * 4 "Smart Fan III" mode | |
88 | + | |
89 | +pwm[1-4]_mode - controls if output is PWM or DC level | |
90 | + * 0 DC output (0 - 12v) | |
91 | + * 1 PWM output | |
86 | 92 | |
87 | 93 | Thermal Cruise mode |
88 | 94 | ------------------- |
drivers/hwmon/w83627ehf.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | Copyright (C) 2006 Yuan Mu (Winbond), |
6 | 6 | Rudolf Marek <r.marek@assembler.cz> |
7 | 7 | David Hubbard <david.c.hubbard@gmail.com> |
8 | + Daniel J Blueman <daniel.blueman@gmail.com> | |
8 | 9 | |
9 | 10 | Shamelessly ripped from the w83627hf driver |
10 | 11 | Copyright (C) 2003 Mark Studebaker |
11 | 12 | |
... | ... | @@ -177,12 +178,15 @@ |
177 | 178 | #define W83627EHF_REG_ALARM3 0x45B |
178 | 179 | |
179 | 180 | /* SmartFan registers */ |
181 | +#define W83627EHF_REG_FAN_STEPUP_TIME 0x0f | |
182 | +#define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e | |
183 | + | |
180 | 184 | /* DC or PWM output fan configuration */ |
181 | 185 | static const u8 W83627EHF_REG_PWM_ENABLE[] = { |
182 | 186 | 0x04, /* SYS FAN0 output mode and PWM mode */ |
183 | 187 | 0x04, /* CPU FAN0 output mode and PWM mode */ |
184 | 188 | 0x12, /* AUX FAN mode */ |
185 | - 0x62, /* CPU fan1 mode */ | |
189 | + 0x62, /* CPU FAN1 mode */ | |
186 | 190 | }; |
187 | 191 | |
188 | 192 | static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 }; |
189 | 193 | |
... | ... | @@ -193,10 +197,12 @@ |
193 | 197 | static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 }; |
194 | 198 | static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 }; |
195 | 199 | |
196 | - | |
197 | 200 | /* Advanced Fan control, some values are common for all fans */ |
198 | -static const u8 W83627EHF_REG_FAN_MIN_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 }; | |
199 | -static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0C, 0x0D, 0x17, 0x66 }; | |
201 | +static const u8 W83627EHF_REG_FAN_START_OUTPUT[] = { 0x0a, 0x0b, 0x16, 0x65 }; | |
202 | +static const u8 W83627EHF_REG_FAN_STOP_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 }; | |
203 | +static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0c, 0x0d, 0x17, 0x66 }; | |
204 | +static const u8 W83627EHF_REG_FAN_MAX_OUTPUT[] = { 0xff, 0x67, 0xff, 0x69 }; | |
205 | +static const u8 W83627EHF_REG_FAN_STEP_OUTPUT[] = { 0xff, 0x68, 0xff, 0x6a }; | |
200 | 206 | |
201 | 207 | /* |
202 | 208 | * Conversions |
203 | 209 | |
... | ... | @@ -295,14 +301,19 @@ |
295 | 301 | |
296 | 302 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
297 | 303 | u8 pwm_enable[4]; /* 1->manual |
298 | - 2->thermal cruise (also called SmartFan I) */ | |
304 | + 2->thermal cruise mode (also called SmartFan I) | |
305 | + 3->fan speed cruise mode | |
306 | + 4->variable thermal cruise (also called SmartFan III) */ | |
299 | 307 | u8 pwm_num; /* number of pwm */ |
300 | 308 | u8 pwm[4]; |
301 | 309 | u8 target_temp[4]; |
302 | 310 | u8 tolerance[4]; |
303 | 311 | |
304 | - u8 fan_min_output[4]; /* minimum fan speed */ | |
305 | - u8 fan_stop_time[4]; | |
312 | + u8 fan_start_output[4]; /* minimum fan speed when spinning up */ | |
313 | + u8 fan_stop_output[4]; /* minimum fan speed when spinning down */ | |
314 | + u8 fan_stop_time[4]; /* time at minimum before disabling fan */ | |
315 | + u8 fan_max_output[4]; /* maximum fan speed */ | |
316 | + u8 fan_step_output[4]; /* rate of change output value */ | |
306 | 317 | |
307 | 318 | u8 vid; |
308 | 319 | u8 vrm; |
... | ... | @@ -529,8 +540,10 @@ |
529 | 540 | & 3) + 1; |
530 | 541 | data->pwm[i] = w83627ehf_read_value(data, |
531 | 542 | W83627EHF_REG_PWM[i]); |
532 | - data->fan_min_output[i] = w83627ehf_read_value(data, | |
533 | - W83627EHF_REG_FAN_MIN_OUTPUT[i]); | |
543 | + data->fan_start_output[i] = w83627ehf_read_value(data, | |
544 | + W83627EHF_REG_FAN_START_OUTPUT[i]); | |
545 | + data->fan_stop_output[i] = w83627ehf_read_value(data, | |
546 | + W83627EHF_REG_FAN_STOP_OUTPUT[i]); | |
534 | 547 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
535 | 548 | W83627EHF_REG_FAN_STOP_TIME[i]); |
536 | 549 | data->target_temp[i] = |
... | ... | @@ -976,7 +989,7 @@ |
976 | 989 | u32 val = simple_strtoul(buf, NULL, 10); |
977 | 990 | u16 reg; |
978 | 991 | |
979 | - if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | |
992 | + if (!val || (val > 4)) | |
980 | 993 | return -EINVAL; |
981 | 994 | mutex_lock(&data->update_lock); |
982 | 995 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
... | ... | @@ -1118,7 +1131,10 @@ |
1118 | 1131 | return count; \ |
1119 | 1132 | } |
1120 | 1133 | |
1121 | -fan_functions(fan_min_output, FAN_MIN_OUTPUT) | |
1134 | +fan_functions(fan_start_output, FAN_START_OUTPUT) | |
1135 | +fan_functions(fan_stop_output, FAN_STOP_OUTPUT) | |
1136 | +fan_functions(fan_max_output, FAN_MAX_OUTPUT) | |
1137 | +fan_functions(fan_step_output, FAN_STEP_OUTPUT) | |
1122 | 1138 | |
1123 | 1139 | #define fan_time_functions(reg, REG) \ |
1124 | 1140 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ |
... | ... | @@ -1161,8 +1177,14 @@ |
1161 | 1177 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
1162 | 1178 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
1163 | 1179 | store_fan_stop_time, 3), |
1164 | - SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | |
1165 | - store_fan_min_output, 3), | |
1180 | + SENSOR_ATTR(pwm4_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | |
1181 | + store_fan_start_output, 3), | |
1182 | + SENSOR_ATTR(pwm4_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | |
1183 | + store_fan_stop_output, 3), | |
1184 | + SENSOR_ATTR(pwm4_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, | |
1185 | + store_fan_max_output, 3), | |
1186 | + SENSOR_ATTR(pwm4_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, | |
1187 | + store_fan_step_output, 3), | |
1166 | 1188 | }; |
1167 | 1189 | |
1168 | 1190 | static struct sensor_device_attribute sda_sf3_arrays[] = { |
... | ... | @@ -1172,12 +1194,24 @@ |
1172 | 1194 | store_fan_stop_time, 1), |
1173 | 1195 | SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
1174 | 1196 | store_fan_stop_time, 2), |
1175 | - SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | |
1176 | - store_fan_min_output, 0), | |
1177 | - SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | |
1178 | - store_fan_min_output, 1), | |
1179 | - SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | |
1180 | - store_fan_min_output, 2), | |
1197 | + SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | |
1198 | + store_fan_start_output, 0), | |
1199 | + SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | |
1200 | + store_fan_start_output, 1), | |
1201 | + SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | |
1202 | + store_fan_start_output, 2), | |
1203 | + SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | |
1204 | + store_fan_stop_output, 0), | |
1205 | + SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | |
1206 | + store_fan_stop_output, 1), | |
1207 | + SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | |
1208 | + store_fan_stop_output, 2), | |
1209 | + | |
1210 | + /* pwm1 and pwm3 don't support max and step settings */ | |
1211 | + SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, | |
1212 | + store_fan_max_output, 1), | |
1213 | + SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, | |
1214 | + store_fan_step_output, 1), | |
1181 | 1215 | }; |
1182 | 1216 | |
1183 | 1217 | static ssize_t |