Skip to content

Andrei/ltc2499 support - #3452

Open
stancovici wants to merge 4 commits into
rpi/release/v6.12.y-2026r1from
andrei/ltc2499-support
Open

Andrei/ltc2499 support#3452
stancovici wants to merge 4 commits into
rpi/release/v6.12.y-2026r1from
andrei/ltc2499-support

Conversation

@stancovici

Copy link
Copy Markdown
Collaborator

PR Description

Add LTC2499 support and validation infrastructure to the ADI Linux tree.

This PR introduces:

  1. LTC2499 internal temperature channel support in the ltc2497 driver.
  2. DT binding documentation updates for LTC2499 temperature support.
  3. A Raspberry Pi validation overlay used for LTC2499 bring-up and hardware
    testing.
  4. LTC2499 SPD (2x speed mode) support through the standard IIO
    sampling_frequency ABI.

The temperature support adds an IIO temperature channel backed by the
device's internal PTAT sensor and includes the sticky-PTAT fix required
to reliably switch between temperature and voltage conversions.

The SPD support adds selectable 1x and 2x conversion rates and adjusts
the conversion timing accordingly. Validation on live LTC2499 hardware
demonstrated approximately a 2x throughput improvement while preserving
correct voltage and temperature operation.

The Raspberry Pi overlay is intended as a downstream validation artifact
used for LTC2499 bring-up and testing on ADI Linux platforms.

Validation

Temperature feature:

  • internal temperature channel enumeration
  • raw / scale / offset support
  • corrected temperature calculation
  • voltage-channel backward compatibility
  • sticky-PTAT temp -> voltage -> temp regression

SPD feature:

  • sampling_frequency support
  • 1x / 2x mode switching
  • timing validation
  • temperature unaffected by SPD
  • sticky-PTAT regression retested under 2x mode

Validation was performed on live LTC2499 hardware connected through an
IIO network backend.

Commits

  • iio: adc: ltc2497: add LTC2499 internal temperature channel
  • dt-bindings: iio: adc: lltc,ltc2497: document LTC2499 temp support
  • ARM: dts: overlays: add local LTC2499 validation overlay
  • iio: adc: ltc2497: add 2x conversion speed mode

PR Type

  • New feature

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have compiled my changes, including the documentation
  • I have tested the changes on the relevant hardware
  • I have updated the documentation outside this repo accordingly
  • I have provided links for the relevant upstream lore

@gastmaier gastmaier left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High, some quick thoughts, the llm also found the provided

https://github.com/analogdevicesinc/doctools/blob/docling/media/en/technical-documentation/data-sheets/2497fb.md

so it should be able to dive on the registers for us and provide some feedback on that too.

Comment thread drivers/iio/adc/ltc2497-core.c Outdated
Comment on lines +149 to +151
* IIO reports temperatures in milli-degrees Celsius and
* the core computes the processed value as
* T[m°C] = (raw + offset) * scale

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't explain the subsystem here

Comment thread drivers/iio/adc/ltc2497-core.c Outdated
Comment on lines +153 to +159
* The LTC2499 PTAT sensor yields the absolute temperature
* T(K) = DATAOUT24 * Vref / 1570 (Vref in volts)
* but the raw value exported here is normalised to
* 2^(resolution + 1) == 2^25, i.e. raw = 2 * DATAOUT24, so
* T(K) = raw * Vref / 3140.
* Converting K -> m°C (x1000) and Vref uV -> V (/1e6):
* scale[m°C/LSB] = Vref_uV / 3140000

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be more concise. the code is already the formula, describe what is unexpected.

Comment thread drivers/iio/adc/ltc2497-core.c Outdated
Comment on lines +254 to +258
* time_prev and conv_time_prev are deliberately left untouched:
* a conversion started under the previous mode may still be in
* flight, and the next read must wait out its (old-mode) duration
* from its real start time before reprogramming, or the device
* NACKs the write with -EIO.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't describe actions taken.

the device NACKs the write with -EIO

This is incorrect. the device i2c protocol will NACK, and the consequence in the driver is -EIO.
The NACK has no return code by itself.
Waiting for commands to settle is usual device communication flows, nothing special here.

Comment thread drivers/iio/adc/ltc2497-core.c Outdated
Comment on lines +300 to +304
/*
* The 32 voltage channels are shared by every part in the family. The LTC2499
* appends one temperature channel; it is kept last so that parts without an
* internal temperature sensor can simply exclude it via num_channels.
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, but too verbose too.
would be better to have a one liner were this surprising logic actually occurs [1]

Comment thread drivers/iio/adc/ltc2497-core.c Outdated
Comment on lines +364 to +370
/*
* The temperature channel is the last entry; drop it for parts without
* an internal temperature sensor.
*/
indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel);
if (!ddata->chip_info->has_temp)
indio_dev->num_channels--;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[1] here is the ideal one liner location.

/* Only ltc2499 has a temperature channel */

