Skip to content

Commit

Permalink
Sunxi-6.6: Fix tsc2007 ghost touches on BTT CB1
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnTheCoolingFan committed Dec 16, 2024
1 parent 7183513 commit 3be54c3
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JohnTheCoolingFan <[email protected]>
Date: Sun, 15 Dec 2024 13:59:13 +0000
Subject: Fix ghost touches on tsc2007 tft screen

Signed-off-by: JohnTheCoolingFan <[email protected]>
---
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

1 change: 1 addition & 0 deletions patch/kernel/archive/sunxi-6.6/series.armbian
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,4 @@
patches.armbian/ARM64-dts-sun50i-h616-BigTreeTech-CB1-Enable-IR-receiver.patch
patches.armbian/arm64-dts-sun50i-h618-cherryba-m1.patch
patches.armbian/Add-BananaPi-BPI-M4-Zero-pinctrl.patch
patches.armbian/Fix-ghost-touches-tsc2007.patch
1 change: 1 addition & 0 deletions patch/kernel/archive/sunxi-6.6/series.conf
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,4 @@
patches.armbian/ARM64-dts-sun50i-h616-BigTreeTech-CB1-Enable-IR-receiver.patch
patches.armbian/arm64-dts-sun50i-h618-cherryba-m1.patch
patches.armbian/Add-BananaPi-BPI-M4-Zero-pinctrl.patch
patches.armbian/Fix-ghost-touches-tsc2007.patch

0 comments on commit 3be54c3

Please sign in to comment.