drivers/input/touchscreen/eeti_ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/eeti_ts.c
Extension
.c
Size
6911 bytes
Lines
296
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 eeti_ts {
	struct i2c_client *client;
	struct input_dev *input;
	struct gpio_desc *attn_gpio;
	struct touchscreen_properties props;
	struct mutex mutex;
	bool running;
};

#define EETI_TS_BITDEPTH	(11)
#define EETI_MAXVAL		((1 << (EETI_TS_BITDEPTH + 1)) - 1)

#define REPORT_BIT_PRESSED	BIT(0)
#define REPORT_BIT_AD0		BIT(1)
#define REPORT_BIT_AD1		BIT(2)
#define REPORT_BIT_HAS_PRESSURE	BIT(6)
#define REPORT_RES_BITS(v)	(((v) >> 1) + EETI_TS_BITDEPTH)

static void eeti_ts_report_event(struct eeti_ts *eeti, u8 *buf)
{
	unsigned int res;
	u16 x, y;

	res = REPORT_RES_BITS(buf[0] & (REPORT_BIT_AD0 | REPORT_BIT_AD1));

	x = get_unaligned_be16(&buf[1]);
	y = get_unaligned_be16(&buf[3]);

	/* fix the range to 11 bits */
	x >>= res - EETI_TS_BITDEPTH;
	y >>= res - EETI_TS_BITDEPTH;

	if (buf[0] & REPORT_BIT_HAS_PRESSURE)
		input_report_abs(eeti->input, ABS_PRESSURE, buf[5]);

	touchscreen_report_pos(eeti->input, &eeti->props, x, y, false);
	input_report_key(eeti->input, BTN_TOUCH, buf[0] & REPORT_BIT_PRESSED);
	input_sync(eeti->input);
}

static int eeti_ts_read(struct eeti_ts *eeti)
{
	int len, error;
	char buf[6];

	len = i2c_master_recv(eeti->client, buf, sizeof(buf));
	if (len != sizeof(buf)) {
		error = len < 0 ? len : -EIO;
		dev_err(&eeti->client->dev,
			"failed to read touchscreen data: %d\n",
			error);
		return error;
	}

	/* Motion packet */
	if (buf[0] & 0x80)
		eeti_ts_report_event(eeti, buf);

	return 0;
}

static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
{
	struct eeti_ts *eeti = dev_id;
	int error;

	guard(mutex)(&eeti->mutex);

	do {
		/*
		 * If we have attention GPIO, trust it. Otherwise we'll read
		 * once and exit. We assume that in this case we are using
		 * level triggered interrupt and it will get raised again
		 * if/when there is more data.
		 */
		if (eeti->attn_gpio &&
		    !gpiod_get_value_cansleep(eeti->attn_gpio)) {
			break;
		}

		error = eeti_ts_read(eeti);
		if (error)
			break;

	} while (eeti->running && eeti->attn_gpio);

	return IRQ_HANDLED;
}

static void eeti_ts_start(struct eeti_ts *eeti)

Annotation

Implementation Notes