diff options
author | Guenter Roeck <guenter.roeck@ericsson.com> | 2010-10-28 14:31:43 -0400 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2010-10-28 14:31:43 -0400 |
commit | 06e1c0a2167d48442d0bd06373390886670aa6e5 (patch) | |
tree | ab8dd85f43e2d69ab2fcfd5a2f053ac7923a9685 | |
parent | 6948708dd07573c578aa99f80915cd1867334abe (diff) |
hwmon: (lm90) Add support for max6695 and max6696
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | Documentation/hwmon/lm90 | 17 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/lm90.c | 250 |
3 files changed, 247 insertions, 24 deletions
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index bc2c2b4e0d53..6e963b696d85 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 | |||
@@ -84,6 +84,17 @@ Supported chips: | |||
84 | Addresses scanned: I2C 0x4c | 84 | Addresses scanned: I2C 0x4c |
85 | Datasheet: Publicly available at the Maxim website | 85 | Datasheet: Publicly available at the Maxim website |
86 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 | 86 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 |
87 | * Maxim MAX6695 | ||
88 | Prefix: 'max6695' | ||
89 | Addresses scanned: I2C 0x18 | ||
90 | Datasheet: Publicly available at the Maxim website | ||
91 | http://www.maxim-ic.com/datasheet/index.mvp/id/4199 | ||
92 | * Maxim MAX6696 | ||
93 | Prefix: 'max6695' | ||
94 | Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
95 | 0x4c, 0x4d and 0x4e | ||
96 | Datasheet: Publicly available at the Maxim website | ||
97 | http://www.maxim-ic.com/datasheet/index.mvp/id/4199 | ||
87 | * Winbond/Nuvoton W83L771AWG/ASG | 98 | * Winbond/Nuvoton W83L771AWG/ASG |
88 | Prefix: 'w83l771' | 99 | Prefix: 'w83l771' |
89 | Addresses scanned: I2C 0x4c | 100 | Addresses scanned: I2C 0x4c |
@@ -152,6 +163,12 @@ MAX6680 and MAX6681: | |||
152 | * Selectable address | 163 | * Selectable address |
153 | * Remote sensor type selection | 164 | * Remote sensor type selection |
154 | 165 | ||
166 | MAX6695 and MAX6696: | ||
167 | * Better local resolution | ||
168 | * Selectable address (max6696) | ||
169 | * Second critical temperature limit | ||
170 | * Two remote sensors | ||
171 | |||
155 | W83L771AWG/ASG | 172 | W83L771AWG/ASG |
156 | * The AWG and ASG variants only differ in package format. | 173 | * The AWG and ASG variants only differ in package format. |
157 | * Filter and alert configuration register at 0xBF | 174 | * Filter and alert configuration register at 0xBF |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c357c835eb1e..9a3742b67c8c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -614,8 +614,8 @@ config SENSORS_LM90 | |||
614 | If you say yes here you get support for National Semiconductor LM90, | 614 | If you say yes here you get support for National Semiconductor LM90, |
615 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim | 615 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim |
616 | MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, | 616 | MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, |
617 | MAX6680, MAX6681 and MAX6692, and Winbond/Nuvoton W83L771AWG/ASG | 617 | MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, and Winbond/Nuvoton |
618 | sensor chips. | 618 | W83L771AWG/ASG sensor chips. |
619 | 619 | ||
620 | This driver can also be built as a module. If so, the module | 620 | This driver can also be built as a module. If so, the module |
621 | will be called lm90. | 621 | will be called lm90. |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index de544817d673..366bb624e655 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -44,6 +44,11 @@ | |||
44 | * chips. The MAX6680 and MAX6681 only differ in the pinout so they can | 44 | * chips. The MAX6680 and MAX6681 only differ in the pinout so they can |
45 | * be treated identically. | 45 | * be treated identically. |
46 | * | 46 | * |
47 | * This driver also supports the MAX6695 and MAX6696, two other sensor | ||
48 | * chips made by Maxim. These are also quite similar to other Maxim | ||
49 | * chips, but support three temperature sensors instead of two. MAX6695 | ||
50 | * and MAX6696 only differ in the pinout so they can be treated identically. | ||
51 | * | ||
47 | * This driver also supports the ADT7461 chip from Analog Devices. | 52 | * This driver also supports the ADT7461 chip from Analog Devices. |
48 | * It's supported in both compatibility and extended mode. It is mostly | 53 | * It's supported in both compatibility and extended mode. It is mostly |
49 | * compatible with LM90 except for a data format difference for the | 54 | * compatible with LM90 except for a data format difference for the |
@@ -96,7 +101,7 @@ static const unsigned short normal_i2c[] = { | |||
96 | 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; | 101 | 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; |
97 | 102 | ||
98 | enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, | 103 | enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, |
99 | max6646, w83l771 }; | 104 | max6646, w83l771, max6696 }; |
100 | 105 | ||
101 | /* | 106 | /* |
102 | * The LM90 registers | 107 | * The LM90 registers |
@@ -137,9 +142,10 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, | |||
137 | #define LM90_REG_R_TCRIT_HYST 0x21 | 142 | #define LM90_REG_R_TCRIT_HYST 0x21 |
138 | #define LM90_REG_W_TCRIT_HYST 0x21 | 143 | #define LM90_REG_W_TCRIT_HYST 0x21 |
139 | 144 | ||
140 | /* MAX6646/6647/6649/6657/6658/6659 registers */ | 145 | /* MAX6646/6647/6649/6657/6658/6659/6695/6696 registers */ |
141 | 146 | ||
142 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 | 147 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 |
148 | #define MAX6696_REG_R_STATUS2 0x12 | ||
143 | #define MAX6659_REG_R_REMOTE_EMERG 0x16 | 149 | #define MAX6659_REG_R_REMOTE_EMERG 0x16 |
144 | #define MAX6659_REG_W_REMOTE_EMERG 0x16 | 150 | #define MAX6659_REG_W_REMOTE_EMERG 0x16 |
145 | #define MAX6659_REG_R_LOCAL_EMERG 0x17 | 151 | #define MAX6659_REG_R_LOCAL_EMERG 0x17 |
@@ -154,6 +160,8 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, | |||
154 | #define LM90_HAVE_LOCAL_EXT (1 << 2) /* extended local temperature */ | 160 | #define LM90_HAVE_LOCAL_EXT (1 << 2) /* extended local temperature */ |
155 | #define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */ | 161 | #define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */ |
156 | #define LM90_HAVE_EMERGENCY (1 << 4) /* 3rd upper (emergency) limit */ | 162 | #define LM90_HAVE_EMERGENCY (1 << 4) /* 3rd upper (emergency) limit */ |
163 | #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ | ||
164 | #define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ | ||
157 | 165 | ||
158 | /* | 166 | /* |
159 | * Functions declaration | 167 | * Functions declaration |
@@ -166,6 +174,9 @@ static void lm90_init_client(struct i2c_client *client); | |||
166 | static void lm90_alert(struct i2c_client *client, unsigned int flag); | 174 | static void lm90_alert(struct i2c_client *client, unsigned int flag); |
167 | static int lm90_remove(struct i2c_client *client); | 175 | static int lm90_remove(struct i2c_client *client); |
168 | static struct lm90_data *lm90_update_device(struct device *dev); | 176 | static struct lm90_data *lm90_update_device(struct device *dev); |
177 | static inline void lm90_select_remote_channel(struct i2c_client *client, | ||
178 | struct lm90_data *data, | ||
179 | int channel); | ||
169 | 180 | ||
170 | /* | 181 | /* |
171 | * Driver data (common to all clients) | 182 | * Driver data (common to all clients) |
@@ -186,6 +197,8 @@ static const struct i2c_device_id lm90_id[] = { | |||
186 | { "max6659", max6659 }, | 197 | { "max6659", max6659 }, |
187 | { "max6680", max6680 }, | 198 | { "max6680", max6680 }, |
188 | { "max6681", max6680 }, | 199 | { "max6681", max6680 }, |
200 | { "max6695", max6696 }, | ||
201 | { "max6696", max6696 }, | ||
189 | { "w83l771", w83l771 }, | 202 | { "w83l771", w83l771 }, |
190 | { } | 203 | { } |
191 | }; | 204 | }; |
@@ -217,22 +230,29 @@ struct lm90_data { | |||
217 | int flags; | 230 | int flags; |
218 | 231 | ||
219 | u8 config_orig; /* Original configuration register value */ | 232 | u8 config_orig; /* Original configuration register value */ |
220 | u8 alert_alarms; /* Which alarm bits trigger ALERT# */ | 233 | u16 alert_alarms; /* Which alarm bits trigger ALERT# */ |
234 | /* Upper 8 bits for max6695/96 */ | ||
221 | 235 | ||
222 | /* registers values */ | 236 | /* registers values */ |
223 | s8 temp8[6]; /* 0: local low limit | 237 | s8 temp8[8]; /* 0: local low limit |
224 | 1: local high limit | 238 | 1: local high limit |
225 | 2: local critical limit | 239 | 2: local critical limit |
226 | 3: remote critical limit | 240 | 3: remote critical limit |
227 | 4: local emergency limit (max6659 only) | 241 | 4: local emergency limit (max6659 and max6695/96) |
228 | 5: remote emergency limit (max6659 only) */ | 242 | 5: remote emergency limit (max6659 and max6695/96) |
229 | s16 temp11[5]; /* 0: remote input | 243 | 6: remote 2 critical limit (max6695/96 only) |
244 | 7: remote 2 emergency limit (max6695/96 only) */ | ||
245 | s16 temp11[8]; /* 0: remote input | ||
230 | 1: remote low limit | 246 | 1: remote low limit |
231 | 2: remote high limit | 247 | 2: remote high limit |
232 | 3: remote offset (except max6646 and max6657/58/59) | 248 | 3: remote offset (except max6646, max6657/58/59, |
233 | 4: local input */ | 249 | and max6695/96) |
250 | 4: local input | ||
251 | 5: remote 2 input (max6695/96 only) | ||
252 | 6: remote 2 low limit (max6695/96 only) | ||
253 | 7: remote 2 high limit (ma6695/96 only) */ | ||
234 | u8 temp_hyst; | 254 | u8 temp_hyst; |
235 | u8 alarms; /* bitvector */ | 255 | u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ |
236 | }; | 256 | }; |
237 | 257 | ||
238 | /* | 258 | /* |
@@ -390,13 +410,15 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | |||
390 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | 410 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, |
391 | const char *buf, size_t count) | 411 | const char *buf, size_t count) |
392 | { | 412 | { |
393 | static const u8 reg[6] = { | 413 | static const u8 reg[8] = { |
394 | LM90_REG_W_LOCAL_LOW, | 414 | LM90_REG_W_LOCAL_LOW, |
395 | LM90_REG_W_LOCAL_HIGH, | 415 | LM90_REG_W_LOCAL_HIGH, |
396 | LM90_REG_W_LOCAL_CRIT, | 416 | LM90_REG_W_LOCAL_CRIT, |
397 | LM90_REG_W_REMOTE_CRIT, | 417 | LM90_REG_W_REMOTE_CRIT, |
398 | MAX6659_REG_W_LOCAL_EMERG, | 418 | MAX6659_REG_W_LOCAL_EMERG, |
399 | MAX6659_REG_W_REMOTE_EMERG, | 419 | MAX6659_REG_W_REMOTE_EMERG, |
420 | LM90_REG_W_REMOTE_CRIT, | ||
421 | MAX6659_REG_W_REMOTE_EMERG, | ||
400 | }; | 422 | }; |
401 | 423 | ||
402 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 424 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
@@ -421,7 +443,11 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
421 | data->temp8[nr] = temp_to_u8(val); | 443 | data->temp8[nr] = temp_to_u8(val); |
422 | else | 444 | else |
423 | data->temp8[nr] = temp_to_s8(val); | 445 | data->temp8[nr] = temp_to_s8(val); |
446 | |||
447 | lm90_select_remote_channel(client, data, nr >= 6); | ||
424 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); | 448 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); |
449 | lm90_select_remote_channel(client, data, 0); | ||
450 | |||
425 | mutex_unlock(&data->update_lock); | 451 | mutex_unlock(&data->update_lock); |
426 | return count; | 452 | return count; |
427 | } | 453 | } |
@@ -453,10 +479,13 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
453 | struct { | 479 | struct { |
454 | u8 high; | 480 | u8 high; |
455 | u8 low; | 481 | u8 low; |
456 | } reg[3] = { | 482 | int channel; |
457 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL }, | 483 | } reg[5] = { |
458 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL }, | 484 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 0 }, |
459 | { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL } | 485 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 0 }, |
486 | { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL, 0 }, | ||
487 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 1 }, | ||
488 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 1 } | ||
460 | }; | 489 | }; |
461 | 490 | ||
462 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | 491 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); |
@@ -485,11 +514,14 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
485 | else | 514 | else |
486 | data->temp11[index] = temp_to_s8(val) << 8; | 515 | data->temp11[index] = temp_to_s8(val) << 8; |
487 | 516 | ||
517 | lm90_select_remote_channel(client, data, reg[nr].channel); | ||
488 | i2c_smbus_write_byte_data(client, reg[nr].high, | 518 | i2c_smbus_write_byte_data(client, reg[nr].high, |
489 | data->temp11[index] >> 8); | 519 | data->temp11[index] >> 8); |
490 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) | 520 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) |
491 | i2c_smbus_write_byte_data(client, reg[nr].low, | 521 | i2c_smbus_write_byte_data(client, reg[nr].low, |
492 | data->temp11[index] & 0xff); | 522 | data->temp11[index] & 0xff); |
523 | lm90_select_remote_channel(client, data, 0); | ||
524 | |||
493 | mutex_unlock(&data->update_lock); | 525 | mutex_unlock(&data->update_lock); |
494 | return count; | 526 | return count; |
495 | } | 527 | } |
@@ -643,6 +675,62 @@ static const struct attribute_group lm90_emergency_group = { | |||
643 | .attrs = lm90_emergency_attributes, | 675 | .attrs = lm90_emergency_attributes, |
644 | }; | 676 | }; |
645 | 677 | ||
678 | static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 15); | ||
679 | static SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 13); | ||
680 | |||
681 | static struct attribute *lm90_emergency_alarm_attributes[] = { | ||
682 | &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, | ||
683 | &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, | ||
684 | NULL | ||
685 | }; | ||
686 | |||
687 | static const struct attribute_group lm90_emergency_alarm_group = { | ||
688 | .attrs = lm90_emergency_alarm_attributes, | ||
689 | }; | ||
690 | |||
691 | /* | ||
692 | * Additional attributes for devices with 3 temperature sensors | ||
693 | */ | ||
694 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp11, NULL, 0, 5); | ||
695 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp11, | ||
696 | set_temp11, 3, 6); | ||
697 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp11, | ||
698 | set_temp11, 4, 7); | ||
699 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
700 | set_temp8, 6); | ||
701 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temphyst, NULL, 6); | ||
702 | static SENSOR_DEVICE_ATTR(temp3_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
703 | set_temp8, 7); | ||
704 | static SENSOR_DEVICE_ATTR(temp3_emergency_hyst, S_IRUGO, show_temphyst, | ||
705 | NULL, 7); | ||
706 | |||
707 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
708 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 10); | ||
709 | static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
710 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
711 | static SENSOR_DEVICE_ATTR(temp3_emergency_alarm, S_IRUGO, show_alarm, NULL, 14); | ||
712 | |||
713 | static struct attribute *lm90_temp3_attributes[] = { | ||
714 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
715 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
716 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
717 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
718 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
719 | &sensor_dev_attr_temp3_emergency.dev_attr.attr, | ||
720 | &sensor_dev_attr_temp3_emergency_hyst.dev_attr.attr, | ||
721 | |||
722 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
723 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
724 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
725 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
726 | &sensor_dev_attr_temp3_emergency_alarm.dev_attr.attr, | ||
727 | NULL | ||
728 | }; | ||
729 | |||
730 | static const struct attribute_group lm90_temp3_group = { | ||
731 | .attrs = lm90_temp3_attributes, | ||
732 | }; | ||
733 | |||
646 | /* pec used for ADM1032 only */ | 734 | /* pec used for ADM1032 only */ |
647 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, | 735 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, |
648 | char *buf) | 736 | char *buf) |
@@ -720,6 +808,30 @@ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) | |||
720 | return 0; | 808 | return 0; |
721 | } | 809 | } |
722 | 810 | ||
811 | /* | ||
812 | * client->update_lock must be held when calling this function (unless we are | ||
813 | * in detection or initialization steps), and while a remote channel other | ||
814 | * than channel 0 is selected. Also, calling code must make sure to re-select | ||
815 | * external channel 0 before releasing the lock. This is necessary because | ||
816 | * various registers have different meanings as a result of selecting a | ||
817 | * non-default remote channel. | ||
818 | */ | ||
819 | static inline void lm90_select_remote_channel(struct i2c_client *client, | ||
820 | struct lm90_data *data, | ||
821 | int channel) | ||
822 | { | ||
823 | u8 config; | ||
824 | |||
825 | if (data->kind == max6696) { | ||
826 | lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); | ||
827 | config &= ~0x08; | ||
828 | if (channel) | ||
829 | config |= 0x08; | ||
830 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | ||
831 | config); | ||
832 | } | ||
833 | } | ||
834 | |||
723 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 835 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
724 | static int lm90_detect(struct i2c_client *new_client, | 836 | static int lm90_detect(struct i2c_client *new_client, |
725 | struct i2c_board_info *info) | 837 | struct i2c_board_info *info) |
@@ -794,6 +906,23 @@ static int lm90_detect(struct i2c_client *new_client, | |||
794 | } | 906 | } |
795 | } else | 907 | } else |
796 | if (man_id == 0x4D) { /* Maxim */ | 908 | if (man_id == 0x4D) { /* Maxim */ |
909 | int reg_emerg, reg_emerg2, reg_status2; | ||
910 | |||
911 | /* | ||
912 | * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read | ||
913 | * LM90_REG_R_MAN_ID in between. If MAX6659_REG_R_REMOTE_EMERG | ||
914 | * exists, both readings will reflect the same value. Otherwise, | ||
915 | * the readings will be different. | ||
916 | */ | ||
917 | if ((reg_emerg = i2c_smbus_read_byte_data(new_client, | ||
918 | MAX6659_REG_R_REMOTE_EMERG)) < 0 | ||
919 | || i2c_smbus_read_byte_data(new_client, LM90_REG_R_MAN_ID) < 0 | ||
920 | || (reg_emerg2 = i2c_smbus_read_byte_data(new_client, | ||
921 | MAX6659_REG_R_REMOTE_EMERG)) < 0 | ||
922 | || (reg_status2 = i2c_smbus_read_byte_data(new_client, | ||
923 | MAX6696_REG_R_STATUS2)) < 0) | ||
924 | return -ENODEV; | ||
925 | |||
797 | /* | 926 | /* |
798 | * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id | 927 | * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id |
799 | * register. Reading from that address will return the last | 928 | * register. Reading from that address will return the last |
@@ -817,6 +946,24 @@ static int lm90_detect(struct i2c_client *new_client, | |||
817 | name = "max6659"; | 946 | name = "max6659"; |
818 | } else | 947 | } else |
819 | /* | 948 | /* |
949 | * Even though MAX6695 and MAX6696 do not have a chip ID | ||
950 | * register, reading it returns 0x01. Bit 4 of the config1 | ||
951 | * register is unused and should return zero when read. Bit 0 of | ||
952 | * the status2 register is unused and should return zero when | ||
953 | * read. | ||
954 | * | ||
955 | * MAX6695 and MAX6696 have an additional set of temperature | ||
956 | * limit registers. We can detect those chips by checking if | ||
957 | * one of those registers exists. | ||
958 | */ | ||
959 | if (chip_id == 0x01 | ||
960 | && (reg_config1 & 0x10) == 0x00 | ||
961 | && (reg_status2 & 0x01) == 0x00 | ||
962 | && reg_emerg == reg_emerg2 | ||
963 | && reg_convrate <= 0x07) { | ||
964 | name = "max6696"; | ||
965 | } else | ||
966 | /* | ||
820 | * The chip_id register of the MAX6680 and MAX6681 holds the | 967 | * The chip_id register of the MAX6680 and MAX6681 holds the |
821 | * revision of the chip. The lowest bit of the config1 register | 968 | * revision of the chip. The lowest bit of the config1 register |
822 | * is unused and should return zero when read, so should the | 969 | * is unused and should return zero when read, so should the |
@@ -861,6 +1008,11 @@ static int lm90_detect(struct i2c_client *new_client, | |||
861 | 1008 | ||
862 | static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) | 1009 | static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) |
863 | { | 1010 | { |
1011 | if (data->flags & LM90_HAVE_TEMP3) | ||
1012 | sysfs_remove_group(&client->dev.kobj, &lm90_temp3_group); | ||
1013 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) | ||
1014 | sysfs_remove_group(&client->dev.kobj, | ||
1015 | &lm90_emergency_alarm_group); | ||
864 | if (data->flags & LM90_HAVE_EMERGENCY) | 1016 | if (data->flags & LM90_HAVE_EMERGENCY) |
865 | sysfs_remove_group(&client->dev.kobj, | 1017 | sysfs_remove_group(&client->dev.kobj, |
866 | &lm90_emergency_group); | 1018 | &lm90_emergency_group); |
@@ -901,6 +1053,9 @@ static int lm90_probe(struct i2c_client *new_client, | |||
901 | case lm86: | 1053 | case lm86: |
902 | data->alert_alarms = 0x7b; | 1054 | data->alert_alarms = 0x7b; |
903 | break; | 1055 | break; |
1056 | case max6696: | ||
1057 | data->alert_alarms = 0x187c; | ||
1058 | break; | ||
904 | default: | 1059 | default: |
905 | data->alert_alarms = 0x7c; | 1060 | data->alert_alarms = 0x7c; |
906 | break; | 1061 | break; |
@@ -908,20 +1063,24 @@ static int lm90_probe(struct i2c_client *new_client, | |||
908 | 1063 | ||
909 | /* Set chip capabilities */ | 1064 | /* Set chip capabilities */ |
910 | if (data->kind != max6657 && data->kind != max6659 | 1065 | if (data->kind != max6657 && data->kind != max6659 |
911 | && data->kind != max6646) | 1066 | && data->kind != max6646 && data->kind != max6696) |
912 | data->flags |= LM90_HAVE_OFFSET; | 1067 | data->flags |= LM90_HAVE_OFFSET; |
913 | 1068 | ||
914 | if (data->kind == max6657 || data->kind == max6659 | 1069 | if (data->kind == max6657 || data->kind == max6659 |
915 | || data->kind == max6646) | 1070 | || data->kind == max6646 || data->kind == max6696) |
916 | data->flags |= LM90_HAVE_LOCAL_EXT; | 1071 | data->flags |= LM90_HAVE_LOCAL_EXT; |
917 | 1072 | ||
918 | if (data->kind != max6657 && data->kind != max6659 | 1073 | if (data->kind != max6657 && data->kind != max6659 |
919 | && data->kind != max6646 && data->kind != max6680) | 1074 | && data->kind != max6646 && data->kind != max6680 |
1075 | && data->kind != max6696) | ||
920 | data->flags |= LM90_HAVE_REM_LIMIT_EXT; | 1076 | data->flags |= LM90_HAVE_REM_LIMIT_EXT; |
921 | 1077 | ||
922 | if (data->kind == max6659) | 1078 | if (data->kind == max6659 || data->kind == max6696) |
923 | data->flags |= LM90_HAVE_EMERGENCY; | 1079 | data->flags |= LM90_HAVE_EMERGENCY; |
924 | 1080 | ||
1081 | if (data->kind == max6696) | ||
1082 | data->flags |= LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3; | ||
1083 | |||
925 | /* Initialize the LM90 chip */ | 1084 | /* Initialize the LM90 chip */ |
926 | lm90_init_client(new_client); | 1085 | lm90_init_client(new_client); |
927 | 1086 | ||
@@ -946,6 +1105,18 @@ static int lm90_probe(struct i2c_client *new_client, | |||
946 | if (err) | 1105 | if (err) |
947 | goto exit_remove_files; | 1106 | goto exit_remove_files; |
948 | } | 1107 | } |
1108 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { | ||
1109 | err = sysfs_create_group(&new_client->dev.kobj, | ||
1110 | &lm90_emergency_alarm_group); | ||
1111 | if (err) | ||
1112 | goto exit_remove_files; | ||
1113 | } | ||
1114 | if (data->flags & LM90_HAVE_TEMP3) { | ||
1115 | err = sysfs_create_group(&new_client->dev.kobj, | ||
1116 | &lm90_temp3_group); | ||
1117 | if (err) | ||
1118 | goto exit_remove_files; | ||
1119 | } | ||
949 | 1120 | ||
950 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 1121 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
951 | if (IS_ERR(data->hwmon_dev)) { | 1122 | if (IS_ERR(data->hwmon_dev)) { |
@@ -993,6 +1164,12 @@ static void lm90_init_client(struct i2c_client *client) | |||
993 | if (data->kind == max6680) | 1164 | if (data->kind == max6680) |
994 | config |= 0x18; | 1165 | config |= 0x18; |
995 | 1166 | ||
1167 | /* | ||
1168 | * Select external channel 0 for max6695/96 | ||
1169 | */ | ||
1170 | if (data->kind == max6696) | ||
1171 | config &= ~0x08; | ||
1172 | |||
996 | config &= 0xBF; /* run */ | 1173 | config &= 0xBF; /* run */ |
997 | if (config != data->config_orig) /* Only write if changed */ | 1174 | if (config != data->config_orig) /* Only write if changed */ |
998 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); | 1175 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); |
@@ -1016,10 +1193,14 @@ static int lm90_remove(struct i2c_client *client) | |||
1016 | static void lm90_alert(struct i2c_client *client, unsigned int flag) | 1193 | static void lm90_alert(struct i2c_client *client, unsigned int flag) |
1017 | { | 1194 | { |
1018 | struct lm90_data *data = i2c_get_clientdata(client); | 1195 | struct lm90_data *data = i2c_get_clientdata(client); |
1019 | u8 config, alarms; | 1196 | u8 config, alarms, alarms2 = 0; |
1020 | 1197 | ||
1021 | lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); | 1198 | lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); |
1022 | if ((alarms & 0x7f) == 0) { | 1199 | |
1200 | if (data->kind == max6696) | ||
1201 | lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms2); | ||
1202 | |||
1203 | if ((alarms & 0x7f) == 0 && (alarms2 & 0xfe) == 0) { | ||
1023 | dev_info(&client->dev, "Everything OK\n"); | 1204 | dev_info(&client->dev, "Everything OK\n"); |
1024 | } else { | 1205 | } else { |
1025 | if (alarms & 0x61) | 1206 | if (alarms & 0x61) |
@@ -1032,6 +1213,10 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) | |||
1032 | dev_warn(&client->dev, | 1213 | dev_warn(&client->dev, |
1033 | "temp%d diode open, please check!\n", 2); | 1214 | "temp%d diode open, please check!\n", 2); |
1034 | 1215 | ||
1216 | if (alarms2 & 0x18) | ||
1217 | dev_warn(&client->dev, | ||
1218 | "temp%d out of range, please check!\n", 3); | ||
1219 | |||
1035 | /* Disable ALERT# output, because these chips don't implement | 1220 | /* Disable ALERT# output, because these chips don't implement |
1036 | SMBus alert correctly; they should only hold the alert line | 1221 | SMBus alert correctly; they should only hold the alert line |
1037 | low briefly. */ | 1222 | low briefly. */ |
@@ -1087,6 +1272,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
1087 | if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) | 1272 | if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) |
1088 | || !data->valid) { | 1273 | || !data->valid) { |
1089 | u8 h, l; | 1274 | u8 h, l; |
1275 | u8 alarms; | ||
1090 | 1276 | ||
1091 | dev_dbg(&client->dev, "Updating lm90 data.\n"); | 1277 | dev_dbg(&client->dev, "Updating lm90 data.\n"); |
1092 | lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); | 1278 | lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); |
@@ -1135,7 +1321,27 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
1135 | lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, | 1321 | lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, |
1136 | &data->temp8[5]); | 1322 | &data->temp8[5]); |
1137 | } | 1323 | } |
1138 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); | 1324 | lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); |
1325 | data->alarms = alarms; /* save as 16 bit value */ | ||
1326 | |||
1327 | if (data->kind == max6696) { | ||
1328 | lm90_select_remote_channel(client, data, 1); | ||
1329 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, | ||
1330 | &data->temp8[6]); | ||
1331 | lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, | ||
1332 | &data->temp8[7]); | ||
1333 | lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, | ||
1334 | LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); | ||
1335 | if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) | ||
1336 | data->temp11[6] = h << 8; | ||
1337 | if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) | ||
1338 | data->temp11[7] = h << 8; | ||
1339 | lm90_select_remote_channel(client, data, 0); | ||
1340 | |||
1341 | if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, | ||
1342 | &alarms)) | ||
1343 | data->alarms |= alarms << 8; | ||
1344 | } | ||
1139 | 1345 | ||
1140 | /* Re-enable ALERT# output if it was originally enabled and | 1346 | /* Re-enable ALERT# output if it was originally enabled and |
1141 | * relevant alarms are all clear */ | 1347 | * relevant alarms are all clear */ |