unsignedlong flags; /* lock for hid raw request operation */ struct mutex hid_request_lock; /* buffer used to store hid report event */
u8 *event_buf;
u32 hid_max_event_sz; /* buffer used to do spi data transfer */
u8 xfer_buf[SZ_2K] ____cacheline_aligned;
};
if (GOODIX_SPI_READ_PREFIX_LEN + len > sizeof(ts->xfer_buf)) {
dev_err(ts->dev, "read data len exceed limit %zu", sizeof(ts->xfer_buf) - GOODIX_SPI_READ_PREFIX_LEN); return -EINVAL;
}
if (GOODIX_SPI_WRITE_PREFIX_LEN + len > sizeof(ts->xfer_buf)) {
dev_err(ts->dev, "write data len exceed limit %zu", sizeof(ts->xfer_buf) - GOODIX_SPI_WRITE_PREFIX_LEN); return -EINVAL;
}
/** * goodix_hid_parse() - hid-core .parse() callback * @hid: hid device instance * * This function gets called during call to hid_add_device * * Return: 0 on success and non zero on error
*/ staticint goodix_hid_parse(struct hid_device *hid)
{ struct goodix_ts_data *ts = hid->driver_data;
u16 rsize; int error;
/* Return date length of response data */ staticint goodix_hid_check_ack_status(struct goodix_ts_data *ts, u32 *resp_len)
{ struct goodix_hid_report_header hdr; int retry = 20; int error; int len;
while (retry--) { /* * 3 bytes of hid request response data * - byte 0: Ack flag, value of 1 for data ready * - bytes 1-2: Response data length
*/
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); if (len < GOODIX_HID_PKG_LEN_SIZE) {
dev_err(ts->dev, "hrd.size too short: %d", len); return -EINVAL;
}
*resp_len = len - GOODIX_HID_PKG_LEN_SIZE; return 0;
}
/* Wait 10ms for another try */
usleep_range(10000, 11000);
}
return -EINVAL;
}
/** * goodix_hid_get_raw_report() - Process hidraw GET REPORT operation * @hid: hid device instance * @reportnum: Report ID * @buf: Buffer for store the report date * @len: Length fo report data * @report_type: Report type * * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl * get report request. The transmitted data follows the standard i2c-hid * protocol with a specified header. * * Return: The length of the data in the buf on success, negative error code
*/ staticint goodix_hid_get_raw_report(struct hid_device *hid, unsignedchar reportnum,
u8 *buf, size_t len, unsignedchar report_type)
{ struct goodix_ts_data *ts = hid->driver_data;
u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE]; int tx_len = 0, args_len = 0;
u32 response_data_len;
u8 args[3]; int error;
if (report_type == HID_OUTPUT_REPORT) return -EINVAL;
if (reportnum == 3) { /* Get win8 signature data */
error = goodix_spi_read(ts, GOODIX_HID_SIGN_ADDR, buf, len); if (error) {
dev_err(ts->dev, "failed get win8 sign: %d", error); return -EINVAL;
} return len;
}
if (reportnum >= 0x0F)
args[args_len++] = reportnum;
if (buf[0] != reportnum) {
dev_err(ts->dev, "incorrect report (%d vs %d expected)",
buf[0], reportnum); return -EINVAL;
} return len;
}
/** * goodix_hid_set_raw_report() - process hidraw SET REPORT operation * @hid: HID device * @reportnum: Report ID * @buf: Buffer for communication * @len: Length of data in the buffer * @report_type: Report type * * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl * set report request. The transmitted data follows the standard i2c-hid * protocol with a specified header. * * Return: The length of the data sent, negative error code on failure
*/ staticint goodix_hid_set_raw_report(struct hid_device *hid, unsignedchar reportnum,
__u8 *buf, size_t len, unsignedchar report_type)
{ struct goodix_ts_data *ts = hid->driver_data;
u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register); int tx_len = 0, args_len = 0;
u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
u8 args[5]; int error;
if (!test_bit(GOODIX_HID_STARTED, &ts->flags)) return IRQ_HANDLED; /* * First, read buffer with space for header and coordinate package: * - event header = 3 bytes * - coordinate event = GOODIX_HID_COOR_PKG_LEN bytes * * If the data size info in the event header exceeds * GOODIX_HID_COOR_PKG_LEN, it means that there are other packages * besides the coordinate package.
*/
event = goodix_get_event_report(ts, ts->hid_report_addr, ts->event_buf,
GOODIX_HID_ACK_HEADER_SIZE +
GOODIX_HID_COOR_PKG_LEN); if (!event) {
dev_err(ts->dev, "failed get coordinate data"); return IRQ_HANDLED;
}
/* Check coordinate data valid falg */ if (event->hdr.flag != GOODIX_HID_REPORT_READY_FLAG) return IRQ_HANDLED;
MODULE_DESCRIPTION("Goodix SPI driver for HID touchscreen");
MODULE_AUTHOR("Goodix, Inc.");
MODULE_LICENSE("GPL");
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.