drivers/input/touchscreen/zet6223.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/zet6223.c
Extension
.c
Size
5792 bytes
Lines
257
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 zet6223_ts {
	struct i2c_client *client;
	struct input_dev *input;
	struct touchscreen_properties prop;
	struct regulator_bulk_data supplies[2];
	u16 max_x;
	u16 max_y;
	u8 fingernum;
};

static int zet6223_start(struct input_dev *dev)
{
	struct zet6223_ts *ts = input_get_drvdata(dev);

	enable_irq(ts->client->irq);

	return 0;
}

static void zet6223_stop(struct input_dev *dev)
{
	struct zet6223_ts *ts = input_get_drvdata(dev);

	disable_irq(ts->client->irq);
}

static irqreturn_t zet6223_irq(int irq, void *dev_id)
{
	struct zet6223_ts *ts = dev_id;
	u16 finger_bits;

	/*
	 * First 3 bytes are an identifier, two bytes of finger data.
	 * X, Y data per finger is 4 bytes.
	 */
	u8 bufsize = 3 + 4 * ts->fingernum;
	u8 buf[ZET6223_MAX_PKT_SIZE];
	int i;
	int ret;
	int error;

	ret = i2c_master_recv(ts->client, buf, bufsize);
	if (ret != bufsize) {
		error = ret < 0 ? ret : -EIO;
		dev_err_ratelimited(&ts->client->dev,
				    "Error reading input data: %d\n", error);
		return IRQ_HANDLED;
	}

	if (buf[0] != ZET6223_VALID_PACKET)
		return IRQ_HANDLED;

	finger_bits = get_unaligned_be16(buf + 1);
	for (i = 0; i < ts->fingernum; i++) {
		if (!(finger_bits & BIT(15 - i)))
			continue;

		input_mt_slot(ts->input, i);
		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
		input_event(ts->input, EV_ABS, ABS_MT_POSITION_X,
				((buf[i + 3] >> 4) << 8) + buf[i + 4]);
		input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y,
				((buf[i + 3] & 0xF) << 8) + buf[i + 5]);
	}

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

	return IRQ_HANDLED;
}

static void zet6223_power_off(void *_ts)
{
	struct zet6223_ts *ts = _ts;

	regulator_bulk_disable(ARRAY_SIZE(ts->supplies), ts->supplies);
}

static int zet6223_power_on(struct zet6223_ts *ts)
{
	struct device *dev = &ts->client->dev;
	int error;

	ts->supplies[0].supply = "vio";
	ts->supplies[1].supply = "vcc";

	error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->supplies),
					ts->supplies);
	if (error)
		return error;

Annotation

Implementation Notes