devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Marcelo Schmitt <marcelo.schmitt@analog.com>
Cc: <linux-iio@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-gpio@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Ana-Maria Cusco <ana-maria.cusco@analog.com>, <lars@metafoo.de>,
	<Michael.Hennerich@analog.com>, <dlechner@baylibre.com>,
	<nuno.sa@analog.com>, <andy@kernel.org>, <robh@kernel.org>,
	<krzk+dt@kernel.org>, <conor+dt@kernel.org>,
	<linus.walleij@linaro.org>, <brgl@bgdev.pl>,
	<marcelo.schmitt1@gmail.com>
Subject: Re: [PATCH v3 02/10] iio: adc: Add basic support for AD4170
Date: Sun, 25 May 2025 11:36:59 +0100	[thread overview]
Message-ID: <20250525113659.2661c8d7@jic23-huawei> (raw)
In-Reply-To: <2c308bf8464660079ec6da82a62316e9f2ebd5f7.1747083143.git.marcelo.schmitt@analog.com>

On Tue, 13 May 2025 09:34:00 -0300
Marcelo Schmitt <marcelo.schmitt@analog.com> wrote:

> From: Ana-Maria Cusco <ana-maria.cusco@analog.com>
> 
> The AD4170 is a multichannel, low noise, 24-bit precision sigma-delta
> analog to digital converter. The AD4170 design offers a flexible data
> aquisition solution with crosspoint multiplexed analog inputs, configurable
> ADC voltage reference inputs, ultra-low noise integrated PGA, digital
> filtering, wide range of configurable output data rates, internal
> oscillator and temperature sensor, four GPIOs, and integrated features for
> interfacing with load cell weigh scales, RTD, and thermocouple sensors.
> 
> Add basic support for the AD4170 ADC with the following features:
> - Single-shot read.
> - Analog front end PGA configuration.
> - Differential and pseudo-differential input configuration.
> 
> Signed-off-by: Ana-Maria Cusco <ana-maria.cusco@analog.com>
> Co-developed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
> Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>

A few minor things inline.

J

> diff --git a/drivers/iio/adc/ad4170.c b/drivers/iio/adc/ad4170.c
> new file mode 100644
> index 000000000000..bf19b31095ee
> --- /dev/null
> +++ b/drivers/iio/adc/ad4170.c

