drivers/input/touchscreen/hycon-hy46xx.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/hycon-hy46xx.c
Extension
.c
Size
15066 bytes
Lines
576
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 hycon_hy46xx_data {
	struct i2c_client *client;
	struct input_dev *input;
	struct touchscreen_properties prop;
	struct regulator *vcc;

	struct gpio_desc *reset_gpio;

	struct mutex mutex;
	struct regmap *regmap;

	int threshold;
	bool glove_enable;
	int report_speed;
	bool noise_filter_enable;
	int filter_data;
	int gain;
	int edge_offset;
	int rx_number_used;
	int tx_number_used;
	int power_mode;
	int fw_version;
	int lib_version;
	int tp_information;
	int tp_chip_id;
	int bootloader_version;
};

static const struct regmap_config hycon_hy46xx_i2c_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
};

static bool hycon_hy46xx_check_checksum(struct hycon_hy46xx_data *tsdata, u8 *buf)
{
	u8 chksum = 0;
	int i;

	for (i = 2; i < buf[HY46XX_CHKSUM_LEN]; i++)
		chksum += buf[i];

	if (chksum == buf[HY46XX_CHKSUM_CODE])
		return true;

	dev_err_ratelimited(&tsdata->client->dev,
			    "checksum error: 0x%02x expected, got 0x%02x\n",
			    chksum, buf[HY46XX_CHKSUM_CODE]);

	return false;
}

static irqreturn_t hycon_hy46xx_isr(int irq, void *dev_id)
{
	struct hycon_hy46xx_data *tsdata = dev_id;
	struct device *dev = &tsdata->client->dev;
	u8 rdbuf[HY46XX_REPORT_PKT_LEN];
	int i, x, y, id;
	int error;

	memset(rdbuf, 0, sizeof(rdbuf));

	error = regmap_bulk_read(tsdata->regmap, 0, rdbuf, sizeof(rdbuf));
	if (error) {
		dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
				    error);
		goto out;
	}

	if (!hycon_hy46xx_check_checksum(tsdata, rdbuf))
		goto out;

	for (i = 0; i < HY46XX_MAX_SUPPORTED_POINTS; i++) {
		u8 *buf = &rdbuf[3 + (HY46XX_TPLEN * i)];
		int type = buf[0] >> 6;

		if (type == TOUCH_EVENT_RESERVED)
			continue;

		x = get_unaligned_be16(buf) & 0x0fff;
		y = get_unaligned_be16(buf + 2) & 0x0fff;

		id = buf[2] >> 4;

		input_mt_slot(tsdata->input, id);
		if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
					       type != TOUCH_EVENT_UP))
			touchscreen_report_pos(tsdata->input, &tsdata->prop,
					       x, y, true);
	}

Annotation

Implementation Notes