drivers/input/touchscreen/ilitek_ts_i2c.c

Source file repositories/reference/linux-study-clean/drivers/input/touchscreen/ilitek_ts_i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/ilitek_ts_i2c.c
Extension
.c
Size
15554 bytes
Lines
687
Domain
Driver Families
Bucket
drivers/input
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 ilitek_protocol_info {
	u16 ver;
	u8 ver_major;
};

struct ilitek_ts_data {
	struct i2c_client		*client;
	struct gpio_desc		*reset_gpio;
	struct input_dev		*input_dev;
	struct touchscreen_properties	prop;

	const struct ilitek_protocol_map *ptl_cb_func;
	struct ilitek_protocol_info	ptl;

	char				product_id[30];
	u16				mcu_ver;
	u8				ic_mode;
	u8				firmware_ver[8];

	s32				reset_time;
	s32				screen_max_x;
	s32				screen_max_y;
	s32				screen_min_x;
	s32				screen_min_y;
	s32				max_tp;
};

struct ilitek_protocol_map {
	u16 cmd;
	const char *name;
	int (*func)(struct ilitek_ts_data *ts, u16 cmd, u8 *inbuf, u8 *outbuf);
};

enum ilitek_cmds {
	/* common cmds */
	GET_PTL_VER = 0,
	GET_FW_VER,
	GET_SCRN_RES,
	GET_TP_RES,
	GET_IC_MODE,
	GET_MCU_VER,
	SET_IC_SLEEP,
	SET_IC_WAKE,

	/* ALWAYS keep at the end */
	MAX_CMD_CNT
};

/* ILITEK I2C R/W APIs */
static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
				     u8 *cmd, int write_len, int delay,
				     u8 *data, int read_len)
{
	int error;
	struct i2c_client *client = ts->client;
	struct i2c_msg msgs[] = {
		{
			.addr = client->addr,
			.flags = 0,
			.len = write_len,
			.buf = cmd,
		},
		{
			.addr = client->addr,
			.flags = I2C_M_RD,
			.len = read_len,
			.buf = data,
		},
	};

	if (delay == 0 && write_len > 0 && read_len > 0) {
		error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
		if (error < 0)
			return error;
	} else {
		if (write_len > 0) {
			error = i2c_transfer(client->adapter, msgs, 1);
			if (error < 0)
				return error;
		}
		if (delay > 0)
			fsleep(delay * 1000);

		if (read_len > 0) {
			error = i2c_transfer(client->adapter, msgs + 1, 1);
			if (error < 0)
				return error;
		}
	}

Annotation

Implementation Notes