2 * drivers/input/touchscreen/lpc32xx_tsc.c
4 * Author: Kevin Wells <kevin.wells@nxp.com>
6 * Copyright (C) 2010 NXP Semiconductors
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <linux/platform_device.h>
20 #include <linux/init.h>
21 #include <linux/input.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.h>
24 #include <linux/clk.h>
26 #include <linux/slab.h>
29 * Touchscreen controller register offsets
31 #define LPC32XX_TSC_STAT(x) ((x) + 0x00)
32 #define LPC32XX_TSC_SEL(x) ((x) + 0x04)
33 #define LPC32XX_TSC_CON(x) ((x) + 0x08)
34 #define LPC32XX_TSC_FIFO(x) ((x) + 0x0C)
35 #define LPC32XX_TSC_DTR(x) ((x) + 0x10)
36 #define LPC32XX_TSC_RTR(x) ((x) + 0x14)
37 #define LPC32XX_TSC_UTR(x) ((x) + 0x18)
38 #define LPC32XX_TSC_TTR(x) ((x) + 0x1C)
39 #define LPC32XX_TSC_DXP(x) ((x) + 0x20)
40 #define LPC32XX_TSC_MIN_X(x) ((x) + 0x24)
41 #define LPC32XX_TSC_MAX_X(x) ((x) + 0x28)
42 #define LPC32XX_TSC_MIN_Y(x) ((x) + 0x2C)
43 #define LPC32XX_TSC_MAX_Y(x) ((x) + 0x30)
44 #define LPC32XX_TSC_AUX_UTR(x) ((x) + 0x34)
45 #define LPC32XX_TSC_AUX_MIN(x) ((x) + 0x38)
46 #define LPC32XX_TSC_AUX_MAX(x) ((x) + 0x3C)
48 #define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8)
49 #define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7)
51 #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11)
52 #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - s) << 7)
53 #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - s) << 4)
54 #define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2)
55 #define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0)
57 #define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31)
58 #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16)
59 #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF)
61 #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF
63 #define MOD_NAME "lpc32xx-ts"
65 struct lpc32xx_tsc_t {
66 struct input_dev *dev;
67 void __iomem *tsc_base;
72 static void lpc32xx_fifo_clear(struct lpc32xx_tsc_t *lpc32xx_tsc_dat)
74 while (!(__raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base)) &
75 LPC32XX_TSC_STAT_FIFO_EMPTY))
76 __raw_readl(LPC32XX_TSC_FIFO(lpc32xx_tsc_dat->tsc_base));
79 static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id)
81 u32 tmp, rv[4], xs[4], ys[4];
83 struct lpc32xx_tsc_t *lpc32xx_tsc_dat =
84 (struct lpc32xx_tsc_t *) dev_id;
85 struct input_dev *input = lpc32xx_tsc_dat->dev;
87 tmp = __raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base));
89 if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) {
90 /* FIFO overflow - throw away samples */
91 lpc32xx_fifo_clear(lpc32xx_tsc_dat);
97 (!(__raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base)) &
98 LPC32XX_TSC_STAT_FIFO_EMPTY))) {
99 tmp = __raw_readl(LPC32XX_TSC_FIFO(lpc32xx_tsc_dat->tsc_base));
100 xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
101 LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp);
102 ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
103 LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp);
108 /* Data is only valid if pen is still down */
109 if ((!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL)) && (idx == 4)) {
110 input_report_abs(input, ABS_X, ((xs[1] + xs[2]) / 2));
111 input_report_abs(input, ABS_Y, ((ys[1] + ys[2]) / 2));
112 input_report_abs(input, ABS_PRESSURE, 1);
113 input_report_key(input, BTN_TOUCH, 1);
115 input_report_abs(input, ABS_PRESSURE, 0);
116 input_report_key(input, BTN_TOUCH, 0);
124 static void stop_tsc(struct lpc32xx_tsc_t *lpc32xx_tsc_dat)
128 /* Disable auto mode */
129 tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
130 tmp &= ~LPC32XX_TSC_ADCCON_AUTO_EN;
131 __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
134 static void setup_tsc(struct lpc32xx_tsc_t *lpc32xx_tsc_dat)
138 tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
139 tmp &= ~LPC32XX_TSC_ADCCON_POWER_UP;
140 __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
142 /* Set the TSC FIFO depth to 4 samples @ 10-bits sample */
143 tmp = (LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 |
144 LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) |
145 LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10));
146 __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
148 __raw_writel(0x0284, LPC32XX_TSC_SEL(lpc32xx_tsc_dat->tsc_base));
149 __raw_writel(0x0000, LPC32XX_TSC_MIN_X(lpc32xx_tsc_dat->tsc_base));
150 __raw_writel(0x03FF, LPC32XX_TSC_MAX_X(lpc32xx_tsc_dat->tsc_base));
151 __raw_writel(0x0000, LPC32XX_TSC_MIN_Y(lpc32xx_tsc_dat->tsc_base));
152 __raw_writel(0x03FF, LPC32XX_TSC_MAX_Y(lpc32xx_tsc_dat->tsc_base));
153 __raw_writel(0x0000, LPC32XX_TSC_AUX_UTR(lpc32xx_tsc_dat->tsc_base));
154 __raw_writel(0x0000, LPC32XX_TSC_AUX_MIN(lpc32xx_tsc_dat->tsc_base));
155 __raw_writel(0x0000, LPC32XX_TSC_AUX_MAX(lpc32xx_tsc_dat->tsc_base));
156 __raw_writel(0x2, LPC32XX_TSC_RTR(lpc32xx_tsc_dat->tsc_base));
157 __raw_writel(446, LPC32XX_TSC_UTR(lpc32xx_tsc_dat->tsc_base));
158 __raw_writel(0x2, LPC32XX_TSC_DTR(lpc32xx_tsc_dat->tsc_base));
159 __raw_writel(0x10, LPC32XX_TSC_TTR(lpc32xx_tsc_dat->tsc_base));
160 __raw_writel(0x4, LPC32XX_TSC_DXP(lpc32xx_tsc_dat->tsc_base));
163 * Set sample rate to about 60Hz, this rate is based on the
164 * RTC clock, which should be a stable 32768Hz
166 __raw_writel(88, LPC32XX_TSC_UTR(lpc32xx_tsc_dat->tsc_base));
168 lpc32xx_fifo_clear(lpc32xx_tsc_dat);
170 tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
171 tmp |= LPC32XX_TSC_ADCCON_AUTO_EN;
172 __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base));
175 static int __devinit lpc32xx_ts_probe(struct platform_device *pdev)
177 struct lpc32xx_tsc_t *lpc32xx_tsc_dat = NULL;
178 struct resource *res;
179 int retval = -ENODEV;
181 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
183 dev_err(&pdev->dev, "failed to get platform I/O memory\n");
188 lpc32xx_tsc_dat = kzalloc(sizeof(struct lpc32xx_tsc_t), GFP_KERNEL);
189 if (unlikely(!lpc32xx_tsc_dat)) {
190 dev_err(&pdev->dev, "failed allocating memory\n");
195 lpc32xx_tsc_dat->tsc_base = ioremap(res->start,
196 res->end - res->start + 1);
197 if (!lpc32xx_tsc_dat->tsc_base) {
198 dev_err(&pdev->dev, "failed mapping memory\n");
203 lpc32xx_tsc_dat->dev = input_allocate_device();
204 if (!lpc32xx_tsc_dat->dev) {
205 dev_err(&pdev->dev, "failed allocating input device\n");
210 lpc32xx_tsc_dat->clk = clk_get(&pdev->dev, NULL);
211 if (IS_ERR(lpc32xx_tsc_dat->clk)) {
212 dev_err(&pdev->dev, "failed getting clock\n");
215 clk_enable(lpc32xx_tsc_dat->clk);
217 setup_tsc(lpc32xx_tsc_dat);
219 lpc32xx_tsc_dat->irq = platform_get_irq(pdev, 0);
220 if ((lpc32xx_tsc_dat->irq < 0) || (lpc32xx_tsc_dat->irq >= NR_IRQS)) {
221 dev_err(&pdev->dev, "failed getting interrupt resource\n");
226 retval = request_irq(lpc32xx_tsc_dat->irq, lpc32xx_ts_interrupt,
227 0, MOD_NAME, lpc32xx_tsc_dat);
229 dev_err(&pdev->dev, "failed requesting interrupt\n");
233 platform_set_drvdata(pdev, lpc32xx_tsc_dat);
235 lpc32xx_tsc_dat->dev->name = MOD_NAME;
236 lpc32xx_tsc_dat->dev->phys = "lpc32xx/input0";
237 lpc32xx_tsc_dat->dev->id.bustype = BUS_HOST;
238 lpc32xx_tsc_dat->dev->id.vendor = 0x0001;
239 lpc32xx_tsc_dat->dev->id.product = 0x0002;
240 lpc32xx_tsc_dat->dev->id.version = 0x0100;
241 lpc32xx_tsc_dat->dev->dev.parent = &pdev->dev;
243 lpc32xx_tsc_dat->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
244 lpc32xx_tsc_dat->dev->keybit[BIT_WORD(BTN_TOUCH)] =
246 input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_X, 0, 1023, 0, 0);
247 input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_Y, 0, 1023, 0, 0);
248 input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_PRESSURE, 0, 1, 0, 0);
250 retval = input_register_device(lpc32xx_tsc_dat->dev);
252 dev_err(&pdev->dev, "failed registering input device\n");
259 stop_tsc(lpc32xx_tsc_dat);
260 platform_set_drvdata(pdev, NULL);
261 free_irq(lpc32xx_tsc_dat->irq, lpc32xx_tsc_dat->dev);
264 if (lpc32xx_tsc_dat) {
265 if (lpc32xx_tsc_dat->clk) {
266 clk_disable(lpc32xx_tsc_dat->clk);
267 clk_put(lpc32xx_tsc_dat->clk);
270 if (lpc32xx_tsc_dat->dev)
271 input_free_device(lpc32xx_tsc_dat->dev);
273 if (lpc32xx_tsc_dat->tsc_base)
274 iounmap(lpc32xx_tsc_dat->tsc_base);
276 kfree(lpc32xx_tsc_dat);
282 static int __devexit lpc32xx_ts_remove(struct platform_device *pdev)
284 struct lpc32xx_tsc_t *lpc32xx_tsc_dat = platform_get_drvdata(pdev);
286 stop_tsc(lpc32xx_tsc_dat);
287 free_irq(lpc32xx_tsc_dat->irq, lpc32xx_tsc_dat->dev);
288 platform_set_drvdata(pdev, NULL);
289 input_unregister_device(lpc32xx_tsc_dat->dev);
291 if (lpc32xx_tsc_dat->clk) {
292 clk_disable(lpc32xx_tsc_dat->clk);
293 clk_put(lpc32xx_tsc_dat->clk);
296 if (lpc32xx_tsc_dat->tsc_base)
297 iounmap(lpc32xx_tsc_dat->tsc_base);
299 kfree(lpc32xx_tsc_dat);
304 static struct platform_driver lpc32xx_ts_driver = {
305 .probe = lpc32xx_ts_probe,
306 .remove = __devexit_p(lpc32xx_ts_remove),
312 static int __init lpc32xx_ts_init(void)
314 return platform_driver_register(&lpc32xx_ts_driver);
317 static void __exit lpc32xx_ts_exit(void)
319 platform_driver_unregister(&lpc32xx_ts_driver);
322 module_init(lpc32xx_ts_init);
323 module_exit(lpc32xx_ts_exit);
325 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com");
326 MODULE_DESCRIPTION("LPC32XX TSC Driver");
327 MODULE_LICENSE("GPL");