drivers/input/touchscreen/raydium_i2c_ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/raydium_i2c_ts.c
Extension
.c
Size
30213 bytes
Lines
1260
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 raydium_data_info {
	__le32 data_bank_addr;
	u8 pkg_size;
	u8 tp_info_size;
};

struct raydium_info {
	__le32 hw_ver;		/*device version */
	u8 main_ver;
	u8 sub_ver;
	__le16 ft_ver;		/* test version */
	u8 x_num;
	u8 y_num;
	__le16 x_max;
	__le16 y_max;
	u8 x_res;		/* units/mm */
	u8 y_res;		/* units/mm */
};

/* struct raydium_data - represents state of Raydium touchscreen device */
struct raydium_data {
	struct i2c_client *client;
	struct input_dev *input;

	struct regulator *avdd;
	struct regulator *vccio;
	struct gpio_desc *reset_gpio;

	struct raydium_info info;

	struct mutex sysfs_mutex;

	u8 *report_data;

	u32 data_bank_addr;
	u8 report_size;
	u8 contact_size;
	u8 pkg_size;

	enum raydium_boot_mode boot_mode;
};

/*
 * Header to be sent for RM_CMD_BANK_SWITCH command. This is used by
 * raydium_i2c_{read|send} below.
 */
struct __packed raydium_bank_switch_header {
	u8 cmd;
	__be32 be_addr;
};

static int raydium_i2c_xfer(struct i2c_client *client, u32 addr,
			    struct i2c_msg *xfer, size_t xfer_count)
{
	int ret;
	/*
	 * If address is greater than 255, then RM_CMD_BANK_SWITCH needs to be
	 * sent first. Else, skip the header i.e. xfer[0].
	 */
	int xfer_start_idx = (addr > 0xff) ? 0 : 1;
	xfer_count -= xfer_start_idx;

	ret = i2c_transfer(client->adapter, &xfer[xfer_start_idx], xfer_count);
	if (likely(ret == xfer_count))
		return 0;

	return ret < 0 ? ret : -EIO;
}

static int raydium_i2c_send(struct i2c_client *client,
			    u32 addr, const void *data, size_t len)
{
	int tries = 0;
	int error;
	u8 reg_addr = addr & 0xff;

	u8 *tx_buf __free(kfree) = kmalloc(len + 1, GFP_KERNEL);
	if (!tx_buf)
		return -ENOMEM;

	tx_buf[0] = reg_addr;
	memcpy(tx_buf + 1, data, len);

	do {
		struct raydium_bank_switch_header header = {
			.cmd = RM_CMD_BANK_SWITCH,
			.be_addr = cpu_to_be32(addr),
		};

		/*

Annotation

Implementation Notes