drivers/input/touchscreen/ektf2127.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/ektf2127.c
Extension
.c
Size
9513 bytes
Lines
382
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 ektf2127_ts {
	struct i2c_client *client;
	struct input_dev *input;
	struct gpio_desc *power_gpios;
	struct touchscreen_properties prop;
	int status_shift;
};

struct ektf2127_i2c_chip_data {
	int status_shift;
};

static void ektf2127_parse_coordinates(const u8 *buf, unsigned int touch_count,
				       struct input_mt_pos *touches)
{
	int index = 0;
	int i;

	for (i = 0; i < touch_count; i++) {
		index = 2 + i * 3;

		touches[i].x = (buf[index] & 0x0f);
		touches[i].x <<= 8;
		touches[i].x |= buf[index + 2];

		touches[i].y = (buf[index] & 0xf0);
		touches[i].y <<= 4;
		touches[i].y |= buf[index + 1];
	}
}

static void ektf2127_report_event(struct ektf2127_ts *ts, const u8 *buf)
{
	struct input_mt_pos touches[EKTF2127_MAX_TOUCHES];
	int slots[EKTF2127_MAX_TOUCHES];
	unsigned int touch_count, i;

	touch_count = buf[1] & 0x07;
	if (touch_count > EKTF2127_MAX_TOUCHES) {
		dev_err(&ts->client->dev,
			"Too many touches %d > %d\n",
			touch_count, EKTF2127_MAX_TOUCHES);
		touch_count = EKTF2127_MAX_TOUCHES;
	}

	ektf2127_parse_coordinates(buf, touch_count, touches);
	input_mt_assign_slots(ts->input, slots, touches,
			      touch_count, 0);

	for (i = 0; i < touch_count; i++) {
		input_mt_slot(ts->input, slots[i]);
		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
		touchscreen_report_pos(ts->input, &ts->prop,
				       touches[i].x, touches[i].y, true);
	}

	input_mt_sync_frame(ts->input);
	input_sync(ts->input);
}

static void ektf2127_report2_contact(struct ektf2127_ts *ts, int slot,
				     const u8 *buf, bool active)
{
	input_mt_slot(ts->input, slot);
	input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, active);

	if (active) {
		int x = (buf[0] & 0xf0) << 4 | buf[1];
		int y = (buf[0] & 0x0f) << 8 | buf[2];

		touchscreen_report_pos(ts->input, &ts->prop, x, y, true);
	}
}

static void ektf2127_report2_event(struct ektf2127_ts *ts, const u8 *buf)
{
	ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & BIT(ts->status_shift)));
	ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & BIT(ts->status_shift + 1)));

	input_mt_sync_frame(ts->input);
	input_sync(ts->input);
}

static irqreturn_t ektf2127_irq(int irq, void *dev_id)
{
	struct ektf2127_ts *ts = dev_id;
	struct device *dev = &ts->client->dev;
	char buf[EKTF2127_TOUCH_REPORT_SIZE];
	int ret;

Annotation

Implementation Notes