From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/hwmon/lm90.c | 344 ++++++++++++++++++++++++++++++++------------------------
1 files changed, 195 insertions(+), 149 deletions(-)
diff --git a/kernel/drivers/hwmon/lm90.c b/kernel/drivers/hwmon/lm90.c
index 033c89f..a7142c3 100644
--- a/kernel/drivers/hwmon/lm90.c
+++ b/kernel/drivers/hwmon/lm90.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* lm90.c - Part of lm_sensors, Linux kernel modules for hardware
* monitoring
@@ -34,6 +35,15 @@
* explicitly as max6659, or if its address is not 0x4c.
* These chips lack the remote temperature offset feature.
*
+ * This driver also supports the MAX6654 chip made by Maxim. This chip can be
+ * at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is similar
+ * to MAX6657/MAX6658/MAX6659, but does not support critical temperature
+ * limits. Extended range is available by setting the configuration register
+ * accordingly, and is done during initialization. Extended precision is only
+ * available at conversion rates of 1 Hz and slower. Note that extended
+ * precision is not enabled by default, as this driver initializes all chips
+ * to 2 Hz by design.
+ *
* This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
* MAX6692 chips made by Maxim. These are again similar to the LM86,
* but they use unsigned temperature values and can report temperatures
@@ -60,28 +70,14 @@
* 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
* concern all supported chipsets, unless mentioned otherwise.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
@@ -107,8 +103,8 @@
* have address 0x4d.
* MAX6647 has address 0x4e.
* MAX6659 can have address 0x4c, 0x4d or 0x4e.
- * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
- * 0x4c, 0x4d or 0x4e.
+ * MAX6654, MAX6680, and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29,
+ * 0x2a, 0x2b, 0x4c, 0x4d or 0x4e.
* SA56004 can have address 0x48 through 0x4F.
*/
@@ -117,7 +113,7 @@
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
- max6646, w83l771, max6696, sa56004, g781, tmp451 };
+ max6646, w83l771, max6696, sa56004, g781, tmp451, tmp461, max6654 };
/*
* The LM90 registers
@@ -158,7 +154,7 @@
#define LM90_REG_R_TCRIT_HYST 0x21
#define LM90_REG_W_TCRIT_HYST 0x21
-/* MAX6646/6647/6649/6657/6658/6659/6695/6696 registers */
+/* MAX6646/6647/6649/6654/6657/6658/6659/6695/6696 registers */
#define MAX6657_REG_R_LOCAL_TEMPL 0x11
#define MAX6696_REG_R_STATUS2 0x12
@@ -173,8 +169,12 @@
#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
@@ -187,7 +187,10 @@
#define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */
#define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */
#define LM90_HAVE_BROKEN_ALERT (1 << 7) /* Broken alert */
-#define LM90_PAUSE_FOR_CONFIG (1 << 8) /* Pause conversion for config */
+#define LM90_HAVE_EXTENDED_TEMP (1 << 8) /* extended temperature support*/
+#define LM90_PAUSE_FOR_CONFIG (1 << 9) /* Pause conversion for config */
+#define LM90_HAVE_CRIT (1 << 10)/* Chip supports CRIT/OVERT register */
+#define LM90_HAVE_CRIT_ALRM_SWP (1 << 11)/* critical alarm bits swapped */
/* LM90 status */
#define LM90_STATUS_LTHRM (1 << 0) /* local THERM limit tripped */
@@ -223,6 +226,7 @@
{ "max6646", max6646 },
{ "max6647", max6646 },
{ "max6649", max6646 },
+ { "max6654", max6654 },
{ "max6657", max6657 },
{ "max6658", max6657 },
{ "max6659", max6659 },
@@ -234,11 +238,12 @@
{ "w83l771", w83l771 },
{ "sa56004", sa56004 },
{ "tmp451", tmp451 },
+ { "tmp461", tmp461 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm90_id);
-static const struct of_device_id lm90_of_match[] = {
+static const struct of_device_id __maybe_unused lm90_of_match[] = {
{
.compatible = "adi,adm1032",
.data = (void *)adm1032
@@ -284,6 +289,10 @@
.data = (void *)max6646
},
{
+ .compatible = "dallas,max6654",
+ .data = (void *)max6654
+ },
+ {
.compatible = "dallas,max6657",
.data = (void *)max6657
},
@@ -327,6 +336,10 @@
.compatible = "ti,tmp451",
.data = (void *)tmp451
},
+ {
+ .compatible = "ti,tmp461",
+ .data = (void *)tmp461
+ },
{ },
};
MODULE_DEVICE_TABLE(of, lm90_of_match);
@@ -345,80 +358,99 @@
static const struct lm90_params lm90_params[] = {
[adm1032] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
- | LM90_HAVE_BROKEN_ALERT,
+ | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 10,
},
[adt7461] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
- | LM90_HAVE_BROKEN_ALERT,
+ | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP
+ | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 10,
},
[g781] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
- | LM90_HAVE_BROKEN_ALERT,
+ | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 7,
},
[lm86] = {
- .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
+ | LM90_HAVE_CRIT,
.alert_alarms = 0x7b,
.max_convrate = 9,
},
[lm90] = {
- .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
+ | LM90_HAVE_CRIT,
.alert_alarms = 0x7b,
.max_convrate = 9,
},
[lm99] = {
- .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
+ | LM90_HAVE_CRIT,
.alert_alarms = 0x7b,
.max_convrate = 9,
},
[max6646] = {
+ .flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT,
.alert_alarms = 0x7c,
.max_convrate = 6,
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
},
+ [max6654] = {
+ .flags = LM90_HAVE_BROKEN_ALERT,
+ .alert_alarms = 0x7c,
+ .max_convrate = 7,
+ .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
+ },
[max6657] = {
- .flags = LM90_PAUSE_FOR_CONFIG,
+ .flags = LM90_PAUSE_FOR_CONFIG | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 8,
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
},
[max6659] = {
- .flags = LM90_HAVE_EMERGENCY,
+ .flags = LM90_HAVE_EMERGENCY | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 8,
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
},
[max6680] = {
- .flags = LM90_HAVE_OFFSET,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT
+ | LM90_HAVE_CRIT_ALRM_SWP | LM90_HAVE_BROKEN_ALERT,
.alert_alarms = 0x7c,
.max_convrate = 7,
},
[max6696] = {
.flags = LM90_HAVE_EMERGENCY
- | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3,
+ | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3 | LM90_HAVE_CRIT,
.alert_alarms = 0x1c7c,
.max_convrate = 6,
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
},
[w83l771] = {
- .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 8,
},
[sa56004] = {
- .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
+ .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
.alert_alarms = 0x7b,
.max_convrate = 9,
.reg_local_ext = SA56004_REG_R_LOCAL_TEMPL,
},
[tmp451] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
- | LM90_HAVE_BROKEN_ALERT,
+ | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
+ .alert_alarms = 0x7c,
+ .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 | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 9,
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
@@ -473,6 +505,7 @@
unsigned int update_interval; /* in milliseconds */
+ u8 config; /* Current configuration register value */
u8 config_orig; /* Original configuration register value */
u8 convrate_orig; /* Original conversion rate register value */
u16 alert_alarms; /* Which alarm bits trigger ALERT# */
@@ -556,6 +589,21 @@
return (newh << 8) | l;
}
+static int lm90_update_confreg(struct lm90_data *data, u8 config)
+{
+ if (data->config != config) {
+ int err;
+
+ err = i2c_smbus_write_byte_data(data->client,
+ LM90_REG_W_CONFIG1,
+ config);
+ if (err)
+ return err;
+ data->config = config;
+ }
+ return 0;
+}
+
/*
* client->update_lock must be held when calling this function (unless we are
* in detection or initialization steps), and while a remote channel other
@@ -564,53 +612,37 @@
* various registers have different meanings as a result of selecting a
* non-default remote channel.
*/
-static inline int lm90_select_remote_channel(struct i2c_client *client,
- struct lm90_data *data,
- int channel)
+static int lm90_select_remote_channel(struct lm90_data *data, int channel)
{
- int config;
+ int err = 0;
if (data->kind == max6696) {
- config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
- if (config < 0)
- return config;
- config &= ~0x08;
+ u8 config = data->config & ~0x08;
+
if (channel)
config |= 0x08;
- i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
- config);
+ err = lm90_update_confreg(data, config);
}
- return 0;
+ return err;
}
-static int lm90_write_convrate(struct i2c_client *client,
- struct lm90_data *data, int val)
+static int lm90_write_convrate(struct lm90_data *data, int val)
{
+ u8 config = data->config;
int err;
- int config_orig, config_stop;
/* Save config and pause conversion */
if (data->flags & LM90_PAUSE_FOR_CONFIG) {
- config_orig = lm90_read_reg(client, LM90_REG_R_CONFIG1);
- if (config_orig < 0)
- return config_orig;
- config_stop = config_orig | 0x40;
- if (config_orig != config_stop) {
- err = i2c_smbus_write_byte_data(client,
- LM90_REG_W_CONFIG1,
- config_stop);
- if (err < 0)
- return err;
- }
+ err = lm90_update_confreg(data, config | 0x40);
+ if (err < 0)
+ return err;
}
/* Set conv rate */
- err = i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, val);
+ err = i2c_smbus_write_byte_data(data->client, LM90_REG_W_CONVRATE, val);
/* Revert change to config */
- if (data->flags & LM90_PAUSE_FOR_CONFIG && config_orig != config_stop)
- i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
- config_orig);
+ lm90_update_confreg(data, config);
return err;
}
@@ -635,7 +667,7 @@
if (interval >= update_interval * 3 / 4)
break;
- err = lm90_write_convrate(client, data, i);
+ err = lm90_write_convrate(data, i);
data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64);
return err;
}
@@ -646,20 +678,22 @@
struct i2c_client *client = data->client;
int val;
- val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
- if (val < 0)
- return val;
- data->temp8[LOCAL_CRIT] = val;
+ if (data->flags & LM90_HAVE_CRIT) {
+ val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
+ if (val < 0)
+ return val;
+ data->temp8[LOCAL_CRIT] = val;
- val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
- if (val < 0)
- return val;
- data->temp8[REMOTE_CRIT] = val;
+ val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
+ if (val < 0)
+ return val;
+ data->temp8[REMOTE_CRIT] = val;
- val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
- if (val < 0)
- return val;
- data->temp_hyst = val;
+ val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
+ if (val < 0)
+ return val;
+ data->temp_hyst = val;
+ }
val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
if (val < 0)
@@ -706,7 +740,7 @@
}
if (data->kind == max6696) {
- val = lm90_select_remote_channel(client, data, 1);
+ val = lm90_select_remote_channel(data, 1);
if (val < 0)
return val;
@@ -730,7 +764,7 @@
return val;
data->temp11[REMOTE2_HIGH] = val << 8;
- lm90_select_remote_channel(client, data, 0);
+ lm90_select_remote_channel(data, 0);
}
return 0;
@@ -790,19 +824,19 @@
data->alarms = val & ~LM90_STATUS_BUSY;
if (data->kind == max6696) {
- val = lm90_select_remote_channel(client, data, 1);
+ val = lm90_select_remote_channel(data, 1);
if (val < 0)
return val;
val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
LM90_REG_R_REMOTE_TEMPL);
if (val < 0) {
- lm90_select_remote_channel(client, data, 0);
+ lm90_select_remote_channel(data, 0);
return val;
}
data->temp11[REMOTE2_TEMP] = val;
- lm90_select_remote_channel(client, data, 0);
+ lm90_select_remote_channel(data, 0);
val = lm90_read_reg(client, MAX6696_REG_R_STATUS2);
if (val < 0)
@@ -816,15 +850,9 @@
*/
if (!(data->config_orig & 0x80) &&
!(data->alarms & data->alert_alarms)) {
- val = lm90_read_reg(client, LM90_REG_R_CONFIG1);
- if (val < 0)
- return val;
-
- if (val & 0x80) {
+ if (data->config & 0x80) {
dev_dbg(&client->dev, "Re-enabling ALERT#\n");
- i2c_smbus_write_byte_data(client,
- LM90_REG_W_CONFIG1,
- val & ~0x80);
+ lm90_update_confreg(data, data->config & ~0x80);
}
}
@@ -999,7 +1027,7 @@
s16 temp11 = data->temp11[index];
int temp;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u16_adt7461(data, temp11);
else if (data->kind == max6646)
temp = temp_from_u16(temp11);
@@ -1033,7 +1061,7 @@
if (data->kind == lm99 && index <= 2)
val -= 16000;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
data->temp11[index] = temp_to_u16_adt7461(data, val);
else if (data->kind == max6646)
data->temp11[index] = temp_to_u8(val) << 8;
@@ -1042,7 +1070,7 @@
else
data->temp11[index] = temp_to_s8(val) << 8;
- lm90_select_remote_channel(client, data, index >= 3);
+ lm90_select_remote_channel(data, index >= 3);
err = i2c_smbus_write_byte_data(client, regp->high,
data->temp11[index] >> 8);
if (err < 0)
@@ -1051,7 +1079,7 @@
err = i2c_smbus_write_byte_data(client, regp->low,
data->temp11[index] & 0xff);
- lm90_select_remote_channel(client, data, 0);
+ lm90_select_remote_channel(data, 0);
return err;
}
@@ -1060,7 +1088,7 @@
s8 temp8 = data->temp8[index];
int temp;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, temp8);
else if (data->kind == max6646)
temp = temp_from_u8(temp8);
@@ -1093,16 +1121,16 @@
if (data->kind == lm99 && index == 3)
val -= 16000;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
data->temp8[index] = temp_to_u8_adt7461(data, val);
else if (data->kind == max6646)
data->temp8[index] = temp_to_u8(val);
else
data->temp8[index] = temp_to_s8(val);
- lm90_select_remote_channel(client, data, index >= 6);
+ lm90_select_remote_channel(data, index >= 6);
err = i2c_smbus_write_byte_data(client, reg[index], data->temp8[index]);
- lm90_select_remote_channel(client, data, 0);
+ lm90_select_remote_channel(data, 0);
return err;
}
@@ -1111,7 +1139,7 @@
{
int temp;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, data->temp8[index]);
else if (data->kind == max6646)
temp = temp_from_u8(data->temp8[index]);
@@ -1131,7 +1159,7 @@
int temp;
int err;
- if (data->kind == adt7461 || data->kind == tmp451)
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]);
else if (data->kind == max6646)
temp = temp_from_u8(data->temp8[LOCAL_CRIT]);
@@ -1167,6 +1195,7 @@
static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 };
static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 };
static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 };
+static const u8 lm90_crit_alarm_bits_swapped[3] = { 1, 0, 9 };
static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 };
static const u8 lm90_fault_bits[3] = { 0, 2, 10 };
@@ -1192,7 +1221,10 @@
*val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1;
break;
case hwmon_temp_crit_alarm:
- *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
+ if (data->flags & LM90_HAVE_CRIT_ALRM_SWP)
+ *val = (data->alarms >> lm90_crit_alarm_bits_swapped[channel]) & 1;
+ else
+ *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
break;
case hwmon_temp_emergency_alarm:
*val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1;
@@ -1301,17 +1333,17 @@
case hwmon_temp_emergency_alarm:
case hwmon_temp_emergency_hyst:
case hwmon_temp_fault:
- return S_IRUGO;
+ return 0444;
case hwmon_temp_min:
case hwmon_temp_max:
case hwmon_temp_crit:
case hwmon_temp_emergency:
case hwmon_temp_offset:
- return S_IRUGO | S_IWUSR;
+ return 0644;
case hwmon_temp_crit_hyst:
if (channel == 0)
- return S_IRUGO | S_IWUSR;
- return S_IRUGO;
+ return 0644;
+ return 0444;
default:
return 0;
}
@@ -1373,9 +1405,9 @@
{
switch (attr) {
case hwmon_chip_update_interval:
- return S_IRUGO | S_IWUSR;
+ return 0644;
case hwmon_chip_alarms:
- return S_IRUGO;
+ return 0444;
default:
return 0;
}
@@ -1576,6 +1608,16 @@
&& (config1 & 0x3f) == 0x00
&& convrate <= 0x07) {
name = "max6646";
+ } else
+ /*
+ * The chip_id of the MAX6654 holds the revision of the chip.
+ * The lowest 3 bits of the config1 register are unused and
+ * should return zero when read.
+ */
+ if (chip_id == 0x08
+ && (config1 & 0x07) == 0x00
+ && convrate <= 0x07) {
+ name = "max6654";
}
} else
if (address == 0x4C
@@ -1608,18 +1650,26 @@
&& 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);
+ 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 (chip_id == 0x00 /* TMP451 */
- && (config1 & 0x1B) == 0x00
- && convrate <= 0x09
- && (local_ext & 0x0F) == 0x00)
- name = "tmp451";
+ 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 */
@@ -1640,7 +1690,7 @@
struct i2c_client *client = data->client;
/* Restore initial configuration */
- lm90_write_convrate(client, data, data->convrate_orig);
+ lm90_write_convrate(data, data->convrate_orig);
i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
data->config_orig);
}
@@ -1661,11 +1711,12 @@
if (config < 0)
return config;
data->config_orig = config;
+ data->config = config;
lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */
/* Check Temperature Range Select */
- if (data->kind == adt7461 || data->kind == tmp451) {
+ if (data->flags & LM90_HAVE_EXTENDED_TEMP) {
if (config & 0x04)
data->flags |= LM90_FLAG_ADT7461_EXT;
}
@@ -1679,14 +1730,22 @@
config |= 0x18;
/*
+ * Put MAX6654 into extended range (0x20, extend minimum range from
+ * 0 degrees to -64 degrees). Note that extended resolution is not
+ * possible on the MAX6654 unless conversion rate is set to 1 Hz or
+ * slower, which is intentionally not done by default.
+ */
+ if (data->kind == max6654)
+ config |= 0x20;
+
+ /*
* Select external channel 0 for max6695/96
*/
if (data->kind == max6696)
config &= ~0x08;
config &= 0xBF; /* run */
- if (config != data->config_orig) /* Only write if changed */
- i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
+ lm90_update_confreg(data, config);
return devm_add_action_or_reset(&client->dev, lm90_restore_conf, data);
}
@@ -1754,16 +1813,6 @@
regulator_disable(regulator);
}
-static const u32 lm90_chip_config[] = {
- HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS,
- 0
-};
-
-static const struct hwmon_channel_info lm90_chip_info = {
- .type = hwmon_chip,
- .config = lm90_chip_config,
-};
-
static const struct hwmon_ops lm90_ops = {
.is_visible = lm90_is_visible,
@@ -1771,11 +1820,10 @@
.write = lm90_write,
};
-static int lm90_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm90_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
- struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
+ struct i2c_adapter *adapter = client->adapter;
struct hwmon_channel_info *info;
struct regulator *regulator;
struct device *hwmon_dev;
@@ -1808,7 +1856,7 @@
if (client->dev.of_node)
data->kind = (enum chips)of_device_get_match_data(&client->dev);
else
- data->kind = id->driver_data;
+ data->kind = i2c_match_id(lm90_id, client)->driver_data;
if (data->kind == adm1032) {
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
client->flags &= ~I2C_CLIENT_PEC;
@@ -1826,7 +1874,8 @@
data->chip.ops = &lm90_ops;
data->chip.info = data->info;
- data->info[0] = &lm90_chip_info;
+ data->info[0] = HWMON_CHANNEL_INFO(chip,
+ HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS);
data->info[1] = &data->temp_info;
info = &data->temp_info;
@@ -1834,11 +1883,14 @@
info->config = data->channel_config;
data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM;
+ HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM;
data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;
+ HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_FAULT;
+
+ if (data->flags & LM90_HAVE_CRIT) {
+ data->channel_config[0] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
+ data->channel_config[1] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
+ }
if (data->flags & LM90_HAVE_OFFSET)
data->channel_config[1] |= HWMON_T_OFFSET;
@@ -1929,14 +1981,8 @@
if ((data->flags & LM90_HAVE_BROKEN_ALERT) &&
(alarms & data->alert_alarms)) {
- int config;
-
dev_dbg(&client->dev, "Disabling ALERT#\n");
- config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
- if (config >= 0)
- i2c_smbus_write_byte_data(client,
- LM90_REG_W_CONFIG1,
- config | 0x80);
+ lm90_update_confreg(data, data->config | 0x80);
}
} else {
dev_info(&client->dev, "Everything OK\n");
@@ -1949,7 +1995,7 @@
.name = "lm90",
.of_match_table = of_match_ptr(lm90_of_match),
},
- .probe = lm90_probe,
+ .probe_new = lm90_probe,
.alert = lm90_alert,
.id_table = lm90_id,
.detect = lm90_detect,
--
Gitblit v1.6.2