diff options
author | Steve Pfetsch <spfetsch@google.com> | 2020-09-11 11:53:01 -0700 |
---|---|---|
committer | Steve Pfetsch <spfetsch@google.com> | 2020-09-24 22:44:53 +0000 |
commit | 6f2831fddffb0158b6af92e7c0b5cc369f883530 (patch) | |
tree | bfa0831edfd9a487773f97ba49e104948cded91d | |
parent | f18fb6c6f33b237bd5bed3e11f89ace042471df8 (diff) | |
download | sec_touch-6f2831fddffb0158b6af92e7c0b5cc369f883530.tar.gz |
input: touchscreen: sec_ts: 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: I3669603d8ef6a32bfd0613383eb2653487dfea45
-rw-r--r-- | sec_ts.c | 142 |
1 files changed, 86 insertions, 56 deletions
@@ -1598,6 +1598,9 @@ static void sec_ts_handle_coord_event(struct sec_ts_data *ts, #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) ts->offload.coords[t_id].x = ts->coord[t_id].x; ts->offload.coords[t_id].y = ts->coord[t_id].y; + ts->offload.coords[t_id].major = ts->coord[t_id].major; + ts->offload.coords[t_id].minor = ts->coord[t_id].minor; + ts->offload.coords[t_id].pressure = ts->coord[t_id].z; #endif if ((ts->coord[t_id].ttype == @@ -1907,11 +1910,15 @@ static void sec_ts_populate_coordinate_channel(struct sec_ts_data *ts, 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 = ts->offload.coords[j].x; dc->coords[j].y = ts->offload.coords[j].y; + dc->coords[j].major = ts->offload.coords[j].major; + dc->coords[j].minor = ts->offload.coords[j].minor; + dc->coords[j].pressure = ts->offload.coords[j].pressure; dc->coords[j].status = ts->offload.coords[j].status; } } @@ -1945,7 +1952,8 @@ static void sec_ts_populate_mutual_channel(struct sec_ts_data *ts, mutual_strength->tx_size = ts->tx_count; mutual_strength->rx_size = ts->rx_count; - 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); @@ -2000,7 +2008,7 @@ static void sec_ts_populate_mutual_channel(struct sec_ts_data *ts, ret = sec_ts_read_heap(ts, SEC_TS_READ_TOUCH_RAWDATA, (u8 *)ts->heatmap_buff, - mutual_strength->size_bytes); + mutual_strength->header.channel_size); if (ret < 0) { input_err(true, &ts->client->dev, "%s: Read mutual frame failed\n", __func__); @@ -2047,7 +2055,8 @@ static void sec_ts_populate_self_channel(struct sec_ts_data *ts, self_strength->tx_size = ts->tx_count; self_strength->rx_size = ts->rx_count; - 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); @@ -2102,7 +2111,7 @@ static void sec_ts_populate_self_channel(struct sec_ts_data *ts, ret = sec_ts_read_heap(ts, SEC_TS_READ_TOUCH_SELF_RAWDATA, (u8 *)ts->heatmap_buff, - self_strength->size_bytes); + self_strength->header.channel_size); if (ret < 0) { input_err(true, &ts->client->dev, "%s: Read self frame failed\n", __func__); @@ -2148,6 +2157,48 @@ static void sec_ts_populate_frame(struct sec_ts_data *ts, } } +int sec_ts_enable_grip(struct sec_ts_data *ts, bool enable) +{ + u8 value = enable ? 1 : 0; + int ret; + int final_result = 0; + + /* Set grip */ + ret = ts->sec_ts_write(ts, SEC_TS_CMD_SET_GRIP_DETEC, &value, 1); + if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: SEC_TS_CMD_SET_GRIP_DETEC failed with ret=%d\n", + __func__, ret); + final_result = ret; + } + + /* Set deadzone */ + value = enable ? 1 : 0; + ret = ts->sec_ts_write(ts, SEC_TS_CMD_EDGE_DEADZONE, &value, 1); + if (ret < 0) { + input_err(true, &ts->client->dev, + "%s: SEC_TS_CMD_EDGE_DEADZONE failed with ret=%d\n", + __func__, ret); + final_result = ret; + } + + return final_result; +} + +static void sec_ts_offload_set_running(struct sec_ts_data *ts, bool running) +{ + if (ts->offload.offload_running != running) { + ts->offload.offload_running = running; + if (running) { + pr_info("%s: disabling FW grip.\n", __func__); + sec_ts_enable_grip(ts, false); + } else { + pr_info("%s: enabling FW grip.\n", __func__); + sec_ts_enable_grip(ts, true); + } + } +} + #endif /* CONFIG_TOUCHSCREEN_OFFLOAD */ #define MAX_EVENT_COUNT 32 @@ -2483,22 +2534,24 @@ static void sec_ts_read_event(struct sec_ts_data *ts) #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) } - ret = touch_offload_reserve_frame(&ts->offload, &frame); - if (ret != 0) { - input_dbg(true, &ts->client->dev, - "Could not reserve a frame: ret=%d.\n", ret); + if (processed_pointer_event) { + ret = touch_offload_reserve_frame(&ts->offload, &frame); + if (ret != 0) { + input_dbg(true, &ts->client->dev, + "Could not reserve a frame: ret=%d.\n", ret); - /* Consider a lack of buffers to be the feature stopping */ - ts->offload.offload_running = false; - } else { - ts->offload.offload_running = true; + /* Stop offload when there are no buffers available */ + sec_ts_offload_set_running(ts, false); + } else { + sec_ts_offload_set_running(ts, true); - sec_ts_populate_frame(ts, frame); + sec_ts_populate_frame(ts, frame); - ret = touch_offload_queue_frame(&ts->offload, frame); - if (ret != 0) { - pr_err("%s: Failed to queue reserved frame: ret=%d.\n", - __func__, ret); + ret = touch_offload_queue_frame(&ts->offload, frame); + if (ret != 0) { + pr_err("%s: Failed to queue reserved frame: ret=%d.\n", + __func__, ret); + } } } #endif @@ -2562,7 +2615,9 @@ static irqreturn_t sec_ts_isr(int irq, void *handle) struct sec_ts_data *ts = (struct sec_ts_data *)handle; ts->timestamp = ktime_get(); +#if !IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) input_set_timestamp(ts->input_dev, ts->timestamp); +#endif return IRQ_WAKE_THREAD; } @@ -2609,6 +2664,8 @@ static void sec_ts_offload_report(void *handle, bool touch_down = 0; int i; + input_set_timestamp(ts->input_dev, report->timestamp); + for (i = 0; i < MAX_COORDS; i++) { if (report->coords[i].status == COORD_STATUS_FINGER) { input_mt_slot(ts->input_dev, i); @@ -2621,19 +2678,13 @@ static void sec_ts_offload_report(void *handle, report->coords[i].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, report->coords[i].y); - - /* TODO: replace with upcoming support for size and - * pressure via touch_offload path. - * For now, simply report acceptable constant size and - * pressure. - */ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 0x30); + report->coords[i].major); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, - 0x30); + report->coords[i].minor); #ifndef SKIP_PRESSURE input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 0x30); + report->coords[i].pressure); #endif } else { input_mt_slot(ts->input_dev, i); @@ -3848,6 +3899,13 @@ static int sec_ts_probe(struct spi_device *client) } #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) + ts->offload.caps.touch_offload_major_version = 1; + ts->offload.caps.touch_offload_minor_version = 0; + /* ID equivalent to the 4-byte, little-endian string: '00r3' */ + ts->offload.caps.device_id = + '3' << 24 | 'r' << 16 | '0' << 8 | '0' << 0; + ts->offload.caps.display_width = ts->plat_data->max_x + 1; + ts->offload.caps.display_height = ts->plat_data->max_y + 1; ts->offload.caps.tx_size = ts->tx_count; ts->offload.caps.rx_size = ts->rx_count; ts->offload.caps.heatmap_size = HEATMAP_SIZE_FULL; @@ -4838,34 +4896,6 @@ static void sec_ts_suspend_work(struct work_struct *work) mutex_unlock(&ts->device_mutex); } -int sec_ts_disable_grip(struct sec_ts_data *ts) -{ - u8 enable = 0; - int ret; - int final_result = 0; - - // disable grip - ret = ts->sec_ts_write(ts, SEC_TS_CMD_SET_GRIP_DETEC, &enable, 1); - if (ret < 0) { - input_err(true, &ts->client->dev, - "%s: SEC_TS_CMD_SET_GRIP_DETEC failed with ret=%d\n", - __func__, ret); - final_result = ret; - } - - // disable deadzone - enable = 0; - ret = ts->sec_ts_write(ts, SEC_TS_CMD_EDGE_DEADZONE, &enable, 1); - if (ret < 0) { - input_err(true, &ts->client->dev, - "%s: SEC_TS_CMD_EDGE_DEADZONE failed with ret=%d\n", - __func__, ret); - final_result = ret; - } - - return final_result; -} - static void sec_ts_resume_work(struct work_struct *work) { struct sec_ts_data *ts = container_of(work, struct sec_ts_data, @@ -4977,7 +5007,7 @@ static void sec_ts_resume_work(struct work_struct *work) "applying touch_offload settings.\n"); if (!ts->offload.config.filter_grip) - sec_ts_disable_grip(ts); + sec_ts_enable_grip(ts, false); } #endif |