hwmon: (lm95245) Fix hysteresis temperatures
authorGuenter Roeck <linux@roeck-us.net>
Mon, 3 Feb 2014 02:29:28 +0000 (18:29 -0800)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 3 Mar 2014 16:01:06 +0000 (08:01 -0800)
Hysteresis temperatures are defined as absolute temperatures,
not as delta value from the critical temperatures.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Jean Delvare <jdelvare@suse.de>
drivers/hwmon/lm95245.c

index 3f0956e18a23f18ba5350cd7c5cfbf90c6b46591..a400d4c4416bc6ca2d87328733a5a2f59daab4a0 100644 (file)
@@ -272,27 +272,38 @@ static ssize_t set_limit(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
+static ssize_t show_crit_hyst(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct lm95245_data *data = lm95245_update_device(dev);
+       int index = to_sensor_dev_attr(attr)->index;
+       int hyst = data->regs[index] - data->regs[8];
+
+       return snprintf(buf, PAGE_SIZE - 1, "%d\n", hyst * 1000);
+}
+
 static ssize_t set_crit_hyst(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct lm95245_data *data = i2c_get_clientdata(client);
+       int index = to_sensor_dev_attr(attr)->index;
        unsigned long val;
+       int hyst, limit;
 
        if (kstrtoul(buf, 10, &val) < 0)
                return -EINVAL;
 
-       val /= 1000;
-
-       val = clamp_val(val, 0, 31);
-
        mutex_lock(&data->update_lock);
 
-       data->valid = 0;
+       limit = i2c_smbus_read_byte_data(client, lm95245_reg_address[index]);
+       hyst = limit - val / 1000;
+       hyst = clamp_val(hyst, 0, 31);
+       data->regs[8] = hyst;
 
        /* shared crit hysteresis */
        i2c_smbus_write_byte_data(client, LM95245_REG_RW_COMMON_HYSTERESIS,
-               val);
+               hyst);
 
        mutex_unlock(&data->update_lock);
 
@@ -378,16 +389,16 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_limit,
                set_limit, 6);
-static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_limit,
-               set_crit_hyst, 8);
+static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_crit_hyst,
+               set_crit_hyst, 6);
 static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL,
                STATUS1_LOC);
 
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2);
 static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_limit,
                set_limit, 7);
-static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_limit,
-               set_crit_hyst, 8);
+static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_crit_hyst,
+               set_crit_hyst, 7);
 static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL,
                STATUS1_RTCRIT);
 static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type,