summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Chang <changmark@google.com>2021-12-10 03:50:12 +0000
committerSteve Pfetsch <spfetsch@google.com>2022-01-06 18:43:20 +0000
commit0949cefad199962342664a5fe3db309ee4d0f761 (patch)
tree2ac789d9b3aa77aa2c11321f7945379e75f332b9
parentb1348bbf79b84911616554844d6de03c4a491fe4 (diff)
downloadfts_touch-0949cefad199962342664a5fe3db309ee4d0f761.tar.gz
touch/ftm5: Push frame with empty coords on suspend.
Bug: 205512786 Test: Build pass and bug no longer reproducible. Signed-off-by: Mark Chang <changmark@google.com> Change-Id: I16a8ca2db27ad023b57f93bccc90f414c7bcfb9b
-rw-r--r--ftm5/fts.c69
-rw-r--r--ftm5/fts.h1
2 files changed, 64 insertions, 6 deletions
diff --git a/ftm5/fts.c b/ftm5/fts.c
index 2187ca5..6098d8f 100644
--- a/ftm5/fts.c
+++ b/ftm5/fts.c
@@ -122,6 +122,10 @@ static int fts_chip_initialization(struct fts_ts_info *info, int init_type);
static int register_panel_bridge(struct fts_ts_info *info);
static void unregister_panel_bridge(struct drm_bridge *bridge);
+#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
+static void fts_offload_push_coord_frame(struct fts_ts_info *info);
+#endif
+
/**
* Release all the touches in the linux input subsystem
* @param info pointer to fts_ts_info which contains info about device/hw setup
@@ -131,6 +135,18 @@ void release_all_touches(struct fts_ts_info *info)
unsigned int type = MT_TOOL_FINGER;
int i;
+#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
+ /* If the previous coord_frame that was pushed to touch_offload had
+ * active coords (eg. there are fingers still on the screen), push an
+ * empty coord_frame to touch_offload for clearing coords in twoshay.*/
+ if (info->touch_offload_active_coords) {
+ for (i = 0; i < TOUCH_ID_MAX; i++) {
+ info->offload.coords[i].status = COORD_STATUS_INACTIVE;
+ }
+ fts_offload_push_coord_frame(info);
+ } else {
+#endif
+
mutex_lock(&info->input_report_mutex);
for (i = 0; i < TOUCH_ID_MAX; i++) {
@@ -156,6 +172,10 @@ void release_all_touches(struct fts_ts_info *info)
mutex_unlock(&info->input_report_mutex);
+#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
+ }
+#endif
+
info->touch_id = 0;
info->palm_touch_mask = 0;
info->grip_touch_mask = 0;
@@ -4107,6 +4127,7 @@ static void fts_populate_coordinate_channel(struct fts_ts_info *info,
int channel)
{
int j;
+ int active_coords = 0;
struct TouchOffloadDataCoord *dc =
(struct TouchOffloadDataCoord *)frame->channel_data[channel];
@@ -4121,7 +4142,11 @@ static void fts_populate_coordinate_channel(struct fts_ts_info *info,
dc->coords[j].minor = info->offload.coords[j].minor;
dc->coords[j].pressure = info->offload.coords[j].pressure;
dc->coords[j].status = info->offload.coords[j].status;
+ if (dc->coords[j].status != COORD_STATUS_INACTIVE)
+ active_coords += 1;
}
+
+ info->touch_offload_active_coords = active_coords;
}
static void fts_update_v4l2_mutual_strength(struct fts_ts_info *info,
@@ -4325,7 +4350,8 @@ static void fts_populate_self_channel(struct fts_ts_info *info,
}
static void fts_populate_frame(struct fts_ts_info *info,
- struct touch_offload_frame *frame)
+ struct touch_offload_frame *frame,
+ int populate_channel_types)
{
static u64 index;
int i;
@@ -4335,11 +4361,14 @@ static void fts_populate_frame(struct fts_ts_info *info,
/* Populate all channels */
for (i = 0; i < frame->num_channels; i++) {
- if (frame->channel_type[i] == TOUCH_DATA_TYPE_COORD)
+ if ((frame->channel_type[i] & populate_channel_types) ==
+ TOUCH_DATA_TYPE_COORD)
fts_populate_coordinate_channel(info, frame, i);
- else if ((frame->channel_type[i] & TOUCH_SCAN_TYPE_MUTUAL) != 0)
+ else if ((frame->channel_type[i] & TOUCH_SCAN_TYPE_MUTUAL &
+ populate_channel_types) != 0)
fts_populate_mutual_channel(info, frame, i);
- else if ((frame->channel_type[i] & TOUCH_SCAN_TYPE_SELF) != 0)
+ else if ((frame->channel_type[i] & TOUCH_SCAN_TYPE_SELF &
+ populate_channel_types) != 0)
fts_populate_self_channel(info, frame, i);
}
}
@@ -4460,7 +4489,7 @@ static irqreturn_t fts_interrupt_handler(int irq, void *handle)
} else {
fts_offload_set_running(info, true);
- fts_populate_frame(info, frame);
+ fts_populate_frame(info, frame, 0xFFFFFFFF);
error = touch_offload_queue_frame(&info->offload,
frame);
@@ -4488,6 +4517,32 @@ static irqreturn_t fts_interrupt_handler(int irq, void *handle)
}
#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
+static void fts_offload_push_coord_frame(struct fts_ts_info *info) {
+ struct touch_offload_frame *frame = NULL;
+ int error = 0;
+
+ dev_info(info->dev, "%s: active coords %d.\n",
+ __func__, info->touch_offload_active_coords);
+
+ error = touch_offload_reserve_frame(&info->offload, &frame);
+ if (error != 0) {
+ dev_dbg(info->dev,
+ "%s: Could not reserve a frame: error=%d.\n",
+ __func__, error);
+
+ } else {
+ fts_populate_frame(info, frame, TOUCH_DATA_TYPE_COORD);
+
+ error = touch_offload_queue_frame(&info->offload,
+ frame);
+ if (error != 0) {
+ dev_err(info->dev,
+ "%s: Failed to queue reserved frame: error=%d.\n",
+ __func__, error);
+ }
+ }
+}
+
static void fts_offload_report(void *handle,
struct TouchOffloadIocReport *report)
{
@@ -6641,7 +6696,9 @@ static int fts_probe(struct spi_device *client)
info->mutual_strength_heatmap.data = NULL;
info->v4l2_mutual_strength_updated = false;
#endif
-
+#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
+ info->touch_offload_active_coords = 0;
+#endif
/* init motion filter mode */
info->use_default_mf = false;
diff --git a/ftm5/fts.h b/ftm5/fts.h
index 2a84748..89aa218 100644
--- a/ftm5/fts.h
+++ b/ftm5/fts.h
@@ -834,6 +834,7 @@ struct fts_ts_info {
#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD)
struct touch_offload_context offload;
struct delayed_work offload_resume_work;
+ int touch_offload_active_coords;
#endif
struct delayed_work fwu_work; /* Work for fw update */