All of lore.kernel.org
 help / color / mirror / Atom feed
From: Janani Sunil <janani.sunil@analog.com>
To: "Nuno Sá" <nuno.sa@analog.com>,
	"Michael Hennerich" <Michael.Hennerich@analog.com>,
	"Jonathan Cameron" <jic23@kernel.org>,
	"David Lechner" <dlechner@baylibre.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Olivier Moysan" <olivier.moysan@foss.st.com>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Linus Walleij" <linusw@kernel.org>,
	"Bartosz Golaszewski" <brgl@kernel.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Shuah Khan" <skhan@linuxfoundation.org>,
	"Michael Walle" <mwalle@kernel.org>,
	"Randy Dunlap" <rdunlap@infradead.org>
Cc: linux@analog.com, linux-iio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	jananisunil.dev@gmail.com,
	"Uwe Kleine-König" <u.kleine-koenig@baylibre.com>,
	"Janani Sunil" <janani.sunil@analog.com>,
	"Jonathan Cameron" <jic23@kernel.org>
Subject: [PATCH v6 14/17] iio: adc: ad7768: Add per-channel conversion delay
Date: Fri, 4 Sep 2026 16:15:06 +0200	[thread overview]
Message-ID: <20260904-ad7768-driver-v6-14-e4378f946bfb@analog.com> (raw)
In-Reply-To: <20260904-ad7768-driver-v6-0-e4378f946bfb@analog.com>

Expose the per-channel synchronization phase offset through the IIO
conversion-delay attribute.

Derive the delay resolution from MCLK, power mode and decimation rate.
Validate the requested delay and program the corresponding phase
register when applying the active channel configuration.

Signed-off-by: Janani Sunil <janani.sunil@analog.com>
---
 drivers/iio/adc/ad7768.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c
index 802666f7abd4..9c6bebb1857f 100644
--- a/drivers/iio/adc/ad7768.c
+++ b/drivers/iio/adc/ad7768.c
@@ -149,6 +149,12 @@ struct ad7768_freq_config {
 	unsigned int dec_rate;
 };
 
