From: Jonathan Cameron <jic23@kernel.org>
To: sashiko-reviews@lists.linux.dev
Cc: Janani Sunil <janani.sunil@analog.com>,
conor+dt@kernel.org, robh@kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH v6 05/17] iio: adc: Add AD7768 and AD7768-4 core support
Date: Sun, 06 Sep 2026 03:24:54 +0100 [thread overview]
Message-ID: <178866149408.3402141.12120124355772738970.b4-reply@b4> (raw)
In-Reply-To: <20260904143153.9AF1A1F00A3E@smtp.kernel.org>
>
> commit cad3d6d13491f167da3c31d541a31ac850d8d3b5
> Author: Janani Sunil <janani.sunil@analog.com>
>
> iio: adc: Add AD7768 and AD7768-4 core support
>
> Add core support for the AD7768 and AD7768-4 simultaneous sampling ADCs.
> Configure supplies, clock and reset, use a custom regmap bus for the SPI
> protocol, and parse the enabled channels and input buffer settings from
> devicetree.
There was quite a bit of sashiko feedback on this one. I took a look
as getting close to merging the series. Please check my logic.
>
> > diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c
> > new file mode 100644
> > index 0000000000000..c80056a9edd8c
> > --- /dev/null
> > +++ b/drivers/iio/adc/ad7768.c
> > @@ -0,0 +1,1000 @@
> > +// SPDX-License-Identifier: GPL-2.0
>
> [ ... ]
>
> > +#define AD7768_REG_PRECHARGE_BUF1 0x11
> > +#define AD7768_REG_PRECHARGE_BUF2 0x12
> > +#define AD7768_PREBUF_POS_EN(ch) BIT((ch) * 2)
> > +#define AD7768_PREBUF_NEG_EN(ch) BIT(((ch) * 2) + 1)
>
> [Severity: Medium]
> Are these bit assignments for the precharge buffers swapped? According to the
> AD7768 datasheet, the positive (POS) precharge buffers are assigned to odd bits,
> and the negative (NEG) precharge buffers are assigned to even bits.
No they aren't. I think sashiko didn't realize table starts at bit 7
and works down to bit 0.
>
> > +
> > +#define AD7768_REG_REFP_BUF 0x13
> > +#define AD7768_REG_REFN_BUF 0x14
>
> [ ... ]
>
> > +static u8 ad7768_all_standby_mask(const struct ad7768_state *st)
> > +{
> > + return GENMASK(st->chip_info->num_channels - 1, 0);
> > +}
>
> [Severity: High]
> Does this generate the correct physical mask for the AD7768-4? The AD7768-4
> maps its 4 logical channels to physical channels 0, 1, 4, and 5. This returns
> GENMASK(3, 0) which is 0x0F, writing 0 to physical bits 4, 5, 6, and 7,
> leaving them fully active.
>
> [ ... ]
This one looks plausible. There is handling of the bits written to
deal with the mapping but not the mask I think. Please take a look.
>
> > +static int ad7768_regmap_read(void *context, const void *reg_buf,
> > + size_t reg_size, void *val_buf, size_t val_size)
> > +{
> > + struct ad7768_state *st = spi_get_drvdata(context);
> > + struct spi_device *spi = context;
> > + struct spi_transfer t[] = {
> > + {
> > + .tx_buf = &st->d16,
> > + .len = sizeof(st->d16),
> > + .cs_change = 1,
> > + }, {
> > + /*
> > + * Register responses are delayed by one CS frame. While
> > + * receiving the response to this read, the device also
> > + * decodes another command on SDI. Repeat the read
> > + * command to avoid sending an unspecified dummy
> > + * command.
> > + */
> > + .tx_buf = &st->d16,
> > + .rx_buf = &st->d16,
> > + .len = sizeof(st->d16),
> > + },
> > + };
>
> [Severity: High]
> Can this violate the DMA API? Both transfers use the same memory address
> (&st->d16) for their buffers. When the SPI subsystem maps all transfers for
> DMA concurrently, attempting to map the same memory region twice concurrently
> (DMA_TO_DEVICE and DMA_BIDIRECTIONAL) can cause cache coherency issues on
> non-coherent architectures.
So this one I'm fairly sure on, but feel free to check.
There is nothing stopping SPI using one buffer for both directions. If it's a
problem for a particular setup I think they have to bounce it.
>
> [ ... ]
>
> > +static int ad7768_update_scan_mode(struct iio_dev *indio_dev,
> > + const unsigned long *scan_mask)
> > +{
> > + struct ad7768_state *st = iio_priv(indio_dev);
> > + unsigned long channel_mask;
> > + unsigned long standby_mask;
> > + int ret;
> > +
> > + channel_mask = ad7768_all_standby_mask(st);
> > + standby_mask = channel_mask & ~*scan_mask;
> > +
> > + /*
> > + * Crystal excitation requires channel 4 on AD7768 or channel 2 on
> > + * AD7768-4 to remain active.
> > + */
> > + if (st->clock_source == AD7768_CLOCK_SOURCE_XTAL)
> > + __clear_bit(st->chip_info->num_channels / 2, &standby_mask);
> > +
> > + ret = regmap_update_bits(st->regmap, AD7768_REG_CH_STANDBY,
> > + channel_mask, standby_mask);
> > + if (ret)
> > + return ret;
> > +
> > + for (unsigned int c = 0; c < st->chip_info->num_channels; c++) {
> > + if (test_bit(c, scan_mask))
> > + ret = iio_backend_chan_enable(st->back, c);
> > + else
> > + ret = iio_backend_chan_disable(st->back, c);
> > + if (ret)
> > + return ret;
> > + }
>
> [Severity: Medium]
> Will this leave the backend hardware out of sync if an error occurs? If one
> operation fails, it returns the error immediately without unwinding the
> previously modified channels.
This is one of those error cases where unwinding may just be impractical.
Real question is whether there is anything that means trying again won't
end up in a sane state or that anything particularly bad will happen
as a result of the bad state in the meantime. I think this is fine
but please check.
>
> > +
> > + return 0;
> > +}
>
> [ ... ]
>
> > +static int ad7768_buffer_postdisable(struct iio_dev *indio_dev)
> > +{
> > + struct ad7768_state *st = iio_priv(indio_dev);
> > +
> > + pm_runtime_put_autosuspend(regmap_get_device(st->regmap));
> > + return 0;
> > +}
>
> [Severity: Medium]
> Could this leave the hardware powered on after device removal?
>
> If the driver is unbound while the IIO buffer is active,
> devm_iio_device_register unwinds first, calling iio_device_unregister(),
> which disables the buffer and triggers ad7768_buffer_postdisable().
>
> Immediately after, devm_pm_runtime_set_active_enabled unwinds, calling
> pm_runtime_disable() which cancels the pending autosuspend work. The
> driver should ensure synchronous suspend if the buffer is active during
> removal.
Ah. Interesting corner case. There are probably lots of other
paths to the power happening to be on at shut down but I can see
maybe we ultimately want a flag to say we are going down in that
buffer disable path. Anyhow, you should be careful to ensure it
doesn't matter what state we are in wrt to runtime pm, after we've
turned that off we should make sure we turn off the device by hand.
Afterall maybe runtime pm was never enabled in the first place
(or even built!)
>
> [ ... ]
>
> > +static int ad7768_configure_precharge_buffers(struct iio_dev *indio_dev,
> > + struct ad7768_precharge_config *precharge_cfg)
> > +{
> > + struct ad7768_state *st = iio_priv(indio_dev);
> > + u8 prebuf1_val, prebuf2_val;
> > + u16 prebuf_mask = 0;
> > + u8 refbufp_val = 0;
> > + u8 refbufn_val = 0;
> > + int ret;
> > +
> > + for (unsigned int ch = 0; ch < indio_dev->num_channels; ch++) {
> > + u8 channel = indio_dev->channels[ch].channel;
> > +
> > + if (precharge_cfg[channel].prebufp_en)
> > + prebuf_mask |= AD7768_PREBUF_POS_EN(channel);
> > +
> > + if (precharge_cfg[channel].prebufn_en)
> > + prebuf_mask |= AD7768_PREBUF_NEG_EN(channel);
> > +
> > + if (precharge_cfg[channel].refbufp)
> > + refbufp_val |= ad7768_channel_mask(st, channel);
> > +
> > + if (precharge_cfg[channel].refbufn)
> > + refbufn_val |= ad7768_channel_mask(st, channel);
> > + }
>
> [Severity: Medium]
> Does this apply the incorrect polarity for the reference buffer configuration?
> When adi,refbuf-pos-enable or adi,refbuf-neg-enable are provided in the device
> tree, the driver sets the corresponding bit to 1. According to the AD7768
> datasheet, setting a bit to 1 in the REFP_BUF and REFN_BUF registers powers down
> the buffer.
I'm not sure what datasheet sashiko has. Mine says 1 is power up.
I'm going to guess it's assuming layout of values that aren't true.
>
> [ ... ]
>
> > + device_for_each_named_child_node_scoped(dev, child, "channel") {
> > + u32 channel;
> > +
> > + ret = fwnode_property_read_u32(child, "reg", &channel);
> > + if (ret)
> > + return dev_err_probe(dev, ret,
> > + "Failed to parse reg of %pfwP\n",
> > + child);
> > +
> > + if (channel >= st->chip_info->num_channels)
> > + return dev_err_probe(dev, -ECHRNG,
> > + "Invalid channel %u in firmware\n",
> > + channel);
> > +
> > + ret = regmap_clear_bits(st->regmap, AD7768_REG_CH_STANDBY,
> > + BIT(channel));
>
> [Severity: High]
> Does this use logical indices instead of physical bits for the AD7768-4? The
> AD7768-4 uses physical channels 0, 1, 4, and 5. Using BIT(channel) will update
> physical bits 0-3 instead of the mapped hardware bits.
This seems plausible. Please check.
>
> > + if (ret)
> > + return ret;
> > +
>
> [ ... ]
>
> > + pm_runtime_set_autosuspend_delay(dev, 2000);
> > + pm_runtime_use_autosuspend(dev);
> > + ret = devm_pm_runtime_set_active_enabled(dev);
> > + if (ret)
> > + return ret;
> > +
> > + return devm_iio_device_register(dev, indio_dev);
> > +}
>
> [Severity: Medium]
> Does this leave the device permanently active? This configures autosuspend and
> enables runtime PM, which transitions the device to RPM_ACTIVE with a usage
> count of 0, but fails to call pm_request_idle(dev). As a result, the autosuspend
> timer is never triggered, leaving the device fully powered indefinitely until
> a user explicitly accesses it.
Nope. This is usual thing of sashiko failing to notice the stuff
in base/dd.c that always checks if the reference count is 0 and hence
it can put it to sleep. This happens just after probe.
So a definite mixed bag for sashiko on this one.
Jonathan
next prev parent reply other threads:[~2026-09-06 2:25 UTC|newest]
Thread overview: 28+ 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-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 [this message]
2026-09-06 3:05 ` Jonathan Cameron
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-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-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-04 14:15 ` [PATCH v6 14/17] iio: adc: ad7768: Add per-channel conversion delay Janani Sunil
2026-09-04 14:33 ` sashiko-bot
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
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=178866149408.3402141.12120124355772738970.b4-reply@b4 \
--to=jic23@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=janani.sunil@analog.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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