drivers/input/touchscreen/auo-pixcir-ts.c

Source file repositories/reference/linux-study-clean/drivers/input/touchscreen/auo-pixcir-ts.c

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/auo-pixcir-ts.c
Extension
.c
Size
16285 bytes
Lines
649
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 auo_pixcir_ts {
	struct i2c_client	*client;
	struct input_dev	*input;
	struct gpio_desc	*gpio_int;
	struct gpio_desc	*gpio_rst;
	char			phys[32];

	unsigned int		x_max;
	unsigned int		y_max;

	/* special handling for touch_indicate interrupt mode */
	bool			touch_ind_mode;

	wait_queue_head_t	wait;
	bool			stopped;
};

struct auo_point_t {
	int	coord_x;
	int	coord_y;
	int	area_major;
	int	area_minor;
	int	orientation;
};

static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts,
				   struct auo_point_t *point)
{
	struct i2c_client *client = ts->client;
	uint8_t raw_coord[8];
	uint8_t raw_area[4];
	int i, ret;

	/* touch coordinates */
	ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_X1_LSB,
					    8, raw_coord);
	if (ret < 0) {
		dev_err(&client->dev, "failed to read coordinate, %d\n", ret);
		return ret;
	}

	/* touch area */
	ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_TOUCHAREA_X1,
					    4, raw_area);
	if (ret < 0) {
		dev_err(&client->dev, "could not read touch area, %d\n", ret);
		return ret;
	}

	for (i = 0; i < AUO_PIXCIR_REPORT_POINTS; i++) {
		point[i].coord_x =
			raw_coord[4 * i + 1] << 8 | raw_coord[4 * i];
		point[i].coord_y =
			raw_coord[4 * i + 3] << 8 | raw_coord[4 * i + 2];

		if (point[i].coord_x > ts->x_max ||
		    point[i].coord_y > ts->y_max) {
			dev_warn(&client->dev, "coordinates (%d,%d) invalid\n",
				point[i].coord_x, point[i].coord_y);
			point[i].coord_x = point[i].coord_y = 0;
		}

		/* determine touch major, minor and orientation */
		point[i].area_major = max(raw_area[2 * i], raw_area[2 * i + 1]);
		point[i].area_minor = min(raw_area[2 * i], raw_area[2 * i + 1]);
		point[i].orientation = raw_area[2 * i] > raw_area[2 * i + 1];
	}

	return 0;
}

static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id)
{
	struct auo_pixcir_ts *ts = dev_id;
	struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS];
	int i;
	int ret;
	int fingers = 0;
	int abs = -1;

	while (!ts->stopped) {

		/* check for up event in touch touch_ind_mode */
		if (ts->touch_ind_mode) {
			if (gpiod_get_value_cansleep(ts->gpio_int) == 0) {
				input_mt_sync(ts->input);
				input_report_key(ts->input, BTN_TOUCH, 0);
				input_sync(ts->input);
				break;
			}

Annotation

Implementation Notes