Commit 41e9a062361de204d3710038925ae7f356ebb40d

Authored by Daniel J Blueman
Committed by Linus Torvalds
1 parent e40d6eaa79

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