diff --git a/patch/kernel/archive/sunxi-6.11/patches.armbian/Fix-ghost-touches-tsc2007.patch b/patch/kernel/archive/sunxi-6.11/patches.armbian/Fix-ghost-touches-tsc2007.patch new file mode 100644 index 000000000000..320e1aad426b --- /dev/null +++ b/patch/kernel/archive/sunxi-6.11/patches.armbian/Fix-ghost-touches-tsc2007.patch @@ -0,0 +1,224 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: John Doe +Date: Sun, 15 Dec 2024 13:59:13 +0000 +Subject: Fix ghost touches on tsc2007 tft screen + +Signed-off-by: John Doe +--- + arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 1 + + drivers/input/touchscreen/tsc2007.h | 1 + + drivers/input/touchscreen/tsc2007_core.c | 111 +++++----- + include/linux/platform_data/tsc2007.h | 1 + + 4 files changed, 60 insertions(+), 54 deletions(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +index 2022990e4..3b3a196ea 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +@@ -123,10 +123,11 @@ i2c_gpio: i2c-gpio { + tft_tp: ns2009@48 { + compatible = "ti,tsc2007"; + reg = <0x48>; + status = "disabled"; + ti,x-plate-ohms = <660>; ++ ti,y-plate-ohms = <660>; + ti,rt-thr = <3000>; + ti,fuzzx = <32>; + ti,fuzzy = <16>; + i2c,ignore-nak = <1>; + }; +diff --git a/drivers/input/touchscreen/tsc2007.h b/drivers/input/touchscreen/tsc2007.h +index 5252b6c6d..7411b8bce 100644 +--- a/drivers/input/touchscreen/tsc2007.h ++++ b/drivers/input/touchscreen/tsc2007.h +@@ -63,10 +63,11 @@ struct tsc2007 { + + struct i2c_client *client; + + u16 model; + u16 x_plate_ohms; ++ u16 y_plate_ohms; + u16 max_rt; + u16 rt_thr; + u8 touched; + unsigned long poll_period; /* in jiffies */ + int fuzzx; +diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c +index 08bbbafbb..3059d4097 100644 +--- a/drivers/input/touchscreen/tsc2007_core.c ++++ b/drivers/input/touchscreen/tsc2007_core.c +@@ -68,26 +68,29 @@ static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc) + tsc2007_xfer(tsc, PWRDOWN); + } + + u32 tsc2007_calculate_resistance(struct tsc2007 *tsc, struct ts_event *tc) + { +- u32 rt = 0; +- +- /* range filtering */ +- if (tc->x == MAX_12BIT) +- tc->x = 0; +- +- if (likely(tc->x && tc->z1)) { +- /* compute touch resistance using equation #1 */ +- rt = tc->z2 - tc->z1; +- rt *= tc->x; +- rt *= tsc->x_plate_ohms; +- rt /= tc->z1; +- rt = (rt + 2047) >> 12; +- } ++ u32 rt = 0; ++ if (tc->x == MAX_12BIT){ ++ /* dev_info(&tsc->client->dev, "[DEBUG TSC] RESISTANCE CALCULATED | TC->X is MAX_12BIT Force to 0 || TC Z1: (%4d) | TC Z2: (%4d) | TC X: (%4d) | TC Y: (%4d)", tc->z1, tc->z2, tc->x, tc->y);*/ ++ tc->x = 0; ++ } ++ ++ if (tc->y == MAX_12BIT){ ++ /*dev_info(&tsc->client->dev, "[DEBUG TSC] RESISTANCE CALCULATED | TC->Y is MAX_12BIT Force to 0 || TC Z1: (%4d) | TC Z2: (%4d) | TC X: (%4d) | TC Y: (%4d)", tc->z1, tc->z2, tc->x, tc->y);*/ ++ tc->y = 0; ++ } ++ ++ ++ if (likely(tc->x && tc->y && tc->z1)) { ++ return (tsc->x_plate_ohms * tc->x / 4096) * ((4096 / tc->z1) - 1) - tsc->y_plate_ohms * (1 - tc->y / 4096); ++ }else{ ++ /*dev_info(&tsc->client->dev, "[DEBUG TSC] RESISTANCE CALCULATED | Missing mandatory Data TCX(%4d) | TCY(%4d) | TCZ1(%4d)",tc->x,tc->y,tc->z1);*/ ++ return false; ++ } + +- return rt; + } + + bool tsc2007_is_pen_down(struct tsc2007 *ts) + { + /* +@@ -178,60 +181,53 @@ static irqreturn_t tsc2007_soft_poll(int irq, void *handle) + { + struct tsc2007 *ts = handle; + struct input_dev *input = ts->input; + struct ts_event tc; + u32 rt; ++ bool skipSync = false; + + if(!ts->stopped) { + + mutex_lock(&ts->mlock); + tsc2007_read_values(ts, &tc); + mutex_unlock(&ts->mlock); + + rt = tsc2007_calculate_resistance(ts, &tc); + +- if (rt == 0 || rt == 256) { +- +- /* +- * Sample found inconsistent by debouncing or pressure is +- * beyond the maximum. Don't report it to user space, +- * repeat at least once more the measurement. +- */ +- dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); +- +- } else { +- +- if (rt < ts->rt_thr) { +- +- dev_dbg(&ts->client->dev, +- "DOWN point(%4d,%4d), resistance (%4u)\n", +- tc.x, tc.y, rt); +- +- rt = ts->max_rt - rt; +- +- input_report_key(input, BTN_TOUCH, 1); +- input_report_abs(input, ABS_X, tc.y); +- input_report_abs(input, ABS_Y, 4096 - tc.x); +- input_report_abs(input, ABS_PRESSURE, rt); +- +- input_sync(input); +- ts->touched = 1; +- +- } else if (ts->touched == 1) { +- +- dev_dbg(&ts->client->dev, "UP\n"); +- +- input_report_key(input, BTN_TOUCH, 0); +- input_report_abs(input, ABS_PRESSURE, 0); +- input_sync(input); +- ts->touched = 0; +- } +- } +- +- ++ if (likely(rt)) { ++ ++ /* range >= 0 && <= 4096 */ ++ if (rt > 0 && rt <= ts->max_rt) { ++ rt = ts->max_rt - rt; ++ input_report_key(input, BTN_TOUCH, 1); ++ input_report_abs(input, ABS_X, tc.y); ++ input_report_abs(input, ABS_Y, 4096 - tc.x); ++ input_report_abs(input, ABS_PRESSURE, rt); ++ input_sync(input); ++ /*dev_info(&ts->client->dev, "[DEBUG TSC] TOUCH TRIGGERED | RT: (%4d) | TC Z1: (%4d) | TC Z2: (%4d) | TC X: (%4d) | TC Y: (%4d)", rt, tc.z1, tc.z2, tc.x, tc.y);*/ ++ ++ } else { ++ //Discard Input Ghost or inconsistent ++ /*dev_info(&ts->client->dev, "[DEBUG TSC] TOUCH DISCARD | RT: (%4d) | TC Z1: (%4d) | TC Z2: (%4d) | TC X: (%4d) | TC Y: (%4d)", rt, tc.z1, tc.z2, tc.x, tc.y);*/ ++ skipSync= true; ++ } ++ }else{ ++ // No touch event or missing data for rt calculation ++ skipSync= true; ++ } ++ ++ }else{ ++ // TFT Not initialized ++ /* dev_info(&ts->client->dev, "DEBUG TSC: TouchScreen Stopped"); */ + } + ++ if(skipSync){ ++ input_report_key(input, BTN_TOUCH, 0); ++ input_report_abs(input, ABS_PRESSURE, 0); ++ input_sync(input); ++ } ++ + return IRQ_HANDLED; + } + + static void tsc2007_stop(struct tsc2007 *ts) + { +@@ -327,10 +323,17 @@ static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts) + } else { + dev_err(dev, "Missing ti,x-plate-ohms device property\n"); + return -EINVAL; + } + ++ if (!device_property_read_u32(dev, "ti,y-plate-ohms", &val32)) { ++ ts->y_plate_ohms = val32; ++ } else { ++ dev_err(dev, "Missing ti,y-plate-ohms device property\n"); ++ return -EINVAL; ++ } ++ + ts->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); + if (IS_ERR(ts->gpiod)) + return PTR_ERR(ts->gpiod); + + if (ts->gpiod) +diff --git a/include/linux/platform_data/tsc2007.h b/include/linux/platform_data/tsc2007.h +index a0ca52c41..f88e58032 100644 +--- a/include/linux/platform_data/tsc2007.h ++++ b/include/linux/platform_data/tsc2007.h +@@ -5,10 +5,11 @@ + /* linux/platform_data/tsc2007.h */ + + struct tsc2007_platform_data { + u16 model; /* 2007. */ + u16 x_plate_ohms; /* must be non-zero value */ ++ u16 y_plate_ohms; /* must be non-zero value */ + u16 max_rt; /* max. resistance above which samples are ignored */ + unsigned long poll_period; /* time (in ms) between samples */ + int fuzzx; /* fuzz factor for X, Y and pressure axes */ + int fuzzy; + int fuzzz; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.11/series.armbian b/patch/kernel/archive/sunxi-6.11/series.armbian index d59ac121f518..1f4349dcd155 100644 --- a/patch/kernel/archive/sunxi-6.11/series.armbian +++ b/patch/kernel/archive/sunxi-6.11/series.armbian @@ -171,3 +171,4 @@ patches.armbian/Add-board-BananaPi-BPI-M4-Zero.patch patches.armbian/Add-BananaPi-BPI-M4-Zero-pinctrl.patch patches.armbian/Add-BananaPi-BPI-M4-Zero-overlays.patch + patches.armbian/Fix-ghost-touches-tsc2007.patch diff --git a/patch/kernel/archive/sunxi-6.11/series.conf b/patch/kernel/archive/sunxi-6.11/series.conf index 4b65f2769013..8a7bca00539b 100644 --- a/patch/kernel/archive/sunxi-6.11/series.conf +++ b/patch/kernel/archive/sunxi-6.11/series.conf @@ -425,3 +425,4 @@ patches.armbian/Add-board-BananaPi-BPI-M4-Zero.patch patches.armbian/Add-BananaPi-BPI-M4-Zero-pinctrl.patch patches.armbian/Add-BananaPi-BPI-M4-Zero-overlays.patch + patches.armbian/Fix-ghost-touches-tsc2007.patch