fsl-imx25-tcq.c 15 KB

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