diff options
author | Michael Abbott <michael@araneidae.co.uk> | 2009-09-21 20:04:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:49 -0400 |
commit | f266889517252bc697e7103bcd6ed46bdf2c1579 (patch) | |
tree | 008a9f272f14e1f3b8e6009dc2509d274cf3155a /drivers/hwmon/adm1021.c | |
parent | dc791f8aeeeea4314beede83d6ee74e6af5f627b (diff) |
drivers/hwmon/adm1021.c: support high precision ADM1023 remote sensor
The ADM1023 temperature sensor supports higher resolution for its external
sensor (sensitivity of 1/8 deg C). This patch makes this higher
resolution available through the appropriate temperature sysfs nodes.
Curiously, this functionality was available in the 2.4 kernel driver (but
formatted in a less helpful manner).
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Michael Abbott <michael.abbott@diamond.ac.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/adm1021.c')
-rw-r--r-- | drivers/hwmon/adm1021.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index b11e06f644b1..de84398775b6 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -85,14 +85,11 @@ struct adm1021_data { | |||
85 | char valid; /* !=0 if following fields are valid */ | 85 | char valid; /* !=0 if following fields are valid */ |
86 | unsigned long last_updated; /* In jiffies */ | 86 | unsigned long last_updated; /* In jiffies */ |
87 | 87 | ||
88 | s8 temp_max[2]; /* Register values */ | 88 | int temp_max[2]; /* Register values */ |
89 | s8 temp_min[2]; | 89 | int temp_min[2]; |
90 | s8 temp[2]; | 90 | int temp[2]; |
91 | u8 alarms; | 91 | u8 alarms; |
92 | /* Special values for ADM1023 only */ | 92 | /* Special values for ADM1023 only */ |
93 | u8 remote_temp_prec; | ||
94 | u8 remote_temp_os_prec; | ||
95 | u8 remote_temp_hyst_prec; | ||
96 | u8 remote_temp_offset; | 93 | u8 remote_temp_offset; |
97 | u8 remote_temp_offset_prec; | 94 | u8 remote_temp_offset_prec; |
98 | }; | 95 | }; |
@@ -141,7 +138,7 @@ static ssize_t show_temp(struct device *dev, | |||
141 | int index = to_sensor_dev_attr(devattr)->index; | 138 | int index = to_sensor_dev_attr(devattr)->index; |
142 | struct adm1021_data *data = adm1021_update_device(dev); | 139 | struct adm1021_data *data = adm1021_update_device(dev); |
143 | 140 | ||
144 | return sprintf(buf, "%d\n", 1000 * data->temp[index]); | 141 | return sprintf(buf, "%d\n", data->temp[index]); |
145 | } | 142 | } |
146 | 143 | ||
147 | static ssize_t show_temp_max(struct device *dev, | 144 | static ssize_t show_temp_max(struct device *dev, |
@@ -150,7 +147,7 @@ static ssize_t show_temp_max(struct device *dev, | |||
150 | int index = to_sensor_dev_attr(devattr)->index; | 147 | int index = to_sensor_dev_attr(devattr)->index; |
151 | struct adm1021_data *data = adm1021_update_device(dev); | 148 | struct adm1021_data *data = adm1021_update_device(dev); |
152 | 149 | ||
153 | return sprintf(buf, "%d\n", 1000 * data->temp_max[index]); | 150 | return sprintf(buf, "%d\n", data->temp_max[index]); |
154 | } | 151 | } |
155 | 152 | ||
156 | static ssize_t show_temp_min(struct device *dev, | 153 | static ssize_t show_temp_min(struct device *dev, |
@@ -159,7 +156,7 @@ static ssize_t show_temp_min(struct device *dev, | |||
159 | int index = to_sensor_dev_attr(devattr)->index; | 156 | int index = to_sensor_dev_attr(devattr)->index; |
160 | struct adm1021_data *data = adm1021_update_device(dev); | 157 | struct adm1021_data *data = adm1021_update_device(dev); |
161 | 158 | ||
162 | return sprintf(buf, "%d\n", 1000 * data->temp_min[index]); | 159 | return sprintf(buf, "%d\n", data->temp_min[index]); |
163 | } | 160 | } |
164 | 161 | ||
165 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 162 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
@@ -412,25 +409,27 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) | |||
412 | dev_dbg(&client->dev, "Starting adm1021 update\n"); | 409 | dev_dbg(&client->dev, "Starting adm1021 update\n"); |
413 | 410 | ||
414 | for (i = 0; i < 2; i++) { | 411 | for (i = 0; i < 2; i++) { |
415 | data->temp[i] = i2c_smbus_read_byte_data(client, | 412 | data->temp[i] = 1000 * |
416 | ADM1021_REG_TEMP(i)); | 413 | (s8) i2c_smbus_read_byte_data( |
417 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | 414 | client, ADM1021_REG_TEMP(i)); |
418 | ADM1021_REG_TOS_R(i)); | 415 | data->temp_max[i] = 1000 * |
419 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | 416 | (s8) i2c_smbus_read_byte_data( |
420 | ADM1021_REG_THYST_R(i)); | 417 | client, ADM1021_REG_TOS_R(i)); |
418 | data->temp_min[i] = 1000 * | ||
419 | (s8) i2c_smbus_read_byte_data( | ||
420 | client, ADM1021_REG_THYST_R(i)); | ||
421 | } | 421 | } |
422 | data->alarms = i2c_smbus_read_byte_data(client, | 422 | data->alarms = i2c_smbus_read_byte_data(client, |
423 | ADM1021_REG_STATUS) & 0x7c; | 423 | ADM1021_REG_STATUS) & 0x7c; |
424 | if (data->type == adm1023) { | 424 | if (data->type == adm1023) { |
425 | data->remote_temp_prec = | 425 | /* The ADM1023 provides 3 extra bits of precision for |
426 | i2c_smbus_read_byte_data(client, | 426 | * the remote sensor in extra registers. */ |
427 | ADM1023_REG_REM_TEMP_PREC); | 427 | data->temp[1] += 125 * (i2c_smbus_read_byte_data( |
428 | data->remote_temp_os_prec = | 428 | client, ADM1023_REG_REM_TEMP_PREC) >> 5); |
429 | i2c_smbus_read_byte_data(client, | 429 | data->temp_max[1] += 125 * (i2c_smbus_read_byte_data( |
430 | ADM1023_REG_REM_TOS_PREC); | 430 | client, ADM1023_REG_REM_TOS_PREC) >> 5); |
431 | data->remote_temp_hyst_prec = | 431 | data->temp_min[1] += 125 * (i2c_smbus_read_byte_data( |
432 | i2c_smbus_read_byte_data(client, | 432 | client, ADM1023_REG_REM_THYST_PREC) >> 5); |
433 | ADM1023_REG_REM_THYST_PREC); | ||
434 | data->remote_temp_offset = | 433 | data->remote_temp_offset = |
435 | i2c_smbus_read_byte_data(client, | 434 | i2c_smbus_read_byte_data(client, |
436 | ADM1023_REG_REM_OFFSET); | 435 | ADM1023_REG_REM_OFFSET); |