diff options
author | Steve Pfetsch <spfetsch@google.com> | 2020-09-11 12:02:55 -0700 |
---|---|---|
committer | Steve Pfetsch <spfetsch@google.com> | 2020-09-24 22:44:52 +0000 |
commit | ed664b07d67ce440f666faf03da086f84e783794 (patch) | |
tree | 7465e90b842cc1ee822af4dde778c4b9a4d0f87b | |
parent | 3ffa2f46ca37a9ecd74e8dcc24b7d7ed33baee25 (diff) | |
download | fts_touch-ed664b07d67ce440f666faf03da086f84e783794.tar.gz |
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 <spfetsch@google.com>
Change-Id: I937357fe5f5b7fc3c63f255c17d27c231cd3d495
-rw-r--r-- | fts.c | 96 |
1 files changed, 75 insertions, 21 deletions
@@ -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); @@ -4198,7 +4219,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); @@ -4247,6 +4269,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 */ /** @@ -4331,22 +4367,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 @@ -4375,6 +4414,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); @@ -4387,10 +4428,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); @@ -4890,7 +4935,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; } @@ -6296,6 +6343,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; |