aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2014-04-20 11:07:42 -0400
committerGuenter Roeck <linux@roeck-us.net>2014-05-21 19:02:20 -0400
commit50bf46509f24c914562b4d818a155d8dc8f45e10 (patch)
tree5e1e777ca2f6b49361a3dbd3b080bb1ef9131606
parent9f9edcd4c32bf33255f8db7329c78a99baa94585 (diff)
hwmon: (lm77) Do not preserve hysteresis when updating critical temp limit
Updating the hysteresis value when updating the critical temperature limit was following the rule of 'least surprise'. However, it had the undesirable side effect of changing the hysteresis for all other attributes, which defeats the purpose of least surprise. In addition, it could result in invalid hysteresis values if the resulting hysteresis was too large. In such cases the resulting hysteresis ended up changed anyway, which again defeats the purpose. So drop that code and document the new behavior. Reviewed-by: Jean Delvare <jdelvare@suse.de> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/lm7720
-rw-r--r--drivers/hwmon/lm77.c6
2 files changed, 18 insertions, 8 deletions
diff --git a/Documentation/hwmon/lm77 b/Documentation/hwmon/lm77
index 57c3a46d6370..bfc915fe3639 100644
--- a/Documentation/hwmon/lm77
+++ b/Documentation/hwmon/lm77
@@ -18,5 +18,21 @@ sensor incorporates a band-gap type temperature sensor,
1810-bit ADC, and a digital comparator with user-programmable upper 1810-bit ADC, and a digital comparator with user-programmable upper
19and lower limit values. 19and lower limit values.
20 20
21Limits can be set through the Overtemperature Shutdown register and 21The LM77 implements 3 limits: low (temp1_min), high (temp1_max) and
22Hysteresis register. 22critical (temp1_crit.) It also implements an hysteresis mechanism which
23applies to all 3 limits. The relative difference is stored in a single
24register on the chip, which means that the relative difference between
25the limit and its hysteresis is always the same for all 3 limits.
26
27This implementation detail implies the following:
28* When setting a limit, its hysteresis will automatically follow, the
29 difference staying unchanged. For example, if the old critical limit
30 was 80 degrees C, and the hysteresis was 75 degrees C, and you change
31 the critical limit to 90 degrees C, then the hysteresis will
32 automatically change to 85 degrees C.
33* All 3 hysteresis can't be set independently. We decided to make
34 temp1_crit_hyst writable, while temp1_min_hyst and temp1_max_hyst are
35 read-only. Setting temp1_crit_hyst writes the difference between
36 temp1_crit_hyst and temp1_crit into the chip, and the same relative
37 hysteresis applies automatically to the low and high limits.
38* The limits should be set before the hysteresis.
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 4cd8a513c47b..85e5b3355be4 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -216,13 +216,11 @@ static ssize_t set_temp_crit_hyst(struct device *dev,
216 return count; 216 return count;
217} 217}
218 218
219/* preserve hysteresis when setting T_crit */
220static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, 219static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
221 const char *buf, size_t count) 220 const char *buf, size_t count)
222{ 221{
223 struct i2c_client *client = to_i2c_client(dev); 222 struct i2c_client *client = to_i2c_client(dev);
224 struct lm77_data *data = i2c_get_clientdata(client); 223 struct lm77_data *data = i2c_get_clientdata(client);
225 int oldcrithyst;
226 unsigned long val; 224 unsigned long val;
227 int err; 225 int err;
228 226
@@ -231,13 +229,9 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
231 return err; 229 return err;
232 230
233 mutex_lock(&data->update_lock); 231 mutex_lock(&data->update_lock);
234 oldcrithyst = data->temp_crit - data->temp_hyst;
235 data->temp_crit = val; 232 data->temp_crit = val;
236 data->temp_hyst = data->temp_crit - oldcrithyst;
237 lm77_write_value(client, LM77_REG_TEMP_CRIT, 233 lm77_write_value(client, LM77_REG_TEMP_CRIT,
238 LM77_TEMP_TO_REG(data->temp_crit)); 234 LM77_TEMP_TO_REG(data->temp_crit));
239 lm77_write_value(client, LM77_REG_TEMP_HYST,
240 LM77_TEMP_TO_REG(data->temp_hyst));
241 mutex_unlock(&data->update_lock); 235 mutex_unlock(&data->update_lock);
242 return count; 236 return count;
243} 237}