Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
  3 *
  4 * This program is free software; you can redistribute it and/or modify it under
  5 * the terms of the GNU General Public License version 2 as published by the
  6 * Free Software Foundation.
  7 *
  8 * Based on driver from 2011:
  9 *   Juergen Beisert, Pengutronix <kernel@pengutronix.de>
 10 *
 11 * This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
 12 * connected to the imx25 ADC.
 13 */
 14
 15#include <linux/clk.h>
 16#include <linux/device.h>
 17#include <linux/input.h>
 18#include <linux/interrupt.h>
 19#include <linux/mfd/imx25-tsadc.h>
 20#include <linux/module.h>
 21#include <linux/of.h>
 22#include <linux/platform_device.h>
 23#include <linux/regmap.h>
 24
 25static const char mx25_tcq_name[] = "mx25-tcq";
 26
 27enum mx25_tcq_mode {
 28	MX25_TS_4WIRE,
 29};
 30
 31struct mx25_tcq_priv {
 32	struct regmap *regs;
 33	struct regmap *core_regs;
 34	struct input_dev *idev;
 35	enum mx25_tcq_mode mode;
 36	unsigned int pen_threshold;
 37	unsigned int sample_count;
 38	unsigned int expected_samples;
 39	unsigned int pen_debounce;
 40	unsigned int settling_time;
 41	struct clk *clk;
 42	int irq;
 43	struct device *dev;
 44};
 45
 46static struct regmap_config mx25_tcq_regconfig = {
 47	.fast_io = true,
 48	.max_register = 0x5c,
 49	.reg_bits = 32,
 50	.val_bits = 32,
 51	.reg_stride = 4,
 52};
 53
 54static const struct of_device_id mx25_tcq_ids[] = {
 55	{ .compatible = "fsl,imx25-tcq", },
 56	{ /* Sentinel */ }
 57};
 
 58
 59#define TSC_4WIRE_PRE_INDEX 0
 60#define TSC_4WIRE_X_INDEX 1
 61#define TSC_4WIRE_Y_INDEX 2
 62#define TSC_4WIRE_POST_INDEX 3
 63#define TSC_4WIRE_LEAVE 4
 64
 65#define MX25_TSC_DEF_THRESHOLD 80
 66#define TSC_MAX_SAMPLES 16
 67
 68#define MX25_TSC_REPEAT_WAIT 14
 69
 70enum mx25_adc_configurations {
 71	MX25_CFG_PRECHARGE = 0,
 72	MX25_CFG_TOUCH_DETECT,
 73	MX25_CFG_X_MEASUREMENT,
 74	MX25_CFG_Y_MEASUREMENT,
 75};
 76
 77#define MX25_PRECHARGE_VALUE (\
 78			MX25_ADCQ_CFG_YPLL_OFF | \
 79			MX25_ADCQ_CFG_XNUR_OFF | \
 80			MX25_ADCQ_CFG_XPUL_HIGH | \
 81			MX25_ADCQ_CFG_REFP_INT | \
 82			MX25_ADCQ_CFG_IN_XP | \
 83			MX25_ADCQ_CFG_REFN_NGND2 | \
 84			MX25_ADCQ_CFG_IGS)
 85
 86#define MX25_TOUCH_DETECT_VALUE (\
 87			MX25_ADCQ_CFG_YNLR | \
 88			MX25_ADCQ_CFG_YPLL_OFF | \
 89			MX25_ADCQ_CFG_XNUR_OFF | \
 90			MX25_ADCQ_CFG_XPUL_OFF | \
 91			MX25_ADCQ_CFG_REFP_INT | \
 92			MX25_ADCQ_CFG_IN_XP | \
 93			MX25_ADCQ_CFG_REFN_NGND2 | \
 94			MX25_ADCQ_CFG_PENIACK)
 95
 96static void imx25_setup_queue_cfgs(struct mx25_tcq_priv *priv,
 97				   unsigned int settling_cnt)
 98{
 99	u32 precharge_cfg =
100			MX25_PRECHARGE_VALUE |
101			MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
102	u32 touch_detect_cfg =
103			MX25_TOUCH_DETECT_VALUE |
104			MX25_ADCQ_CFG_NOS(1) |
105			MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
106
107	regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg);
108
109	/* PRECHARGE */
110	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE),
111		     precharge_cfg);
112
113	/* TOUCH_DETECT */
114	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT),
115		     touch_detect_cfg);
116
117	/* X Measurement */
118	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT),
119		     MX25_ADCQ_CFG_YPLL_OFF |
120		     MX25_ADCQ_CFG_XNUR_LOW |
121		     MX25_ADCQ_CFG_XPUL_HIGH |
122		     MX25_ADCQ_CFG_REFP_XP |
123		     MX25_ADCQ_CFG_IN_YP |
124		     MX25_ADCQ_CFG_REFN_XN |
125		     MX25_ADCQ_CFG_NOS(priv->sample_count) |
126		     MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
127
128	/* Y Measurement */
129	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT),
130		     MX25_ADCQ_CFG_YNLR |
131		     MX25_ADCQ_CFG_YPLL_HIGH |
132		     MX25_ADCQ_CFG_XNUR_OFF |
133		     MX25_ADCQ_CFG_XPUL_OFF |
134		     MX25_ADCQ_CFG_REFP_YP |
135		     MX25_ADCQ_CFG_IN_XP |
136		     MX25_ADCQ_CFG_REFN_YN |
137		     MX25_ADCQ_CFG_NOS(priv->sample_count) |
138		     MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
139
140	/* Enable the touch detection right now */
141	regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg |
142		     MX25_ADCQ_CFG_IGS);
143}
144
145static int imx25_setup_queue_4wire(struct mx25_tcq_priv *priv,
146				   unsigned settling_cnt, int *items)
147{
148	imx25_setup_queue_cfgs(priv, settling_cnt);
149
150	/* Setup the conversion queue */
151	regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
152		     MX25_ADCQ_ITEM(0, MX25_CFG_PRECHARGE) |
153		     MX25_ADCQ_ITEM(1, MX25_CFG_TOUCH_DETECT) |
154		     MX25_ADCQ_ITEM(2, MX25_CFG_X_MEASUREMENT) |
155		     MX25_ADCQ_ITEM(3, MX25_CFG_Y_MEASUREMENT) |
156		     MX25_ADCQ_ITEM(4, MX25_CFG_PRECHARGE) |
157		     MX25_ADCQ_ITEM(5, MX25_CFG_TOUCH_DETECT));
158
159	/*
160	 * We measure X/Y with 'sample_count' number of samples and execute a
161	 * touch detection twice, with 1 sample each
162	 */
163	priv->expected_samples = priv->sample_count * 2 + 2;
164	*items = 6;
165
166	return 0;
167}
168
169static void mx25_tcq_disable_touch_irq(struct mx25_tcq_priv *priv)
170{
171	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK,
172			   MX25_ADCQ_CR_PDMSK);
173}
174
175static void mx25_tcq_enable_touch_irq(struct mx25_tcq_priv *priv)
176{
177	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0);
178}
179
180static void mx25_tcq_disable_fifo_irq(struct mx25_tcq_priv *priv)
181{
182	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ,
183			   MX25_ADCQ_MR_FDRY_IRQ);
184}
185
186static void mx25_tcq_enable_fifo_irq(struct mx25_tcq_priv *priv)
187{
188	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0);
189}
190
191static void mx25_tcq_force_queue_start(struct mx25_tcq_priv *priv)
192{
193	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
194			   MX25_ADCQ_CR_FQS,
195			   MX25_ADCQ_CR_FQS);
196}
197
198static void mx25_tcq_force_queue_stop(struct mx25_tcq_priv *priv)
199{
200	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
201			   MX25_ADCQ_CR_FQS, 0);
202}
203
204static void mx25_tcq_fifo_reset(struct mx25_tcq_priv *priv)
205{
206	u32 tcqcr;
207
208	regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr);
209	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST,
210			   MX25_ADCQ_CR_FRST);
211	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0);
212	regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr);
213}
214
215static void mx25_tcq_re_enable_touch_detection(struct mx25_tcq_priv *priv)
216{
217	/* stop the queue from looping */
218	mx25_tcq_force_queue_stop(priv);
219
220	/* for a clean touch detection, preload the X plane */
221	regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE);
222
223	/* waste some time now to pre-load the X plate to high voltage */
224	mx25_tcq_fifo_reset(priv);
225
226	/* re-enable the detection right now */
227	regmap_write(priv->core_regs, MX25_TSC_TICR,
228		     MX25_TOUCH_DETECT_VALUE | MX25_ADCQ_CFG_IGS);
229
230	regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD,
231			   MX25_ADCQ_SR_PD);
232
233	/* enable the pen down event to be a source for the interrupt */
234	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0);
235
236	/* lets fire the next IRQ if someone touches the touchscreen */
237	mx25_tcq_enable_touch_irq(priv);
238}
239
240static void mx25_tcq_create_event_for_4wire(struct mx25_tcq_priv *priv,
241					    u32 *sample_buf,
242					    unsigned int samples)
243{
244	unsigned int x_pos = 0;
245	unsigned int y_pos = 0;
246	unsigned int touch_pre = 0;
247	unsigned int touch_post = 0;
248	unsigned int i;
249
250	for (i = 0; i < samples; i++) {
251		unsigned int index = MX25_ADCQ_FIFO_ID(sample_buf[i]);
252		unsigned int val = MX25_ADCQ_FIFO_DATA(sample_buf[i]);
253
254		switch (index) {
255		case 1:
256			touch_pre = val;
257			break;
258		case 2:
259			x_pos = val;
260			break;
261		case 3:
262			y_pos = val;
263			break;
264		case 5:
265			touch_post = val;
266			break;
267		default:
268			dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n",
269				index);
270			return;
271		}
272	}
273
274	if (samples != 0) {
275		/*
276		 * only if both touch measures are below a threshold,
277		 * the position is valid
278		 */
279		if (touch_pre < priv->pen_threshold &&
280		    touch_post < priv->pen_threshold) {
281			/* valid samples, generate a report */
282			x_pos /= priv->sample_count;
283			y_pos /= priv->sample_count;
284			input_report_abs(priv->idev, ABS_X, x_pos);
285			input_report_abs(priv->idev, ABS_Y, y_pos);
286			input_report_key(priv->idev, BTN_TOUCH, 1);
287			input_sync(priv->idev);
288
289			/* get next sample */
290			mx25_tcq_enable_fifo_irq(priv);
291		} else if (touch_pre >= priv->pen_threshold &&
292			   touch_post >= priv->pen_threshold) {
293			/*
294			 * if both samples are invalid,
295			 * generate a release report
296			 */
297			input_report_key(priv->idev, BTN_TOUCH, 0);
298			input_sync(priv->idev);
299			mx25_tcq_re_enable_touch_detection(priv);
300		} else {
301			/*
302			 * if only one of both touch measurements are
303			 * below the threshold, still some bouncing
304			 * happens. Take additional samples in this
305			 * case to be sure
306			 */
307			mx25_tcq_enable_fifo_irq(priv);
308		}
309	}
310}
311
312static irqreturn_t mx25_tcq_irq_thread(int irq, void *dev_id)
313{
314	struct mx25_tcq_priv *priv = dev_id;
315	u32 sample_buf[TSC_MAX_SAMPLES];
316	unsigned int samples;
317	u32 stats;
318	unsigned int i;
319
320	/*
321	 * Check how many samples are available. We always have to read exactly
322	 * sample_count samples from the fifo, or a multiple of sample_count.
323	 * Otherwise we mixup samples into different touch events.
324	 */
325	regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
326	samples = MX25_ADCQ_SR_FDN(stats);
327	samples -= samples % priv->sample_count;
328
329	if (!samples)
330		return IRQ_HANDLED;
331
332	for (i = 0; i != samples; ++i)
333		regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]);
334
335	mx25_tcq_create_event_for_4wire(priv, sample_buf, samples);
336
337	return IRQ_HANDLED;
338}
339
340static irqreturn_t mx25_tcq_irq(int irq, void *dev_id)
341{
342	struct mx25_tcq_priv *priv = dev_id;
343	u32 stat;
344	int ret = IRQ_HANDLED;
345
346	regmap_read(priv->regs, MX25_ADCQ_SR, &stat);
347
348	if (stat & (MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR))
349		mx25_tcq_re_enable_touch_detection(priv);
350
351	if (stat & MX25_ADCQ_SR_PD) {
352		mx25_tcq_disable_touch_irq(priv);
353		mx25_tcq_force_queue_start(priv);
354		mx25_tcq_enable_fifo_irq(priv);
355	}
356
357	if (stat & MX25_ADCQ_SR_FDRY) {
358		mx25_tcq_disable_fifo_irq(priv);
359		ret = IRQ_WAKE_THREAD;
360	}
361
362	regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
363			   MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
364			   MX25_ADCQ_SR_PD,
365			   MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR |
366			   MX25_ADCQ_SR_FOR | MX25_ADCQ_SR_PD);
367
368	return ret;
369}
370
371/* configure the state machine for a 4-wire touchscreen */
372static int mx25_tcq_init(struct mx25_tcq_priv *priv)
373{
374	u32 tgcr;
375	unsigned int ipg_div;
376	unsigned int adc_period;
377	unsigned int debounce_cnt;
378	unsigned int settling_cnt;
379	int itemct;
380	int error;
381
382	regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr);
383	ipg_div = max_t(unsigned int, 4, MX25_TGCR_GET_ADCCLK(tgcr));
384	adc_period = USEC_PER_SEC * ipg_div * 2 + 2;
385	adc_period /= clk_get_rate(priv->clk) / 1000 + 1;
386	debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1;
387	settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1;
388
389	/* Reset */
390	regmap_write(priv->regs, MX25_ADCQ_CR,
391		     MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST);
392	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
393			   MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST, 0);
394
395	/* up to 128 * 8 ADC clocks are possible */
396	if (debounce_cnt > 127)
397		debounce_cnt = 127;
398
399	/* up to 255 * 8 ADC clocks are possible */
400	if (settling_cnt > 255)
401		settling_cnt = 255;
402
403	error = imx25_setup_queue_4wire(priv, settling_cnt, &itemct);
404	if (error)
405		return error;
406
407	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
408			   MX25_ADCQ_CR_LITEMID_MASK | MX25_ADCQ_CR_WMRK_MASK,
409			   MX25_ADCQ_CR_LITEMID(itemct - 1) |
410			   MX25_ADCQ_CR_WMRK(priv->expected_samples - 1));
411
412	/* setup debounce count */
413	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR,
414			   MX25_TGCR_PDBTIME_MASK,
415			   MX25_TGCR_PDBTIME(debounce_cnt));
416
417	/* enable debounce */
418	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN,
419			   MX25_TGCR_PDBEN);
420	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN,
421			   MX25_TGCR_PDEN);
422
423	/* enable the engine on demand */
424	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK,
425			   MX25_ADCQ_CR_QSM_FQS);
426
427	/* Enable repeat and repeat wait */
428	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
429			   MX25_ADCQ_CR_RPT | MX25_ADCQ_CR_RWAIT_MASK,
430			   MX25_ADCQ_CR_RPT |
431			   MX25_ADCQ_CR_RWAIT(MX25_TSC_REPEAT_WAIT));
432
433	return 0;
434}
435
436static int mx25_tcq_parse_dt(struct platform_device *pdev,
437			     struct mx25_tcq_priv *priv)
438{
439	struct device_node *np = pdev->dev.of_node;
440	u32 wires;
441	int error;
442
443	/* Setup defaults */
444	priv->pen_threshold = 500;
445	priv->sample_count = 3;
446	priv->pen_debounce = 1000000;
447	priv->settling_time = 250000;
448
449	error = of_property_read_u32(np, "fsl,wires", &wires);
450	if (error) {
451		dev_err(&pdev->dev, "Failed to find fsl,wires properties\n");
452		return error;
453	}
454
455	if (wires == 4) {
456		priv->mode = MX25_TS_4WIRE;
457	} else {
458		dev_err(&pdev->dev, "%u-wire mode not supported\n", wires);
459		return -EINVAL;
460	}
461
462	/* These are optional, we don't care about the return values */
463	of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold);
464	of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time);
465	of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce);
466
467	return 0;
468}
469
470static int mx25_tcq_open(struct input_dev *idev)
471{
472	struct device *dev = &idev->dev;
473	struct mx25_tcq_priv *priv = dev_get_drvdata(dev);
474	int error;
475
476	error = clk_prepare_enable(priv->clk);
477	if (error) {
478		dev_err(dev, "Failed to enable ipg clock\n");
479		return error;
480	}
481
482	error = mx25_tcq_init(priv);
483	if (error) {
484		dev_err(dev, "Failed to init tcq\n");
485		clk_disable_unprepare(priv->clk);
486		return error;
487	}
488
489	mx25_tcq_re_enable_touch_detection(priv);
490
491	return 0;
492}
493
494static void mx25_tcq_close(struct input_dev *idev)
495{
496	struct mx25_tcq_priv *priv = input_get_drvdata(idev);
497
498	mx25_tcq_force_queue_stop(priv);
499	mx25_tcq_disable_touch_irq(priv);
500	mx25_tcq_disable_fifo_irq(priv);
501	clk_disable_unprepare(priv->clk);
502}
503
504static int mx25_tcq_probe(struct platform_device *pdev)
505{
506	struct device *dev = &pdev->dev;
507	struct input_dev *idev;
508	struct mx25_tcq_priv *priv;
509	struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
510	struct resource *res;
511	void __iomem *mem;
512	int error;
513
514	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
515	if (!priv)
516		return -ENOMEM;
517	priv->dev = dev;
518
519	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520	mem = devm_ioremap_resource(dev, res);
521	if (IS_ERR(mem))
522		return PTR_ERR(mem);
523
524	error = mx25_tcq_parse_dt(pdev, priv);
525	if (error)
526		return error;
527
528	priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig);
529	if (IS_ERR(priv->regs)) {
530		dev_err(dev, "Failed to initialize regmap\n");
531		return PTR_ERR(priv->regs);
532	}
533
534	priv->irq = platform_get_irq(pdev, 0);
535	if (priv->irq <= 0) {
536		dev_err(dev, "Failed to get IRQ\n");
537		return priv->irq;
538	}
539
540	idev = devm_input_allocate_device(dev);
541	if (!idev) {
542		dev_err(dev, "Failed to allocate input device\n");
543		return -ENOMEM;
544	}
545
546	idev->name = mx25_tcq_name;
547	input_set_capability(idev, EV_KEY, BTN_TOUCH);
548	input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
549	input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
550
551	idev->id.bustype = BUS_HOST;
552	idev->open = mx25_tcq_open;
553	idev->close = mx25_tcq_close;
554
555	priv->idev = idev;
556	input_set_drvdata(idev, priv);
557
558	priv->core_regs = tsadc->regs;
559	if (!priv->core_regs)
560		return -EINVAL;
561
562	priv->clk = tsadc->clk;
563	if (!priv->clk)
564		return -EINVAL;
565
566	platform_set_drvdata(pdev, priv);
567
568	error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq,
569					  mx25_tcq_irq_thread, 0, pdev->name,
570					  priv);
571	if (error) {
572		dev_err(dev, "Failed requesting IRQ\n");
573		return error;
574	}
575
576	error = input_register_device(idev);
577	if (error) {
578		dev_err(dev, "Failed to register input device\n");
579		return error;
580	}
581
582	return 0;
583}
584
585static struct platform_driver mx25_tcq_driver = {
586	.driver		= {
587		.name	= "mx25-tcq",
588		.of_match_table = mx25_tcq_ids,
589	},
590	.probe		= mx25_tcq_probe,
591};
592module_platform_driver(mx25_tcq_driver);
593
594MODULE_DESCRIPTION("TS input driver for Freescale mx25");
595MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
596MODULE_LICENSE("GPL v2");
v4.17
  1/*
  2 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
  3 *
  4 * This program is free software; you can redistribute it and/or modify it under
  5 * the terms of the GNU General Public License version 2 as published by the
  6 * Free Software Foundation.
  7 *
  8 * Based on driver from 2011:
  9 *   Juergen Beisert, Pengutronix <kernel@pengutronix.de>
 10 *
 11 * This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
 12 * connected to the imx25 ADC.
 13 */
 14
 15#include <linux/clk.h>
 16#include <linux/device.h>
 17#include <linux/input.h>
 18#include <linux/interrupt.h>
 19#include <linux/mfd/imx25-tsadc.h>
 20#include <linux/module.h>
 21#include <linux/of.h>
 22#include <linux/platform_device.h>
 23#include <linux/regmap.h>
 24
 25static const char mx25_tcq_name[] = "mx25-tcq";
 26
 27enum mx25_tcq_mode {
 28	MX25_TS_4WIRE,
 29};
 30
 31struct mx25_tcq_priv {
 32	struct regmap *regs;
 33	struct regmap *core_regs;
 34	struct input_dev *idev;
 35	enum mx25_tcq_mode mode;
 36	unsigned int pen_threshold;
 37	unsigned int sample_count;
 38	unsigned int expected_samples;
 39	unsigned int pen_debounce;
 40	unsigned int settling_time;
 41	struct clk *clk;
 42	int irq;
 43	struct device *dev;
 44};
 45
 46static struct regmap_config mx25_tcq_regconfig = {
 47	.fast_io = true,
 48	.max_register = 0x5c,
 49	.reg_bits = 32,
 50	.val_bits = 32,
 51	.reg_stride = 4,
 52};
 53
 54static const struct of_device_id mx25_tcq_ids[] = {
 55	{ .compatible = "fsl,imx25-tcq", },
 56	{ /* Sentinel */ }
 57};
 58MODULE_DEVICE_TABLE(of, mx25_tcq_ids);
 59
 60#define TSC_4WIRE_PRE_INDEX 0
 61#define TSC_4WIRE_X_INDEX 1
 62#define TSC_4WIRE_Y_INDEX 2
 63#define TSC_4WIRE_POST_INDEX 3
 64#define TSC_4WIRE_LEAVE 4
 65
 66#define MX25_TSC_DEF_THRESHOLD 80
 67#define TSC_MAX_SAMPLES 16
 68
 69#define MX25_TSC_REPEAT_WAIT 14
 70
 71enum mx25_adc_configurations {
 72	MX25_CFG_PRECHARGE = 0,
 73	MX25_CFG_TOUCH_DETECT,
 74	MX25_CFG_X_MEASUREMENT,
 75	MX25_CFG_Y_MEASUREMENT,
 76};
 77
 78#define MX25_PRECHARGE_VALUE (\
 79			MX25_ADCQ_CFG_YPLL_OFF | \
 80			MX25_ADCQ_CFG_XNUR_OFF | \
 81			MX25_ADCQ_CFG_XPUL_HIGH | \
 82			MX25_ADCQ_CFG_REFP_INT | \
 83			MX25_ADCQ_CFG_IN_XP | \
 84			MX25_ADCQ_CFG_REFN_NGND2 | \
 85			MX25_ADCQ_CFG_IGS)
 86
 87#define MX25_TOUCH_DETECT_VALUE (\
 88			MX25_ADCQ_CFG_YNLR | \
 89			MX25_ADCQ_CFG_YPLL_OFF | \
 90			MX25_ADCQ_CFG_XNUR_OFF | \
 91			MX25_ADCQ_CFG_XPUL_OFF | \
 92			MX25_ADCQ_CFG_REFP_INT | \
 93			MX25_ADCQ_CFG_IN_XP | \
 94			MX25_ADCQ_CFG_REFN_NGND2 | \
 95			MX25_ADCQ_CFG_PENIACK)
 96
 97static void imx25_setup_queue_cfgs(struct mx25_tcq_priv *priv,
 98				   unsigned int settling_cnt)
 99{
100	u32 precharge_cfg =
101			MX25_PRECHARGE_VALUE |
102			MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
103	u32 touch_detect_cfg =
104			MX25_TOUCH_DETECT_VALUE |
105			MX25_ADCQ_CFG_NOS(1) |
106			MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
107
108	regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg);
109
110	/* PRECHARGE */
111	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE),
112		     precharge_cfg);
113
114	/* TOUCH_DETECT */
115	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT),
116		     touch_detect_cfg);
117
118	/* X Measurement */
119	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT),
120		     MX25_ADCQ_CFG_YPLL_OFF |
121		     MX25_ADCQ_CFG_XNUR_LOW |
122		     MX25_ADCQ_CFG_XPUL_HIGH |
123		     MX25_ADCQ_CFG_REFP_XP |
124		     MX25_ADCQ_CFG_IN_YP |
125		     MX25_ADCQ_CFG_REFN_XN |
126		     MX25_ADCQ_CFG_NOS(priv->sample_count) |
127		     MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
128
129	/* Y Measurement */
130	regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT),
131		     MX25_ADCQ_CFG_YNLR |
132		     MX25_ADCQ_CFG_YPLL_HIGH |
133		     MX25_ADCQ_CFG_XNUR_OFF |
134		     MX25_ADCQ_CFG_XPUL_OFF |
135		     MX25_ADCQ_CFG_REFP_YP |
136		     MX25_ADCQ_CFG_IN_XP |
137		     MX25_ADCQ_CFG_REFN_YN |
138		     MX25_ADCQ_CFG_NOS(priv->sample_count) |
139		     MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
140
141	/* Enable the touch detection right now */
142	regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg |
143		     MX25_ADCQ_CFG_IGS);
144}
145
146static int imx25_setup_queue_4wire(struct mx25_tcq_priv *priv,
147				   unsigned settling_cnt, int *items)
148{
149	imx25_setup_queue_cfgs(priv, settling_cnt);
150
151	/* Setup the conversion queue */
152	regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
153		     MX25_ADCQ_ITEM(0, MX25_CFG_PRECHARGE) |
154		     MX25_ADCQ_ITEM(1, MX25_CFG_TOUCH_DETECT) |
155		     MX25_ADCQ_ITEM(2, MX25_CFG_X_MEASUREMENT) |
156		     MX25_ADCQ_ITEM(3, MX25_CFG_Y_MEASUREMENT) |
157		     MX25_ADCQ_ITEM(4, MX25_CFG_PRECHARGE) |
158		     MX25_ADCQ_ITEM(5, MX25_CFG_TOUCH_DETECT));
159
160	/*
161	 * We measure X/Y with 'sample_count' number of samples and execute a
162	 * touch detection twice, with 1 sample each
163	 */
164	priv->expected_samples = priv->sample_count * 2 + 2;
165	*items = 6;
166
167	return 0;
168}
169
170static void mx25_tcq_disable_touch_irq(struct mx25_tcq_priv *priv)
171{
172	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK,
173			   MX25_ADCQ_CR_PDMSK);
174}
175
176static void mx25_tcq_enable_touch_irq(struct mx25_tcq_priv *priv)
177{
178	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0);
179}
180
181static void mx25_tcq_disable_fifo_irq(struct mx25_tcq_priv *priv)
182{
183	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ,
184			   MX25_ADCQ_MR_FDRY_IRQ);
185}
186
187static void mx25_tcq_enable_fifo_irq(struct mx25_tcq_priv *priv)
188{
189	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0);
190}
191
192static void mx25_tcq_force_queue_start(struct mx25_tcq_priv *priv)
193{
194	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
195			   MX25_ADCQ_CR_FQS,
196			   MX25_ADCQ_CR_FQS);
197}
198
199static void mx25_tcq_force_queue_stop(struct mx25_tcq_priv *priv)
200{
201	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
202			   MX25_ADCQ_CR_FQS, 0);
203}
204
205static void mx25_tcq_fifo_reset(struct mx25_tcq_priv *priv)
206{
207	u32 tcqcr;
208
209	regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr);
210	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST,
211			   MX25_ADCQ_CR_FRST);
212	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0);
213	regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr);
214}
215
216static void mx25_tcq_re_enable_touch_detection(struct mx25_tcq_priv *priv)
217{
218	/* stop the queue from looping */
219	mx25_tcq_force_queue_stop(priv);
220
221	/* for a clean touch detection, preload the X plane */
222	regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE);
223
224	/* waste some time now to pre-load the X plate to high voltage */
225	mx25_tcq_fifo_reset(priv);
226
227	/* re-enable the detection right now */
228	regmap_write(priv->core_regs, MX25_TSC_TICR,
229		     MX25_TOUCH_DETECT_VALUE | MX25_ADCQ_CFG_IGS);
230
231	regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD,
232			   MX25_ADCQ_SR_PD);
233
234	/* enable the pen down event to be a source for the interrupt */
235	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0);
236
237	/* lets fire the next IRQ if someone touches the touchscreen */
238	mx25_tcq_enable_touch_irq(priv);
239}
240
241static void mx25_tcq_create_event_for_4wire(struct mx25_tcq_priv *priv,
242					    u32 *sample_buf,
243					    unsigned int samples)
244{
245	unsigned int x_pos = 0;
246	unsigned int y_pos = 0;
247	unsigned int touch_pre = 0;
248	unsigned int touch_post = 0;
249	unsigned int i;
250
251	for (i = 0; i < samples; i++) {
252		unsigned int index = MX25_ADCQ_FIFO_ID(sample_buf[i]);
253		unsigned int val = MX25_ADCQ_FIFO_DATA(sample_buf[i]);
254
255		switch (index) {
256		case 1:
257			touch_pre = val;
258			break;
259		case 2:
260			x_pos = val;
261			break;
262		case 3:
263			y_pos = val;
264			break;
265		case 5:
266			touch_post = val;
267			break;
268		default:
269			dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n",
270				index);
271			return;
272		}
273	}
274
275	if (samples != 0) {
276		/*
277		 * only if both touch measures are below a threshold,
278		 * the position is valid
279		 */
280		if (touch_pre < priv->pen_threshold &&
281		    touch_post < priv->pen_threshold) {
282			/* valid samples, generate a report */
283			x_pos /= priv->sample_count;
284			y_pos /= priv->sample_count;
285			input_report_abs(priv->idev, ABS_X, x_pos);
286			input_report_abs(priv->idev, ABS_Y, y_pos);
287			input_report_key(priv->idev, BTN_TOUCH, 1);
288			input_sync(priv->idev);
289
290			/* get next sample */
291			mx25_tcq_enable_fifo_irq(priv);
292		} else if (touch_pre >= priv->pen_threshold &&
293			   touch_post >= priv->pen_threshold) {
294			/*
295			 * if both samples are invalid,
296			 * generate a release report
297			 */
298			input_report_key(priv->idev, BTN_TOUCH, 0);
299			input_sync(priv->idev);
300			mx25_tcq_re_enable_touch_detection(priv);
301		} else {
302			/*
303			 * if only one of both touch measurements are
304			 * below the threshold, still some bouncing
305			 * happens. Take additional samples in this
306			 * case to be sure
307			 */
308			mx25_tcq_enable_fifo_irq(priv);
309		}
310	}
311}
312
313static irqreturn_t mx25_tcq_irq_thread(int irq, void *dev_id)
314{
315	struct mx25_tcq_priv *priv = dev_id;
316	u32 sample_buf[TSC_MAX_SAMPLES];
317	unsigned int samples;
318	u32 stats;
319	unsigned int i;
320
321	/*
322	 * Check how many samples are available. We always have to read exactly
323	 * sample_count samples from the fifo, or a multiple of sample_count.
324	 * Otherwise we mixup samples into different touch events.
325	 */
326	regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
327	samples = MX25_ADCQ_SR_FDN(stats);
328	samples -= samples % priv->sample_count;
329
330	if (!samples)
331		return IRQ_HANDLED;
332
333	for (i = 0; i != samples; ++i)
334		regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]);
335
336	mx25_tcq_create_event_for_4wire(priv, sample_buf, samples);
337
338	return IRQ_HANDLED;
339}
340
341static irqreturn_t mx25_tcq_irq(int irq, void *dev_id)
342{
343	struct mx25_tcq_priv *priv = dev_id;
344	u32 stat;
345	int ret = IRQ_HANDLED;
346
347	regmap_read(priv->regs, MX25_ADCQ_SR, &stat);
348
349	if (stat & (MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR))
350		mx25_tcq_re_enable_touch_detection(priv);
351
352	if (stat & MX25_ADCQ_SR_PD) {
353		mx25_tcq_disable_touch_irq(priv);
354		mx25_tcq_force_queue_start(priv);
355		mx25_tcq_enable_fifo_irq(priv);
356	}
357
358	if (stat & MX25_ADCQ_SR_FDRY) {
359		mx25_tcq_disable_fifo_irq(priv);
360		ret = IRQ_WAKE_THREAD;
361	}
362
363	regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
364			   MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
365			   MX25_ADCQ_SR_PD,
366			   MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR |
367			   MX25_ADCQ_SR_FOR | MX25_ADCQ_SR_PD);
368
369	return ret;
370}
371
372/* configure the state machine for a 4-wire touchscreen */
373static int mx25_tcq_init(struct mx25_tcq_priv *priv)
374{
375	u32 tgcr;
376	unsigned int ipg_div;
377	unsigned int adc_period;
378	unsigned int debounce_cnt;
379	unsigned int settling_cnt;
380	int itemct;
381	int error;
382
383	regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr);
384	ipg_div = max_t(unsigned int, 4, MX25_TGCR_GET_ADCCLK(tgcr));
385	adc_period = USEC_PER_SEC * ipg_div * 2 + 2;
386	adc_period /= clk_get_rate(priv->clk) / 1000 + 1;
387	debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1;
388	settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1;
389
390	/* Reset */
391	regmap_write(priv->regs, MX25_ADCQ_CR,
392		     MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST);
393	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
394			   MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST, 0);
395
396	/* up to 128 * 8 ADC clocks are possible */
397	if (debounce_cnt > 127)
398		debounce_cnt = 127;
399
400	/* up to 255 * 8 ADC clocks are possible */
401	if (settling_cnt > 255)
402		settling_cnt = 255;
403
404	error = imx25_setup_queue_4wire(priv, settling_cnt, &itemct);
405	if (error)
406		return error;
407
408	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
409			   MX25_ADCQ_CR_LITEMID_MASK | MX25_ADCQ_CR_WMRK_MASK,
410			   MX25_ADCQ_CR_LITEMID(itemct - 1) |
411			   MX25_ADCQ_CR_WMRK(priv->expected_samples - 1));
412
413	/* setup debounce count */
414	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR,
415			   MX25_TGCR_PDBTIME_MASK,
416			   MX25_TGCR_PDBTIME(debounce_cnt));
417
418	/* enable debounce */
419	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN,
420			   MX25_TGCR_PDBEN);
421	regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN,
422			   MX25_TGCR_PDEN);
423
424	/* enable the engine on demand */
425	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK,
426			   MX25_ADCQ_CR_QSM_FQS);
427
428	/* Enable repeat and repeat wait */
429	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
430			   MX25_ADCQ_CR_RPT | MX25_ADCQ_CR_RWAIT_MASK,
431			   MX25_ADCQ_CR_RPT |
432			   MX25_ADCQ_CR_RWAIT(MX25_TSC_REPEAT_WAIT));
433
434	return 0;
435}
436
437static int mx25_tcq_parse_dt(struct platform_device *pdev,
438			     struct mx25_tcq_priv *priv)
439{
440	struct device_node *np = pdev->dev.of_node;
441	u32 wires;
442	int error;
443
444	/* Setup defaults */
445	priv->pen_threshold = 500;
446	priv->sample_count = 3;
447	priv->pen_debounce = 1000000;
448	priv->settling_time = 250000;
449
450	error = of_property_read_u32(np, "fsl,wires", &wires);
451	if (error) {
452		dev_err(&pdev->dev, "Failed to find fsl,wires properties\n");
453		return error;
454	}
455
456	if (wires == 4) {
457		priv->mode = MX25_TS_4WIRE;
458	} else {
459		dev_err(&pdev->dev, "%u-wire mode not supported\n", wires);
460		return -EINVAL;
461	}
462
463	/* These are optional, we don't care about the return values */
464	of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold);
465	of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time);
466	of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce);
467
468	return 0;
469}
470
471static int mx25_tcq_open(struct input_dev *idev)
472{
473	struct device *dev = &idev->dev;
474	struct mx25_tcq_priv *priv = dev_get_drvdata(dev);
475	int error;
476
477	error = clk_prepare_enable(priv->clk);
478	if (error) {
479		dev_err(dev, "Failed to enable ipg clock\n");
480		return error;
481	}
482
483	error = mx25_tcq_init(priv);
484	if (error) {
485		dev_err(dev, "Failed to init tcq\n");
486		clk_disable_unprepare(priv->clk);
487		return error;
488	}
489
490	mx25_tcq_re_enable_touch_detection(priv);
491
492	return 0;
493}
494
495static void mx25_tcq_close(struct input_dev *idev)
496{
497	struct mx25_tcq_priv *priv = input_get_drvdata(idev);
498
499	mx25_tcq_force_queue_stop(priv);
500	mx25_tcq_disable_touch_irq(priv);
501	mx25_tcq_disable_fifo_irq(priv);
502	clk_disable_unprepare(priv->clk);
503}
504
505static int mx25_tcq_probe(struct platform_device *pdev)
506{
507	struct device *dev = &pdev->dev;
508	struct input_dev *idev;
509	struct mx25_tcq_priv *priv;
510	struct mx25_tsadc *tsadc = dev_get_drvdata(dev->parent);
511	struct resource *res;
512	void __iomem *mem;
513	int error;
514
515	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
516	if (!priv)
517		return -ENOMEM;
518	priv->dev = dev;
519
520	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
521	mem = devm_ioremap_resource(dev, res);
522	if (IS_ERR(mem))
523		return PTR_ERR(mem);
524
525	error = mx25_tcq_parse_dt(pdev, priv);
526	if (error)
527		return error;
528
529	priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig);
530	if (IS_ERR(priv->regs)) {
531		dev_err(dev, "Failed to initialize regmap\n");
532		return PTR_ERR(priv->regs);
533	}
534
535	priv->irq = platform_get_irq(pdev, 0);
536	if (priv->irq <= 0) {
537		dev_err(dev, "Failed to get IRQ\n");
538		return priv->irq;
539	}
540
541	idev = devm_input_allocate_device(dev);
542	if (!idev) {
543		dev_err(dev, "Failed to allocate input device\n");
544		return -ENOMEM;
545	}
546
547	idev->name = mx25_tcq_name;
548	input_set_capability(idev, EV_KEY, BTN_TOUCH);
549	input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
550	input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
551
552	idev->id.bustype = BUS_HOST;
553	idev->open = mx25_tcq_open;
554	idev->close = mx25_tcq_close;
555
556	priv->idev = idev;
557	input_set_drvdata(idev, priv);
558
559	priv->core_regs = tsadc->regs;
560	if (!priv->core_regs)
561		return -EINVAL;
562
563	priv->clk = tsadc->clk;
564	if (!priv->clk)
565		return -EINVAL;
566
567	platform_set_drvdata(pdev, priv);
568
569	error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq,
570					  mx25_tcq_irq_thread, 0, pdev->name,
571					  priv);
572	if (error) {
573		dev_err(dev, "Failed requesting IRQ\n");
574		return error;
575	}
576
577	error = input_register_device(idev);
578	if (error) {
579		dev_err(dev, "Failed to register input device\n");
580		return error;
581	}
582
583	return 0;
584}
585
586static struct platform_driver mx25_tcq_driver = {
587	.driver		= {
588		.name	= "mx25-tcq",
589		.of_match_table = mx25_tcq_ids,
590	},
591	.probe		= mx25_tcq_probe,
592};
593module_platform_driver(mx25_tcq_driver);
594
595MODULE_DESCRIPTION("TS input driver for Freescale mx25");
596MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
597MODULE_LICENSE("GPL v2");