1 From 821604bad5ce1ef942eeb420afd9ea2c5c92875e Mon Sep 17 00:00:00 2001
2 From: Mark Brown <broonie@opensource.wolfsonmicro.com>
3 Date: Sat, 26 Jan 2008 21:14:19 +0300
4 Subject: [PATCH 34/64] Driver for WM97xx touchscreens in streaming mode on Mainstone
6 Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
7 Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
8 Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
9 Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
10 Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
11 Cc: Stanley Cai <stanley.cai@intel.com>
12 Cc: Rodolfo Giometti <giometti@enneenne.com>
13 Cc: Russell King <rmk@arm.linux.org.uk>
14 Cc: Marc Kleine-Budde <mkl@pengutronix.de>
15 Cc: Ian Molton <spyro@f2s.com>
16 Cc: Vince Sanders <vince@kyllikki.org>
17 Cc: Andrew Zabolotny <zap@homelink.ru>
19 drivers/input/touchscreen/mainstone-wm97xx.c | 298 ++++++++++++++++++++++++++
20 1 files changed, 298 insertions(+), 0 deletions(-)
21 create mode 100644 drivers/input/touchscreen/mainstone-wm97xx.c
23 diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
25 index 0000000..8e1c35d
27 +++ b/drivers/input/touchscreen/mainstone-wm97xx.c
30 + * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for
31 + * Wolfson WM97xx AC97 Codecs.
33 + * Copyright 2004, 2007 Wolfson Microelectronics PLC.
34 + * Author: Liam Girdwood
35 + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
36 + * Parts Copyright : Ian Molton <spyro@f2s.com>
37 + * Andrew Zabolotny <zap@homelink.ru>
39 + * This program is free software; you can redistribute it and/or modify it
40 + * under the terms of the GNU General Public License as published by the
41 + * Free Software Foundation; either version 2 of the License, or (at your
42 + * option) any later version.
45 + * This is a wm97xx extended touch driver to capture touch
46 + * data in a continuous manner on the Intel XScale archictecture
49 + * - codecs supported:- WM9705, WM9712, WM9713
50 + * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
54 +#include <linux/module.h>
55 +#include <linux/moduleparam.h>
56 +#include <linux/version.h>
57 +#include <linux/kernel.h>
58 +#include <linux/init.h>
59 +#include <linux/delay.h>
60 +#include <linux/irq.h>
61 +#include <linux/interrupt.h>
62 +#include <linux/wm97xx.h>
63 +#include <linux/io.h>
64 +#include <asm/arch/pxa-regs.h>
66 +#define VERSION "0.13"
69 + u16 id; /* codec id */
70 + u8 code; /* continuous code */
71 + u8 reads; /* number of coord reads per read cycle */
72 + u32 speed; /* number of coords per second */
75 +#define WM_READS(sp) ((sp / HZ) + 1)
77 +static const struct continuous cinfo[] = {
78 + {WM9705_ID2, 0, WM_READS(94), 94},
79 + {WM9705_ID2, 1, WM_READS(188), 188},
80 + {WM9705_ID2, 2, WM_READS(375), 375},
81 + {WM9705_ID2, 3, WM_READS(750), 750},
82 + {WM9712_ID2, 0, WM_READS(94), 94},
83 + {WM9712_ID2, 1, WM_READS(188), 188},
84 + {WM9712_ID2, 2, WM_READS(375), 375},
85 + {WM9712_ID2, 3, WM_READS(750), 750},
86 + {WM9713_ID2, 0, WM_READS(94), 94},
87 + {WM9713_ID2, 1, WM_READS(120), 120},
88 + {WM9713_ID2, 2, WM_READS(154), 154},
89 + {WM9713_ID2, 3, WM_READS(188), 188},
92 +/* continuous speed index */
94 +static u16 last, tries;
97 + * Pen sampling frequency (Hz) in continuous mode.
99 +static int cont_rate = 200;
100 +module_param(cont_rate, int, 0);
101 +MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
104 + * Pen down detection.
106 + * This driver can either poll or use an interrupt to indicate a pen down
107 + * event. If the irq request fails then it will fall back to polling mode.
110 +module_param(pen_int, int, 0);
111 +MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
114 + * Pressure readback.
116 + * Set to 1 to read back pen down pressure
118 +static int pressure;
119 +module_param(pressure, int, 0);
120 +MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
123 + * AC97 touch data slot.
125 + * Touch screen readback data ac97 slot
127 +static int ac97_touch_slot = 5;
128 +module_param(ac97_touch_slot, int, 0);
129 +MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
132 +/* flush AC97 slot 5 FIFO on pxa machines */
133 +#ifdef CONFIG_PXA27x
134 +static void wm97xx_acc_pen_up(struct wm97xx *wm)
136 + set_current_state(TASK_INTERRUPTIBLE);
137 + schedule_timeout(1);
139 + while (MISR & (1 << 2))
143 +static void wm97xx_acc_pen_up(struct wm97xx *wm)
146 + set_current_state(TASK_INTERRUPTIBLE);
147 + schedule_timeout(1);
149 + while (count < 16) {
156 +static int wm97xx_acc_pen_down(struct wm97xx *wm)
158 + u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
161 + /* data is never immediately available after pen down irq */
162 + set_current_state(TASK_INTERRUPTIBLE);
163 + schedule_timeout(1);
183 + /* are samples valid */
184 + if ((x & 0x7000) != WM97XX_ADCSEL_X ||
185 + (y & 0x7000) != WM97XX_ADCSEL_Y ||
186 + (p & 0x7000) != WM97XX_ADCSEL_PRES)
189 + /* coordinate is good */
191 + input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
192 + input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
193 + input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
194 + input_sync(wm->input_dev);
196 + } while (reads < cinfo[sp_idx].reads);
198 + return RC_PENDOWN | RC_AGAIN;
201 +static int wm97xx_acc_startup(struct wm97xx *wm)
205 + /* check we have a codec */
206 + if (wm->ac97 == NULL)
209 + /* Go you big red fire engine */
210 + for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
211 + if (wm->id != cinfo[idx].id)
214 + if (cont_rate <= cinfo[idx].speed)
217 + wm->acc_rate = cinfo[sp_idx].code;
218 + wm->acc_slot = ac97_touch_slot;
220 + "mainstone accelerated touchscreen driver, %d samples/sec\n",
221 + cinfo[sp_idx].speed);
223 + /* codec specific irq config */
227 + wm->pen_irq = IRQ_GPIO(4);
228 + set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
232 + /* enable pen down interrupt */
233 + /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
234 + wm->pen_irq = MAINSTONE_AC97_IRQ;
235 + wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
236 + WM97XX_GPIO_POL_HIGH,
237 + WM97XX_GPIO_STICKY,
239 + wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
240 + WM97XX_GPIO_POL_HIGH,
241 + WM97XX_GPIO_NOTSTICKY,
242 + WM97XX_GPIO_NOWAKE);
246 + "pen down irq not supported on this device\n");
255 +static void wm97xx_acc_shutdown(struct wm97xx *wm)
257 + /* codec specific deconfig */
259 + switch (wm->id & 0xffff) {
265 + /* disable interrupt */
272 +static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
275 + enable_irq(wm->pen_irq);
277 + disable_irq(wm->pen_irq);
280 +static struct wm97xx_mach_ops mainstone_mach_ops = {
282 + .acc_pen_up = wm97xx_acc_pen_up,
283 + .acc_pen_down = wm97xx_acc_pen_down,
284 + .acc_startup = wm97xx_acc_startup,
285 + .acc_shutdown = wm97xx_acc_shutdown,
286 + .irq_enable = wm97xx_irq_enable,
289 +static int mainstone_wm97xx_probe(struct platform_device *pdev)
291 + struct wm97xx *wm = platform_get_drvdata(pdev);
292 + return wm97xx_register_mach_ops(wm, &mainstone_mach_ops);
295 +static int mainstone_wm97xx_remove(struct platform_device *pdev)
297 + struct wm97xx *wm = platform_get_drvdata(pdev);
298 + wm97xx_unregister_mach_ops(wm);
302 +static struct platform_driver mainstone_wm97xx_driver = {
303 + .probe = mainstone_wm97xx_probe,
304 + .remove = mainstone_wm97xx_remove,
306 + .name = "wm97xx-touch",
310 +static int __init mainstone_wm97xx_init(void)
312 + return platform_driver_register(&mainstone_wm97xx_driver);
315 +static void __exit mainstone_wm97xx_exit(void)
317 + platform_driver_unregister(&mainstone_wm97xx_driver);
320 +module_init(mainstone_wm97xx_init);
321 +module_exit(mainstone_wm97xx_exit);
323 +/* Module information */
324 +MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
325 +MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
326 +MODULE_LICENSE("GPL");