From: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>
To: Conor Dooley <conor+dt@kernel.org>,
David Lechner <dlechner@baylibre.com>,
Dumitru Ceclan <dumitru.ceclan@analog.com>,
Jonathan Cameron <jic23@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Lars-Peter Clausen <lars@metafoo.de>,
Michael Hennerich <Michael.Hennerich@analog.com>,
Nuno Sa <nuno.sa@analog.com>, Rob Herring <robh@kernel.org>
Cc: devicetree@vger.kernel.org, linux-iio@vger.kernel.org
Subject: [PATCH v2 3/4] iio: adc: ad_sigma_delta: Add support for reading irq status using a GPIO
Date: Mon, 28 Oct 2024 17:07:52 +0100 [thread overview]
Message-ID: <20241028160748.489596-9-u.kleine-koenig@baylibre.com> (raw)
In-Reply-To: <20241028160748.489596-6-u.kleine-koenig@baylibre.com>
Some of the ADCs by Analog signal their irq condition on the MISO line.
So typically that line is connected to an SPI controller and a GPIO. The
GPIO is used as input and the respective interrupt is enabled when the
last SPI transfer is completed.
Depending on the GPIO controller the toggling MISO line might make the
interrupt pending even while it's masked. In that case the irq handler
is called immediately after irq_enable() and so before the device
actually pulls that line low which results in non-sense values being
reported to the upper layers.
The only way to find out if the line was actually pulled low is to read
the GPIO. (There is a flag in AD7124's status register that also signals
if an interrupt was asserted, but reading that register toggles the MISO
line and so might trigger another spurious interrupt.)
Add the possibility to specify an interrupt GPIO in the machine
description instead of a plain interrupt. This GPIO is used as interrupt
source and to check if the irq line is actually active in the irq
handler.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
drivers/iio/adc/ad_sigma_delta.c | 35 ++++++++++++++++++++++----
include/linux/iio/adc/ad_sigma_delta.h | 1 +
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index e2bed2d648f2..b5785f2a0abe 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -539,12 +539,29 @@ static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
{
struct ad_sigma_delta *sigma_delta = private;
- complete(&sigma_delta->completion);
- disable_irq_nosync(irq);
- sigma_delta->irq_dis = true;
- iio_trigger_poll(sigma_delta->trig);
+ /*
+ * AD7124 and a few others use the same physical line for interrupt
+ * reporting (nRDY) and MISO.
+ * As MISO toggles when reading a register, this likely results in a
+ * pending interrupt. This has two consequences: a) The irq might
+ * trigger immediately after it's enabled even though the conversion
+ * isn't done yet; and b) checking the STATUS register's nRDY flag is
+ * off-limits as reading that would trigger another irq event.
+ *
+ * So read the MOSI line as GPIO (if available) and only trigger the irq
+ * if the line is active.
+ */
- return IRQ_HANDLED;
+ if (!sigma_delta->rdy_gpiod || gpiod_get_value(sigma_delta->rdy_gpiod)) {
+ complete(&sigma_delta->completion);
+ disable_irq_nosync(irq);
+ sigma_delta->irq_dis = true;
+ iio_trigger_poll(sigma_delta->trig);
+
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
}
/**
@@ -679,6 +696,14 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
else
sigma_delta->irq_line = spi->irq;
+ sigma_delta->rdy_gpiod = devm_gpiod_get_optional(&spi->dev, "rdy", GPIOD_IN);
+ if (IS_ERR(sigma_delta->rdy_gpiod))
+ return dev_err_probe(&spi->dev, PTR_ERR(sigma_delta->rdy_gpiod),
+ "Failed to find rdy gpio\n");
+
+ if (sigma_delta->rdy_gpiod && !sigma_delta->irq_line)
+ sigma_delta->irq_line = gpiod_to_irq(sigma_delta->rdy_gpiod);
+
iio_device_set_drvdata(indio_dev, sigma_delta);
return 0;
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h
index f8c1d2505940..866b4c21794b 100644
--- a/include/linux/iio/adc/ad_sigma_delta.h
+++ b/include/linux/iio/adc/ad_sigma_delta.h
@@ -96,6 +96,7 @@ struct ad_sigma_delta {
unsigned int active_slots;
unsigned int current_slot;
unsigned int num_slots;
+ struct gpio_desc *rdy_gpiod;
int irq_line;
bool status_appended;
/* map slots to channels in order to know what to expect from devices */
--
2.45.2
next prev parent reply other threads:[~2024-10-28 16:08 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-28 16:07 [PATCH v2 0/4] iio: adc: ad7124: Make it work on de10-nano Uwe Kleine-König
2024-10-28 16:07 ` [PATCH v2 1/4] dt-bindings: iio: adc: adi,ad7124: Use symbolic name for interrupt flag Uwe Kleine-König
2024-10-29 7:36 ` Krzysztof Kozlowski
2024-10-28 16:07 ` [PATCH v2 2/4] dt-bindings: iio: adc: adi,ad7124: Allow specifications of a gpio for irq line Uwe Kleine-König
2024-11-01 19:20 ` Rob Herring
2024-10-28 16:07 ` Uwe Kleine-König [this message]
2024-10-30 13:04 ` [PATCH v2 3/4] iio: adc: ad_sigma_delta: Add support for reading irq status using a GPIO Nuno Sá
2024-10-30 20:44 ` Jonathan Cameron
2024-10-31 10:40 ` Uwe Kleine-König
2024-10-31 12:05 ` Nuno Sá
2024-10-31 12:28 ` Nuno Sá
2024-11-04 12:49 ` Uwe Kleine-König
2024-11-04 13:15 ` Nuno Sá
2024-11-05 9:20 ` Uwe Kleine-König
2024-11-05 10:30 ` Nuno Sá
2024-10-28 16:07 ` [PATCH v2 4/4] iio: adc: ad7124: Disable all channels at probe time Uwe Kleine-König
2024-10-30 7:17 ` Nuno Sá
2024-10-28 16:38 ` [PATCH v2 0/4] iio: adc: ad7124: Make it work on de10-nano David Lechner
2024-11-18 18:12 ` Uwe Kleine-König
2024-11-23 14:24 ` 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=20241028160748.489596-9-u.kleine-koenig@baylibre.com \
--to=u.kleine-koenig@baylibre.com \
--cc=Michael.Hennerich@analog.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=dumitru.ceclan@analog.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--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