diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-03-22 08:02:24 +0000 |
---|---|---|
committer | Android Partner Code Review <android-gerrit-partner@google.com> | 2022-03-22 08:02:24 +0000 |
commit | 8bf43151e1bc346577314114d968ae5a9d3f0362 (patch) | |
tree | 72aa611b5a09ec9f7216e14f86cbaec12acf2df2 /ft3658/focaltech_core.c | |
parent | 90f747d69454ec7449ba4c4c29eae7a0ef0903f0 (diff) | |
parent | 9317e79e4f3684367922ee70b92478445056965e (diff) | |
download | focaltech_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.c | 70 |
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"); |