Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  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");