summaryrefslogtreecommitdiff
path: root/ft3658/focaltech_core.c
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2022-03-22 08:02:24 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2022-03-22 08:02:24 +0000
commit8bf43151e1bc346577314114d968ae5a9d3f0362 (patch)
tree72aa611b5a09ec9f7216e14f86cbaec12acf2df2 /ft3658/focaltech_core.c
parent90f747d69454ec7449ba4c4c29eae7a0ef0903f0 (diff)
parent9317e79e4f3684367922ee70b92478445056965e (diff)
downloadfocaltech_touch-8bf43151e1bc346577314114d968ae5a9d3f0362.tar.gz
Merge "touch/focaltech: enable continuously touch reporting" into android13-gs-pixel-5.10
Diffstat (limited to 'ft3658/focaltech_core.c')
-rw-r--r--ft3658/focaltech_core.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/ft3658/focaltech_core.c b/ft3658/focaltech_core.c
index a8c37ee..97e8cbf 100644
--- a/ft3658/focaltech_core.c
+++ b/ft3658/focaltech_core.c
@@ -90,6 +90,7 @@ static u8 current_host_status;
static int fts_ts_suspend(struct device *dev);
static int fts_ts_resume(struct device *dev);
static void fts_update_feature_setting(struct fts_ts_data *ts_data);
+static void fts_update_motion_filter(struct fts_ts_data *ts, u8 touches);
int fts_check_cid(struct fts_ts_data *ts_data, u8 id_h)
{
@@ -621,6 +622,7 @@ static int fts_input_report_b(struct fts_ts_data *data)
}
input_set_timestamp(data->input_dev, data->coords_timestamp);
input_sync(data->input_dev);
+ fts_update_motion_filter(data, data->point_num);
#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
}
#endif
@@ -1194,6 +1196,66 @@ static void unregister_panel_bridge(struct drm_bridge *bridge)
}
#endif
+/* Update a state machine used to toggle control of the touch IC's motion
+ * filter.
+ */
+static void fts_update_motion_filter(struct fts_ts_data *ts, u8 touches)
+{
+ /* Motion filter timeout, in milliseconds */
+ const u32 mf_timeout_ms = 500;
+ u8 next_state;
+
+ next_state = ts->mf_state;
+ if (ts->mf_mode == MF_OFF) {
+ next_state = MF_UNFILTERED;
+ } else if (ts->mf_mode == MF_DYNAMIC) {
+ /* Determine the next filter state. The motion filter is enabled by
+ * default and it is disabled while a single finger is touching the
+ * screen. If another finger is touched down or if a timeout expires,
+ * the motion filter is reenabled and remains enabled until all fingers
+ * are lifted.
+ */
+ next_state = ts->mf_state;
+ switch (ts->mf_state) {
+ case MF_FILTERED:
+ if (touches == 1) {
+ next_state = MF_UNFILTERED;
+ ts->mf_downtime = ktime_get();
+ }
+ break;
+ case MF_UNFILTERED:
+ if (touches == 0) {
+ next_state = MF_FILTERED;
+ } else if (touches > 1 || ktime_after(ktime_get(),
+ ktime_add_ms(ts->mf_downtime, mf_timeout_ms))) {
+ next_state = MF_FILTERED_LOCKED;
+ }
+ break;
+ case MF_FILTERED_LOCKED:
+ if (touches == 0)
+ next_state = MF_FILTERED;
+ break;
+ }
+ } else if (ts->mf_mode == MF_ON) {
+ next_state = MF_FILTERED;
+ } else {
+ /* Set MF_DYNAMIC as default when an invalid value is found. */
+ ts->mf_mode = MF_DYNAMIC;
+ return;
+ }
+
+ /* Send command to update firmware continuous report */
+ if ((next_state == MF_UNFILTERED) !=
+ (ts->mf_state == MF_UNFILTERED)) {
+ ts->set_continuously_report =
+ (next_state == MF_UNFILTERED) ? 0x01 : 0x00;
+ PR_LOGD("set firmware continuous report(%s).\n",
+ ts->set_continuously_report ? "Enable" : "Disable");
+ fts_write_reg(FTS_REG_CONTINUOUS_EN, ts->set_continuously_report);
+ }
+ ts->mf_state = next_state;
+}
+
#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) || \
IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP)
#if IS_ENABLED(GOOGLE_HEATMAP_DEBUG)
@@ -1416,6 +1478,8 @@ static void fts_offload_report(void *handle,
struct fts_ts_data *ts_data = (struct fts_ts_data *)handle;
bool touch_down = 0;
int i;
+ int touch_count = 0;
+
mutex_lock(&ts_data->report_mutex);
input_set_timestamp(ts_data->input_dev, ts_data->coords_timestamp);
@@ -1423,6 +1487,7 @@ static void fts_offload_report(void *handle,
for (i = 0; i < MAX_COORDS; i++) {
if (report->coords[i].status == COORD_STATUS_FINGER) {
input_mt_slot(ts_data->input_dev, i);
+ touch_count++;
touch_down = 1;
input_report_key(ts_data->input_dev, BTN_TOUCH, touch_down);
input_report_key(ts_data->input_dev, BTN_TOOL_FINGER, touch_down);
@@ -1448,6 +1513,7 @@ static void fts_offload_report(void *handle,
input_report_key(ts_data->input_dev, BTN_TOOL_FINGER, touch_down);
input_sync(ts_data->input_dev);
+ fts_update_motion_filter(ts_data, touch_count);
mutex_unlock(&ts_data->report_mutex);
}
@@ -2704,6 +2770,10 @@ static int fts_ts_probe_entry(struct fts_ts_data *ts_data)
}
#endif
+ /* init motion filter mode and state. */
+ ts_data->mf_mode = MF_DYNAMIC;
+ ts_data->mf_state = MF_UNFILTERED;
+
ret = fts_create_sysfs(ts_data);
if (ret) {
FTS_ERROR("create sysfs node fail");