summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidycchen <davidycchen@google.com>2021-07-16 13:33:33 +0800
committerdavidycchen <davidycchen@google.com>2021-07-20 12:55:36 +0800
commitef26212d3d392febee8a93ab91e62625cbd82e1b (patch)
tree88ec66b003cd8e79b1adc17ee5a6476155b42979
parent177a930e8ce8dda2f3c72fb4bac22a5f2ae108ab (diff)
downloadfts_touch-ef26212d3d392febee8a93ab91e62625cbd82e1b.tar.gz
ftm5: check finger status while touch resume
Check the touch finger status on udfps area and send a cancel event for fingerprint sensor when the device is woken up by the long press gesture but there is no finger on the fingerprint area. Bug: 192509652 Test: cancel event works. Signed-off-by: davidycchen <davidycchen@google.com> Change-Id: I640b6189efbe6cc79f03d3c0f54282264ed5ba95
-rw-r--r--ftm5/fts.c111
-rw-r--r--ftm5/fts.h2
-rw-r--r--ftm5/fts_lib/ftsCore.h3
-rw-r--r--ftm5/fts_lib/ftsSoftware.h8
4 files changed, 123 insertions, 1 deletions
diff --git a/ftm5/fts.c b/ftm5/fts.c
index 12ac860..ba1a245 100644
--- a/ftm5/fts.c
+++ b/ftm5/fts.c
@@ -5356,6 +5356,106 @@ static int fts_mode_handler(struct fts_ts_info *info, int force)
return res;
}
+/* Report a finger down event on the long press gesture area then immediately
+ * report a cancel event(MT_TOOL_PALM).
+ */
+static void report_cancel_event(struct fts_ts_info *info)
+{
+ dev_info(info->dev, "%s\n", __func__);
+
+ mutex_lock(&info->input_report_mutex);
+
+ /* Finger down on UDFPS area. */
+ input_mt_slot(info->input_dev, 0);
+ input_report_key(info->input_dev, BTN_TOUCH, 1);
+ input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1);
+ input_report_abs(info->input_dev, ABS_MT_POSITION_X, info->board->udfps_x);
+ input_report_abs(info->input_dev, ABS_MT_POSITION_Y, info->board->udfps_y);
+ input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, 200);
+ input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, 200);
+#ifndef SKIP_PRESSURE
+ input_report_abs(info->input_dev, ABS_MT_PRESSURE, 1);
+#endif
+ input_sync(info->input_dev);
+
+ /* Report MT_TOOL_PALM for canceling the touch event. */
+ input_mt_slot(info->input_dev, 0);
+ input_report_key(info->input_dev, BTN_TOUCH, 1);
+ input_mt_report_slot_state(info->input_dev, MT_TOOL_PALM, 1);
+ input_sync(info->input_dev);
+
+ /* Release touches. */
+ input_mt_slot(info->input_dev, 0);
+ input_report_abs(info->input_dev, ABS_MT_PRESSURE, 0);
+ input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 0);
+ input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1);
+ input_report_key(info->input_dev, BTN_TOUCH, 0);
+ input_sync(info->input_dev);
+
+ mutex_unlock(&info->input_report_mutex);
+}
+
+/* Check the finger status on long press gesture area. */
+static void check_finger_status(struct fts_ts_info *info)
+{
+ u8 command[3] = { FTS_CMD_SYSTEM, SYS_CMD_LOAD_DATA, LOAD_DEBUG_INFO };
+ u8 data[DEBUG_INFO_SIZE] = { 0 };
+ ktime_t ktime_start = ktime_get();
+ int retry = 0;
+ int ret;
+
+ dev_info(info->dev, "%s\n", __func__);
+
+ while (ktime_ms_delta(ktime_get(), ktime_start) < 500) {
+ retry++;
+ ret = fts_write(info, command, ARRAY_SIZE(command));
+ if (ret < OK) {
+ dev_err(info->dev,
+ "%s: error while writing the sys cmd ERROR %08X\n",
+ __func__, ret);
+ msleep(10);
+ continue;
+ }
+
+ ret = fts_writeReadU8UX(info, FTS_CMD_FRAMEBUFFER_R, BITS_16,
+ ADDR_FRAMEBUFFER, data, DEBUG_INFO_SIZE,
+ DUMMY_FRAMEBUFFER);
+ if (ret < OK) {
+ dev_err(info->dev,
+ "%s: error while write/read cmd ERROR %08X\n",
+ __func__, ret);
+ msleep(10);
+ continue;
+ }
+
+ /* Check header. */
+ if (data[0] != HEADER_SIGNATURE || data[1] != LOAD_DEBUG_INFO) {
+ dev_err(info->dev,
+ "%s: Fail to get debug info, header = %#x %#x, read next frame.\n",
+ __func__, data[0], data[1]);
+ msleep(10);
+ continue;
+ }
+
+ /* Check scan mode (data[4]).
+ 0x05: low power detect mode.
+ 0x06: low power active mode. */
+ if (data[4] != DEBUG_INFO_LP_DETECT && data[4] != DEBUG_INFO_LP_ACTIVE)
+ return;
+
+ /* Check finger count (data[60]). */
+ if (data[60] == 0) {
+ /* Report cancel event when finger count is 0. */
+ report_cancel_event(info);
+ break;
+ } else if (data[60] > 1) {
+ /* Skip the process when the count is abnormal. */
+ break;
+ }
+ msleep(10);
+ }
+}
+
/**
* Configure the switch GPIO to toggle bus master between AP and SLPI.
* gpio_value takes one of
@@ -5404,6 +5504,9 @@ static void fts_resume_work(struct work_struct *work)
info->resume_bit = 1;
+ if (info->board->udfps_x != 0 && info->board->udfps_y != 0)
+ check_finger_status(info);
+
fts_system_reset(info);
release_all_touches(info);
@@ -6071,6 +6174,14 @@ static int parse_dt(struct device *dev, struct fts_hw_platform_data *bdata)
bdata->x_axis_max = coords[0];
bdata->y_axis_max = coords[1];
+ if (of_property_read_u32_array(np, "st,udfps-coords", coords, 2)) {
+ dev_err(dev, "st,udfps-coords not found\n");
+ coords[0] = 0;
+ coords[1] = 0;
+ }
+ bdata->udfps_x = coords[0];
+ bdata->udfps_y = coords[1];
+
bdata->sensor_inverted_x = 0;
if (of_property_read_bool(np, "st,sensor_inverted_x"))
bdata->sensor_inverted_x = 1;
diff --git a/ftm5/fts.h b/ftm5/fts.h
index e0ab321..5594cae 100644
--- a/ftm5/fts.h
+++ b/ftm5/fts.h
@@ -304,6 +304,8 @@ struct fts_hw_platform_data {
bool sensor_inverted;
int x_axis_max;
int y_axis_max;
+ int udfps_x;
+ int udfps_y;
bool auto_fw_update;
bool separate_save_golden_ms_raw_cmd;
bool sensor_inverted_x;
diff --git a/ftm5/fts_lib/ftsCore.h b/ftm5/fts_lib/ftsCore.h
index ea8064c..4c87907 100644
--- a/ftm5/fts_lib/ftsCore.h
+++ b/ftm5/fts_lib/ftsCore.h
@@ -56,6 +56,9 @@ typedef enum {
#define SYS_INFO_SIZE 216 /* Num bytes of die info */
/** @}*/
+/* Size in bytes of Debug Info data */
+#define DEBUG_INFO_SIZE 64 /* Num bytes of debug info */
+
/* RETRY MECHANISM */
#define RETRY_MAX_REQU_DATA 2 /* /< Max number of attempts
* performed
diff --git a/ftm5/fts_lib/ftsSoftware.h b/ftm5/fts_lib/ftsSoftware.h
index 813404e..720430f 100644
--- a/ftm5/fts_lib/ftsSoftware.h
+++ b/ftm5/fts_lib/ftsSoftware.h
@@ -348,7 +348,13 @@ enum {
* Force */
#define LOAD_SENS_CAL_COEFF 0xC0 /* /< Load Sesitivity
* Calibration Coefficients */
-#define LOAD_GOLDEN_MUTUAL_RAW 0x80 /* /< Load Goden Mutual Raw Data */
+#define LOAD_DEBUG_INFO 0xC3 /* /< Load Sesitivity
+ * Calibration Coefficients */
+#define LOAD_GOLDEN_MUTUAL_RAW 0x80 /* /< Load Goden Mutual Raw Data */
+
+/* Debug information. */
+#define DEBUG_INFO_LP_DETECT 0x05 /* Low power detect scan mode. */
+#define DEBUG_INFO_LP_ACTIVE 0x06 /* Low power active scan mode. */
/** @}*/