drivers/input/touchscreen/hynitron_cstxxx.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/hynitron_cstxxx.c
Extension
.c
Size
12861 bytes
Lines
499
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 hynitron_ts_chip_data {
	unsigned int max_touch_num;
	u32 ic_chkcode;
	int (*firmware_info)(struct i2c_client *client);
	int (*bootloader_enter)(struct i2c_client *client);
	int (*init_input)(struct i2c_client *client);
	void (*report_touch)(struct i2c_client *client);
};

/* Data generic to all (supported and non-supported) controllers. */
struct hynitron_ts_data {
	const struct hynitron_ts_chip_data *chip;
	struct i2c_client *client;
	struct input_dev *input_dev;
	struct touchscreen_properties prop;
	struct gpio_desc *reset_gpio;
};

/*
 * Since I have no datasheet, these values are guessed and/or assumed
 * based on observation and testing.
 */
#define CST3XX_FIRMWARE_INFO_START_CMD		0x01d1
#define CST3XX_FIRMWARE_INFO_END_CMD		0x09d1
#define CST3XX_FIRMWARE_CHK_CODE_REG		0xfcd1
#define CST3XX_FIRMWARE_VERSION_REG		0x08d2
#define CST3XX_FIRMWARE_VER_INVALID_VAL		0xa5a5a5a5

#define CST3XX_BOOTLDR_PROG_CMD			0xaa01a0
#define CST3XX_BOOTLDR_PROG_CHK_REG		0x02a0
#define CST3XX_BOOTLDR_CHK_VAL			0xac

#define CST3XX_TOUCH_DATA_PART_REG		0x00d0
#define CST3XX_TOUCH_DATA_FULL_REG		0x07d0
#define CST3XX_TOUCH_DATA_CHK_VAL		0xab
#define CST3XX_TOUCH_DATA_TOUCH_VAL		0x03
#define CST3XX_TOUCH_DATA_STOP_CMD		0xab00d0
#define CST3XX_TOUCH_COUNT_MASK			GENMASK(6, 0)


/*
 * Hard coded reset delay value of 20ms not IC dependent in
 * vendor driver.
 */
static void hyn_reset_proc(struct i2c_client *client, int delay)
{
	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);

	gpiod_set_value_cansleep(ts_data->reset_gpio, 1);
	msleep(20);
	gpiod_set_value_cansleep(ts_data->reset_gpio, 0);
	if (delay)
		fsleep(delay * 1000);
}

static irqreturn_t hyn_interrupt_handler(int irq, void *dev_id)
{
	struct i2c_client *client = dev_id;
	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);

	ts_data->chip->report_touch(client);

	return IRQ_HANDLED;
}

/*
 * The vendor driver would retry twice before failing to read or write
 * to the i2c device.
 */

static int cst3xx_i2c_write(struct i2c_client *client,
			    unsigned char *buf, int len)
{
	int ret;
	int retries = 0;

	while (retries < 2) {
		ret = i2c_master_send(client, buf, len);
		if (ret == len)
			return 0;
		if (ret <= 0)
			retries++;
		else
			break;
	}

	return ret < 0 ? ret : -EIO;
}

static int cst3xx_i2c_read_register(struct i2c_client *client, u16 reg,

Annotation

Implementation Notes