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>
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>
Subject: [PATCH v5 13/20] iio: adc: ad7768: Add calibration controls
Date: Fri, 28 Aug 2026 17:30:36 +0200	[thread overview]
Message-ID: <20260828-ad7768-driver-v5-13-e33ca6f841a2@analog.com> (raw)
In-Reply-To: <20260828-ad7768-driver-v5-0-e33ca6f841a2@analog.com>

Expose the per-channel offset and gain calibration registers through the
IIO calibbias and calibscale attributes.

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

diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c
index 84b96b1fab09..f2f318ebf964 100644
--- a/drivers/iio/adc/ad7768.c
+++ b/drivers/iio/adc/ad7768.c
@@ -27,6 +27,7 @@
 #include <linux/spi/spi.h>
 #include <linux/time.h>
 #include <linux/types.h>
+#include <linux/unaligned.h>
 #include <linux/units.h>
 
 #include <linux/iio/backend.h>
@@ -112,6 +113,7 @@
 #define AD7768_MAX_FREQ_PER_MODE			6
 #define AD7768_MAX_CHANNEL				8
 #define AD7768_NUM_CHANNEL_MODES			2
+#define AD7768_CALIB_REG_MSK				GENMASK(23, 0)
 #define AD7768_WIDEBAND_SETTLING_SAMPLES		68
 #define AD7768_SINC5_SETTLING_SAMPLES			7
 
@@ -237,6 +239,18 @@ static u8 ad7768_all_standby_mask(const struct ad7768_state *st)
 	return GENMASK(st->chip_info->num_channels - 1, 0);
 }
 
+static unsigned int ad7768_offset_reg(const struct ad7768_state *st,
+				      unsigned int ch)
+{
+	return AD7768_REG_OFFSET(st->chip_info->chan_map[ch]);
+}
+
+static unsigned int ad7768_gain_reg(const struct ad7768_state *st,
+				    unsigned int ch)
+{
+	return AD7768_REG_GAIN(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);
@@ -354,6 +368,59 @@ static const struct regmap_config ad7768_4_regmap_config = {
 	.readable_reg = ad7768_4_readable_reg,
 };
 
+static unsigned int ad7768_get_calib_reg_base(struct ad7768_state *st,
+					      const struct iio_chan_spec *chan,
+					      bool is_gain)
+{
+	if (is_gain)
+		return ad7768_gain_reg(st, chan->channel);
+
+	return ad7768_offset_reg(st, chan->channel);
+}
+
+static int ad7768_read_calib_value(struct ad7768_state *st,
+				   unsigned int base_reg, unsigned int *val)
+{
+	u8 data[3];
+	int ret;
+
+	PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm);
+	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+	if (ret)
+		return ret;
+
+	guard(mutex)(&st->lock);
+
+	ret = regmap_bulk_read(st->regmap, base_reg, data, sizeof(data));
+	if (ret)
+		return ret;
+
+	*val = get_unaligned_be24(data);
+
+	return 0;
+}
+
+static int ad7768_write_calib_value(struct ad7768_state *st,
+				    unsigned int base_reg, unsigned int val)
+{
+	u8 data[3];
+	int ret;
+
+	if (val > AD7768_CALIB_REG_MSK)
+		return -EINVAL;
+
+	put_unaligned_be24(val, data);
+
+	PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm);
+	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+	if (ret)
+		return ret;
+
+	guard(mutex)(&st->lock);
+
+	return regmap_bulk_write(st->regmap, base_reg, data, sizeof(data));
+}
+
 static int ad7768_reg_access(struct iio_dev *indio_dev,
 			     unsigned int reg,
 			     unsigned int writeval,
@@ -780,6 +847,7 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
 			   int *val, int *val2, long info)
 {
 	struct ad7768_state *st = iio_priv(indio_dev);
+	int ret;
 
 	switch (info) {
 	case IIO_CHAN_INFO_SCALE: {
@@ -797,6 +865,21 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
 
 		return IIO_VAL_INT;
 	}
+
+	case IIO_CHAN_INFO_CALIBBIAS:
+	case IIO_CHAN_INFO_CALIBSCALE: {
+		bool is_gain = info == IIO_CHAN_INFO_CALIBSCALE;
+		unsigned int base_reg;
+		unsigned int calib;
+
+		base_reg = ad7768_get_calib_reg_base(st, chan, is_gain);
+		ret = ad7768_read_calib_value(st, base_reg, &calib);
+		if (ret)
+			return ret;
+
+		*val = calib;
+		return IIO_VAL_INT;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -805,24 +888,45 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
 static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev,
 				    struct iio_chan_spec const *chan, long info)
 {
-	if (info == IIO_CHAN_INFO_SAMP_FREQ)
+	switch (info) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+	case IIO_CHAN_INFO_CALIBBIAS:
+	case IIO_CHAN_INFO_CALIBSCALE:
 		return IIO_VAL_INT;
-
-	return -EINVAL;
+	default:
+		return -EINVAL;
+	}
 }
 
 static int ad7768_write_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int val, int val2, long info)
 {
+	struct ad7768_state *st = iio_priv(indio_dev);
+	unsigned int base_reg;
+
 	IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
 	if (IIO_DEV_ACQUIRE_FAILED(claim))
 		return -EBUSY;
 
-	if (info == IIO_CHAN_INFO_SAMP_FREQ)
+	switch (info) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
 		return ad7768_set_sampling_freq(indio_dev, val, chan->channel);
+	case IIO_CHAN_INFO_CALIBBIAS:
+		if (val < 0 || val > AD7768_CALIB_REG_MSK)
+			return -EINVAL;
 
-	return -EINVAL;
+		base_reg = ad7768_get_calib_reg_base(st, chan, false);
+		return ad7768_write_calib_value(st, base_reg, val);
+	case IIO_CHAN_INFO_CALIBSCALE:
+		if (val < 0 || val > AD7768_CALIB_REG_MSK)
+			return -EINVAL;
+
+		base_reg = ad7768_get_calib_reg_base(st, chan, true);
+		return ad7768_write_calib_value(st, base_reg, val);
+	default:
+		return -EINVAL;
+	}
 }
 
 static int ad7768_read_avail(struct iio_dev *indio_dev,
@@ -1035,7 +1139,9 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
 
 		chan[chan_idx] = (struct iio_chan_spec) {
 			.type = IIO_VOLTAGE,
-			.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) |
+			.info_mask_separate = BIT(IIO_CHAN_INFO_CALIBBIAS) |
+					      BIT(IIO_CHAN_INFO_CALIBSCALE) |
+					      BIT(IIO_CHAN_INFO_SCALE) |
 					      BIT(IIO_CHAN_INFO_SAMP_FREQ),
 			.info_mask_separate_available =
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),