> +
> +/*
> + * Verifies whether the channel configuration is valid by checking the provided
> + * input type, polarity, and voltage references result in a sane input range.
> + * Returns negative error code on failure.
> + */
> +static int ad4170_get_input_range(struct ad4170_state *st,
> +				  struct iio_chan_spec const *chan,
> +				  unsigned int ch_reg, unsigned int ref_sel)
> +{
> +	bool bipolar = chan->scan_type.sign == 's';
> +	struct device *dev = &st->spi->dev;
> +	int refp, refn, ain_voltage, ret;
> +
> +	switch (ref_sel) {
> +	case AD4170_REF_REFIN1:
> +		if (st->vrefs_uv[AD4170_REFIN1P_SUP] == -ENODEV ||
> +		    st->vrefs_uv[AD4170_REFIN1N_SUP] == -ENODEV)
> +			return dev_err_probe(dev, -ENODEV,
> +					     "REFIN± selected but not provided\n");
> +
> +		refp = st->vrefs_uv[AD4170_REFIN1P_SUP];
> +		refn = st->vrefs_uv[AD4170_REFIN1N_SUP];
> +		break;
> +	case AD4170_REF_REFIN2:
> +		if (st->vrefs_uv[AD4170_REFIN2P_SUP] == -ENODEV ||
> +		    st->vrefs_uv[AD4170_REFIN2N_SUP] == -ENODEV)
> +			return dev_err_probe(dev, -ENODEV,
> +					     "REFIN2± selected but not provided\n");
> +
> +		refp = st->vrefs_uv[AD4170_REFIN2P_SUP];
> +		refn = st->vrefs_uv[AD4170_REFIN2N_SUP];
> +		break;
> +	case AD4170_REF_AVDD:
> +		refp = st->vrefs_uv[AD4170_AVDD_SUP];
> +		refn = st->vrefs_uv[AD4170_AVSS_SUP];
> +		break;
> +	case AD4170_REF_REFOUT:
> +		/* REFOUT is 2.5 V relative to AVSS */
> +		refp = st->vrefs_uv[AD4170_AVSS_SUP] + AD4170_INT_REF_2_5V;
> +		refn = st->vrefs_uv[AD4170_AVSS_SUP];
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * Find out the analog input range from the channel type, polarity, and
> +	 * voltage reference selection.
> +	 * AD4170 channels are either differential or pseudo-differential.
> +	 * Diff input voltage range: −VREF/gain to +VREF/gain (datasheet page 6)
> +	 * Pseudo-diff input voltage range: 0 to VREF/gain (datasheet page 6)
> +	 */
> +	if (chan->differential) {
> +		if (!bipolar)
> +			return dev_err_probe(&st->spi->dev, -EINVAL,

dev

> +					     "Channel %u differential unipolar\n",
> +					     ch_reg);
> +
> +		/*
> +		 * Differential bipolar channel.
> +		 * avss-supply is never above 0V.
> +		 * Assuming refin1n-supply not above 0V.
> +		 * Assuming refin2n-supply not above 0V.
> +		 */
> +		return refp + abs(refn);
> +	}
> +	/*
> +	 * Some configurations can lead to invalid setups.
> +	 * For example, if AVSS = -2.5V, REF_SELECT set to REFOUT (REFOUT/AVSS),
> +	 * and pseudo-diff channel configuration set, then the input range
> +	 * should go from 0V to +VREF (single-ended - datasheet pg 10), but
> +	 * REFOUT/AVSS range would be -2.5V to 0V.
> +	 * Check the positive reference is higher than 0V for pseudo-diff
> +	 * channels.
> +	 */
> +	if (refp <= 0)
> +		return dev_err_probe(&st->spi->dev, -EINVAL,

dev

> +				     "REF+ <= GND for pseudo-diff chan %u\n",
> +				     ch_reg);
> +
> +	if (bipolar)
> +		return refp;
> +
> +	/*
> +	 * Pseudo-differential unipolar channel.
> +	 * Input expected to swing from IN- to +VREF.
> +	 */
> +	ret = ad4170_get_ain_voltage_uv(st, chan->channel2, &ain_voltage);
> +	if (ret)
> +		return ret;
> +
> +	if (refp - ain_voltage <= 0)
> +		return dev_err_probe(&st->spi->dev, -EINVAL,

dev

> +				     "Negative input >= REF+ for pseudo-diff chan %u\n",
> +				     ch_reg);
> +
> +	return refp - ain_voltage;
> +}



> +static int ad4170_parse_reference(struct ad4170_state *st,
> +				  struct fwnode_handle *child,
> +				  struct ad4170_setup *setup)
> +{
> +	struct device *dev = &st->spi->dev;
> +	int ret;
> +	u8 aux;
> +
> +	/* Optional positive reference buffering, if omitted we use the default */

I'd drop the "if omitted" part as the next line makes that clear.

> +	aux = AD4170_REF_BUF_FULL; /* Default to full precharge buffer enabled. */
> +	ret = fwnode_property_read_u8(child, "adi,buffered-positive", &aux);
> +	if (!ret) {
> +		if (aux < AD4170_REF_BUF_PRE || aux > AD4170_REF_BUF_BYPASS)

Given default is within these limits (I assume!), can simplified as:

	aux = AD4170_REF_BUF_FULL;
	fwnode_property_read_u8(child, "adi,buffered-positive", &aux);
	if (aux < AD4170_REF_BUF_PRE || aux > AD4170_REF_BUF_BYPASS)
		return dev_err_probe(dev, -EINVAL,
				     "Invalid adi,buffered-positive: %u\n", aux);

	setup->afe |= FIELD_PREP(AD4170_AFE_REF_BUF_P_MSK, aux);


> +					     aux);
> +			return dev_err_probe(dev, -EINVAL,
> +					     "Invalid adi,buffered-positive: %u\n",
> +					     aux);
> +	}
> +	setup->afe |= FIELD_PREP(AD4170_AFE_REF_BUF_P_MSK, aux);
> +
> +	/* Optional negative reference buffering, if omitted we use the default */
> +	aux = AD4170_REF_BUF_FULL; /* Default to full precharge buffer enabled. */

Similar refactor to above applies here and dropping the obvious what happens
if omitted comment.

> +	ret = fwnode_property_read_u8(child, "adi,buffered-negative", &aux);
> +	if (!ret) {
> +		if (aux < AD4170_REF_BUF_PRE || aux > AD4170_REF_BUF_BYPASS)
> +			return dev_err_probe(dev, -EINVAL,
> +					     "Invalid adi,buffered-negative: %u\n",
> +					     aux);
> +	}
> +	setup->afe |= FIELD_PREP(AD4170_AFE_REF_BUF_M_MSK, aux);
> +
> +	/* Optional voltage reference selection, if omitted we use the default */
> +	aux = AD4170_REF_REFOUT; /* Default reference selection. */

And here.

> +	ret = fwnode_property_read_u8(child, "adi,reference-select", &aux);
> +	if (!ret) {
> +		if (aux > AD4170_REF_AVDD)
> +			return dev_err_probe(dev, -EINVAL,
> +					     "Invalid reference selected %u\n",
> +					     aux);
> +	}
> +	setup->afe |= FIELD_PREP(AD4170_AFE_REF_SELECT_MSK, aux);
> +
> +	return 0;
> +}
> +
> +static int ad4170_parse_adc_channel_type(struct device *dev,
> +					 struct fwnode_handle *child,
> +					 struct iio_chan_spec *chan)
> +{
> +	u32 pins[2];
> +	int ret, ret2;
> +
> +	/* Parse pseudo-differential channel configuration */
> +	ret = fwnode_property_read_u32(child, "single-channel", &pins[0]);
> +	ret2 = fwnode_property_read_u32(child, "common-mode-channel", &pins[1]);
> +	if (!ret && ret2)
> +		return dev_err_probe(dev, ret,
> +			"single-ended channels must define common-mode-channel\n");

ret == 0 so that will report success.

Move the ret2 logic down into this (!ret) statement that comes next then you
can just use ret and avoid this sort of issue. (Likely smatch would have
caught this but better to never have a bug report + fix :)


> +	if (!ret) {
> +		chan->differential = false;
> +		chan->channel = pins[0];
> +		chan->channel2 = pins[1];
> +		return 0;
> +	}
> +
> +	/* Parse differential channel configuration */
> +	ret = fwnode_property_read_u32_array(child, "diff-channels", pins,
> +					     ARRAY_SIZE(pins));
> +	if (!ret) {
> +		chan->differential = true;
> +		chan->channel = pins[0];
> +		chan->channel2 = pins[1];
> +		return 0;
> +	}
> +	return dev_err_probe(dev, ret,
> +		"Channel must define one of diff-channels or single-channel.\n");
> +}

