Skip to content

Commit

Permalink
hwmon: (lm90) Add basic support for TI TMP461
Browse files Browse the repository at this point in the history
[ Upstream commit f8344f7 ]

TMP461 is almost identical to TMP451 and was actually detected as TMP451
with the existing lm90 driver if its I2C address is 0x4c. Add support
for it to the lm90 driver. At the same time, improve the chip detection
function to at least try to distinguish between TMP451 and TMP461.

As a side effect, this fixes commit 24333ac ("hwmon: (tmp401) use
smb word operations instead of 2 smb byte operations"). TMP461 does not
support word operations on temperature registers, which causes bad
temperature readings with the tmp401 driver. The lm90 driver does not
perform word operations on temperature registers and thus does not have
this problem.

Support is listed as basic because TMP461 supports a sensor resolution
of 0.0625 degrees C, while the lm90 driver assumes a resolution of 0.125
degrees C. Also, the TMP461 supports negative temperatures with its
default temperature range, which is not the case for similar chips
supported by the lm90 and the tmp401 drivers. Those limitations will be
addressed with follow-up patches.

Fixes: 24333ac ("hwmon: (tmp401) use smb word operations instead of 2 smb byte operations")
Reported-by: David T. Wilson <david.wilson@nasa.gov>
Cc: David T. Wilson <david.wilson@nasa.gov>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
groeck authored and gregkh committed Dec 29, 2021
1 parent fa2e149 commit 196df56
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
10 changes: 10 additions & 0 deletions Documentation/hwmon/lm90.rst
Expand Up @@ -265,6 +265,16 @@ Supported chips:

https://www.ti.com/litv/pdf/sbos686

* Texas Instruments TMP461

Prefix: 'tmp461'

Addresses scanned: I2C 0x48 through 0x4F

Datasheet: Publicly available at TI website

https://www.ti.com/lit/gpn/tmp461

Author: Jean Delvare <jdelvare@suse.de>


Expand Down
2 changes: 1 addition & 1 deletion drivers/hwmon/Kconfig
Expand Up @@ -1275,7 +1275,7 @@ config SENSORS_LM90
Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6654, MAX6657, MAX6658,
MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, MAX6696,
ON Semiconductor NCT1008, Winbond/Nuvoton W83L771W/G/AWG/ASG,
Philips SA56004, GMT G781, and Texas Instruments TMP451
Philips SA56004, GMT G781, Texas Instruments TMP451 and TMP461
sensor chips.

This driver can also be built as a module. If so, the module
Expand Down
54 changes: 39 additions & 15 deletions drivers/hwmon/lm90.c
Expand Up @@ -69,10 +69,10 @@
* This driver also supports the G781 from GMT. This device is compatible
* with the ADM1032.
*
* This driver also supports TMP451 from Texas Instruments. This device is
* supported in both compatibility and extended mode. It's mostly compatible
* with ADT7461 except for local temperature low byte register and max
* conversion rate.
* This driver also supports TMP451 and TMP461 from Texas Instruments.
* Those devices are supported in both compatibility and extended mode.
* They are mostly compatible with ADT7461 except for local temperature
* low byte register and max conversion rate.
*
* Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and
Expand Down Expand Up @@ -112,7 +112,7 @@ static const unsigned short normal_i2c[] = {
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };

enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
max6646, w83l771, max6696, sa56004, g781, tmp451, max6654 };
max6646, w83l771, max6696, sa56004, g781, tmp451, tmp461, max6654 };

/*
* The LM90 registers
Expand Down Expand Up @@ -168,8 +168,12 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,

#define LM90_MAX_CONVRATE_MS 16000 /* Maximum conversion rate in ms */

/* TMP451 registers */
/* TMP451/TMP461 registers */
#define TMP451_REG_R_LOCAL_TEMPL 0x15
#define TMP451_REG_CONALERT 0x22

#define TMP461_REG_CHEN 0x16
#define TMP461_REG_DFC 0x24

/*
* Device flags
Expand Down Expand Up @@ -229,6 +233,7 @@ static const struct i2c_device_id lm90_id[] = {
{ "w83l771", w83l771 },
{ "sa56004", sa56004 },
{ "tmp451", tmp451 },
{ "tmp461", tmp461 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm90_id);
Expand Down Expand Up @@ -326,6 +331,10 @@ static const struct of_device_id __maybe_unused lm90_of_match[] = {
.compatible = "ti,tmp451",
.data = (void *)tmp451
},
{
.compatible = "ti,tmp461",
.data = (void *)tmp461
},
{ },
};
MODULE_DEVICE_TABLE(of, lm90_of_match);
Expand Down Expand Up @@ -427,6 +436,13 @@ static const struct lm90_params lm90_params[] = {
.max_convrate = 9,
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
},
[tmp461] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
.alert_alarms = 0x7c,
.max_convrate = 9,
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
},
};

/*
Expand Down Expand Up @@ -1616,18 +1632,26 @@ static int lm90_detect(struct i2c_client *client,
&& convrate <= 0x08)
name = "g781";
} else
if (address == 0x4C
&& man_id == 0x55) { /* Texas Instruments */
int local_ext;
if (man_id == 0x55 && chip_id == 0x00 &&
(config1 & 0x1B) == 0x00 && convrate <= 0x09) {
int local_ext, conalert, chen, dfc;

local_ext = i2c_smbus_read_byte_data(client,
TMP451_REG_R_LOCAL_TEMPL);

if (chip_id == 0x00 /* TMP451 */
&& (config1 & 0x1B) == 0x00
&& convrate <= 0x09
&& (local_ext & 0x0F) == 0x00)
name = "tmp451";
conalert = i2c_smbus_read_byte_data(client,
TMP451_REG_CONALERT);
chen = i2c_smbus_read_byte_data(client, TMP461_REG_CHEN);
dfc = i2c_smbus_read_byte_data(client, TMP461_REG_DFC);

if ((local_ext & 0x0F) == 0x00 &&
(conalert & 0xf1) == 0x01 &&
(chen & 0xfc) == 0x00 &&
(dfc & 0xfc) == 0x00) {
if (address == 0x4c && !(chen & 0x03))
name = "tmp451";
else if (address >= 0x48 && address <= 0x4f)
name = "tmp461";
}
}

if (!name) { /* identification failed */
Expand Down

0 comments on commit 196df56

Please sign in to comment.