drivers/input/touchscreen/pixcir_i2c_ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/pixcir_i2c_ts.c
Extension
.c
Size
14810 bytes
Lines
613
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 pixcir_i2c_chip_data {
	u8 max_fingers;
	bool has_hw_ids;
};

struct pixcir_i2c_ts_data {
	struct i2c_client *client;
	struct input_dev *input;
	struct gpio_desc *gpio_attb;
	struct gpio_desc *gpio_reset;
	struct gpio_desc *gpio_enable;
	struct gpio_desc *gpio_wake;
	const struct pixcir_i2c_chip_data *chip;
	struct touchscreen_properties prop;
	bool running;
};

struct pixcir_report_data {
	int num_touches;
	struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
	int ids[PIXCIR_MAX_SLOTS];
};

static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
			    struct pixcir_report_data *report)
{
	u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5];
	u8 wrbuf[1] = { 0 };
	u8 *bufptr;
	u8 touch;
	int ret, i;
	int readsize;
	const struct pixcir_i2c_chip_data *chip = tsdata->chip;

	memset(report, 0, sizeof(struct pixcir_report_data));

	i = chip->has_hw_ids ? 1 : 0;
	readsize = 2 + tsdata->chip->max_fingers * (4 + i);
	if (readsize > sizeof(rdbuf))
		readsize = sizeof(rdbuf);

	ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
	if (ret != sizeof(wrbuf)) {
		dev_err(&tsdata->client->dev,
			"%s: i2c_master_send failed(), ret=%d\n",
			__func__, ret);
		return;
	}

	ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
	if (ret != readsize) {
		dev_err(&tsdata->client->dev,
			"%s: i2c_master_recv failed(), ret=%d\n",
			__func__, ret);
		return;
	}

	touch = rdbuf[0] & 0x7;
	if (touch > tsdata->chip->max_fingers)
		touch = tsdata->chip->max_fingers;

	report->num_touches = touch;
	bufptr = &rdbuf[2];

	for (i = 0; i < touch; i++) {
		touchscreen_set_mt_pos(&report->pos[i], &tsdata->prop,
				       get_unaligned_le16(bufptr),
				       get_unaligned_le16(bufptr + 2));
		if (chip->has_hw_ids) {
			report->ids[i] = bufptr[4];
			bufptr = bufptr + 5;
		} else {
			bufptr = bufptr + 4;
		}
	}
}

static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
			     struct pixcir_report_data *report)
{
	int slots[PIXCIR_MAX_SLOTS];
	int n, i, slot;
	struct device *dev = &ts->client->dev;
	const struct pixcir_i2c_chip_data *chip = ts->chip;

	n = report->num_touches;
	if (n > PIXCIR_MAX_SLOTS)
		n = PIXCIR_MAX_SLOTS;

	if (!ts->chip->has_hw_ids)

Annotation

Implementation Notes