From: Tim auf der Landwehr <tadl-git@taufderl.de>
To: Kristian Brox <isyourbrainfoss@proton.me>
Cc: David Heidelberg <david@ixit.cz>,
luca.weiss@fairphone.com, oe-linux-nfc@lists.linux.dev,
linux-kernel@vger.kernel.org,
Tim auf der Landwehr <tadl-git@taufderl.de>
Subject: [PATCH 2/3] nfc: st-nci: restart the reference clock on power-up
Date: Wed, 30 Sep 2026 00:41:24 +0200 [thread overview]
Message-ID: <20260929224125.3656680-3-tadl-git@taufderl.de> (raw)
In-Reply-To: <20260902-fp5-st21nfcd-v4-v4-0-ded2f1c501be@proton.me>
On the Fairphone 4 (and reported on the Fairphone 5), the ST21NFCD stops
answering NCI after a poll enable/disable cycle: the next NFC_CMD_DEV_UP
sends CORE_RESET and never gets a response (__nci_request timeout,
nfc_dev_up: SE discovery failed), and the controller stays dead until a
reboot. No tag is needed to trigger it; enable/disable/enable polling is
enough.
A reset pulse alone does not recover the part; its input clock has to be
stopped and restarted. The driver enabled the clock once at probe and left
it running, so only re-probing (which cycles the clock) recovered it.
Cycle the reference clock in the power-up path, while the controller is
held in reset. Scope it to the raw-NCI (st21nfcd) part so the NDLC parts
are untouched; the reset-assert delay stays unconditional.
Signed-off-by: Tim auf der Landwehr <tadl-git@taufderl.de>
---
drivers/nfc/st-nci/i2c.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/nfc/st-nci/i2c.c b/drivers/nfc/st-nci/i2c.c
index e527d3cc9..16f643b3a 100644
--- a/drivers/nfc/st-nci/i2c.c
+++ b/drivers/nfc/st-nci/i2c.c
@@ -46,6 +46,7 @@ struct st_nci_i2c_phy {
bool irq_active;
bool raw_nci;
+ struct clk *clk;
struct gpio_desc *gpiod_reset;
struct st_nci_se_status se_status;
@@ -60,15 +61,29 @@ static int st_nci_i2c_enable(void *phy_id)
* chip-running. GPIO_ACTIVE_LOW: logical 1 asserts reset
* (physical LOW).
*/
- if (gpiod_is_active_low(phy->gpiod_reset)) {
+ if (gpiod_is_active_low(phy->gpiod_reset))
gpiod_set_value(phy->gpiod_reset, 1);
- usleep_range(10000, 15000);
+ else
gpiod_set_value(phy->gpiod_reset, 0);
- } else {
+
+ /*
+ * The ST21NFCD (raw NCI) stops answering NCI after a poll on/off cycle
+ * and does not recover on a reset pulse alone: its input clock has to be
+ * stopped and restarted. The clock is enabled once at probe, so cycle it
+ * here, while the controller is held in reset, on every power-up. Scoped
+ * to the raw-NCI part; the NDLC parts keep their previous timing. The
+ * usleep below is the reset-assert width and stays unconditional.
+ */
+ if (phy->raw_nci)
+ clk_disable_unprepare(phy->clk);
+ usleep_range(10000, 15000);
+ if (phy->raw_nci)
+ clk_prepare_enable(phy->clk);
+
+ if (gpiod_is_active_low(phy->gpiod_reset))
gpiod_set_value(phy->gpiod_reset, 0);
- usleep_range(10000, 15000);
+ else
gpiod_set_value(phy->gpiod_reset, 1);
- }
usleep_range(80000, 85000);
if (phy->ndlc->powered == 0 && phy->irq_active == 0) {
@@ -282,9 +297,10 @@ static int st_nci_i2c_probe(struct i2c_client *client)
if (r && r != -ENODEV)
return dev_err_probe(dev, r, "failed to enable vdd-io\n");
- r = PTR_ERR_OR_ZERO(devm_clk_get_optional_enabled(dev, NULL));
- if (r)
- return dev_err_probe(dev, r, "failed to enable clock\n");
+ phy->clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (IS_ERR(phy->clk))
+ return dev_err_probe(dev, PTR_ERR(phy->clk),
+ "failed to enable clock\n");
/* Get RESET GPIO */
phy->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
--
2.55.0
next prev parent reply other threads:[~2026-09-29 22:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 21:22 [PATCH v4 0/3] nfc: st-nci: Fairphone 5 NFC bring-up (ST21NFCD) Kristian Brox
2026-09-02 21:22 ` [PATCH v4 1/3] dt-bindings: net: nfc: add st,st21nfcd Kristian Brox
2026-09-03 13:47 ` Krzysztof Kozlowski
2026-09-02 21:22 ` [PATCH v4 2/3] nfc: st-nci: add raw NCI path for ST21NFCD Kristian Brox
2026-09-03 21:22 ` sashiko-bot
2026-09-02 21:22 ` [PATCH v4 3/3] arm64: dts: qcom: qcm6490-fairphone-fp5: add ST21NFCD NFC Kristian Brox
2026-09-03 6:49 ` Konrad Dybcio
2026-09-03 7:49 ` Abel Vesa
2026-09-03 21:22 ` sashiko-bot
2026-09-18 8:08 ` [PATCH v4 0/3] nfc: st-nci: Fairphone 5 NFC bring-up (ST21NFCD) Luca Weiss
2026-09-23 19:35 ` Kristian Brox
2026-09-29 22:41 ` [PATCH 0/3] nfc: st-nci: three ST21NFCD fixes found bringing v4 up on the Fairphone 4 Tim auf der Landwehr
2026-09-29 22:41 ` [PATCH 1/3] nfc: st-nci: map proprietary RF 0x90 to MIFARE Tim auf der Landwehr
2026-09-29 22:41 ` Tim auf der Landwehr [this message]
2026-09-29 22:41 ` [PATCH 3/3] nfc: st-nci: treat the idle 0x7e read as no-data Tim auf der Landwehr
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=20260929224125.3656680-3-tadl-git@taufderl.de \
--to=tadl-git@taufderl.de \
--cc=david@ixit.cz \
--cc=isyourbrainfoss@proton.me \
--cc=linux-kernel@vger.kernel.org \
--cc=luca.weiss@fairphone.com \
--cc=oe-linux-nfc@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.