From: Marek Vasut <marex@nabladev.com>
To: linux-input@vger.kernel.org
Cc: Marek Vasut <marex@nabladev.com>,
Conor Dooley <conor+dt@kernel.org>,
Dmitry Torokhov <dmitry.torokhov@gmail.com>,
Jens Reidel <adrian@mainlining.org>,
Joel Selvaraj <foss@joelselvaraj.com>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Rob Herring <robh@kernel.org>,
Wolfram Sang <wsa+renesas@sang-engineering.com>,
devicetree@vger.kernel.org, kernel@dh-electronics.com,
linux-kernel@vger.kernel.org
Subject: [PATCH 2/2] Input: edt-ft5x06 - add support for polling mode
Date: Fri, 9 Jan 2026 04:51:45 +0100 [thread overview]
Message-ID: <20260109035149.1341931-2-marex@nabladev.com> (raw)
In-Reply-To: <20260109035149.1341931-1-marex@nabladev.com>
There are designs incorporating EDT ETM touch controller that do not
connect interrupt pin, for example Raspberry Pi. To support such systems
use polling mode for the input device when I2C client does not have
interrupt assigned to it.
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jens Reidel <adrian@mainlining.org>
Cc: Joel Selvaraj <foss@joelselvaraj.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: devicetree@vger.kernel.org
Cc: kernel@dh-electronics.com
Cc: linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
drivers/input/touchscreen/edt-ft5x06.c | 74 ++++++++++++++++++--------
1 file changed, 53 insertions(+), 21 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 9a0add3d39159..a16bf93243976 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -69,6 +69,7 @@
#define TOUCH_EVENT_RESERVED 0x03
#define EDT_NAME_LEN 23
+#define EDT_POLL_INTERVAL_MS 17 /* msec */
#define EDT_SWITCH_MODE_RETRIES 10
#define EDT_SWITCH_MODE_DELAY 5 /* msec */
#define EDT_RAW_DATA_RETRIES 100
@@ -295,9 +296,9 @@ static const struct regmap_config edt_M06_i2c_regmap_config = {
.write = edt_M06_i2c_write,
};
-static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+static void edt_ft5x06_ts_process_events(struct edt_ft5x06_ts_data *tsdata,
+ bool poll)
{
- struct edt_ft5x06_ts_data *tsdata = dev_id;
struct device *dev = &tsdata->client->dev;
u8 rdbuf[63];
int i, type, x, y, id;
@@ -307,9 +308,13 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf,
tsdata->tdata_len);
if (error) {
- dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
- error);
- goto out;
+ if (!poll) {
+ /* Polling may result in no data. */
+ dev_err_ratelimited(dev,
+ "Unable to fetch data, error: %d\n",
+ error);
+ }
+ return;
}
for (i = 0; i < tsdata->max_support_points; i++) {
@@ -341,11 +346,24 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
input_mt_report_pointer_emulation(tsdata->input, true);
input_sync(tsdata->input);
+}
+
+static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+{
+ struct edt_ft5x06_ts_data *tsdata = dev_id;
+
+ edt_ft5x06_ts_process_events(tsdata, false);
-out:
return IRQ_HANDLED;
}
+static void edt_ft5x06_work_i2c_poll(struct input_dev *input)
+{
+ struct edt_ft5x06_ts_data *tsdata = input_get_drvdata(input);
+
+ edt_ft5x06_ts_process_events(tsdata, true);
+}
+
struct edt_ft5x06_attribute {
struct device_attribute dattr;
size_t field_offset;
@@ -613,7 +631,8 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
return -EINVAL;
}
- disable_irq(client->irq);
+ if (client->irq)
+ disable_irq(client->irq);
if (!tsdata->raw_buffer) {
tsdata->raw_bufsize = tsdata->num_x * tsdata->num_y *
@@ -656,7 +675,8 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
kfree(tsdata->raw_buffer);
tsdata->raw_buffer = NULL;
tsdata->factory_mode = false;
- enable_irq(client->irq);
+ if (client->irq)
+ enable_irq(client->irq);
return error;
}
@@ -697,7 +717,8 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
tsdata->raw_buffer = NULL;
edt_ft5x06_restore_reg_parameters(tsdata);
- enable_irq(client->irq);
+ if (client->irq)
+ enable_irq(client->irq);
return 0;
}
@@ -1331,17 +1352,26 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
return error;
}
- irq_flags = irq_get_trigger_type(client->irq);
- if (irq_flags == IRQF_TRIGGER_NONE)
- irq_flags = IRQF_TRIGGER_FALLING;
- irq_flags |= IRQF_ONESHOT;
+ input_set_drvdata(input, tsdata);
- error = devm_request_threaded_irq(&client->dev, client->irq,
- NULL, edt_ft5x06_ts_isr, irq_flags,
- client->name, tsdata);
- if (error) {
- dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
- return error;
+ if (client->irq) {
+ irq_flags = irq_get_trigger_type(client->irq);
+ if (irq_flags == IRQF_TRIGGER_NONE)
+ irq_flags = IRQF_TRIGGER_FALLING;
+ irq_flags |= IRQF_ONESHOT;
+
+ error = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, edt_ft5x06_ts_isr, irq_flags,
+ client->name, tsdata);
+ if (error) {
+ dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
+ return error;
+ }
+ } else {
+ error = input_setup_polling(input, edt_ft5x06_work_i2c_poll);
+ if (error)
+ return dev_err_probe(&client->dev, error, "Unable to set up polling.\n");
+ input_set_poll_interval(input, EDT_POLL_INTERVAL_MS);
}
error = input_register_device(input);
@@ -1394,7 +1424,8 @@ static int edt_ft5x06_ts_suspend(struct device *dev)
* settings. Disable the irq to avoid adjusting each host till the
* device is back in a full functional state.
*/
- disable_irq(tsdata->client->irq);
+ if (tsdata->client->irq)
+ disable_irq(tsdata->client->irq);
gpiod_set_value_cansleep(reset_gpio, 1);
usleep_range(1000, 2000);
@@ -1456,7 +1487,8 @@ static int edt_ft5x06_ts_resume(struct device *dev)
msleep(300);
edt_ft5x06_restore_reg_parameters(tsdata);
- enable_irq(tsdata->client->irq);
+ if (tsdata->client->irq)
+ enable_irq(tsdata->client->irq);
if (tsdata->factory_mode)
ret = edt_ft5x06_factory_mode(tsdata);
--
2.51.0
next prev parent reply other threads:[~2026-01-09 3:52 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-09 3:51 [PATCH 1/2] dt-bindings: input: touchscreen: edt-ft5x06: Drop 'interrupts' requirement Marek Vasut
2026-01-09 3:51 ` Marek Vasut [this message]
2026-01-15 17:14 ` Rob Herring (Arm)
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=20260109035149.1341931-2-marex@nabladev.com \
--to=marex@nabladev.com \
--cc=adrian@mainlining.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=foss@joelselvaraj.com \
--cc=kernel@dh-electronics.com \
--cc=krzk+dt@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
--cc=wsa+renesas@sang-engineering.com \
/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