Skip to content

Commit 8b45a31

Browse files
committed
ipts: Simplify feedback implementation
This implementation originated from the new IPTS driver for linux 5.4 and newer. Reportedly, the new driver is way more stable on gen4 devices (SB1 + SP4) than this driver, without needing the no_feedback hack. Normally, the feedback data is provided by the GuC. The driver takes this data, copies it into the feedback data buffer, and then tells the ME about it. The data inside of the buffer is completely opaque to the driver itself, it is not touched except for copying it. In the new driver it is impossible to use the GuC for touch processing, therefor it is also impossible to receive feedback data from it. The new driver just uses an empty buffer and only fills in the parts that are definitly required: The type of feedback we are sending, and the buffer / transaction ID. This seems to work just fine. Signed-off-by: Dorian Stoll <[email protected]>
1 parent 69ee395 commit 8b45a31

2 files changed

Lines changed: 25 additions & 49 deletions

File tree

‎drivers/misc/ipts/hid.c‎

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,11 @@ int ipts_handle_hid_data(struct ipts_info *ipts,
356356
static int handle_outputs(struct ipts_info *ipts, int parallel_idx)
357357
{
358358
struct kernel_output_buffer_header *out_buf_hdr;
359-
struct ipts_buffer_info *output_buf, *fb_buf = NULL;
359+
struct ipts_buffer_info *output_buf;
360360
u8 *input_report, *payload;
361-
u32 tr_id;
362-
int i, payload_size, ret = 0, header_size;
361+
u8 tr_id;
362+
int i, payload_size, header_size;
363+
bool send_feedback = false;
363364

364365
header_size = sizeof(struct kernel_output_buffer_header);
365366
output_buf = ipts_get_output_buffers_by_parallel_id(ipts,
@@ -372,6 +373,9 @@ static int handle_outputs(struct ipts_info *ipts, int parallel_idx)
372373
if (out_buf_hdr->length < header_size)
373374
continue;
374375

376+
tr_id = *(u8 *)&out_buf_hdr->hid_private_data.transaction_id;
377+
send_feedback = true;
378+
375379
payload_size = out_buf_hdr->length - header_size;
376380
payload = out_buf_hdr->data;
377381

@@ -394,12 +398,7 @@ static int handle_outputs(struct ipts_info *ipts, int parallel_idx)
394398
break;
395399
}
396400
case OUTPUT_BUFFER_PAYLOAD_FEEDBACK_BUFFER: {
397-
// send feedback data for raw data mode
398-
fb_buf = ipts_get_feedback_buffer(ipts, parallel_idx);
399-
tr_id = out_buf_hdr->hid_private_data.transaction_id;
400-
401-
memcpy(fb_buf->addr, payload, payload_size);
402-
401+
// Ignored
403402
break;
404403
}
405404
case OUTPUT_BUFFER_PAYLOAD_ERROR: {
@@ -429,42 +428,10 @@ static int handle_outputs(struct ipts_info *ipts, int parallel_idx)
429428
}
430429
}
431430

432-
/*
433-
* XXX: Calling the "ipts_send_feedback" function repeatedly seems to
434-
* be what is causing touch to crash (found by sebanc, see the link
435-
* below for the comment) on some models, especially on Surface Pro 4
436-
* and Surface Book 1.
437-
* The most desirable fix could be done by raising IPTS GuC priority.
438-
* Until we find a better solution, use this workaround.
439-
*
440-
* The decision which devices have no_feedback enabled by default is
441-
* made by the companion driver. If no companion driver was loaded,
442-
* no_feedback is disabled and the default behaviour is used.
443-
*
444-
* Link to the comment where sebanc found this workaround:
445-
* https://github.com/jakeday/linux-surface/issues/374#issuecomment-508234110
446-
* (Touch and pen issue persists · Issue #374 · jakeday/linux-surface)
447-
*
448-
* Link to the usage from kitakar5525 who made this change:
449-
* https://github.com/jakeday/linux-surface/issues/374#issuecomment-517289171
450-
* (Touch and pen issue persists · Issue #374 · jakeday/linux-surface)
451-
*/
452-
if (fb_buf) {
453-
// A negative value means "decide by dmi table"
454-
if (ipts_modparams.no_feedback < 0) {
455-
if (ipts_get_quirks() & IPTS_QUIRK_NO_FEEDBACK)
456-
ipts_modparams.no_feedback = true;
457-
else
458-
ipts_modparams.no_feedback = false;
459-
}
460431

461-
if (ipts_modparams.no_feedback)
462-
return 0;
463432

464-
ret = ipts_send_feedback(ipts, parallel_idx, tr_id);
465-
if (ret)
466-
return ret;
467-
}
433+
if (send_feedback)
434+
return ipts_send_feedback(ipts, parallel_idx, tr_id);
468435

469436
return 0;
470437
}

‎drivers/misc/ipts/msg-handler.c‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,24 @@ int ipts_handle_cmd(struct ipts_info *ipts, u32 cmd, void *data, int data_size)
4242
int ipts_send_feedback(struct ipts_info *ipts, int buffer_idx,
4343
u32 transaction_id)
4444
{
45-
int cmd_len = sizeof(struct touch_sensor_feedback_ready_cmd_data);
46-
struct touch_sensor_feedback_ready_cmd_data fb_ready_cmd;
45+
struct ipts_buffer_info feedback_buffer;
46+
struct touch_feedback_hdr *feedback;
47+
struct touch_sensor_feedback_ready_cmd_data cmd;
4748

48-
memset(&fb_ready_cmd, 0, cmd_len);
49+
feedback_buffer = ipts->resource.feedback_buffer[buffer_idx];
50+
feedback = (struct touch_feedback_hdr *)feedback_buffer.addr;
4951

50-
fb_ready_cmd.feedback_index = buffer_idx;
51-
fb_ready_cmd.transaction_id = transaction_id;
52+
memset(feedback, 0, sizeof(struct touch_feedback_hdr));
53+
memset(&cmd, 0, sizeof(struct touch_sensor_feedback_ready_cmd_data));
54+
55+
feedback->feedback_cmd_type = TOUCH_FEEDBACK_CMD_TYPE_NONE;
56+
feedback->buffer_id = transaction_id;
57+
58+
cmd.feedback_index = buffer_idx;
59+
cmd.transaction_id = transaction_id;
5260

5361
return ipts_handle_cmd(ipts, TOUCH_SENSOR_FEEDBACK_READY_CMD,
54-
&fb_ready_cmd, cmd_len);
62+
&cmd, sizeof(struct touch_sensor_feedback_ready_cmd_data));
5563
}
5664

5765
int ipts_send_sensor_quiesce_io_cmd(struct ipts_info *ipts)
@@ -339,6 +347,7 @@ int ipts_handle_resp(struct ipts_info *ipts,
339347
}
340348
case TOUCH_SENSOR_FEEDBACK_READY_RSP: {
341349
if (rsp_status != TOUCH_STATUS_COMPAT_CHECK_FAIL &&
350+
rsp_status != TOUCH_STATUS_INVALID_PARAMS &&
342351
rsp_status != 0) {
343352
rsp_failed(ipts, cmd, rsp_status);
344353
break;

0 commit comments

Comments
 (0)