> +
> +static int ad4170_probe(struct spi_device *spi)
> +{

> +
> +	init_completion(&st->completion);
> +
> +	if (spi->irq) {
> +		ret = devm_request_irq(&st->spi->dev, st->spi->irq,

Use dev and spi->irq.




> +				       &ad4170_irq_handler, IRQF_ONESHOT,
> +				       indio_dev->name, indio_dev);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return devm_iio_device_register(dev, indio_dev);
> +}

  reply	other threads:[~2025-05-25 10:37 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-13 12:32 [PATCH v3 00/10] Add support for AD4170 series of ADCs Marcelo Schmitt
2025-05-13 12:33 ` [PATCH v3 01/10] dt-bindings: iio: adc: Add AD4170 Marcelo Schmitt
2025-05-13 15:47   ` David Lechner
2025-05-16 15:45     ` Marcelo Schmitt
2025-05-16 16:06       ` David Lechner
2025-05-21  8:33       ` Krzysztof Kozlowski
2025-05-21  8:41   ` Krzysztof Kozlowski
2025-05-22 15:07     ` Marcelo Schmitt
2025-05-25 10:05       ` Jonathan Cameron
2025-05-25 10:11   ` Jonathan Cameron
2025-05-26 21:59     ` Marcelo Schmitt
2025-05-31 15:50       ` Jonathan Cameron
2025-05-13 12:34 ` [PATCH v3 02/10] iio: adc: Add basic support for AD4170 Marcelo Schmitt
2025-05-25 10:36   ` Jonathan Cameron [this message]
2025-05-26 10:21   ` Nuno Sá
2025-05-13 12:34 ` [PATCH v3 03/10] iio: adc: ad4170: Add support for calibration gain Marcelo Schmitt
2025-05-26 10:24   ` Nuno Sá
2025-05-13 12:34 ` [PATCH v3 04/10] iio: adc: ad4170: Add support for calibration bias Marcelo Schmitt
2025-05-26 10:27   ` Nuno Sá
2025-05-13 12:35 ` [PATCH v3 05/10] iio: adc: ad4170: Add digital filter and sample frequency config support Marcelo Schmitt
2025-05-25 10:41   ` Jonathan Cameron
2025-05-13 12:35 ` [PATCH v3 06/10] iio: adc: ad4170: Add support for buffered data capture Marcelo Schmitt
2025-05-25 10:46   ` Jonathan Cameron
2025-05-13 12:35 ` [PATCH v3 07/10] iio: adc: ad4170: Add clock provider support Marcelo Schmitt
2025-05-13 16:59   ` David Lechner
2025-05-13 12:36 ` [PATCH v3 08/10] iio: adc: ad4170: Add GPIO controller support Marcelo Schmitt
2025-05-20 17:06   ` Bartosz Golaszewski
2025-05-13 12:36 ` [PATCH v3 09/10] iio: adc: ad4170: Add support for internal temperature sensor Marcelo Schmitt
2025-05-13 12:36 ` [PATCH v3 10/10] iio: adc: ad4170: Add support for weigh scale and RTD sensors Marcelo Schmitt
2025-05-25 10:57   ` 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=20250525113659.2661c8d7@jic23-huawei \
    --to=jic23@kernel.org \
    --cc=Michael.Hennerich@analog.com \
    --cc=ana-maria.cusco@analog.com \
    --cc=andy@kernel.org \
    --cc=brgl@bgdev.pl \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=krzk+dt@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo.schmitt1@gmail.com \
    --cc=marcelo.schmitt@analog.com \
    --cc=nuno.sa@analog.com \
    --cc=robh@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).