From dc9662a7ce0db7a9e1f8884008f9968e7f825ff1 Mon Sep 17 00:00:00 2001 From: Super Liu Date: Wed, 9 Sep 2020 15:53:13 +0800 Subject: fts: release all fingers for offload case Bug: 167758661 Change-Id: I93005492bc203d19bff3191f2e0c63221d5f0ffb Signed-off-by: Super Liu (cherry picked from commit 3ffa2f46ca37a9ecd74e8dcc24b7d7ed33baee25) --- fts.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fts.c b/fts.c index 8629758..a601334 100644 --- a/fts.c +++ b/fts.c @@ -174,6 +174,9 @@ void release_all_touches(struct fts_ts_info *info) input_report_abs(info->input_dev, ABS_MT_PRESSURE, 0); input_mt_report_slot_state(info->input_dev, type, 0); input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1); +#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) + info->offload.coords[i].status = COORD_STATUS_INACTIVE; +#endif } input_report_key(info->input_dev, BTN_TOUCH, 0); input_sync(info->input_dev); -- cgit v1.2.3 From d29ad7ab0f865b36d915303f03c75130a7c46694 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Mon, 28 Sep 2020 13:16:01 -0700 Subject: input: touchscreen: stm: fix memory leak Free memory allocated by calls to getMSFrame3 and getSSFrame3. Bug: 169240052 Signed-off-by: Steve Pfetsch Change-Id: I204502f08e702417b8879430bd6c414aef2275f5 --- fts.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fts.c b/fts.c index a601334..9d77879 100644 --- a/fts.c +++ b/fts.c @@ -4185,6 +4185,7 @@ static void fts_populate_mutual_channel(struct fts_ts_info *info, } } } + kfree(ms_frame.node_data); } static void fts_populate_self_channel(struct fts_ts_info *info, @@ -4225,6 +4226,8 @@ static void fts_populate_self_channel(struct fts_ts_info *info, memcpy(&self_strength->data[2 * self_strength->tx_size], ss_frame.sense_data, 2 * self_strength->rx_size); } + kfree(ss_frame.force_data); + kfree(ss_frame.sense_data); } static void fts_populate_frame(struct fts_ts_info *info, -- cgit v1.2.3 From e919a53da7c765b437cd952cfbfe165092aa6ea1 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Fri, 11 Sep 2020 12:02:55 -0700 Subject: input: touchscreen: stm: improve touch_offload support Fully route pressure and major/minor size of touch points, apply routed timestamps, and keep firmware grip closely synced with touch_offload. Additional miscellaneous changes to support updated touch_offload interface. Bug: 167758661 Bug: 168076476 Signed-off-by: Steve Pfetsch Change-Id: I937357fe5f5b7fc3c63f255c17d27c231cd3d495 --- fts.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 21 deletions(-) diff --git a/fts.c b/fts.c index 9d77879..b9292e2 100644 --- a/fts.c +++ b/fts.c @@ -3092,8 +3092,17 @@ static bool fts_enter_pointer_event_handler(struct fts_ts_info *info, unsigned #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) info->offload.coords[touchId].x = x; info->offload.coords[touchId].y = y; + info->offload.coords[touchId].major = major; + info->offload.coords[touchId].minor = minor; info->offload.coords[touchId].status = COORD_STATUS_FINGER; +#ifndef SKIP_PRESSURE + info->offload.coords[touchId].pressure = z; +#else + /* Select a reasonable constant pressure */ + info->offload.coords[touchId].pressure = 0x30; +#endif + if (!info->offload.offload_running) { #endif @@ -4078,12 +4087,19 @@ static int update_motion_filter(struct fts_ts_info *info) return 0; } -int fts_disable_grip(struct fts_ts_info *info) + +int fts_enable_grip(struct fts_ts_info *info, bool enable) { - uint8_t cmd[] = {0xC0, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static uint8_t enable_cmd[] = + {0xC0, 0x03, 0x10, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00}; + static uint8_t disable_cmd[] = + {0xC0, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int res; - res = fts_write(cmd, sizeof(cmd)); + if (enable) + res = fts_write(enable_cmd, sizeof(enable_cmd)); + else + res = fts_write(disable_cmd, sizeof(disable_cmd)); if (res < 0) pr_err("%s: fts_write failed with res=%d.\n", __func__, res); @@ -4100,7 +4116,7 @@ static void fts_offload_resume_work(struct work_struct *work) struct fts_ts_info *info = container_of(dwork, struct fts_ts_info, offload_resume_work); - fts_disable_grip(info); + fts_enable_grip(info, false); } static void fts_populate_coordinate_channel(struct fts_ts_info *info, @@ -4112,11 +4128,15 @@ static void fts_populate_coordinate_channel(struct fts_ts_info *info, struct TouchOffloadDataCoord *dc = (struct TouchOffloadDataCoord *)frame->channel_data[channel]; memset(dc, 0, frame->channel_data_size[channel]); - dc->size_bytes = TOUCH_OFFLOAD_FRAME_SIZE_COORD; + dc->header.channel_type = TOUCH_DATA_TYPE_COORD; + dc->header.channel_size = TOUCH_OFFLOAD_FRAME_SIZE_COORD; for (j = 0; j < MAX_COORDS; j++) { dc->coords[j].x = info->offload.coords[j].x; dc->coords[j].y = info->offload.coords[j].y; + dc->coords[j].major = info->offload.coords[j].major; + 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; } } @@ -4150,7 +4170,8 @@ static void fts_populate_mutual_channel(struct fts_ts_info *info, } mutual_strength->tx_size = getForceLen(); mutual_strength->rx_size = getSenseLen(); - mutual_strength->size_bytes = + mutual_strength->header.channel_type = frame->channel_type[channel]; + mutual_strength->header.channel_size = TOUCH_OFFLOAD_FRAME_SIZE_2D(mutual_strength->rx_size, mutual_strength->tx_size); @@ -4199,7 +4220,8 @@ static void fts_populate_self_channel(struct fts_ts_info *info, (struct TouchOffloadData1d *)frame->channel_data[channel]; self_strength->tx_size = getForceLen(); self_strength->rx_size = getSenseLen(); - self_strength->size_bytes = + self_strength->header.channel_type = frame->channel_type[channel]; + self_strength->header.channel_size = TOUCH_OFFLOAD_FRAME_SIZE_1D(self_strength->rx_size, self_strength->tx_size); @@ -4250,6 +4272,20 @@ static void fts_populate_frame(struct fts_ts_info *info, } } +static void fts_offload_set_running(struct fts_ts_info *info, bool running) +{ + if (info->offload.offload_running != running) { + info->offload.offload_running = running; + if (running) { + pr_info("%s: disabling FW grip.\n", __func__); + fts_enable_grip(info, false); + } else { + pr_info("%s: enabling FW grip.\n", __func__); + fts_enable_grip(info, true); + } + } +} + #endif /* CONFIG_TOUCHSCREEN_OFFLOAD */ /** @@ -4334,22 +4370,25 @@ static irqreturn_t fts_interrupt_handler(int irq, void *handle) #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) } - error = touch_offload_reserve_frame(&info->offload, &frame); - if (error != 0) { - pr_debug("%s: Could not reserve a frame: error=%d.\n", - __func__, error); + if (processed_pointer_event) { + error = touch_offload_reserve_frame(&info->offload, &frame); + if (error != 0) { + pr_debug("%s: Could not reserve a frame: error=%d.\n", + __func__, error); - /* Consider a lack of buffers to be the feature stopping */ - info->offload.offload_running = false; - } else { - info->offload.offload_running = true; + /* Stop offload when there are no buffers available */ + fts_offload_set_running(info, false); + } else { + fts_offload_set_running(info, true); - fts_populate_frame(info, frame); + fts_populate_frame(info, frame); - error = touch_offload_queue_frame(&info->offload, frame); - if (error != 0) { - pr_err("%s: Failed to queue reserved frame: error=%d.\n", - __func__, error); + error = touch_offload_queue_frame(&info->offload, + frame); + if (error != 0) { + pr_err("%s: Failed to queue reserved frame: error=%d.\n", + __func__, error); + } } } #endif @@ -4378,6 +4417,8 @@ static void fts_offload_report(void *handle, bool touch_down = 0; int i; + input_set_timestamp(info->input_dev, report->timestamp); + for (i = 0; i < MAX_COORDS; i++) { if (report->coords[i].status == COORD_STATUS_FINGER) { input_mt_slot(info->input_dev, i); @@ -4390,10 +4431,14 @@ static void fts_offload_report(void *handle, report->coords[i].x); input_report_abs(info->input_dev, ABS_MT_POSITION_Y, report->coords[i].y); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, + report->coords[i].major); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, + report->coords[i].minor); #ifndef SKIP_PRESSURE input_report_abs(info->input_dev, ABS_MT_PRESSURE, - 0x30); + report->coords[i].pressure); #endif } else { input_mt_slot(info->input_dev, i); @@ -4893,7 +4938,9 @@ static irqreturn_t fts_isr(int irq, void *handle) struct fts_ts_info *info = handle; info->timestamp = ktime_get(); +#if !IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) input_set_timestamp(info->input_dev, info->timestamp); +#endif return IRQ_WAKE_THREAD; } @@ -6299,6 +6346,13 @@ static int fts_probe(struct spi_device *client) #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) + info->offload.caps.touch_offload_major_version = 1; + info->offload.caps.touch_offload_minor_version = 0; + /* ID equivalent to the 4-byte, little-endian string: '00b5' */ + info->offload.caps.device_id = + '5' << 24 | 'b' << 16 | '0' << 8 | '0' << 0; + info->offload.caps.display_width = info->board->x_axis_max; + info->offload.caps.display_height = info->board->y_axis_max; info->offload.caps.tx_size = getForceLen(); info->offload.caps.rx_size = getSenseLen(); info->offload.caps.bus_type = BUS_TYPE_SPI; -- cgit v1.2.3 From 47874b71e19d1420bd3d0b33b7dea3f81e855520 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Wed, 11 Nov 2020 18:51:56 -0800 Subject: input: touchscreen: stm: Read touch_offload device_id from DT Bug: 172058450 Signed-off-by: Steve Pfetsch Change-Id: If75fd20aebdc90882ff796c3d562836c7ef477a4 --- fts.c | 18 +++++++++++++++--- fts.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/fts.c b/fts.c index b9292e2..d8e3105 100644 --- a/fts.c +++ b/fts.c @@ -5917,6 +5917,7 @@ static int parse_dt(struct device *dev, struct fts_hw_platform_data *bdata) const char *name; struct device_node *np = dev->of_node; u32 coords[2]; + u8 offload_id[4]; if (of_property_read_bool(np, "st,panel_map")) { for (index = 0 ;; index++) { @@ -6014,6 +6015,19 @@ static int parse_dt(struct device *dev, struct fts_hw_platform_data *bdata) bdata->sensor_inverted_y = 1; pr_info("Sensor inverted y = %u\n", bdata->sensor_inverted_y); + bdata->offload_id = 0; + retval = of_property_read_u8_array(np, "st,touch_offload_id", + offload_id, 4); + if (retval == -EINVAL) + pr_err("Failed to read st,touch_offload_id with error = %d\n", + retval); + else { + bdata->offload_id = *(u32 *)offload_id; + pr_info("Offload device ID = \"%c%c%c%c\" / 0x%08X\n", + offload_id[0], offload_id[1], offload_id[2], offload_id[3], + bdata->offload_id); + } + return OK; } @@ -6348,9 +6362,7 @@ static int fts_probe(struct spi_device *client) #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) info->offload.caps.touch_offload_major_version = 1; info->offload.caps.touch_offload_minor_version = 0; - /* ID equivalent to the 4-byte, little-endian string: '00b5' */ - info->offload.caps.device_id = - '5' << 24 | 'b' << 16 | '0' << 8 | '0' << 0; + info->offload.caps.device_id = info->board->offload_id; info->offload.caps.display_width = info->board->x_axis_max; info->offload.caps.display_height = info->board->y_axis_max; info->offload.caps.tx_size = getForceLen(); diff --git a/fts.h b/fts.h index acf52a2..939dc2b 100644 --- a/fts.h +++ b/fts.h @@ -302,6 +302,7 @@ struct fts_hw_platform_data { struct drm_panel *panel; u32 initial_panel_index; u32 *force_pi_cfg_ver; + u32 offload_id; }; /* Bits for the bus reference mask */ -- cgit v1.2.3 From c8440098c6918685a7d61d8c0f2e44e566d84f37 Mon Sep 17 00:00:00 2001 From: Tai Kuo Date: Thu, 28 Jan 2021 17:31:46 +0800 Subject: touch: fts: cancel offload_resume_work before suspend Put offload_resume_work, resume_work, suspend_work into the same high-priority workqueue. Cancel the resume_work does not cancel the derived delayed work offload_resume_work. Need to cancel offload_resume_work before queue the suspend work. If suspend_work was executed right after the resume_work, __pm_relax in suspend will delete __pm_wakeup_event timer immediately, and hence the offload_resume_work spi_sync work will be blocked forever. Bug: 177551504 Test: test resume then suspend to check offload_resume_work. Signed-off-by: Tai Kuo Change-Id: I8c050d48f2d2d45fb1a82fb227bb24f915c604e7 (cherry picked from commit 4d794d1ee9d43a00150bf87f10442322d2c572ff) --- fts.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fts.c b/fts.c index d8e3105..63e0783 100644 --- a/fts.c +++ b/fts.c @@ -5399,7 +5399,9 @@ static void fts_resume_work(struct work_struct *work) /* The grip disable command will not take effect unless * it is delayed ~100ms. */ - schedule_delayed_work(&info->offload_resume_work, 100); + queue_delayed_work(info->event_wq, + &info->offload_resume_work, + msecs_to_jiffies(100)); } } #endif @@ -5466,9 +5468,12 @@ static void fts_aggregate_bus_state(struct fts_ts_info *info) (info->bus_refmask != 0 && !info->sensor_sleep)) return; - if (info->bus_refmask == 0) + if (info->bus_refmask == 0) { +#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) + cancel_delayed_work_sync(&info->offload_resume_work); +#endif queue_work(info->event_wq, &info->suspend_work); - else + } else queue_work(info->event_wq, &info->resume_work); } -- cgit v1.2.3 From e71f3fa0ccca468ea288b844cfac7eca70e49cd7 Mon Sep 17 00:00:00 2001 From: Tai Kuo Date: Thu, 28 Jan 2021 17:31:46 +0800 Subject: touch: fts: cancel offload_resume_work before suspend Put offload_resume_work, resume_work, suspend_work into the same high-priority workqueue. Cancel the resume_work does not cancel the derived delayed work offload_resume_work. Need to cancel offload_resume_work before queue the suspend work. If suspend_work was executed right after the resume_work, __pm_relax in suspend will delete __pm_wakeup_event timer immediately, and hence the offload_resume_work spi_sync work will be blocked forever. Bug: 177551504 Bug: 172556964 Test: test resume then suspend to check offload_resume_work. Signed-off-by: Tai Kuo Change-Id: I8c050d48f2d2d45fb1a82fb227bb24f915c604e7 (cherry picked from commit 4d794d1ee9d43a00150bf87f10442322d2c572ff) --- fts.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fts.c b/fts.c index b9292e2..97eec98 100644 --- a/fts.c +++ b/fts.c @@ -5399,7 +5399,9 @@ static void fts_resume_work(struct work_struct *work) /* The grip disable command will not take effect unless * it is delayed ~100ms. */ - schedule_delayed_work(&info->offload_resume_work, 100); + queue_delayed_work(info->event_wq, + &info->offload_resume_work, + msecs_to_jiffies(100)); } } #endif @@ -5466,9 +5468,12 @@ static void fts_aggregate_bus_state(struct fts_ts_info *info) (info->bus_refmask != 0 && !info->sensor_sleep)) return; - if (info->bus_refmask == 0) + if (info->bus_refmask == 0) { +#if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) + cancel_delayed_work_sync(&info->offload_resume_work); +#endif queue_work(info->event_wq, &info->suspend_work); - else + } else queue_work(info->event_wq, &info->resume_work); } -- cgit v1.2.3