drivers/input/touchscreen/mxs-lradc-ts.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/touchscreen/mxs-lradc-ts.c
Extension
.c
Size
19479 bytes
Lines
703
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 mxs_lradc_ts {
	struct mxs_lradc	*lradc;
	struct device		*dev;

	void __iomem		*base;
	/*
	 * When the touchscreen is enabled, we give it two private virtual
	 * channels: #6 and #7. This means that only 6 virtual channels (instead
	 * of 8) will be available for buffered capture.
	 */
#define TOUCHSCREEN_VCHANNEL1		7
#define TOUCHSCREEN_VCHANNEL2		6

	struct input_dev	*ts_input;

	enum mxs_lradc_ts_plate	cur_plate; /* state machine */
	bool			ts_valid;
	unsigned int		ts_x_pos;
	unsigned int		ts_y_pos;
	unsigned int		ts_pressure;

	/* handle touchscreen's physical behaviour */
	/* samples per coordinate */
	unsigned int		over_sample_cnt;
	/* time clocks between samples */
	unsigned int		over_sample_delay;
	/* time in clocks to wait after the plates where switched */
	unsigned int		settling_delay;
	spinlock_t		lock;
};

struct state_info {
	u32		mask;
	u32		bit;
	u32		x_plate;
	u32		y_plate;
	u32		pressure;
};

static struct state_info info[] = {
	{LRADC_CTRL0_MX23_PLATE_MASK, LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE,
	 LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM,
	 LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM,
	 LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM},
	{LRADC_CTRL0_MX28_PLATE_MASK, LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE,
	 LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW,
	 LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW,
	 LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW}
};

static bool mxs_lradc_check_touch_event(struct mxs_lradc_ts *ts)
{
	return !!(readl(ts->base + LRADC_STATUS) &
					LRADC_STATUS_TOUCH_DETECT_RAW);
}

static void mxs_lradc_map_ts_channel(struct mxs_lradc_ts *ts, unsigned int vch,
				     unsigned int ch)
{
	writel(LRADC_CTRL4_LRADCSELECT_MASK(vch),
	       ts->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
	writel(LRADC_CTRL4_LRADCSELECT(vch, ch),
	       ts->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
}

static void mxs_lradc_setup_ts_channel(struct mxs_lradc_ts *ts, unsigned int ch)
{
	/*
	 * prepare for oversampling conversion
	 *
	 * from the datasheet:
	 * "The ACCUMULATE bit in the appropriate channel register
	 * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
	 * otherwise, the IRQs will not fire."
	 */
	writel(LRADC_CH_ACCUMULATE |
	       LRADC_CH_NUM_SAMPLES(ts->over_sample_cnt - 1),
	       ts->base + LRADC_CH(ch));

	/* from the datasheet:
	 * "Software must clear this register in preparation for a
	 * multi-cycle accumulation.
	 */
	writel(LRADC_CH_VALUE_MASK,
	       ts->base + LRADC_CH(ch) + STMP_OFFSET_REG_CLR);

	/*
	 * prepare the delay/loop unit according to the oversampling count
	 *
	 * from the datasheet:

Annotation

Implementation Notes