drivers/input/touchscreen/ts4800-ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/ts4800-ts.c
Extension
.c
Size
5161 bytes
Lines
223
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 ts4800_ts {
	struct input_dev        *input;
	struct device           *dev;
	char                    phys[32];

	void __iomem            *base;
	struct regmap           *regmap;
	unsigned int            reg;
	unsigned int            bit;

	bool                    pendown;
	int                     debounce;
};

static int ts4800_ts_open(struct input_dev *input_dev)
{
	struct ts4800_ts *ts = input_get_drvdata(input_dev);
	int error;

	ts->pendown = false;
	ts->debounce = DEBOUNCE_COUNT;

	error = regmap_update_bits(ts->regmap, ts->reg, ts->bit, ts->bit);
	if (error) {
		dev_warn(ts->dev, "Failed to enable touchscreen: %d\n", error);
		return error;
	}

	return 0;
}

static void ts4800_ts_close(struct input_dev *input_dev)
{
	struct ts4800_ts *ts = input_get_drvdata(input_dev);
	int ret;

	ret = regmap_update_bits(ts->regmap, ts->reg, ts->bit, 0);
	if (ret)
		dev_warn(ts->dev, "Failed to disable touchscreen\n");

}

static void ts4800_ts_poll(struct input_dev *input_dev)
{
	struct ts4800_ts *ts = input_get_drvdata(input_dev);
	u16 last_x = readw(ts->base + X_OFFSET);
	u16 last_y = readw(ts->base + Y_OFFSET);
	bool pendown = last_x & PENDOWN_MASK;

	if (pendown) {
		if (ts->debounce) {
			ts->debounce--;
			return;
		}

		if (!ts->pendown) {
			input_report_key(input_dev, BTN_TOUCH, 1);
			ts->pendown = true;
		}

		last_x = ((~last_x) >> 4) & MAX_12BIT;
		last_y = ((~last_y) >> 4) & MAX_12BIT;

		input_report_abs(input_dev, ABS_X, last_x);
		input_report_abs(input_dev, ABS_Y, last_y);
		input_sync(input_dev);
	} else if (ts->pendown) {
		ts->pendown = false;
		ts->debounce = DEBOUNCE_COUNT;
		input_report_key(input_dev, BTN_TOUCH, 0);
		input_sync(input_dev);
	}
}

static int ts4800_parse_dt(struct platform_device *pdev,
			   struct ts4800_ts *ts)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	u32 reg, bit;
	int error;

	struct device_node *syscon_np __free(device_node) =
		of_parse_phandle(np, "syscon", 0);
	if (!syscon_np) {
		dev_err(dev, "no syscon property\n");
		return -ENODEV;
	}

	ts->regmap = syscon_node_to_regmap(syscon_np);

Annotation

Implementation Notes