diff mbox series

[RFC,4/4] input: edt-ft5x06 - Handle unreliable TOUCH_UP events

Message ID 20211216233041.1220-5-tharvey@gateworks.com (mailing list archive)
State New, archived
Headers show
Series input: edt-ft5x06: add support for DFROBOT touch controller to | expand

Commit Message

Tim Harvey Dec. 16, 2021, 11:30 p.m. UTC
The ft5x06 is unreliable in sending touch up events, so some
touch IDs can become stuck in the detected state.

Ensure that IDs that are unreported by the controller are
released.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 drivers/input/touchscreen/edt-ft5x06.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index a3622d6e8e65..53906fcbaa51 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -126,6 +126,7 @@  struct edt_ft5x06_ts_data {
 	int offset_y;
 	int report_rate;
 	int max_support_points;
+	unsigned int known_ids;
 
 	char name[EDT_NAME_LEN];
 
@@ -198,6 +199,8 @@  static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 	int offset, tplen, datalen, crclen;
 	int error;
 	int num_points;
+	unsigned int active_ids = 0, known_ids = tsdata->known_ids;
+	long released_ids;
 
 	switch (tsdata->version) {
 	case EDT_M06:
@@ -297,10 +300,21 @@  static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 
 		input_mt_slot(tsdata->input, id);
 		if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
-					       type != TOUCH_EVENT_UP))
+					       type != TOUCH_EVENT_UP)) {
 			touchscreen_report_pos(tsdata->input, &tsdata->prop,
 					       x, y, true);
+			active_ids |= BIT(id);
+		} else {
+			known_ids &= ~BIT(id);
+		}
+	}
+
+	released_ids = known_ids & ~active_ids;
+	for_each_set_bit_from(i, &released_ids, tsdata->max_support_points) {
+		input_mt_slot(tsdata->input, i);
+		input_mt_report_slot_inactive(tsdata->input);
 	}
+	tsdata->known_ids = active_ids;
 
 	input_mt_report_pointer_emulation(tsdata->input, true);
 	input_sync(tsdata->input);