Re: [PATCH 2/3] iio: adc: ltc2497: add LTC2499 internal temperature channel
Andy Shevchenko <[email protected]>
| Newsgroups | org.kernel.vger.linux-iio,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAHp75Vd7sq58kFE6EsLxFwk2z0QtOsyNwh0b-CrZb0HDYVjDJA@mail.gmail.com> |
On Wed, Aug 5, 2026 at 12:44 PM Andrei Stancovici <[email protected]> wrote: > > The LTC2499 has an internal PTAT (proportional to absolute temperature) > sensor that is activated by a second I2C configuration byte (EN2 | IM). > Expose it as an IIO_TEMP channel providing raw, scale and offset so the > standard IIO formula > > T[m°C] = (raw + offset) * scale > > reconstructs the temperature. > > The PTAT sensor yields the absolute temperature as > > T(K) = DATAOUT24 * Vref / 1570 (Vref in volts) > > The raw value exported here is sign-extended and normalised to > 2^(resolution + 1) == 2^25, i.e. raw = 2 * DATAOUT24, so on the IIO > milli-degree-Celsius convention > > scale[m°C/LSB] = Vref_uV / 3140000 > offset = -273150 * 3140000 / Vref_uV > > The scale and offset are derived from the reference voltage returned by > regulator_get_voltage(); its error is propagated as before, so a board > that fails to describe vref-supply gets a clear read error instead of a > silently wrong temperature. No board-specific reference value is assumed > in the driver. > > The single temperature channel is appended as the last entry of the > shared channel array and excluded via num_channels for parts without an > internal sensor, so the existing LTC2497 channel layout and device name > are unchanged. > > The LTC2499 latches its converter configuration from the second command > byte and only re-evaluates it when that byte has EN2 set. EN2 | IM > selects the internal temperature sensor. Because a single-byte command, > or a second byte with EN2 = 0, means "keep previous", a one-byte channel > select cannot pull the device back out of temperature mode: after a > temperature read every subsequent voltage read would keep returning the > PTAT result instead of the selected input. Temperature support is > therefore only correct if the voltage path also emits a second command > byte that re-selects an external input. > > Send two-byte commands for all conversions on parts that have the sensor > (has_temp): > > temperature: EN2 | IM > voltage: EN2 (IM = 0 -> external input) > > The LTC2497 and LTC2496, which lack the second-byte mechanism, keep using > the original single-byte channel select and are unchanged. ... > + case IIO_VOLTAGE: > + *val = ret / 1000; We have SI unit multipliers > + *val2 = ddata->chip_info->resolution + 1; > + return IIO_VAL_FRACTIONAL_LOG2; ... > + case IIO_CHAN_INFO_OFFSET: > + switch (chan->type) { > + case IIO_TEMP: > + ret = regulator_get_voltage(ddata->ref); > + if (ret < 0) > + return ret; > + /* > + * 0 °C == 273.15 K must map to raw + offset such that > + * (raw + offset) * scale == 0 m°C, i.e. > + * offset = -273150 / scale > + * = -273150 * 3140000 / Vref_uV > + * Computed in 64-bit to avoid overflow. > + */ > + *val = div_s64(-273150LL * 3140000, ret); We have ABSOLUTE_ZERO_MILLICELSIUS, use it. > + return IIO_VAL_INT; ... > indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel); > + /* Only the ltc2499 has a temperature channel; it is the last entry. */ > + if (!ddata->chip_info->has_temp) > + indio_dev->num_channels--; I would do it explicitly: if (...) num_channels = ARRAY_SIZE(...); else num_channels = ARRAY_SIZE(...) - 1; -- With Best Regards, Andy Shevchenko