drivers/input/touchscreen/ad7879.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/ad7879.c
Extension
.c
Size
15336 bytes
Lines
626
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 ad7879 {
	struct regmap		*regmap;
	struct device		*dev;
	struct input_dev	*input;
	struct timer_list	timer;
#ifdef CONFIG_GPIOLIB
	struct gpio_chip	gc;
	struct mutex		mutex;
#endif
	unsigned int		irq;
	bool			disabled;	/* P: input->mutex */
	bool			suspended;	/* P: input->mutex */
	bool			swap_xy;
	u16			conversion_data[AD7879_NR_SENSE];
	char			phys[32];
	u8			first_conversion_delay;
	u8			acquisition_time;
	u8			averaging;
	u8			pen_down_acc_interval;
	u8			median;
	u16			x_plate_ohms;
	u16			cmd_crtl1;
	u16			cmd_crtl2;
	u16			cmd_crtl3;
	int			x;
	int			y;
	int			Rt;
};

static int ad7879_read(struct ad7879 *ts, u8 reg)
{
	unsigned int val;
	int error;

	error = regmap_read(ts->regmap, reg, &val);
	if (error) {
		dev_err(ts->dev, "failed to read register %#02x: %d\n",
			reg, error);
		return error;
	}

	return val;
}

static int ad7879_write(struct ad7879 *ts, u8 reg, u16 val)
{
	int error;

	error = regmap_write(ts->regmap, reg, val);
	if (error) {
		dev_err(ts->dev,
			"failed to write %#04x to register %#02x: %d\n",
			val, reg, error);
		return error;
	}

	return 0;
}

static int ad7879_report(struct ad7879 *ts)
{
	struct input_dev *input_dev = ts->input;
	unsigned Rt;
	u16 x, y, z1, z2;

	x = ts->conversion_data[AD7879_SEQ_XPOS] & MAX_12BIT;
	y = ts->conversion_data[AD7879_SEQ_YPOS] & MAX_12BIT;
	z1 = ts->conversion_data[AD7879_SEQ_Z1] & MAX_12BIT;
	z2 = ts->conversion_data[AD7879_SEQ_Z2] & MAX_12BIT;

	if (ts->swap_xy)
		swap(x, y);

	/*
	 * The samples processed here are already preprocessed by the AD7879.
	 * The preprocessing function consists of a median and an averaging
	 * filter.  The combination of these two techniques provides a robust
	 * solution, discarding the spurious noise in the signal and keeping
	 * only the data of interest.  The size of both filters is
	 * programmable. (dev.platform_data, see linux/platform_data/ad7879.h)
	 * Other user-programmable conversion controls include variable
	 * acquisition time, and first conversion delay. Up to 16 averages can
	 * be taken per conversion.
	 */

	if (likely(x && z1)) {
		/* compute touch pressure resistance using equation #1 */
		Rt = (z2 - z1) * x * ts->x_plate_ohms;
		Rt /= z1;
		Rt = (Rt + 2047) >> 12;

Annotation

Implementation Notes