+struct ad7768_convdelay_params {
+	unsigned int shift;
+	unsigned int max_raw;
+	u64 step_ps;
+};
+
 struct ad7768_avail_freq {
 	unsigned int n_freqs;
 	struct ad7768_freq_config freq_cfg[AD7768_MAX_FREQ_PER_MODE];
@@ -175,6 +181,7 @@ struct ad7768_state {
 	struct ad7768_avail_freq avail_freq[ARRAY_SIZE(ad7768_power_modes)];
 	unsigned int n_freqs;
 	int freqs[AD7768_MAX_FREQS];
+	u64 ch_convdelay_ps[AD7768_MAX_CHANNEL];
 	unsigned int ch_freq[AD7768_MAX_CHANNEL];
 	unsigned int power_mode_idx;
 	enum ad7768_filter_type ch_filter[AD7768_MAX_CHANNEL];
@@ -246,6 +253,12 @@ static unsigned int ad7768_gain_reg(const struct ad7768_state *st,
 	return AD7768_REG_GAIN(st->chip_info->chan_map[ch]);
 }
 
+static unsigned int ad7768_phase_reg(const struct ad7768_state *st,
+				     unsigned int ch)
+{
+	return AD7768_REG_PHASE(st->chip_info->chan_map[ch]);
+}
+
 static u8 ad7768_precharge_buf1_mask(const struct ad7768_state *st, u16 val)
 {
 	return val & GENMASK(st->chip_info->prebuf_split - 1, 0);
@@ -665,6 +678,92 @@ static int ad7768_find_matching_mode(const bool *mode_used,
 	return -EINVAL;
 }
 
+static int ad7768_get_convdelay_params(struct ad7768_state *st, unsigned int ch,
+				       struct ad7768_convdelay_params *params)
+{
+	const struct ad7768_freq_config *freq_cfg;
+	unsigned int dec_rate;
+	unsigned int mclk_div;
+	u64 mclk;
+	u64 mult;
+
+	freq_cfg = ad7768_find_freq_config(st, st->power_mode_idx,
+					   st->ch_freq[ch]);
+	if (!freq_cfg)
+		return -EINVAL;
+
+	dec_rate = ad7768_dec_rate[freq_cfg->dec_rate];
+	switch (dec_rate) {
+	case 32:
+		params->shift = 3;
+		params->max_raw = 31;
+		mult = 1;
+		break;
+	case 64:
+		params->shift = 2;
+		params->max_raw = 63;
+		mult = 1;
+		break;
+	case 128:
+		params->shift = 1;
+		params->max_raw = 127;
+		mult = 1;
+		break;
+	case 256:
+		params->shift = 0;
+		params->max_raw = 255;
+		mult = 1;
+		break;
+	case 512:
+		params->shift = 0;
+		params->max_raw = 255;
+		mult = 2;
+		break;
+	case 1024:
+		params->shift = 0;
+		params->max_raw = 255;
+		mult = 4;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mclk = clk_get_rate(st->mclk);
+	if (!mclk)
+		return -EINVAL;
+
+	mclk_div = ad7768_power_modes[st->power_mode_idx].mclk_div;
+	params->step_ps =
+		DIV_ROUND_CLOSEST_ULL(mult * PSEC_PER_SEC * mclk_div, mclk);
+
+	return 0;
+}
+
+static int ad7768_set_channel_convdelay(struct ad7768_state *st,
+					unsigned int ch)
+{
+	u64 delay_ps = st->ch_convdelay_ps[ch];
+	struct ad7768_convdelay_params params;
+	u64 max_delay_ps;
+	u64 raw;
+	int ret;
+
+	ret = ad7768_get_convdelay_params(st, ch, &params);
+	if (ret)
+		return ret;
+
+	max_delay_ps = (u64)params.max_raw * params.step_ps;
+	if (delay_ps > max_delay_ps)
+		return -EINVAL;
+
+	raw = DIV_ROUND_CLOSEST_ULL(delay_ps, params.step_ps);
+	if (raw > params.max_raw)
+		return -EINVAL;
+
+	return regmap_write(st->regmap, ad7768_phase_reg(st, ch),
+			    raw << params.shift);
+}
+
 static void ad7768_filter_wait(const unsigned int *mode_freq,
 			       const enum ad7768_filter_type *mode_filter,
 			       const bool *mode_used)
@@ -771,6 +870,16 @@ static int ad7768_apply_channel_modes(struct iio_dev *indio_dev,
 		max_freq = max(max_freq, mode_freq[mode]);
 	}
 
+	for_each_set_bit(c, scan_mask, st->chip_info->num_channels) {
+		ret = ad7768_set_channel_convdelay(st, c);
+		if (ret == -EINVAL)
+			return dev_err_probe(regmap_get_device(st->regmap), ret,
+					     "Invalid conversion delay for channel %u\n",
+					     c);
+		if (ret)
+			return ret;
+	}
+
 	ret = ad7768_set_clk_divs(st, max_freq);
 	if (ret)
 		return ret;
@@ -891,6 +1000,13 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
 		*val = calib;
 		return IIO_VAL_INT;
 	}
+	case IIO_CHAN_INFO_CONVDELAY: {
+		guard(mutex)(&st->lock);
+		iio_val_s64_decompose(st->ch_convdelay_ps[chan->channel],
+				      val, val2);
+
+		return IIO_VAL_DECIMAL64_PICO;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -904,6 +1020,8 @@ static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_CALIBSCALE:
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CONVDELAY:
+		return IIO_VAL_DECIMAL64_PICO;
 	default:
 		return -EINVAL;
 	}
@@ -915,6 +1033,7 @@ static int ad7768_write_raw(struct iio_dev *indio_dev,
 {
 	struct ad7768_state *st = iio_priv(indio_dev);
 	unsigned int base_reg;
+	s64 delay_ps;
 
 	IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
 	if (IIO_DEV_ACQUIRE_FAILED(claim))
@@ -935,6 +1054,15 @@ static int ad7768_write_raw(struct iio_dev *indio_dev,
 
 		base_reg = ad7768_get_calib_reg_base(st, chan, true);
 		return ad7768_write_calib_value(st, base_reg, val);
+	case IIO_CHAN_INFO_CONVDELAY: {
+		delay_ps = iio_val_s64_compose(val, val2);
+		if (delay_ps < 0)
+			return -EINVAL;
+
+		guard(mutex)(&st->lock);
+		st->ch_convdelay_ps[chan->channel] = delay_ps;
+		return 0;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -1151,6 +1279,7 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) |
 					      BIT(IIO_CHAN_INFO_CALIBBIAS) |
 					      BIT(IIO_CHAN_INFO_CALIBSCALE) |
+					      BIT(IIO_CHAN_INFO_CONVDELAY) |
 					      BIT(IIO_CHAN_INFO_SAMP_FREQ),
 			.info_mask_separate_available =
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),

-- 
2.43.0


  parent reply	other threads:[~2026-09-04 14:16 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04 14:14 [PATCH v6 00/17] iio: adc: Add AD7768/AD7768-4 ADC driver support Janani Sunil
2026-09-04 14:14 ` [PATCH v6 01/17] iio: adc: adi-axi-adc: Initialize state mutex Janani Sunil
2026-09-04 14:14 ` [PATCH v6 02/17] dt-bindings: iio: adc: Add AD7768 Janani Sunil
2026-09-04 14:21   ` sashiko-bot
2026-09-04 17:08   ` Conor Dooley
2026-09-04 14:14 ` [PATCH v6 03/17] iio: backend: Add support for CRC Janani Sunil
2026-09-06  3:50   ` Jonathan Cameron
2026-09-04 14:14 ` [PATCH v6 04/17] iio: adc: adi-axi-adc: " Janani Sunil
2026-09-04 14:24   ` sashiko-bot
2026-09-04 14:14 ` [PATCH v6 05/17] iio: adc: Add AD7768 and AD7768-4 core support Janani Sunil
2026-09-04 14:31   ` sashiko-bot
2026-09-06  2:24     ` Jonathan Cameron
2026-09-06  3:05       ` Jonathan Cameron
2026-09-06  3:50   ` Jonathan Cameron
2026-09-07 11:25     ` Janani Sunil
2026-09-10  3:43       ` Jonathan Cameron
2026-09-06  8:34   ` Andy Shevchenko
2026-09-07 11:17     ` Janani Sunil
2026-09-04 14:14 ` [PATCH v6 06/17] iio: adc: ad7768: Validate master clock rate Janani Sunil
2026-09-04 14:14 ` [PATCH v6 07/17] iio: adc: ad7768: Add power mode helper Janani Sunil
2026-09-04 14:25   ` sashiko-bot
2026-09-06  3:50   ` Jonathan Cameron
2026-09-04 14:15 ` [PATCH v6 08/17] iio: adc: ad7768: Derive output data rates Janani Sunil
2026-09-04 14:15 ` [PATCH v6 09/17] iio: adc: ad7768: Configure channel sampling profiles Janani Sunil
2026-09-04 14:45   ` sashiko-bot
2026-09-06  3:50   ` Jonathan Cameron
2026-09-04 14:15 ` [PATCH v6 10/17] iio: adc: ad7768: Add sampling frequency controls Janani Sunil
2026-09-04 14:15 ` [PATCH v6 11/17] iio: adc: ad7768: Add per-channel filter controls Janani Sunil
2026-09-04 14:15 ` [PATCH v6 12/17] iio: adc: ad7768: Wait for digital filters to settle Janani Sunil
2026-09-04 14:15 ` [PATCH v6 13/17] iio: adc: ad7768: Add calibration controls Janani Sunil
2026-09-04 14:35   ` sashiko-bot
2026-09-06  3:50   ` Jonathan Cameron
2026-09-04 14:15 ` Janani Sunil [this message]
2026-09-04 14:33   ` [PATCH v6 14/17] iio: adc: ad7768: Add per-channel conversion delay sashiko-bot
2026-09-06  3:50   ` Jonathan Cameron
2026-09-04 14:15 ` [PATCH v6 15/17] iio: adc: ad7768: Add VCM regulator support Janani Sunil
2026-09-04 14:15 ` [PATCH v6 16/17] iio: adc: ad7768: Register GPIO auxiliary device Janani Sunil
2026-09-04 14:15 ` [PATCH v6 17/17] Documentation: iio: Add AD7768 Documentation Janani Sunil
2026-09-06  3:50   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260904-ad7768-driver-v6-14-e4378f946bfb@analog.com \
    --to=janani.sunil@analog.com \
    --cc=Michael.Hennerich@analog.com \
    --cc=andy@kernel.org \
    --cc=brgl@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=jananisunil.dev@gmail.com \
    --cc=jic23@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@analog.com \
    --cc=mwalle@kernel.org \
    --cc=nuno.sa@analog.com \
    --cc=olivier.moysan@foss.st.com \
    --cc=p.zabel@pengutronix.de \
    --cc=rdunlap@infradead.org \
    --cc=robh@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=u.kleine-koenig@baylibre.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.