diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-10-17 11:51:11 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-17 11:51:11 -0400 |
commit | 271dabf5bbf6ae6e2792cd5cf6f0434230e5c18c (patch) | |
tree | 654915a99671b90924bf34e1ddaa4cb0bb600290 | |
parent | 9d4d3834229e9949c066c2d0f73ed5d4b4965761 (diff) |
hwmon: (lm90) Support MAX6646, MAX6647 and MAX6649
These Maxim chips are similar to MAX6657 but use unsigned temperature
values to allow for readings up to 145 degrees.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | Documentation/hwmon/lm90 | 15 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 3 | ||||
-rw-r--r-- | drivers/hwmon/lm90.c | 77 |
3 files changed, 82 insertions, 13 deletions
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 53cd829f3f4d..e0d5206d1de3 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 | |||
@@ -32,6 +32,21 @@ Supported chips: | |||
32 | Addresses scanned: I2C 0x4c and 0x4d | 32 | Addresses scanned: I2C 0x4c and 0x4d |
33 | Datasheet: Publicly available at the ON Semiconductor website | 33 | Datasheet: Publicly available at the ON Semiconductor website |
34 | http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461 | 34 | http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461 |
35 | * Maxim MAX6646 | ||
36 | Prefix: 'max6646' | ||
37 | Addresses scanned: I2C 0x4d | ||
38 | Datasheet: Publicly available at the Maxim website | ||
39 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 | ||
40 | * Maxim MAX6647 | ||
41 | Prefix: 'max6646' | ||
42 | Addresses scanned: I2C 0x4e | ||
43 | Datasheet: Publicly available at the Maxim website | ||
44 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 | ||
45 | * Maxim MAX6649 | ||
46 | Prefix: 'max6646' | ||
47 | Addresses scanned: I2C 0x4c | ||
48 | Datasheet: Publicly available at the Maxim website | ||
49 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 | ||
35 | * Maxim MAX6657 | 50 | * Maxim MAX6657 |
36 | Prefix: 'max6657' | 51 | Prefix: 'max6657' |
37 | Addresses scanned: I2C 0x4c | 52 | Addresses scanned: I2C 0x4c |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 96701e099e81..6de1e0ffd391 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -511,7 +511,8 @@ config SENSORS_LM90 | |||
511 | help | 511 | help |
512 | If you say yes here you get support for National Semiconductor LM90, | 512 | If you say yes here you get support for National Semiconductor LM90, |
513 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim | 513 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim |
514 | MAX6657, MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips. | 514 | MAX6646, MAX6647, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680 and |
515 | MAX6681 sensor chips. | ||
515 | 516 | ||
516 | This driver can also be built as a module. If so, the module | 517 | This driver can also be built as a module. If so, the module |
517 | will be called lm90. | 518 | will be called lm90. |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 85ba2c4feb46..fe09f82c42e8 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -32,6 +32,11 @@ | |||
32 | * supported by this driver. These chips lack the remote temperature | 32 | * supported by this driver. These chips lack the remote temperature |
33 | * offset feature. | 33 | * offset feature. |
34 | * | 34 | * |
35 | * This driver also supports the MAX6646, MAX6647 and MAX6649 chips | ||
36 | * made by Maxim. These are again similar to the LM86, but they use | ||
37 | * unsigned temperature values and can report temperatures from 0 to | ||
38 | * 145 degrees. | ||
39 | * | ||
35 | * This driver also supports the MAX6680 and MAX6681, two other sensor | 40 | * This driver also supports the MAX6680 and MAX6681, two other sensor |
36 | * chips made by Maxim. These are quite similar to the other Maxim | 41 | * chips made by Maxim. These are quite similar to the other Maxim |
37 | * chips. The MAX6680 and MAX6681 only differ in the pinout so they can | 42 | * chips. The MAX6680 and MAX6681 only differ in the pinout so they can |
@@ -76,9 +81,10 @@ | |||
76 | * Addresses to scan | 81 | * Addresses to scan |
77 | * Address is fully defined internally and cannot be changed except for | 82 | * Address is fully defined internally and cannot be changed except for |
78 | * MAX6659, MAX6680 and MAX6681. | 83 | * MAX6659, MAX6680 and MAX6681. |
79 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 | 84 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657 |
80 | * have address 0x4c. | 85 | * and MAX6658 have address 0x4c. |
81 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. | 86 | * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d. |
87 | * MAX6647 has address 0x4e. | ||
82 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). | 88 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). |
83 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | 89 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, |
84 | * 0x4c, 0x4d or 0x4e. | 90 | * 0x4c, 0x4d or 0x4e. |
@@ -91,7 +97,8 @@ static const unsigned short normal_i2c[] = { | |||
91 | * Insmod parameters | 97 | * Insmod parameters |
92 | */ | 98 | */ |
93 | 99 | ||
94 | I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | 100 | I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, |
101 | max6646); | ||
95 | 102 | ||
96 | /* | 103 | /* |
97 | * The LM90 registers | 104 | * The LM90 registers |
@@ -132,7 +139,7 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | |||
132 | #define LM90_REG_R_TCRIT_HYST 0x21 | 139 | #define LM90_REG_R_TCRIT_HYST 0x21 |
133 | #define LM90_REG_W_TCRIT_HYST 0x21 | 140 | #define LM90_REG_W_TCRIT_HYST 0x21 |
134 | 141 | ||
135 | /* MAX6657-specific registers */ | 142 | /* MAX6646/6647/6649/6657/6658/6659 registers */ |
136 | 143 | ||
137 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 | 144 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 |
138 | 145 | ||
@@ -164,6 +171,9 @@ static const struct i2c_device_id lm90_id[] = { | |||
164 | { "lm86", lm86 }, | 171 | { "lm86", lm86 }, |
165 | { "lm89", lm99 }, | 172 | { "lm89", lm99 }, |
166 | { "lm99", lm99 }, /* Missing temperature offset */ | 173 | { "lm99", lm99 }, /* Missing temperature offset */ |
174 | { "max6646", max6646 }, | ||
175 | { "max6647", max6646 }, | ||
176 | { "max6649", max6646 }, | ||
167 | { "max6657", max6657 }, | 177 | { "max6657", max6657 }, |
168 | { "max6658", max6657 }, | 178 | { "max6658", max6657 }, |
169 | { "max6659", max6657 }, | 179 | { "max6659", max6657 }, |
@@ -205,7 +215,7 @@ struct lm90_data { | |||
205 | s16 temp11[5]; /* 0: remote input | 215 | s16 temp11[5]; /* 0: remote input |
206 | 1: remote low limit | 216 | 1: remote low limit |
207 | 2: remote high limit | 217 | 2: remote high limit |
208 | 3: remote offset (except max6657) | 218 | 3: remote offset (except max6646 and max6657) |
209 | 4: local input */ | 219 | 4: local input */ |
210 | u8 temp_hyst; | 220 | u8 temp_hyst; |
211 | u8 alarms; /* bitvector */ | 221 | u8 alarms; /* bitvector */ |
@@ -216,7 +226,8 @@ struct lm90_data { | |||
216 | * For local temperatures and limits, critical limits and the hysteresis | 226 | * For local temperatures and limits, critical limits and the hysteresis |
217 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. | 227 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. |
218 | * For remote temperatures and limits, it uses signed 11-bit values with | 228 | * For remote temperatures and limits, it uses signed 11-bit values with |
219 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. | 229 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some |
230 | * Maxim chips use unsigned values. | ||
220 | */ | 231 | */ |
221 | 232 | ||
222 | static inline int temp_from_s8(s8 val) | 233 | static inline int temp_from_s8(s8 val) |
@@ -224,11 +235,21 @@ static inline int temp_from_s8(s8 val) | |||
224 | return val * 1000; | 235 | return val * 1000; |
225 | } | 236 | } |
226 | 237 | ||
238 | static inline int temp_from_u8(u8 val) | ||
239 | { | ||
240 | return val * 1000; | ||
241 | } | ||
242 | |||
227 | static inline int temp_from_s16(s16 val) | 243 | static inline int temp_from_s16(s16 val) |
228 | { | 244 | { |
229 | return val / 32 * 125; | 245 | return val / 32 * 125; |
230 | } | 246 | } |
231 | 247 | ||
248 | static inline int temp_from_u16(u16 val) | ||
249 | { | ||
250 | return val / 32 * 125; | ||
251 | } | ||
252 | |||
232 | static s8 temp_to_s8(long val) | 253 | static s8 temp_to_s8(long val) |
233 | { | 254 | { |
234 | if (val <= -128000) | 255 | if (val <= -128000) |
@@ -240,6 +261,15 @@ static s8 temp_to_s8(long val) | |||
240 | return (val + 500) / 1000; | 261 | return (val + 500) / 1000; |
241 | } | 262 | } |
242 | 263 | ||
264 | static u8 temp_to_u8(long val) | ||
265 | { | ||
266 | if (val <= 0) | ||
267 | return 0; | ||
268 | if (val >= 255000) | ||
269 | return 255; | ||
270 | return (val + 500) / 1000; | ||
271 | } | ||
272 | |||
243 | static s16 temp_to_s16(long val) | 273 | static s16 temp_to_s16(long val) |
244 | { | 274 | { |
245 | if (val <= -128000) | 275 | if (val <= -128000) |
@@ -331,6 +361,8 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | |||
331 | 361 | ||
332 | if (data->kind == adt7461) | 362 | if (data->kind == adt7461) |
333 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | 363 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); |
364 | else if (data->kind == max6646) | ||
365 | temp = temp_from_u8(data->temp8[attr->index]); | ||
334 | else | 366 | else |
335 | temp = temp_from_s8(data->temp8[attr->index]); | 367 | temp = temp_from_s8(data->temp8[attr->index]); |
336 | 368 | ||
@@ -356,6 +388,8 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
356 | mutex_lock(&data->update_lock); | 388 | mutex_lock(&data->update_lock); |
357 | if (data->kind == adt7461) | 389 | if (data->kind == adt7461) |
358 | data->temp8[nr] = temp_to_u8_adt7461(data, val); | 390 | data->temp8[nr] = temp_to_u8_adt7461(data, val); |
391 | else if (data->kind == max6646) | ||
392 | data->temp8[nr] = temp_to_u8(val); | ||
359 | else | 393 | else |
360 | data->temp8[nr] = temp_to_s8(val); | 394 | data->temp8[nr] = temp_to_s8(val); |
361 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); | 395 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); |
@@ -372,6 +406,8 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
372 | 406 | ||
373 | if (data->kind == adt7461) | 407 | if (data->kind == adt7461) |
374 | temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); | 408 | temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); |
409 | else if (data->kind == max6646) | ||
410 | temp = temp_from_u16(data->temp11[attr->index]); | ||
375 | else | 411 | else |
376 | temp = temp_from_s16(data->temp11[attr->index]); | 412 | temp = temp_from_s16(data->temp11[attr->index]); |
377 | 413 | ||
@@ -401,12 +437,15 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
401 | data->temp11[nr] = temp_to_u16_adt7461(data, val); | 437 | data->temp11[nr] = temp_to_u16_adt7461(data, val); |
402 | else if (data->kind == max6657 || data->kind == max6680) | 438 | else if (data->kind == max6657 || data->kind == max6680) |
403 | data->temp11[nr] = temp_to_s8(val) << 8; | 439 | data->temp11[nr] = temp_to_s8(val) << 8; |
440 | else if (data->kind == max6646) | ||
441 | data->temp11[nr] = temp_to_u8(val) << 8; | ||
404 | else | 442 | else |
405 | data->temp11[nr] = temp_to_s16(val); | 443 | data->temp11[nr] = temp_to_s16(val); |
406 | 444 | ||
407 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], | 445 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], |
408 | data->temp11[nr] >> 8); | 446 | data->temp11[nr] >> 8); |
409 | if (data->kind != max6657 && data->kind != max6680) | 447 | if (data->kind != max6657 && data->kind != max6680 |
448 | && data->kind != max6646) | ||
410 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], | 449 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], |
411 | data->temp11[nr] & 0xff); | 450 | data->temp11[nr] & 0xff); |
412 | mutex_unlock(&data->update_lock); | 451 | mutex_unlock(&data->update_lock); |
@@ -689,6 +728,16 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
689 | && (reg_config1 & 0x03) == 0x00 | 728 | && (reg_config1 & 0x03) == 0x00 |
690 | && reg_convrate <= 0x07) { | 729 | && reg_convrate <= 0x07) { |
691 | kind = max6680; | 730 | kind = max6680; |
731 | } else | ||
732 | /* The chip_id register of the MAX6646/6647/6649 | ||
733 | * holds the revision of the chip. | ||
734 | * The lowest 6 bits of the config1 register are | ||
735 | * unused and should return zero when read. | ||
736 | */ | ||
737 | if (chip_id == 0x59 | ||
738 | && (reg_config1 & 0x3f) == 0x00 | ||
739 | && reg_convrate <= 0x07) { | ||
740 | kind = max6646; | ||
692 | } | 741 | } |
693 | } | 742 | } |
694 | 743 | ||
@@ -719,6 +768,8 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
719 | name = "max6680"; | 768 | name = "max6680"; |
720 | } else if (kind == adt7461) { | 769 | } else if (kind == adt7461) { |
721 | name = "adt7461"; | 770 | name = "adt7461"; |
771 | } else if (kind == max6646) { | ||
772 | name = "max6646"; | ||
722 | } | 773 | } |
723 | strlcpy(info->type, name, I2C_NAME_SIZE); | 774 | strlcpy(info->type, name, I2C_NAME_SIZE); |
724 | 775 | ||
@@ -758,7 +809,7 @@ static int lm90_probe(struct i2c_client *new_client, | |||
758 | &dev_attr_pec))) | 809 | &dev_attr_pec))) |
759 | goto exit_remove_files; | 810 | goto exit_remove_files; |
760 | } | 811 | } |
761 | if (data->kind != max6657) { | 812 | if (data->kind != max6657 && data->kind != max6646) { |
762 | if ((err = device_create_file(&new_client->dev, | 813 | if ((err = device_create_file(&new_client->dev, |
763 | &sensor_dev_attr_temp2_offset.dev_attr))) | 814 | &sensor_dev_attr_temp2_offset.dev_attr))) |
764 | goto exit_remove_files; | 815 | goto exit_remove_files; |
@@ -824,7 +875,7 @@ static int lm90_remove(struct i2c_client *client) | |||
824 | hwmon_device_unregister(data->hwmon_dev); | 875 | hwmon_device_unregister(data->hwmon_dev); |
825 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | 876 | sysfs_remove_group(&client->dev.kobj, &lm90_group); |
826 | device_remove_file(&client->dev, &dev_attr_pec); | 877 | device_remove_file(&client->dev, &dev_attr_pec); |
827 | if (data->kind != max6657) | 878 | if (data->kind != max6657 && data->kind != max6646) |
828 | device_remove_file(&client->dev, | 879 | device_remove_file(&client->dev, |
829 | &sensor_dev_attr_temp2_offset.dev_attr); | 880 | &sensor_dev_attr_temp2_offset.dev_attr); |
830 | 881 | ||
@@ -881,7 +932,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
881 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); | 932 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); |
882 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); | 933 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); |
883 | 934 | ||
884 | if (data->kind == max6657) { | 935 | if (data->kind == max6657 || data->kind == max6646) { |
885 | lm90_read16(client, LM90_REG_R_LOCAL_TEMP, | 936 | lm90_read16(client, LM90_REG_R_LOCAL_TEMP, |
886 | MAX6657_REG_R_LOCAL_TEMPL, | 937 | MAX6657_REG_R_LOCAL_TEMPL, |
887 | &data->temp11[4]); | 938 | &data->temp11[4]); |
@@ -896,6 +947,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
896 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { | 947 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { |
897 | data->temp11[1] = h << 8; | 948 | data->temp11[1] = h << 8; |
898 | if (data->kind != max6657 && data->kind != max6680 | 949 | if (data->kind != max6657 && data->kind != max6680 |
950 | && data->kind != max6646 | ||
899 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, | 951 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, |
900 | &l) == 0) | 952 | &l) == 0) |
901 | data->temp11[1] |= l; | 953 | data->temp11[1] |= l; |
@@ -903,12 +955,13 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
903 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { | 955 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { |
904 | data->temp11[2] = h << 8; | 956 | data->temp11[2] = h << 8; |
905 | if (data->kind != max6657 && data->kind != max6680 | 957 | if (data->kind != max6657 && data->kind != max6680 |
958 | && data->kind != max6646 | ||
906 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, | 959 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, |
907 | &l) == 0) | 960 | &l) == 0) |
908 | data->temp11[2] |= l; | 961 | data->temp11[2] |= l; |
909 | } | 962 | } |
910 | 963 | ||
911 | if (data->kind != max6657) { | 964 | if (data->kind != max6657 && data->kind != max6646) { |
912 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, | 965 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, |
913 | &h) == 0 | 966 | &h) == 0 |
914 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, | 967 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, |