2 * TI Touch Screen driver
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/err.h>
20 #include <linux/module.h>
21 #include <linux/input.h>
22 #include <linux/slab.h>
23 #include <linux/interrupt.h>
24 #include <linux/clk.h>
25 #include <linux/platform_device.h>
27 #include <linux/input/ti_tscadc.h>
28 #include <linux/delay.h>
30 #define REG_IRQEOI 0x020
31 #define REG_RAWIRQSTATUS 0x024
32 #define REG_IRQSTATUS 0x028
33 #define REG_IRQENABLE 0x02C
34 #define REG_IRQWAKEUP 0x034
35 #define REG_CTRL 0x040
36 #define REG_ADCFSM 0x044
37 #define REG_CLKDIV 0x04C
39 #define REG_IDLECONFIG 0x058
40 #define REG_CHARGECONFIG 0x05C
41 #define REG_CHARGEDELAY 0x060
42 #define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8))
43 #define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8))
44 #define REG_STEPCONFIG13 0x0C4
45 #define REG_STEPDELAY13 0x0C8
46 #define REG_STEPCONFIG14 0x0CC
47 #define REG_STEPDELAY14 0x0D0
48 #define REG_FIFO0CNT 0xE4
49 #define REG_FIFO1THR 0xF4
50 #define REG_FIFO0 0x100
51 #define REG_FIFO1 0x200
53 /* Register Bitfields */
54 #define IRQWKUP_ENB BIT(0)
55 #define STPENB_STEPENB 0x7FFF
56 #define IRQENB_FIFO1THRES BIT(5)
57 #define IRQENB_PENUP BIT(9)
58 #define STEPCONFIG_MODE_HWSYNC 0x2
59 #define STEPCONFIG_SAMPLES_AVG (1 << 4)
60 #define STEPCONFIG_XPP (1 << 5)
61 #define STEPCONFIG_XNN (1 << 6)
62 #define STEPCONFIG_YPP (1 << 7)
63 #define STEPCONFIG_YNN (1 << 8)
64 #define STEPCONFIG_XNP (1 << 9)
65 #define STEPCONFIG_YPN (1 << 10)
66 #define STEPCONFIG_INM (1 << 18)
67 #define STEPCONFIG_INP (1 << 20)
68 #define STEPCONFIG_INP_5 (1 << 21)
69 #define STEPCONFIG_FIFO1 (1 << 26)
70 #define STEPCONFIG_OPENDLY 0xff
71 #define STEPCONFIG_Z1 (3 << 19)
72 #define STEPIDLE_INP (1 << 22)
73 #define STEPCHARGE_RFP (1 << 12)
74 #define STEPCHARGE_INM (1 << 15)
75 #define STEPCHARGE_INP (1 << 19)
76 #define STEPCHARGE_RFM (1 << 23)
77 #define STEPCHARGE_DELAY 0x1
78 #define CNTRLREG_TSCSSENB (1 << 0)
79 #define CNTRLREG_STEPID (1 << 1)
80 #define CNTRLREG_STEPCONFIGWRT (1 << 2)
81 #define CNTRLREG_4WIRE (1 << 5)
82 #define CNTRLREG_5WIRE (1 << 6)
83 #define CNTRLREG_8WIRE (3 << 5)
84 #define CNTRLREG_TSCENB (1 << 7)
85 #define ADCFSM_STEPID 0x10
87 #define SEQ_SETTLE 275
88 #define ADC_CLK 3000000
89 #define MAX_12BIT ((1 << 12) - 1)
90 #define TSCADC_DELTA_X 15
91 #define TSCADC_DELTA_Y 15
94 struct input_dev
*input
;
96 void __iomem
*tsc_base
;
99 unsigned int x_plate_resistance
;
103 static unsigned int tscadc_readl(struct tscadc
*ts
, unsigned int reg
)
105 return readl(ts
->tsc_base
+ reg
);
108 static void tscadc_writel(struct tscadc
*tsc
, unsigned int reg
,
111 writel(val
, tsc
->tsc_base
+ reg
);
114 static void tscadc_step_config(struct tscadc
*ts_dev
)
119 /* Configure the Step registers */
121 config
= STEPCONFIG_MODE_HWSYNC
|
122 STEPCONFIG_SAMPLES_AVG
| STEPCONFIG_XPP
;
123 switch (ts_dev
->wires
) {
125 config
|= STEPCONFIG_INP
| STEPCONFIG_XNN
;
128 config
|= STEPCONFIG_YNN
|
129 STEPCONFIG_INP_5
| STEPCONFIG_XNN
|
133 config
|= STEPCONFIG_INP
| STEPCONFIG_XNN
;
137 for (i
= 1; i
< 7; i
++) {
138 tscadc_writel(ts_dev
, REG_STEPCONFIG(i
), config
);
139 tscadc_writel(ts_dev
, REG_STEPDELAY(i
), STEPCONFIG_OPENDLY
);
143 config
= STEPCONFIG_MODE_HWSYNC
|
144 STEPCONFIG_SAMPLES_AVG
| STEPCONFIG_YNN
|
145 STEPCONFIG_INM
| STEPCONFIG_FIFO1
;
146 switch (ts_dev
->wires
) {
148 config
|= STEPCONFIG_YPP
;
151 config
|= STEPCONFIG_XPP
| STEPCONFIG_INP_5
|
152 STEPCONFIG_XNP
| STEPCONFIG_YPN
;
155 config
|= STEPCONFIG_YPP
;
159 for (i
= 7; i
< 13; i
++) {
160 tscadc_writel(ts_dev
, REG_STEPCONFIG(i
), config
);
161 tscadc_writel(ts_dev
, REG_STEPDELAY(i
), STEPCONFIG_OPENDLY
);
165 /* Charge step configuration */
166 config
= STEPCONFIG_XPP
| STEPCONFIG_YNN
|
167 STEPCHARGE_RFP
| STEPCHARGE_RFM
|
168 STEPCHARGE_INM
| STEPCHARGE_INP
;
170 tscadc_writel(ts_dev
, REG_CHARGECONFIG
, config
);
171 tscadc_writel(ts_dev
, REG_CHARGEDELAY
, STEPCHARGE_DELAY
);
174 /* Configure to calculate pressure */
175 config
= STEPCONFIG_MODE_HWSYNC
|
176 STEPCONFIG_SAMPLES_AVG
| STEPCONFIG_YPP
|
177 STEPCONFIG_XNN
| STEPCONFIG_INM
;
178 tscadc_writel(ts_dev
, REG_STEPCONFIG13
, config
);
179 tscadc_writel(ts_dev
, REG_STEPDELAY13
, STEPCONFIG_OPENDLY
);
181 config
|= STEPCONFIG_Z1
| STEPCONFIG_FIFO1
;
182 tscadc_writel(ts_dev
, REG_STEPCONFIG14
, config
);
183 tscadc_writel(ts_dev
, REG_STEPDELAY14
, STEPCONFIG_OPENDLY
);
185 tscadc_writel(ts_dev
, REG_SE
, STPENB_STEPENB
);
188 static void tscadc_idle_config(struct tscadc
*ts_config
)
190 unsigned int idleconfig
;
192 idleconfig
= STEPCONFIG_YNN
|
194 STEPCONFIG_YPN
| STEPIDLE_INP
;
195 tscadc_writel(ts_config
, REG_IDLECONFIG
, idleconfig
);
198 static void tscadc_read_coordinates(struct tscadc
*ts_dev
,
199 unsigned int *x
, unsigned int *y
)
201 unsigned int fifocount
= tscadc_readl(ts_dev
, REG_FIFO0CNT
);
202 unsigned int prev_val_x
= ~0, prev_val_y
= ~0;
203 unsigned int prev_diff_x
= ~0, prev_diff_y
= ~0;
204 unsigned int read
, diff
;
208 * Delta filter is used to remove large variations in sampled
209 * values from ADC. The filter tries to predict where the next
210 * coordinate could be. This is done by taking a previous
211 * coordinate and subtracting it form current one. Further the
212 * algorithm compares the difference with that of a present value,
213 * if true the value is reported to the sub system.
215 for (i
= 0; i
< fifocount
- 1; i
++) {
216 read
= tscadc_readl(ts_dev
, REG_FIFO0
) & 0xfff;
217 diff
= abs(read
- prev_val_x
);
218 if (diff
< prev_diff_x
) {
224 read
= tscadc_readl(ts_dev
, REG_FIFO1
) & 0xfff;
225 diff
= abs(read
- prev_val_y
);
226 if (diff
< prev_diff_y
) {
234 static irqreturn_t
tscadc_irq(int irq
, void *dev
)
236 struct tscadc
*ts_dev
= dev
;
237 struct input_dev
*input_dev
= ts_dev
->input
;
238 unsigned int status
, irqclr
= 0;
239 unsigned int x
= 0, y
= 0;
240 unsigned int z1
, z2
, z
;
243 status
= tscadc_readl(ts_dev
, REG_IRQSTATUS
);
244 if (status
& IRQENB_FIFO1THRES
) {
245 tscadc_read_coordinates(ts_dev
, &x
, &y
);
247 z1
= tscadc_readl(ts_dev
, REG_FIFO0
) & 0xfff;
248 z2
= tscadc_readl(ts_dev
, REG_FIFO1
) & 0xfff;
250 if (ts_dev
->pen_down
&& z1
!= 0 && z2
!= 0) {
252 * Calculate pressure using formula
253 * Resistance(touch) = x plate resistance *
254 * x postion/4096 * ((z2 / z1) - 1)
258 z
*= ts_dev
->x_plate_resistance
;
260 z
= (z
+ 2047) >> 12;
262 if (z
<= MAX_12BIT
) {
263 input_report_abs(input_dev
, ABS_X
, x
);
264 input_report_abs(input_dev
, ABS_Y
, y
);
265 input_report_abs(input_dev
, ABS_PRESSURE
, z
);
266 input_report_key(input_dev
, BTN_TOUCH
, 1);
267 input_sync(input_dev
);
270 irqclr
|= IRQENB_FIFO1THRES
;
274 * Time for sequencer to settle, to read
275 * correct state of the sequencer.
279 status
= tscadc_readl(ts_dev
, REG_RAWIRQSTATUS
);
280 if (status
& IRQENB_PENUP
) {
282 fsm
= tscadc_readl(ts_dev
, REG_ADCFSM
);
283 if (fsm
== ADCFSM_STEPID
) {
284 ts_dev
->pen_down
= false;
285 input_report_key(input_dev
, BTN_TOUCH
, 0);
286 input_report_abs(input_dev
, ABS_PRESSURE
, 0);
287 input_sync(input_dev
);
289 ts_dev
->pen_down
= true;
291 irqclr
|= IRQENB_PENUP
;
294 tscadc_writel(ts_dev
, REG_IRQSTATUS
, irqclr
);
295 /* check pending interrupts */
296 tscadc_writel(ts_dev
, REG_IRQEOI
, 0x0);
298 tscadc_writel(ts_dev
, REG_SE
, STPENB_STEPENB
);
303 * The functions for inserting/removing driver as a module.
306 static int __devinit
tscadc_probe(struct platform_device
*pdev
)
308 const struct tsc_data
*pdata
= pdev
->dev
.platform_data
;
309 struct resource
*res
;
310 struct tscadc
*ts_dev
;
311 struct input_dev
*input_dev
;
314 int clk_value
, ctrl
, irq
;
317 dev_err(&pdev
->dev
, "missing platform data.\n");
321 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
323 dev_err(&pdev
->dev
, "no memory resource defined.\n");
327 irq
= platform_get_irq(pdev
, 0);
329 dev_err(&pdev
->dev
, "no irq ID is specified.\n");
333 /* Allocate memory for device */
334 ts_dev
= kzalloc(sizeof(struct tscadc
), GFP_KERNEL
);
335 input_dev
= input_allocate_device();
336 if (!ts_dev
|| !input_dev
) {
337 dev_err(&pdev
->dev
, "failed to allocate memory.\n");
342 ts_dev
->input
= input_dev
;
344 ts_dev
->wires
= pdata
->wires
;
345 ts_dev
->x_plate_resistance
= pdata
->x_plate_resistance
;
347 res
= request_mem_region(res
->start
, resource_size(res
), pdev
->name
);
349 dev_err(&pdev
->dev
, "failed to reserve registers.\n");
354 ts_dev
->tsc_base
= ioremap(res
->start
, resource_size(res
));
355 if (!ts_dev
->tsc_base
) {
356 dev_err(&pdev
->dev
, "failed to map registers.\n");
358 goto err_release_mem_region
;
361 err
= request_irq(ts_dev
->irq
, tscadc_irq
,
362 0, pdev
->dev
.driver
->name
, ts_dev
);
364 dev_err(&pdev
->dev
, "failed to allocate irq.\n");
368 ts_dev
->tsc_ick
= clk_get(&pdev
->dev
, "adc_tsc_ick");
369 if (IS_ERR(ts_dev
->tsc_ick
)) {
370 dev_err(&pdev
->dev
, "failed to get TSC ick\n");
373 clk_enable(ts_dev
->tsc_ick
);
375 clk
= clk_get(&pdev
->dev
, "adc_tsc_fck");
377 dev_err(&pdev
->dev
, "failed to get TSC fck\n");
379 goto err_disable_clk
;
382 clk_value
= clk_get_rate(clk
) / ADC_CLK
;
386 dev_err(&pdev
->dev
, "clock input less than min clock requirement\n");
387 goto err_disable_clk
;
389 /* CLKDIV needs to be configured to the value minus 1 */
390 tscadc_writel(ts_dev
, REG_CLKDIV
, clk_value
- 1);
392 /* Enable wake-up of the SoC using touchscreen */
393 tscadc_writel(ts_dev
, REG_IRQWAKEUP
, IRQWKUP_ENB
);
395 ctrl
= CNTRLREG_STEPCONFIGWRT
|
398 switch (ts_dev
->wires
) {
400 ctrl
|= CNTRLREG_4WIRE
;
403 ctrl
|= CNTRLREG_5WIRE
;
406 ctrl
|= CNTRLREG_8WIRE
;
409 tscadc_writel(ts_dev
, REG_CTRL
, ctrl
);
411 tscadc_idle_config(ts_dev
);
412 tscadc_writel(ts_dev
, REG_IRQENABLE
, IRQENB_FIFO1THRES
);
413 tscadc_step_config(ts_dev
);
414 tscadc_writel(ts_dev
, REG_FIFO1THR
, 6);
416 ctrl
|= CNTRLREG_TSCSSENB
;
417 tscadc_writel(ts_dev
, REG_CTRL
, ctrl
);
419 input_dev
->name
= "ti-tsc-adc";
420 input_dev
->dev
.parent
= &pdev
->dev
;
422 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
423 input_dev
->keybit
[BIT_WORD(BTN_TOUCH
)] = BIT_MASK(BTN_TOUCH
);
425 input_set_abs_params(input_dev
, ABS_X
, 0, MAX_12BIT
, 0, 0);
426 input_set_abs_params(input_dev
, ABS_Y
, 0, MAX_12BIT
, 0, 0);
427 input_set_abs_params(input_dev
, ABS_PRESSURE
, 0, MAX_12BIT
, 0, 0);
429 /* register to the input system */
430 err
= input_register_device(input_dev
);
432 goto err_disable_clk
;
434 platform_set_drvdata(pdev
, ts_dev
);
438 clk_disable(ts_dev
->tsc_ick
);
439 clk_put(ts_dev
->tsc_ick
);
441 free_irq(ts_dev
->irq
, ts_dev
);
443 iounmap(ts_dev
->tsc_base
);
444 err_release_mem_region
:
445 release_mem_region(res
->start
, resource_size(res
));
447 input_free_device(input_dev
);
452 static int __devexit
tscadc_remove(struct platform_device
*pdev
)
454 struct tscadc
*ts_dev
= platform_get_drvdata(pdev
);
455 struct resource
*res
;
457 free_irq(ts_dev
->irq
, ts_dev
);
459 input_unregister_device(ts_dev
->input
);
461 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
462 iounmap(ts_dev
->tsc_base
);
463 release_mem_region(res
->start
, resource_size(res
));
465 clk_disable(ts_dev
->tsc_ick
);
466 clk_put(ts_dev
->tsc_ick
);
470 platform_set_drvdata(pdev
, NULL
);
474 static struct platform_driver ti_tsc_driver
= {
475 .probe
= tscadc_probe
,
476 .remove
= __devexit_p(tscadc_remove
),
479 .owner
= THIS_MODULE
,
482 module_platform_driver(ti_tsc_driver
);
484 MODULE_DESCRIPTION("TI touchscreen controller driver");
485 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
486 MODULE_LICENSE("GPL");