aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-10-17 11:51:09 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-10-17 11:51:09 -0400
commitf65e17086fc141bee1592bbf6e709e9c7a43541b (patch)
tree165e6da0dc246a02907108316fe12c5d6af4d2e6
parent6388a388ffb720f40fc8046c261252ea2be9c12f (diff)
hwmon: (lm90) Support the extra resolution bits of MAX6657
The Maxim MAX6657, MAX6658 and MAX6659 have extra resolution bits for the local temperature measurement. Let the lm90 driver read them and export them to user-space. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Martyn Welch <martyn.welch@gefanuc.com>
-rw-r--r--Documentation/hwmon/lm9010
-rw-r--r--drivers/hwmon/lm90.c54
2 files changed, 39 insertions, 25 deletions
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index aa4a0ec20081..0b3e8bb7c1f0 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -86,9 +86,8 @@ family is that it features critical limits with hysteresis, and an
86increased resolution of the remote temperature measurement. 86increased resolution of the remote temperature measurement.
87 87
88The different chipsets of the family are not strictly identical, although 88The different chipsets of the family are not strictly identical, although
89very similar. This driver doesn't handle any specific feature for now, 89very similar. For reference, here comes a non-exhaustive list of specific
90with the exception of SMBus PEC. For reference, here comes a non-exhaustive 90features:
91list of specific features:
92 91
93LM90: 92LM90:
94 * Filter and alert configuration register at 0xBF. 93 * Filter and alert configuration register at 0xBF.
@@ -114,9 +113,11 @@ ADT7461:
114 * Lower resolution for remote temperature 113 * Lower resolution for remote temperature
115 114
116MAX6657 and MAX6658: 115MAX6657 and MAX6658:
116 * Better local resolution
117 * Remote sensor type selection 117 * Remote sensor type selection
118 118
119MAX6659: 119MAX6659:
120 * Better local resolution
120 * Selectable address 121 * Selectable address
121 * Second critical temperature limit 122 * Second critical temperature limit
122 * Remote sensor type selection 123 * Remote sensor type selection
@@ -127,7 +128,8 @@ MAX6680 and MAX6681:
127 128
128All temperature values are given in degrees Celsius. Resolution 129All temperature values are given in degrees Celsius. Resolution
129is 1.0 degree for the local temperature, 0.125 degree for the remote 130is 1.0 degree for the local temperature, 0.125 degree for the remote
130temperature. 131temperature, except for the MAX6657, MAX6658 and MAX6659 which have a
132resolution of 0.125 degree for both temperatures.
131 133
132Each sensor has its own high and low limits, plus a critical limit. 134Each sensor has its own high and low limits, plus a critical limit.
133Additionally, there is a relative hysteresis value common to both critical 135Additionally, there is a relative hysteresis value common to both critical
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 73a1c622fb7a..16b99e0bdff0 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -149,6 +149,10 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
149#define LM90_REG_R_TCRIT_HYST 0x21 149#define LM90_REG_R_TCRIT_HYST 0x21
150#define LM90_REG_W_TCRIT_HYST 0x21 150#define LM90_REG_W_TCRIT_HYST 0x21
151 151
152/* MAX6657-specific registers */
153
154#define MAX6657_REG_R_LOCAL_TEMPL 0x11
155
152/* 156/*
153 * Conversions and various macros 157 * Conversions and various macros
154 * For local temperatures and limits, critical limits and the hysteresis 158 * For local temperatures and limits, critical limits and the hysteresis
@@ -239,15 +243,15 @@ struct lm90_data {
239 int kind; 243 int kind;
240 244
241 /* registers values */ 245 /* registers values */
242 s8 temp8[5]; /* 0: local input 246 s8 temp8[4]; /* 0: local low limit
243 1: local low limit 247 1: local high limit
244 2: local high limit 248 2: local critical limit
245 3: local critical limit 249 3: remote critical limit */
246 4: remote critical limit */ 250 s16 temp11[5]; /* 0: remote input
247 s16 temp11[4]; /* 0: remote input
248 1: remote low limit 251 1: remote low limit
249 2: remote high limit 252 2: remote high limit
250 3: remote offset (except max6657) */ 253 3: remote offset (except max6657)
254 4: local input */
251 u8 temp_hyst; 255 u8 temp_hyst;
252 u8 alarms; /* bitvector */ 256 u8 alarms; /* bitvector */
253}; 257};
@@ -285,7 +289,7 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
285 data->temp8[nr] = TEMP1_TO_REG_ADT7461(val); 289 data->temp8[nr] = TEMP1_TO_REG_ADT7461(val);
286 else 290 else
287 data->temp8[nr] = TEMP1_TO_REG(val); 291 data->temp8[nr] = TEMP1_TO_REG(val);
288 i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]); 292 i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]);
289 mutex_unlock(&data->update_lock); 293 mutex_unlock(&data->update_lock);
290 return count; 294 return count;
291} 295}
@@ -347,7 +351,7 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
347 long hyst; 351 long hyst;
348 352
349 mutex_lock(&data->update_lock); 353 mutex_lock(&data->update_lock);
350 hyst = TEMP1_FROM_REG(data->temp8[3]) - val; 354 hyst = TEMP1_FROM_REG(data->temp8[2]) - val;
351 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, 355 i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
352 HYST_TO_REG(hyst)); 356 HYST_TO_REG(hyst));
353 mutex_unlock(&data->update_lock); 357 mutex_unlock(&data->update_lock);
@@ -371,23 +375,23 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute
371 return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); 375 return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
372} 376}
373 377
374static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); 378static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 4);
375static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); 379static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
376static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, 380static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
377 set_temp8, 1); 381 set_temp8, 0);
378static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, 382static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
379 set_temp11, 1); 383 set_temp11, 1);
380static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, 384static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
381 set_temp8, 2); 385 set_temp8, 1);
382static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, 386static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
383 set_temp11, 2); 387 set_temp11, 2);
384static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, 388static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8,
385 set_temp8, 3); 389 set_temp8, 2);
386static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, 390static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
387 set_temp8, 4); 391 set_temp8, 3);
388static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, 392static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
389 set_temphyst, 3); 393 set_temphyst, 2);
390static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); 394static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 3);
391static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, 395static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11,
392 set_temp11, 3); 396 set_temp11, 3);
393 397
@@ -779,13 +783,21 @@ static struct lm90_data *lm90_update_device(struct device *dev)
779 u8 h, l; 783 u8 h, l;
780 784
781 dev_dbg(&client->dev, "Updating lm90 data.\n"); 785 dev_dbg(&client->dev, "Updating lm90 data.\n");
782 lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); 786 lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]);
783 lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]); 787 lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]);
784 lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]); 788 lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]);
785 lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]); 789 lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]);
786 lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]);
787 lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); 790 lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
788 791
792 if (data->kind == max6657) {
793 lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
794 MAX6657_REG_R_LOCAL_TEMPL,
795 &data->temp11[4]);
796 } else {
797 if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP,
798 &h) == 0)
799 data->temp11[4] = h << 8;
800 }
789 lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, 801 lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
790 LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); 802 LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]);
791 803