Commit 4c7b8ca1 authored by Guenter Roeck's avatar Guenter Roeck

hwmon: (it87) Do not overwrite bit 2..6 of pwm control registers

In IT8620E, after setting pwm control to manual, it was observed that
pwm values for fan 4..6 have reversed results (writing 0 results in fans
running at full speed, writing 255 results in fans turned off).

With the new PWM control, pwm polarity for pwm control 4..6 is specified
in its pwm control registers. Those registers are overwritten when setting
the pwm mode or the temperature mapping. Do not touch bit 2..6 of pwm
control registers on register writes to fix the problem.

Cc: stable@vger.kernel.org # 4.9+
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent d66777ca
......@@ -1316,25 +1316,35 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
data->fan_main_ctrl);
} else {
u8 ctrl;
/* No on/off mode, set maximum pwm value */
data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
it87_write_value(data, IT87_REG_PWM_DUTY[nr],
data->pwm_duty[nr]);
/* and set manual mode */
data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
data->pwm_temp_map[nr] :
data->pwm_duty[nr];
it87_write_value(data, IT87_REG_PWM[nr],
data->pwm_ctrl[nr]);
if (has_newer_autopwm(data)) {
ctrl = (data->pwm_ctrl[nr] & 0x7c) |
data->pwm_temp_map[nr];
} else {
ctrl = data->pwm_duty[nr];
}
data->pwm_ctrl[nr] = ctrl;
it87_write_value(data, IT87_REG_PWM[nr], ctrl);
}
} else {
if (val == 1) /* Manual mode */
data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
data->pwm_temp_map[nr] :
data->pwm_duty[nr];
else /* Automatic mode */
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
u8 ctrl;
if (has_newer_autopwm(data)) {
ctrl = (data->pwm_ctrl[nr] & 0x7c) |
data->pwm_temp_map[nr];
if (val != 1)
ctrl |= 0x80;
} else {
ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
}
data->pwm_ctrl[nr] = ctrl;
it87_write_value(data, IT87_REG_PWM[nr], ctrl);
if (data->type != it8603 && nr < 3) {
/* set SmartGuardian mode */
......@@ -1480,7 +1490,8 @@ static ssize_t set_pwm_temp_map(struct device *dev,
* otherwise, just store it for later use.
*/
if (data->pwm_ctrl[nr] & 0x80) {
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
data->pwm_temp_map[nr];
it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
}
mutex_unlock(&data->update_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment