Skip to content

Commit f8344f7

Browse files
committed
hwmon: (lm90) Add basic support for TI TMP461
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 <[email protected]> Cc: David T. Wilson <[email protected]> Signed-off-by: Guenter Roeck <[email protected]>
1 parent f347e24 commit f8344f7

File tree

3 files changed

+50
-16
lines changed

3 files changed

+50
-16
lines changed

Documentation/hwmon/lm90.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ Supported chips:
265265

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

268+
* Texas Instruments TMP461
269+
270+
Prefix: 'tmp461'
271+
272+
Addresses scanned: I2C 0x48 through 0x4F
273+
274+
Datasheet: Publicly available at TI website
275+
276+
https://www.ti.com/lit/gpn/tmp461
277+
268278
Author: Jean Delvare <[email protected]>
269279

270280

drivers/hwmon/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ config SENSORS_LM90
13271327
Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6654, MAX6657, MAX6658,
13281328
MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, MAX6696,
13291329
ON Semiconductor NCT1008, Winbond/Nuvoton W83L771W/G/AWG/ASG,
1330-
Philips SA56004, GMT G781, and Texas Instruments TMP451
1330+
Philips SA56004, GMT G781, Texas Instruments TMP451 and TMP461
13311331
sensor chips.
13321332

13331333
This driver can also be built as a module. If so, the module

drivers/hwmon/lm90.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@
6969
* This driver also supports the G781 from GMT. This device is compatible
7070
* with the ADM1032.
7171
*
72-
* This driver also supports TMP451 from Texas Instruments. This device is
73-
* supported in both compatibility and extended mode. It's mostly compatible
74-
* with ADT7461 except for local temperature low byte register and max
75-
* conversion rate.
72+
* This driver also supports TMP451 and TMP461 from Texas Instruments.
73+
* Those devices are supported in both compatibility and extended mode.
74+
* They are mostly compatible with ADT7461 except for local temperature
75+
* low byte register and max conversion rate.
7676
*
7777
* Since the LM90 was the first chipset supported by this driver, most
7878
* comments will refer to this chipset, but are actually general and
@@ -112,7 +112,7 @@ static const unsigned short normal_i2c[] = {
112112
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
113113

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

117117
/*
118118
* The LM90 registers
@@ -168,8 +168,12 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
168168

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

171-
/* TMP451 registers */
171+
/* TMP451/TMP461 registers */
172172
#define TMP451_REG_R_LOCAL_TEMPL 0x15
173+
#define TMP451_REG_CONALERT 0x22
174+
175+
#define TMP461_REG_CHEN 0x16
176+
#define TMP461_REG_DFC 0x24
173177

174178
/*
175179
* Device flags
@@ -230,6 +234,7 @@ static const struct i2c_device_id lm90_id[] = {
230234
{ "w83l771", w83l771 },
231235
{ "sa56004", sa56004 },
232236
{ "tmp451", tmp451 },
237+
{ "tmp461", tmp461 },
233238
{ }
234239
};
235240
MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -327,6 +332,10 @@ static const struct of_device_id __maybe_unused lm90_of_match[] = {
327332
.compatible = "ti,tmp451",
328333
.data = (void *)tmp451
329334
},
335+
{
336+
.compatible = "ti,tmp461",
337+
.data = (void *)tmp461
338+
},
330339
{ },
331340
};
332341
MODULE_DEVICE_TABLE(of, lm90_of_match);
@@ -428,6 +437,13 @@ static const struct lm90_params lm90_params[] = {
428437
.max_convrate = 9,
429438
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
430439
},
440+
[tmp461] = {
441+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
442+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
443+
.alert_alarms = 0x7c,
444+
.max_convrate = 9,
445+
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
446+
},
431447
};
432448

433449
/*
@@ -1628,18 +1644,26 @@ static int lm90_detect(struct i2c_client *client,
16281644
&& convrate <= 0x08)
16291645
name = "g781";
16301646
} else
1631-
if (address == 0x4C
1632-
&& man_id == 0x55) { /* Texas Instruments */
1633-
int local_ext;
1647+
if (man_id == 0x55 && chip_id == 0x00 &&
1648+
(config1 & 0x1B) == 0x00 && convrate <= 0x09) {
1649+
int local_ext, conalert, chen, dfc;
16341650

16351651
local_ext = i2c_smbus_read_byte_data(client,
16361652
TMP451_REG_R_LOCAL_TEMPL);
1637-
1638-
if (chip_id == 0x00 /* TMP451 */
1639-
&& (config1 & 0x1B) == 0x00
1640-
&& convrate <= 0x09
1641-
&& (local_ext & 0x0F) == 0x00)
1642-
name = "tmp451";
1653+
conalert = i2c_smbus_read_byte_data(client,
1654+
TMP451_REG_CONALERT);
1655+
chen = i2c_smbus_read_byte_data(client, TMP461_REG_CHEN);
1656+
dfc = i2c_smbus_read_byte_data(client, TMP461_REG_DFC);
1657+
1658+
if ((local_ext & 0x0F) == 0x00 &&
1659+
(conalert & 0xf1) == 0x01 &&
1660+
(chen & 0xfc) == 0x00 &&
1661+
(dfc & 0xfc) == 0x00) {
1662+
if (address == 0x4c && !(chen & 0x03))
1663+
name = "tmp451";
1664+
else if (address >= 0x48 && address <= 0x4f)
1665+
name = "tmp461";
1666+
}
16431667
}
16441668

16451669
if (!name) { /* identification failed */

0 commit comments

Comments
 (0)