hwmon: (max31790) Fix pwmX_enable attributes
[linux-2.6-microblaze.git] / drivers / hwmon / max31790.c
index 693497e..67677c4 100644 (file)
@@ -27,6 +27,7 @@
 
 /* Fan Config register bits */
 #define MAX31790_FAN_CFG_RPM_MODE      0x80
+#define MAX31790_FAN_CFG_CTRL_MON      0x10
 #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08
 #define MAX31790_FAN_CFG_TACH_INPUT    0x01
 
@@ -271,12 +272,12 @@ static int max31790_read_pwm(struct device *dev, u32 attr, int channel,
                *val = data->pwm[channel] >> 8;
                return 0;
        case hwmon_pwm_enable:
-               if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
+               if (fan_config & MAX31790_FAN_CFG_CTRL_MON)
+                       *val = 0;
+               else if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
                        *val = 2;
-               else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN)
-                       *val = 1;
                else
-                       *val = 0;
+                       *val = 1;
                return 0;
        default:
                return -EOPNOTSUPP;
@@ -307,23 +308,33 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
        case hwmon_pwm_enable:
                fan_config = data->fan_config[channel];
                if (val == 0) {
-                       fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN |
-                                       MAX31790_FAN_CFG_RPM_MODE);
+                       fan_config |= MAX31790_FAN_CFG_CTRL_MON;
+                       /*
+                        * Disable RPM mode; otherwise disabling fan speed
+                        * monitoring is not possible.
+                        */
+                       fan_config &= ~MAX31790_FAN_CFG_RPM_MODE;
                } else if (val == 1) {
-                       fan_config = (fan_config |
-                                     MAX31790_FAN_CFG_TACH_INPUT_EN) &
-                                    ~MAX31790_FAN_CFG_RPM_MODE;
+                       fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE);
                } else if (val == 2) {
-                       fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN |
-                                     MAX31790_FAN_CFG_RPM_MODE;
+                       fan_config &= ~MAX31790_FAN_CFG_CTRL_MON;
+                       /*
+                        * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its
+                        * own if MAX31790_FAN_CFG_RPM_MODE is set.
+                        * Do it here as well to reflect the actual register
+                        * value in the cache.
+                        */
+                       fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN);
                } else {
                        err = -EINVAL;
                        break;
                }
-               data->fan_config[channel] = fan_config;
-               err = i2c_smbus_write_byte_data(client,
-                                       MAX31790_REG_FAN_CONFIG(channel),
-                                       fan_config);
+               if (fan_config != data->fan_config[channel]) {
+                       err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),
+                                                       fan_config);
+                       if (!err)
+                               data->fan_config[channel] = fan_config;
+               }
                break;
        default:
                err = -EOPNOTSUPP;