196 lines
4.9 KiB
Diff
196 lines
4.9 KiB
Diff
|
From 8e4468c6de5f11c7ed078599dee21171f8de17af Mon Sep 17 00:00:00 2001
|
||
|
From: Alan <Alan>
|
||
|
Date: Sat, 20 May 2023 14:44:07 +0800
|
||
|
Subject: [PATCH] Optimize: TSC2007 touchscreen add polling method
|
||
|
|
||
|
---
|
||
|
drivers/input/touchscreen/tsc2007.h | 6 ++
|
||
|
drivers/input/touchscreen/tsc2007_core.c | 110 +++++++++++++++++++++--
|
||
|
2 files changed, 108 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/input/touchscreen/tsc2007.h b/drivers/input/touchscreen/tsc2007.h
|
||
|
index 69b08dd6c8df..5252b6c6daeb 100644
|
||
|
--- a/drivers/input/touchscreen/tsc2007.h
|
||
|
+++ b/drivers/input/touchscreen/tsc2007.h
|
||
|
@@ -66,10 +66,13 @@ struct tsc2007 {
|
||
|
u16 model;
|
||
|
u16 x_plate_ohms;
|
||
|
u16 max_rt;
|
||
|
+ u16 rt_thr;
|
||
|
+ u8 touched;
|
||
|
unsigned long poll_period; /* in jiffies */
|
||
|
int fuzzx;
|
||
|
int fuzzy;
|
||
|
int fuzzz;
|
||
|
+ bool ignore_nak;
|
||
|
|
||
|
struct gpio_desc *gpiod;
|
||
|
int irq;
|
||
|
@@ -81,6 +84,9 @@ struct tsc2007 {
|
||
|
void (*clear_penirq)(void);
|
||
|
|
||
|
struct mutex mlock;
|
||
|
+
|
||
|
+ struct timer_list timer;
|
||
|
+ struct work_struct work_i2c_poll;
|
||
|
};
|
||
|
|
||
|
int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd);
|
||
|
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c
|
||
|
index 21916a30fb76..9e91df8c6bc0 100644
|
||
|
--- a/drivers/input/touchscreen/tsc2007_core.c
|
||
|
+++ b/drivers/input/touchscreen/tsc2007_core.c
|
||
|
@@ -28,6 +28,8 @@
|
||
|
#include <linux/platform_data/tsc2007.h>
|
||
|
#include "tsc2007.h"
|
||
|
|
||
|
+#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */
|
||
|
+
|
||
|
int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
|
||
|
{
|
||
|
s32 data;
|
||
|
@@ -172,6 +174,65 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
|
||
|
return IRQ_HANDLED;
|
||
|
}
|
||
|
|
||
|
+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;
|
||
|
+
|
||
|
+ 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;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ return IRQ_HANDLED;
|
||
|
+}
|
||
|
+
|
||
|
static void tsc2007_stop(struct tsc2007 *ts)
|
||
|
{
|
||
|
ts->stopped = true;
|
||
|
@@ -216,11 +277,32 @@ static int tsc2007_get_pendown_state_gpio(struct device *dev)
|
||
|
return gpiod_get_value_cansleep(ts->gpiod);
|
||
|
}
|
||
|
|
||
|
+static void tsc2007_ts_irq_poll_timer(struct timer_list *t)
|
||
|
+{
|
||
|
+ struct tsc2007 *ts = from_timer(ts, t, timer);
|
||
|
+
|
||
|
+ schedule_work(&ts->work_i2c_poll);
|
||
|
+ mod_timer(&ts->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
|
||
|
+}
|
||
|
+
|
||
|
+static void tsc2007_ts_work_i2c_poll(struct work_struct *work)
|
||
|
+{
|
||
|
+ struct tsc2007 *ts = container_of(work,
|
||
|
+ struct tsc2007, work_i2c_poll);
|
||
|
+
|
||
|
+ tsc2007_soft_poll(0, ts);
|
||
|
+}
|
||
|
+
|
||
|
static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts)
|
||
|
{
|
||
|
u32 val32;
|
||
|
u64 val64;
|
||
|
|
||
|
+ ts->ignore_nak = device_property_read_bool(dev, "i2c,ignore-nak");
|
||
|
+
|
||
|
+ if (!device_property_read_u32(dev, "ti,rt-thr", &val32))
|
||
|
+ ts->rt_thr = val32;
|
||
|
+
|
||
|
if (!device_property_read_u32(dev, "ti,max-rt", &val32))
|
||
|
ts->max_rt = val32;
|
||
|
else
|
||
|
@@ -317,6 +399,9 @@ static int tsc2007_probe(struct i2c_client *client)
|
||
|
if (!input_dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
+ if (ts->ignore_nak)
|
||
|
+ client->flags |= I2C_M_IGNORE_NAK;
|
||
|
+
|
||
|
i2c_set_clientdata(client, ts);
|
||
|
|
||
|
ts->client = client;
|
||
|
@@ -362,14 +447,23 @@ static int tsc2007_probe(struct i2c_client *client)
|
||
|
pdata->init_platform_hw();
|
||
|
}
|
||
|
|
||
|
- err = devm_request_threaded_irq(&client->dev, ts->irq,
|
||
|
- NULL, tsc2007_soft_irq,
|
||
|
- IRQF_ONESHOT,
|
||
|
- client->dev.driver->name, ts);
|
||
|
- if (err) {
|
||
|
- dev_err(&client->dev, "Failed to request irq %d: %d\n",
|
||
|
- ts->irq, err);
|
||
|
- return err;
|
||
|
+ if (ts->gpiod) {
|
||
|
+ err = devm_request_threaded_irq(&client->dev, ts->irq,
|
||
|
+ NULL, tsc2007_soft_irq,
|
||
|
+ IRQF_ONESHOT,
|
||
|
+ client->dev.driver->name, ts);
|
||
|
+ if (err) {
|
||
|
+ dev_err(&client->dev, "Failed to request irq %d: %d\n",
|
||
|
+ ts->irq, err);
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ INIT_WORK(&ts->work_i2c_poll,
|
||
|
+ tsc2007_ts_work_i2c_poll);
|
||
|
+ timer_setup(&ts->timer, tsc2007_ts_irq_poll_timer, 0);
|
||
|
+ ts->timer.expires = jiffies +
|
||
|
+ msecs_to_jiffies(POLL_INTERVAL_MS);
|
||
|
+ add_timer(&ts->timer);
|
||
|
}
|
||
|
|
||
|
tsc2007_stop(ts);
|
||
|
--
|
||
|
2.34.1
|
||
|
|