From: Jonathan Cameron <jic23@kernel.org>
To: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
Michael Hennerich <Michael.Hennerich@analog.com>,
linux-iio@vger.kernel.org
Subject: Re: [PATCH v2 5/6] iio: adc: ad7124: Implement internal calibration at probe time
Date: Sat, 22 Feb 2025 14:44:49 +0000 [thread overview]
Message-ID: <20250222144449.43ad5948@jic23-huawei> (raw)
In-Reply-To: <deef14543f8f5ff34076e69d90711bbe719c4d12.1739902968.git.u.kleine-koenig@baylibre.com>
On Tue, 18 Feb 2025 19:31:12 +0100
Uwe Kleine-König <u.kleine-koenig@baylibre.com> wrote:
> Use the calibration function provided by the ad_sigma_delta shim to
> calibrate all channels at probe time.
>
> For measurements with gain 1 (i.e. if CONFIG_x.PGA = 0) full-scale
> calibrations are not supported and the reset default value of the GAIN
> register is supposed to be used then.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
one passing comment inline.
> +static int ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio_dev)
> +{
> + struct device *dev = &st->sd.spi->dev;
> + int ret, i;
> + unsigned int adc_control = st->adc_control;
Maybe factor out from here...
> +
> + /*
> + * Calibration isn't supported at full power, so speed down a bit.
> + * Setting .adc_control is enough here because the control register is
> + * written as part of ad_sd_calibrate() -> ad_sigma_delta_set_mode().
> + */
> + if (FIELD_GET(AD7124_ADC_CTRL_PWR_MSK, adc_control) >= AD7124_FULL_POWER) {
> + st->adc_control &= ~AD7124_ADC_CTRL_PWR_MSK;
> + st->adc_control |= AD7124_ADC_CTRL_PWR(AD7124_MID_POWER);
> + }
> +
> + for (i = 0; i < st->num_channels; i++) {
> +
> + if (indio_dev->channels[i].type != IIO_VOLTAGE)
> + continue;
> +
> + /*
> + * For calibration the OFFSET register should hold its reset default
> + * value. For the GAIN register there is no such requirement but
> + * for gain 1 it should hold the reset default value, too. So to
> + * simplify matters use the reset default value for both.
> + */
> + st->channels[i].cfg.calibration_offset = 0x800000;
> + st->channels[i].cfg.calibration_gain = st->gain_default;
> +
> + /*
> + * Full-scale calibration isn't supported at gain 1, so skip in
> + * that case. Note that untypically full-scale calibration has
> + * to happen before zero-scale calibration. This only applies to
> + * the internal calibration. For system calibration it's as
> + * usual: first zero-scale then full-scale calibration.
> + */
> + if (st->channels[i].cfg.pga_bits > 0) {
> + ret = ad_sd_calibrate(&st->sd, AD7124_MODE_CAL_INT_FULL, i);
> + if (ret < 0)
> + goto out;
> +
> + /*
> + * read out the resulting value of GAIN
> + * after full-scale calibration because the next
> + * ad_sd_calibrate() call overwrites this via
> + * ad_sigma_delta_set_channel() -> ad7124_set_channel()
> + * ... -> ad7124_enable_channel().
> + */
> + ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(st->channels[i].cfg.cfg_slot), 3,
> + &st->channels[i].cfg.calibration_gain);
> + if (ret < 0)
> + goto out;
> + }
> +
> + ret = ad_sd_calibrate(&st->sd, AD7124_MODE_CAL_INT_ZERO, i);
> + if (ret < 0)
> + goto out;
> +
> + ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(st->channels[i].cfg.cfg_slot), 3,
> + &st->channels[i].cfg.calibration_offset);
> + if (ret < 0)
> + goto out;
> +
> + dev_dbg(dev, "offset and gain for channel %d = 0x%x + 0x%x\n", i,
> + st->channels[i].cfg.calibration_offset,
> + st->channels[i].cfg.calibration_gain);
> + }
to here as a ad7124_do_calibrate_all() or something like that.
Then you can do direct returns and it becomes really obvious this function
is stashing and restoring the adc_control value.
I don't mind that much as the flow is fairly simple.
> +
> +out:
> + st->adc_control = adc_control;
> +
> + return ret;
> +}
> +
> static void ad7124_reg_disable(void *r)
> {
> regulator_disable(r);
> @@ -1132,6 +1241,10 @@ static int ad7124_probe(struct spi_device *spi)
> if (ret < 0)
> return dev_err_probe(dev, ret, "Failed to setup triggers\n");
>
> + ret = ad7124_calibrate_all(st, indio_dev);
> + if (ret)
> + return ret;
> +
> ret = devm_iio_device_register(&spi->dev, indio_dev);
> if (ret < 0)
> return dev_err_probe(dev, ret, "Failed to register iio device\n");
next prev parent reply other threads:[~2025-02-22 14:44 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-18 18:31 [PATCH v2 0/6] iio: adc: ad{4130,7124,7173}: A few fixes and ad7124 calibration Uwe Kleine-König
2025-02-18 18:31 ` [PATCH v2 1/6] iio: adc: ad_sigma_delta: Disable channel after calibration Uwe Kleine-König
2025-02-18 18:31 ` [PATCH v2 2/6] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König
2025-02-18 19:18 ` David Lechner
2025-02-19 8:53 ` Andy Shevchenko
2025-02-19 15:54 ` Uwe Kleine-König
2025-02-18 18:31 ` [PATCH v2 3/6] iio: adc: ad7124: Fix comparison of channel configs Uwe Kleine-König
2025-02-18 18:31 ` [PATCH v2 4/6] iio: adc: ad7173: " Uwe Kleine-König
2025-02-18 18:31 ` [PATCH v2 5/6] iio: adc: ad7124: Implement internal calibration at probe time Uwe Kleine-König
2025-02-22 14:44 ` Jonathan Cameron [this message]
2025-02-18 18:31 ` [PATCH v2 6/6] iio: adc: ad7124: Implement system calibration Uwe Kleine-König
2025-02-18 19:37 ` David Lechner
2025-02-21 18:23 ` Uwe Kleine-König
2025-02-19 10:45 ` Nuno Sá
2025-02-22 14:48 ` [PATCH v2 0/6] iio: adc: ad{4130,7124,7173}: A few fixes and ad7124 calibration 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=20250222144449.43ad5948@jic23-huawei \
--to=jic23@kernel.org \
--cc=Michael.Hennerich@analog.com \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox