drivers/input/touchscreen/colibri-vf50-ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/colibri-vf50-ts.c
Extension
.c
Size
9410 bytes
Lines
375
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 vf50_touch_device {
	struct platform_device *pdev;
	struct input_dev *ts_input;
	struct iio_channel *channels;
	struct gpio_desc *gpio_xp;
	struct gpio_desc *gpio_xm;
	struct gpio_desc *gpio_yp;
	struct gpio_desc *gpio_ym;
	int pen_irq;
	int min_pressure;
	bool stop_touchscreen;
};

/*
 * Enables given plates and measures touch parameters using ADC
 */
static int adc_ts_measure(struct iio_channel *channel,
			  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
{
	int i, value = 0, val = 0;
	int error;

	gpiod_set_value(plate_p, 1);
	gpiod_set_value(plate_m, 1);

	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);

	for (i = 0; i < COLI_TOUCH_NO_OF_AVGS; i++) {
		error = iio_read_channel_raw(channel, &val);
		if (error < 0) {
			value = error;
			goto error_iio_read;
		}

		value += val;
	}

	value /= COLI_TOUCH_NO_OF_AVGS;

error_iio_read:
	gpiod_set_value(plate_p, 0);
	gpiod_set_value(plate_m, 0);

	return value;
}

/*
 * Enable touch detection using falling edge detection on XM
 */
static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
{
	/* Enable plate YM (needs to be strong GND, high active) */
	gpiod_set_value(vf50_ts->gpio_ym, 1);

	/*
	 * Let the platform mux to idle state in order to enable
	 * Pull-Up on GPIO
	 */
	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);

	/* Wait for the pull-up to be stable on high */
	usleep_range(COLI_PULLUP_MIN_DELAY_US, COLI_PULLUP_MAX_DELAY_US);
}

/*
 * ADC touch screen sampling bottom half irq handler
 */
static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
{
	struct vf50_touch_device *vf50_ts = private;
	struct device *dev = &vf50_ts->pdev->dev;
	int val_x, val_y, val_z1, val_z2, val_p = 0;
	bool discard_val_on_start = true;

	/* Disable the touch detection plates */
	gpiod_set_value(vf50_ts->gpio_ym, 0);

	/* Let the platform mux to default state in order to mux as ADC */
	pinctrl_pm_select_default_state(dev);

	while (!vf50_ts->stop_touchscreen) {
		/* X-Direction */
		val_x = adc_ts_measure(&vf50_ts->channels[0],
				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
		if (val_x < 0)
			break;

		/* Y-Direction */
		val_y = adc_ts_measure(&vf50_ts->channels[1],
				vf50_ts->gpio_yp, vf50_ts->gpio_ym);

Annotation

Implementation Notes