Comment on lines +372 to +378
/*
* Parts with a speed mode expose in_voltage_sampling_frequency /
* _available on the voltage channels only. SPD is ignored during a
* temperature measurement, so the temperature channel deliberately
* carries no SAMP_FREQ attribute. Patch a private copy of the shared
* channel array so parts without a speed mode stay untouched.
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this is the best approach.
why can't the temp channel be correctly const instead of patching it on probe?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I kept the runtime-patched copy is extensibility: the channel metadata is expected to grow with additional optional features on the LTC2499 family, and keeping a single base channel description avoids maintaining multiple near-duplicate channel tables.
I'm happy to switch to a static const table if you feel that is the preferred direction for this series.

Comment thread drivers/iio/adc/ltc2497.h Outdated

/*
* Worst-case conversion times (datasheet t_CONV max, simultaneous 50/60Hz
* rejection - the only rejection mode reachable today). The 1x value also

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only rejection mode reachable today

what does this mean?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention was to describe a driver limitation, not a hardware limitation. The original wording was ambiguous and could also be interpreted as a roadmap reference.
I've reworded the comment to explicitly state that the driver only programs simultaneous 50/60Hz rejection and that FA/FB selection is not implemented.
This keeps the comment focused on the behavior implemented by the current change.

@github-actions

Copy link
Copy Markdown
Contributor

LLM review

This series adds an internal PTAT temperature channel and a 2x conversion speed mode ("SPD") for the
LTC2499, plus dt-bindings/documentation and a validation dts overlay.

run: 29905280095

Open review comments still unaddressed

All 6 open comments from @gastmaier on ltc2497-core.c/ltc2497.h are still present in the tree at
head_sha:

  • ltc2497-core.c:151/159 — the temperature SCALE comment re-explains the generic IIO
    (raw + offset) * scale convention instead of just the LTC2499-specific, non-obvious bit (the
    raw = 2 * DATAOUT24 normalisation).
  • ltc2497-core.c:258 — "the device NACKs the write with -EIO" is not quite right: NACK is an I2C
    protocol event, not itself a return code; -EIO is the driver's own mapping of it.
  • ltc2497-core.c:304/370 — the comment ahead of the channel array is verbose; the reviewer's
    suggested one-liner belongs at the num_channels-- site instead.
  • ltc2497-core.c:378 — the LTC2499 SPD channel table is built by devm_kmemdup()-ing
    ltc2497core_channel[] and patching SAMP_FREQ bits into it at probe time, instead of just being a
    second static const table.
  • ltc2497.h:8 — "the only rejection mode reachable today" is ambiguous; it should say the driver only
    programs the simultaneous 50/60Hz rejection mode (FA/FB selection is not implemented).

19bb7716127be / 0421f8f49d6e2 — comment verbosity and const-table design

Design issue: ltc2497core_probe() allocates a private copy of the channel array with
devm_kmemdup() and patches SAMP_FREQ masks into the voltage channels at probe time for
has_speed_mode parts. Since there is exactly one such part (LTC2499) and its channel layout is fully
known at compile time, this can (and per review, should) be a second static const array instead,
removing the runtime allocation/mutation and the now-unneeded <linux/slab.h>/<linux/device.h>
includes.

CI warnings

The smatch warnings in /tmp/tmp.ZUxNVQl3TN.txt (arch/arm/include/asm/irqflags.h,
kernel/module/main.c) are unrelated to this series — neither file is touched by any of the 4 commits.

Build validation

Cross-compiled drivers/iio/adc/ltc2497-core.c/ltc2497.c/ltc2496.c and the two .dtbo overlays for
arm and arm64 with make W=1: clean, no warnings, on both the original series and after applying the
suggested fixups below. checkpatch.pl is clean on all 4 commits (aside from the expected "new file,
update MAINTAINERS?" note on the dts overlay). dt_binding_check is clean for the touched
lltc,ltc2497.yaml schema.

Verification data

The LTC2499 datasheet PDF was blocked (HTTP 403) from analog.com even with a spoofed user agent, so it
was fetched and converted to markdown with docling. This confirmed:

  • t_CONV_1/t_CONV_2 (simultaneous 50/60Hz) typ 146.9 ms / 73.6 ms match the driver's comments exactly,
    and the 150/76 ms constants correctly round up from the datasheet max values (149.9/75.1 ms).
  • The PTAT formula comment (T(K) = DATAOUT24 * Vref / 1570) was independently re-derived from the
    datasheet's slope/offset numbers (93.5 µV/°C, 28 mV @ 27 °C, 314 LSB24/°C @ 5V) since the datasheet's
    own formula was embedded as an undecoded image; the re-derived constant (≈1568.7) matches to within
    rounding.

Suggested patches

Two fixup commits address all 6 review comments: comment trims (19bb7716127be) and the write_raw
comment/ltc2497.h wording/const-table refactor (0421f8f49d6e2). Both were rebuilt (W=1,
arm/arm64) and re-checked with checkpatch.pl — clean.

Apply the suggested patches with:

cd path/to/repository
export GITHUB_TOKEN=ghp_***
apply-patches --repo=analogdevicesinc/linux 29905280095
Install instructions

The following one-liner installs the script if not present already:

curl -fSsL "https://raw.githubusercontent.com/analogdevicesinc/doctools/refs/heads/main/ci/scripts/apply-patches.sh"      -o ~/.local/bin/apply-patches.sh &&   grep -q "/apply-patches.sh" ~/.bashrc || echo "source ~/.local/bin/apply-patches.sh" >> $_ ; . $_

More information at AI Usage.

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.

Signed-off-by: Andrei Stancovici <andrei.stancovici@analog.com>
…port

Add the LTC2499 to the binding title and note that its internal
temperature sensor derives its scale and offset from the reference
voltage, so an accurate vref-supply is required for the temperature
channel to report correctly. vref-supply is already a required property,
so no schema change is needed.

Signed-off-by: Andrei Stancovici <andrei.stancovici@analog.com>
@stancovici
stancovici force-pushed the andrei/ltc2499-support branch from 0421f8f to 0b0047e Compare July 23, 2026 13:15
@stancovici

Copy link
Copy Markdown
Collaborator Author

v2:

Addressed the review comments from @gastmaier and force-pushed an updated series.

Changes:

  • Trimmed the LTC2499 temperature SCALE comment and removed the generic IIO explanation.
  • Replaced the verbose temperature-channel comments with a concise one-liner at the actual num_channels handling site.
  • Reworked the SPD write_raw comment to describe the invariant rather than implementation bookkeeping, and removed the incorrect NACK/-EIO wording.
  • Clarified the conversion-time comment in ltc2497.h to explicitly state that the driver only programs simultaneous 50/60Hz rejection and that FA/FB selection is not implemented.
  • Preserved the dt-binding and validation overlay patches unchanged.

Notes:

  • No functional changes.
  • Comment-only updates.
  • checkpatch.pl --strict clean.
  • make W=1 clean (arm64).

The fixes were amended into the original temperature and SPD commits and the series was force-pushed; the overall commit structure remains unchanged.

One review item remains open for discussion:

  • probe-time channel patching (devm_kmemdup() vs. a second static const channel table).

For the SPD-only series, the static table is cleaner in isolation. The current approach was kept for extensibility, but I'm happy to switch if that is the preferred direction for this series.

Add a Raspberry Pi overlay that instantiates an LTC2499 on I2C1 and wires
its reference to the board's existing 3.3 V regulator via

	vref-supply = <&vdd_3v3_reg>;

so that regulator_get_voltage() returns 3300000 and the temperature
channel reports correctly without relying on any driver-side fallback.

This is a local validation/example artifact for the Raspberry Pi and is
not intended for upstream: every board must describe its own actual VREF
regulator (2.5 V, 3.3 V, 4.096 V, ...). The 3.3 V value here is specific
to this board and is not a universal hardware assumption.

Signed-off-by: Andrei Stancovici <andrei.stancovici@analog.com>
The LTC2499 supports a 2x output rate (SPD bit in the second
configuration byte).  In 2x mode the offset auto-calibration is
disabled, roughly doubling the conversion rate (~13.6Hz vs ~6.8Hz in
simultaneous 50/60Hz rejection) while leaving linearity and full-scale
errors unchanged (datasheet).  During a temperature measurement the part
always converts at 1x regardless of SPD.

Expose the rate through the standard sampling_frequency /
sampling_frequency_available ABI on the voltage channels only: SPD is
ignored for temperature conversions, so the temperature channel
deliberately carries no SAMP_FREQ attribute.  A new has_speed_mode
capability flag gates the feature (LTC2499); the two-byte command path
is now taken for has_temp || has_speed_mode, since both features need the
second config byte.

The conversion-time wait becomes mode dependent: 150ms at 1x, 76ms at 2x
(datasheet t_CONV max, simultaneous rejection, rounded up).  The wait is
keyed on the conversion currently in flight, whose duration is fixed by
the mode that was active when it started - not by the newly selected
mode.  This matters on a 1x->2x switch: a 1x conversion may still be
running when the first 2x read arrives, and reprogramming the device
before it finishes would be NACKed with -EIO.  Timing is centralized in
ltc2497core_conv_time_ms() so a future FA/FB rejection-mode selection
can extend it into a [rejection][speed] lookup without touching callers.

LTC2496/LTC2497 (no speed mode) keep the single-byte path and the
unchanged 150ms wait.

Validated on a live LTC2499: 20 reads take ~3.1s at 1x and ~1.6s at 2x
(~0.5x, no -EIO), voltage and temperature readings stay sane in both
modes, and the temperature/voltage interleave (sticky-PTAT) regression
still passes at 1x and 2x.

Signed-off-by: Andrei Stancovici <andrei.stancovici@analog.com>
@stancovici
stancovici force-pushed the andrei/ltc2499-support branch 2 times, most recently from e94c70c to 0c63d33 Compare July 23, 2026 17:55
@stancovici

Copy link
Copy Markdown
Collaborator Author

v3: Minor follow-up:

The overlay header still described the file as a local validation/example artifact. Since the overlay is kept as part of the delivered LTC2499 series, I updated the wording to describe its actual role and removed the obsolete "not upstream" / "validation artifact" language.

No functional changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llm review Request a review from a LLM Reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants