Re: [PATCH v2 3/3] iio: adc: ti-ads112c14: add continuous mode support
From: Jonathan Cameron
Date: Sun Aug 02 2026 - 14:18:08 EST
On Fri, 31 Jul 2026 18:48:12 -0500
"David Lechner (TI)" <dlechner@xxxxxxxxxxxx> wrote:
> Add support for continuous mode in the TI ADS112C14 ADC driver. In this
> mode the ADC itself is starting each conversion, so we add a trigger
> based on the DRDY interrupt to read each sample. This mode is also
> limited in that only one channel can be enabled at a time since the
> chip does not have a sequencer or simultaneous sampling capability.
> Continuous mode will only be used when this new trigger is the current
> trigger.
>
> Signed-off-by: David Lechner (TI) <dlechner@xxxxxxxxxxxx>
There is some follow on stuff in here from the earlier suggestion to
check the status register even when datardy involved
> ---
> drivers/iio/adc/ti-ads112c14.c | 146 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 144 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iio/adc/ti-ads112c14.c b/drivers/iio/adc/ti-ads112c14.c
> index c6d83298c312..5147d10785fb 100644
> --- a/drivers/iio/adc/ti-ads112c14.c
> +++ b/drivers/iio/adc/ti-ads112c14.c
> @@ -9,6 +9,7 @@
> */
>
> #include <linux/bitfield.h>
> +#include <linux/bitmap.h>
> #include <linux/cleanup.h>
> #include <linux/completion.h>
> #include <linux/crc8.h>
> @@ -18,6 +19,7 @@
> #include <linux/i2c.h>
> #include <linux/iio/buffer.h>
> #include <linux/iio/iio.h>
> +#include <linux/iio/trigger.h>
> #include <linux/iio/trigger_consumer.h>
> #include <linux/iio/triggered_buffer.h>
> #include <linux/interrupt.h>
> @@ -257,6 +259,7 @@ struct ads112c14_measurement {
> struct ads112c14_data {
> const struct ads112c14_chip_info *chip_info;
> struct regmap *regmap;
> + struct iio_trigger *drdy_trig;
> /* Synchronizes access to register value fields. */
> struct mutex lock;
> int drdy_irq;
> @@ -280,11 +283,32 @@ static irqreturn_t ads112c14_drdy_irq_handler(int irq, void *private)
> struct iio_dev *indio_dev = private;
> struct ads112c14_data *data = iio_priv(indio_dev);
>
> - complete(&data->drdy_completion);
> + if (indio_dev->trig && iio_trigger_using_own(indio_dev))
> + iio_trigger_poll(data->drdy_trig);
Even for this path we should be checking it wasn't a spurious interrupt.
If that's happening in a threaded interrupt we'll then call iio_trigger_poll_nested()
and the handler will happen in the interrupt thread. So the overhead
of that check should just be the check.
> + else
> + complete(&data->drdy_completion);
For this single shot read we are probably less bothered by overhead so
moving this to a thread should be fine I think.
>
> return IRQ_HANDLED;
> }
>
> +static int ads112c14_trigger_set_state(struct iio_trigger *trig, bool state)
> +{
> + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> + struct ads112c14_data *data = iio_priv(indio_dev);
> +
> + if (state)
> + enable_irq(data->drdy_irq);
> + else
> + disable_irq(data->drdy_irq);
> +
So do we need to do this to avoid some condition, or is this the defensive
stuff you pointed out in that other thread?
I'd normally expect a dataready trigger to be controlling if the interrupt
is generated at all rather than masking host end.
> + return 0;
> +}
> +
> +static const struct iio_trigger_ops ads112c14_trigger_ops = {
> + .set_trigger_state = ads112c14_trigger_set_state,
> + .validate_device = iio_trigger_validate_own_device,
> +};
> +