drivers/hid/hid-goodix-spi.c

Source file repositories/reference/linux-study-clean/drivers/hid/hid-goodix-spi.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-goodix-spi.c
Extension
.c
Size
21679 bytes
Lines
822
Domain
Driver Families
Bucket
drivers/hid
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct goodix_hid_report_header {
	u8 flag;
	__le16 size;
} __packed;
#define GOODIX_HID_ACK_HEADER_SIZE	sizeof(struct goodix_hid_report_header)

struct goodix_hid_report_package {
	__le16 size;
	u8 data[];
};

#define GOODIX_HID_PKG_LEN_SIZE		sizeof(u16)
#define GOODIX_HID_COOR_DATA_LEN	82
#define GOODIX_HID_COOR_PKG_LEN		(GOODIX_HID_PKG_LEN_SIZE + \
					 GOODIX_HID_COOR_DATA_LEN)

/* power state */
#define GOODIX_SPI_POWER_ON		0x00
#define GOODIX_SPI_POWER_SLEEP		0x01

/* flags used to record the current device operating state */
#define GOODIX_HID_STARTED		0

struct goodix_hid_report_event {
	struct goodix_hid_report_header hdr;
	u8 data[GOODIX_HID_COOR_PKG_LEN];
} __packed;

struct goodix_hid_desc {
	__le16 desc_length;
	__le16 bcd_version;
	__le16 report_desc_length;
	__le16 report_desc_register;
	__le16 input_register;
	__le16 max_input_length;
	__le16 output_register;
	__le16 max_output_length;
	__le16 cmd_register;
	__le16 data_register;
	__le16 vendor_id;
	__le16 product_id;
	__le16 version_id;
	__le32 reserved;
} __packed;

struct goodix_ts_data {
	struct device *dev;
	struct spi_device *spi;
	struct hid_device *hid;
	struct goodix_hid_desc hid_desc;

	struct gpio_desc *reset_gpio;
	u32 hid_report_addr;

	unsigned long 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;
};

static void *goodix_get_event_report(struct goodix_ts_data *ts, u32 addr,
				     u8 *data, size_t len)
{
	struct spi_device *spi = to_spi_device(&ts->spi->dev);
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	int error;

	/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
	data[0] = GOODIX_SPI_READ_FLAG;
	put_unaligned_be32(addr, data + GOODIX_SPI_TRANS_PREFIX_LEN);

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));
	xfers.tx_buf = data;
	xfers.rx_buf = data;
	xfers.len = GOODIX_SPI_READ_PREFIX_LEN + len;
	spi_message_add_tail(&xfers, &spi_msg);

	error = spi_sync(spi, &spi_msg);
	if (error) {
		dev_err(ts->dev, "spi transfer error: %d", error);
		return NULL;
	}

	return data + GOODIX_SPI_READ_PREFIX_LEN;

Annotation

Implementation Notes