From: Liviu Stan <liviu.stan@analog.com>
To: "Lars-Peter Clausen" <lars@metafoo.de>,
"Michael Hennerich" <Michael.Hennerich@analog.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Jonathan Cameron" <jic23@kernel.org>,
"David Lechner" <dlechner@baylibre.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: Liviu Stan <liviu.stan@analog.com>
Subject: [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604
Date: Mon, 27 Apr 2026 16:25:08 +0300 [thread overview]
Message-ID: <20260427132526.272716-3-liviu.stan@analog.com> (raw)
In-Reply-To: <20260427132526.272716-1-liviu.stan@analog.com>
The ADT7604 shares the same die as the LTC2984. It repurposes the
custom RTD sensor type (18) as a copper trace resistance sensor
and the custom thermistor type (27) as a leak detector, and
removes thermocouple, diode and direct ADC sensor types.
Custom RTD (type 18) becomes the copper trace sensor. Sensor
configuration bits 21:18 are hardcoded to 0b1001 per the
datasheet. Two variants are supported via the new
adi,copper-trace-sub-ohm DT property: sub-ohm traces (< 1 ohm)
have bits 17:0 cleared with no excitation current or custom
table; standard traces (> 1 ohm) accept an optional
resistance-to-temperature table.
Custom thermistor (type 27) becomes the leak detector. Sensor
configuration bits are hardcoded to 0b001. The custom table
uses a resolution of 16 (20+4 bit resistance field) instead of
64, and is specified via the new adi,custom-leak-detector DT
property.
Both sensor types expose an IIO_RESISTANCE channel reading from
the resistance result register bank (0x060-0x00AF), added to
the regmap readable ranges. Scales are 1/1,024,000 for copper
trace (result in mOhm) and 1/1024 for leak detector (result
in Ohm).
A has_copper_trace capability flag is introduced in
ltc2983_chip_info to identify the ADT7604, following the
existing has_temp and has_eeprom pattern.
Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
drivers/iio/temperature/ltc2983.c | 347 +++++++++++++++++++++---------
1 file changed, 251 insertions(+), 96 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 38e6f8dfd3b8..1966f6fb0305 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -28,6 +28,8 @@
#define LTC2983_STATUS_REG 0x0000
#define LTC2983_TEMP_RES_START_REG 0x0010
#define LTC2983_TEMP_RES_END_REG 0x005F
+#define ADT7604_RES_RES_START_REG 0x0060
+#define ADT7604_RES_RES_END_REG 0x00AF
#define LTC2983_EEPROM_KEY_REG 0x00B0
#define LTC2983_EEPROM_READ_STATUS_REG 0x00D0
#define LTC2983_GLOBAL_CONFIG_REG 0x00F0
@@ -58,8 +60,8 @@
#define LTC2983_CHAN_START_ADDR(chan) \
(((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
-#define LTC2983_CHAN_RES_ADDR(chan) \
- (((chan - 1) * 4) + LTC2983_TEMP_RES_START_REG)
+#define LTC2983_CHAN_RES_ADDR(chan, base) \
+ ((((chan) - 1) * 4) + (base))
#define LTC2983_THERMOCOUPLE_DIFF_MASK BIT(3)
#define LTC2983_THERMOCOUPLE_SGL(x) \
FIELD_PREP(LTC2983_THERMOCOUPLE_DIFF_MASK, x)
@@ -214,6 +216,7 @@ struct ltc2983_chip_info {
unsigned int max_channels_nr;
bool has_temp;
bool has_eeprom;
+ bool has_copper_trace;
};
struct ltc2983_data {
@@ -272,6 +275,7 @@ struct ltc2983_rtd {
u32 r_sense_chan;
u32 excitation_current;
u32 rtd_curve;
+ bool sub_ohm;
};
struct ltc2983_thermistor {
@@ -575,6 +579,10 @@ static int ltc2983_rtd_assign_chan(struct ltc2983_data *st,
if (ret)
return ret;
}
+
+ if (rtd->sub_ohm)
+ chan_val &= ~GENMASK(17, 0);
+
return __ltc2983_chan_assign_common(st, sensor, chan_val);
}
@@ -758,83 +766,113 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
return dev_err_ptr_probe(dev, ret,
"Property reg must be given\n");
- ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
- if (!ret) {
- switch (n_wires) {
- case 2:
- rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
- break;
- case 3:
- rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
- break;
- case 4:
- rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
- break;
- case 5:
- /* 4 wires, Kelvin Rsense */
- rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
- break;
- default:
+ /* ADT7604 requires hardcoding sensor configuration bits to 0b1001 */
+ if (st->info->has_copper_trace &&
+ sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
+ rtd->sensor_config = 0x9;
+ if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid number of wires:%u\n",
- n_wires);
+ "Invalid chann:%d for copper trace\n",
+ sensor->chan);
+ } else {
+ ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
+ if (!ret) {
+ switch (n_wires) {
+ case 2:
+ rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
+ break;
+ case 3:
+ rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
+ break;
+ case 4:
+ rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
+ break;
+ case 5:
+ /* 4 wires, Kelvin Rsense */
+ rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
+ break;
+ default:
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid number of wires:%u\n",
+ n_wires);
+ }
}
- }
- if (fwnode_property_read_bool(child, "adi,rsense-share")) {
- /* Current rotation is only available with rsense sharing */
- if (fwnode_property_read_bool(child, "adi,current-rotate")) {
- if (n_wires == 2 || n_wires == 3)
+ if (fwnode_property_read_bool(child, "adi,rsense-share")) {
+ /* Current rotation is only available with rsense sharing */
+ if (fwnode_property_read_bool(child, "adi,current-rotate")) {
+ if (n_wires == 2 || n_wires == 3)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Rotation not allowed for 2/3 Wire RTDs\n");
+
+ rtd->sensor_config |= LTC2983_RTD_C_ROTATE(1);
+ } else {
+ rtd->sensor_config |= LTC2983_RTD_R_SHARE(1);
+ }
+ }
+ /*
+ * rtd channel indexes are a bit more complicated to validate.
+ * For 4wire RTD with rotation, the channel selection cannot be
+ * >=19 since the chann + 1 is used in this configuration.
+ * For 4wire RTDs with kelvin rsense, the rsense channel cannot be
+ * <=1 since chanel - 1 and channel - 2 are used.
+ */
+ if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
+ /* 4-wire */
+ u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
+ max = st->info->max_channels_nr;
+
+ if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
+ max = st->info->max_channels_nr - 1;
+
+ if ((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
+ == LTC2983_RTD_KELVIN_R_SENSE_MASK &&
+ rtd->r_sense_chan <= min)
+ /* kelvin rsense*/
return dev_err_ptr_probe(dev, -EINVAL,
- "Rotation not allowed for 2/3 Wire RTDs\n");
+ "Invalid rsense chann:%d to use in kelvin rsense\n",
+ rtd->r_sense_chan);
- rtd->sensor_config |= LTC2983_RTD_C_ROTATE(1);
+ if (sensor->chan < min || sensor->chan > max)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid chann:%d for the rtd config\n",
+ sensor->chan);
} else {
- rtd->sensor_config |= LTC2983_RTD_R_SHARE(1);
+ /* same as differential case */
+ if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+ return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ "Invalid chann:%d for RTD\n",
+ sensor->chan);
}
}
- /*
- * rtd channel indexes are a bit more complicated to validate.
- * For 4wire RTD with rotation, the channel selection cannot be
- * >=19 since the chann + 1 is used in this configuration.
- * For 4wire RTDs with kelvin rsense, the rsense channel cannot be
- * <=1 since channel - 1 and channel - 2 are used.
- */
- if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
- /* 4-wire */
- u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
- max = st->info->max_channels_nr;
-
- if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
- max = st->info->max_channels_nr - 1;
-
- if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
- == LTC2983_RTD_KELVIN_R_SENSE_MASK) &&
- (rtd->r_sense_chan <= min))
- /* kelvin rsense*/
- return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid rsense chann:%d to use in kelvin rsense\n",
- rtd->r_sense_chan);
-
- if (sensor->chan < min || sensor->chan > max)
- return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for the rtd config\n",
- sensor->chan);
- } else {
- /* same as differential case */
- if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
- "Invalid chann:%d for RTD\n",
- sensor->chan);
- }
/* check custom sensor */
if (sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
- rtd->custom = __ltc2983_custom_sensor_new(st, child,
- "adi,custom-rtd",
- false, 2048, false);
- if (IS_ERR(rtd->custom))
- return ERR_CAST(rtd->custom);
+ if (st->info->has_copper_trace) {
+ if (fwnode_property_present(child, "adi,custom-rtd")) {
+ rtd->custom = __ltc2983_custom_sensor_new(st, child,
+ "adi,custom-rtd",
+ false, 2048,
+ false);
+ if (IS_ERR(rtd->custom))
+ return ERR_CAST(rtd->custom);
+ }
+ } else {
+ rtd->custom = __ltc2983_custom_sensor_new(st, child,
+ "adi,custom-rtd",
+ false, 2048, false);
+ if (IS_ERR(rtd->custom))
+ return ERR_CAST(rtd->custom);
+ }
+ }
+
+ if (st->info->has_copper_trace &&
+ sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
+ rtd->sub_ohm = fwnode_property_read_bool(child,
+ "adi,copper-trace-sub-ohm");
+ if (rtd->sub_ohm && rtd->custom)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "sub-ohm copper trace cannot have a custom table\n");
}
/* set common parameters */
@@ -908,17 +946,27 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
return dev_err_ptr_probe(dev, ret,
"rsense channel must be configured...\n");
- if (fwnode_property_read_bool(child, "adi,single-ended")) {
- thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
- } else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
- /* rotation is only possible if sharing rsense */
- if (fwnode_property_read_bool(child, "adi,current-rotate"))
- thermistor->sensor_config =
- LTC2983_THERMISTOR_C_ROTATE(1);
- else
- thermistor->sensor_config =
- LTC2983_THERMISTOR_R_SHARE(1);
+ if (st->info->has_copper_trace &&
+ sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
+ thermistor->sensor_config = LTC2983_THERMISTOR_C_ROTATE(1);
+ if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid chann:%d for leak detector\n",
+ sensor->chan);
+ } else {
+ if (fwnode_property_read_bool(child, "adi,single-ended")) {
+ thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
+ } else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
+ /* rotation is only possible if sharing rsense */
+ if (fwnode_property_read_bool(child, "adi,current-rotate"))
+ thermistor->sensor_config =
+ LTC2983_THERMISTOR_C_ROTATE(1);
+ else
+ thermistor->sensor_config =
+ LTC2983_THERMISTOR_R_SHARE(1);
+ }
}
+
/* validate channel index */
if (!(thermistor->sensor_config & LTC2983_THERMISTOR_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
@@ -928,23 +976,36 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
/* check custom sensor */
if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART) {
- bool steinhart = false;
- const char *propname;
-
- if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
- steinhart = true;
- propname = "adi,custom-steinhart";
+ if (st->info->has_copper_trace &&
+ sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
+ if (fwnode_property_present(child, "adi,custom-leak-detector")) {
+ thermistor->custom =
+ __ltc2983_custom_sensor_new(st, child,
+ "adi,custom-leak-detector",
+ false, 16, false);
+ if (IS_ERR(thermistor->custom))
+ return ERR_CAST(thermistor->custom);
+ }
} else {
- propname = "adi,custom-thermistor";
+ bool steinhart = false;
+ const char *propname;
+
+ if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
+ steinhart = true;
+ propname = "adi,custom-steinhart";
+ } else {
+ propname = "adi,custom-thermistor";
+ }
+
+ thermistor->custom = __ltc2983_custom_sensor_new(st, child,
+ propname,
+ steinhart,
+ 64, false);
+ if (IS_ERR(thermistor->custom))
+ return ERR_CAST(thermistor->custom);
}
-
- thermistor->custom = __ltc2983_custom_sensor_new(st, child,
- propname,
- steinhart,
- 64, false);
- if (IS_ERR(thermistor->custom))
- return ERR_CAST(thermistor->custom);
}
+
/* set common parameters */
thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan;
@@ -1167,7 +1228,8 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
}
static int ltc2983_chan_read(struct ltc2983_data *st,
- const struct ltc2983_sensor *sensor, int *val)
+ const struct ltc2983_sensor *sensor,
+ u32 base_reg, int *val)
{
u32 start_conversion = 0;
int ret;
@@ -1197,13 +1259,23 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
}
/* read the converted data */
- ret = regmap_bulk_read(st->regmap, LTC2983_CHAN_RES_ADDR(sensor->chan),
+ ret = regmap_bulk_read(st->regmap, LTC2983_CHAN_RES_ADDR(sensor->chan, base_reg),
&st->temp, sizeof(st->temp));
if (ret)
return ret;
*val = __be32_to_cpu(st->temp);
+ if (base_reg == ADT7604_RES_RES_START_REG) {
+ /*
+ * Resistance result register gives a plain unsigned value,
+ * D31 is always 0, no valid bit, no fault bits. Read bits[30:0]
+ * directly — the temperature result format does not apply here.
+ */
+ *val &= GENMASK(30, 0);
+ return 0;
+ }
+
if (!(LTC2983_RES_VALID_MASK & *val)) {
dev_err(&st->spi->dev, "Invalid conversion detected\n");
return -EIO;
@@ -1214,6 +1286,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
return ret;
*val = sign_extend32((*val) & LTC2983_DATA_MASK, LTC2983_DATA_SIGN_BIT);
+
return 0;
}
@@ -1234,7 +1307,12 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
- ret = ltc2983_chan_read(st, st->sensors[chan->address], val);
+ if (chan->type == IIO_RESISTANCE)
+ ret = ltc2983_chan_read(st, st->sensors[chan->address],
+ ADT7604_RES_RES_START_REG, val);
+ else
+ ret = ltc2983_chan_read(st, st->sensors[chan->address],
+ LTC2983_TEMP_RES_START_REG, val);
mutex_unlock(&st->lock);
return ret ?: IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
@@ -1251,6 +1329,18 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
/* 2^21 */
*val2 = 2097152;
return IIO_VAL_FRACTIONAL;
+ case IIO_RESISTANCE:
+ /* value in ohm */
+ *val = 1;
+ /*
+ * Copper trace result is in milliohm with 10 fractional
+ * bits: divide by 2^10 * 1000 = 1024000.
+ * Leak detector result is in ohm with 10 fractional
+ * bits: divide by 2^10 = 1024.
+ */
+ *val2 = (st->sensors[chan->address]->type == LTC2983_SENSOR_RTD_CUSTOM) ?
+ 1024000 : 1024;
+ return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
@@ -1292,6 +1382,17 @@ static irqreturn_t ltc2983_irq_handler(int irq, void *data)
__chan; \
})
+#define LTC2983_RESISTANCE_CHAN(index, __address) ({ \
+ struct iio_chan_spec __chan = { \
+ .type = IIO_RESISTANCE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
+ .address = __address, \
+ }; \
+ __chan; \
+})
+
static int ltc2983_parse_fw(struct ltc2983_data *st)
{
struct device *dev = &st->spi->dev;
@@ -1339,6 +1440,16 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
return dev_err_probe(dev, ret,
"adi,sensor-type property must given for child nodes\n");
+ if (st->info->has_copper_trace) {
+ if ((sensor.type >= LTC2983_SENSOR_THERMOCOUPLE &&
+ sensor.type <= LTC2983_SENSOR_THERMOCOUPLE_CUSTOM) ||
+ sensor.type == LTC2983_SENSOR_DIODE ||
+ sensor.type == LTC2983_SENSOR_DIRECT_ADC)
+ return dev_err_probe(dev, -EINVAL,
+ "sensor type %d not supported on %s\n",
+ sensor.type, st->info->name);
+ }
+
dev_dbg(dev, "Create new sensor, type %u, chann %u",
sensor.type, sensor.chan);
@@ -1380,6 +1491,15 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
st->sensors[chan]->chan = sensor.chan;
st->sensors[chan]->type = sensor.type;
+ if (st->info->has_copper_trace) {
+ if (st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
+ to_thermistor(st->sensors[chan])->custom)
+ st->iio_channels++;
+ else if (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
+ to_rtd(st->sensors[chan])->custom)
+ st->iio_channels++;
+ }
+
channel_avail_mask |= BIT(sensor.chan);
chan++;
}
@@ -1426,7 +1546,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
{
- u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
+ u32 iio_chan_t = 0, iio_chan_v = 0, iio_chan_r = 0, chan, iio_idx = 0, status;
int ret;
/* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
@@ -1473,6 +1593,26 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
!assign_iio)
continue;
+ /*
+ * Copper trace and leak detector sensors without a custom table
+ * produce only a resistance result; the chip does not populate
+ * the temperature result register. Emit only an IIO_RESISTANCE
+ * channel in this case.
+ */
+ if (st->info->has_copper_trace) {
+ bool resistance_only =
+ (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
+ !to_rtd(st->sensors[chan])->custom) ||
+ (st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
+ !to_thermistor(st->sensors[chan])->custom);
+
+ if (resistance_only) {
+ st->iio_chan[iio_idx++] =
+ LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);
+ continue;
+ }
+ }
+
/* assign iio channel */
if (st->sensors[chan]->type != LTC2983_SENSOR_DIRECT_ADC) {
chan_type = IIO_TEMP;
@@ -1488,6 +1628,11 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
*/
st->iio_chan[iio_idx++] = LTC2983_CHAN(chan_type, (*iio_chan)++,
chan);
+
+ if (st->info->has_copper_trace &&
+ (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM ||
+ st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM))
+ st->iio_chan[iio_idx++] = LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);
}
return 0;
@@ -1496,6 +1641,7 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
static const struct regmap_range ltc2983_reg_ranges[] = {
regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG),
regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG),
+ regmap_reg_range(ADT7604_RES_RES_START_REG, ADT7604_RES_RES_END_REG),
regmap_reg_range(LTC2983_EEPROM_KEY_REG, LTC2983_EEPROM_KEY_REG),
regmap_reg_range(LTC2983_EEPROM_READ_STATUS_REG,
LTC2983_EEPROM_READ_STATUS_REG),
@@ -1659,11 +1805,19 @@ static const struct ltc2983_chip_info ltm2985_chip_info_data = {
.has_eeprom = true,
};
+static const struct ltc2983_chip_info adt7604_chip_info_data = {
+ .name = "adt7604",
+ .max_channels_nr = 20,
+ .has_eeprom = true,
+ .has_copper_trace = true,
+};
+
static const struct spi_device_id ltc2983_id_table[] = {
{ "ltc2983", (kernel_ulong_t)<c2983_chip_info_data },
{ "ltc2984", (kernel_ulong_t)<c2984_chip_info_data },
{ "ltc2986", (kernel_ulong_t)<c2986_chip_info_data },
{ "ltm2985", (kernel_ulong_t)<m2985_chip_info_data },
+ { "adt7604", (kernel_ulong_t)&adt7604_chip_info_data },
{ }
};
MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
@@ -1673,6 +1827,7 @@ static const struct of_device_id ltc2983_of_match[] = {
{ .compatible = "adi,ltc2984", .data = <c2984_chip_info_data },
{ .compatible = "adi,ltc2986", .data = <c2986_chip_info_data },
{ .compatible = "adi,ltm2985", .data = <m2985_chip_info_data },
+ { .compatible = "adi,adt7604", .data = &adt7604_chip_info_data },
{ }
};
MODULE_DEVICE_TABLE(of, ltc2983_of_match);
--
2.43.0
next prev parent reply other threads:[~2026-04-27 13:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 13:25 [PATCH 0/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-04-27 13:25 ` [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
2026-04-27 19:34 ` Conor Dooley
2026-04-28 14:58 ` Jonathan Cameron
2026-04-27 13:25 ` Liviu Stan [this message]
2026-04-27 18:23 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Andy Shevchenko
2026-04-28 11:14 ` Nuno Sá
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260427132526.272716-3-liviu.stan@analog.com \
--to=liviu.stan@analog.com \
--cc=Michael.Hennerich@analog.com \
--cc=andy@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox