aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:38:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:38:14 -0400
commitce1d5b23a8d1e19866ab82bdec0dc41fde5273d8 (patch)
tree028c80655ee8853ebf607d435bc3d6ab223aef1f /drivers/input/touchscreen
parentad5e1b0f5d913d2c8bddfba81049cc07228da1a6 (diff)
parent308f0a5898033691d050374a949bbfe173987a16 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (40 commits) Input: wacom - add support for Cintiq 20WSX Input: ucb1400_ts - IRQ probe fix Input: at32psif - update MODULE_AUTHOR with new email Input: mac_hid - add lockdep annotation to emumousebtn Input: i8042 - fix incorrect usage of strncpy and strncat Input: bf54x-keys - add infrastructure for keypad wakeups Input: add MODULE_ALIAS() to hotpluggable platform modules Input: drivers/char/keyboard.c - use time_after Input: fix ordering in joystick Makefile Input: wm97xx-core - support use as a wakeup source Input: wm97xx-core - use IRQF_SAMPLE_RANDOM Input: wm97xx-core - only schedule interrupt handler if not already scheduled Input: add Zhen Hua driver Input: aiptek - add support for Genius G-PEN 560 tablet Input: wacom - implement suspend and autosuspend Input: xpad - set proper buffer length for outgoing requests Input: omap-keypad - fix build warning Input: gpio_keys - irq handling cleanup Input: add PS/2 serio driver for AVR32 devices Input: put ledstate in the keyboard notifier ...
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig53
-rw-r--r--drivers/input/touchscreen/Makefile7
-rw-r--r--drivers/input/touchscreen/ads7846.c22
-rw-r--r--drivers/input/touchscreen/corgi_ts.c2
-rw-r--r--drivers/input/touchscreen/jornada720_ts.c4
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c302
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c4
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c31
-rw-r--r--drivers/input/touchscreen/wm9705.c353
-rw-r--r--drivers/input/touchscreen/wm9712.c462
-rw-r--r--drivers/input/touchscreen/wm9713.c460
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c829
12 files changed, 2501 insertions, 28 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 90e8e92dfe4..565ec711c2e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -185,6 +185,59 @@ config TOUCHSCREEN_UCB1400
185 To compile this driver as a module, choose M here: the 185 To compile this driver as a module, choose M here: the
186 module will be called ucb1400_ts. 186 module will be called ucb1400_ts.
187 187
188config TOUCHSCREEN_WM97XX
189 tristate "Support for WM97xx AC97 touchscreen controllers"
190 depends on AC97_BUS
191 help
192 Say Y here if you have a Wolfson Microelectronics WM97xx
193 touchscreen connected to your system. Note that this option
194 only enables core driver, you will also need to select
195 support for appropriate chip below.
196
197 If unsure, say N.
198
199 To compile this driver as a module, choose M here: the
200 module will be called wm97xx-ts.
201
202config TOUCHSCREEN_WM9705
203 bool "WM9705 Touchscreen interface support"
204 depends on TOUCHSCREEN_WM97XX
205 help
206 Say Y here if you have a Wolfson Microelectronics WM9705
207 touchscreen controller connected to your system.
208
209 If unsure, say N.
210
211config TOUCHSCREEN_WM9712
212 bool "WM9712 Touchscreen interface support"
213 depends on TOUCHSCREEN_WM97XX
214 help
215 Say Y here if you have a Wolfson Microelectronics WM9712
216 touchscreen controller connected to your system.
217
218 If unsure, say N.
219
220config TOUCHSCREEN_WM9713
221 bool "WM9713 Touchscreen interface support"
222 depends on TOUCHSCREEN_WM97XX
223 help
224 Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen
225 controller connected to your system.
226
227 If unsure, say N.
228
229config TOUCHSCREEN_WM97XX_MAINSTONE
230 tristate "WM97xx Mainstone accelerated touch"
231 depends on TOUCHSCREEN_WM97XX && ARCH_PXA
232 help
233 Say Y here for support for streaming mode with WM97xx touchscreens
234 on Mainstone systems.
235
236 If unsure, say N.
237
238 To compile this driver as a module, choose M here: the
239 module will be called mainstone-wm97xx.
240
188config TOUCHSCREEN_USB_COMPOSITE 241config TOUCHSCREEN_USB_COMPOSITE
189 tristate "USB Touchscreen Driver" 242 tristate "USB Touchscreen Driver"
190 depends on USB_ARCH_HAS_HCD 243 depends on USB_ARCH_HAS_HCD
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 35d4097df35..3c096d75651 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -4,6 +4,8 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7wm97xx-ts-y := wm97xx-core.o
8
7obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 9obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
8obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 10obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
9obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o 11obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
@@ -19,3 +21,8 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
19obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o 21obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
20obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o 22obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
21obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o 23obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
24obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
25wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
26wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
27wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
28obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 39573b91c8d..907a45fe9d4 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -80,6 +80,7 @@ struct ads7846 {
80#endif 80#endif
81 81
82 u16 model; 82 u16 model;
83 u16 vref_mv;
83 u16 vref_delay_usecs; 84 u16 vref_delay_usecs;
84 u16 x_plate_ohms; 85 u16 x_plate_ohms;
85 u16 pressure_max; 86 u16 pressure_max;
@@ -177,9 +178,6 @@ struct ads7846 {
177 * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; 178 * The range is GND..vREF. The ads7843 and ads7835 must use external vREF;
178 * ads7846 lets that pin be unconnected, to use internal vREF. 179 * ads7846 lets that pin be unconnected, to use internal vREF.
179 */ 180 */
180static unsigned vREF_mV;
181module_param(vREF_mV, uint, 0);
182MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts");
183 181
184struct ser_req { 182struct ser_req {
185 u8 ref_on; 183 u8 ref_on;
@@ -206,7 +204,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
206 struct ads7846 *ts = dev_get_drvdata(dev); 204 struct ads7846 *ts = dev_get_drvdata(dev);
207 struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); 205 struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
208 int status; 206 int status;
209 int uninitialized_var(sample);
210 int use_internal; 207 int use_internal;
211 208
212 if (!req) 209 if (!req)
@@ -263,13 +260,13 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
263 260
264 if (status == 0) { 261 if (status == 0) {
265 /* on-wire is a must-ignore bit, a BE12 value, then padding */ 262 /* on-wire is a must-ignore bit, a BE12 value, then padding */
266 sample = be16_to_cpu(req->sample); 263 status = be16_to_cpu(req->sample);
267 sample = sample >> 3; 264 status = status >> 3;
268 sample &= 0x0fff; 265 status &= 0x0fff;
269 } 266 }
270 267
271 kfree(req); 268 kfree(req);
272 return status ? status : sample; 269 return status;
273} 270}
274 271
275#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) 272#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
@@ -310,7 +307,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v)
310 unsigned retval = v; 307 unsigned retval = v;
311 308
312 /* external resistors may scale vAUX into 0..vREF */ 309 /* external resistors may scale vAUX into 0..vREF */
313 retval *= vREF_mV; 310 retval *= ts->vref_mv;
314 retval = retval >> 12; 311 retval = retval >> 12;
315 return retval; 312 return retval;
316} 313}
@@ -368,14 +365,14 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts)
368 /* hwmon sensors need a reference voltage */ 365 /* hwmon sensors need a reference voltage */
369 switch (ts->model) { 366 switch (ts->model) {
370 case 7846: 367 case 7846:
371 if (!vREF_mV) { 368 if (!ts->vref_mv) {
372 dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); 369 dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
373 vREF_mV = 2500; 370 ts->vref_mv = 2500;
374 } 371 }
375 break; 372 break;
376 case 7845: 373 case 7845:
377 case 7843: 374 case 7843:
378 if (!vREF_mV) { 375 if (!ts->vref_mv) {
379 dev_warn(&spi->dev, 376 dev_warn(&spi->dev,
380 "external vREF for ADS%d not specified\n", 377 "external vREF for ADS%d not specified\n",
381 ts->model); 378 ts->model);
@@ -868,6 +865,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
868 865
869 ts->spi = spi; 866 ts->spi = spi;
870 ts->input = input_dev; 867 ts->input = input_dev;
868 ts->vref_mv = pdata->vref_mv;
871 869
872 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 870 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
873 ts->timer.function = ads7846_timer; 871 ts->timer.function = ads7846_timer;
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index a22576779ac..4e9d8eece2e 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -362,6 +362,7 @@ static struct platform_driver corgits_driver = {
362 .resume = corgits_resume, 362 .resume = corgits_resume,
363 .driver = { 363 .driver = {
364 .name = "corgi-ts", 364 .name = "corgi-ts",
365 .owner = THIS_MODULE,
365 }, 366 },
366}; 367};
367 368
@@ -381,3 +382,4 @@ module_exit(corgits_exit);
381MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 382MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
382MODULE_DESCRIPTION("Corgi TouchScreen Driver"); 383MODULE_DESCRIPTION("Corgi TouchScreen Driver");
383MODULE_LICENSE("GPL"); 384MODULE_LICENSE("GPL");
385MODULE_ALIAS("platform:corgi-ts");
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c
index 42a1c9a1940..742242111bf 100644
--- a/drivers/input/touchscreen/jornada720_ts.c
+++ b/drivers/input/touchscreen/jornada720_ts.c
@@ -160,11 +160,15 @@ static int __devexit jornada720_ts_remove(struct platform_device *pdev)
160 return 0; 160 return 0;
161} 161}
162 162
163/* work with hotplug and coldplug */
164MODULE_ALIAS("platform:jornada_ts");
165
163static struct platform_driver jornada720_ts_driver = { 166static struct platform_driver jornada720_ts_driver = {
164 .probe = jornada720_ts_probe, 167 .probe = jornada720_ts_probe,
165 .remove = __devexit_p(jornada720_ts_remove), 168 .remove = __devexit_p(jornada720_ts_remove),
166 .driver = { 169 .driver = {
167 .name = "jornada_ts", 170 .name = "jornada_ts",
171 .owner = THIS_MODULE,
168 }, 172 },
169}; 173};
170 174
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
new file mode 100644
index 00000000000..a79f029b91c
--- /dev/null
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -0,0 +1,302 @@
1/*
2 * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for
3 * Wolfson WM97xx AC97 Codecs.
4 *
5 * Copyright 2004, 2007 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
8 * Parts Copyright : Ian Molton <spyro@f2s.com>
9 * Andrew Zabolotny <zap@homelink.ru>
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 as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * Notes:
17 * This is a wm97xx extended touch driver to capture touch
18 * data in a continuous manner on the Intel XScale archictecture
19 *
20 * Features:
21 * - codecs supported:- WM9705, WM9712, WM9713
22 * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/version.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/irq.h>
33#include <linux/interrupt.h>
34#include <linux/wm97xx.h>
35#include <linux/io.h>
36#include <asm/arch/pxa-regs.h>
37
38#define VERSION "0.13"
39
40struct continuous {
41 u16 id; /* codec id */
42 u8 code; /* continuous code */
43 u8 reads; /* number of coord reads per read cycle */
44 u32 speed; /* number of coords per second */
45};
46
47#define WM_READS(sp) ((sp / HZ) + 1)
48
49static const struct continuous cinfo[] = {
50 {WM9705_ID2, 0, WM_READS(94), 94},
51 {WM9705_ID2, 1, WM_READS(188), 188},
52 {WM9705_ID2, 2, WM_READS(375), 375},
53 {WM9705_ID2, 3, WM_READS(750), 750},
54 {WM9712_ID2, 0, WM_READS(94), 94},
55 {WM9712_ID2, 1, WM_READS(188), 188},
56 {WM9712_ID2, 2, WM_READS(375), 375},
57 {WM9712_ID2, 3, WM_READS(750), 750},
58 {WM9713_ID2, 0, WM_READS(94), 94},
59 {WM9713_ID2, 1, WM_READS(120), 120},
60 {WM9713_ID2, 2, WM_READS(154), 154},
61 {WM9713_ID2, 3, WM_READS(188), 188},
62};
63
64/* continuous speed index */
65static int sp_idx;
66static u16 last, tries;
67
68/*
69 * Pen sampling frequency (Hz) in continuous mode.
70 */
71static int cont_rate = 200;
72module_param(cont_rate, int, 0);
73MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
74
75/*
76 * Pen down detection.
77 *
78 * This driver can either poll or use an interrupt to indicate a pen down
79 * event. If the irq request fails then it will fall back to polling mode.
80 */
81static int pen_int;
82module_param(pen_int, int, 0);
83MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
84
85/*
86 * Pressure readback.
87 *
88 * Set to 1 to read back pen down pressure
89 */
90static int pressure;
91module_param(pressure, int, 0);
92MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
93
94/*
95 * AC97 touch data slot.
96 *
97 * Touch screen readback data ac97 slot
98 */
99static int ac97_touch_slot = 5;
100module_param(ac97_touch_slot, int, 0);
101MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
102
103
104/* flush AC97 slot 5 FIFO on pxa machines */
105#ifdef CONFIG_PXA27x
106static void wm97xx_acc_pen_up(struct wm97xx *wm)
107{
108 schedule_timeout_uninterruptible(1);
109
110 while (MISR & (1 << 2))
111 MODR;
112}
113#else
114static void wm97xx_acc_pen_up(struct wm97xx *wm)
115{
116 int count = 16;
117 schedule_timeout_uninterruptible(1);
118
119 while (count < 16) {
120 MODR;
121 count--;
122 }
123}
124#endif
125
126static int wm97xx_acc_pen_down(struct wm97xx *wm)
127{
128 u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
129 int reads = 0;
130
131 /* When the AC97 queue has been drained we need to allow time
132 * to buffer up samples otherwise we end up spinning polling
133 * for samples. The controller can't have a suitably low
134 * threashold set to use the notifications it gives.
135 */
136 schedule_timeout_uninterruptible(1);
137
138 if (tries > 5) {
139 tries = 0;
140 return RC_PENUP;
141 }
142
143 x = MODR;
144 if (x == last) {
145 tries++;
146 return RC_AGAIN;
147 }
148 last = x;
149 do {
150 if (reads)
151 x = MODR;
152 y = MODR;
153 if (pressure)
154 p = MODR;
155
156 /* are samples valid */
157 if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
158 (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
159 (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES)
160 goto up;
161
162 /* coordinate is good */
163 tries = 0;
164 input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
165 input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
166 input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
167 input_sync(wm->input_dev);
168 reads++;
169 } while (reads < cinfo[sp_idx].reads);
170up:
171 return RC_PENDOWN | RC_AGAIN;
172}
173
174static int wm97xx_acc_startup(struct wm97xx *wm)
175{
176 int idx = 0;
177
178 /* check we have a codec */
179 if (wm->ac97 == NULL)
180 return -ENODEV;
181
182 /* Go you big red fire engine */
183 for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
184 if (wm->id != cinfo[idx].id)
185 continue;
186 sp_idx = idx;
187 if (cont_rate <= cinfo[idx].speed)
188 break;
189 }
190 wm->acc_rate = cinfo[sp_idx].code;
191 wm->acc_slot = ac97_touch_slot;
192 dev_info(wm->dev,
193 "mainstone accelerated touchscreen driver, %d samples/sec\n",
194 cinfo[sp_idx].speed);
195
196 /* codec specific irq config */
197 if (pen_int) {
198 switch (wm->id) {
199 case WM9705_ID2:
200 wm->pen_irq = IRQ_GPIO(4);
201 set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
202 break;
203 case WM9712_ID2:
204 case WM9713_ID2:
205 /* enable pen down interrupt */
206 /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
207 wm->pen_irq = MAINSTONE_AC97_IRQ;
208 wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
209 WM97XX_GPIO_POL_HIGH,
210 WM97XX_GPIO_STICKY,
211 WM97XX_GPIO_WAKE);
212 wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
213 WM97XX_GPIO_POL_HIGH,
214 WM97XX_GPIO_NOTSTICKY,
215 WM97XX_GPIO_NOWAKE);
216 break;
217 default:
218 dev_err(wm->dev,
219 "pen down irq not supported on this device\n");
220 pen_int = 0;
221 break;
222 }
223 }
224
225 return 0;
226}
227
228static void wm97xx_acc_shutdown(struct wm97xx *wm)
229{
230 /* codec specific deconfig */
231 if (pen_int) {
232 switch (wm->id & 0xffff) {
233 case WM9705_ID2:
234 wm->pen_irq = 0;
235 break;
236 case WM9712_ID2:
237 case WM9713_ID2:
238 /* disable interrupt */
239 wm->pen_irq = 0;
240 break;
241 }
242 }
243}
244
245static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
246{
247 if (enable)
248 enable_irq(wm->pen_irq);
249 else
250 disable_irq(wm->pen_irq);
251}
252
253static struct wm97xx_mach_ops mainstone_mach_ops = {
254 .acc_enabled = 1,
255 .acc_pen_up = wm97xx_acc_pen_up,
256 .acc_pen_down = wm97xx_acc_pen_down,
257 .acc_startup = wm97xx_acc_startup,
258 .acc_shutdown = wm97xx_acc_shutdown,
259 .irq_enable = wm97xx_irq_enable,
260 .irq_gpio = WM97XX_GPIO_2,
261};
262
263static int mainstone_wm97xx_probe(struct platform_device *pdev)
264{
265 struct wm97xx *wm = platform_get_drvdata(pdev);
266
267 return wm97xx_register_mach_ops(wm, &mainstone_mach_ops);
268}
269
270static int mainstone_wm97xx_remove(struct platform_device *pdev)
271{
272 struct wm97xx *wm = platform_get_drvdata(pdev);
273
274 wm97xx_unregister_mach_ops(wm);
275 return 0;
276}
277
278static struct platform_driver mainstone_wm97xx_driver = {
279 .probe = mainstone_wm97xx_probe,
280 .remove = mainstone_wm97xx_remove,
281 .driver = {
282 .name = "wm97xx-touch",
283 },
284};
285
286static int __init mainstone_wm97xx_init(void)
287{
288 return platform_driver_register(&mainstone_wm97xx_driver);
289}
290
291static void __exit mainstone_wm97xx_exit(void)
292{
293 platform_driver_unregister(&mainstone_wm97xx_driver);
294}
295
296module_init(mainstone_wm97xx_init);
297module_exit(mainstone_wm97xx_exit);
298
299/* Module information */
300MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
301MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
302MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 607f9933aa1..bce018e45bc 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -427,10 +427,6 @@ static int ucb1400_detect_irq(struct ucb1400 *ucb)
427 unsigned long mask, timeout; 427 unsigned long mask, timeout;
428 428
429 mask = probe_irq_on(); 429 mask = probe_irq_on();
430 if (!mask) {
431 probe_irq_off(mask);
432 return -EBUSY;
433 }
434 430
435 /* Enable the ADC interrupt. */ 431 /* Enable the ADC interrupt. */
436 ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); 432 ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 63f9664a066..3a0a8ca5707 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -396,9 +396,12 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
396static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) 396static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
397{ 397{
398 struct usb_device *dev = usbtouch->udev; 398 struct usb_device *dev = usbtouch->udev;
399 int ret; 399 int ret = -ENOMEM;
400 unsigned char buf[2]; 400 unsigned char *buf;
401 401
402 buf = kmalloc(2, GFP_KERNEL);
403 if (!buf)
404 goto err_nobuf;
402 /* reset */ 405 /* reset */
403 buf[0] = buf[1] = 0xFF; 406 buf[0] = buf[1] = 0xFF;
404 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), 407 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
@@ -406,9 +409,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
406 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 409 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
407 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 410 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
408 if (ret < 0) 411 if (ret < 0)
409 return ret; 412 goto err_out;
410 if (buf[0] != 0x06 || buf[1] != 0x00) 413 if (buf[0] != 0x06 || buf[1] != 0x00) {
411 return -ENODEV; 414 ret = -ENODEV;
415 goto err_out;
416 }
412 417
413 /* set coordinate output rate */ 418 /* set coordinate output rate */
414 buf[0] = buf[1] = 0xFF; 419 buf[0] = buf[1] = 0xFF;
@@ -417,20 +422,22 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
417 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 422 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
418 TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 423 TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
419 if (ret < 0) 424 if (ret < 0)
420 return ret; 425 goto err_out;
421 if ((buf[0] != 0x06 || buf[1] != 0x00) && 426 if ((buf[0] != 0x06 || buf[1] != 0x00) &&
422 (buf[0] != 0x15 || buf[1] != 0x01)) 427 (buf[0] != 0x15 || buf[1] != 0x01)) {
423 return -ENODEV; 428 ret = -ENODEV;
429 goto err_out;
430 }
424 431
425 /* start sending data */ 432 /* start sending data */
426 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), 433 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
427 TSC10_CMD_DATA1, 434 TSC10_CMD_DATA1,
428 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 435 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
429 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 436 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
430 if (ret < 0) 437err_out:
431 return ret; 438 kfree(buf);
432 439err_nobuf:
433 return 0; 440 return ret;
434} 441}
435 442
436 443
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
new file mode 100644
index 00000000000..978e1a13ffc
--- /dev/null
+++ b/drivers/input/touchscreen/wm9705.c
@@ -0,0 +1,353 @@
1/*
2 * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk>
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 as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h>
22#include <linux/input.h>
23#include <linux/delay.h>
24#include <linux/bitops.h>
25#include <linux/wm97xx.h>
26
27#define TS_NAME "wm97xx"
28#define WM9705_VERSION "1.00"
29#define DEFAULT_PRESSURE 0xb0c0
30
31/*
32 * Module parameters
33 */
34
35/*
36 * Set current used for pressure measurement.
37 *
38 * Set pil = 2 to use 400uA
39 * pil = 1 to use 200uA and
40 * pil = 0 to disable pressure measurement.
41 *
42 * This is used to increase the range of values returned by the adc
43 * when measureing touchpanel pressure.
44 */
45static int pil;
46module_param(pil, int, 0);
47MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
48
49/*
50 * Set threshold for pressure measurement.
51 *
52 * Pen down pressure below threshold is ignored.
53 */
54static int pressure = DEFAULT_PRESSURE & 0xfff;
55module_param(pressure, int, 0);
56MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
57
58/*
59 * Set adc sample delay.
60 *
61 * For accurate touchpanel measurements, some settling time may be
62 * required between the switch matrix applying a voltage across the
63 * touchpanel plate and the ADC sampling the signal.
64 *
65 * This delay can be set by setting delay = n, where n is the array
66 * position of the delay in the array delay_table below.
67 * Long delays > 1ms are supported for completeness, but are not
68 * recommended.
69 */
70static int delay = 4;
71module_param(delay, int, 0);
72MODULE_PARM_DESC(delay, "Set adc sample delay.");
73
74/*
75 * Pen detect comparator threshold.
76 *
77 * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
78 * i.e. 1 = Vmid/15 threshold
79 * 15 = Vmid/1 threshold
80 *
81 * Adjust this value if you are having problems with pen detect not
82 * detecting any down events.
83 */
84static int pdd = 8;
85module_param(pdd, int, 0);
86MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold");
87
88/*
89 * Set adc mask function.
90 *
91 * Sources of glitch noise, such as signals driving an LCD display, may feed
92 * through to the touch screen plates and affect measurement accuracy. In
93 * order to minimise this, a signal may be applied to the MASK pin to delay or
94 * synchronise the sampling.
95 *
96 * 0 = No delay or sync
97 * 1 = High on pin stops conversions
98 * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
99 * 3 = Edge triggered, edge on pin starts conversion after delay param
100 */
101static int mask;
102module_param(mask, int, 0);
103MODULE_PARM_DESC(mask, "Set adc mask function.");
104
105/*
106 * ADC sample delay times in uS
107 */
108static const int delay_table[] = {
109 21, /* 1 AC97 Link frames */
110 42, /* 2 */
111 84, /* 4 */
112 167, /* 8 */
113 333, /* 16 */
114 667, /* 32 */
115 1000, /* 48 */
116 1333, /* 64 */
117 2000, /* 96 */
118 2667, /* 128 */
119 3333, /* 160 */
120 4000, /* 192 */
121 4667, /* 224 */
122 5333, /* 256 */
123 6000, /* 288 */
124 0 /* No delay, switch matrix always on */
125};
126
127/*
128 * Delay after issuing a POLL command.
129 *
130 * The delay is 3 AC97 link frames + the touchpanel settling delay
131 */
132static inline void poll_delay(int d)
133{
134 udelay(3 * AC97_LINK_FRAME + delay_table[d]);
135}
136
137/*
138 * set up the physical settings of the WM9705
139 */
140static void wm9705_phy_init(struct wm97xx *wm)
141{
142 u16 dig1 = 0, dig2 = WM97XX_RPR;
143
144 /*
145 * mute VIDEO and AUX as they share X and Y touchscreen
146 * inputs on the WM9705
147 */
148 wm97xx_reg_write(wm, AC97_AUX, 0x8000);
149 wm97xx_reg_write(wm, AC97_VIDEO, 0x8000);
150
151 /* touchpanel pressure current*/
152 if (pil == 2) {
153 dig2 |= WM9705_PIL;
154 dev_dbg(wm->dev,
155 "setting pressure measurement current to 400uA.");
156 } else if (pil)
157 dev_dbg(wm->dev,
158 "setting pressure measurement current to 200uA.");
159 if (!pil)
160 pressure = 0;
161
162 /* polling mode sample settling delay */
163 if (delay != 4) {
164 if (delay < 0 || delay > 15) {
165 dev_dbg(wm->dev, "supplied delay out of range.");
166 delay = 4;
167 }
168 }
169 dig1 &= 0xff0f;
170 dig1 |= WM97XX_DELAY(delay);
171 dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.",
172 delay_table[delay]);
173
174 /* WM9705 pdd */
175 dig2 |= (pdd & 0x000f);
176 dev_dbg(wm->dev, "setting pdd to Vmid/%d", 1 - (pdd & 0x000f));
177
178 /* mask */
179 dig2 |= ((mask & 0x3) << 4);
180
181 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
182 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
183}
184
185static void wm9705_dig_enable(struct wm97xx *wm, int enable)
186{
187 if (enable) {
188 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
189 wm->dig[2] | WM97XX_PRP_DET_DIG);
190 wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
191 } else
192 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
193 wm->dig[2] & ~WM97XX_PRP_DET_DIG);
194}
195
196static void wm9705_aux_prepare(struct wm97xx *wm)
197{
198 memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
199 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
200 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
201}
202
203static void wm9705_dig_restore(struct wm97xx *wm)
204{
205 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
206 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
207}
208
209static inline int is_pden(struct wm97xx *wm)
210{
211 return wm->dig[2] & WM9705_PDEN;
212}
213
214/*
215 * Read a sample from the WM9705 adc in polling mode.
216 */
217static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
218{
219 int timeout = 5 * delay;
220
221 if (!wm->pen_probably_down) {
222 u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
223 if (!(data & WM97XX_PEN_DOWN))
224 return RC_PENUP;
225 wm->pen_probably_down = 1;
226 }
227
228 /* set up digitiser */
229 if (adcsel & 0x8000)
230 adcsel = ((adcsel & 0x7fff) + 3) << 12;
231
232 if (wm->mach_ops && wm->mach_ops->pre_sample)
233 wm->mach_ops->pre_sample(adcsel);
234 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
235 adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
236
237 /* wait 3 AC97 time slots + delay for conversion */
238 poll_delay(delay);
239
240 /* wait for POLL to go low */
241 while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
242 && timeout) {
243 udelay(AC97_LINK_FRAME);
244 timeout--;
245 }
246
247 if (timeout == 0) {
248 /* If PDEN is set, we can get a timeout when pen goes up */
249 if (is_pden(wm))
250 wm->pen_probably_down = 0;
251 else
252 dev_dbg(wm->dev, "adc sample timeout");
253 return RC_PENUP;
254 }
255
256 *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
257 if (wm->mach_ops && wm->mach_ops->post_sample)
258 wm->mach_ops->post_sample(adcsel);
259
260 /* check we have correct sample */
261 if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
262 dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
263 *sample & WM97XX_ADCSEL_MASK);
264 return RC_PENUP;
265 }
266
267 if (!(*sample & WM97XX_PEN_DOWN)) {
268 wm->pen_probably_down = 0;
269 return RC_PENUP;
270 }
271
272 return RC_VALID;
273}
274
275/*
276 * Sample the WM9705 touchscreen in polling mode
277 */
278static int wm9705_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
279{
280 int rc;
281
282 rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x);
283 if (rc != RC_VALID)
284 return rc;
285 rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y);
286 if (rc != RC_VALID)
287 return rc;
288 if (pil) {
289 rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p);
290 if (rc != RC_VALID)
291 return rc;
292 } else
293 data->p = DEFAULT_PRESSURE;
294
295 return RC_VALID;
296}
297
298/*
299 * Enable WM9705 continuous mode, i.e. touch data is streamed across
300 * an AC97 slot
301 */
302static int wm9705_acc_enable(struct wm97xx *wm, int enable)
303{
304 u16 dig1, dig2;
305 int ret = 0;
306
307 dig1 = wm->dig[1];
308 dig2 = wm->dig[2];
309
310 if (enable) {
311 /* continous mode */
312 if (wm->mach_ops->acc_startup &&
313 (ret = wm->mach_ops->acc_startup(wm)) < 0)
314 return ret;
315 dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
316 WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
317 dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
318 WM97XX_DELAY(delay) |
319 WM97XX_SLT(wm->acc_slot) |
320 WM97XX_RATE(wm->acc_rate);
321 if (pil)
322 dig1 |= WM97XX_ADCSEL_PRES;
323 dig2 |= WM9705_PDEN;
324 } else {
325 dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
326 dig2 &= ~WM9705_PDEN;
327 if (wm->mach_ops->acc_shutdown)
328 wm->mach_ops->acc_shutdown(wm);
329 }
330
331 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
332 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
333
334 return ret;
335}
336
337struct wm97xx_codec_drv wm9705_codec = {
338 .id = WM9705_ID2,
339 .name = "wm9705",
340 .poll_sample = wm9705_poll_sample,
341 .poll_touch = wm9705_poll_touch,
342 .acc_enable = wm9705_acc_enable,
343 .phy_init = wm9705_phy_init,
344 .dig_enable = wm9705_dig_enable,
345 .dig_restore = wm9705_dig_restore,
346 .aux_prepare = wm9705_aux_prepare,
347};
348EXPORT_SYMBOL_GPL(wm9705_codec);
349
350/* Module information */
351MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
352MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
353MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
new file mode 100644
index 00000000000..0b6e4cfa6a2
--- /dev/null
+++ b/drivers/input/touchscreen/wm9712.c
@@ -0,0 +1,462 @@
1/*
2 * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk>
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 as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h>
22#include <linux/input.h>
23#include <linux/delay.h>
24#include <linux/bitops.h>
25#include <linux/wm97xx.h>
26
27#define TS_NAME "wm97xx"
28#define WM9712_VERSION "1.00"
29#define DEFAULT_PRESSURE 0xb0c0
30
31/*
32 * Module parameters
33 */
34
35/*
36 * Set internal pull up for pen detect.
37 *
38 * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
39 * i.e. pull up resistance = 64k Ohms / rpu.
40 *
41 * Adjust this value if you are having problems with pen detect not
42 * detecting any down event.
43 */
44static int rpu = 8;
45module_param(rpu, int, 0);
46MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
47
48/*
49 * Set current used for pressure measurement.
50 *
51 * Set pil = 2 to use 400uA
52 * pil = 1 to use 200uA and
53 * pil = 0 to disable pressure measurement.
54 *
55 * This is used to increase the range of values returned by the adc
56 * when measureing touchpanel pressure.
57 */
58static int pil;
59module_param(pil, int, 0);
60MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
61
62/*
63 * Set threshold for pressure measurement.
64 *
65 * Pen down pressure below threshold is ignored.
66 */
67static int pressure = DEFAULT_PRESSURE & 0xfff;
68module_param(pressure, int, 0);
69MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
70
71/*
72 * Set adc sample delay.
73 *
74 * For accurate touchpanel measurements, some settling time may be
75 * required between the switch matrix applying a voltage across the
76 * touchpanel plate and the ADC sampling the signal.
77 *
78 * This delay can be set by setting delay = n, where n is the array
79 * position of the delay in the array delay_table below.
80 * Long delays > 1ms are supported for completeness, but are not
81 * recommended.
82 */
83static int delay = 3;
84module_param(delay, int, 0);
85MODULE_PARM_DESC(delay, "Set adc sample delay.");
86
87/*
88 * Set five_wire = 1 to use a 5 wire touchscreen.
89 *
90 * NOTE: Five wire mode does not allow for readback of pressure.
91 */
92static int five_wire;
93module_param(five_wire, int, 0);
94MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
95
96/*
97 * Set adc mask function.
98 *
99 * Sources of glitch noise, such as signals driving an LCD display, may feed
100 * through to the touch screen plates and affect measurement accuracy. In
101 * order to minimise this, a signal may be applied to the MASK pin to delay or
102 * synchronise the sampling.
103 *
104 * 0 = No delay or sync
105 * 1 = High on pin stops conversions
106 * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
107 * 3 = Edge triggered, edge on pin starts conversion after delay param
108 */
109static int mask;
110module_param(mask, int, 0);
111MODULE_PARM_DESC(mask, "Set adc mask function.");
112
113/*
114 * Coordinate Polling Enable.
115 *
116 * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
117 * for every poll.
118 */
119static int coord;
120module_param(coord, int, 0);
121MODULE_PARM_DESC(coord, "Polling coordinate mode");
122
123/*
124 * ADC sample delay times in uS
125 */
126static const int delay_table[] = {
127 21, /* 1 AC97 Link frames */
128 42, /* 2 */
129 84, /* 4 */
130 167, /* 8 */
131 333, /* 16 */
132 667, /* 32 */
133 1000, /* 48 */
134 1333, /* 64 */
135 2000, /* 96 */
136 2667, /* 128 */
137 3333, /* 160 */
138 4000, /* 192 */
139 4667, /* 224 */
140 5333, /* 256 */
141 6000, /* 288 */
142 0 /* No delay, switch matrix always on */
143};
144
145/*
146 * Delay after issuing a POLL command.
147 *
148 * The delay is 3 AC97 link frames + the touchpanel settling delay
149 */
150static inline void poll_delay(int d)
151{
152 udelay(3 * AC97_LINK_FRAME + delay_table[d]);
153}
154
155/*
156 * set up the physical settings of the WM9712
157 */
158static void wm9712_phy_init(struct wm97xx *wm)
159{
160 u16 dig1 = 0;
161 u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
162
163 /* WM9712 rpu */
164 if (rpu) {
165 dig2 &= 0xffc0;
166 dig2 |= WM9712_RPU(rpu);
167 dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms",
168 64000 / rpu);
169 }
170
171 /* touchpanel pressure current*/
172 if (pil == 2) {
173 dig2 |= WM9712_PIL;
174 dev_dbg(wm->dev,
175 "setting pressure measurement current to 400uA.");
176 } else if (pil)
177 dev_dbg(wm->dev,
178 "setting pressure measurement current to 200uA.");
179 if (!pil)
180 pressure = 0;
181
182 /* WM9712 five wire */
183 if (five_wire) {
184 dig2 |= WM9712_45W;
185 dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
186 }
187
188 /* polling mode sample settling delay */
189 if (delay < 0 || delay > 15) {
190 dev_dbg(wm->dev, "supplied delay out of range.");
191 delay = 4;
192 }
193 dig1 &= 0xff0f;
194 dig1 |= WM97XX_DELAY(delay);
195 dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.",
196 delay_table[delay]);
197
198 /* mask */
199 dig2 |= ((mask & 0x3) << 6);
200 if (mask) {
201 u16 reg;
202 /* Set GPIO4 as Mask Pin*/
203 reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
204 wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
205 reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
206 wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
207 }
208
209 /* wait - coord mode */
210 if (coord)
211 dig2 |= WM9712_WAIT;
212
213 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
214 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
215}
216
217static void wm9712_dig_enable(struct wm97xx *wm, int enable)
218{
219 u16 dig2 = wm->dig[2];
220
221 if (enable) {
222 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
223 dig2 | WM97XX_PRP_DET_DIG);
224 wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
225 } else
226 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
227 dig2 & ~WM97XX_PRP_DET_DIG);
228}
229
230static void wm9712_aux_prepare(struct wm97xx *wm)
231{
232 memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
233 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
234 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
235}
236
237static void wm9712_dig_restore(struct wm97xx *wm)
238{
239 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
240 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
241}
242
243static inline int is_pden(struct wm97xx *wm)
244{
245 return wm->dig[2] & WM9712_PDEN;
246}
247
248/*
249 * Read a sample from the WM9712 adc in polling mode.
250 */
251static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
252{
253 int timeout = 5 * delay;
254
255 if (!wm->pen_probably_down) {
256 u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
257 if (!(data & WM97XX_PEN_DOWN))
258 return RC_PENUP;
259 wm->pen_probably_down = 1;
260 }
261
262 /* set up digitiser */
263 if (adcsel & 0x8000)
264 adcsel = ((adcsel & 0x7fff) + 3) << 12;
265
266 if (wm->mach_ops && wm->mach_ops->pre_sample)
267 wm->mach_ops->pre_sample(adcsel);
268 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
269 adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
270
271 /* wait 3 AC97 time slots + delay for conversion */
272 poll_delay(delay);
273
274 /* wait for POLL to go low */
275 while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
276 && timeout) {
277 udelay(AC97_LINK_FRAME);
278 timeout--;
279 }
280
281 if (timeout <= 0) {
282 /* If PDEN is set, we can get a timeout when pen goes up */
283 if (is_pden(wm))
284 wm->pen_probably_down = 0;
285 else
286 dev_dbg(wm->dev, "adc sample timeout");
287 return RC_PENUP;
288 }
289
290 *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
291 if (wm->mach_ops && wm->mach_ops->post_sample)
292 wm->mach_ops->post_sample(adcsel);
293
294 /* check we have correct sample */
295 if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
296 dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
297 *sample & WM97XX_ADCSEL_MASK);
298 return RC_PENUP;
299 }
300
301 if (!(*sample & WM97XX_PEN_DOWN)) {
302 wm->pen_probably_down = 0;
303 return RC_PENUP;
304 }
305
306 return RC_VALID;
307}
308
309/*
310 * Read a coord from the WM9712 adc in polling mode.
311 */
312static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
313{
314 int timeout = 5 * delay;
315
316 if (!wm->pen_probably_down) {
317 u16 data_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
318 if (!(data_rd & WM97XX_PEN_DOWN))
319 return RC_PENUP;
320 wm->pen_probably_down = 1;
321 }
322
323 /* set up digitiser */
324 if (wm->mach_ops && wm->mach_ops->pre_sample)
325 wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
326
327 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
328 WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
329
330 /* wait 3 AC97 time slots + delay for conversion and read x */
331 poll_delay(delay);
332 data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
333 /* wait for POLL to go low */
334 while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
335 && timeout) {
336 udelay(AC97_LINK_FRAME);
337 timeout--;
338 }
339
340 if (timeout <= 0) {
341 /* If PDEN is set, we can get a timeout when pen goes up */
342 if (is_pden(wm))
343 wm->pen_probably_down = 0;
344 else
345 dev_dbg(wm->dev, "adc sample timeout");
346 return RC_PENUP;
347 }
348
349 /* read back y data */
350 data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
351 if (pil)
352 data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
353 else
354 data->p = DEFAULT_PRESSURE;
355
356 if (wm->mach_ops && wm->mach_ops->post_sample)
357 wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
358
359 /* check we have correct sample */
360 if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
361 goto err;
362 if (pil && !(data->p & WM97XX_ADCSEL_PRES))
363 goto err;
364
365 if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) {
366 wm->pen_probably_down = 0;
367 return RC_PENUP;
368 }
369 return RC_VALID;
370err:
371 return 0;
372}
373
374/*
375 * Sample the WM9712 touchscreen in polling mode
376 */
377static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
378{
379 int rc;
380
381 if (coord) {
382 rc = wm9712_poll_coord(wm, data);
383 if (rc != RC_VALID)
384 return rc;
385 } else {
386 rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x);
387 if (rc != RC_VALID)
388 return rc;
389
390 rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y);
391 if (rc != RC_VALID)
392 return rc;
393
394 if (pil && !five_wire) {
395 rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES,
396 &data->p);
397 if (rc != RC_VALID)
398 return rc;
399 } else
400 data->p = DEFAULT_PRESSURE;
401 }
402 return RC_VALID;
403}
404
405/*
406 * Enable WM9712 continuous mode, i.e. touch data is streamed across
407 * an AC97 slot
408 */
409static int wm9712_acc_enable(struct wm97xx *wm, int enable)
410{
411 u16 dig1, dig2;
412 int ret = 0;
413
414 dig1 = wm->dig[1];
415 dig2 = wm->dig[2];
416
417 if (enable) {
418 /* continous mode */
419 if (wm->mach_ops->acc_startup) {
420 ret = wm->mach_ops->acc_startup(wm);
421 if (ret < 0)
422 return ret;
423 }
424 dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
425 WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
426 dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
427 WM97XX_DELAY(delay) |
428 WM97XX_SLT(wm->acc_slot) |
429 WM97XX_RATE(wm->acc_rate);
430 if (pil)
431 dig1 |= WM97XX_ADCSEL_PRES;
432 dig2 |= WM9712_PDEN;
433 } else {
434 dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
435 dig2 &= ~WM9712_PDEN;
436 if (wm->mach_ops->acc_shutdown)
437 wm->mach_ops->acc_shutdown(wm);
438 }
439
440 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
441 wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
442
443 return 0;
444}
445
446struct wm97xx_codec_drv wm9712_codec = {
447 .id = WM9712_ID2,
448 .name = "wm9712",
449 .poll_sample = wm9712_poll_sample,
450 .poll_touch = wm9712_poll_touch,
451 .acc_enable = wm9712_acc_enable,
452 .phy_init = wm9712_phy_init,
453 .dig_enable = wm9712_dig_enable,
454 .dig_restore = wm9712_dig_restore,
455 .aux_prepare = wm9712_aux_prepare,
456};
457EXPORT_SYMBOL_GPL(wm9712_codec);
458
459/* Module information */
460MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
461MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
462MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
new file mode 100644
index 00000000000..01278bd7e65
--- /dev/null
+++ b/drivers/input/touchscreen/wm9713.c
@@ -0,0 +1,460 @@
1/*
2 * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
3 *
4 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Parts Copyright : Ian Molton <spyro@f2s.com>
8 * Andrew Zabolotny <zap@homelink.ru>
9 * Russell King <rmk@arm.linux.org.uk>
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 as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h>
22#include <linux/input.h>
23#include <linux/delay.h>
24#include <linux/bitops.h>
25#include <linux/wm97xx.h>
26
27#define TS_NAME "wm97xx"
28#define WM9713_VERSION "1.00"
29#define DEFAULT_PRESSURE 0xb0c0
30
31/*
32 * Module parameters
33 */
34
35/*
36 * Set internal pull up for pen detect.
37 *
38 * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
39 * i.e. pull up resistance = 64k Ohms / rpu.
40 *
41 * Adjust this value if you are having problems with pen detect not
42 * detecting any down event.
43 */
44static int rpu = 8;
45module_param(rpu, int, 0);
46MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
47
48/*
49 * Set current used for pressure measurement.
50 *
51 * Set pil = 2 to use 400uA
52 * pil = 1 to use 200uA and
53 * pil = 0 to disable pressure measurement.
54 *
55 * This is used to increase the range of values returned by the adc
56 * when measureing touchpanel pressure.
57 */
58static int pil;
59module_param(pil, int, 0);
60MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
61
62/*
63 * Set threshold for pressure measurement.
64 *
65 * Pen down pressure below threshold is ignored.
66 */
67static int pressure = DEFAULT_PRESSURE & 0xfff;
68module_param(pressure, int, 0);
69MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
70
71/*
72 * Set adc sample delay.
73 *
74 * For accurate touchpanel measurements, some settling time may be
75 * required between the switch matrix applying a voltage across the
76 * touchpanel plate and the ADC sampling the signal.
77 *
78 * This delay can be set by setting delay = n, where n is the array
79 * position of the delay in the array delay_table below.
80 * Long delays > 1ms are supported for completeness, but are not
81 * recommended.
82 */
83static int delay = 4;
84module_param(delay, int, 0);
85MODULE_PARM_DESC(delay, "Set adc sample delay.");
86
87/*
88 * Set adc mask function.
89 *
90 * Sources of glitch noise, such as signals driving an LCD display, may feed
91 * through to the touch screen plates and affect measurement accuracy. In
92 * order to minimise this, a signal may be applied to the MASK pin to delay or
93 * synchronise the sampling.
94 *
95 * 0 = No delay or sync
96 * 1 = High on pin stops conversions
97 * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
98 * 3 = Edge triggered, edge on pin starts conversion after delay param
99 */
100static int mask;
101module_param(mask, int, 0);
102MODULE_PARM_DESC(mask, "Set adc mask function.");
103
104/*
105 * Coordinate Polling Enable.
106 *
107 * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
108 * for every poll.
109 */
110static int coord;
111module_param(coord, int, 0);
112MODULE_PARM_DESC(coord, "Polling coordinate mode");
113
114/*
115 * ADC sample delay times in uS
116 */
117static const int delay_table[] = {
118 21, /* 1 AC97 Link frames */
119 42, /* 2 */
120 84, /* 4 */
121 167, /* 8 */
122 333, /* 16 */
123 667, /* 32 */
124 1000, /* 48 */
125 1333, /* 64 */
126 2000, /* 96 */
127 2667, /* 128 */
128 3333, /* 160 */
129 4000, /* 192 */
130 4667, /* 224 */
131 5333, /* 256 */
132 6000, /* 288 */
133 0 /* No delay, switch matrix always on */
134};
135
136/*
137 * Delay after issuing a POLL command.
138 *
139 * The delay is 3 AC97 link frames + the touchpanel settling delay
140 */
141static inline void poll_delay(int d)
142{
143 udelay(3 * AC97_LINK_FRAME + delay_table[d]);
144}
145
146/*
147 * set up the physical settings of the WM9713
148 */
149static void wm9713_phy_init(struct wm97xx *wm)
150{
151 u16 dig1 = 0, dig2, dig3;
152
153 /* default values */
154 dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
155 dig3 = WM9712_RPU(1);
156
157 /* rpu */
158 if (rpu) {
159 dig3 &= 0xffc0;
160 dig3 |= WM9712_RPU(rpu);
161 dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n",
162 64000 / rpu);
163 }
164
165 /* touchpanel pressure */
166 if (pil == 2) {
167 dig3 |= WM9712_PIL;
168 dev_info(wm->dev,
169 "setting pressure measurement current to 400uA.");
170 } else if (pil)
171 dev_info(wm->dev,
172 "setting pressure measurement current to 200uA.");
173 if (!pil)
174 pressure = 0;
175
176 /* sample settling delay */
177 if (delay < 0 || delay > 15) {
178 dev_info(wm->dev, "supplied delay out of range.");
179 delay = 4;
180 dev_info(wm->dev, "setting adc sample delay to %d u Secs.",
181 delay_table[delay]);
182 }
183 dig2 &= 0xff0f;
184 dig2 |= WM97XX_DELAY(delay);
185
186 /* mask */
187 dig3 |= ((mask & 0x3) << 4);
188 if (coord)
189 dig3 |= WM9713_WAIT;
190
191 wm->misc = wm97xx_reg_read(wm, 0x5a);
192
193 wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
194 wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
195 wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
196 wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
197}
198
199static void wm9713_dig_enable(struct wm97xx *wm, int enable)
200{
201 u16 val;
202
203 if (enable) {
204 val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
205 wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
206 wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] |
207 WM97XX_PRP_DET_DIG);
208 wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
209 } else {
210 wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] &
211 ~WM97XX_PRP_DET_DIG);
212 val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
213 wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
214 }
215}
216
217static void wm9713_dig_restore(struct wm97xx *wm)
218{
219 wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
220 wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
221 wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
222}
223
224static void wm9713_aux_prepare(struct wm97xx *wm)
225{
226 memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
227 wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
228 wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
229 wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
230}
231
232static inline int is_pden(struct wm97xx *wm)
233{
234 return wm->dig[2] & WM9713_PDEN;
235}
236
237/*
238 * Read a sample from the WM9713 adc in polling mode.
239 */
240static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
241{
242 u16 dig1;
243 int timeout = 5 * delay;
244
245 if (!wm->pen_probably_down) {
246 u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
247 if (!(data & WM97XX_PEN_DOWN))
248 return RC_PENUP;
249 wm->pen_probably_down = 1;
250 }
251
252 /* set up digitiser */
253 if (adcsel & 0x8000)
254 adcsel = 1 << ((adcsel & 0x7fff) + 3);
255
256 dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
257 dig1 &= ~WM9713_ADCSEL_MASK;
258
259 if (wm->mach_ops && wm->mach_ops->pre_sample)
260 wm->mach_ops->pre_sample(adcsel);
261 wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL);
262
263 /* wait 3 AC97 time slots + delay for conversion */
264 poll_delay(delay);
265
266 /* wait for POLL to go low */
267 while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) &&
268 timeout) {
269 udelay(AC97_LINK_FRAME);
270 timeout--;
271 }
272
273 if (timeout <= 0) {
274 /* If PDEN is set, we can get a timeout when pen goes up */
275 if (is_pden(wm))
276 wm->pen_probably_down = 0;
277 else
278 dev_dbg(wm->dev, "adc sample timeout");
279 return RC_PENUP;
280 }
281
282 *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
283 if (wm->mach_ops && wm->mach_ops->post_sample)
284 wm->mach_ops->post_sample(adcsel);
285
286 /* check we have correct sample */
287 if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) {
288 dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
289 *sample & WM97XX_ADCSRC_MASK);
290 return RC_PENUP;
291 }
292
293 if (!(*sample & WM97XX_PEN_DOWN)) {
294 wm->pen_probably_down = 0;
295 return RC_PENUP;
296 }
297
298 return RC_VALID;
299}
300
301/*
302 * Read a coordinate from the WM9713 adc in polling mode.
303 */
304static int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
305{
306 u16 dig1;
307 int timeout = 5 * delay;
308
309 if (!wm->pen_probably_down) {
310 u16 val = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
311 if (!(val & WM97XX_PEN_DOWN))
312 return RC_PENUP;
313 wm->pen_probably_down = 1;
314 }
315
316 /* set up digitiser */
317 dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
318 dig1 &= ~WM9713_ADCSEL_MASK;
319 if (pil)
320 dig1 |= WM9713_ADCSEL_PRES;
321
322 if (wm->mach_ops && wm->mach_ops->pre_sample)
323 wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
324 wm97xx_reg_write(wm, AC97_WM9713_DIG1,
325 dig1 | WM9713_POLL | WM9713_COO);
326
327 /* wait 3 AC97 time slots + delay for conversion */
328 poll_delay(delay);
329 data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
330 /* wait for POLL to go low */
331 while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL)
332 && timeout) {
333 udelay(AC97_LINK_FRAME);
334 timeout--;
335 }
336
337 if (timeout <= 0) {
338 /* If PDEN is set, we can get a timeout when pen goes up */
339 if (is_pden(wm))
340 wm->pen_probably_down = 0;
341 else
342 dev_dbg(wm->dev, "adc sample timeout");
343 return RC_PENUP;
344 }
345
346 /* read back data */
347 data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
348 if (pil)
349 data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
350 else
351 data->p = DEFAULT_PRESSURE;
352
353 if (wm->mach_ops && wm->mach_ops->post_sample)
354 wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
355
356 /* check we have correct sample */
357 if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
358 goto err;
359 if (pil && !(data->p & WM97XX_ADCSEL_PRES))
360 goto err;
361
362 if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) {
363 wm->pen_probably_down = 0;
364 return RC_PENUP;
365 }
366 return RC_VALID;
367err:
368 return 0;
369}
370
371/*
372 * Sample the WM9713 touchscreen in polling mode
373 */
374static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
375{
376 int rc;
377
378 if (coord) {
379 rc = wm9713_poll_coord(wm, data);
380 if (rc != RC_VALID)
381 return rc;
382 } else {
383 rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x);
384 if (rc != RC_VALID)
385 return rc;
386 rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y);
387 if (rc != RC_VALID)
388 return rc;
389 if (pil) {
390 rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES,
391 &data->p);
392 if (rc != RC_VALID)
393 return rc;
394 } else
395 data->p = DEFAULT_PRESSURE;
396 }
397 return RC_VALID;
398}
399
400/*
401 * Enable WM9713 continuous mode, i.e. touch data is streamed across
402 * an AC97 slot
403 */
404static int wm9713_acc_enable(struct wm97xx *wm, int enable)
405{
406 u16 dig1, dig2, dig3;
407 int ret = 0;
408
409 dig1 = wm->dig[0];
410 dig2 = wm->dig[1];
411 dig3 = wm->dig[2];
412
413 if (enable) {
414 /* continous mode */
415 if (wm->mach_ops->acc_startup &&
416 (ret = wm->mach_ops->acc_startup(wm)) < 0)
417 return ret;
418
419 dig1 &= ~WM9713_ADCSEL_MASK;
420 dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X |
421 WM9713_ADCSEL_Y;
422 if (pil)
423 dig1 |= WM9713_ADCSEL_PRES;
424 dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK |
425 WM97XX_CM_RATE_MASK);
426 dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) |
427 WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate);
428 dig3 |= WM9713_PDEN;
429 } else {
430 dig1 &= ~(WM9713_CTC | WM9713_COO);
431 dig2 &= ~WM97XX_SLEN;
432 dig3 &= ~WM9713_PDEN;
433 if (wm->mach_ops->acc_shutdown)
434 wm->mach_ops->acc_shutdown(wm);
435 }
436
437 wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
438 wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
439 wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
440
441 return ret;
442}
443
444struct wm97xx_codec_drv wm9713_codec = {
445 .id = WM9713_ID2,
446 .name = "wm9713",
447 .poll_sample = wm9713_poll_sample,
448 .poll_touch = wm9713_poll_touch,
449 .acc_enable = wm9713_acc_enable,
450 .phy_init = wm9713_phy_init,
451 .dig_enable = wm9713_dig_enable,
452 .dig_restore = wm9713_dig_restore,
453 .aux_prepare = wm9713_aux_prepare,
454};
455EXPORT_SYMBOL_GPL(wm9713_codec);
456
457/* Module information */
458MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
459MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
460MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
new file mode 100644
index 00000000000..e9c7ea46b6e
--- /dev/null
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -0,0 +1,829 @@
1/*
2 * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712
3 * and WM9713 AC97 Codecs.
4 *
5 * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
8 * Parts Copyright : Ian Molton <spyro@f2s.com>
9 * Andrew Zabolotny <zap@homelink.ru>
10 * Russell King <rmk@arm.linux.org.uk>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * Notes:
18 *
19 * Features:
20 * - supports WM9705, WM9712, WM9713
21 * - polling mode
22 * - continuous mode (arch-dependent)
23 * - adjustable rpu/dpp settings
24 * - adjustable pressure current
25 * - adjustable sample settle delay
26 * - 4 and 5 wire touchscreens (5 wire is WM9712 only)
27 * - pen down detection
28 * - battery monitor
29 * - sample AUX adcs
30 * - power management
31 * - codec GPIO
32 * - codec event notification
33 * Todo
34 * - Support for async sampling control for noisy LCDs.
35 *
36 */
37
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/version.h>
41#include <linux/kernel.h>
42#include <linux/init.h>
43#include <linux/delay.h>
44#include <linux/string.h>
45#include <linux/proc_fs.h>
46#include <linux/pm.h>
47#include <linux/interrupt.h>
48#include <linux/bitops.h>
49#include <linux/workqueue.h>
50#include <linux/wm97xx.h>
51#include <linux/uaccess.h>
52#include <linux/io.h>
53
54#define TS_NAME "wm97xx"
55#define WM_CORE_VERSION "1.00"
56#define DEFAULT_PRESSURE 0xb0c0
57
58
59/*
60 * Touchscreen absolute values
61 *
62 * These parameters are used to help the input layer discard out of
63 * range readings and reduce jitter etc.
64 *
65 * o min, max:- indicate the min and max values your touch screen returns
66 * o fuzz:- use a higher number to reduce jitter
67 *
68 * The default values correspond to Mainstone II in QVGA mode
69 *
70 * Please read
71 * Documentation/input/input-programming.txt for more details.
72 */
73
74static int abs_x[3] = {350, 3900, 5};
75module_param_array(abs_x, int, NULL, 0);
76MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
77
78static int abs_y[3] = {320, 3750, 40};
79module_param_array(abs_y, int, NULL, 0);
80MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
81
82static int abs_p[3] = {0, 150, 4};
83module_param_array(abs_p, int, NULL, 0);
84MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");
85
86/*
87 * wm97xx IO access, all IO locking done by AC97 layer
88 */
89int wm97xx_reg_read(struct wm97xx *wm, u16 reg)
90{
91 if (wm->ac97)
92 return wm->ac97->bus->ops->read(wm->ac97, reg);
93 else
94 return -1;
95}
96EXPORT_SYMBOL_GPL(wm97xx_reg_read);
97
98void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val)
99{
100 /* cache digitiser registers */
101 if (reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3)
102 wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val;
103
104 /* cache gpio regs */
105 if (reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE)
106 wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val;
107
108 /* wm9713 irq reg */
109 if (reg == 0x5a)
110 wm->misc = val;
111
112 if (wm->ac97)
113 wm->ac97->bus->ops->write(wm->ac97, reg, val);
114}
115EXPORT_SYMBOL_GPL(wm97xx_reg_write);
116
117/**
118 * wm97xx_read_aux_adc - Read the aux adc.
119 * @wm: wm97xx device.
120 * @adcsel: codec ADC to be read
121 *
122 * Reads the selected AUX ADC.
123 */
124
125int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
126{
127 int power_adc = 0, auxval;
128 u16 power = 0;
129
130 /* get codec */
131 mutex_lock(&wm->codec_mutex);
132
133 /* When the touchscreen is not in use, we may have to power up
134 * the AUX ADC before we can use sample the AUX inputs->
135 */
136 if (wm->id == WM9713_ID2 &&
137 (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
138 power_adc = 1;
139 wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
140 }
141
142 /* Prepare the codec for AUX reading */
143 wm->codec->aux_prepare(wm);
144
145 /* Turn polling mode on to read AUX ADC */
146 wm->pen_probably_down = 1;
147 wm->codec->poll_sample(wm, adcsel, &auxval);
148
149 if (power_adc)
150 wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
151
152 wm->codec->dig_restore(wm);
153
154 wm->pen_probably_down = 0;
155
156 mutex_unlock(&wm->codec_mutex);
157 return auxval & 0xfff;
158}
159EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
160
161/**
162 * wm97xx_get_gpio - Get the status of a codec GPIO.
163 * @wm: wm97xx device.
164 * @gpio: gpio
165 *
166 * Get the status of a codec GPIO pin
167 */
168
169enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
170{
171 u16 status;
172 enum wm97xx_gpio_status ret;
173
174 mutex_lock(&wm->codec_mutex);
175 status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
176
177 if (status & gpio)
178 ret = WM97XX_GPIO_HIGH;
179 else
180 ret = WM97XX_GPIO_LOW;
181
182 mutex_unlock(&wm->codec_mutex);
183 return ret;
184}
185EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
186
187/**
188 * wm97xx_set_gpio - Set the status of a codec GPIO.
189 * @wm: wm97xx device.
190 * @gpio: gpio
191 *
192 *
193 * Set the status of a codec GPIO pin
194 */
195
196void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
197 enum wm97xx_gpio_status status)
198{
199 u16 reg;
200
201 mutex_lock(&wm->codec_mutex);
202 reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
203
204 if (status & WM97XX_GPIO_HIGH)
205 reg |= gpio;
206 else
207 reg &= ~gpio;
208
209 if (wm->id == WM9712_ID2)
210 wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
211 else
212 wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
213 mutex_unlock(&wm->codec_mutex);
214}
215EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
216
217/*
218 * Codec GPIO pin configuration, this sets pin direction, polarity,
219 * stickyness and wake up.
220 */
221void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir,
222 enum wm97xx_gpio_pol pol, enum wm97xx_gpio_sticky sticky,
223 enum wm97xx_gpio_wake wake)
224{
225 u16 reg;
226
227 mutex_lock(&wm->codec_mutex);
228 reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
229
230 if (pol == WM97XX_GPIO_POL_HIGH)
231 reg |= gpio;
232 else
233 reg &= ~gpio;
234
235 wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg);
236 reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
237
238 if (sticky == WM97XX_GPIO_STICKY)
239 reg |= gpio;
240 else
241 reg &= ~gpio;
242
243 wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg);
244 reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
245
246 if (wake == WM97XX_GPIO_WAKE)
247 reg |= gpio;
248 else
249 reg &= ~gpio;
250
251 wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg);
252 reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
253
254 if (dir == WM97XX_GPIO_IN)
255 reg |= gpio;
256 else
257 reg &= ~gpio;
258
259 wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
260 mutex_unlock(&wm->codec_mutex);
261}
262EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
263
264/*
265 * Configure the WM97XX_PRP value to use while system is suspended.
266 * If a value other than 0 is set then WM97xx pen detection will be
267 * left enabled in the configured mode while the system is in suspend,
268 * the device has users and suspend has not been disabled via the
269 * wakeup sysfs entries.
270 *
271 * @wm: WM97xx device to configure
272 * @mode: WM97XX_PRP value to configure while suspended
273 */
274void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode)
275{
276 wm->suspend_mode = mode;
277 device_init_wakeup(&wm->input_dev->dev, mode != 0);
278}
279EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode);
280
281/*
282 * Handle a pen down interrupt.
283 */
284static void wm97xx_pen_irq_worker(struct work_struct *work)
285{
286 struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work);
287 int pen_was_down = wm->pen_is_down;
288
289 /* do we need to enable the touch panel reader */
290 if (wm->id == WM9705_ID2) {
291 if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) &
292 WM97XX_PEN_DOWN)
293 wm->pen_is_down = 1;
294 else
295 wm->pen_is_down = 0;
296 } else {
297 u16 status, pol;
298 mutex_lock(&wm->codec_mutex);
299 status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
300 pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
301
302 if (WM97XX_GPIO_13 & pol & status) {
303 wm->pen_is_down = 1;
304 wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol &
305 ~WM97XX_GPIO_13);
306 } else {
307 wm->pen_is_down = 0;
308 wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol |
309 WM97XX_GPIO_13);
310 }
311
312 if (wm->id == WM9712_ID2)
313 wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status &
314 ~WM97XX_GPIO_13) << 1);
315 else
316 wm97xx_reg_write(wm, AC97_GPIO_STATUS, status &
317 ~WM97XX_GPIO_13);
318 mutex_unlock(&wm->codec_mutex);
319 }
320
321 /* If the system is not using continuous mode or it provides a
322 * pen down operation then we need to schedule polls while the
323 * pen is down. Otherwise the machine driver is responsible
324 * for scheduling reads.
325 */
326 if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) {
327 if (wm->pen_is_down && !pen_was_down) {
328 /* Data is not availiable immediately on pen down */
329 queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1);
330 }
331
332 /* Let ts_reader report the pen up for debounce. */
333 if (!wm->pen_is_down && pen_was_down)
334 wm->pen_is_down = 1;
335 }
336
337 if (!wm->pen_is_down && wm->mach_ops->acc_enabled)
338 wm->mach_ops->acc_pen_up(wm);
339
340 wm->mach_ops->irq_enable(wm, 1);
341}
342
343/*
344 * Codec PENDOWN irq handler
345 *
346 * We have to disable the codec interrupt in the handler because it
347 * can take upto 1ms to clear the interrupt source. We schedule a task
348 * in a work queue to do the actual interaction with the chip. The
349 * interrupt is then enabled again in the slow handler when the source
350 * has been cleared.
351 */
352static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
353{
354 struct wm97xx *wm = dev_id;
355
356 if (!work_pending(&wm->pen_event_work)) {
357 wm->mach_ops->irq_enable(wm, 0);
358 queue_work(wm->ts_workq, &wm->pen_event_work);
359 }
360
361 return IRQ_HANDLED;
362}
363
364/*
365 * initialise pen IRQ handler and workqueue
366 */
367static int wm97xx_init_pen_irq(struct wm97xx *wm)
368{
369 u16 reg;
370
371 /* If an interrupt is supplied an IRQ enable operation must also be
372 * provided. */
373 BUG_ON(!wm->mach_ops->irq_enable);
374
375 if (request_irq(wm->pen_irq, wm97xx_pen_interrupt,
376 IRQF_SHARED | IRQF_SAMPLE_RANDOM,
377 "wm97xx-pen", wm)) {
378 dev_err(wm->dev,
379 "Failed to register pen down interrupt, polling");
380 wm->pen_irq = 0;
381 return -EINVAL;
382 }
383
384 /* Configure GPIO as interrupt source on WM971x */
385 if (wm->id != WM9705_ID2) {
386 BUG_ON(!wm->mach_ops->irq_gpio);
387 reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
388 wm97xx_reg_write(wm, AC97_MISC_AFE,
389 reg & ~(wm->mach_ops->irq_gpio));
390 reg = wm97xx_reg_read(wm, 0x5a);
391 wm97xx_reg_write(wm, 0x5a, reg & ~0x0001);
392 }
393
394 return 0;
395}
396
397static int wm97xx_read_samples(struct wm97xx *wm)
398{
399 struct wm97xx_data data;
400 int rc;
401
402 mutex_lock(&wm->codec_mutex);
403
404 if (wm->mach_ops && wm->mach_ops->acc_enabled)
405 rc = wm->mach_ops->acc_pen_down(wm);
406 else
407 rc = wm->codec->poll_touch(wm, &data);
408
409 if (rc & RC_PENUP) {
410 if (wm->pen_is_down) {
411 wm->pen_is_down = 0;
412 dev_dbg(wm->dev, "pen up\n");
413 input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
414 input_sync(wm->input_dev);
415 } else if (!(rc & RC_AGAIN)) {
416 /* We need high frequency updates only while
417 * pen is down, the user never will be able to
418 * touch screen faster than a few times per
419 * second... On the other hand, when the user
420 * is actively working with the touchscreen we
421 * don't want to lose the quick response. So we
422 * will slowly increase sleep time after the
423 * pen is up and quicky restore it to ~one task
424 * switch when pen is down again.
425 */
426 if (wm->ts_reader_interval < HZ / 10)
427 wm->ts_reader_interval++;
428 }
429
430 } else if (rc & RC_VALID) {
431 dev_dbg(wm->dev,
432 "pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n",
433 data.x >> 12, data.x & 0xfff, data.y >> 12,
434 data.y & 0xfff, data.p >> 12, data.p & 0xfff);
435 input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
436 input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
437 input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
438 input_sync(wm->input_dev);
439 wm->pen_is_down = 1;
440 wm->ts_reader_interval = wm->ts_reader_min_interval;
441 } else if (rc & RC_PENDOWN) {
442 dev_dbg(wm->dev, "pen down\n");
443 wm->pen_is_down = 1;
444 wm->ts_reader_interval = wm->ts_reader_min_interval;
445 }
446
447 mutex_unlock(&wm->codec_mutex);
448 return rc;
449}
450
451/*
452* The touchscreen sample reader.
453*/
454static void wm97xx_ts_reader(struct work_struct *work)
455{
456 int rc;
457 struct wm97xx *wm = container_of(work, struct wm97xx, ts_reader.work);
458
459 BUG_ON(!wm->codec);
460
461 do {
462 rc = wm97xx_read_samples(wm);
463 } while (rc & RC_AGAIN);
464
465 if (wm->pen_is_down || !wm->pen_irq)
466 queue_delayed_work(wm->ts_workq, &wm->ts_reader,
467 wm->ts_reader_interval);
468}
469
470/**
471 * wm97xx_ts_input_open - Open the touch screen input device.
472 * @idev: Input device to be opened.
473 *
474 * Called by the input sub system to open a wm97xx touchscreen device.
475 * Starts the touchscreen thread and touch digitiser.
476 */
477static int wm97xx_ts_input_open(struct input_dev *idev)
478{
479 struct wm97xx *wm = input_get_drvdata(idev);
480
481 wm->ts_workq = create_singlethread_workqueue("kwm97xx");
482 if (wm->ts_workq == NULL) {
483 dev_err(wm->dev,
484 "Failed to create workqueue\n");
485 return -EINVAL;
486 }
487
488 /* start digitiser */
489 if (wm->mach_ops && wm->mach_ops->acc_enabled)
490 wm->codec->acc_enable(wm, 1);
491 wm->codec->dig_enable(wm, 1);
492
493 INIT_DELAYED_WORK(&wm->ts_reader, wm97xx_ts_reader);
494 INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker);
495
496 wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1;
497 if (wm->ts_reader_min_interval < 1)
498 wm->ts_reader_min_interval = 1;
499 wm->ts_reader_interval = wm->ts_reader_min_interval;
500
501 wm->pen_is_down = 0;
502 if (wm->pen_irq)
503 wm97xx_init_pen_irq(wm);
504 else
505 dev_err(wm->dev, "No IRQ specified\n");
506
507 /* If we either don't have an interrupt for pen down events or
508 * failed to acquire it then we need to poll.
509 */
510 if (wm->pen_irq == 0)
511 queue_delayed_work(wm->ts_workq, &wm->ts_reader,
512 wm->ts_reader_interval);
513
514 return 0;
515}
516
517/**
518 * wm97xx_ts_input_close - Close the touch screen input device.
519 * @idev: Input device to be closed.
520 *
521 * Called by the input sub system to close a wm97xx touchscreen
522 * device. Kills the touchscreen thread and stops the touch
523 * digitiser.
524 */
525
526static void wm97xx_ts_input_close(struct input_dev *idev)
527{
528 struct wm97xx *wm = input_get_drvdata(idev);
529 u16 reg;
530
531 if (wm->pen_irq) {
532 /* Return the interrupt to GPIO usage (disabling it) */
533 if (wm->id != WM9705_ID2) {
534 BUG_ON(!wm->mach_ops->irq_gpio);
535 reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
536 wm97xx_reg_write(wm, AC97_MISC_AFE,
537 reg | wm->mach_ops->irq_gpio);
538 }
539
540 free_irq(wm->pen_irq, wm);
541 }
542
543 wm->pen_is_down = 0;
544
545 /* Balance out interrupt disables/enables */
546 if (cancel_work_sync(&wm->pen_event_work))
547 wm->mach_ops->irq_enable(wm, 1);
548
549 /* ts_reader rearms itself so we need to explicitly stop it
550 * before we destroy the workqueue.
551 */
552 cancel_delayed_work_sync(&wm->ts_reader);
553
554 destroy_workqueue(wm->ts_workq);
555
556 /* stop digitiser */
557 wm->codec->dig_enable(wm, 0);
558 if (wm->mach_ops && wm->mach_ops->acc_enabled)
559 wm->codec->acc_enable(wm, 0);
560}
561
562static int wm97xx_probe(struct device *dev)
563{
564 struct wm97xx *wm;
565 int ret = 0, id = 0;
566
567 wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL);
568 if (!wm)
569 return -ENOMEM;
570 mutex_init(&wm->codec_mutex);
571
572 wm->dev = dev;
573 dev->driver_data = wm;
574 wm->ac97 = to_ac97_t(dev);
575
576 /* check that we have a supported codec */
577 id = wm97xx_reg_read(wm, AC97_VENDOR_ID1);
578 if (id != WM97XX_ID1) {
579 dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id);
580 ret = -ENODEV;
581 goto alloc_err;
582 }
583
584 wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
585
586 dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff);
587
588 switch (wm->id & 0xff) {
589#ifdef CONFIG_TOUCHSCREEN_WM9705
590 case 0x05:
591 wm->codec = &wm9705_codec;
592 break;
593#endif
594#ifdef CONFIG_TOUCHSCREEN_WM9712
595 case 0x12:
596 wm->codec = &wm9712_codec;
597 break;
598#endif
599#ifdef CONFIG_TOUCHSCREEN_WM9713
600 case 0x13:
601 wm->codec = &wm9713_codec;
602 break;
603#endif
604 default:
605 dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
606 wm->id & 0xff);
607 ret = -ENODEV;
608 goto alloc_err;
609 }
610
611 wm->input_dev = input_allocate_device();
612 if (wm->input_dev == NULL) {
613 ret = -ENOMEM;
614 goto alloc_err;
615 }
616
617 /* set up touch configuration */
618 wm->input_dev->name = "wm97xx touchscreen";
619 wm->input_dev->open = wm97xx_ts_input_open;
620 wm->input_dev->close = wm97xx_ts_input_close;
621 set_bit(EV_ABS, wm->input_dev->evbit);
622 set_bit(ABS_X, wm->input_dev->absbit);
623 set_bit(ABS_Y, wm->input_dev->absbit);
624 set_bit(ABS_PRESSURE, wm->input_dev->absbit);
625 input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
626 abs_x[2], 0);
627 input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
628 abs_y[2], 0);
629 input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
630 abs_p[2], 0);
631 input_set_drvdata(wm->input_dev, wm);
632 wm->input_dev->dev.parent = dev;
633 ret = input_register_device(wm->input_dev);
634 if (ret < 0)
635 goto dev_alloc_err;
636
637 /* set up physical characteristics */
638 wm->codec->phy_init(wm);
639
640 /* load gpio cache */
641 wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG);
642 wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
643 wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
644 wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
645 wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
646 wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
647
648 /* register our battery device */
649 wm->battery_dev = platform_device_alloc("wm97xx-battery", -1);
650 if (!wm->battery_dev) {
651 ret = -ENOMEM;
652 goto batt_err;
653 }
654 platform_set_drvdata(wm->battery_dev, wm);
655 wm->battery_dev->dev.parent = dev;
656 ret = platform_device_add(wm->battery_dev);
657 if (ret < 0)
658 goto batt_reg_err;
659
660 /* register our extended touch device (for machine specific
661 * extensions) */
662 wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
663 if (!wm->touch_dev) {
664 ret = -ENOMEM;
665 goto touch_err;
666 }
667 platform_set_drvdata(wm->touch_dev, wm);
668 wm->touch_dev->dev.parent = dev;
669 ret = platform_device_add(wm->touch_dev);
670 if (ret < 0)
671 goto touch_reg_err;
672
673 return ret;
674
675 touch_reg_err:
676 platform_device_put(wm->touch_dev);
677 touch_err:
678 platform_device_unregister(wm->battery_dev);
679 wm->battery_dev = NULL;
680 batt_reg_err:
681 platform_device_put(wm->battery_dev);
682 batt_err:
683 input_unregister_device(wm->input_dev);
684 wm->input_dev = NULL;
685 dev_alloc_err:
686 input_free_device(wm->input_dev);
687 alloc_err:
688 kfree(wm);
689
690 return ret;
691}
692
693static int wm97xx_remove(struct device *dev)
694{
695 struct wm97xx *wm = dev_get_drvdata(dev);
696
697 platform_device_unregister(wm->battery_dev);
698 platform_device_unregister(wm->touch_dev);
699 input_unregister_device(wm->input_dev);
700 kfree(wm);
701
702 return 0;
703}
704
705#ifdef CONFIG_PM
706static int wm97xx_suspend(struct device *dev, pm_message_t state)
707{
708 struct wm97xx *wm = dev_get_drvdata(dev);
709 u16 reg;
710 int suspend_mode;
711
712 if (device_may_wakeup(&wm->input_dev->dev))
713 suspend_mode = wm->suspend_mode;
714 else
715 suspend_mode = 0;
716
717 if (wm->input_dev->users)
718 cancel_delayed_work_sync(&wm->ts_reader);
719
720 /* Power down the digitiser (bypassing the cache for resume) */
721 reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2);
722 reg &= ~WM97XX_PRP_DET_DIG;
723 if (wm->input_dev->users)
724 reg |= suspend_mode;
725 wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg);
726
727 /* WM9713 has an additional power bit - turn it off if there
728 * are no users or if suspend mode is zero. */
729 if (wm->id == WM9713_ID2 &&
730 (!wm->input_dev->users || !suspend_mode)) {
731 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
732 wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
733 }
734
735 return 0;
736}
737
738static int wm97xx_resume(struct device *dev)
739{
740 struct wm97xx *wm = dev_get_drvdata(dev);
741
742 /* restore digitiser and gpios */
743 if (wm->id == WM9713_ID2) {
744 wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
745 wm97xx_reg_write(wm, 0x5a, wm->misc);
746 if (wm->input_dev->users) {
747 u16 reg;
748 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
749 wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
750 }
751 }
752
753 wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]);
754 wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]);
755
756 wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]);
757 wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]);
758 wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]);
759 wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]);
760 wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
761 wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
762
763 if (wm->input_dev->users && !wm->pen_irq) {
764 wm->ts_reader_interval = wm->ts_reader_min_interval;
765 queue_delayed_work(wm->ts_workq, &wm->ts_reader,
766 wm->ts_reader_interval);
767 }
768
769 return 0;
770}
771
772#else
773#define wm97xx_suspend NULL
774#define wm97xx_resume NULL
775#endif
776
777/*
778 * Machine specific operations
779 */
780int wm97xx_register_mach_ops(struct wm97xx *wm,
781 struct wm97xx_mach_ops *mach_ops)
782{
783 mutex_lock(&wm->codec_mutex);
784 if (wm->mach_ops) {
785 mutex_unlock(&wm->codec_mutex);
786 return -EINVAL;
787 }
788 wm->mach_ops = mach_ops;
789 mutex_unlock(&wm->codec_mutex);
790
791 return 0;
792}
793EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
794
795void wm97xx_unregister_mach_ops(struct wm97xx *wm)
796{
797 mutex_lock(&wm->codec_mutex);
798 wm->mach_ops = NULL;
799 mutex_unlock(&wm->codec_mutex);
800}
801EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
802
803static struct device_driver wm97xx_driver = {
804 .name = "ac97",
805 .bus = &ac97_bus_type,
806 .owner = THIS_MODULE,
807 .probe = wm97xx_probe,
808 .remove = wm97xx_remove,
809 .suspend = wm97xx_suspend,
810 .resume = wm97xx_resume,
811};
812
813static int __init wm97xx_init(void)
814{
815 return driver_register(&wm97xx_driver);
816}
817
818static void __exit wm97xx_exit(void)
819{
820 driver_unregister(&wm97xx_driver);
821}
822
823module_init(wm97xx_init);
824module_exit(wm97xx_exit);
825
826/* Module information */
827MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
828MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
829MODULE_LICENSE("GPL");