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: [email protected] # 4.9+
Signed-off-by: Guenter Roeck <[email protected]>
---
 drivers/hwmon/it87.c | 37 ++++++++++++++++++++++++-------------
 1 file 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,
                        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);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to