mirror of
https://github.com/armbian/build.git
synced 2025-08-14 07:06:58 +02:00
The patches in the series were applied to the Linux kernel git repository as the "git am" command. And then re-extracted to the target patches.armbian folder using the tools/mk_format_patch script. In this case, the series.armbian file is created anew and all patches in the series strictly correspond to this list. I.e. unused ones will be deleted. The name of the patch file will match the string "Subject:". Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>
196 lines
4.9 KiB
Diff
196 lines
4.9 KiB
Diff
From 4927f5e069624c24ff08d6af3b81a4dff5b697c9 Mon Sep 17 00:00:00 2001
|
|
From: Alan <Alan>
|
|
Date: Sat, 20 May 2023 14:44:07 +0800
|
|
Subject: 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 8d832a372b89..08bbbafbbae1 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.35.3
|
|
|