cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fsl-imx25-tcq.c (15430B)


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