fe956c2ed441652950ec9c29c41d4f638d836eb4
[openwrt/staging/ldir.git] /
1 From dd802fc03b1c71b4297e87068077bfcf9810300a Mon Sep 17 00:00:00 2001
2 From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
3 Date: Wed, 11 Oct 2023 15:14:59 +0100
4 Subject: [PATCH] input: touchscreen: edt-ft5x06: Suppress bogus data on
5 startup
6
7 When polled without the use of IRQ, FT5x06 registers may return
8 undefined initial data, causing unwanted touches or event spamming.
9 A simple way to filter this out is to suppress touches until the
10 TD_STATUS register changes for the first time.
11
12 Increase the delay before first polling to 300ms, to avoid
13 transient I2C read flakiness that seems to occur after reset.
14
15 Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
16 ---
17 drivers/input/touchscreen/edt-ft5x06.c | 31 +++++++++++++++++++++++---
18 1 file changed, 28 insertions(+), 3 deletions(-)
19
20 --- a/drivers/input/touchscreen/edt-ft5x06.c
21 +++ b/drivers/input/touchscreen/edt-ft5x06.c
22 @@ -75,6 +75,8 @@
23 #define EDT_DEFAULT_NUM_X 1024
24 #define EDT_DEFAULT_NUM_Y 1024
25
26 +#define RESET_DELAY_MS 300 /* reset deassert to I2C */
27 +#define FIRST_POLL_DELAY_MS 300 /* in addition to the above */
28 #define POLL_INTERVAL_MS 17 /* 17ms = 60fps */
29
30 enum edt_pmode {
31 @@ -134,6 +136,7 @@ struct edt_ft5x06_ts_data {
32
33 char name[EDT_NAME_LEN];
34 char fw_version[EDT_NAME_LEN];
35 + int init_td_status;
36
37 struct edt_reg_addr reg_addr;
38 enum edt_ver version;
39 @@ -268,12 +271,33 @@ static irqreturn_t edt_ft5x06_ts_isr(int
40 * points.
41 */
42 num_points = min(rdbuf[2] & 0xf, tsdata->max_support_points);
43 +
44 + /* When polling FT5x06 without IRQ: initial register contents
45 + * could be stale or undefined; discard all readings until
46 + * TD_STATUS changes for the first time (or num_points is 0).
47 + */
48 + if (tsdata->init_td_status) {
49 + if (tsdata->init_td_status < 0)
50 + tsdata->init_td_status = rdbuf[2];
51 +
52 + if (num_points && rdbuf[2] == tsdata->init_td_status)
53 + goto out;
54 +
55 + tsdata->init_td_status = 0;
56 + }
57 +
58 if (num_points) {
59 datalen = tplen * num_points + crclen;
60 cmd = offset;
61 error = edt_ft5x06_ts_readwrite(tsdata->client,
62 sizeof(cmd), &cmd,
63 datalen, &rdbuf[offset]);
64 + if (error) {
65 + dev_err_ratelimited(dev,
66 + "Unable to fetch data, error: %d\n",
67 + error);
68 + goto out;
69 + }
70 }
71 }
72
73 @@ -1294,7 +1318,7 @@ static int edt_ft5x06_ts_probe(struct i2
74 if (tsdata->reset_gpio) {
75 usleep_range(5000, 6000);
76 gpiod_set_value_cansleep(tsdata->reset_gpio, 0);
77 - msleep(300);
78 + msleep(RESET_DELAY_MS);
79 }
80
81 input = devm_input_allocate_device(&client->dev);
82 @@ -1384,11 +1408,12 @@ static int edt_ft5x06_ts_probe(struct i2
83 return error;
84 }
85 } else {
86 + tsdata->init_td_status = -1; /* filter bogus initial data */
87 INIT_WORK(&tsdata->work_i2c_poll,
88 edt_ft5x06_ts_work_i2c_poll);
89 timer_setup(&tsdata->timer, edt_ft5x06_ts_irq_poll_timer, 0);
90 - tsdata->timer.expires = jiffies +
91 - msecs_to_jiffies(POLL_INTERVAL_MS);
92 + tsdata->timer.expires =
93 + jiffies + msecs_to_jiffies(FIRST_POLL_DELAY_MS);
94 add_timer(&tsdata->timer);
95 }
96