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,
linux-iio@vger.kernel.org, "Nuno Sá" <nuno.sa@analog.com>,
"Michael Hennerich" <Michael.Hennerich@analog.com>,
"David Lechner" <dlechner@baylibre.com>,
"Andy Shevchenko" <andy@kernel.org>
Subject: Re: [PATCH v6 05/17] iio: adc: Add AD7768 and AD7768-4 core support
Date: Sun, 6 Sep 2026 04:05:17 +0100 [thread overview]
Message-ID: <20260906040517.480347b2@jic23-huawei> (raw)
In-Reply-To: <178866149408.3402141.12120124355772738970.b4-reply@b4>
On Sun, 06 Sep 2026 03:24:54 +0100
Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > 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.
oops. I replied to this but the sashiko email only ever went to the
device tree list not all the other places the original thread went.
Added linux-iio and a few others.
>
> >
> > > 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 3:05 UTC|newest]
Thread overview: 38+ 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 [this message]
2026-09-06 3:50 ` Jonathan Cameron
2026-09-07 11:25 ` Janani Sunil
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 ` [PATCH v6 14/17] iio: adc: ad7768: Add per-channel conversion delay Janani Sunil
2026-09-04 14:33 ` 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=20260906040517.480347b2@jic23-huawei \
--to=jic23@kernel.org \
--cc=Michael.Hennerich@analog.com \
--cc=andy@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=janani.sunil@analog.com \
--cc=linux-iio@vger.kernel.org \
--cc=nuno.sa@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