summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2022-07-03 18:28:04 -0700
committerRobin Peng <robinpeng@google.com>2022-07-06 03:07:21 +0000
commit591daad6521b8ae1ece4930bc63fb2eac40f85aa (patch)
treeeec486c54435410386131a74437bf517ea05136d
parentf03f25010d4e4d393561d74a4df1fb1b40c40261 (diff)
parentb3e734863d475b878856d513179c96b152b0590d (diff)
downloadfocaltech_touch-591daad6521b8ae1ece4930bc63fb2eac40f85aa.tar.gz
Merge android13-gs-pixel-5.10-tm-d1 into android13-gs-pixel-5.10-tm-qpr1
Bug: 233569354 SBMerger: 442815275 Change-Id: I9b852aa5a73f4f886f21b049019bce75e95e4113 Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--ft3658/focaltech_common.h4
-rw-r--r--ft3658/focaltech_core.c95
-rw-r--r--ft3658/focaltech_core.h25
-rw-r--r--ft3658/focaltech_gesture.c106
4 files changed, 158 insertions, 72 deletions
diff --git a/ft3658/focaltech_common.h b/ft3658/focaltech_common.h
index 4688d96..be4583f 100644
--- a/ft3658/focaltech_common.h
+++ b/ft3658/focaltech_common.h
@@ -151,6 +151,10 @@
#define FTS_PRESSURE_SCALE 85 // 255 / 3
#define FTS_CUSTOMER_STATUS_LEN 4
#define FTS_CUSTOMER_STATUS1_MASK 0x0F
+#define FTS_ORIENTATION_SCALE 45
+#define FTS_GESTURE_ID_STTW 0x25
+#define FTS_GESTURE_ID_LPTW_DOWN 0x26
+#define FTS_GESTURE_ID_LPTW_UP 0x27
#define FTS_SYSFS_ECHO_ON(buf) (buf[0] == '1')
#define FTS_SYSFS_ECHO_OFF(buf) (buf[0] == '0')
diff --git a/ft3658/focaltech_core.c b/ft3658/focaltech_core.c
index f982bd7..5d3ebad 100644
--- a/ft3658/focaltech_core.c
+++ b/ft3658/focaltech_core.c
@@ -50,6 +50,7 @@
#include <linux/earlysuspend.h>
#define FTS_SUSPEND_LEVEL 1 /* Early-suspend level */
#endif
+#include <linux/types.h>
#include "focaltech_core.h"
/*****************************************************************************
@@ -828,15 +829,15 @@ static int fts_read_touchdata(struct fts_ts_data *data)
FTS_ERROR("touch data(%x) abnormal,ret:%d", buf[1], ret);
return -EIO;
}
+#endif
if (data->gesture_mode) {
- ret = fts_gesture_readdata(data, buf + FTS_TOUCH_DATA_LEN);
+ ret = fts_gesture_readdata(data, true);
if (ret == 0) {
FTS_INFO("succuss to get gesture data in irq handler");
return 1;
}
}
-#endif
#if IS_ENABLED(GOOGLE_REPORT_MODE)
if (data->work_mode == FTS_REG_WORKMODE_WORK_VALUE) {
@@ -3549,7 +3550,7 @@ static int fts_ts_suspend(struct device *dev)
fts_irq_disable();
#if IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP)
- fts_set_heatmap_mode(ts_data, FW_HEATMAP_MODE_DISABLE);
+ fts_set_heatmap_mode(ts_data, FW_HEATMAP_MODE_DISABLE);
#endif
FTS_DEBUG("make TP enter into sleep mode");
mutex_lock(&ts_data->reg_lock);
@@ -3575,6 +3576,85 @@ static int fts_ts_suspend(struct device *dev)
return 0;
}
+
+/**
+ * Report a finger down event on the long press gesture area then immediately
+ * report a cancel event(MT_TOOL_PALM).
+ */
+static void fts_report_cancel_event(struct fts_ts_data *ts_data)
+{
+ FTS_INFO("Report cancel event for UDFPS");
+
+ mutex_lock(&ts_data->report_mutex);
+ /* Finger down on UDFPS area. */
+ input_mt_slot(ts_data->input_dev, 0);
+ input_report_key(ts_data->input_dev, BTN_TOUCH, 1);
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 1);
+ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X,
+ ts_data->fts_gesture_data.coordinate_x[0]);
+ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y,
+ ts_data->fts_gesture_data.coordinate_y[0]);
+ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
+ ts_data->fts_gesture_data.major[0]);
+ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MINOR,
+ ts_data->fts_gesture_data.minor[0]);
+#ifndef SKIP_PRESSURE
+ input_report_abs(ts_data->input_dev, ABS_MT_PRESSURE, 1);
+#endif
+ input_report_abs(ts_data->input_dev, ABS_MT_ORIENTATION,
+ ts_data->fts_gesture_data.orientation[0]);
+ input_sync(ts_data->input_dev);
+
+ /* Report MT_TOOL_PALM for canceling the touch event. */
+ input_mt_slot(ts_data->input_dev, 0);
+ input_report_key(ts_data->input_dev, BTN_TOUCH, 1);
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_PALM, 1);
+ input_sync(ts_data->input_dev);
+
+ /* Release touches. */
+ input_mt_slot(ts_data->input_dev, 0);
+#ifndef SKIP_PRESSURE
+ input_report_abs(ts_data->input_dev, ABS_MT_PRESSURE, 0);
+#endif
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 0);
+ input_report_abs(ts_data->input_dev, ABS_MT_TRACKING_ID, -1);
+ input_report_key(ts_data->input_dev, BTN_TOUCH, 0);
+ input_sync(ts_data->input_dev);
+ mutex_unlock(&ts_data->report_mutex);
+}
+
+static void fts_check_finger_status(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+ u8 power_mode = FTS_REG_POWER_MODE_SLEEP;
+ ktime_t timeout = ktime_add_ms(ktime_get(), 500); /* 500ms. */
+
+ /* If power mode is deep sleep mode, then reurn. */
+ ret = fts_read_reg(FTS_REG_POWER_MODE, &power_mode);
+ if (ret)
+ return;
+
+ if (power_mode == FTS_REG_POWER_MODE_SLEEP)
+ return;
+
+ while (ktime_get() < timeout) {
+ ret = fts_gesture_readdata(ts_data, false);
+ if (ret)
+ break;
+
+ if (ts_data->fts_gesture_data.gesture_id == FTS_GESTURE_ID_LPTW_DOWN) {
+ msleep(30);
+ continue;
+ }
+
+ if (ts_data->fts_gesture_data.gesture_id == FTS_GESTURE_ID_LPTW_UP ||
+ ts_data->fts_gesture_data.gesture_id == FTS_GESTURE_ID_STTW) {
+ fts_report_cancel_event(ts_data);
+ }
+ break;
+ }
+}
+
static int fts_ts_resume(struct device *dev)
{
struct fts_ts_data *ts_data = fts_data;
@@ -3589,9 +3669,13 @@ static int fts_ts_resume(struct device *dev)
fts_release_all_finger();
if (!ts_data->ic_info.is_incell) {
+ if (!ts_data->gesture_mode) {
#if FTS_POWER_SOURCE_CUST_EN
- fts_power_source_resume(ts_data);
+ fts_power_source_resume(ts_data);
#endif
+ fts_check_finger_status(ts_data);
+ }
+
fts_reset_proc(FTS_RESET_INTERVAL);
}
@@ -3599,7 +3683,8 @@ static int fts_ts_resume(struct device *dev)
if (ret != 0) {
FTS_ERROR("Resume has been cancelled by wake up timeout");
#if FTS_POWER_SOURCE_CUST_EN
- fts_power_source_suspend(ts_data);
+ if (!ts_data->gesture_mode)
+ fts_power_source_suspend(ts_data);
#endif
return ret;
}
diff --git a/ft3658/focaltech_core.h b/ft3658/focaltech_core.h
index d63d493..515d28a 100644
--- a/ft3658/focaltech_core.h
+++ b/ft3658/focaltech_core.h
@@ -80,7 +80,8 @@
#define FTS_TOUCH_DATA_LEN (FTS_MAX_POINTS_SUPPORT * FTS_ONE_TCH_LEN + 3)
#define FTS_GESTURE_POINTS_MAX 1
-#define FTS_GESTURE_DATA_LEN (FTS_GESTURE_POINTS_MAX * 4 + 4)
+#define FTS_GESTURE_DATA_LEN 14
+#define FTS_GESTURE_TOTAL_DATA_SIZE (FTS_GESTURE_POINTS_MAX * FTS_GESTURE_DATA_LEN)
#define FTS_MAX_ID 0x0A
#define FTS_TOUCH_X_H_POS 3
@@ -204,6 +205,25 @@ enum MF_MODE {
MF_ON,
};
+/*
+* gesture_id - mean which gesture is recognised
+* point_num - points number of this gesture
+* coordinate_x - All gesture point x coordinate
+* coordinate_y - All gesture point y coordinate
+* major - All gesture major value
+* minor - All gesture minor value
+* orientation - All gesture orientation value
+*/
+struct fts_gesture_st {
+ u8 gesture_id;
+ u8 point_num;
+ int coordinate_x[FTS_GESTURE_POINTS_MAX];
+ int coordinate_y[FTS_GESTURE_POINTS_MAX];
+ int major[FTS_GESTURE_POINTS_MAX];
+ int minor[FTS_GESTURE_POINTS_MAX];
+ int orientation[FTS_GESTURE_POINTS_MAX];
+};
+
struct fts_ts_data {
struct i2c_client *client;
struct spi_device *spi;
@@ -226,6 +246,7 @@ struct fts_ts_data {
struct mutex reg_lock;
struct mutex device_mutex;
struct completion bus_resumed;
+ struct fts_gesture_st fts_gesture_data;
unsigned long intr_jiffies;
int irq;
int log_level;
@@ -393,7 +414,7 @@ int fts_spi_transfer_direct(u8 *writebuf, u32 writelen, u8 *readbuf, u32 readlen
int fts_gesture_init(struct fts_ts_data *ts_data);
int fts_gesture_exit(struct fts_ts_data *ts_data);
void fts_gesture_recovery(struct fts_ts_data *ts_data);
-int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data);
+int fts_gesture_readdata(struct fts_ts_data *ts_data, bool is_report);
int fts_gesture_suspend(struct fts_ts_data *ts_data);
int fts_gesture_resume(struct fts_ts_data *ts_data);
diff --git a/ft3658/focaltech_gesture.c b/ft3658/focaltech_gesture.c
index 36e1565..811f574 100644
--- a/ft3658/focaltech_gesture.c
+++ b/ft3658/focaltech_gesture.c
@@ -73,29 +73,10 @@
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
-/*
-* gesture_id - mean which gesture is recognised
-* point_num - points number of this gesture
-* coordinate_x - All gesture point x coordinate
-* coordinate_y - All gesture point y coordinate
-* mode - gesture enable/disable, need enable by host
-* - 1:enable gesture function(default) 0:disable
-* active - gesture work flag,
-* always set 1 when suspend, set 0 when resume
-*/
-struct fts_gesture_st {
- u8 gesture_id;
- u8 point_num;
- u16 coordinate_x[FTS_GESTURE_POINTS_MAX];
- u16 coordinate_y[FTS_GESTURE_POINTS_MAX];
- u8 Gesture_major[FTS_GESTURE_POINTS_MAX];
- u8 Gesture_minor[FTS_GESTURE_POINTS_MAX];
-};
/*****************************************************************************
* Static variables
*****************************************************************************/
-static struct fts_gesture_st fts_gesture_data;
/*****************************************************************************
* Global variable or extern global variabls/functions
@@ -146,7 +127,7 @@ static ssize_t fts_gesture_buf_show(
int count = 0;
int i = 0;
struct input_dev *input_dev = fts_data->input_dev;
- struct fts_gesture_st *gesture = &fts_gesture_data;
+ struct fts_gesture_st *gesture = &fts_data->fts_gesture_data;
mutex_lock(&input_dev->mutex);
count = snprintf(buf, PAGE_SIZE, "Gesture ID:%d\n", gesture->gesture_id);
@@ -290,76 +271,71 @@ static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
* It will be called this function every intrrupt when FTS_GESTURE_EN = 1
*
* gesture data length: 1(enable) + 1(reserve) + 2(header) + 6 * 4
-* Input: ts_data - global struct data
-* data - gesture data buffer if non-flash, else NULL
+* Input: ts_data - global struct data
+* is_report - whether report gesture event or not.
* Output:
* Return: 0 - read gesture data successfully, the report data is gesture data
* 1 - tp not in suspend/gesture not enable in TP FW
* -Exx - error
*****************************************************************************/
-int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data)
+int fts_gesture_readdata(struct fts_ts_data *ts_data, bool is_report)
{
- int ret = 0;
int i = 0;
int index = 0;
- u8 buf[FTS_GESTURE_DATA_LEN] = { 0 };
struct input_dev *input_dev = ts_data->input_dev;
- struct fts_gesture_st *gesture = &fts_gesture_data;
- u8 majorminor_buf[8 * FTS_GESTURE_POINTS_MAX] = { 0 };
+ struct fts_gesture_st *gesture = &fts_data->fts_gesture_data;
+ u8 gesture_buf[FTS_GESTURE_TOTAL_DATA_SIZE] = { 0 };
u8 cmd[2] = { 0 };
cmd[0] = FTS_GESTURE_MAJOR_MINOR;
- if (!ts_data->suspended || !ts_data->gesture_mode) {
- return 1;
+ if (!ts_data->suspended) {
+ return -EINVAL;
}
- if (!data) {
- FTS_ERROR("gesture data buffer is null");
- ret = -EINVAL;
- return ret;
- }
+ fts_read(cmd, 1, gesture_buf, FTS_GESTURE_TOTAL_DATA_SIZE);
- memcpy(buf, data, FTS_GESTURE_DATA_LEN);
- if (buf[0] != ENABLE) {
+ if (gesture_buf[0] != ENABLE) {
FTS_DEBUG("gesture not enable in fw, don't process gesture");
- return 1;
+ return -EINVAL;
}
/* init variable before read gesture point */
memset(gesture->coordinate_x, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
memset(gesture->coordinate_y, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
- gesture->gesture_id = buf[2];
- gesture->point_num = buf[3];
- FTS_DEBUG("gesture_id=0x%x, point_num=%d",
- gesture->gesture_id, gesture->point_num);
- fts_read(cmd, 1, majorminor_buf, 8 * FTS_GESTURE_POINTS_MAX);
-
+ gesture->point_num = gesture_buf[2];
+ gesture->gesture_id = gesture_buf[3];
+ if (ts_data->log_level >= 1) {
+ FTS_DEBUG("gesture_id=0x%x, point_num=%d",
+ gesture->gesture_id, gesture->point_num);
+ }
/* save point data,max:6 */
for (i = 0; i < FTS_GESTURE_POINTS_MAX; i++) {
- index = 4 * i + 4;
- gesture->coordinate_x[i] = (u16)(((buf[0 + index] & 0x0F) << 8)
- + buf[1 + index]);
- gesture->coordinate_y[i] = (u16)(((buf[2 + index] & 0x0F) << 8)
- + buf[3 + index]);
-
- gesture->Gesture_major[i] = majorminor_buf[8 * i + 4];
- gesture->Gesture_minor[i] = majorminor_buf[8 * i + 5];
-
- FTS_DEBUG("x=%d, y=%d, major=%d, minor=%d\n",
- gesture->coordinate_x[i], gesture->coordinate_y[i],
- gesture->Gesture_major[i], gesture->Gesture_minor[i]);
+ index = FTS_GESTURE_DATA_LEN * i;
+ gesture->major[i] =
+ (u16)(gesture_buf[6 + index] * ts_data->pdata->mm2px);
+ gesture->minor[i] =
+ (u16)(gesture_buf[7 + index] * ts_data->pdata->mm2px);
+ gesture->coordinate_x[i] = (u16)(((gesture_buf[8 + index] & 0x0F) << 8)
+ + gesture_buf[9 + index]);
+ gesture->coordinate_y[i] = (u16)(((gesture_buf[10 + index] & 0x0F) << 8)
+ + (gesture_buf[11 + index]& 0xFF));
+ gesture->orientation[i] =
+ (s16)(gesture_buf[13 + index] * FTS_ORIENTATION_SCALE);
+
+ if (ts_data->log_level >= 1) {
+ FTS_DEBUG("x=%d, y=%d, major=%d, minor=%d, orientation=%d\n",
+ gesture->coordinate_x[i], gesture->coordinate_y[i],
+ gesture->major[i], gesture->minor[i],
+ gesture->orientation[i]);
+ }
}
- /* report gesture to OS */
- fts_gesture_report(input_dev, gesture->gesture_id);
-
- for(i = 0; i < gesture->point_num; i++) {
- input_report_abs(input_dev, ABS_MT_POSITION_X, gesture->coordinate_x[i]);
- input_report_abs(input_dev, ABS_MT_POSITION_Y, gesture->coordinate_y[i]);
- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, gesture->Gesture_major[i]);
- input_report_abs(input_dev, ABS_MT_TOUCH_MINOR, gesture->Gesture_minor[i]);
- input_sync(input_dev);
+ if (is_report) {
+ mutex_lock(&ts_data->report_mutex);
+ /* report gesture to OS. */
+ fts_gesture_report(input_dev, gesture->gesture_id);
+ mutex_unlock(&ts_data->report_mutex);
}
return 0;
@@ -477,7 +453,7 @@ int fts_gesture_init(struct fts_ts_data *ts_data)
fts_create_gesture_sysfs(ts_data->dev);
- memset(&fts_gesture_data, 0, sizeof(struct fts_gesture_st));
+ memset(&ts_data->fts_gesture_data, 0, sizeof(struct fts_gesture_st));
ts_data->gesture_mode = FTS_GESTURE_EN;
FTS_FUNC_EXIT();