diff options
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 9 | ||||
-rw-r--r-- | drivers/input/touchscreen/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/ad7877.c | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/ad7879.c | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/pcap_ts.c | 271 | ||||
-rw-r--r-- | drivers/input/touchscreen/wm97xx-core.c | 3 |
7 files changed, 287 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6dfb0a2b0a7d..8cc453c85ea7 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -521,4 +521,13 @@ config TOUCHSCREEN_W90X900 | |||
521 | To compile this driver as a module, choose M here: the | 521 | To compile this driver as a module, choose M here: the |
522 | module will be called w90p910_ts. | 522 | module will be called w90p910_ts. |
523 | 523 | ||
524 | config TOUCHSCREEN_PCAP | ||
525 | tristate "Motorola PCAP touchscreen" | ||
526 | depends on EZX_PCAP | ||
527 | help | ||
528 | Say Y here if you have a Motorola EZX telephone and | ||
529 | want to enable support for the built-in touchscreen. | ||
530 | |||
531 | To compile this driver as a module, choose M here: the | ||
532 | module will be called pcap_ts. | ||
524 | endif | 533 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index a882ca16506b..15fa62cffc77 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -41,3 +41,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o | |||
41 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 41 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
42 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 42 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
43 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | 43 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o |
44 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index ecaeb7e8e75e..eb83939c705e 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -842,3 +842,4 @@ module_exit(ad7877_exit); | |||
842 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 842 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
843 | MODULE_DESCRIPTION("AD7877 touchscreen Driver"); | 843 | MODULE_DESCRIPTION("AD7877 touchscreen Driver"); |
844 | MODULE_LICENSE("GPL"); | 844 | MODULE_LICENSE("GPL"); |
845 | MODULE_ALIAS("spi:ad7877"); | ||
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index b965101074ec..c21e6d3a8844 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -781,3 +781,4 @@ module_exit(ad7879_exit); | |||
781 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 781 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
782 | MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); | 782 | MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); |
783 | MODULE_LICENSE("GPL"); | 783 | MODULE_LICENSE("GPL"); |
784 | MODULE_ALIAS("spi:ad7879"); | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index ba9d38c3f412..09c810999b92 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -1256,3 +1256,4 @@ module_exit(ads7846_exit); | |||
1256 | 1256 | ||
1257 | MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); | 1257 | MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); |
1258 | MODULE_LICENSE("GPL"); | 1258 | MODULE_LICENSE("GPL"); |
1259 | MODULE_ALIAS("spi:ads7846"); | ||
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c new file mode 100644 index 000000000000..67fcd33595de --- /dev/null +++ b/drivers/input/touchscreen/pcap_ts.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Driver for Motorola PCAP2 touchscreen as found in the EZX phone platform. | ||
3 | * | ||
4 | * Copyright (C) 2006 Harald Welte <laforge@openezx.org> | ||
5 | * Copyright (C) 2009 Daniel Ribeiro <drwyrm@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/fs.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/timer.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/mfd/ezx-pcap.h> | ||
23 | |||
24 | struct pcap_ts { | ||
25 | struct pcap_chip *pcap; | ||
26 | struct input_dev *input; | ||
27 | struct delayed_work work; | ||
28 | u16 x, y; | ||
29 | u16 pressure; | ||
30 | u8 read_state; | ||
31 | }; | ||
32 | |||
33 | #define SAMPLE_DELAY 20 /* msecs */ | ||
34 | |||
35 | #define X_AXIS_MIN 0 | ||
36 | #define X_AXIS_MAX 1023 | ||
37 | #define Y_AXIS_MAX X_AXIS_MAX | ||
38 | #define Y_AXIS_MIN X_AXIS_MIN | ||
39 | #define PRESSURE_MAX X_AXIS_MAX | ||
40 | #define PRESSURE_MIN X_AXIS_MIN | ||
41 | |||
42 | static void pcap_ts_read_xy(void *data, u16 res[2]) | ||
43 | { | ||
44 | struct pcap_ts *pcap_ts = data; | ||
45 | |||
46 | switch (pcap_ts->read_state) { | ||
47 | case PCAP_ADC_TS_M_PRESSURE: | ||
48 | /* pressure reading is unreliable */ | ||
49 | if (res[0] > PRESSURE_MIN && res[0] < PRESSURE_MAX) | ||
50 | pcap_ts->pressure = res[0]; | ||
51 | pcap_ts->read_state = PCAP_ADC_TS_M_XY; | ||
52 | schedule_delayed_work(&pcap_ts->work, 0); | ||
53 | break; | ||
54 | case PCAP_ADC_TS_M_XY: | ||
55 | pcap_ts->y = res[0]; | ||
56 | pcap_ts->x = res[1]; | ||
57 | if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX || | ||
58 | pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) { | ||
59 | /* pen has been released */ | ||
60 | input_report_abs(pcap_ts->input, ABS_PRESSURE, 0); | ||
61 | input_report_key(pcap_ts->input, BTN_TOUCH, 0); | ||
62 | |||
63 | pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY; | ||
64 | schedule_delayed_work(&pcap_ts->work, 0); | ||
65 | } else { | ||
66 | /* pen is touching the screen */ | ||
67 | input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x); | ||
68 | input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y); | ||
69 | input_report_key(pcap_ts->input, BTN_TOUCH, 1); | ||
70 | input_report_abs(pcap_ts->input, ABS_PRESSURE, | ||
71 | pcap_ts->pressure); | ||
72 | |||
73 | /* switch back to pressure read mode */ | ||
74 | pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE; | ||
75 | schedule_delayed_work(&pcap_ts->work, | ||
76 | msecs_to_jiffies(SAMPLE_DELAY)); | ||
77 | } | ||
78 | input_sync(pcap_ts->input); | ||
79 | break; | ||
80 | default: | ||
81 | dev_warn(&pcap_ts->input->dev, | ||
82 | "pcap_ts: Warning, unhandled read_state %d\n", | ||
83 | pcap_ts->read_state); | ||
84 | break; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static void pcap_ts_work(struct work_struct *work) | ||
89 | { | ||
90 | struct delayed_work *dw = container_of(work, struct delayed_work, work); | ||
91 | struct pcap_ts *pcap_ts = container_of(dw, struct pcap_ts, work); | ||
92 | u8 ch[2]; | ||
93 | |||
94 | pcap_set_ts_bits(pcap_ts->pcap, | ||
95 | pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); | ||
96 | |||
97 | if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) | ||
98 | return; | ||
99 | |||
100 | /* start adc conversion */ | ||
101 | ch[0] = PCAP_ADC_CH_TS_X1; | ||
102 | ch[1] = PCAP_ADC_CH_TS_Y1; | ||
103 | pcap_adc_async(pcap_ts->pcap, PCAP_ADC_BANK_1, 0, ch, | ||
104 | pcap_ts_read_xy, pcap_ts); | ||
105 | } | ||
106 | |||
107 | static irqreturn_t pcap_ts_event_touch(int pirq, void *data) | ||
108 | { | ||
109 | struct pcap_ts *pcap_ts = data; | ||
110 | |||
111 | if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) { | ||
112 | pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE; | ||
113 | schedule_delayed_work(&pcap_ts->work, 0); | ||
114 | } | ||
115 | return IRQ_HANDLED; | ||
116 | } | ||
117 | |||
118 | static int pcap_ts_open(struct input_dev *dev) | ||
119 | { | ||
120 | struct pcap_ts *pcap_ts = input_get_drvdata(dev); | ||
121 | |||
122 | pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY; | ||
123 | schedule_delayed_work(&pcap_ts->work, 0); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static void pcap_ts_close(struct input_dev *dev) | ||
129 | { | ||
130 | struct pcap_ts *pcap_ts = input_get_drvdata(dev); | ||
131 | |||
132 | cancel_delayed_work_sync(&pcap_ts->work); | ||
133 | |||
134 | pcap_ts->read_state = PCAP_ADC_TS_M_NONTS; | ||
135 | pcap_set_ts_bits(pcap_ts->pcap, | ||
136 | pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); | ||
137 | } | ||
138 | |||
139 | static int __devinit pcap_ts_probe(struct platform_device *pdev) | ||
140 | { | ||
141 | struct input_dev *input_dev; | ||
142 | struct pcap_ts *pcap_ts; | ||
143 | int err = -ENOMEM; | ||
144 | |||
145 | pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL); | ||
146 | if (!pcap_ts) | ||
147 | return err; | ||
148 | |||
149 | pcap_ts->pcap = dev_get_drvdata(pdev->dev.parent); | ||
150 | platform_set_drvdata(pdev, pcap_ts); | ||
151 | |||
152 | input_dev = input_allocate_device(); | ||
153 | if (!input_dev) | ||
154 | goto fail; | ||
155 | |||
156 | INIT_DELAYED_WORK(&pcap_ts->work, pcap_ts_work); | ||
157 | |||
158 | pcap_ts->read_state = PCAP_ADC_TS_M_NONTS; | ||
159 | pcap_set_ts_bits(pcap_ts->pcap, | ||
160 | pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); | ||
161 | |||
162 | pcap_ts->input = input_dev; | ||
163 | input_set_drvdata(input_dev, pcap_ts); | ||
164 | |||
165 | input_dev->name = "pcap-touchscreen"; | ||
166 | input_dev->phys = "pcap_ts/input0"; | ||
167 | input_dev->id.bustype = BUS_HOST; | ||
168 | input_dev->id.vendor = 0x0001; | ||
169 | input_dev->id.product = 0x0002; | ||
170 | input_dev->id.version = 0x0100; | ||
171 | input_dev->dev.parent = &pdev->dev; | ||
172 | input_dev->open = pcap_ts_open; | ||
173 | input_dev->close = pcap_ts_close; | ||
174 | |||
175 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
176 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
177 | input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); | ||
178 | input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); | ||
179 | input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, | ||
180 | PRESSURE_MAX, 0, 0); | ||
181 | |||
182 | err = input_register_device(pcap_ts->input); | ||
183 | if (err) | ||
184 | goto fail_allocate; | ||
185 | |||
186 | err = request_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), | ||
187 | pcap_ts_event_touch, 0, "Touch Screen", pcap_ts); | ||
188 | if (err) | ||
189 | goto fail_register; | ||
190 | |||
191 | return 0; | ||
192 | |||
193 | fail_register: | ||
194 | input_unregister_device(input_dev); | ||
195 | goto fail; | ||
196 | fail_allocate: | ||
197 | input_free_device(input_dev); | ||
198 | fail: | ||
199 | kfree(pcap_ts); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static int __devexit pcap_ts_remove(struct platform_device *pdev) | ||
205 | { | ||
206 | struct pcap_ts *pcap_ts = platform_get_drvdata(pdev); | ||
207 | |||
208 | free_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), pcap_ts); | ||
209 | cancel_delayed_work_sync(&pcap_ts->work); | ||
210 | |||
211 | input_unregister_device(pcap_ts->input); | ||
212 | |||
213 | kfree(pcap_ts); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | #ifdef CONFIG_PM | ||
219 | static int pcap_ts_suspend(struct device *dev) | ||
220 | { | ||
221 | struct pcap_ts *pcap_ts = dev_get_drvdata(dev); | ||
222 | |||
223 | pcap_set_ts_bits(pcap_ts->pcap, PCAP_ADC_TS_REF_LOWPWR); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int pcap_ts_resume(struct device *dev) | ||
228 | { | ||
229 | struct pcap_ts *pcap_ts = dev_get_drvdata(dev); | ||
230 | |||
231 | pcap_set_ts_bits(pcap_ts->pcap, | ||
232 | pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct dev_pm_ops pcap_ts_pm_ops = { | ||
237 | .suspend = pcap_ts_suspend, | ||
238 | .resume = pcap_ts_resume, | ||
239 | }; | ||
240 | #define PCAP_TS_PM_OPS (&pcap_ts_pm_ops) | ||
241 | #else | ||
242 | #define PCAP_TS_PM_OPS NULL | ||
243 | #endif | ||
244 | |||
245 | static struct platform_driver pcap_ts_driver = { | ||
246 | .probe = pcap_ts_probe, | ||
247 | .remove = __devexit_p(pcap_ts_remove), | ||
248 | .driver = { | ||
249 | .name = "pcap-ts", | ||
250 | .owner = THIS_MODULE, | ||
251 | .pm = PCAP_TS_PM_OPS, | ||
252 | }, | ||
253 | }; | ||
254 | |||
255 | static int __init pcap_ts_init(void) | ||
256 | { | ||
257 | return platform_driver_register(&pcap_ts_driver); | ||
258 | } | ||
259 | |||
260 | static void __exit pcap_ts_exit(void) | ||
261 | { | ||
262 | platform_driver_unregister(&pcap_ts_driver); | ||
263 | } | ||
264 | |||
265 | module_init(pcap_ts_init); | ||
266 | module_exit(pcap_ts_exit); | ||
267 | |||
268 | MODULE_DESCRIPTION("Motorola PCAP2 touchscreen driver"); | ||
269 | MODULE_AUTHOR("Daniel Ribeiro / Harald Welte"); | ||
270 | MODULE_LICENSE("GPL"); | ||
271 | MODULE_ALIAS("platform:pcap_ts"); | ||
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 252eb11fe9db..f944918466e5 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -561,6 +561,7 @@ static void wm97xx_ts_input_close(struct input_dev *idev) | |||
561 | static int wm97xx_probe(struct device *dev) | 561 | static int wm97xx_probe(struct device *dev) |
562 | { | 562 | { |
563 | struct wm97xx *wm; | 563 | struct wm97xx *wm; |
564 | struct wm97xx_pdata *pdata = dev->platform_data; | ||
564 | int ret = 0, id = 0; | 565 | int ret = 0, id = 0; |
565 | 566 | ||
566 | wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); | 567 | wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); |
@@ -658,6 +659,7 @@ static int wm97xx_probe(struct device *dev) | |||
658 | } | 659 | } |
659 | platform_set_drvdata(wm->battery_dev, wm); | 660 | platform_set_drvdata(wm->battery_dev, wm); |
660 | wm->battery_dev->dev.parent = dev; | 661 | wm->battery_dev->dev.parent = dev; |
662 | wm->battery_dev->dev.platform_data = pdata; | ||
661 | ret = platform_device_add(wm->battery_dev); | 663 | ret = platform_device_add(wm->battery_dev); |
662 | if (ret < 0) | 664 | if (ret < 0) |
663 | goto batt_reg_err; | 665 | goto batt_reg_err; |
@@ -671,6 +673,7 @@ static int wm97xx_probe(struct device *dev) | |||
671 | } | 673 | } |
672 | platform_set_drvdata(wm->touch_dev, wm); | 674 | platform_set_drvdata(wm->touch_dev, wm); |
673 | wm->touch_dev->dev.parent = dev; | 675 | wm->touch_dev->dev.parent = dev; |
676 | wm->touch_dev->dev.platform_data = pdata; | ||
674 | ret = platform_device_add(wm->touch_dev); | 677 | ret = platform_device_add(wm->touch_dev); |
675 | if (ret < 0) | 678 | if (ret < 0) |
676 | goto touch_reg_err; | 679 | goto touch_reg_err; |