diff options
-rw-r--r-- | drivers/hwmon/lm75.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 4670fbef6a9c..559e675db3c8 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -71,9 +71,12 @@ struct lm75_data { struct device *hwmon_dev; struct mutex update_lock; u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; char valid; /* !=0 if registers are valid */ unsigned long last_updated; /* In jiffies */ - u16 temp[3]; /* Register values, + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, 0 = input 1 = max 2 = hyst */ @@ -93,12 +96,15 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm75_data *data = lm75_update_device(dev); + long temp; if (IS_ERR(data)) return PTR_ERR(data); - return sprintf(buf, "%d\n", - LM75_TEMP_FROM_REG(data->temp[attr->index])); + temp = ((data->temp[attr->index] >> (16 - data->resolution)) * 1000) + >> (data->resolution - 8); + + return sprintf(buf, "%ld\n", temp); } static ssize_t set_temp(struct device *dev, struct device_attribute *da, @@ -110,13 +116,25 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, int nr = attr->index; long temp; int error; + u8 resolution; error = kstrtol(buf, 10, &temp); if (error) return error; + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (attr->index && data->resolution_limits) + resolution = data->resolution_limits; + else + resolution = data->resolution; + mutex_lock(&data->update_lock); - data->temp[nr] = LM75_TEMP_TO_REG(temp); + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); mutex_unlock(&data->update_lock); return count; @@ -190,6 +208,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) break; } + data->resolution = 9; + data->sample_time = HZ + HZ / 2; + /* configure as specified */ status = lm75_read_value(client, LM75_REG_CONF); if (status < 0) { @@ -427,7 +448,7 @@ static struct lm75_data *lm75_update_device(struct device *dev) mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + if (time_after(jiffies, data->last_updated + data->sample_time) || !data->valid) { int i; dev_dbg(&client->dev, "Starting lm75 update\n"); |