aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig37
-rw-r--r--drivers/input/touchscreen/Makefile4
-rw-r--r--drivers/input/touchscreen/ads7846.c25
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c47
-rw-r--r--drivers/input/touchscreen/dynapro.c206
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c457
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c11
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c104
8 files changed, 855 insertions, 36 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 8cc453c85ea7..32fc8ba039aa 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -111,6 +111,18 @@ config TOUCHSCREEN_DA9034
111 Say Y here to enable the support for the touchscreen found 111 Say Y here to enable the support for the touchscreen found
112 on Dialog Semiconductor DA9034 PMIC. 112 on Dialog Semiconductor DA9034 PMIC.
113 113
114config TOUCHSCREEN_DYNAPRO
115 tristate "Dynapro serial touchscreen"
116 select SERIO
117 help
118 Say Y here if you have a Dynapro serial touchscreen connected to
119 your system.
120
121 If unsure, say N.
122
123 To compile this driver as a module, choose M here: the
124 module will be called dynapro.
125
114config TOUCHSCREEN_EETI 126config TOUCHSCREEN_EETI
115 tristate "EETI touchscreen panel support" 127 tristate "EETI touchscreen panel support"
116 depends on I2C 128 depends on I2C
@@ -133,6 +145,18 @@ config TOUCHSCREEN_FUJITSU
133 To compile this driver as a module, choose M here: the 145 To compile this driver as a module, choose M here: the
134 module will be called fujitsu-ts. 146 module will be called fujitsu-ts.
135 147
148config TOUCHSCREEN_S3C2410
149 tristate "Samsung S3C2410 touchscreen input driver"
150 depends on ARCH_S3C2410
151 select S3C24XX_ADC
152 help
153 Say Y here if you have the s3c2410 touchscreen.
154
155 If unsure, say N.
156
157 To compile this driver as a module, choose M here: the
158 module will be called s3c2410_ts.
159
136config TOUCHSCREEN_GUNZE 160config TOUCHSCREEN_GUNZE
137 tristate "Gunze AHL-51S touchscreen" 161 tristate "Gunze AHL-51S touchscreen"
138 select SERIO 162 select SERIO
@@ -297,7 +321,7 @@ config TOUCHSCREEN_TOUCHWIN
297 321
298config TOUCHSCREEN_ATMEL_TSADCC 322config TOUCHSCREEN_ATMEL_TSADCC
299 tristate "Atmel Touchscreen Interface" 323 tristate "Atmel Touchscreen Interface"
300 depends on ARCH_AT91SAM9RL 324 depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
301 help 325 help
302 Say Y here if you have a 4-wire touchscreen connected to the 326 Say Y here if you have a 4-wire touchscreen connected to the
303 ADC Controller on your Atmel SoC (such as the AT91SAM9RL). 327 ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
@@ -418,6 +442,7 @@ config TOUCHSCREEN_USB_COMPOSITE
418 - IdealTEK URTC1000 442 - IdealTEK URTC1000
419 - GoTop Super_Q2/GogoPen/PenPower tablets 443 - GoTop Super_Q2/GogoPen/PenPower tablets
420 - JASTEC USB Touch Controller/DigiTech DTR-02U 444 - JASTEC USB Touch Controller/DigiTech DTR-02U
445 - Zytronic controllers
421 446
422 Have a look at <http://linux.chapter7.ch/touchkit/> for 447 Have a look at <http://linux.chapter7.ch/touchkit/> for
423 a usage description and the required user-space stuff. 448 a usage description and the required user-space stuff.
@@ -490,6 +515,16 @@ config TOUCHSCREEN_USB_E2I
490 bool "e2i Touchscreen controller (e.g. from Mimo 740)" 515 bool "e2i Touchscreen controller (e.g. from Mimo 740)"
491 depends on TOUCHSCREEN_USB_COMPOSITE 516 depends on TOUCHSCREEN_USB_COMPOSITE
492 517
518config TOUCHSCREEN_USB_ZYTRONIC
519 default y
520 bool "Zytronic controller" if EMBEDDED
521 depends on TOUCHSCREEN_USB_COMPOSITE
522
523config TOUCHSCREEN_USB_ETT_TC5UH
524 default y
525 bool "ET&T TC5UH touchscreen controler support" if EMBEDDED
526 depends on TOUCHSCREEN_USB_COMPOSITE
527
493config TOUCHSCREEN_TOUCHIT213 528config TOUCHSCREEN_TOUCHIT213
494 tristate "Sahara TouchIT-213 touchscreen" 529 tristate "Sahara TouchIT-213 touchscreen"
495 select SERIO 530 select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 15fa62cffc77..f1f59c9e1211 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
12obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o 12obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
13obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 13obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
14obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o 14obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
15obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
15obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 16obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
16obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o 17obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
17obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o 18obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
@@ -25,7 +26,9 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
25obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o 26obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
26obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o 27obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
27obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o 28obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
29obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
28obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o 30obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
31obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
29obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o 32obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
30obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o 33obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
31obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o 34obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
@@ -41,4 +44,3 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o
41obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o 44obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
42obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o 45obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
43obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o 46obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
44obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 09c810999b92..52d2ca147d8f 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -29,10 +29,9 @@
29#include <linux/spi/ads7846.h> 29#include <linux/spi/ads7846.h>
30#include <asm/irq.h> 30#include <asm/irq.h>
31 31
32
33/* 32/*
34 * This code has been heavily tested on a Nokia 770, and lightly 33 * This code has been heavily tested on a Nokia 770, and lightly
35 * tested on other ads7846 devices (OSK/Mistral, Lubbock). 34 * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz).
36 * TSC2046 is just newer ads7846 silicon. 35 * TSC2046 is just newer ads7846 silicon.
37 * Support for ads7843 tested on Atmel at91sam926x-EK. 36 * Support for ads7843 tested on Atmel at91sam926x-EK.
38 * Support for ads7845 has only been stubbed in. 37 * Support for ads7845 has only been stubbed in.
@@ -43,7 +42,7 @@
43 * have to maintain our own SW IRQ disabled status. This should be 42 * have to maintain our own SW IRQ disabled status. This should be
44 * removed as soon as the affected platform's IRQ handling is fixed. 43 * removed as soon as the affected platform's IRQ handling is fixed.
45 * 44 *
46 * app note sbaa036 talks in more detail about accurate sampling... 45 * App note sbaa036 talks in more detail about accurate sampling...
47 * that ought to help in situations like LCDs inducing noise (which 46 * that ought to help in situations like LCDs inducing noise (which
48 * can also be helped by using synch signals) and more generally. 47 * can also be helped by using synch signals) and more generally.
49 * This driver tries to utilize the measures described in the app 48 * This driver tries to utilize the measures described in the app
@@ -566,10 +565,8 @@ static void ads7846_rx(void *ads)
566 * once more the measurement 565 * once more the measurement
567 */ 566 */
568 if (packet->tc.ignore || Rt > ts->pressure_max) { 567 if (packet->tc.ignore || Rt > ts->pressure_max) {
569#ifdef VERBOSE 568 dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
570 pr_debug("%s: ignored %d pressure %d\n", 569 packet->tc.ignore, Rt);
571 dev_name(&ts->spi->dev), packet->tc.ignore, Rt);
572#endif
573 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 570 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
574 HRTIMER_MODE_REL); 571 HRTIMER_MODE_REL);
575 return; 572 return;
@@ -598,9 +595,7 @@ static void ads7846_rx(void *ads)
598 if (!ts->pendown) { 595 if (!ts->pendown) {
599 input_report_key(input, BTN_TOUCH, 1); 596 input_report_key(input, BTN_TOUCH, 1);
600 ts->pendown = 1; 597 ts->pendown = 1;
601#ifdef VERBOSE 598 dev_vdbg(&ts->spi->dev, "DOWN\n");
602 dev_dbg(&ts->spi->dev, "DOWN\n");
603#endif
604 } 599 }
605 600
606 if (ts->swap_xy) 601 if (ts->swap_xy)
@@ -608,12 +603,10 @@ static void ads7846_rx(void *ads)
608 603
609 input_report_abs(input, ABS_X, x); 604 input_report_abs(input, ABS_X, x);
610 input_report_abs(input, ABS_Y, y); 605 input_report_abs(input, ABS_Y, y);
611 input_report_abs(input, ABS_PRESSURE, Rt); 606 input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);
612 607
613 input_sync(input); 608 input_sync(input);
614#ifdef VERBOSE 609 dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
615 dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
616#endif
617 } 610 }
618 611
619 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 612 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
@@ -723,9 +716,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
723 input_sync(input); 716 input_sync(input);
724 717
725 ts->pendown = 0; 718 ts->pendown = 0;
726#ifdef VERBOSE 719 dev_vdbg(&ts->spi->dev, "UP\n");
727 dev_dbg(&ts->spi->dev, "UP\n");
728#endif
729 } 720 }
730 721
731 /* measurement cycle ended */ 722 /* measurement cycle ended */
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index 9c7fce4d74d0..3d9b5166ebe9 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -22,6 +22,8 @@
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <mach/board.h>
26#include <mach/cpu.h>
25 27
26/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ 28/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
27 29
@@ -36,7 +38,9 @@
36#define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ 38#define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */
37#define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ 39#define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */
38#define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ 40#define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */
41#define ATMEL_TSADCC_PRES (1 << 7) /* Pressure Measurement Selection */
39#define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ 42#define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */
43#define ATMEL_TSADCC_EPRESCAL (0xff << 8) /* Prescalar Rate Selection (Extended) */
40#define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ 44#define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */
41#define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ 45#define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */
42#define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ 46#define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */
@@ -84,7 +88,13 @@
84#define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ 88#define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */
85#define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ 89#define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */
86 90
87#define ADC_CLOCK 1000000 91#define ATMEL_TSADCC_XPOS 0x50
92#define ATMEL_TSADCC_Z1DAT 0x54
93#define ATMEL_TSADCC_Z2DAT 0x58
94
95#define PRESCALER_VAL(x) ((x) >> 8)
96
97#define ADC_DEFAULT_CLOCK 100000
88 98
89struct atmel_tsadcc { 99struct atmel_tsadcc {
90 struct input_dev *input; 100 struct input_dev *input;
@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
172 struct atmel_tsadcc *ts_dev; 182 struct atmel_tsadcc *ts_dev;
173 struct input_dev *input_dev; 183 struct input_dev *input_dev;
174 struct resource *res; 184 struct resource *res;
185 struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
175 int err = 0; 186 int err = 0;
176 unsigned int prsc; 187 unsigned int prsc;
177 unsigned int reg; 188 unsigned int reg;
@@ -242,31 +253,49 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
242 input_dev->phys = ts_dev->phys; 253 input_dev->phys = ts_dev->phys;
243 input_dev->dev.parent = &pdev->dev; 254 input_dev->dev.parent = &pdev->dev;
244 255
245 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 256 __set_bit(EV_ABS, input_dev->evbit);
246 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
247
248 input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); 257 input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
249 input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); 258 input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
250 259
260 input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
261
251 /* clk_enable() always returns 0, no need to check it */ 262 /* clk_enable() always returns 0, no need to check it */
252 clk_enable(ts_dev->clk); 263 clk_enable(ts_dev->clk);
253 264
254 prsc = clk_get_rate(ts_dev->clk); 265 prsc = clk_get_rate(ts_dev->clk);
255 dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); 266 dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
256 267
257 prsc = prsc / ADC_CLOCK / 2 - 1; 268 if (!pdata)
269 goto err_fail;
270
271 if (!pdata->adc_clock)
272 pdata->adc_clock = ADC_DEFAULT_CLOCK;
273
274 prsc = (prsc / (2 * pdata->adc_clock)) - 1;
275
276 /* saturate if this value is too high */
277 if (cpu_is_at91sam9rl()) {
278 if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
279 prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
280 } else {
281 if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
282 prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
283 }
284
285 dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
258 286
259 reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | 287 reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE |
260 ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ 288 ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */
261 ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ 289 ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */
262 ((prsc << 8) & ATMEL_TSADCC_PRESCAL) | /* PRESCAL */ 290 (prsc << 8) |
263 ((0x13 << 16) & ATMEL_TSADCC_STARTUP) | /* STARTUP */ 291 ((0x26 << 16) & ATMEL_TSADCC_STARTUP) |
264 ((0x0F << 28) & ATMEL_TSADCC_PENDBC); /* PENDBC */ 292 ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
265 293
266 atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); 294 atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
267 atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); 295 atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
268 atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); 296 atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
269 atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM); 297 atmel_tsadcc_write(ATMEL_TSADCC_TSR,
298 (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
270 299
271 atmel_tsadcc_read(ATMEL_TSADCC_SR); 300 atmel_tsadcc_read(ATMEL_TSADCC_SR);
272 atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); 301 atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c
new file mode 100644
index 000000000000..455353908bdf
--- /dev/null
+++ b/drivers/input/touchscreen/dynapro.c
@@ -0,0 +1,206 @@
1/*
2 * Dynapro serial touchscreen driver
3 *
4 * Copyright (c) 2009 Tias Guns
5 * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and
6 * Richard Lemon
7 *
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
14 */
15
16/*
17 * 2009/09/19 Tias Guns <tias@ulyssis.org>
18 * Copied inexio.c and edited for Dynapro protocol (from retired Xorg module)
19 */
20
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/input.h>
26#include <linux/serio.h>
27#include <linux/init.h>
28
29#define DRIVER_DESC "Dynapro serial touchscreen driver"
30
31MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>");
32MODULE_DESCRIPTION(DRIVER_DESC);
33MODULE_LICENSE("GPL");
34
35/*
36 * Definitions & global arrays.
37 */
38
39#define DYNAPRO_FORMAT_TOUCH_BIT 0x40
40#define DYNAPRO_FORMAT_LENGTH 3
41#define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80
42
43#define DYNAPRO_MIN_XC 0
44#define DYNAPRO_MAX_XC 0x3ff
45#define DYNAPRO_MIN_YC 0
46#define DYNAPRO_MAX_YC 0x3ff
47
48#define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4))
49#define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7))
50#define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0])
51
52/*
53 * Per-touchscreen data.
54 */
55
56struct dynapro {
57 struct input_dev *dev;
58 struct serio *serio;
59 int idx;
60 unsigned char data[DYNAPRO_FORMAT_LENGTH];
61 char phys[32];
62};
63
64static void dynapro_process_data(struct dynapro *pdynapro)
65{
66 struct input_dev *dev = pdynapro->dev;
67
68 if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) {
69 input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data));
70 input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data));
71 input_report_key(dev, BTN_TOUCH,
72 DYNAPRO_GET_TOUCHED(pdynapro->data));
73 input_sync(dev);
74
75 pdynapro->idx = 0;
76 }
77}
78
79static irqreturn_t dynapro_interrupt(struct serio *serio,
80 unsigned char data, unsigned int flags)
81{
82 struct dynapro *pdynapro = serio_get_drvdata(serio);
83
84 pdynapro->data[pdynapro->idx] = data;
85
86 if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0])
87 dynapro_process_data(pdynapro);
88 else
89 dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",
90 pdynapro->data[0]);
91
92 return IRQ_HANDLED;
93}
94
95static void dynapro_disconnect(struct serio *serio)
96{
97 struct dynapro *pdynapro = serio_get_drvdata(serio);
98
99 input_get_device(pdynapro->dev);
100 input_unregister_device(pdynapro->dev);
101 serio_close(serio);
102 serio_set_drvdata(serio, NULL);
103 input_put_device(pdynapro->dev);
104 kfree(pdynapro);
105}
106
107/*
108 * dynapro_connect() is the routine that is called when someone adds a
109 * new serio device that supports dynapro protocol and registers it as
110 * an input device. This is usually accomplished using inputattach.
111 */
112
113static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
114{
115 struct dynapro *pdynapro;
116 struct input_dev *input_dev;
117 int err;
118
119 pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL);
120 input_dev = input_allocate_device();
121 if (!pdynapro || !input_dev) {
122 err = -ENOMEM;
123 goto fail1;
124 }
125
126 pdynapro->serio = serio;
127 pdynapro->dev = input_dev;
128 snprintf(pdynapro->phys, sizeof(pdynapro->phys),
129 "%s/input0", serio->phys);
130
131 input_dev->name = "Dynapro Serial TouchScreen";
132 input_dev->phys = pdynapro->phys;
133 input_dev->id.bustype = BUS_RS232;
134 input_dev->id.vendor = SERIO_DYNAPRO;
135 input_dev->id.product = 0;
136 input_dev->id.version = 0x0001;
137 input_dev->dev.parent = &serio->dev;
138 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
139 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
140 input_set_abs_params(pdynapro->dev, ABS_X,
141 DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0);
142 input_set_abs_params(pdynapro->dev, ABS_Y,
143 DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0);
144
145 serio_set_drvdata(serio, pdynapro);
146
147 err = serio_open(serio, drv);
148 if (err)
149 goto fail2;
150
151 err = input_register_device(pdynapro->dev);
152 if (err)
153 goto fail3;
154
155 return 0;
156
157 fail3: serio_close(serio);
158 fail2: serio_set_drvdata(serio, NULL);
159 fail1: input_free_device(input_dev);
160 kfree(pdynapro);
161 return err;
162}
163
164/*
165 * The serio driver structure.
166 */
167
168static struct serio_device_id dynapro_serio_ids[] = {
169 {
170 .type = SERIO_RS232,
171 .proto = SERIO_DYNAPRO,
172 .id = SERIO_ANY,
173 .extra = SERIO_ANY,
174 },
175 { 0 }
176};
177
178MODULE_DEVICE_TABLE(serio, dynapro_serio_ids);
179
180static struct serio_driver dynapro_drv = {
181 .driver = {
182 .name = "dynapro",
183 },
184 .description = DRIVER_DESC,
185 .id_table = dynapro_serio_ids,
186 .interrupt = dynapro_interrupt,
187 .connect = dynapro_connect,
188 .disconnect = dynapro_disconnect,
189};
190
191/*
192 * The functions for inserting/removing us as a module.
193 */
194
195static int __init dynapro_init(void)
196{
197 return serio_register_driver(&dynapro_drv);
198}
199
200static void __exit dynapro_exit(void)
201{
202 serio_unregister_driver(&dynapro_drv);
203}
204
205module_init(dynapro_init);
206module_exit(dynapro_exit);
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
new file mode 100644
index 000000000000..6386b441ef85
--- /dev/null
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -0,0 +1,457 @@
1/*
2 * Samsung S3C24XX touchscreen driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the term of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Copyright 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
19 * Copyright 2008 Ben Dooks <ben-linux@fluff.org>
20 * Copyright 2009 Simtec Electronics <linux@simtec.co.uk>
21 *
22 * Additional work by Herbert Pötzl <herbert@13thfloor.at> and
23 * Harald Welte <laforge@openmoko.org>
24 */
25
26#include <linux/errno.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/gpio.h>
31#include <linux/input.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/interrupt.h>
35#include <linux/platform_device.h>
36#include <linux/clk.h>
37#include <linux/io.h>
38
39#include <plat/adc.h>
40#include <plat/regs-adc.h>
41
42#include <mach/regs-gpio.h>
43#include <mach/ts.h>
44
45#define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
46
47#define INT_DOWN (0)
48#define INT_UP (1 << 8)
49
50#define WAIT4INT (S3C2410_ADCTSC_YM_SEN | \
51 S3C2410_ADCTSC_YP_SEN | \
52 S3C2410_ADCTSC_XP_SEN | \
53 S3C2410_ADCTSC_XY_PST(3))
54
55#define AUTOPST (S3C2410_ADCTSC_YM_SEN | \
56 S3C2410_ADCTSC_YP_SEN | \
57 S3C2410_ADCTSC_XP_SEN | \
58 S3C2410_ADCTSC_AUTO_PST | \
59 S3C2410_ADCTSC_XY_PST(0))
60
61/* Per-touchscreen data. */
62
63/**
64 * struct s3c2410ts - driver touchscreen state.
65 * @client: The ADC client we registered with the core driver.
66 * @dev: The device we are bound to.
67 * @input: The input device we registered with the input subsystem.
68 * @clock: The clock for the adc.
69 * @io: Pointer to the IO base.
70 * @xp: The accumulated X position data.
71 * @yp: The accumulated Y position data.
72 * @irq_tc: The interrupt number for pen up/down interrupt
73 * @count: The number of samples collected.
74 * @shift: The log2 of the maximum count to read in one go.
75 */
76struct s3c2410ts {
77 struct s3c_adc_client *client;
78 struct device *dev;
79 struct input_dev *input;
80 struct clk *clock;
81 void __iomem *io;
82 unsigned long xp;
83 unsigned long yp;
84 int irq_tc;
85 int count;
86 int shift;
87};
88
89static struct s3c2410ts ts;
90
91/**
92 * s3c2410_ts_connect - configure gpio for s3c2410 systems
93 *
94 * Configure the GPIO for the S3C2410 system, where we have external FETs
95 * connected to the device (later systems such as the S3C2440 integrate
96 * these into the device).
97*/
98static inline void s3c2410_ts_connect(void)
99{
100 s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
101 s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
102 s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
103 s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
104}
105
106/**
107 * get_down - return the down state of the pen
108 * @data0: The data read from ADCDAT0 register.
109 * @data1: The data read from ADCDAT1 register.
110 *
111 * Return non-zero if both readings show that the pen is down.
112 */
113static inline bool get_down(unsigned long data0, unsigned long data1)
114{
115 /* returns true if both data values show stylus down */
116 return (!(data0 & S3C2410_ADCDAT0_UPDOWN) &&
117 !(data1 & S3C2410_ADCDAT0_UPDOWN));
118}
119
120static void touch_timer_fire(unsigned long data)
121{
122 unsigned long data0;
123 unsigned long data1;
124 bool down;
125
126 data0 = readl(ts.io + S3C2410_ADCDAT0);
127 data1 = readl(ts.io + S3C2410_ADCDAT1);
128
129 down = get_down(data0, data1);
130
131 if (ts.count == (1 << ts.shift)) {
132 ts.xp >>= ts.shift;
133 ts.yp >>= ts.shift;
134
135 dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
136 __func__, ts.xp, ts.yp, ts.count);
137
138 input_report_abs(ts.input, ABS_X, ts.xp);
139 input_report_abs(ts.input, ABS_Y, ts.yp);
140
141 input_report_key(ts.input, BTN_TOUCH, 1);
142 input_sync(ts.input);
143
144 ts.xp = 0;
145 ts.yp = 0;
146 ts.count = 0;
147 }
148
149 if (down) {
150 s3c_adc_start(ts.client, 0, 1 << ts.shift);
151 } else {
152 ts.count = 0;
153
154 input_report_key(ts.input, BTN_TOUCH, 0);
155 input_sync(ts.input);
156
157 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
158 }
159}
160
161static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0);
162
163/**
164 * stylus_irq - touchscreen stylus event interrupt
165 * @irq: The interrupt number
166 * @dev_id: The device ID.
167 *
168 * Called when the IRQ_TC is fired for a pen up or down event.
169 */
170static irqreturn_t stylus_irq(int irq, void *dev_id)
171{
172 unsigned long data0;
173 unsigned long data1;
174 bool down;
175
176 data0 = readl(ts.io + S3C2410_ADCDAT0);
177 data1 = readl(ts.io + S3C2410_ADCDAT1);
178
179 down = get_down(data0, data1);
180
181 /* TODO we should never get an interrupt with down set while
182 * the timer is running, but maybe we ought to verify that the
183 * timer isn't running anyways. */
184
185 if (down)
186 s3c_adc_start(ts.client, 0, 1 << ts.shift);
187 else
188 dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count);
189
190 return IRQ_HANDLED;
191}
192
193/**
194 * s3c24xx_ts_conversion - ADC conversion callback
195 * @client: The client that was registered with the ADC core.
196 * @data0: The reading from ADCDAT0.
197 * @data1: The reading from ADCDAT1.
198 * @left: The number of samples left.
199 *
200 * Called when a conversion has finished.
201 */
202static void s3c24xx_ts_conversion(struct s3c_adc_client *client,
203 unsigned data0, unsigned data1,
204 unsigned *left)
205{
206 dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1);
207
208 ts.xp += data0;
209 ts.yp += data1;
210
211 ts.count++;
212
213 /* From tests, it seems that it is unlikely to get a pen-up
214 * event during the conversion process which means we can
215 * ignore any pen-up events with less than the requisite
216 * count done.
217 *
218 * In several thousand conversions, no pen-ups where detected
219 * before count completed.
220 */
221}
222
223/**
224 * s3c24xx_ts_select - ADC selection callback.
225 * @client: The client that was registered with the ADC core.
226 * @select: The reason for select.
227 *
228 * Called when the ADC core selects (or deslects) us as a client.
229 */
230static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select)
231{
232 if (select) {
233 writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
234 ts.io + S3C2410_ADCTSC);
235 } else {
236 mod_timer(&touch_timer, jiffies+1);
237 writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
238 }
239}
240
241/**
242 * s3c2410ts_probe - device core probe entry point
243 * @pdev: The device we are being bound to.
244 *
245 * Initialise, find and allocate any resources we need to run and then
246 * register with the ADC and input systems.
247 */
248static int __devinit s3c2410ts_probe(struct platform_device *pdev)
249{
250 struct s3c2410_ts_mach_info *info;
251 struct device *dev = &pdev->dev;
252 struct input_dev *input_dev;
253 struct resource *res;
254 int ret = -EINVAL;
255
256 /* Initialise input stuff */
257 memset(&ts, 0, sizeof(struct s3c2410ts));
258
259 ts.dev = dev;
260
261 info = pdev->dev.platform_data;
262 if (!info) {
263 dev_err(dev, "no platform data, cannot attach\n");
264 return -EINVAL;
265 }
266
267 dev_dbg(dev, "initialising touchscreen\n");
268
269 ts.clock = clk_get(dev, "adc");
270 if (IS_ERR(ts.clock)) {
271 dev_err(dev, "cannot get adc clock source\n");
272 return -ENOENT;
273 }
274
275 clk_enable(ts.clock);
276 dev_dbg(dev, "got and enabled clocks\n");
277
278 ts.irq_tc = ret = platform_get_irq(pdev, 0);
279 if (ret < 0) {
280 dev_err(dev, "no resource for interrupt\n");
281 goto err_clk;
282 }
283
284 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
285 if (!res) {
286 dev_err(dev, "no resource for registers\n");
287 ret = -ENOENT;
288 goto err_clk;
289 }
290
291 ts.io = ioremap(res->start, resource_size(res));
292 if (ts.io == NULL) {
293 dev_err(dev, "cannot map registers\n");
294 ret = -ENOMEM;
295 goto err_clk;
296 }
297
298 /* Configure the touchscreen external FETs on the S3C2410 */
299 if (!platform_get_device_id(pdev)->driver_data)
300 s3c2410_ts_connect();
301
302 ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
303 s3c24xx_ts_conversion, 1);
304 if (IS_ERR(ts.client)) {
305 dev_err(dev, "failed to register adc client\n");
306 ret = PTR_ERR(ts.client);
307 goto err_iomap;
308 }
309
310 /* Initialise registers */
311 if ((info->delay & 0xffff) > 0)
312 writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
313
314 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
315
316 input_dev = input_allocate_device();
317 if (!input_dev) {
318 dev_err(dev, "Unable to allocate the input device !!\n");
319 ret = -ENOMEM;
320 goto err_iomap;
321 }
322
323 ts.input = input_dev;
324 ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
325 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
326 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
327 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
328
329 ts.input->name = "S3C24XX TouchScreen";
330 ts.input->id.bustype = BUS_HOST;
331 ts.input->id.vendor = 0xDEAD;
332 ts.input->id.product = 0xBEEF;
333 ts.input->id.version = 0x0102;
334
335 ts.shift = info->oversampling_shift;
336
337 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
338 "s3c2410_ts_pen", ts.input);
339 if (ret) {
340 dev_err(dev, "cannot get TC interrupt\n");
341 goto err_inputdev;
342 }
343
344 dev_info(dev, "driver attached, registering input device\n");
345
346 /* All went ok, so register to the input system */
347 ret = input_register_device(ts.input);
348 if (ret < 0) {
349 dev_err(dev, "failed to register input device\n");
350 ret = -EIO;
351 goto err_tcirq;
352 }
353
354 return 0;
355
356 err_tcirq:
357 free_irq(ts.irq_tc, ts.input);
358 err_inputdev:
359 input_unregister_device(ts.input);
360 err_iomap:
361 iounmap(ts.io);
362 err_clk:
363 del_timer_sync(&touch_timer);
364 clk_put(ts.clock);
365 return ret;
366}
367
368/**
369 * s3c2410ts_remove - device core removal entry point
370 * @pdev: The device we are being removed from.
371 *
372 * Free up our state ready to be removed.
373 */
374static int __devexit s3c2410ts_remove(struct platform_device *pdev)
375{
376 free_irq(ts.irq_tc, ts.input);
377 del_timer_sync(&touch_timer);
378
379 clk_disable(ts.clock);
380 clk_put(ts.clock);
381
382 input_unregister_device(ts.input);
383 iounmap(ts.io);
384
385 return 0;
386}
387
388#ifdef CONFIG_PM
389static int s3c2410ts_suspend(struct device *dev)
390{
391 writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC);
392 disable_irq(ts.irq_tc);
393 clk_disable(ts.clock);
394
395 return 0;
396}
397
398static int s3c2410ts_resume(struct device *dev)
399{
400 struct platform_device *pdev = to_platform_device(dev);
401 struct s3c2410_ts_mach_info *info = pdev->dev.platform_data;
402
403 clk_enable(ts.clock);
404
405 /* Initialise registers */
406 if ((info->delay & 0xffff) > 0)
407 writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
408
409 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
410
411 return 0;
412}
413
414static struct dev_pm_ops s3c_ts_pmops = {
415 .suspend = s3c2410ts_suspend,
416 .resume = s3c2410ts_resume,
417};
418#endif
419
420static struct platform_device_id s3cts_driver_ids[] = {
421 { "s3c2410-ts", 0 },
422 { "s3c2440-ts", 1 },
423 { }
424};
425MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
426
427static struct platform_driver s3c_ts_driver = {
428 .driver = {
429 .name = "s3c24xx-ts",
430 .owner = THIS_MODULE,
431#ifdef CONFIG_PM
432 .pm = &s3c_ts_pmops,
433#endif
434 },
435 .id_table = s3cts_driver_ids,
436 .probe = s3c2410ts_probe,
437 .remove = __devexit_p(s3c2410ts_remove),
438};
439
440static int __init s3c2410ts_init(void)
441{
442 return platform_driver_register(&s3c_ts_driver);
443}
444
445static void __exit s3c2410ts_exit(void)
446{
447 platform_driver_unregister(&s3c_ts_driver);
448}
449
450module_init(s3c2410ts_init);
451module_exit(s3c2410ts_exit);
452
453MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
454 "Ben Dooks <ben@simtec.co.uk>, "
455 "Simtec Electronics <linux@simtec.co.uk>");
456MODULE_DESCRIPTION("S3C24XX Touchscreen driver");
457MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 095f84b1f56e..89dcbe7b4b02 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -355,10 +355,13 @@ static int ucb1400_ts_probe(struct platform_device *dev)
355 goto err; 355 goto err;
356 } 356 }
357 357
358 error = ucb1400_ts_detect_irq(ucb); 358 /* Only in case the IRQ line wasn't supplied, try detecting it */
359 if (error) { 359 if (ucb->irq < 0) {
360 printk(KERN_ERR "UCB1400: IRQ probe failed\n"); 360 error = ucb1400_ts_detect_irq(ucb);
361 goto err_free_devs; 361 if (error) {
362 printk(KERN_ERR "UCB1400: IRQ probe failed\n");
363 goto err_free_devs;
364 }
362 } 365 }
363 366
364 init_waitqueue_head(&ucb->ts_wait); 367 init_waitqueue_head(&ucb->ts_wait);
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 68ece5801a58..09a5e7341bd5 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -14,6 +14,7 @@
14 * - General Touch 14 * - General Touch
15 * - GoTop Super_Q2/GogoPen/PenPower tablets 15 * - GoTop Super_Q2/GogoPen/PenPower tablets
16 * - JASTEC USB touch controller/DigiTech DTR-02U 16 * - JASTEC USB touch controller/DigiTech DTR-02U
17 * - Zytronic capacitive touchscreen
17 * 18 *
18 * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> 19 * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
19 * Copyright (C) by Todd E. Johnson (mtouchusb.c) 20 * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -73,6 +74,15 @@ struct usbtouch_device_info {
73 int min_press, max_press; 74 int min_press, max_press;
74 int rept_size; 75 int rept_size;
75 76
77 /*
78 * Always service the USB devices irq not just when the input device is
79 * open. This is useful when devices have a watchdog which prevents us
80 * from periodically polling the device. Leave this unset unless your
81 * touchscreen device requires it, as it does consume more of the USB
82 * bandwidth.
83 */
84 bool irq_always;
85
76 void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); 86 void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
77 87
78 /* 88 /*
@@ -121,6 +131,8 @@ enum {
121 DEVTYPE_GOTOP, 131 DEVTYPE_GOTOP,
122 DEVTYPE_JASTEC, 132 DEVTYPE_JASTEC,
123 DEVTYPE_E2I, 133 DEVTYPE_E2I,
134 DEVTYPE_ZYTRONIC,
135 DEVTYPE_TC5UH,
124}; 136};
125 137
126#define USB_DEVICE_HID_CLASS(vend, prod) \ 138#define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -201,6 +213,15 @@ static struct usb_device_id usbtouch_devices[] = {
201#ifdef CONFIG_TOUCHSCREEN_USB_E2I 213#ifdef CONFIG_TOUCHSCREEN_USB_E2I
202 {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, 214 {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},
203#endif 215#endif
216
217#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
218 {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC},
219#endif
220
221#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
222 {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH},
223#endif
224
204 {} 225 {}
205}; 226};
206 227
@@ -538,6 +559,19 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
538} 559}
539#endif 560#endif
540 561
562/*****************************************************************************
563 * ET&T TC5UH part
564 */
565#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
566static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
567{
568 dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
569 dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
570 dev->touch = pkt[0] & 0x01;
571
572 return 1;
573}
574#endif
541 575
542/***************************************************************************** 576/*****************************************************************************
543 * IdealTEK URTC1000 Part 577 * IdealTEK URTC1000 Part
@@ -621,6 +655,39 @@ static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
621} 655}
622#endif 656#endif
623 657
658/*****************************************************************************
659 * Zytronic Part
660 */
661#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
662static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
663{
664 switch (pkt[0]) {
665 case 0x3A: /* command response */
666 dbg("%s: Command response %d", __func__, pkt[1]);
667 break;
668
669 case 0xC0: /* down */
670 dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
671 dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
672 dev->touch = 1;
673 dbg("%s: down %d,%d", __func__, dev->x, dev->y);
674 return 1;
675
676 case 0x80: /* up */
677 dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
678 dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
679 dev->touch = 0;
680 dbg("%s: up %d,%d", __func__, dev->x, dev->y);
681 return 1;
682
683 default:
684 dbg("%s: Unknown return %d", __func__, pkt[0]);
685 break;
686 }
687
688 return 0;
689}
690#endif
624 691
625/***************************************************************************** 692/*****************************************************************************
626 * the different device descriptors 693 * the different device descriptors
@@ -783,6 +850,29 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
783 .read_data = e2i_read_data, 850 .read_data = e2i_read_data,
784 }, 851 },
785#endif 852#endif
853
854#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
855 [DEVTYPE_ZYTRONIC] = {
856 .min_xc = 0x0,
857 .max_xc = 0x03ff,
858 .min_yc = 0x0,
859 .max_yc = 0x03ff,
860 .rept_size = 5,
861 .read_data = zytronic_read_data,
862 .irq_always = true,
863 },
864#endif
865
866#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
867 [DEVTYPE_TC5UH] = {
868 .min_xc = 0x0,
869 .max_xc = 0x0fff,
870 .min_yc = 0x0,
871 .max_yc = 0x0fff,
872 .rept_size = 5,
873 .read_data = tc5uh_read_data,
874 },
875#endif
786}; 876};
787 877
788 878
@@ -933,8 +1023,10 @@ static int usbtouch_open(struct input_dev *input)
933 1023
934 usbtouch->irq->dev = usbtouch->udev; 1024 usbtouch->irq->dev = usbtouch->udev;
935 1025
936 if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) 1026 if (!usbtouch->type->irq_always) {
937 return -EIO; 1027 if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
1028 return -EIO;
1029 }
938 1030
939 return 0; 1031 return 0;
940} 1032}
@@ -943,7 +1035,8 @@ static void usbtouch_close(struct input_dev *input)
943{ 1035{
944 struct usbtouch_usb *usbtouch = input_get_drvdata(input); 1036 struct usbtouch_usb *usbtouch = input_get_drvdata(input);
945 1037
946 usb_kill_urb(usbtouch->irq); 1038 if (!usbtouch->type->irq_always)
1039 usb_kill_urb(usbtouch->irq);
947} 1040}
948 1041
949 1042
@@ -1066,6 +1159,9 @@ static int usbtouch_probe(struct usb_interface *intf,
1066 1159
1067 usb_set_intfdata(intf, usbtouch); 1160 usb_set_intfdata(intf, usbtouch);
1068 1161
1162 if (usbtouch->type->irq_always)
1163 usb_submit_urb(usbtouch->irq, GFP_KERNEL);
1164
1069 return 0; 1165 return 0;
1070 1166
1071out_free_buffers: 1167out_free_buffers:
@@ -1087,7 +1183,7 @@ static void usbtouch_disconnect(struct usb_interface *intf)
1087 1183
1088 dbg("%s - usbtouch is initialized, cleaning up", __func__); 1184 dbg("%s - usbtouch is initialized, cleaning up", __func__);
1089 usb_set_intfdata(intf, NULL); 1185 usb_set_intfdata(intf, NULL);
1090 usb_kill_urb(usbtouch->irq); 1186 /* this will stop IO via close */
1091 input_unregister_device(usbtouch->input); 1187 input_unregister_device(usbtouch->input);
1092 usb_free_urb(usbtouch->irq); 1188 usb_free_urb(usbtouch->irq);
1093 usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); 1189 usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);