aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2017-02-08 17:07:42 -0500
committerGuenter Roeck <linux@roeck-us.net>2017-02-11 00:35:08 -0500
commit4c7b8ca1ae5ed9e27014732c8a918ba11a86cf09 (patch)
treefa4299c85a4b35bc5700902c071a389d9ab2da32
parentd66777caa57ffade6061782f3a4d4056f0b0c1ac (diff)
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: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/it87.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 4f3fabcd470d..37acb38b5e17 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1316,25 +1316,35 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
1316 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, 1316 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
1317 data->fan_main_ctrl); 1317 data->fan_main_ctrl);
1318 } else { 1318 } else {
1319 u8 ctrl;
1320
1319 /* No on/off mode, set maximum pwm value */ 1321 /* No on/off mode, set maximum pwm value */
1320 data->pwm_duty[nr] = pwm_to_reg(data, 0xff); 1322 data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
1321 it87_write_value(data, IT87_REG_PWM_DUTY[nr], 1323 it87_write_value(data, IT87_REG_PWM_DUTY[nr],
1322 data->pwm_duty[nr]); 1324 data->pwm_duty[nr]);
1323 /* and set manual mode */ 1325 /* and set manual mode */
1324 data->pwm_ctrl[nr] = has_newer_autopwm(data) ? 1326 if (has_newer_autopwm(data)) {
1325 data->pwm_temp_map[nr] : 1327 ctrl = (data->pwm_ctrl[nr] & 0x7c) |
1326 data->pwm_duty[nr]; 1328 data->pwm_temp_map[nr];
1327 it87_write_value(data, IT87_REG_PWM[nr], 1329 } else {
1328 data->pwm_ctrl[nr]); 1330 ctrl = data->pwm_duty[nr];
1331 }
1332 data->pwm_ctrl[nr] = ctrl;
1333 it87_write_value(data, IT87_REG_PWM[nr], ctrl);
1329 } 1334 }
1330 } else { 1335 } else {
1331 if (val == 1) /* Manual mode */ 1336 u8 ctrl;
1332 data->pwm_ctrl[nr] = has_newer_autopwm(data) ? 1337
1333 data->pwm_temp_map[nr] : 1338 if (has_newer_autopwm(data)) {
1334 data->pwm_duty[nr]; 1339 ctrl = (data->pwm_ctrl[nr] & 0x7c) |
1335 else /* Automatic mode */ 1340 data->pwm_temp_map[nr];
1336 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; 1341 if (val != 1)
1337 it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]); 1342 ctrl |= 0x80;
1343 } else {
1344 ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
1345 }
1346 data->pwm_ctrl[nr] = ctrl;
1347 it87_write_value(data, IT87_REG_PWM[nr], ctrl);
1338 1348
1339 if (data->type != it8603 && nr < 3) { 1349 if (data->type != it8603 && nr < 3) {
1340 /* set SmartGuardian mode */ 1350 /* set SmartGuardian mode */
@@ -1480,7 +1490,8 @@ static ssize_t set_pwm_temp_map(struct device *dev,
1480 * otherwise, just store it for later use. 1490 * otherwise, just store it for later use.
1481 */ 1491 */
1482 if (data->pwm_ctrl[nr] & 0x80) { 1492 if (data->pwm_ctrl[nr] & 0x80) {
1483 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; 1493 data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
1494 data->pwm_temp_map[nr];
1484 it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]); 1495 it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
1485 } 1496 }
1486 mutex_unlock(&data->update_lock); 1497 mutex_unlock(&data->update_lock);