-- 
2.43.0


  parent reply	other threads:[~2026-08-28 15:31 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-28 15:30 [PATCH v5 00/20] iio: adc: Add AD7768/AD7768-4 ADC driver support Janani Sunil
2026-08-28 15:30 ` [PATCH v5 01/20] iio: adc: adi-axi-adc: Initialize state mutex Janani Sunil
2026-08-28 15:30 ` [PATCH v5 02/20] dt-bindings: iio: adc: Add AD7768 Janani Sunil
2026-08-28 15:30 ` [PATCH v5 03/20] iio: backend: Add support for CRC Janani Sunil
2026-08-28 15:30 ` [PATCH v5 04/20] iio: adc: adi-axi-adc: " Janani Sunil
2026-08-28 15:30 ` [PATCH v5 05/20] iio: adc: Add AD7768 and AD7768-4 core support Janani Sunil
2026-08-31  9:04   ` Andy Shevchenko
2026-08-31 15:20     ` Janani Sunil
2026-09-01  7:19       ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 06/20] iio: adc: ad7768: Validate master clock rate Janani Sunil
2026-08-28 15:30 ` [PATCH v5 07/20] iio: adc: ad7768: Add power mode helper Janani Sunil
2026-08-31  4:44   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 08/20] iio: adc: ad7768: Derive output data rates Janani Sunil
2026-08-31  8:09   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 09/20] iio: adc: ad7768: Configure channel sampling profiles Janani Sunil
2026-08-31  8:18   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 10/20] iio: adc: ad7768: Add sampling frequency controls Janani Sunil
2026-08-31  8:24   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 11/20] iio: adc: ad7768: Add per-channel filter controls Janani Sunil
2026-08-28 15:30 ` [PATCH v5 12/20] iio: adc: ad7768: Wait for digital filters to settle Janani Sunil
2026-08-31  7:45   ` Andy Shevchenko
2026-08-28 15:30 ` Janani Sunil [this message]
2026-08-31  8:26   ` [PATCH v5 13/20] iio: adc: ad7768: Add calibration controls Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 14/20] iio: adc: ad7768: Add per-channel conversion delay Janani Sunil
2026-08-31  8:30   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 15/20] iio: adc: ad7768: Add VCM regulator support Janani Sunil
2026-08-28 15:30 ` [PATCH v5 16/20] iio: adc: ad7768: Register GPIO auxiliary device Janani Sunil
2026-08-31  8:33   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 17/20] gpio: regmap: Use regmap_test_bits() for single bit reads Janani Sunil
2026-09-02 13:48   ` Bartosz Golaszewski
2026-09-03 12:08     ` Janani Sunil
2026-08-28 15:30 ` [PATCH v5 18/20] gpio: regmap: Add optional runtime PM support Janani Sunil
2026-08-31  7:15   ` Andy Shevchenko
2026-08-28 15:30 ` [PATCH v5 19/20] gpio: ad7768: Add AD7768 GPIO auxiliary driver Janani Sunil
2026-08-28 15:30 ` [PATCH v5 20/20] Documentation: iio: Add AD7768 Documentation Janani Sunil
2026-08-29 18:19 ` [PATCH v5 00/20] iio: adc: Add AD7768/AD7768-4 ADC driver support Jonathan Cameron
2026-08-30  7:12   ` Andy Shevchenko
2026-09-01  8:32 ` Bartosz Golaszewski
2026-09-01 15:44   ` 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=20260828-ad7768-driver-v5-13-e33ca6f841a2@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=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.