[PATCH v3 2/3] Input: goodix - fix simultaneous axes inversion and swap
From: Marcin Niestroj <hidden>
Date: 2018-01-25 19:35:56
Subsystem:
goodix touchscreen, input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Hans de Goede, Dmitry Torokhov, Linus Torvalds
goodix_ts_data structure contains abs_x_max and abs_y_max members,
which contain already swapped maximum ranges. That causes reporting
touch events with invalid position (out of range values).
Problem occurs for example when ts->inverted_x and ts->swapped_x_y are
true, but ts->inverted_y is false. Assuming we have 720x1280 touch
panel, ts->abs_x_max == 1279 and ts->abs_y_max == 719 (because we
inverted that in goodix_read_config()). Now let's assume that we
received event from (0:0) position (in touch panel original
coordinates). In function goodix_ts_report_touch() we calculate
input_x as 1279, but after swapping input_y takes that value (which is
more that maximum 719 value reported during initialization).
Take into account that abs_x_max and abs_y_max are already swapped
in goodix_ts_report_touch(), so position for inverted axes will be
calculated correctly.
Signed-off-by: Marcin Niestroj <redacted>
Fixes: ad48cf5e9597 ("Input: goodix - add axis swapping and axis inversion support")
---
Changes v2 -> v3 (suggested by Bastien):
- add explanation about when the problem occurs
Changes v1 -> v2 (suggested by Bastien):
- patch splitted off from patch 3
drivers/input/touchscreen/goodix.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index 7896097ca69b..dc832890f6d3 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c@@ -296,12 +296,18 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) int input_w = get_unaligned_le16(&coor_data[5]); /* Inversions have to happen before axis swapping */ - if (ts->inverted_x) - input_x = ts->abs_x_max - input_x; - if (ts->inverted_y) - input_y = ts->abs_y_max - input_y; - if (ts->swapped_x_y) + if (!ts->swapped_x_y) { + if (ts->inverted_x) + input_x = ts->abs_x_max - input_x; + if (ts->inverted_y) + input_y = ts->abs_y_max - input_y; + } else { + if (ts->inverted_x) + input_x = ts->abs_y_max - input_x; + if (ts->inverted_y) + input_y = ts->abs_x_max - input_y; swap(input_x, input_y); + } input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
--
2.16.1