aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2006-01-08 16:34:21 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-13 19:29:54 -0500
commitffa458c1bd9b6f653008d450f337602f3d52a646 (patch)
tree0e42f7d36790dd7088586b32d9c5290d34b10831 /drivers/input/touchscreen
parent8ae12a0d85987dc138f8c944cb78a92bf466cea0 (diff)
[PATCH] spi: ads7846 driver
This is a driver for the ADS7846 touchscreen sensor, derived from the corgi_ts and omap_ts drivers. Key differences from those two: - Uses the new SPI framework (minimalist version) - <linux/spi/ads7846.h> abstracts board-specific touchscreen info - Sysfs attributes for the temperature and voltage sensors - Uses fewer ARM-specific IRQ primitives The temperature and voltage sensors show up in sysfs like this: $ pwd /sys/devices/platform/omap-uwire/spi2.0 $ ls bus@ input:event0@ power/ temp1 vbatt driver@ modalias temp0 vaux $ cat modalias ads7846 $ cat temp0 991 $ cat temp1 1177 $ So far only basic testing has been done. There's a fair amount of hardware that uses this sensor, and which also runs Linux, which should eventually be able to use this driver. One portability note may be of special interest. It turns out that not all SPI controllers are happy issuing requests that do things like "write 8 bit command, read 12 bit response". Most of them seem happy to handle various word sizes, so the issue isn't "12 bit response" but rather "different rx and tx write sizes", despite that being a common MicroWire convention. So this version of the driver no longer reads 12 bit native-endian words; it reads 16-bit big-endian responses, then byteswaps them and shifts the results to discard the noise. Signed-off-by: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig13
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ads7846.c621
3 files changed, 635 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 21d55ed4b88a..2c674023a6ac 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,19 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_ADS7846
15 tristate "ADS 7846 based touchscreens"
16 depends on SPI_MASTER
17 help
18 Say Y here if you have a touchscreen interface using the
19 ADS7846 controller, and your board-specific initialization
20 code includes that in its table of SPI devices.
21
22 If unsure, say N (but it's safe to say "Y").
23
24 To compile this driver as a module, choose M here: the
25 module will be called ads7846.
26
14config TOUCHSCREEN_BITSY 27config TOUCHSCREEN_BITSY
15 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" 28 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
16 depends on SA1100_BITSY 29 depends on SA1100_BITSY
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 6842869c9a26..5e5557c43121 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
7obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 8obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
8obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o 9obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
9obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 10obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
new file mode 100644
index 000000000000..24ff6c5a4021
--- /dev/null
+++ b/drivers/input/touchscreen/ads7846.c
@@ -0,0 +1,621 @@
1/*
2 * ADS7846 based touchscreen and sensor driver
3 *
4 * Copyright (c) 2005 David Brownell
5 *
6 * Using code from:
7 * - corgi_ts.c
8 * Copyright (C) 2004-2005 Richard Purdie
9 * - omap_ts.[hc], ads7846.h, ts_osk.c
10 * Copyright (C) 2002 MontaVista Software
11 * Copyright (C) 2004 Texas Instruments
12 * Copyright (C) 2005 Dirk Behme
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/device.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/spi/spi.h>
25#include <linux/spi/ads7846.h>
26
27#ifdef CONFIG_ARM
28#include <asm/mach-types.h>
29#ifdef CONFIG_ARCH_OMAP
30#include <asm/arch/gpio.h>
31#endif
32
33#else
34#define set_irq_type(irq,type) do{}while(0)
35#endif
36
37
38/*
39 * This code has been lightly tested on an ads7846.
40 * Support for ads7843 and ads7845 has only been stubbed in.
41 *
42 * Not yet done: investigate the values reported. Are x/y/pressure
43 * event values sane enough for X11? How accurate are the temperature
44 * and voltage readings? (System-specific calibration should support
45 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
46 *
47 * app note sbaa036 talks in more detail about accurate sampling...
48 * that ought to help in situations like LCDs inducing noise (which
49 * can also be helped by using synch signals) and more generally.
50 */
51
52#define TS_POLL_PERIOD msecs_to_jiffies(10)
53
54struct ts_event {
55 /* For portability, we can't read 12 bit values using SPI (which
56 * would make the controller deliver them as native byteorder u16
57 * with msbs zeroed). Instead, we read them as two 8-byte values,
58 * which need byteswapping then range adjustment.
59 */
60 __be16 x;
61 __be16 y;
62 __be16 z1, z2;
63};
64
65struct ads7846 {
66 struct input_dev input;
67 char phys[32];
68
69 struct spi_device *spi;
70 u16 model;
71 u16 vref_delay_usecs;
72 u16 x_plate_ohms;
73
74 struct ts_event tc;
75
76 struct spi_transfer xfer[8];
77 struct spi_message msg;
78
79 spinlock_t lock;
80 struct timer_list timer; /* P: lock */
81 unsigned pendown:1; /* P: lock */
82 unsigned pending:1; /* P: lock */
83// FIXME remove "irq_disabled"
84 unsigned irq_disabled:1; /* P: lock */
85};
86
87/* leave chip selected when we're done, for quicker re-select? */
88#if 0
89#define CS_CHANGE(xfer) ((xfer).cs_change = 1)
90#else
91#define CS_CHANGE(xfer) ((xfer).cs_change = 0)
92#endif
93
94/*--------------------------------------------------------------------------*/
95
96/* The ADS7846 has touchscreen and other sensors.
97 * Earlier ads784x chips are somewhat compatible.
98 */
99#define ADS_START (1 << 7)
100#define ADS_A2A1A0_d_y (1 << 4) /* differential */
101#define ADS_A2A1A0_d_z1 (3 << 4) /* differential */
102#define ADS_A2A1A0_d_z2 (4 << 4) /* differential */
103#define ADS_A2A1A0_d_x (5 << 4) /* differential */
104#define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */
105#define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */
106#define ADS_A2A1A0_vaux (6 << 4) /* non-differential */
107#define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */
108#define ADS_8_BIT (1 << 3)
109#define ADS_12_BIT (0 << 3)
110#define ADS_SER (1 << 2) /* non-differential */
111#define ADS_DFR (0 << 2) /* differential */
112#define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */
113#define ADS_PD10_ADC_ON (1 << 0) /* ADC on */
114#define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */
115#define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */
116
117#define MAX_12BIT ((1<<12)-1)
118
119/* leave ADC powered up (disables penirq) between differential samples */
120#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
121 | ADS_12_BIT | ADS_DFR)
122
123static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON;
124static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON;
125static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON;
126static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */
127
128/* single-ended samples need to first power up reference voltage;
129 * we leave both ADC and VREF powered
130 */
131#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
132 | ADS_12_BIT | ADS_SER)
133
134static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON;
135static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN;
136
137/*--------------------------------------------------------------------------*/
138
139/*
140 * Non-touchscreen sensors only use single-ended conversions.
141 */
142
143struct ser_req {
144 u8 command;
145 u16 scratch;
146 __be16 sample;
147 struct spi_message msg;
148 struct spi_transfer xfer[6];
149};
150
151static int ads7846_read12_ser(struct device *dev, unsigned command)
152{
153 struct spi_device *spi = to_spi_device(dev);
154 struct ads7846 *ts = dev_get_drvdata(dev);
155 struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL);
156 int status;
157 int sample;
158
159 if (!req)
160 return -ENOMEM;
161
162 /* activate reference, so it has time to settle; */
163 req->xfer[0].tx_buf = &ref_on;
164 req->xfer[0].len = 1;
165 req->xfer[1].rx_buf = &req->scratch;
166 req->xfer[1].len = 2;
167
168 /*
169 * for external VREF, 0 usec (and assume it's always on);
170 * for 1uF, use 800 usec;
171 * no cap, 100 usec.
172 */
173 req->xfer[1].delay_usecs = ts->vref_delay_usecs;
174
175 /* take sample */
176 req->command = (u8) command;
177 req->xfer[2].tx_buf = &req->command;
178 req->xfer[2].len = 1;
179 req->xfer[3].rx_buf = &req->sample;
180 req->xfer[3].len = 2;
181
182 /* REVISIT: take a few more samples, and compare ... */
183
184 /* turn off reference */
185 req->xfer[4].tx_buf = &ref_off;
186 req->xfer[4].len = 1;
187 req->xfer[5].rx_buf = &req->scratch;
188 req->xfer[5].len = 2;
189
190 CS_CHANGE(req->xfer[5]);
191
192 /* group all the transfers together, so we can't interfere with
193 * reading touchscreen state; disable penirq while sampling
194 */
195 req->msg.transfers = req->xfer;
196 req->msg.n_transfer = 6;
197
198 disable_irq(spi->irq);
199 status = spi_sync(spi, &req->msg);
200 enable_irq(spi->irq);
201
202 if (req->msg.status)
203 status = req->msg.status;
204 sample = be16_to_cpu(req->sample);
205 sample = sample >> 4;
206 kfree(req);
207
208 return status ? status : sample;
209}
210
211#define SHOW(name) static ssize_t \
212name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
213{ \
214 ssize_t v = ads7846_read12_ser(dev, \
215 READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \
216 if (v < 0) \
217 return v; \
218 return sprintf(buf, "%u\n", (unsigned) v); \
219} \
220static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
221
222SHOW(temp0)
223SHOW(temp1)
224SHOW(vaux)
225SHOW(vbatt)
226
227/*--------------------------------------------------------------------------*/
228
229/*
230 * PENIRQ only kicks the timer. The timer only reissues the SPI transfer,
231 * to retrieve touchscreen status.
232 *
233 * The SPI transfer completion callback does the real work. It reports
234 * touchscreen events and reactivates the timer (or IRQ) as appropriate.
235 */
236
237static void ads7846_rx(void *ads)
238{
239 struct ads7846 *ts = ads;
240 unsigned Rt;
241 unsigned sync = 0;
242 u16 x, y, z1, z2;
243 unsigned long flags;
244
245 /* adjust: 12 bit samples (left aligned), built from
246 * two 8 bit values writen msb-first.
247 */
248 x = be16_to_cpu(ts->tc.x) >> 4;
249 y = be16_to_cpu(ts->tc.y) >> 4;
250 z1 = be16_to_cpu(ts->tc.z1) >> 4;
251 z2 = be16_to_cpu(ts->tc.z2) >> 4;
252
253 /* range filtering */
254 if (x == MAX_12BIT)
255 x = 0;
256
257 if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
258 /* compute touch pressure resistance using equation #2 */
259 Rt = z2;
260 Rt -= z1;
261 Rt *= x;
262 Rt *= ts->x_plate_ohms;
263 Rt /= z1;
264 Rt = (Rt + 2047) >> 12;
265 } else
266 Rt = 0;
267
268 /* NOTE: "pendown" is inferred from pressure; we don't rely on
269 * being able to check nPENIRQ status, or "friendly" trigger modes
270 * (both-edges is much better than just-falling or low-level).
271 *
272 * REVISIT: some boards may require reading nPENIRQ; it's
273 * needed on 7843. and 7845 reads pressure differently...
274 *
275 * REVISIT: the touchscreen might not be connected; this code
276 * won't notice that, even if nPENIRQ never fires ...
277 */
278 if (!ts->pendown && Rt != 0) {
279 input_report_key(&ts->input, BTN_TOUCH, 1);
280 sync = 1;
281 } else if (ts->pendown && Rt == 0) {
282 input_report_key(&ts->input, BTN_TOUCH, 0);
283 sync = 1;
284 }
285
286 if (Rt) {
287 input_report_abs(&ts->input, ABS_X, x);
288 input_report_abs(&ts->input, ABS_Y, y);
289 input_report_abs(&ts->input, ABS_PRESSURE, Rt);
290 sync = 1;
291 }
292 if (sync)
293 input_sync(&ts->input);
294
295#ifdef VERBOSE
296 if (Rt || ts->pendown)
297 pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
298 x, y, Rt, Rt ? "" : " UP");
299#endif
300
301 /* don't retrigger while we're suspended */
302 spin_lock_irqsave(&ts->lock, flags);
303
304 ts->pendown = (Rt != 0);
305 ts->pending = 0;
306
307 if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
308 if (ts->pendown)
309 mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
310 else if (ts->irq_disabled) {
311 ts->irq_disabled = 0;
312 enable_irq(ts->spi->irq);
313 }
314 }
315
316 spin_unlock_irqrestore(&ts->lock, flags);
317}
318
319static void ads7846_timer(unsigned long handle)
320{
321 struct ads7846 *ts = (void *)handle;
322 int status = 0;
323 unsigned long flags;
324
325 spin_lock_irqsave(&ts->lock, flags);
326 if (!ts->pending) {
327 ts->pending = 1;
328 if (!ts->irq_disabled) {
329 ts->irq_disabled = 1;
330 disable_irq(ts->spi->irq);
331 }
332 status = spi_async(ts->spi, &ts->msg);
333 if (status)
334 dev_err(&ts->spi->dev, "spi_async --> %d\n",
335 status);
336 }
337 spin_unlock_irqrestore(&ts->lock, flags);
338}
339
340static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
341{
342 ads7846_timer((unsigned long) handle);
343 return IRQ_HANDLED;
344}
345
346/*--------------------------------------------------------------------------*/
347
348/* non-empty "extra" is needed before 2.6.14-git5 or so */
349#define EXTRA // , u32 level
350#define EXTRA2 // , 0
351
352static int
353ads7846_suspend(struct device *dev, pm_message_t message EXTRA)
354{
355 struct ads7846 *ts = dev_get_drvdata(dev);
356 unsigned long flags;
357
358 spin_lock_irqsave(&ts->lock, flags);
359
360 ts->spi->dev.power.power_state = message;
361
362 /* are we waiting for IRQ, or polling? */
363 if (!ts->pendown) {
364 if (!ts->irq_disabled) {
365 ts->irq_disabled = 1;
366 disable_irq(ts->spi->irq);
367 }
368 } else {
369 /* polling; force a final SPI completion;
370 * that will clean things up neatly
371 */
372 if (!ts->pending)
373 mod_timer(&ts->timer, jiffies);
374
375 while (ts->pendown || ts->pending) {
376 spin_unlock_irqrestore(&ts->lock, flags);
377 udelay(10);
378 spin_lock_irqsave(&ts->lock, flags);
379 }
380 }
381
382 /* we know the chip's in lowpower mode since we always
383 * leave it that way after every request
384 */
385
386 spin_unlock_irqrestore(&ts->lock, flags);
387 return 0;
388}
389
390static int ads7846_resume(struct device *dev EXTRA)
391{
392 struct ads7846 *ts = dev_get_drvdata(dev);
393
394 ts->irq_disabled = 0;
395 enable_irq(ts->spi->irq);
396 dev->power.power_state = PMSG_ON;
397 return 0;
398}
399
400static int __init ads7846_probe(struct device *dev)
401{
402 struct spi_device *spi = to_spi_device(dev);
403 struct ads7846 *ts;
404 struct ads7846_platform_data *pdata = dev->platform_data;
405 struct spi_transfer *x;
406
407 if (!spi->irq) {
408 dev_dbg(dev, "no IRQ?\n");
409 return -ENODEV;
410 }
411
412 if (!pdata) {
413 dev_dbg(dev, "no platform data?\n");
414 return -ENODEV;
415 }
416
417 /* don't exceed max specified sample rate */
418 if (spi->max_speed_hz > (125000 * 16)) {
419 dev_dbg(dev, "f(sample) %d KHz?\n",
420 (spi->max_speed_hz/16)/1000);
421 return -EINVAL;
422 }
423
424 /* We'd set the wordsize to 12 bits ... except that some controllers
425 * will then treat the 8 bit command words as 12 bits (and drop the
426 * four MSBs of the 12 bit result). Result: inputs must be shifted
427 * to discard the four garbage LSBs.
428 */
429
430 if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL)))
431 return -ENOMEM;
432
433 dev_set_drvdata(dev, ts);
434
435 ts->spi = spi;
436 spi->dev.power.power_state = PMSG_ON;
437
438 init_timer(&ts->timer);
439 ts->timer.data = (unsigned long) ts;
440 ts->timer.function = ads7846_timer;
441
442 ts->model = pdata->model ? : 7846;
443 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
444 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
445
446 init_input_dev(&ts->input);
447
448 ts->input.dev = dev;
449 ts->input.name = "ADS784x Touchscreen";
450 snprintf(ts->phys, sizeof ts->phys, "%s/input0", dev->bus_id);
451 ts->input.phys = ts->phys;
452
453 ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
454 ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
455 input_set_abs_params(&ts->input, ABS_X,
456 pdata->x_min ? : 0,
457 pdata->x_max ? : MAX_12BIT,
458 0, 0);
459 input_set_abs_params(&ts->input, ABS_Y,
460 pdata->y_min ? : 0,
461 pdata->y_max ? : MAX_12BIT,
462 0, 0);
463 input_set_abs_params(&ts->input, ABS_PRESSURE,
464 pdata->pressure_min, pdata->pressure_max, 0, 0);
465
466 input_register_device(&ts->input);
467
468 /* set up the transfers to read touchscreen state; this assumes we
469 * use formula #2 for pressure, not #3.
470 */
471 x = ts->xfer;
472
473 /* y- still on; turn on only y+ (and ADC) */
474 x->tx_buf = &read_y;
475 x->len = 1;
476 x++;
477 x->rx_buf = &ts->tc.y;
478 x->len = 2;
479 x++;
480
481 /* turn y+ off, x- on; we'll use formula #2 */
482 if (ts->model == 7846) {
483 x->tx_buf = &read_z1;
484 x->len = 1;
485 x++;
486 x->rx_buf = &ts->tc.z1;
487 x->len = 2;
488 x++;
489
490 x->tx_buf = &read_z2;
491 x->len = 1;
492 x++;
493 x->rx_buf = &ts->tc.z2;
494 x->len = 2;
495 x++;
496 }
497
498 /* turn y- off, x+ on, then leave in lowpower */
499 x->tx_buf = &read_x;
500 x->len = 1;
501 x++;
502 x->rx_buf = &ts->tc.x;
503 x->len = 2;
504 x++;
505
506 CS_CHANGE(x[-1]);
507
508 ts->msg.transfers = ts->xfer;
509 ts->msg.n_transfer = x - ts->xfer;
510 ts->msg.complete = ads7846_rx;
511 ts->msg.context = ts;
512
513 if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM,
514 dev->bus_id, ts)) {
515 dev_dbg(dev, "irq %d busy?\n", spi->irq);
516 input_unregister_device(&ts->input);
517 kfree(ts);
518 return -EBUSY;
519 }
520 set_irq_type(spi->irq, IRQT_FALLING);
521
522 dev_info(dev, "touchscreen, irq %d\n", spi->irq);
523
524 /* take a first sample, leaving nPENIRQ active; avoid
525 * the touchscreen, in case it's not connected.
526 */
527 (void) ads7846_read12_ser(dev,
528 READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
529
530 /* ads7843/7845 don't have temperature sensors, and
531 * use the other sensors a bit differently too
532 */
533 if (ts->model == 7846) {
534 device_create_file(dev, &dev_attr_temp0);
535 device_create_file(dev, &dev_attr_temp1);
536 }
537 if (ts->model != 7845)
538 device_create_file(dev, &dev_attr_vbatt);
539 device_create_file(dev, &dev_attr_vaux);
540
541 return 0;
542}
543
544static int __exit ads7846_remove(struct device *dev)
545{
546 struct ads7846 *ts = dev_get_drvdata(dev);
547
548 ads7846_suspend(dev, PMSG_SUSPEND EXTRA2);
549 free_irq(ts->spi->irq, ts);
550 if (ts->irq_disabled)
551 enable_irq(ts->spi->irq);
552
553 if (ts->model == 7846) {
554 device_remove_file(dev, &dev_attr_temp0);
555 device_remove_file(dev, &dev_attr_temp1);
556 }
557 if (ts->model != 7845)
558 device_remove_file(dev, &dev_attr_vbatt);
559 device_remove_file(dev, &dev_attr_vaux);
560
561 input_unregister_device(&ts->input);
562 kfree(ts);
563
564 dev_dbg(dev, "unregistered touchscreen\n");
565 return 0;
566}
567
568static struct device_driver ads7846_driver = {
569 .name = "ads7846",
570 .bus = &spi_bus_type,
571 .probe = ads7846_probe,
572 .remove = __exit_p(ads7846_remove),
573 .suspend = ads7846_suspend,
574 .resume = ads7846_resume,
575};
576
577static int __init ads7846_init(void)
578{
579 /* grr, board-specific init should stay out of drivers!! */
580
581#ifdef CONFIG_ARCH_OMAP
582 if (machine_is_omap_osk()) {
583 /* GPIO4 = PENIRQ; GPIO6 = BUSY */
584 omap_request_gpio(4);
585 omap_set_gpio_direction(4, 1);
586 omap_request_gpio(6);
587 omap_set_gpio_direction(6, 1);
588 }
589 // also TI 1510 Innovator, bitbanging through FPGA
590 // also Nokia 770
591 // also Palm Tungsten T2
592#endif
593
594 // PXA:
595 // also Dell Axim X50
596 // also HP iPaq H191x/H192x/H415x/H435x
597 // also Intel Lubbock (alternate to UCB1400)
598 // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
599
600 // also various AMD Au1x00 devel boards
601
602 return driver_register(&ads7846_driver);
603}
604module_init(ads7846_init);
605
606static void __exit ads7846_exit(void)
607{
608 driver_unregister(&ads7846_driver);
609
610#ifdef CONFIG_ARCH_OMAP
611 if (machine_is_omap_osk()) {
612 omap_free_gpio(4);
613 omap_free_gpio(6);
614 }
615#endif
616
617}
618module_exit(ads7846_exit);
619
620MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
621MODULE_LICENSE("GPL");