drivers/input/touchscreen/tps6507x-ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/tps6507x-ts.c
Extension
.c
Size
6988 bytes
Lines
293
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 ts_event {
	u16	x;
	u16	y;
	u16	pressure;
};

struct tps6507x_ts {
	struct device		*dev;
	struct input_dev	*input;
	struct tps6507x_dev	*mfd;
	char			phys[32];
	struct ts_event		tc;
	u16			min_pressure;
	bool			pendown;
};

static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data)
{
	return tsc->mfd->read_dev(tsc->mfd, reg, 1, data);
}

static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data)
{
	return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data);
}

static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc,
				   u8 tsc_mode, u16 *value)
{
	s32 ret;
	u8 adc_status;
	u8 result;

	/* Route input signal to A/D converter */

	ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode);
	if (ret) {
		dev_err(tsc->dev, "TSC mode read failed\n");
		goto err;
	}

	/* Start A/D conversion */

	ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
				TPS6507X_ADCONFIG_CONVERT_TS);
	if (ret) {
		dev_err(tsc->dev, "ADC config write failed\n");
		return ret;
	}

	do {
		ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG,
				       &adc_status);
		if (ret) {
			dev_err(tsc->dev, "ADC config read failed\n");
			goto err;
		}
	} while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION);

	ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result);
	if (ret) {
		dev_err(tsc->dev, "ADC result 2 read failed\n");
		goto err;
	}

	*value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8;

	ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result);
	if (ret) {
		dev_err(tsc->dev, "ADC result 1 read failed\n");
		goto err;
	}

	*value |= result;

	dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value);

err:
	return ret;
}

/* Need to call tps6507x_adc_standby() after using A/D converter for the
 * touch screen interrupt to work properly.
 */

static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
{
	s32 ret;
	u8 val;

Annotation

Implementation Notes