aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch98
1 files changed, 98 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch b/target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch
new file mode 100644
index 0000000000..402b149fca
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.15/950-0315-Input-edt-ft5x06-Poll-the-device-if-no-interrupt-is-.patch
@@ -0,0 +1,98 @@
+From cd24e1ce67ea6e34d9ef0886858b8b5ac77bf847 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 6 Nov 2020 18:45:10 +0000
+Subject: [PATCH] Input: edt-ft5x06: Poll the device if no interrupt is
+ configured.
+
+Not all systems have the interrupt line wired up, so switch to
+polling the touchscreen off a timer if no interrupt line is
+configured.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/input/touchscreen/edt-ft5x06.c | 51 +++++++++++++++++++++-----
+ 1 file changed, 41 insertions(+), 10 deletions(-)
+
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -72,6 +72,8 @@
+ #define EDT_DEFAULT_NUM_X 1024
+ #define EDT_DEFAULT_NUM_Y 1024
+
++#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */
++
+ enum edt_pmode {
+ EDT_PMODE_NOT_SUPPORTED,
+ EDT_PMODE_HIBERNATE,
+@@ -130,6 +132,9 @@ struct edt_ft5x06_ts_data {
+
+ struct edt_reg_addr reg_addr;
+ enum edt_ver version;
++
++ struct timer_list timer;
++ struct work_struct work_i2c_poll;
+ };
+
+ struct edt_i2c_chip_data {
+@@ -279,6 +284,22 @@ out:
+ return IRQ_HANDLED;
+ }
+
++static void edt_ft5x06_ts_irq_poll_timer(struct timer_list *t)
++{
++ struct edt_ft5x06_ts_data *tsdata = from_timer(tsdata, t, timer);
++
++ schedule_work(&tsdata->work_i2c_poll);
++ mod_timer(&tsdata->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
++}
++
++static void edt_ft5x06_ts_work_i2c_poll(struct work_struct *work)
++{
++ struct edt_ft5x06_ts_data *tsdata = container_of(work,
++ struct edt_ft5x06_ts_data, work_i2c_poll);
++
++ edt_ft5x06_ts_isr(0, tsdata);
++}
++
+ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
+ u8 addr, u8 value)
+ {
+@@ -1234,17 +1255,27 @@ static int edt_ft5x06_ts_probe(struct i2
+
+ i2c_set_clientdata(client, tsdata);
+
+- 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;
++ 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 {
++ INIT_WORK(&tsdata->work_i2c_poll,
++ edt_ft5x06_ts_work_i2c_poll);
++ timer_setup(&tsdata->timer, edt_ft5x06_ts_irq_poll_timer, 0);
++ tsdata->timer.expires = jiffies +
++ msecs_to_jiffies(POLL_INTERVAL_MS);
++ add_timer(&tsdata->timer);
+ }
+
+ error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group);