aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/lm90.rst12
-rw-r--r--drivers/hwmon/lm90.c41
2 files changed, 47 insertions, 6 deletions
diff --git a/Documentation/hwmon/lm90.rst b/Documentation/hwmon/lm90.rst
index 9886a298797f..e947e609990b 100644
--- a/Documentation/hwmon/lm90.rst
+++ b/Documentation/hwmon/lm90.rst
@@ -105,7 +105,7 @@ Supported chips:
* Maxim MAX6648
- Prefix: 'max6646'
+ Prefix: 'max6648'
Addresses scanned: I2C 0x4c
@@ -191,7 +191,7 @@ Supported chips:
* Maxim MAX6692
- Prefix: 'max6646'
+ Prefix: 'max6648'
Addresses scanned: I2C 0x4c
@@ -324,6 +324,14 @@ ADT7461, ADT7461A, NCT1008:
* Lower resolution for remote temperature
* SMBus PEC support for Write Byte and Receive Byte transactions.
+MAX6646, MAX6647, MAX6649:
+ * Better local resolution
+ * Extended range unsigned external temperature
+
+MAX6648, MAX6692:
+ * Better local resolution
+ * Unsigned temperature
+
MAX6654:
* Better local resolution
* Selectable address
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index e6a9c6832fc6..fded11b0003e 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -115,7 +115,7 @@ static const unsigned short normal_i2c[] = {
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
enum chips { adm1032, adt7461, adt7461a, g781, lm86, lm90, lm99,
- max6646, max6654, max6657, max6659, max6680, max6696,
+ max6646, max6648, max6654, max6657, max6659, max6680, max6696,
sa56004, tmp451, tmp461, w83l771,
};
@@ -179,6 +179,7 @@ enum chips { adm1032, adt7461, adt7461a, g781, lm86, lm90, lm99,
#define LM90_HAVE_PEC BIT(11) /* Chip supports PEC */
#define LM90_HAVE_PARTIAL_PEC BIT(12) /* Partial PEC support (adm1032)*/
#define LM90_HAVE_ALARMS BIT(13) /* Create 'alarms' attribute */
+#define LM90_HAVE_EXT_UNSIGNED BIT(14) /* extended unsigned temperature*/
/* LM90 status */
#define LM90_STATUS_LTHRM BIT(0) /* local THERM limit tripped */
@@ -213,6 +214,7 @@ static const struct i2c_device_id lm90_id[] = {
{ "lm99", lm99 },
{ "max6646", max6646 },
{ "max6647", max6646 },
+ { "max6648", max6648 },
{ "max6649", max6646 },
{ "max6654", max6654 },
{ "max6657", max6657 },
@@ -220,6 +222,7 @@ static const struct i2c_device_id lm90_id[] = {
{ "max6659", max6659 },
{ "max6680", max6680 },
{ "max6681", max6680 },
+ { "max6692", max6648 },
{ "max6695", max6696 },
{ "max6696", max6696 },
{ "nct1008", adt7461a },
@@ -400,7 +403,14 @@ static const struct lm90_params lm90_params[] = {
},
[max6646] = {
.flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT
- | LM90_HAVE_UNSIGNED_TEMP | LM90_HAVE_ALARMS,
+ | LM90_HAVE_EXT_UNSIGNED | LM90_HAVE_ALARMS,
+ .alert_alarms = 0x7c,
+ .max_convrate = 6,
+ .reg_local_ext = MAX6657_REG_LOCAL_TEMPL,
+ },
+ [max6648] = {
+ .flags = LM90_HAVE_UNSIGNED_TEMP | LM90_HAVE_CRIT
+ | LM90_HAVE_BROKEN_ALERT,
.alert_alarms = 0x7c,
.max_convrate = 6,
.reg_local_ext = MAX6657_REG_LOCAL_TEMPL,
@@ -1119,7 +1129,7 @@ static int lm90_temp_from_reg(u32 flags, u16 regval, u8 resolution)
if (flags & LM90_HAVE_EXTENDED_TEMP)
val = regval - 0x4000;
- else if (flags & LM90_HAVE_UNSIGNED_TEMP)
+ else if (flags & (LM90_HAVE_UNSIGNED_TEMP | LM90_HAVE_EXT_UNSIGNED))
val = regval;
else
val = (s16)regval;
@@ -1147,6 +1157,8 @@ static u16 lm90_temp_to_reg(u32 flags, long val, u8 resolution)
if (flags & LM90_HAVE_EXTENDED_TEMP) {
val = clamp_val(val, -64000, 191000 + fraction);
val += 64000;
+ } else if (flags & LM90_HAVE_EXT_UNSIGNED) {
+ val = clamp_val(val, 0, 255000 + fraction);
} else if (flags & LM90_HAVE_UNSIGNED_TEMP) {
val = clamp_val(val, 0, 127000 + fraction);
} else {
@@ -1675,11 +1687,32 @@ static const char *lm90_detect_maxim(struct i2c_client *client, int chip_id,
* The chip_id register of the MAX6646/6647/6649 holds the
* revision of the chip. The lowest 6 bits of the config1
* register are unused and should return zero when read.
+ * The I2C address of MAX6648/6692 is fixed at 0x4c.
+ * MAX6646 is at address 0x4d, MAX6647 is at address 0x4e,
+ * and MAX6649 is at address 0x4c. A slight difference between
+ * the two sets of chips is that the remote temperature register
+ * reports different values if the DXP pin is open or shorted.
+ * We can use that information to help distinguish between the
+ * chips. MAX6648 will be mis-detected as MAX6649 if the remote
+ * diode is connected, but there isn't really anything we can
+ * do about that.
*/
if (!(config1 & 0x3f) && convrate <= 0x07) {
+ int temp;
+
switch (address) {
case 0x4c:
- name = "max6649";
+ /*
+ * MAX6649 reports an external temperature
+ * value of 0xff if DXP is open or shorted.
+ * MAX6648 reports 0x80 in that case.
+ */
+ temp = i2c_smbus_read_byte_data(client,
+ LM90_REG_REMOTE_TEMPH);
+ if (temp == 0x80)
+ name = "max6648";
+ else
+ name = "max6649";
break;
case 0x4d:
name = "max6646";