summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch2899
1 files changed, 2899 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch
new file mode 100644
index 0000000000..c918c5daff
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch
@@ -0,0 +1,2899 @@
1Index: linux-2.6.17/drivers/input/touchscreen/Kconfig
2===================================================================
3--- linux-2.6.17.orig/drivers/input/touchscreen/Kconfig 2006-09-19 20:35:35.060495500 +0200
4+++ linux-2.6.17/drivers/input/touchscreen/Kconfig 2006-09-19 20:36:47.965051750 +0200
5@@ -121,4 +121,57 @@ config TOUCHSCREEN_TSC2101
6 To compile this driver as a module, choose M here: the
7 module will be called ads7846_ts.
8
9+config TOUCHSCREEN_WM97XX
10+ tristate "Support for WM97xx AC97 touchscreen controllers"
11+ depends SND_AC97_BUS
12+
13+choice
14+ prompt "WM97xx codec type"
15+
16+config TOUCHSCREEN_WM9705
17+ bool "WM9705 Touchscreen interface support"
18+ depends on TOUCHSCREEN_WM97XX
19+ help
20+ Say Y here if you have the wm9705 touchscreen.
21+
22+ If unsure, say N.
23+
24+ To compile this driver as a module, choose M here: the
25+ module will be called wm9705.
26+
27+config TOUCHSCREEN_WM9712
28+ bool "WM9712 Touchscreen interface support"
29+ depends on TOUCHSCREEN_WM97XX
30+ help
31+ Say Y here if you have the wm9712 touchscreen.
32+
33+ If unsure, say N.
34+
35+ To compile this driver as a module, choose M here: the
36+ module will be called wm9712.
37+
38+config TOUCHSCREEN_WM9713
39+ bool "WM9713 Touchscreen interface support"
40+ depends on TOUCHSCREEN_WM97XX
41+ help
42+ Say Y here if you have the wm9713 touchscreen.
43+
44+ If unsure, say N.
45+
46+ To compile this driver as a module, choose M here: the
47+ module will be called wm9713.
48+
49+endchoice
50+
51+config TOUCHSCREEN_WM97XX_PXA
52+ tristate "WM97xx PXA accelerated touch"
53+ depends on TOUCHSCREEN_WM97XX && ARCH_PXA
54+ help
55+ Say Y here for continuous mode touch on the PXA
56+
57+ If unsure, say N
58+
59+ To compile this driver as a module, choose M here: the
60+ module will be called pxa-wm97xx
61+
62 endif
63Index: linux-2.6.17/drivers/input/touchscreen/Makefile
64===================================================================
65--- linux-2.6.17.orig/drivers/input/touchscreen/Makefile 2006-09-19 20:35:35.072496250 +0200
66+++ linux-2.6.17/drivers/input/touchscreen/Makefile 2006-09-19 20:37:40.540337500 +0200
67@@ -4,6 +4,8 @@
68
69 # Each configuration option enables a list of files.
70
71+wm97xx-ts-objs := wm97xx-core.o
72+
73 obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
74 obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
75 obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
76@@ -13,3 +15,16 @@ obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtou
77 obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
78 obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
79 obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o
80+obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
81+obj-$(CONFIG_TOUCHSCREEN_WM97XX_PXA) += pxa-wm97xx.o
82+
83+ifeq ($(CONFIG_TOUCHSCREEN_WM9713),y)
84+wm97xx-ts-objs += wm9713.o
85+endif
86+
87+ifeq ($(CONFIG_TOUCHSCREEN_WM9712),y)
88+wm97xx-ts-objs += wm9712.o
89+endif
90+ifeq ($(CONFIG_TOUCHSCREEN_WM9705),y)
91+wm97xx-ts-objs += wm9705.o
92+endif
93Index: linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c
94===================================================================
95--- /dev/null 1970-01-01 00:00:00.000000000 +0000
96+++ linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c 2006-09-19 20:36:47.965051750 +0200
97@@ -0,0 +1,289 @@
98+/*
99+ * pxa-wm97xx.c -- pxa-wm97xx Continuous Touch screen driver for
100+ * Wolfson WM97xx AC97 Codecs.
101+ *
102+ * Copyright 2004 Wolfson Microelectronics PLC.
103+ * Author: Liam Girdwood
104+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
105+ * Parts Copyright : Ian Molton <spyro@f2s.com>
106+ * Andrew Zabolotny <zap@homelink.ru>
107+ *
108+ * This program is free software; you can redistribute it and/or modify it
109+ * under the terms of the GNU General Public License as published by the
110+ * Free Software Foundation; either version 2 of the License, or (at your
111+ * option) any later version.
112+ *
113+ * Notes:
114+ * This is a wm97xx extended touch driver to capture touch
115+ * data in a continuous manner on the Intel XScale archictecture
116+ *
117+ * Features:
118+ * - codecs supported:- WM9705, WM9712, WM9713
119+ * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
120+ *
121+ * Revision history
122+ * 18th Aug 2004 Initial version.
123+ * 26th Jul 2005 Improved continous read back and added FIFO flushing.
124+ * 06th Sep 2005 Mike Arthur <linux@wolfsonmicro.com>
125+ * Moved to using the wm97xx bus
126+ *
127+ */
128+
129+#include <linux/module.h>
130+#include <linux/moduleparam.h>
131+#include <linux/version.h>
132+#include <linux/kernel.h>
133+#include <linux/init.h>
134+#include <linux/delay.h>
135+#include <linux/irq.h>
136+#include <linux/wm97xx.h>
137+#include <asm/io.h>
138+#include <asm/arch/pxa-regs.h>
139+
140+#define VERSION "0.13"
141+
142+struct continuous {
143+ u16 id; /* codec id */
144+ u8 code; /* continuous code */
145+ u8 reads; /* number of coord reads per read cycle */
146+ u32 speed; /* number of coords per second */
147+};
148+
149+#define WM_READS(sp) ((sp / HZ) + 1)
150+
151+static const struct continuous cinfo[] = {
152+ {WM9705_ID2, 0, WM_READS(94), 94},
153+ {WM9705_ID2, 1, WM_READS(188), 188},
154+ {WM9705_ID2, 2, WM_READS(375), 375},
155+ {WM9705_ID2, 3, WM_READS(750), 750},
156+ {WM9712_ID2, 0, WM_READS(94), 94},
157+ {WM9712_ID2, 1, WM_READS(188), 188},
158+ {WM9712_ID2, 2, WM_READS(375), 375},
159+ {WM9712_ID2, 3, WM_READS(750), 750},
160+ {WM9713_ID2, 0, WM_READS(94), 94},
161+ {WM9713_ID2, 1, WM_READS(120), 120},
162+ {WM9713_ID2, 2, WM_READS(154), 154},
163+ {WM9713_ID2, 3, WM_READS(188), 188},
164+};
165+
166+/* continuous speed index */
167+static int sp_idx = 0;
168+static u16 last = 0, tries = 0;
169+
170+/*
171+ * Pen sampling frequency (Hz) in continuous mode.
172+ */
173+static int cont_rate = 200;
174+module_param(cont_rate, int, 0);
175+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
176+
177+/*
178+ * Pen down detection.
179+ *
180+ * This driver can either poll or use an interrupt to indicate a pen down
181+ * event. If the irq request fails then it will fall back to polling mode.
182+ */
183+static int pen_int = 1;
184+module_param(pen_int, int, 0);
185+MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
186+
187+/*
188+ * Pressure readback.
189+ *
190+ * Set to 1 to read back pen down pressure
191+ */
192+static int pressure = 0;
193+module_param(pressure, int, 0);
194+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
195+
196+/*
197+ * AC97 touch data slot.
198+ *
199+ * Touch screen readback data ac97 slot
200+ */
201+static int ac97_touch_slot = 5;
202+module_param(ac97_touch_slot, int, 0);
203+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
204+
205+
206+/* flush AC97 slot 5 FIFO on pxa machines */
207+#ifdef CONFIG_PXA27x
208+void wm97xx_acc_pen_up (struct wm97xx* wm)
209+{
210+ set_current_state(TASK_INTERRUPTIBLE);
211+ schedule_timeout(1);
212+
213+ while (MISR & (1 << 2))
214+ MODR;
215+}
216+#else
217+void wm97xx_acc_pen_up (struct wm97xx* wm)
218+{
219+ int count = 16;
220+ set_current_state(TASK_INTERRUPTIBLE);
221+ schedule_timeout(1);
222+
223+ while (count < 16) {
224+ MODR;
225+ count--;
226+ }
227+}
228+#endif
229+
230+int wm97xx_acc_pen_down (struct wm97xx* wm)
231+{
232+ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
233+ int reads = 0;
234+
235+ /* data is never immediately available after pen down irq */
236+ set_current_state(TASK_INTERRUPTIBLE);
237+ schedule_timeout(1);
238+
239+ if (tries > 5){
240+ tries = 0;
241+ return RC_PENUP;
242+ }
243+
244+ x = MODR;
245+ if (x == last) {
246+ tries++;
247+ return RC_AGAIN;
248+ }
249+ last = x;
250+ do {
251+ if (reads)
252+ x= MODR;
253+ y= MODR;
254+ if (pressure)
255+ p = MODR;
256+
257+ /* are samples valid */
258+ if ((x & 0x7000) != WM97XX_ADCSEL_X ||
259+ (y & 0x7000) != WM97XX_ADCSEL_Y ||
260+ (p & 0x7000) != WM97XX_ADCSEL_PRES)
261+ goto up;
262+
263+ /* coordinate is good */
264+ tries = 0;
265+ //printk("x %x y %x p %x\n", x,y,p);
266+ input_report_abs (wm->input_dev, ABS_X, x & 0xfff);
267+ input_report_abs (wm->input_dev, ABS_Y, y & 0xfff);
268+ input_report_abs (wm->input_dev, ABS_PRESSURE, p & 0xfff);
269+ input_sync (wm->input_dev);
270+ reads++;
271+ } while (reads < cinfo[sp_idx].reads);
272+up:
273+ return RC_PENDOWN | RC_AGAIN;
274+}
275+
276+int wm97xx_acc_startup(struct wm97xx* wm)
277+{
278+ int idx = 0;
279+
280+ /* check we have a codec */
281+ if (wm->ac97 == NULL)
282+ return -ENODEV;
283+
284+ /* Go you big red fire engine */
285+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
286+ if (wm->id != cinfo[idx].id)
287+ continue;
288+ sp_idx = idx;
289+ if (cont_rate <= cinfo[idx].speed)
290+ break;
291+ }
292+ wm->acc_rate = cinfo[sp_idx].code;
293+ wm->acc_slot = ac97_touch_slot;
294+ printk(KERN_INFO "pxa2xx accelerated touchscreen driver, %d samples (sec)\n",
295+ cinfo[sp_idx].speed);
296+
297+ /* codec specific irq config */
298+ if (pen_int) {
299+ switch (wm->id) {
300+ case WM9705_ID2:
301+ wm->pen_irq = IRQ_GPIO(4);
302+ set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
303+ break;
304+ case WM9712_ID2:
305+ case WM9713_ID2:
306+ /* enable pen down interrupt */
307+ /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
308+ wm->pen_irq = MAINSTONE_AC97_IRQ;
309+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
310+ WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_STICKY, WM97XX_GPIO_WAKE);
311+ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
312+ WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
313+ break;
314+ default:
315+ printk(KERN_WARNING "pen down irq not supported on this device\n");
316+ pen_int = 0;
317+ break;
318+ }
319+ }
320+
321+ return 0;
322+}
323+
324+void wm97xx_acc_shutdown(struct wm97xx* wm)
325+{
326+ /* codec specific deconfig */
327+ if (pen_int) {
328+ switch (wm->id & 0xffff) {
329+ case WM9705_ID2:
330+ wm->pen_irq = 0;
331+ break;
332+ case WM9712_ID2:
333+ case WM9713_ID2:
334+ /* disable interrupt */
335+ wm->pen_irq = 0;
336+ break;
337+ }
338+ }
339+}
340+
341+static struct wm97xx_mach_ops pxa_mach_ops = {
342+ .acc_enabled = 1,
343+ .acc_pen_up = wm97xx_acc_pen_up,
344+ .acc_pen_down = wm97xx_acc_pen_down,
345+ .acc_startup = wm97xx_acc_startup,
346+ .acc_shutdown = wm97xx_acc_shutdown,
347+};
348+
349+int pxa_wm97xx_probe(struct device *dev)
350+{
351+ struct wm97xx *wm = dev->driver_data;
352+ return wm97xx_register_mach_ops (wm, &pxa_mach_ops);
353+}
354+
355+int pxa_wm97xx_remove(struct device *dev)
356+{
357+ struct wm97xx *wm = dev->driver_data;
358+ wm97xx_unregister_mach_ops (wm);
359+ return 0;
360+}
361+
362+static struct device_driver pxa_wm97xx_driver = {
363+ .name = "wm97xx-touchscreen",
364+ .bus = &wm97xx_bus_type,
365+ .owner = THIS_MODULE,
366+ .probe = pxa_wm97xx_probe,
367+ .remove = pxa_wm97xx_remove
368+};
369+
370+static int __init pxa_wm97xx_init(void)
371+{
372+ return driver_register(&pxa_wm97xx_driver);
373+}
374+
375+static void __exit pxa_wm97xx_exit(void)
376+{
377+ driver_unregister(&pxa_wm97xx_driver);
378+}
379+
380+module_init(pxa_wm97xx_init);
381+module_exit(pxa_wm97xx_exit);
382+
383+/* Module information */
384+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
385+MODULE_DESCRIPTION("wm97xx continuous touch driver for pxa2xx");
386+MODULE_LICENSE("GPL");
387Index: linux-2.6.17/drivers/input/touchscreen/wm9705.c
388===================================================================
389--- /dev/null 1970-01-01 00:00:00.000000000 +0000
390+++ linux-2.6.17/drivers/input/touchscreen/wm9705.c 2006-09-19 20:36:47.969052000 +0200
391@@ -0,0 +1,360 @@
392+/*
393+ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
394+ *
395+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
396+ * Author: Liam Girdwood
397+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
398+ * Parts Copyright : Ian Molton <spyro@f2s.com>
399+ * Andrew Zabolotny <zap@homelink.ru>
400+ * Russell King <rmk@arm.linux.org.uk>
401+ *
402+ * This program is free software; you can redistribute it and/or modify it
403+ * under the terms of the GNU General Public License as published by the
404+ * Free Software Foundation; either version 2 of the License, or (at your
405+ * option) any later version.
406+ *
407+ * Revision history
408+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
409+ * Added pre and post sample calls.
410+ *
411+ */
412+
413+#include <linux/module.h>
414+#include <linux/moduleparam.h>
415+#include <linux/version.h>
416+#include <linux/kernel.h>
417+#include <linux/input.h>
418+#include <linux/delay.h>
419+#include <linux/bitops.h>
420+#include <linux/wm97xx.h>
421+
422+#define TS_NAME "wm97xx"
423+#define WM9705_VERSION "0.62"
424+#define DEFAULT_PRESSURE 0xb0c0
425+
426+/*
427+ * Debug
428+ */
429+#if 0
430+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
431+#else
432+#define dbg(format, arg...)
433+#endif
434+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
435+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
436+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
437+
438+/*
439+ * Module parameters
440+ */
441+
442+/*
443+ * Set current used for pressure measurement.
444+ *
445+ * Set pil = 2 to use 400uA
446+ * pil = 1 to use 200uA and
447+ * pil = 0 to disable pressure measurement.
448+ *
449+ * This is used to increase the range of values returned by the adc
450+ * when measureing touchpanel pressure.
451+ */
452+static int pil = 0;
453+module_param(pil, int, 0);
454+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
455+
456+/*
457+ * Set threshold for pressure measurement.
458+ *
459+ * Pen down pressure below threshold is ignored.
460+ */
461+static int pressure = DEFAULT_PRESSURE & 0xfff;
462+module_param(pressure, int, 0);
463+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
464+
465+/*
466+ * Set adc sample delay.
467+ *
468+ * For accurate touchpanel measurements, some settling time may be
469+ * required between the switch matrix applying a voltage across the
470+ * touchpanel plate and the ADC sampling the signal.
471+ *
472+ * This delay can be set by setting delay = n, where n is the array
473+ * position of the delay in the array delay_table below.
474+ * Long delays > 1ms are supported for completeness, but are not
475+ * recommended.
476+ */
477+static int delay = 4;
478+module_param(delay, int, 0);
479+MODULE_PARM_DESC(delay, "Set adc sample delay.");
480+
481+/*
482+ * Pen detect comparator threshold.
483+ *
484+ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
485+ * i.e. 1 = Vmid/15 threshold
486+ * 15 = Vmid/1 threshold
487+ *
488+ * Adjust this value if you are having problems with pen detect not
489+ * detecting any down events.
490+ */
491+static int pdd = 8;
492+module_param(pdd, int, 0);
493+MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold");
494+
495+/*
496+ * Set adc mask function.
497+ *
498+ * Sources of glitch noise, such as signals driving an LCD display, may feed
499+ * through to the touch screen plates and affect measurement accuracy. In
500+ * order to minimise this, a signal may be applied to the MASK pin to delay or
501+ * synchronise the sampling.
502+ *
503+ * 0 = No delay or sync
504+ * 1 = High on pin stops conversions
505+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
506+ * 3 = Edge triggered, edge on pin starts conversion after delay param
507+ */
508+static int mask = 0;
509+module_param(mask, int, 0);
510+MODULE_PARM_DESC(mask, "Set adc mask function.");
511+
512+/*
513+ * ADC sample delay times in uS
514+ */
515+static const int delay_table[] = {
516+ 21, // 1 AC97 Link frames
517+ 42, // 2
518+ 84, // 4
519+ 167, // 8
520+ 333, // 16
521+ 667, // 32
522+ 1000, // 48
523+ 1333, // 64
524+ 2000, // 96
525+ 2667, // 128
526+ 3333, // 160
527+ 4000, // 192
528+ 4667, // 224
529+ 5333, // 256
530+ 6000, // 288
531+ 0 // No delay, switch matrix always on
532+};
533+
534+/*
535+ * Delay after issuing a POLL command.
536+ *
537+ * The delay is 3 AC97 link frames + the touchpanel settling delay
538+ */
539+static inline void poll_delay(int d)
540+{
541+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
542+}
543+
544+/*
545+ * set up the physical settings of the WM9705
546+ */
547+static void init_wm9705_phy(struct wm97xx* wm)
548+{
549+ u16 dig1 = 0, dig2 = WM97XX_RPR;
550+
551+ /*
552+ * mute VIDEO and AUX as they share X and Y touchscreen
553+ * inputs on the WM9705
554+ */
555+ wm97xx_reg_write(wm, AC97_AUX, 0x8000);
556+ wm97xx_reg_write(wm, AC97_VIDEO, 0x8000);
557+
558+ /* touchpanel pressure current*/
559+ if (pil == 2) {
560+ dig2 |= WM9705_PIL;
561+ dbg("setting pressure measurement current to 400uA.");
562+ } else if (pil)
563+ dbg("setting pressure measurement current to 200uA.");
564+ if(!pil)
565+ pressure = 0;
566+
567+ /* polling mode sample settling delay */
568+ if (delay!=4) {
569+ if (delay < 0 || delay > 15) {
570+ dbg("supplied delay out of range.");
571+ delay = 4;
572+ }
573+ }
574+ dig1 &= 0xff0f;
575+ dig1 |= WM97XX_DELAY(delay);
576+ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
577+
578+ /* WM9705 pdd */
579+ dig2 |= (pdd & 0x000f);
580+ dbg("setting pdd to Vmid/%d", 1 - (pdd & 0x000f));
581+
582+ /* mask */
583+ dig2 |= ((mask & 0x3) << 4);
584+
585+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
586+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
587+}
588+
589+static int wm9705_digitiser_ioctl(struct wm97xx* wm, int cmd)
590+{
591+ switch(cmd) {
592+ case WM97XX_DIG_START:
593+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] | WM97XX_PRP_DET_DIG);
594+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
595+ break;
596+ case WM97XX_DIG_STOP:
597+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
598+ break;
599+ case WM97XX_AUX_PREPARE:
600+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
601+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
602+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
603+ break;
604+ case WM97XX_DIG_RESTORE:
605+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
606+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
607+ break;
608+ case WM97XX_PHY_INIT:
609+ init_wm9705_phy(wm);
610+ break;
611+ default:
612+ return -EINVAL;
613+ }
614+ return 0;
615+}
616+
617+static inline int is_pden (struct wm97xx* wm)
618+{
619+ return wm->dig[2] & WM9705_PDEN;
620+}
621+
622+/*
623+ * Read a sample from the WM9705 adc in polling mode.
624+ */
625+static int wm9705_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
626+{
627+ int timeout = 5 * delay;
628+
629+ if (!wm->pen_probably_down) {
630+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
631+ if (!(data & WM97XX_PEN_DOWN))
632+ return RC_PENUP;
633+ wm->pen_probably_down = 1;
634+ }
635+
636+ /* set up digitiser */
637+ if (adcsel & 0x8000)
638+ adcsel = ((adcsel & 0x7fff) + 3) << 12;
639+
640+ if (wm->mach_ops && wm->mach_ops->pre_sample)
641+ wm->mach_ops->pre_sample(adcsel);
642+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
643+
644+ /* wait 3 AC97 time slots + delay for conversion */
645+ poll_delay (delay);
646+
647+ /* wait for POLL to go low */
648+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
649+ udelay(AC97_LINK_FRAME);
650+ timeout--;
651+ }
652+
653+ if (timeout <= 0) {
654+ /* If PDEN is set, we can get a timeout when pen goes up */
655+ if (is_pden(wm))
656+ wm->pen_probably_down = 0;
657+ else
658+ dbg ("adc sample timeout");
659+ return RC_PENUP;
660+ }
661+
662+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
663+ if (wm->mach_ops && wm->mach_ops->post_sample)
664+ wm->mach_ops->post_sample(adcsel);
665+
666+ /* check we have correct sample */
667+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
668+ dbg ("adc wrong sample, read %x got %x", adcsel,
669+ *sample & WM97XX_ADCSEL_MASK);
670+ return RC_PENUP;
671+ }
672+
673+ if (!(*sample & WM97XX_PEN_DOWN)) {
674+ wm->pen_probably_down = 0;
675+ return RC_PENUP;
676+ }
677+
678+ return RC_VALID;
679+}
680+
681+/*
682+ * Sample the WM9705 touchscreen in polling mode
683+ */
684+static int wm9705_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
685+{
686+ int rc;
687+
688+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
689+ return rc;
690+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
691+ return rc;
692+ if (pil) {
693+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
694+ return rc;
695+ } else
696+ data->p = DEFAULT_PRESSURE;
697+
698+ return RC_VALID;
699+}
700+
701+/*
702+ * Enable WM9705 continuous mode, i.e. touch data is streamed across an AC97 slot
703+ */
704+static int wm9705_acc_enable (struct wm97xx* wm, int enable)
705+{
706+ u16 dig1, dig2;
707+ int ret = 0;
708+
709+ dig1 = wm->dig[1];
710+ dig2 = wm->dig[2];
711+
712+ if (enable) {
713+ /* continous mode */
714+ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
715+ return ret;
716+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
717+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
718+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
719+ WM97XX_DELAY (delay) |
720+ WM97XX_SLT (wm->acc_slot) |
721+ WM97XX_RATE (wm->acc_rate);
722+ if (pil)
723+ dig1 |= WM97XX_ADCSEL_PRES;
724+ dig2 |= WM9705_PDEN;
725+ } else {
726+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
727+ dig2 &= ~WM9705_PDEN;
728+ if (wm->mach_ops->acc_shutdown)
729+ wm->mach_ops->acc_shutdown(wm);
730+ }
731+
732+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
733+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
734+ return ret;
735+}
736+
737+struct wm97xx_codec_drv wm97xx_codec = {
738+ .id = WM9705_ID2,
739+ .name = "wm9705",
740+ .poll_sample = wm9705_poll_sample,
741+ .poll_touch = wm9705_poll_touch,
742+ .acc_enable = wm9705_acc_enable,
743+ .digitiser_ioctl = wm9705_digitiser_ioctl,
744+};
745+
746+EXPORT_SYMBOL_GPL(wm97xx_codec);
747+
748+/* Module information */
749+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
750+MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
751+MODULE_LICENSE("GPL");
752Index: linux-2.6.17/drivers/input/touchscreen/wm9712.c
753===================================================================
754--- /dev/null 1970-01-01 00:00:00.000000000 +0000
755+++ linux-2.6.17/drivers/input/touchscreen/wm9712.c 2006-09-19 20:36:47.969052000 +0200
756@@ -0,0 +1,464 @@
757+/*
758+ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
759+ *
760+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
761+ * Author: Liam Girdwood
762+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
763+ * Parts Copyright : Ian Molton <spyro@f2s.com>
764+ * Andrew Zabolotny <zap@homelink.ru>
765+ * Russell King <rmk@arm.linux.org.uk>
766+ *
767+ * This program is free software; you can redistribute it and/or modify it
768+ * under the terms of the GNU General Public License as published by the
769+ * Free Software Foundation; either version 2 of the License, or (at your
770+ * option) any later version.
771+ *
772+ * Revision history
773+ * 4th Jul 2005 Initial version.
774+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
775+ * Added pre and post sample calls.
776+ *
777+ */
778+
779+#include <linux/module.h>
780+#include <linux/moduleparam.h>
781+#include <linux/version.h>
782+#include <linux/kernel.h>
783+#include <linux/input.h>
784+#include <linux/delay.h>
785+#include <linux/bitops.h>
786+#include <linux/wm97xx.h>
787+
788+#define TS_NAME "wm97xx"
789+#define WM9712_VERSION "0.61"
790+#define DEFAULT_PRESSURE 0xb0c0
791+
792+/*
793+ * Debug
794+ */
795+#if 0
796+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
797+#else
798+#define dbg(format, arg...)
799+#endif
800+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
801+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
802+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
803+
804+/*
805+ * Module parameters
806+ */
807+
808+/*
809+ * Set internal pull up for pen detect.
810+ *
811+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
812+ * i.e. pull up resistance = 64k Ohms / rpu.
813+ *
814+ * Adjust this value if you are having problems with pen detect not
815+ * detecting any down event.
816+ */
817+static int rpu = 3;
818+module_param(rpu, int, 0);
819+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
820+
821+/*
822+ * Set current used for pressure measurement.
823+ *
824+ * Set pil = 2 to use 400uA
825+ * pil = 1 to use 200uA and
826+ * pil = 0 to disable pressure measurement.
827+ *
828+ * This is used to increase the range of values returned by the adc
829+ * when measureing touchpanel pressure.
830+ */
831+static int pil = 0;
832+module_param(pil, int, 0);
833+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
834+
835+/*
836+ * Set threshold for pressure measurement.
837+ *
838+ * Pen down pressure below threshold is ignored.
839+ */
840+static int pressure = DEFAULT_PRESSURE & 0xfff;
841+module_param(pressure, int, 0);
842+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
843+
844+/*
845+ * Set adc sample delay.
846+ *
847+ * For accurate touchpanel measurements, some settling time may be
848+ * required between the switch matrix applying a voltage across the
849+ * touchpanel plate and the ADC sampling the signal.
850+ *
851+ * This delay can be set by setting delay = n, where n is the array
852+ * position of the delay in the array delay_table below.
853+ * Long delays > 1ms are supported for completeness, but are not
854+ * recommended.
855+ */
856+static int delay = 3;
857+module_param(delay, int, 0);
858+MODULE_PARM_DESC(delay, "Set adc sample delay.");
859+
860+/*
861+ * Set five_wire = 1 to use a 5 wire touchscreen.
862+ *
863+ * NOTE: Five wire mode does not allow for readback of pressure.
864+ */
865+static int five_wire;
866+module_param(five_wire, int, 0);
867+MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
868+
869+/*
870+ * Set adc mask function.
871+ *
872+ * Sources of glitch noise, such as signals driving an LCD display, may feed
873+ * through to the touch screen plates and affect measurement accuracy. In
874+ * order to minimise this, a signal may be applied to the MASK pin to delay or
875+ * synchronise the sampling.
876+ *
877+ * 0 = No delay or sync
878+ * 1 = High on pin stops conversions
879+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
880+ * 3 = Edge triggered, edge on pin starts conversion after delay param
881+ */
882+static int mask = 0;
883+module_param(mask, int, 0);
884+MODULE_PARM_DESC(mask, "Set adc mask function.");
885+
886+/*
887+ * Coordinate Polling Enable.
888+ *
889+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
890+ * for every poll.
891+ */
892+static int coord = 0;
893+module_param(coord, int, 0);
894+MODULE_PARM_DESC(coord, "Polling coordinate mode");
895+
896+/*
897+ * ADC sample delay times in uS
898+ */
899+static const int delay_table[] = {
900+ 21, // 1 AC97 Link frames
901+ 42, // 2
902+ 84, // 4
903+ 167, // 8
904+ 333, // 16
905+ 667, // 32
906+ 1000, // 48
907+ 1333, // 64
908+ 2000, // 96
909+ 2667, // 128
910+ 3333, // 160
911+ 4000, // 192
912+ 4667, // 224
913+ 5333, // 256
914+ 6000, // 288
915+ 0 // No delay, switch matrix always on
916+};
917+
918+/*
919+ * Delay after issuing a POLL command.
920+ *
921+ * The delay is 3 AC97 link frames + the touchpanel settling delay
922+ */
923+static inline void poll_delay(int d)
924+{
925+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
926+}
927+
928+/*
929+ * set up the physical settings of the WM9712
930+ */
931+static void init_wm9712_phy(struct wm97xx* wm)
932+{
933+ u16 dig1 = 0;
934+ u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
935+
936+ /* WM9712 rpu */
937+ if (rpu) {
938+ dig2 &= 0xffc0;
939+ dig2 |= WM9712_RPU(rpu);
940+ dbg("setting pen detect pull-up to %d Ohms",64000 / rpu);
941+ }
942+
943+ /* touchpanel pressure current*/
944+ if (pil == 2) {
945+ dig2 |= WM9712_PIL;
946+ dbg("setting pressure measurement current to 400uA.");
947+ } else if (pil)
948+ dbg("setting pressure measurement current to 200uA.");
949+ if(!pil)
950+ pressure = 0;
951+
952+ /* WM9712 five wire */
953+ if (five_wire) {
954+ dig2 |= WM9712_45W;
955+ dbg("setting 5-wire touchscreen mode.");
956+ }
957+
958+ /* polling mode sample settling delay */
959+ if (delay < 0 || delay > 15) {
960+ dbg("supplied delay out of range.");
961+ delay = 4;
962+ }
963+ dig1 &= 0xff0f;
964+ dig1 |= WM97XX_DELAY(delay);
965+ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
966+
967+ /* mask */
968+ dig2 |= ((mask & 0x3) << 6);
969+ if (mask) {
970+ u16 reg;
971+ /* Set GPIO4 as Mask Pin*/
972+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
973+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
974+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
975+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
976+ }
977+
978+ /* wait - coord mode */
979+ if(coord)
980+ dig2 |= WM9712_WAIT;
981+
982+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
983+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
984+}
985+
986+static int wm9712_digitiser_ioctl(struct wm97xx* wm, int cmd)
987+{
988+ u16 dig2 = wm->dig[2];
989+
990+ switch(cmd) {
991+ case WM97XX_DIG_START:
992+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 | WM97XX_PRP_DET_DIG);
993+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
994+ break;
995+ case WM97XX_DIG_STOP:
996+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 & ~WM97XX_PRP_DET_DIG);
997+ break;
998+ case WM97XX_AUX_PREPARE:
999+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
1000+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
1001+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
1002+ break;
1003+ case WM97XX_DIG_RESTORE:
1004+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
1005+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
1006+ break;
1007+ case WM97XX_PHY_INIT:
1008+ init_wm9712_phy(wm);
1009+ break;
1010+ default:
1011+ return -EINVAL;
1012+ }
1013+ return 0;
1014+}
1015+
1016+static inline int is_pden (struct wm97xx* wm)
1017+{
1018+ return wm->dig[2] & WM9712_PDEN;
1019+}
1020+
1021+/*
1022+ * Read a sample from the WM9712 adc in polling mode.
1023+ */
1024+static int wm9712_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
1025+{
1026+ int timeout = 5 * delay;
1027+
1028+ if (!wm->pen_probably_down) {
1029+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1030+ if (!(data & WM97XX_PEN_DOWN))
1031+ return RC_PENUP;
1032+ wm->pen_probably_down = 1;
1033+ }
1034+
1035+ /* set up digitiser */
1036+ if (adcsel & 0x8000)
1037+ adcsel = ((adcsel & 0x7fff) + 3) << 12;
1038+
1039+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1040+ wm->mach_ops->pre_sample(adcsel);
1041+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
1042+
1043+ /* wait 3 AC97 time slots + delay for conversion */
1044+ poll_delay (delay);
1045+
1046+ /* wait for POLL to go low */
1047+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
1048+ udelay(AC97_LINK_FRAME);
1049+ timeout--;
1050+ }
1051+
1052+ if (timeout <= 0) {
1053+ /* If PDEN is set, we can get a timeout when pen goes up */
1054+ if (is_pden(wm))
1055+ wm->pen_probably_down = 0;
1056+ else
1057+ dbg ("adc sample timeout");
1058+ return RC_PENUP;
1059+ }
1060+
1061+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1062+ if (wm->mach_ops && wm->mach_ops->post_sample)
1063+ wm->mach_ops->post_sample(adcsel);
1064+
1065+ /* check we have correct sample */
1066+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
1067+ dbg ("adc wrong sample, read %x got %x", adcsel,
1068+ *sample & WM97XX_ADCSEL_MASK);
1069+ return RC_PENUP;
1070+ }
1071+
1072+ if (!(*sample & WM97XX_PEN_DOWN)) {
1073+ wm->pen_probably_down = 0;
1074+ return RC_PENUP;
1075+ }
1076+
1077+ return RC_VALID;
1078+}
1079+
1080+/*
1081+ * Read a coord from the WM9712 adc in polling mode.
1082+ */
1083+static int wm9712_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
1084+{
1085+ int timeout = 5 * delay;
1086+
1087+ if (!wm->pen_probably_down) {
1088+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1089+ if (!(data & WM97XX_PEN_DOWN))
1090+ return RC_PENUP;
1091+ wm->pen_probably_down = 1;
1092+ }
1093+
1094+ /* set up digitiser */
1095+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1096+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1097+
1098+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
1099+ WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
1100+
1101+ /* wait 3 AC97 time slots + delay for conversion and read x */
1102+ poll_delay(delay);
1103+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1104+ /* wait for POLL to go low */
1105+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
1106+ udelay(AC97_LINK_FRAME);
1107+ timeout--;
1108+ }
1109+
1110+ if (timeout <= 0) {
1111+ /* If PDEN is set, we can get a timeout when pen goes up */
1112+ if (is_pden(wm))
1113+ wm->pen_probably_down = 0;
1114+ else
1115+ dbg ("adc sample timeout");
1116+ return RC_PENUP;
1117+ }
1118+
1119+ /* read back y data */
1120+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1121+ if (pil)
1122+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1123+ else
1124+ data->p = DEFAULT_PRESSURE;
1125+
1126+ if (wm->mach_ops && wm->mach_ops->post_sample)
1127+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1128+
1129+ /* check we have correct sample */
1130+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
1131+ goto err;
1132+ if(pil && !(data->p & WM97XX_ADCSEL_PRES))
1133+ goto err;
1134+
1135+ if (!(data->x & WM97XX_PEN_DOWN)) {
1136+ wm->pen_probably_down = 0;
1137+ return RC_PENUP;
1138+ }
1139+ return RC_VALID;
1140+err:
1141+ return RC_PENUP;
1142+}
1143+
1144+/*
1145+ * Sample the WM9712 touchscreen in polling mode
1146+ */
1147+static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
1148+{
1149+ int rc;
1150+
1151+ if(coord) {
1152+ if((rc = wm9712_poll_coord(wm, data)) != RC_VALID)
1153+ return rc;
1154+ } else {
1155+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
1156+ return rc;
1157+
1158+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
1159+ return rc;
1160+
1161+ if (pil && !five_wire) {
1162+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
1163+ return rc;
1164+ } else
1165+ data->p = DEFAULT_PRESSURE;
1166+ }
1167+ return RC_VALID;
1168+}
1169+
1170+/*
1171+ * Enable WM9712 continuous mode, i.e. touch data is streamed across an AC97 slot
1172+ */
1173+static int wm9712_acc_enable (struct wm97xx* wm, int enable)
1174+{
1175+ u16 dig1, dig2;
1176+ int ret = 0;
1177+
1178+ dig1 = wm->dig[1];
1179+ dig2 = wm->dig[2];
1180+
1181+ if (enable) {
1182+ /* continous mode */
1183+ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
1184+ return ret;
1185+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
1186+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
1187+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
1188+ WM97XX_DELAY (delay) |
1189+ WM97XX_SLT (wm->acc_slot) |
1190+ WM97XX_RATE (wm->acc_rate);
1191+ if (pil)
1192+ dig1 |= WM97XX_ADCSEL_PRES;
1193+ dig2 |= WM9712_PDEN;
1194+ } else {
1195+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
1196+ dig2 &= ~WM9712_PDEN;
1197+ if (wm->mach_ops->acc_shutdown)
1198+ wm->mach_ops->acc_shutdown(wm);
1199+ }
1200+
1201+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
1202+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
1203+ return 0;
1204+}
1205+
1206+struct wm97xx_codec_drv wm97xx_codec = {
1207+ .id = WM9712_ID2,
1208+ .name = "wm9712",
1209+ .poll_sample = wm9712_poll_sample,
1210+ .poll_touch = wm9712_poll_touch,
1211+ .acc_enable = wm9712_acc_enable,
1212+ .digitiser_ioctl = wm9712_digitiser_ioctl,
1213+};
1214+
1215+EXPORT_SYMBOL_GPL(wm97xx_codec);
1216+
1217+/* Module information */
1218+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
1219+MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
1220+MODULE_LICENSE("GPL");
1221Index: linux-2.6.17/drivers/input/touchscreen/wm9713.c
1222===================================================================
1223--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1224+++ linux-2.6.17/drivers/input/touchscreen/wm9713.c 2006-09-19 20:36:47.969052000 +0200
1225@@ -0,0 +1,461 @@
1226+/*
1227+ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
1228+ *
1229+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
1230+ * Author: Liam Girdwood
1231+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
1232+ * Parts Copyright : Ian Molton <spyro@f2s.com>
1233+ * Andrew Zabolotny <zap@homelink.ru>
1234+ * Russell King <rmk@arm.linux.org.uk>
1235+ *
1236+ * This program is free software; you can redistribute it and/or modify it
1237+ * under the terms of the GNU General Public License as published by the
1238+ * Free Software Foundation; either version 2 of the License, or (at your
1239+ * option) any later version.
1240+ *
1241+ * Revision history
1242+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
1243+ * Added pre and post sample calls.
1244+ *
1245+ */
1246+
1247+#include <linux/module.h>
1248+#include <linux/moduleparam.h>
1249+#include <linux/version.h>
1250+#include <linux/kernel.h>
1251+#include <linux/input.h>
1252+#include <linux/delay.h>
1253+#include <linux/bitops.h>
1254+#include <linux/wm97xx.h>
1255+
1256+#define TS_NAME "wm97xx"
1257+#define WM9713_VERSION "0.53"
1258+#define DEFAULT_PRESSURE 0xb0c0
1259+
1260+/*
1261+ * Debug
1262+ */
1263+#if 0
1264+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
1265+#else
1266+#define dbg(format, arg...)
1267+#endif
1268+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
1269+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
1270+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
1271+
1272+/*
1273+ * Module parameters
1274+ */
1275+
1276+/*
1277+ * Set internal pull up for pen detect.
1278+ *
1279+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
1280+ * i.e. pull up resistance = 64k Ohms / rpu.
1281+ *
1282+ * Adjust this value if you are having problems with pen detect not
1283+ * detecting any down event.
1284+ */
1285+static int rpu = 1;
1286+module_param(rpu, int, 0);
1287+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
1288+
1289+/*
1290+ * Set current used for pressure measurement.
1291+ *
1292+ * Set pil = 2 to use 400uA
1293+ * pil = 1 to use 200uA and
1294+ * pil = 0 to disable pressure measurement.
1295+ *
1296+ * This is used to increase the range of values returned by the adc
1297+ * when measureing touchpanel pressure.
1298+ */
1299+static int pil = 0;
1300+module_param(pil, int, 0);
1301+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
1302+
1303+/*
1304+ * Set threshold for pressure measurement.
1305+ *
1306+ * Pen down pressure below threshold is ignored.
1307+ */
1308+static int pressure = DEFAULT_PRESSURE & 0xfff;
1309+module_param(pressure, int, 0);
1310+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
1311+
1312+/*
1313+ * Set adc sample delay.
1314+ *
1315+ * For accurate touchpanel measurements, some settling time may be
1316+ * required between the switch matrix applying a voltage across the
1317+ * touchpanel plate and the ADC sampling the signal.
1318+ *
1319+ * This delay can be set by setting delay = n, where n is the array
1320+ * position of the delay in the array delay_table below.
1321+ * Long delays > 1ms are supported for completeness, but are not
1322+ * recommended.
1323+ */
1324+static int delay = 4;
1325+module_param(delay, int, 0);
1326+MODULE_PARM_DESC(delay, "Set adc sample delay.");
1327+
1328+/*
1329+ * Set adc mask function.
1330+ *
1331+ * Sources of glitch noise, such as signals driving an LCD display, may feed
1332+ * through to the touch screen plates and affect measurement accuracy. In
1333+ * order to minimise this, a signal may be applied to the MASK pin to delay or
1334+ * synchronise the sampling.
1335+ *
1336+ * 0 = No delay or sync
1337+ * 1 = High on pin stops conversions
1338+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
1339+ * 3 = Edge triggered, edge on pin starts conversion after delay param
1340+ */
1341+static int mask = 0;
1342+module_param(mask, int, 0);
1343+MODULE_PARM_DESC(mask, "Set adc mask function.");
1344+
1345+/*
1346+ * Coordinate Polling Enable.
1347+ *
1348+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
1349+ * for every poll.
1350+ */
1351+static int coord = 1;
1352+module_param(coord, int, 0);
1353+MODULE_PARM_DESC(coord, "Polling coordinate mode");
1354+
1355+/*
1356+ * ADC sample delay times in uS
1357+ */
1358+static const int delay_table[] = {
1359+ 21, // 1 AC97 Link frames
1360+ 42, // 2
1361+ 84, // 4
1362+ 167, // 8
1363+ 333, // 16
1364+ 667, // 32
1365+ 1000, // 48
1366+ 1333, // 64
1367+ 2000, // 96
1368+ 2667, // 128
1369+ 3333, // 160
1370+ 4000, // 192
1371+ 4667, // 224
1372+ 5333, // 256
1373+ 6000, // 288
1374+ 0 // No delay, switch matrix always on
1375+};
1376+
1377+/*
1378+ * Delay after issuing a POLL command.
1379+ *
1380+ * The delay is 3 AC97 link frames + the touchpanel settling delay
1381+ */
1382+static inline void poll_delay(int d)
1383+{
1384+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
1385+}
1386+
1387+/*
1388+ * set up the physical settings of the WM9713
1389+ */
1390+static void init_wm9713_phy(struct wm97xx* wm)
1391+{
1392+ u16 dig1 = 0, dig2, dig3;
1393+
1394+ /* default values */
1395+ dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
1396+ dig3= WM9712_RPU(1);
1397+
1398+ /* rpu */
1399+ if (rpu) {
1400+ dig3 &= 0xffc0;
1401+ dig3 |= WM9712_RPU(rpu);
1402+ info("setting pen detect pull-up to %d Ohms",64000 / rpu);
1403+ }
1404+
1405+ /* touchpanel pressure */
1406+ if (pil == 2) {
1407+ dig3 |= WM9712_PIL;
1408+ info("setting pressure measurement current to 400uA.");
1409+ } else if (pil)
1410+ info ("setting pressure measurement current to 200uA.");
1411+ if(!pil)
1412+ pressure = 0;
1413+
1414+ /* sample settling delay */
1415+ if (delay < 0 || delay > 15) {
1416+ info ("supplied delay out of range.");
1417+ delay = 4;
1418+ info("setting adc sample delay to %d u Secs.", delay_table[delay]);
1419+ }
1420+ dig2 &= 0xff0f;
1421+ dig2 |= WM97XX_DELAY(delay);
1422+
1423+ /* mask */
1424+ dig3 |= ((mask & 0x3) << 4);
1425+ if(coord)
1426+ dig3 |= WM9713_WAIT;
1427+
1428+ wm->misc = wm97xx_reg_read(wm, 0x5a);
1429+
1430+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
1431+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
1432+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
1433+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
1434+}
1435+
1436+static int wm9713_digitiser_ioctl(struct wm97xx* wm, int cmd)
1437+{
1438+ u16 val = 0;
1439+
1440+ switch(cmd){
1441+ case WM97XX_DIG_START:
1442+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
1443+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
1444+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | WM97XX_PRP_DET_DIG);
1445+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
1446+ break;
1447+ case WM97XX_DIG_STOP:
1448+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
1449+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
1450+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
1451+ break;
1452+ case WM97XX_AUX_PREPARE:
1453+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
1454+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
1455+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
1456+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
1457+ break;
1458+ case WM97XX_DIG_RESTORE:
1459+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
1460+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
1461+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
1462+ break;
1463+ case WM97XX_PHY_INIT:
1464+ init_wm9713_phy(wm);
1465+ break;
1466+ default:
1467+ return -EINVAL;
1468+ }
1469+ return 0;
1470+}
1471+
1472+static inline int is_pden (struct wm97xx* wm)
1473+{
1474+ return wm->dig[2] & WM9713_PDEN;
1475+}
1476+
1477+/*
1478+ * Read a sample from the WM9713 adc in polling mode.
1479+ */
1480+static int wm9713_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
1481+{
1482+ u16 dig1;
1483+ int timeout = 5 * delay;
1484+
1485+ if (!wm->pen_probably_down) {
1486+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1487+ if (!(data & WM97XX_PEN_DOWN))
1488+ return RC_PENUP;
1489+ wm->pen_probably_down = 1;
1490+ }
1491+
1492+ /* set up digitiser */
1493+ if (adcsel & 0x8000)
1494+ adcsel = 1 << ((adcsel & 0x7fff) + 3);
1495+
1496+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
1497+ dig1 &= ~WM9713_ADCSEL_MASK;
1498+
1499+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1500+ wm->mach_ops->pre_sample(adcsel);
1501+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel |WM9713_POLL);
1502+
1503+ /* wait 3 AC97 time slots + delay for conversion */
1504+ poll_delay(delay);
1505+
1506+ /* wait for POLL to go low */
1507+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
1508+ udelay(AC97_LINK_FRAME);
1509+ timeout--;
1510+ }
1511+
1512+ if (timeout <= 0) {
1513+ /* If PDEN is set, we can get a timeout when pen goes up */
1514+ if (is_pden(wm))
1515+ wm->pen_probably_down = 0;
1516+ else
1517+ dbg ("adc sample timeout");
1518+ return RC_PENUP;
1519+ }
1520+
1521+ *sample =wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1522+ if (wm->mach_ops && wm->mach_ops->post_sample)
1523+ wm->mach_ops->post_sample(adcsel);
1524+
1525+ /* check we have correct sample */
1526+ if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) {
1527+ dbg ("adc wrong sample, read %x got %x", adcsel,
1528+ *sample & WM97XX_ADCSRC_MASK);
1529+ return RC_PENUP;
1530+ }
1531+
1532+ if (!(*sample & WM97XX_PEN_DOWN)) {
1533+ wm->pen_probably_down = 0;
1534+ return RC_PENUP;
1535+ }
1536+
1537+ return RC_VALID;
1538+}
1539+
1540+/*
1541+ * Read a coordinate from the WM9713 adc in polling mode.
1542+ */
1543+static int wm9713_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
1544+{
1545+ u16 dig1;
1546+ int timeout = 5 * delay;
1547+
1548+ if (!wm->pen_probably_down) {
1549+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1550+ if (!(data & WM97XX_PEN_DOWN))
1551+ return RC_PENUP;
1552+ wm->pen_probably_down = 1;
1553+ }
1554+
1555+ /* set up digitiser */
1556+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
1557+ dig1 &= ~WM9713_ADCSEL_MASK;
1558+ if(pil)
1559+ dig1 |= WM97XX_ADCSEL_PRES;
1560+
1561+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1562+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1563+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL | WM9713_COO);
1564+
1565+ /* wait 3 AC97 time slots + delay for conversion */
1566+ poll_delay(delay);
1567+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1568+ /* wait for POLL to go low */
1569+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
1570+ udelay(AC97_LINK_FRAME);
1571+ timeout--;
1572+ }
1573+
1574+ if (timeout <= 0) {
1575+ /* If PDEN is set, we can get a timeout when pen goes up */
1576+ if (is_pden(wm))
1577+ wm->pen_probably_down = 0;
1578+ else
1579+ dbg ("adc sample timeout");
1580+ return RC_PENUP;
1581+ }
1582+
1583+ /* read back data */
1584+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1585+ if (pil)
1586+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1587+ else
1588+ data->p = DEFAULT_PRESSURE;
1589+
1590+ if (wm->mach_ops && wm->mach_ops->post_sample)
1591+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1592+
1593+ /* check we have correct sample */
1594+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
1595+ goto err;
1596+ if(pil && !(data->p & WM97XX_ADCSEL_PRES))
1597+ goto err;
1598+
1599+ if (!(data->x & WM97XX_PEN_DOWN)) {
1600+ wm->pen_probably_down = 0;
1601+ return RC_PENUP;
1602+ }
1603+ return RC_VALID;
1604+err:
1605+ return RC_PENUP;
1606+}
1607+
1608+/*
1609+ * Sample the WM9713 touchscreen in polling mode
1610+ */
1611+static int wm9713_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
1612+{
1613+ int rc;
1614+
1615+ if(coord) {
1616+ if((rc = wm9713_poll_coord(wm, data)) != RC_VALID)
1617+ return rc;
1618+ } else {
1619+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x)) != RC_VALID)
1620+ return rc;
1621+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y)) != RC_VALID)
1622+ return rc;
1623+ if (pil) {
1624+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, &data->p)) != RC_VALID)
1625+ return rc;
1626+ } else
1627+ data->p = DEFAULT_PRESSURE;
1628+ }
1629+ return RC_VALID;
1630+}
1631+
1632+/*
1633+ * Enable WM9713 continuous mode, i.e. touch data is streamed across an AC97 slot
1634+ */
1635+static int wm9713_acc_enable (struct wm97xx* wm, int enable)
1636+{
1637+ u16 dig1, dig2, dig3;
1638+ int ret = 0;
1639+
1640+ dig1 = wm->dig[0];
1641+ dig2 = wm->dig[1];
1642+ dig3 = wm->dig[2];
1643+
1644+ if (enable) {
1645+ /* continous mode */
1646+ if (wm->mach_ops->acc_startup &&
1647+ (ret = wm->mach_ops->acc_startup(wm)) < 0)
1648+ return ret;
1649+
1650+ dig1 &= ~WM9713_ADCSEL_MASK;
1651+ dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | WM9713_ADCSEL_Y;
1652+ if (pil)
1653+ dig1 |= WM9713_ADCSEL_PRES;
1654+ dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | WM97XX_CM_RATE_MASK);
1655+ dig2 |= WM97XX_SLEN | WM97XX_DELAY (delay) |
1656+ WM97XX_SLT (wm->acc_slot) | WM97XX_RATE (wm->acc_rate);
1657+ dig3 |= WM9713_PDEN;
1658+ } else {
1659+ dig1 &= ~(WM9713_CTC | WM9713_COO);
1660+ dig2 &= ~WM97XX_SLEN;
1661+ dig3 &= ~WM9713_PDEN;
1662+ if (wm->mach_ops->acc_shutdown)
1663+ wm->mach_ops->acc_shutdown(wm);
1664+ }
1665+
1666+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
1667+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
1668+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
1669+ return ret;
1670+}
1671+
1672+struct wm97xx_codec_drv wm97xx_codec = {
1673+ .id = WM9713_ID2,
1674+ .name = "wm9713",
1675+ .poll_sample = wm9713_poll_sample,
1676+ .poll_touch = wm9713_poll_touch,
1677+ .acc_enable = wm9713_acc_enable,
1678+ .digitiser_ioctl = wm9713_digitiser_ioctl,
1679+};
1680+
1681+EXPORT_SYMBOL_GPL(wm97xx_codec);
1682+
1683+/* Module information */
1684+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
1685+MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
1686+MODULE_LICENSE("GPL");
1687Index: linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c
1688===================================================================
1689--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1690+++ linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c 2006-09-19 20:36:47.969052000 +0200
1691@@ -0,0 +1,912 @@
1692+/*
1693+ * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712
1694+ * and WM9713 AC97 Codecs.
1695+ *
1696+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
1697+ * Author: Liam Girdwood
1698+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
1699+ * Parts Copyright : Ian Molton <spyro@f2s.com>
1700+ * Andrew Zabolotny <zap@homelink.ru>
1701+ * Russell King <rmk@arm.linux.org.uk>
1702+ *
1703+ * This program is free software; you can redistribute it and/or modify it
1704+ * under the terms of the GNU General Public License as published by the
1705+ * Free Software Foundation; either version 2 of the License, or (at your
1706+ * option) any later version.
1707+ *
1708+ * Notes:
1709+ *
1710+ * Features:
1711+ * - supports WM9705, WM9712, WM9713
1712+ * - polling mode
1713+ * - continuous mode (arch-dependent)
1714+ * - adjustable rpu/dpp settings
1715+ * - adjustable pressure current
1716+ * - adjustable sample settle delay
1717+ * - 4 and 5 wire touchscreens (5 wire is WM9712 only)
1718+ * - pen down detection
1719+ * - battery monitor
1720+ * - sample AUX adc's
1721+ * - power management
1722+ * - codec GPIO
1723+ * - codec event notification
1724+ * Todo
1725+ * - Support for async sampling control for noisy LCD's.
1726+ *
1727+ * Revision history
1728+ * 7th May 2003 Initial version.
1729+ * 6th June 2003 Added non module support and AC97 registration.
1730+ * 18th June 2003 Added AUX adc sampling.
1731+ * 23rd June 2003 Did some minimal reformatting, fixed a couple of
1732+ * codec_mutexing bugs and noted a race to fix.
1733+ * 24th June 2003 Added power management and fixed race condition.
1734+ * 10th July 2003 Changed to a misc device.
1735+ * 31st July 2003 Moved TS_EVENT and TS_CAL to wm97xx.h
1736+ * 8th Aug 2003 Added option for read() calling wm97xx_sample_touch()
1737+ * because some ac97_read/ac_97_write call schedule()
1738+ * 7th Nov 2003 Added Input touch event interface, stanley.cai@intel.com
1739+ * 13th Nov 2003 Removed h3600 touch interface, added interrupt based
1740+ * pen down notification and implemented continous mode
1741+ * on XScale arch.
1742+ * 16th Nov 2003 Ian Molton <spyro@f2s.com>
1743+ * Modified so that it suits the new 2.6 driver model.
1744+ * 25th Jan 2004 Andrew Zabolotny <zap@homelink.ru>
1745+ * Implemented IRQ-driven pen down detection, implemented
1746+ * the private API meant to be exposed to platform-specific
1747+ * drivers, reorganized the driver so that it supports
1748+ * an arbitrary number of devices.
1749+ * 1st Feb 2004 Moved continuous mode handling to a separate
1750+ * architecture-dependent file. For now only PXA
1751+ * built-in AC97 controller is supported (pxa-ac97-wm97xx.c).
1752+ * 11th Feb 2004 Reduced CPU usage by keeping a cached copy of both
1753+ * digitizer registers instead of reading them every time.
1754+ * A reorganization of the whole code for better
1755+ * error handling.
1756+ * 17th Apr 2004 Added BMON support.
1757+ * 17th Nov 2004 Added codec GPIO, codec event handling (real and virtual
1758+ * GPIOs) and 2.6 power management.
1759+ * 29th Nov 2004 Added WM9713 support.
1760+ * 4th Jul 2005 Moved codec specific code out to seperate files.
1761+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
1762+ * Added bus interface.
1763+ */
1764+
1765+#include <linux/module.h>
1766+#include <linux/moduleparam.h>
1767+#include <linux/version.h>
1768+#include <linux/kernel.h>
1769+#include <linux/init.h>
1770+#include <linux/delay.h>
1771+#include <linux/string.h>
1772+#include <linux/proc_fs.h>
1773+#include <linux/pm.h>
1774+#include <linux/interrupt.h>
1775+#include <linux/bitops.h>
1776+#include <linux/workqueue.h>
1777+#include <linux/device.h>
1778+#include <linux/wm97xx.h>
1779+#include <asm/uaccess.h>
1780+#include <asm/io.h>
1781+
1782+#define TS_NAME "wm97xx"
1783+#define WM_CORE_VERSION "0.63"
1784+#define DEFAULT_PRESSURE 0xb0c0
1785+
1786+/*
1787+ * WM97xx - enable/disable AUX ADC sysfs
1788+ */
1789+static int aux_sys = 1;
1790+module_param(aux_sys, int, 0);
1791+MODULE_PARM_DESC(aux_sys, "enable AUX ADC sysfs entries");
1792+
1793+/*
1794+ * WM97xx - enable/disable codec status sysfs
1795+ */
1796+static int status_sys = 1;
1797+module_param(status_sys, int, 0);
1798+MODULE_PARM_DESC(status_sys, "enable codec status sysfs entries");
1799+
1800+/*
1801+ * Touchscreen absolute values
1802+ *
1803+ * These parameters are used to help the input layer discard out of
1804+ * range readings and reduce jitter etc.
1805+ *
1806+ * o min, max:- indicate the min and max values your touch screen returns
1807+ * o fuzz:- use a higher number to reduce jitter
1808+ *
1809+ * The default values correspond to Mainstone II in QVGA mode
1810+ *
1811+ * Please read
1812+ * Documentation/input/input-programming.txt for more details.
1813+ */
1814+
1815+static int abs_x[3] = {350,3900,5};
1816+module_param_array(abs_x, int, NULL, 0);
1817+MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
1818+
1819+static int abs_y[3] = {320,3750,40};
1820+module_param_array(abs_y, int, NULL, 0);
1821+MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
1822+
1823+static int abs_p[3] = {0,150,4};
1824+module_param_array(abs_p, int, NULL, 0);
1825+MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");
1826+
1827+/*
1828+ * Debug
1829+ */
1830+#if 0
1831+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
1832+#else
1833+#define dbg(format, arg...)
1834+#endif
1835+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
1836+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
1837+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
1838+
1839+/* codec AC97 IO access */
1840+int wm97xx_reg_read(struct wm97xx *wm, u16 reg)
1841+{
1842+ if (wm->ac97)
1843+ return wm->ac97->bus->ops->read(wm->ac97, reg);
1844+ else
1845+ return -1;
1846+}
1847+
1848+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val)
1849+{
1850+ /* cache digitiser registers */
1851+ if(reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3)
1852+ wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val;
1853+
1854+ /* cache gpio regs */
1855+ if(reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE)
1856+ wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val;
1857+
1858+ /* wm9713 irq reg */
1859+ if(reg == 0x5a)
1860+ wm->misc = val;
1861+
1862+ if (wm->ac97)
1863+ wm->ac97->bus->ops->write(wm->ac97, reg, val);
1864+}
1865+
1866+
1867+/**
1868+ * wm97xx_read_aux_adc - Read the aux adc.
1869+ * @wm: wm97xx device.
1870+ * @adcsel: codec ADC to be read
1871+ *
1872+ * Reads the selected AUX ADC.
1873+ */
1874+
1875+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
1876+{
1877+ int power_adc = 0, auxval;
1878+ u16 power = 0;
1879+
1880+ /* get codec */
1881+ mutex_lock(&wm->codec_mutex);
1882+
1883+ /* When the touchscreen is not in use, we may have to power up the AUX ADC
1884+ * before we can use sample the AUX inputs->
1885+ */
1886+ if (wm->id == WM9713_ID2 &&
1887+ (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
1888+ power_adc = 1;
1889+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
1890+ }
1891+
1892+ /* Prepare the codec for AUX reading */
1893+ wm->codec->digitiser_ioctl(wm, WM97XX_AUX_PREPARE);
1894+
1895+ /* Turn polling mode on to read AUX ADC */
1896+ wm->pen_probably_down = 1;
1897+ wm->codec->poll_sample(wm, adcsel, &auxval);
1898+
1899+ if (power_adc)
1900+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
1901+
1902+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_RESTORE);
1903+
1904+ wm->pen_probably_down = 0;
1905+
1906+ mutex_unlock(&wm->codec_mutex);
1907+ return auxval & 0xfff;
1908+}
1909+
1910+#define WM97XX_AUX_ATTR(name,input) \
1911+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
1912+{ \
1913+ struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
1914+ return sprintf(buf, "%d\n", wm97xx_read_aux_adc(wm, input)); \
1915+} \
1916+static DEVICE_ATTR(name, 0444, name##_show, NULL)
1917+
1918+WM97XX_AUX_ATTR(aux1, WM97XX_AUX_ID1);
1919+WM97XX_AUX_ATTR(aux2, WM97XX_AUX_ID2);
1920+WM97XX_AUX_ATTR(aux3, WM97XX_AUX_ID3);
1921+WM97XX_AUX_ATTR(aux4, WM97XX_AUX_ID4);
1922+
1923+#define WM97XX_STATUS_ATTR(name) \
1924+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
1925+{ \
1926+ struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
1927+ return sprintf(buf, "%d\n", wm97xx_reg_read(wm, AC97_GPIO_STATUS)); \
1928+} \
1929+static DEVICE_ATTR(name, 0444, name##_show, NULL)
1930+
1931+WM97XX_STATUS_ATTR(gpio);
1932+
1933+static int wm97xx_sys_add(struct device *dev)
1934+{
1935+ if (aux_sys) {
1936+ device_create_file(dev, &dev_attr_aux1);
1937+ device_create_file(dev, &dev_attr_aux2);
1938+ device_create_file(dev, &dev_attr_aux3);
1939+ device_create_file(dev, &dev_attr_aux4);
1940+ }
1941+ if (status_sys)
1942+ device_create_file(dev, &dev_attr_gpio);
1943+ return 0;
1944+}
1945+
1946+static void wm97xx_sys_remove(struct device *dev)
1947+{
1948+ if (status_sys)
1949+ device_remove_file(dev, &dev_attr_gpio);
1950+ if (aux_sys) {
1951+ device_remove_file(dev, &dev_attr_aux1);
1952+ device_remove_file(dev, &dev_attr_aux2);
1953+ device_remove_file(dev, &dev_attr_aux3);
1954+ device_remove_file(dev, &dev_attr_aux4);
1955+ }
1956+}
1957+
1958+/**
1959+ * wm97xx_get_gpio - Get the status of a codec GPIO.
1960+ * @wm: wm97xx device.
1961+ * @gpio: gpio
1962+ *
1963+ * Get the status of a codec GPIO pin
1964+ */
1965+
1966+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
1967+{
1968+ u16 status;
1969+ wm97xx_gpio_status_t ret;
1970+
1971+ mutex_lock(&wm->codec_mutex);
1972+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
1973+
1974+ if (status & gpio)
1975+ ret = WM97XX_GPIO_HIGH;
1976+ else
1977+ ret = WM97XX_GPIO_LOW;
1978+
1979+ mutex_unlock(&wm->codec_mutex);
1980+ return ret;
1981+}
1982+
1983+/**
1984+ * wm97xx_set_gpio - Set the status of a codec GPIO.
1985+ * @wm: wm97xx device.
1986+ * @gpio: gpio
1987+ *
1988+ *
1989+ * Set the status of a codec GPIO pin
1990+ */
1991+
1992+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
1993+ wm97xx_gpio_status_t status)
1994+{
1995+ u16 reg;
1996+
1997+ mutex_lock(&wm->codec_mutex);
1998+ reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
1999+
2000+ if (status & WM97XX_GPIO_HIGH)
2001+ reg |= gpio;
2002+ else
2003+ reg &= ~gpio;
2004+
2005+ if (wm->id == WM9712_ID2)
2006+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
2007+ else
2008+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
2009+ mutex_unlock(&wm->codec_mutex);
2010+}
2011+
2012+/*
2013+ * Codec GPIO pin configuration, this set's pin direction, polarity,
2014+ * stickyness and wake up.
2015+ */
2016+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir,
2017+ wm97xx_gpio_pol_t pol, wm97xx_gpio_sticky_t sticky,
2018+ wm97xx_gpio_wake_t wake)
2019+{
2020+ u16 reg;
2021+
2022+ mutex_lock(&wm->codec_mutex);
2023+ reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2024+
2025+ if (pol == WM97XX_GPIO_POL_HIGH)
2026+ reg |= gpio;
2027+ else
2028+ reg &= ~gpio;
2029+
2030+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg);
2031+ reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
2032+
2033+ if (sticky == WM97XX_GPIO_STICKY)
2034+ reg |= gpio;
2035+ else
2036+ reg &= ~gpio;
2037+
2038+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg);
2039+ reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
2040+
2041+ if (wake == WM97XX_GPIO_WAKE)
2042+ reg |= gpio;
2043+ else
2044+ reg &= ~gpio;
2045+
2046+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg);
2047+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
2048+
2049+ if (dir == WM97XX_GPIO_IN)
2050+ reg |= gpio;
2051+ else
2052+ reg &= ~gpio;
2053+
2054+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
2055+ mutex_unlock(&wm->codec_mutex);
2056+}
2057+
2058+/*
2059+ * Handle a pen down interrupt.
2060+ */
2061+static void wm97xx_pen_irq_worker(void *ptr)
2062+{
2063+ struct wm97xx *wm = (struct wm97xx *) ptr;
2064+
2065+ /* do we need to enable the touch panel reader */
2066+ if (wm->id == WM9705_ID2) {
2067+ if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN)
2068+ wm->pen_is_down = 1;
2069+ else
2070+ wm->pen_is_down = 0;
2071+ wake_up_interruptible(&wm->pen_irq_wait);
2072+ } else {
2073+ u16 status, pol;
2074+ mutex_lock(&wm->codec_mutex);
2075+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
2076+ pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2077+
2078+ if (WM97XX_GPIO_13 & pol & status) {
2079+ wm->pen_is_down = 1;
2080+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & ~WM97XX_GPIO_13);
2081+ } else {
2082+ wm->pen_is_down = 0;
2083+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | WM97XX_GPIO_13);
2084+ }
2085+
2086+ if (wm->id == WM9712_ID2)
2087+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & ~WM97XX_GPIO_13) << 1);
2088+ else
2089+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & ~WM97XX_GPIO_13);
2090+ mutex_unlock(&wm->codec_mutex);
2091+ wake_up_interruptible(&wm->pen_irq_wait);
2092+ }
2093+
2094+ if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled)
2095+ wm->mach_ops->acc_pen_up(wm);
2096+ enable_irq(wm->pen_irq);
2097+}
2098+
2099+/*
2100+ * Codec PENDOWN irq handler
2101+ *
2102+ * We have to disable the codec interrupt in the handler because it can
2103+ * take upto 1ms to clear the interrupt source. The interrupt is then enabled
2104+ * again in the slow handler when the source has been cleared.
2105+ */
2106+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id,
2107+ struct pt_regs *regs)
2108+{
2109+ struct wm97xx *wm = (struct wm97xx *) dev_id;
2110+ disable_irq(wm->pen_irq);
2111+ queue_work(wm->pen_irq_workq, &wm->pen_event_work);
2112+ return IRQ_HANDLED;
2113+}
2114+
2115+/*
2116+ * initialise pen IRQ handler and workqueue
2117+ */
2118+static int wm97xx_init_pen_irq(struct wm97xx *wm)
2119+{
2120+ u16 reg;
2121+
2122+ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker, wm);
2123+ if ((wm->pen_irq_workq =
2124+ create_singlethread_workqueue("kwm97pen")) == NULL) {
2125+ err("could not create pen irq work queue");
2126+ wm->pen_irq = 0;
2127+ return -EINVAL;
2128+ }
2129+
2130+ if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
2131+ err("could not register codec pen down interrupt, will poll for pen down");
2132+ destroy_workqueue(wm->pen_irq_workq);
2133+ wm->pen_irq = 0;
2134+ return -EINVAL;
2135+ }
2136+
2137+ /* enable PEN down on wm9712/13 */
2138+ if (wm->id != WM9705_ID2) {
2139+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
2140+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb);
2141+ reg = wm97xx_reg_read(wm, 0x5a);
2142+ wm97xx_reg_write(wm, 0x5a, reg & ~0x0001);
2143+ }
2144+
2145+ return 0;
2146+}
2147+
2148+/* Private struct for communication between struct wm97xx_tshread
2149+ * and wm97xx_read_samples */
2150+struct ts_state {
2151+ int sleep_time;
2152+ int min_sleep_time;
2153+};
2154+
2155+static int wm97xx_read_samples(struct wm97xx *wm, struct ts_state *state)
2156+{
2157+ struct wm97xx_data data;
2158+ int rc;
2159+
2160+ mutex_lock(&wm->codec_mutex);
2161+
2162+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2163+ rc = wm->mach_ops->acc_pen_down(wm);
2164+ else
2165+ rc = wm->codec->poll_touch(wm, &data);
2166+
2167+ if (rc & RC_PENUP) {
2168+ if (wm->pen_is_down) {
2169+ wm->pen_is_down = 0;
2170+ dbg("pen up");
2171+ input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
2172+ input_sync(wm->input_dev);
2173+ } else if (!(rc & RC_AGAIN)) {
2174+ /* We need high frequency updates only while pen is down,
2175+ * the user never will be able to touch screen faster than
2176+ * a few times per second... On the other hand, when the
2177+ * user is actively working with the touchscreen we don't
2178+ * want to lose the quick response. So we will slowly
2179+ * increase sleep time after the pen is up and quicky
2180+ * restore it to ~one task switch when pen is down again.
2181+ */
2182+ if (state->sleep_time < HZ / 10)
2183+ state->sleep_time++;
2184+ }
2185+
2186+ } else if (rc & RC_VALID) {
2187+ dbg("pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n",
2188+ data.x >> 12, data.x & 0xfff, data.y >> 12,
2189+ data.y & 0xfff, data.p >> 12, data.p & 0xfff);
2190+ input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
2191+ input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
2192+ input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
2193+ input_sync(wm->input_dev);
2194+ wm->pen_is_down = 1;
2195+ state->sleep_time = state->min_sleep_time;
2196+ } else if (rc & RC_PENDOWN) {
2197+ dbg("pen down");
2198+ wm->pen_is_down = 1;
2199+ state->sleep_time = state->min_sleep_time;
2200+ }
2201+
2202+ mutex_unlock(&wm->codec_mutex);
2203+ return rc;
2204+}
2205+
2206+/*
2207+* The touchscreen sample reader thread.
2208+*/
2209+static int wm97xx_ts_read(void *data)
2210+{
2211+ int rc;
2212+ struct ts_state state;
2213+ struct wm97xx *wm = (struct wm97xx *) data;
2214+
2215+ /* set up thread context */
2216+ wm->ts_task = current;
2217+ daemonize("kwm97xxts");
2218+
2219+ if (wm->codec == NULL) {
2220+ wm->ts_task = NULL;
2221+ printk(KERN_ERR "codec is NULL, bailing\n");
2222+ }
2223+
2224+ complete(&wm->ts_init);
2225+ wm->pen_is_down = 0;
2226+ state.min_sleep_time = HZ >= 100 ? HZ / 100 : 1;
2227+ if (state.min_sleep_time < 1)
2228+ state.min_sleep_time = 1;
2229+ state.sleep_time = state.min_sleep_time;
2230+
2231+ /* touch reader loop */
2232+ while (wm->ts_task) {
2233+ do {
2234+ try_to_freeze();
2235+ rc = wm97xx_read_samples(wm, &state);
2236+ } while (rc & RC_AGAIN);
2237+ if (!wm->pen_is_down && wm->pen_irq) {
2238+ /* Nice, we don't have to poll for pen down event */
2239+ wait_event_interruptible(wm->pen_irq_wait, wm->pen_is_down);
2240+ } else {
2241+ set_task_state(current, TASK_INTERRUPTIBLE);
2242+ schedule_timeout(state.sleep_time);
2243+ }
2244+ }
2245+ complete_and_exit(&wm->ts_exit, 0);
2246+}
2247+
2248+/**
2249+ * wm97xx_ts_input_open - Open the touch screen input device.
2250+ * @idev: Input device to be opened.
2251+ *
2252+ * Called by the input sub system to open a wm97xx touchscreen device.
2253+ * Starts the touchscreen thread and touch digitiser.
2254+ */
2255+static int wm97xx_ts_input_open(struct input_dev *idev)
2256+{
2257+ int ret = 0;
2258+ struct wm97xx *wm = (struct wm97xx *) idev->private;
2259+
2260+ mutex_lock(&wm->codec_mutex);
2261+ /* first time opened ? */
2262+ if (wm->ts_use_count++ == 0) {
2263+ /* start touchscreen thread */
2264+ init_completion(&wm->ts_init);
2265+ init_completion(&wm->ts_exit);
2266+ ret = kernel_thread(wm97xx_ts_read, wm, CLONE_KERNEL);
2267+
2268+ if (ret >= 0) {
2269+ wait_for_completion(&wm->ts_init);
2270+ if (wm->ts_task == NULL)
2271+ ret = -EINVAL;
2272+ } else {
2273+ mutex_unlock(&wm->codec_mutex);
2274+ return ret;
2275+ }
2276+
2277+ /* start digitiser */
2278+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2279+ wm->codec->acc_enable(wm, 1);
2280+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_START);
2281+
2282+ /* init pen down/up irq handling */
2283+ if (wm->pen_irq) {
2284+ wm97xx_init_pen_irq(wm);
2285+
2286+ if (wm->pen_irq == 0) {
2287+ /* we failed to get an irq for pen down events,
2288+ * so we resort to polling. kickstart the reader */
2289+ wm->pen_is_down = 1;
2290+ wake_up_interruptible(&wm->pen_irq_wait);
2291+ }
2292+ }
2293+ }
2294+
2295+ mutex_unlock(&wm->codec_mutex);
2296+ return 0;
2297+}
2298+
2299+/**
2300+ * wm97xx_ts_input_close - Close the touch screen input device.
2301+ * @idev: Input device to be closed.
2302+ *
2303+ * Called by the input sub system to close a wm97xx touchscreen device.
2304+ * Kills the touchscreen thread and stops the touch digitiser.
2305+ */
2306+
2307+static void wm97xx_ts_input_close(struct input_dev *idev)
2308+{
2309+ struct wm97xx *wm = (struct wm97xx *) idev->private;
2310+
2311+ mutex_lock(&wm->codec_mutex);
2312+ if (--wm->ts_use_count == 0) {
2313+ /* destroy workqueues and free irqs */
2314+ if (wm->pen_irq) {
2315+ free_irq(wm->pen_irq, wm);
2316+ destroy_workqueue(wm->pen_irq_workq);
2317+ }
2318+
2319+ /* kill thread */
2320+ if (wm->ts_task) {
2321+ wm->ts_task = NULL;
2322+ wm->pen_is_down = 1;
2323+ wake_up_interruptible(&wm->pen_irq_wait);
2324+ wait_for_completion(&wm->ts_exit);
2325+ wm->pen_is_down = 0;
2326+ }
2327+
2328+ /* stop digitiser */
2329+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_STOP);
2330+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2331+ wm->codec->acc_enable(wm, 0);
2332+ }
2333+ mutex_unlock(&wm->codec_mutex);
2334+}
2335+
2336+static int wm97xx_bus_match(struct device *dev, struct device_driver *drv)
2337+{
2338+ return !(strcmp(dev->bus_id,drv->name));
2339+}
2340+
2341+/*
2342+ * The AC97 audio driver will do all the Codec suspend and resume
2343+ * tasks. This is just for anything machine specific or extra.
2344+ */
2345+static int wm97xx_bus_suspend(struct device *dev, pm_message_t state)
2346+{
2347+ int ret = 0;
2348+
2349+ if (dev->driver && dev->driver->suspend)
2350+ ret = dev->driver->suspend(dev, state);
2351+
2352+ return ret;
2353+}
2354+
2355+static int wm97xx_bus_resume(struct device *dev)
2356+{
2357+ int ret = 0;
2358+
2359+ if (dev->driver && dev->driver->resume)
2360+ ret = dev->driver->resume(dev);
2361+
2362+ return ret;
2363+}
2364+
2365+struct bus_type wm97xx_bus_type = {
2366+ .name = "wm97xx",
2367+ .match = wm97xx_bus_match,
2368+ .suspend = wm97xx_bus_suspend,
2369+ .resume = wm97xx_bus_resume,
2370+};
2371+
2372+static void wm97xx_release(struct device *dev)
2373+{
2374+ kfree(dev);
2375+}
2376+
2377+static int wm97xx_probe(struct device *dev)
2378+{
2379+ struct wm97xx* wm;
2380+ int ret = 0, id = 0;
2381+
2382+ if (!(wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL)))
2383+ return -ENOMEM;
2384+ mutex_init(&wm->codec_mutex);
2385+
2386+ init_waitqueue_head(&wm->pen_irq_wait);
2387+ wm->dev = dev;
2388+ dev->driver_data = wm;
2389+ wm->ac97 = to_ac97_t(dev);
2390+
2391+ /* check that we have a supported codec */
2392+ if ((id = wm97xx_reg_read(wm, AC97_VENDOR_ID1)) != WM97XX_ID1) {
2393+ err("could not find a wm97xx, found a %x instead\n", id);
2394+ kfree(wm);
2395+ return -ENODEV;
2396+ }
2397+
2398+ wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
2399+ if(wm->id != wm97xx_codec.id) {
2400+ err("could not find a the selected codec, please build for wm97%2x", wm->id & 0xff);
2401+ kfree(wm);
2402+ return -ENODEV;
2403+ }
2404+
2405+ if((wm->input_dev = input_allocate_device()) == NULL) {
2406+ kfree(wm);
2407+ return -ENOMEM;
2408+ }
2409+
2410+ /* set up touch configuration */
2411+ info("detected a wm97%2x codec", wm->id & 0xff);
2412+ wm->input_dev->name = "wm97xx touchscreen";
2413+ wm->input_dev->open = wm97xx_ts_input_open;
2414+ wm->input_dev->close = wm97xx_ts_input_close;
2415+ set_bit(EV_ABS, wm->input_dev->evbit);
2416+ set_bit(ABS_X, wm->input_dev->absbit);
2417+ set_bit(ABS_Y, wm->input_dev->absbit);
2418+ set_bit(ABS_PRESSURE, wm->input_dev->absbit);
2419+ wm->input_dev->absmax[ABS_X] = abs_x[1];
2420+ wm->input_dev->absmax[ABS_Y] = abs_y[1];
2421+ wm->input_dev->absmax[ABS_PRESSURE] = abs_p[1];
2422+ wm->input_dev->absmin[ABS_X] = abs_x[0];
2423+ wm->input_dev->absmin[ABS_Y] = abs_y[0];
2424+ wm->input_dev->absmin[ABS_PRESSURE] = abs_p[0];
2425+ wm->input_dev->absfuzz[ABS_X] = abs_x[2];
2426+ wm->input_dev->absfuzz[ABS_Y] = abs_y[2];
2427+ wm->input_dev->absfuzz[ABS_PRESSURE] = abs_p[2];
2428+ wm->input_dev->private = wm;
2429+ wm->codec = &wm97xx_codec;
2430+ if((ret = input_register_device(wm->input_dev)) < 0) {
2431+ kfree(wm);
2432+ return -ENOMEM;
2433+ }
2434+
2435+ if(aux_sys)
2436+ wm97xx_sys_add(dev);
2437+
2438+ /* set up physical characteristics */
2439+ wm->codec->digitiser_ioctl(wm, WM97XX_PHY_INIT);
2440+
2441+ /* load gpio cache */
2442+ wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG);
2443+ wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2444+ wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
2445+ wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
2446+ wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
2447+ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
2448+
2449+ /* register our battery device */
2450+ if (!(wm->battery_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
2451+ ret = -ENOMEM;
2452+ goto batt_err;
2453+ }
2454+ wm->battery_dev->bus = &wm97xx_bus_type;
2455+ strcpy(wm->battery_dev->bus_id,"wm97xx-battery");
2456+ wm->battery_dev->driver_data = wm;
2457+ wm->battery_dev->parent = dev;
2458+ wm->battery_dev->release = wm97xx_release;
2459+ if((ret = device_register(wm->battery_dev)) < 0)
2460+ goto batt_reg_err;
2461+
2462+ /* register our extended touch device (for machine specific extensions) */
2463+ if (!(wm->touch_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
2464+ ret = -ENOMEM;
2465+ goto touch_err;
2466+ }
2467+ wm->touch_dev->bus = &wm97xx_bus_type;
2468+ strcpy(wm->touch_dev->bus_id,"wm97xx-touchscreen");
2469+ wm->touch_dev->driver_data = wm;
2470+ wm->touch_dev->parent = dev;
2471+ wm->touch_dev->release = wm97xx_release;
2472+ if((ret = device_register(wm->touch_dev)) < 0)
2473+ goto touch_reg_err;
2474+
2475+ return ret;
2476+
2477+touch_reg_err:
2478+ kfree(wm->touch_dev);
2479+touch_err:
2480+ device_unregister(wm->battery_dev);
2481+batt_reg_err:
2482+ kfree(wm->battery_dev);
2483+batt_err:
2484+ input_unregister_device(wm->input_dev);
2485+ kfree(wm);
2486+ return ret;
2487+}
2488+
2489+static int wm97xx_remove(struct device *dev)
2490+{
2491+ struct wm97xx *wm = dev_get_drvdata(dev);
2492+
2493+ /* Stop touch reader thread */
2494+ if (wm->ts_task) {
2495+ wm->ts_task = NULL;
2496+ wm->pen_is_down = 1;
2497+ wake_up_interruptible(&wm->pen_irq_wait);
2498+ wait_for_completion(&wm->ts_exit);
2499+ }
2500+ device_unregister(wm->battery_dev);
2501+ device_unregister(wm->touch_dev);
2502+ input_unregister_device(wm->input_dev);
2503+
2504+ if(aux_sys)
2505+ wm97xx_sys_remove(dev);
2506+
2507+ kfree(wm);
2508+ return 0;
2509+}
2510+
2511+#ifdef CONFIG_PM
2512+int wm97xx_resume(struct device* dev)
2513+{
2514+ struct wm97xx *wm = dev_get_drvdata(dev);
2515+
2516+ /* restore digitiser and gpio's */
2517+ if(wm->id == WM9713_ID2) {
2518+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
2519+ wm97xx_reg_write(wm, 0x5a, wm->misc);
2520+ if(wm->ts_use_count) {
2521+ u16 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
2522+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
2523+ }
2524+ }
2525+
2526+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]);
2527+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]);
2528+
2529+ wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]);
2530+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]);
2531+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]);
2532+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]);
2533+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
2534+ wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
2535+
2536+ return 0;
2537+}
2538+
2539+#else
2540+#define wm97xx_resume NULL
2541+#endif
2542+
2543+int wm97xx_register_mach_ops(struct wm97xx *wm, struct wm97xx_mach_ops *mach_ops)
2544+{
2545+ mutex_lock(&wm->codec_mutex);
2546+ if(wm->mach_ops) {
2547+ mutex_unlock(&wm->codec_mutex);
2548+ return -EINVAL;
2549+ }
2550+ wm->mach_ops = mach_ops;
2551+ mutex_unlock(&wm->codec_mutex);
2552+ return 0;
2553+}
2554+
2555+void wm97xx_unregister_mach_ops(struct wm97xx *wm)
2556+{
2557+ mutex_lock(&wm->codec_mutex);
2558+ wm->mach_ops = NULL;
2559+ mutex_unlock(&wm->codec_mutex);
2560+}
2561+
2562+static struct device_driver wm97xx_driver = {
2563+ .name = "ac97",
2564+ .bus = &ac97_bus_type,
2565+ .owner = THIS_MODULE,
2566+ .probe = wm97xx_probe,
2567+ .remove = wm97xx_remove,
2568+ .resume = wm97xx_resume,
2569+};
2570+
2571+static int __init wm97xx_init(void)
2572+{
2573+ int ret;
2574+
2575+ info("version %s liam.girdwood@wolfsonmicro.com", WM_CORE_VERSION);
2576+ if((ret = bus_register(&wm97xx_bus_type)) < 0)
2577+ return ret;
2578+ return driver_register(&wm97xx_driver);
2579+}
2580+
2581+static void __exit wm97xx_exit(void)
2582+{
2583+ driver_unregister(&wm97xx_driver);
2584+ bus_unregister(&wm97xx_bus_type);
2585+}
2586+
2587+EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
2588+EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
2589+EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
2590+EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
2591+EXPORT_SYMBOL_GPL(wm97xx_reg_read);
2592+EXPORT_SYMBOL_GPL(wm97xx_reg_write);
2593+EXPORT_SYMBOL_GPL(wm97xx_bus_type);
2594+EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
2595+EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
2596+
2597+module_init(wm97xx_init);
2598+module_exit(wm97xx_exit);
2599+
2600+/* Module information */
2601+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
2602+MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
2603+MODULE_LICENSE("GPL");
2604Index: linux-2.6.17/include/linux/wm97xx.h
2605===================================================================
2606--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2607+++ linux-2.6.17/include/linux/wm97xx.h 2006-09-19 20:36:47.973052250 +0200
2608@@ -0,0 +1,291 @@
2609+
2610+/*
2611+ * Register bits and API for Wolfson WM97xx series of codecs
2612+ */
2613+
2614+#ifndef _LINUX_WM97XX_H
2615+#define _LINUX_WM97XX_H
2616+
2617+#include <sound/driver.h>
2618+#include <sound/core.h>
2619+#include <sound/pcm.h>
2620+#include <sound/ac97_codec.h>
2621+#include <sound/initval.h>
2622+#include <linux/types.h>
2623+#include <linux/list.h>
2624+#include <linux/input.h> /* Input device layer */
2625+
2626+/*
2627+ * WM97xx AC97 Touchscreen registers
2628+ */
2629+#define AC97_WM97XX_DIGITISER1 0x76
2630+#define AC97_WM97XX_DIGITISER2 0x78
2631+#define AC97_WM97XX_DIGITISER_RD 0x7a
2632+#define AC97_WM9713_DIG1 0x74
2633+#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1
2634+#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2
2635+
2636+/*
2637+ * WM97xx register bits
2638+ */
2639+#define WM97XX_POLL 0x8000 /* initiate a polling measurement */
2640+#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */
2641+#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */
2642+#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */
2643+#define WM97XX_ADCSEL_MASK 0x7000
2644+#define WM97XX_COO 0x0800 /* enable coordinate mode */
2645+#define WM97XX_CTC 0x0400 /* enable continuous mode */
2646+#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */
2647+#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */
2648+#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */
2649+#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */
2650+#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */
2651+#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */
2652+#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */
2653+#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */
2654+#define WM97XX_CM_RATE_MASK 0x03f0
2655+#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0))
2656+#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */
2657+#define WM97XX_DELAY_MASK 0x00f0
2658+#define WM97XX_SLEN 0x0008 /* slot read back enable */
2659+#define WM97XX_SLT(i) ((i - 5) & 0x7) /* touchpanel slot selection (5-11) */
2660+#define WM97XX_SLT_MASK 0x0007
2661+#define WM97XX_PRP_DETW 0x4000 /* pen detect on, digitiser off, wake up */
2662+#define WM97XX_PRP_DET 0x8000 /* pen detect on, digitiser off, no wake up */
2663+#define WM97XX_PRP_DET_DIG 0xc000 /* pen detect on, digitiser on */
2664+#define WM97XX_RPR 0x2000 /* wake up on pen down */
2665+#define WM97XX_PEN_DOWN 0x8000 /* pen is down */
2666+#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */
2667+
2668+#define WM97XX_AUX_ID1 0x8001
2669+#define WM97XX_AUX_ID2 0x8002
2670+#define WM97XX_AUX_ID3 0x8003
2671+#define WM97XX_AUX_ID4 0x8004
2672+
2673+
2674+/* WM9712 Bits */
2675+#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */
2676+#define WM9712_PDEN 0x0800 /* measure only when pen down */
2677+#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */
2678+#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */
2679+#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */
2680+#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */
2681+#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */
2682+#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */
2683+#define WM9712_PD(i) (0x1 << i) /* power management */
2684+
2685+/* WM9712 Registers */
2686+#define AC97_WM9712_POWER 0x24
2687+#define AC97_WM9712_REV 0x58
2688+
2689+/* WM9705 Bits */
2690+#define WM9705_PDEN 0x1000 /* measure only when pen is down */
2691+#define WM9705_PINV 0x0800 /* inverts sense of pen down output */
2692+#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */
2693+#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */
2694+#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */
2695+#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */
2696+#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */
2697+#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */
2698+#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */
2699+#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */
2700+#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */
2701+
2702+
2703+/* WM9713 Bits */
2704+#define WM9713_PDPOL 0x0400 /* Pen down polarity */
2705+#define WM9713_POLL 0x0200 /* initiate a polling measurement */
2706+#define WM9713_CTC 0x0100 /* enable continuous mode */
2707+#define WM9713_ADCSEL_X 0x0002 /* X measurement */
2708+#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */
2709+#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */
2710+#define WM9713_COO 0x0001 /* enable coordinate mode */
2711+#define WM9713_PDEN 0x0800 /* measure only when pen down */
2712+#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */
2713+#define WM9713_WAIT 0x0200 /* coordinate wait */
2714+
2715+/* AUX ADC ID's */
2716+#define TS_COMP1 0x0
2717+#define TS_COMP2 0x1
2718+#define TS_BMON 0x2
2719+#define TS_WIPER 0x3
2720+
2721+/* ID numbers */
2722+#define WM97XX_ID1 0x574d
2723+#define WM9712_ID2 0x4c12
2724+#define WM9705_ID2 0x4c05
2725+#define WM9713_ID2 0x4c13
2726+
2727+/* Codec GPIO's */
2728+#define WM97XX_MAX_GPIO 16
2729+#define WM97XX_GPIO_1 (1 << 1)
2730+#define WM97XX_GPIO_2 (1 << 2)
2731+#define WM97XX_GPIO_3 (1 << 3)
2732+#define WM97XX_GPIO_4 (1 << 4)
2733+#define WM97XX_GPIO_5 (1 << 5)
2734+#define WM97XX_GPIO_6 (1 << 6)
2735+#define WM97XX_GPIO_7 (1 << 7)
2736+#define WM97XX_GPIO_8 (1 << 8)
2737+#define WM97XX_GPIO_9 (1 << 9)
2738+#define WM97XX_GPIO_10 (1 << 10)
2739+#define WM97XX_GPIO_11 (1 << 11)
2740+#define WM97XX_GPIO_12 (1 << 12)
2741+#define WM97XX_GPIO_13 (1 << 13)
2742+#define WM97XX_GPIO_14 (1 << 14)
2743+#define WM97XX_GPIO_15 (1 << 15)
2744+
2745+
2746+#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */
2747+
2748+
2749+/*---------------- Return codes from sample reading functions ---------------*/
2750+
2751+/* More data is available; call the sample gathering function again */
2752+#define RC_AGAIN 0x00000001
2753+/* The returned sample is valid */
2754+#define RC_VALID 0x00000002
2755+/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */
2756+#define RC_PENUP 0x00000004
2757+/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful
2758+ to tell the handler that the pen is down but we don't know yet his coords,
2759+ so the handler should not sleep or wait for pendown irq) */
2760+#define RC_PENDOWN 0x00000008
2761+
2762+/* The wm97xx driver provides a private API for writing platform-specific
2763+ * drivers.
2764+ */
2765+
2766+/* The structure used to return arch specific sampled data into */
2767+struct wm97xx_data {
2768+ int x;
2769+ int y;
2770+ int p;
2771+};
2772+
2773+/* Codec GPIO status
2774+ */
2775+typedef enum {
2776+ WM97XX_GPIO_HIGH,
2777+ WM97XX_GPIO_LOW
2778+} wm97xx_gpio_status_t;
2779+
2780+/* Codec GPIO direction
2781+ */
2782+typedef enum {
2783+ WM97XX_GPIO_IN,
2784+ WM97XX_GPIO_OUT
2785+} wm97xx_gpio_dir_t;
2786+
2787+/* Codec GPIO polarity
2788+ */
2789+typedef enum {
2790+ WM97XX_GPIO_POL_HIGH,
2791+ WM97XX_GPIO_POL_LOW
2792+} wm97xx_gpio_pol_t;
2793+
2794+/* Codec GPIO sticky
2795+ */
2796+typedef enum {
2797+ WM97XX_GPIO_STICKY,
2798+ WM97XX_GPIO_NOTSTICKY
2799+} wm97xx_gpio_sticky_t;
2800+
2801+/* Codec GPIO wake
2802+ */
2803+typedef enum {
2804+ WM97XX_GPIO_WAKE,
2805+ WM97XX_GPIO_NOWAKE
2806+} wm97xx_gpio_wake_t;
2807+
2808+
2809+/*
2810+ * Digitiser ioctl commands
2811+ */
2812+#define WM97XX_DIG_START 0x1
2813+#define WM97XX_DIG_STOP 0x2
2814+#define WM97XX_PHY_INIT 0x3
2815+#define WM97XX_AUX_PREPARE 0x4
2816+#define WM97XX_DIG_RESTORE 0x5
2817+
2818+struct wm97xx;
2819+extern struct wm97xx_codec_drv wm97xx_codec;
2820+
2821+/*
2822+ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
2823+ */
2824+struct wm97xx_codec_drv {
2825+ u16 id;
2826+ char *name;
2827+ int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); /* read 1 sample */
2828+ int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); /* read X,Y,[P] in poll */
2829+ int (*digitiser_ioctl) (struct wm97xx *, int cmd);
2830+ int (*acc_enable) (struct wm97xx *, int enable);
2831+};
2832+
2833+
2834+/* Machine specific and accelerated touch operations */
2835+struct wm97xx_mach_ops {
2836+
2837+ /* accelerated touch readback - coords are transmited on AC97 link */
2838+ int acc_enabled;
2839+ void (*acc_pen_up) (struct wm97xx *);
2840+ int (*acc_pen_down) (struct wm97xx *);
2841+ int (*acc_startup) (struct wm97xx *);
2842+ void (*acc_shutdown) (struct wm97xx *);
2843+
2844+ /* pre and post sample - can be used to minimise any analog noise */
2845+ void (*pre_sample) (int); /* function to run before sampling */
2846+ void (*post_sample) (int); /* function to run after sampling */
2847+};
2848+
2849+struct wm97xx {
2850+ u16 dig[3], id, gpio[6], misc; /* Cached codec registers */
2851+ u16 dig_save[3]; /* saved during aux reading */
2852+ struct wm97xx_codec_drv *codec; /* attached codec driver*/
2853+ struct input_dev* input_dev; /* touchscreen input device */
2854+ ac97_t *ac97; /* ALSA codec access */
2855+ struct device *dev; /* ALSA device */
2856+ struct device *battery_dev;
2857+ struct device *touch_dev;
2858+ struct wm97xx_mach_ops *mach_ops;
2859+ struct mutex codec_mutex;
2860+ struct completion ts_init;
2861+ struct completion ts_exit;
2862+ struct task_struct *ts_task;
2863+ unsigned int pen_irq; /* Pen IRQ number in use */
2864+ wait_queue_head_t pen_irq_wait; /* Pen IRQ wait queue */
2865+ struct workqueue_struct *pen_irq_workq;
2866+ struct work_struct pen_event_work;
2867+ u16 acc_slot; /* AC97 slot used for acc touch data */
2868+ u16 acc_rate; /* acc touch data rate */
2869+ unsigned int ts_use_count;
2870+ unsigned pen_is_down:1; /* Pen is down */
2871+ unsigned aux_waiting:1; /* aux measurement waiting */
2872+ unsigned pen_probably_down:1; /* used in polling mode */
2873+};
2874+
2875+/* Codec GPIO access (not supported on WM9705)
2876+ * This can be used to set/get codec GPIO and Virtual GPIO status.
2877+ */
2878+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio);
2879+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
2880+ wm97xx_gpio_status_t status);
2881+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio,
2882+ wm97xx_gpio_dir_t dir,
2883+ wm97xx_gpio_pol_t pol,
2884+ wm97xx_gpio_sticky_t sticky,
2885+ wm97xx_gpio_wake_t wake);
2886+
2887+/* codec AC97 IO access */
2888+int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
2889+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);
2890+
2891+/* aux adc readback */
2892+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel);
2893+
2894+/* machine ops */
2895+int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *);
2896+void wm97xx_unregister_mach_ops(struct wm97xx *);
2897+
2898+extern struct bus_type wm97xx_bus_type;
2899+#endif