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