Re: [PATCH v2 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 <CAHp75Vd2_NwPjqM1MMBn-2KP2h=ug=Nv-v1CgfmfPdN3jE50Yg@mail.gmail.com>
On Thu, Aug 13, 2026 at 7:02 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.

...

> +                       /*
> +                        * raw is normalised to 2^(resolution + 1), i.e.
> +                        * raw = 2 * DATAOUT24, so the PTAT scale (datasheet
> +                        * Vref / 1570 per kelvin) doubles its denominator and,

Kelvin

> +                        * in m°C, becomes Vref_uV / 3140000.
> +                        */

...

> +                       ret = regulator_get_voltage(ddata->ref);
> +                       if (ret < 0)
> +                               return ret;
> +                       if (!ret)

In this case I would rather see

  if (ret == 0)

as it's about value and not a returned error code (success).

> +                               return -EINVAL;
> +                       /*
> +                        * 0 °C == 273.15 K must map to raw + offset such that
> +                        * (raw + offset) * scale == 0 m°C, i.e.
> +                        *   offset = ABSOLUTE_ZERO_MILLICELSIUS / scale
> +                        *          = ABSOLUTE_ZERO_MILLICELSIUS * 3140000 / Vref_uV

This is a bit too far. In the comments the plain numbers are much
better, we should understand math and physics behind.

> +                        * Computed in 64-bit to avoid overflow.
> +                        */
> +                       *val = div_s64((s64)ABSOLUTE_ZERO_MILLICELSIUS * 3140000, ret);

Casting is not needed, the trick is to add LL type suffix to the 3140000.

> +                       return IIO_VAL_INT;
> +               default:
> +                       return -EINVAL;
> +               }

...

>  struct ltc2497_chip_info {
>         u32 resolution;
>         const char *name;
> +       bool has_temp;
>  };

Have you run `pahole`? It might be that on some architectures there
will be a gap in between existing ones due to 64-bit required
alignment.

-- 
With Best Regards,
Andy Shevchenko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.