1) Align with the i2c-hid driver by returning 0 instead of -EINVAL when an empty response is received, ensuring that userspace programs utilizing the hidraw node receive consistent return values. 2) Implement the hid get/set feature report function using a separate address, rather than sharing an address with coordinate reporting, to prevent feature events from being overwritten by coordinate events. Signed-off-by: Charles Wang <charles.goodix@xxxxxxxxx> --- drivers/hid/hid-goodix-spi.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-goodix-spi.c b/drivers/hid/hid-goodix-spi.c index 0f87bf9c6..6ae2300a6 100644 --- a/drivers/hid/hid-goodix-spi.c +++ b/drivers/hid/hid-goodix-spi.c @@ -19,6 +19,7 @@ #define GOODIX_HID_DESC_ADDR 0x1058C #define GOODIX_HID_REPORT_DESC_ADDR 0x105AA #define GOODIX_HID_SIGN_ADDR 0x10D32 +#define GOODIX_HID_CMD_ADDR 0x10364 #define GOODIX_HID_GET_REPORT_CMD 0x02 #define GOODIX_HID_SET_REPORT_CMD 0x03 @@ -348,7 +349,7 @@ static int goodix_hid_check_ack_status(struct goodix_ts_data *ts, u32 *resp_len) * - byte 0: Ack flag, value of 1 for data ready * - bytes 1-2: Response data length */ - error = goodix_spi_read(ts, ts->hid_report_addr, + error = goodix_spi_read(ts, GOODIX_HID_CMD_ADDR, &hdr, sizeof(hdr)); if (!error && (hdr.flag & GOODIX_HID_ACK_READY_FLAG)) { len = le16_to_cpu(hdr.size); @@ -356,7 +357,7 @@ static int goodix_hid_check_ack_status(struct goodix_ts_data *ts, u32 *resp_len) dev_err(ts->dev, "hrd.size too short: %d", len); return -EINVAL; } - *resp_len = len; + *resp_len = len - GOODIX_HID_PKG_LEN_SIZE; return 0; } @@ -431,7 +432,7 @@ static int goodix_hid_get_raw_report(struct hid_device *hid, tx_len += args_len; /* Step1: write report request info */ - error = goodix_spi_write(ts, ts->hid_report_addr, tmp_buf, tx_len); + error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, tmp_buf, tx_len); if (error) { dev_err(ts->dev, "failed send read feature cmd, %d", error); return error; @@ -446,9 +447,12 @@ static int goodix_hid_get_raw_report(struct hid_device *hid, if (error) return error; - len = min(len, response_data_len - GOODIX_HID_PKG_LEN_SIZE); + /* Empty reprot response */ + if (!response_data_len) + return 0; + len = min(len, response_data_len); /* Step3: read response data(skip 2bytes of hid pkg length) */ - error = goodix_spi_read(ts, ts->hid_report_addr + + error = goodix_spi_read(ts, GOODIX_HID_CMD_ADDR + GOODIX_HID_ACK_HEADER_SIZE + GOODIX_HID_PKG_LEN_SIZE, buf, len); if (error) { @@ -518,7 +522,7 @@ static int goodix_hid_set_raw_report(struct hid_device *hid, memcpy(tmp_buf + tx_len, buf, len); tx_len += len; - error = goodix_spi_write(ts, ts->hid_report_addr, tmp_buf, tx_len); + error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, tmp_buf, tx_len); if (error) { dev_err(ts->dev, "failed send report: %*ph", tx_len, tmp_buf); return error; @@ -749,7 +753,7 @@ static int goodix_spi_set_power(struct goodix_ts_data *ts, int power_state) power_control_cmd[5] = power_state; guard(mutex)(&ts->hid_request_lock); - error = goodix_spi_write(ts, ts->hid_report_addr, power_control_cmd, + error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, power_control_cmd, sizeof(power_control_cmd)); if (error) { dev_err(ts->dev, "failed set power mode: %s", -- 2.43.0