diff options
| -rw-r--r-- | Documentation/hwmon/w83627ehf | 10 | ||||
| -rw-r--r-- | drivers/hwmon/w83627ehf.c | 72 |
2 files changed, 61 insertions, 21 deletions
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 02b74899edaf..b7e42ec4b26b 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf | |||
| @@ -81,8 +81,14 @@ pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: | |||
| 81 | 0 (stop) to 255 (full) | 81 | 0 (stop) to 255 (full) |
| 82 | 82 | ||
| 83 | pwm[1-4]_enable - this file controls mode of fan/temperature control: | 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) | 84 | * 1 Manual mode, write to pwm file any value 0-255 (full speed) |
| 85 | * 2 Thermal Cruise | 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 | Thermal Cruise mode | 93 | Thermal Cruise mode |
| 88 | ------------------- | 94 | ------------------- |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index bb5e78748783..0dcaba9b7189 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | Copyright (C) 2006 Yuan Mu (Winbond), | 5 | Copyright (C) 2006 Yuan Mu (Winbond), |
| 6 | Rudolf Marek <r.marek@assembler.cz> | 6 | Rudolf Marek <r.marek@assembler.cz> |
| 7 | David Hubbard <david.c.hubbard@gmail.com> | 7 | David Hubbard <david.c.hubbard@gmail.com> |
| 8 | Daniel J Blueman <daniel.blueman@gmail.com> | ||
| 8 | 9 | ||
| 9 | Shamelessly ripped from the w83627hf driver | 10 | Shamelessly ripped from the w83627hf driver |
| 10 | Copyright (C) 2003 Mark Studebaker | 11 | Copyright (C) 2003 Mark Studebaker |
| @@ -177,12 +178,15 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 }; | |||
| 177 | #define W83627EHF_REG_ALARM3 0x45B | 178 | #define W83627EHF_REG_ALARM3 0x45B |
| 178 | 179 | ||
| 179 | /* SmartFan registers */ | 180 | /* SmartFan registers */ |
| 181 | #define W83627EHF_REG_FAN_STEPUP_TIME 0x0f | ||
| 182 | #define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e | ||
| 183 | |||
| 180 | /* DC or PWM output fan configuration */ | 184 | /* DC or PWM output fan configuration */ |
| 181 | static const u8 W83627EHF_REG_PWM_ENABLE[] = { | 185 | static const u8 W83627EHF_REG_PWM_ENABLE[] = { |
| 182 | 0x04, /* SYS FAN0 output mode and PWM mode */ | 186 | 0x04, /* SYS FAN0 output mode and PWM mode */ |
| 183 | 0x04, /* CPU FAN0 output mode and PWM mode */ | 187 | 0x04, /* CPU FAN0 output mode and PWM mode */ |
| 184 | 0x12, /* AUX FAN mode */ | 188 | 0x12, /* AUX FAN mode */ |
| 185 | 0x62, /* CPU fan1 mode */ | 189 | 0x62, /* CPU FAN1 mode */ |
| 186 | }; | 190 | }; |
| 187 | 191 | ||
| 188 | static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 }; | 192 | static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 }; |
| @@ -193,10 +197,12 @@ static const u8 W83627EHF_REG_PWM[] = { 0x01, 0x03, 0x11, 0x61 }; | |||
| 193 | static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 }; | 197 | static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 }; |
| 194 | static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 }; | 198 | static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 }; |
| 195 | 199 | ||
| 196 | |||
| 197 | /* Advanced Fan control, some values are common for all fans */ | 200 | /* Advanced Fan control, some values are common for all fans */ |
| 198 | static const u8 W83627EHF_REG_FAN_MIN_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 }; | 201 | static const u8 W83627EHF_REG_FAN_START_OUTPUT[] = { 0x0a, 0x0b, 0x16, 0x65 }; |
| 199 | static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0C, 0x0D, 0x17, 0x66 }; | 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 | * Conversions | 208 | * Conversions |
| @@ -295,14 +301,19 @@ struct w83627ehf_data { | |||
| 295 | 301 | ||
| 296 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ | 302 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
| 297 | u8 pwm_enable[4]; /* 1->manual | 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 | u8 pwm_num; /* number of pwm */ | 307 | u8 pwm_num; /* number of pwm */ |
| 300 | u8 pwm[4]; | 308 | u8 pwm[4]; |
| 301 | u8 target_temp[4]; | 309 | u8 target_temp[4]; |
| 302 | u8 tolerance[4]; | 310 | u8 tolerance[4]; |
| 303 | 311 | ||
| 304 | u8 fan_min_output[4]; /* minimum fan speed */ | 312 | u8 fan_start_output[4]; /* minimum fan speed when spinning up */ |
| 305 | u8 fan_stop_time[4]; | 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 | u8 vid; | 318 | u8 vid; |
| 308 | u8 vrm; | 319 | u8 vrm; |
| @@ -529,8 +540,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 529 | & 3) + 1; | 540 | & 3) + 1; |
| 530 | data->pwm[i] = w83627ehf_read_value(data, | 541 | data->pwm[i] = w83627ehf_read_value(data, |
| 531 | W83627EHF_REG_PWM[i]); | 542 | W83627EHF_REG_PWM[i]); |
| 532 | data->fan_min_output[i] = w83627ehf_read_value(data, | 543 | data->fan_start_output[i] = w83627ehf_read_value(data, |
| 533 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); | 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 | data->fan_stop_time[i] = w83627ehf_read_value(data, | 547 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
| 535 | W83627EHF_REG_FAN_STOP_TIME[i]); | 548 | W83627EHF_REG_FAN_STOP_TIME[i]); |
| 536 | data->target_temp[i] = | 549 | data->target_temp[i] = |
| @@ -976,7 +989,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
| 976 | u32 val = simple_strtoul(buf, NULL, 10); | 989 | u32 val = simple_strtoul(buf, NULL, 10); |
| 977 | u16 reg; | 990 | u16 reg; |
| 978 | 991 | ||
| 979 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | 992 | if (!val || (val > 4)) |
| 980 | return -EINVAL; | 993 | return -EINVAL; |
| 981 | mutex_lock(&data->update_lock); | 994 | mutex_lock(&data->update_lock); |
| 982 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); | 995 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
| @@ -1118,7 +1131,10 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
| 1118 | return count; \ | 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 | #define fan_time_functions(reg, REG) \ | 1139 | #define fan_time_functions(reg, REG) \ |
| 1124 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ | 1140 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ |
| @@ -1161,8 +1177,14 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | |||
| 1161 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | 1177 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
| 1162 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1178 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
| 1163 | store_fan_stop_time, 3), | 1179 | store_fan_stop_time, 3), |
| 1164 | SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | 1180 | SENSOR_ATTR(pwm4_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
| 1165 | store_fan_min_output, 3), | 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 | static struct sensor_device_attribute sda_sf3_arrays[] = { | 1190 | static struct sensor_device_attribute sda_sf3_arrays[] = { |
| @@ -1172,12 +1194,24 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
| 1172 | store_fan_stop_time, 1), | 1194 | store_fan_stop_time, 1), |
| 1173 | SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1195 | SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
| 1174 | store_fan_stop_time, 2), | 1196 | store_fan_stop_time, 2), |
| 1175 | SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | 1197 | SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
| 1176 | store_fan_min_output, 0), | 1198 | store_fan_start_output, 0), |
| 1177 | SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | 1199 | SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
| 1178 | store_fan_min_output, 1), | 1200 | store_fan_start_output, 1), |
| 1179 | SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, | 1201 | SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
| 1180 | store_fan_min_output, 2), | 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 | static ssize_t | 1217 | static ssize_t |
