drivers/input/touchscreen/msg2638.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/msg2638.c
Extension
.c
Size
12683 bytes
Lines
506
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 msg_chip_data {
	irq_handler_t irq_handler;
	unsigned int max_fingers;
};

struct msg2138_packet {
	u8	xy_hi; /* higher bits of x and y coordinates */
	u8	x_low;
	u8	y_low;
};

struct msg2138_touch_event {
	u8	magic;
	struct	msg2138_packet pkt[MSG2138_MAX_FINGERS];
	u8	checksum;
};

struct msg2638_packet {
	u8	xy_hi; /* higher bits of x and y coordinates */
	u8	x_low;
	u8	y_low;
	u8	pressure;
};

struct msg2638_touch_event {
	u8	mode;
	struct	msg2638_packet pkt[MSG2638_MAX_FINGERS];
	u8	proximity;
	u8	checksum;
};

struct msg2638_ts_data {
	struct i2c_client *client;
	struct input_dev *input_dev;
	struct touchscreen_properties prop;
	struct regulator_bulk_data supplies[2];
	struct gpio_desc *reset_gpiod;
	int max_fingers;
	u32 keycodes[MAX_BUTTONS];
	int num_keycodes;
};

static u8 msg2638_checksum(u8 *data, u32 length)
{
	s32 sum = 0;
	u32 i;

	for (i = 0; i < length; i++)
		sum += data[i];

	return (u8)((-sum) & 0xFF);
}

static void msg2138_report_keys(struct msg2638_ts_data *msg2638, u8 keys)
{
	int i;

	/* keys can be 0x00 or 0xff when all keys have been released */
	if (keys == 0xff)
		keys = 0;

	for (i = 0; i < msg2638->num_keycodes; ++i)
		input_report_key(msg2638->input_dev, msg2638->keycodes[i],
				 keys & BIT(i));
}

static irqreturn_t msg2138_ts_irq_handler(int irq, void *msg2638_handler)
{
	struct msg2638_ts_data *msg2638 = msg2638_handler;
	struct i2c_client *client = msg2638->client;
	struct input_dev *input = msg2638->input_dev;
	struct msg2138_touch_event touch_event;
	u32 len = sizeof(touch_event);
	struct i2c_msg msg[] = {
		{
			.addr	= client->addr,
			.flags	= I2C_M_RD,
			.len	= sizeof(touch_event),
			.buf	= (u8 *)&touch_event,
		},
	};
	struct msg2138_packet *p0, *p1;
	u16 x, y, delta_x, delta_y;
	int ret;

	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
	if (ret != ARRAY_SIZE(msg)) {
		dev_err(&client->dev,
			"Failed I2C transfer in irq handler: %d\n",
			ret < 0 ? ret : -EIO);

Annotation

Implementation Notes