Re: [PATCH v2 3/3] iio: adc: ltc2497: add 2x conversion speed mode

Andy Shevchenko <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo
Message-ID <[email protected]>
On Thu, Aug 13, 2026 at 07:01:37PM +0300, Andrei Stancovici wrote:
> 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.

...

> -static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
> +static unsigned int ltc2497core_conv_time_ms(struct ltc2497core_driverdata *ddata,
> +					     u8 address)

Wondering if you use --histogram when preparing patches. If not, try it, it may give
more human-readable diffs.

...

> +static int ltc2497core_write_raw(struct iio_dev *indio_dev,
> +				 struct iio_chan_spec const *chan,
> +				 int val, int val2, long mask)
> +{
> +	struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
> +	bool sped_2x;
> +	unsigned int i;

Reversed xmas tree ordering (longer lines first).

> +	switch (mask) {
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		/* Match the (val, val2) pair against the advertised rates. */
> +		for (i = 0; i < ARRAY_SIZE(ltc2497core_samp_freq_avail); i += 2) {
> +			if (val == ltc2497core_samp_freq_avail[i] &&
> +			    val2 == ltc2497core_samp_freq_avail[i + 1])
> +				break;
> +		}
> +		if (i == ARRAY_SIZE(ltc2497core_samp_freq_avail))
> +			return -EINVAL;
> +
> +		sped_2x = i / 2;
> +
> +		mutex_lock(&ddata->lock);
> +		ddata->sped_2x = sped_2x;
> +		/*
> +		 * The new speed only takes effect once the second command byte
> +		 * is reprogrammed, so force the next read to reprogram rather
> +		 * than reuse the value already latched for this address.
> +		 * LTC2497_CONFIG_DEFAULT is not a valid channel/temperature
> +		 * address, so it is a safe re-arm sentinel (as used at probe).
> +		 *
> +		 * A conversion started under the old speed may still be in
> +		 * flight; its own duration (conv_time_prev), not the new mode's,
> +		 * still gates the next reprogram, so the timing state is left
> +		 * untouched here.
> +		 */
> +		ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
> +		mutex_unlock(&ddata->lock);
> +
> +		return 0;
> +
>  	default:
>  		return -EINVAL;
>  	}

>  };

...

> +	/*
> +	 * Parts with a speed mode expose in_voltage_sampling_frequency /
> +	 * _available on the voltage channels only.  SPD is ignored during a

Spell the node name in full, I can't really get if you meant
in_voltage_available or something else.

> +	 * 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.
> +	 */

...

>  	/*
> -	 * Parts with the internal PTAT sensor (LTC2499) latch their converter
> -	 * configuration via a second command byte and only re-evaluate it when
> -	 * that byte has EN2 set; a single byte, or a second byte with EN2 = 0,
> -	 * means "keep previous". A one-byte channel select therefore cannot pull
> -	 * the device back out of temperature mode, so a voltage read after a
> -	 * temperature read would keep returning the PTAT result. Always drive the
> -	 * second byte with EN2 set on these parts: IM = 1 for a temperature read,
> -	 * EN2 alone (IM = 0) to (re)select an external input. FA = FB = 0 keeps
> -	 * the power-on simultaneous 50/60Hz rejection, whose worst-case
> -	 * conversion time the driver's wait already covers.
> +	 * Parts with a second config byte (LTC2499: internal PTAT sensor and/or
> +	 * the 2x speed mode) latch their converter configuration from that byte
> +	 * and only re-evaluate it when EN2 is set; a single byte, or a second
> +	 * byte with EN2 = 0, means "keep previous". A one-byte channel select

Please, be consistent with 1-space versus double-space at the start of a new
sentences. See just above comment and compare.

> +	 * therefore cannot pull the device back out of temperature mode, so a
> +	 * voltage read after a temperature read would keep returning the PTAT
> +	 * result. Always drive the second byte with EN2 set on these parts:
> +	 *   - temperature read: IM = 1 (SPD is ignored by the part in
> +	 *     temperature mode and is left 0 here);
> +	 *   - voltage read: IM = 0 (external input), plus SPD when 2x is
> +	 *     selected.
> +	 * FA = FB = 0 keeps the power-on simultaneous 50/60Hz rejection, whose
> +	 * worst-case conversion time the driver's wait already covers.
>  	 *
>  	 * The two bytes are assembled in the DMA-safe st->data buffer rather than
>  	 * on the stack, so the pointer handed to i2c_master_send() stays valid on
>  	 * adapters that DMA the transfer (e.g. with CONFIG_VMAP_STACK).
>  	 */


-- 
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.