drivers/input/touchscreen/da9052_tsi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/da9052_tsi.c
Extension
.c
Size
8215 bytes
Lines
341
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 da9052_tsi {
	struct da9052 *da9052;
	struct input_dev *dev;
	struct delayed_work ts_pen_work;
	bool stopped;
	bool adc_on;
};

static void da9052_ts_adc_toggle(struct da9052_tsi *tsi, bool on)
{
	da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 0, on);
	tsi->adc_on = on;
}

static irqreturn_t da9052_ts_pendwn_irq(int irq, void *data)
{
	struct da9052_tsi *tsi = data;

	if (!tsi->stopped) {
		/* Mask PEN_DOWN event and unmask TSI_READY event */
		da9052_disable_irq_nosync(tsi->da9052, DA9052_IRQ_PENDOWN);
		da9052_enable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);

		da9052_ts_adc_toggle(tsi, true);

		schedule_delayed_work(&tsi->ts_pen_work, HZ / 50);
	}

	return IRQ_HANDLED;
}

static void da9052_ts_read(struct da9052_tsi *tsi)
{
	struct input_dev *input = tsi->dev;
	int ret;
	u16 x, y, z;
	u8 v;

	ret = da9052_reg_read(tsi->da9052, DA9052_TSI_X_MSB_REG);
	if (ret < 0)
		return;

	x = (u16) ret;

	ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Y_MSB_REG);
	if (ret < 0)
		return;

	y = (u16) ret;

	ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Z_MSB_REG);
	if (ret < 0)
		return;

	z = (u16) ret;

	ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
	if (ret < 0)
		return;

	v = (u8) ret;

	x = ((x << 2) & 0x3fc) | (v & 0x3);
	y = ((y << 2) & 0x3fc) | ((v & 0xc) >> 2);
	z = ((z << 2) & 0x3fc) | ((v & 0x30) >> 4);

	input_report_key(input, BTN_TOUCH, 1);
	input_report_abs(input, ABS_X, x);
	input_report_abs(input, ABS_Y, y);
	input_report_abs(input, ABS_PRESSURE, z);
	input_sync(input);
}

static irqreturn_t da9052_ts_datardy_irq(int irq, void *data)
{
	struct da9052_tsi *tsi = data;

	da9052_ts_read(tsi);

	return IRQ_HANDLED;
}

static void da9052_ts_pen_work(struct work_struct *work)
{
	struct da9052_tsi *tsi = container_of(work, struct da9052_tsi,
					      ts_pen_work.work);
	if (!tsi->stopped) {
		int ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
		if (ret < 0 || (ret & TSI_PEN_DOWN_STATUS)) {
			/* Pen is still DOWN (or read error) */

Annotation

Implementation Notes