Linux 2.6.19
[gumsense-br.git] / target / device / Gumstix / basix-connex / kernel-patches / ucb1400-touchscreen.patch
blob06d8080d88ccabf07548e7e7ed33771f1fe6ffba
1 This patch is slightly adjusted from
3 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3073/1
4 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3074/2
5 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3075/2
7 in order to get it to apply cleanly to the released 2.6.15 codebase
8 and to put the Kconfig stuff in a more reasonable place in the tree.
9 Actually, I think Kconfig should probably separate the notion of the
10 touchscreen driver and the AC97-MCP layer thing; but that problem is
11 basically in the underlying mcp-based ucb1x00 driver layout in the
12 first place.
13 Index: linux-2.6.19/drivers/mfd/Makefile
14 ===================================================================
15 --- linux-2.6.19.orig/drivers/mfd/Makefile
16 +++ linux-2.6.19/drivers/mfd/Makefile
17 @@ -10,3 +10,6 @@ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-
18 ifeq ($(CONFIG_SA1100_ASSABET),y)
19 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
20 endif
22 +obj-$(CONFIG_TOUCHSCREEN_UCB1400) += mcp-ac97.o ucb1x00-core.o ucb1x00-ts.o
24 Index: linux-2.6.19/drivers/mfd/mcp-core.c
25 ===================================================================
26 --- linux-2.6.19.orig/drivers/mfd/mcp-core.c
27 +++ linux-2.6.19/drivers/mfd/mcp-core.c
28 @@ -18,7 +18,6 @@
29 #include <linux/slab.h>
30 #include <linux/string.h>
32 -#include <asm/dma.h>
33 #include <asm/system.h>
35 #include "mcp.h"
36 @@ -208,6 +207,7 @@ struct mcp *mcp_host_alloc(struct device
37 mcp->attached_device.bus = &mcp_bus_type;
38 mcp->attached_device.dma_mask = parent->dma_mask;
39 mcp->attached_device.release = mcp_release;
40 + mcp->dev = &mcp->attached_device;
42 return mcp;
44 Index: linux-2.6.19/drivers/mfd/mcp-sa11x0.c
45 ===================================================================
46 --- linux-2.6.19.orig/drivers/mfd/mcp-sa11x0.c
47 +++ linux-2.6.19/drivers/mfd/mcp-sa11x0.c
48 @@ -31,8 +31,12 @@
49 #include "mcp.h"
51 struct mcp_sa11x0 {
52 - u32 mccr0;
53 - u32 mccr1;
54 + u32 mccr0;
55 + u32 mccr1;
56 + dma_device_t dma_audio_rd;
57 + dma_device_t dma_audio_wr;
58 + dma_device_t dma_telco_rd;
59 + dma_device_t dma_telco_wr;
62 #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
63 @@ -159,10 +163,10 @@ static int mcp_sa11x0_probe(struct platf
64 mcp->owner = THIS_MODULE;
65 mcp->ops = &mcp_sa11x0;
66 mcp->sclk_rate = data->sclk_rate;
67 - mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
68 - mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
69 - mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
70 - mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
71 + priv(mcp)->dma_audio_rd = DMA_Ser4MCP0Rd;
72 + priv(mcp)->dma_audio_wr = DMA_Ser4MCP0Wr;
73 + priv(mcp)->dma_telco_rd = DMA_Ser4MCP1Rd;
74 + priv(mcp)->dma_telco_wr = DMA_Ser4MCP1Wr;
76 platform_set_drvdata(pdev, mcp);
78 Index: linux-2.6.19/drivers/mfd/mcp.h
79 ===================================================================
80 --- linux-2.6.19.orig/drivers/mfd/mcp.h
81 +++ linux-2.6.19/drivers/mfd/mcp.h
82 @@ -19,11 +19,8 @@ struct mcp {
83 int use_count;
84 unsigned int sclk_rate;
85 unsigned int rw_timeout;
86 - dma_device_t dma_audio_rd;
87 - dma_device_t dma_audio_wr;
88 - dma_device_t dma_telco_rd;
89 - dma_device_t dma_telco_wr;
90 struct device attached_device;
91 + struct device *dev;
94 struct mcp_ops {
95 Index: linux-2.6.19/drivers/mfd/ucb1x00-assabet.c
96 ===================================================================
97 --- linux-2.6.19.orig/drivers/mfd/ucb1x00-assabet.c
98 +++ linux-2.6.19/drivers/mfd/ucb1x00-assabet.c
99 @@ -15,8 +15,6 @@
100 #include <linux/proc_fs.h>
101 #include <linux/device.h>
103 -#include <asm/dma.h>
105 #include "ucb1x00.h"
107 #define UCB1X00_ATTR(name,input)\
108 Index: linux-2.6.19/drivers/mfd/ucb1x00-core.c
109 ===================================================================
110 --- linux-2.6.19.orig/drivers/mfd/ucb1x00-core.c
111 +++ linux-2.6.19/drivers/mfd/ucb1x00-core.c
112 @@ -22,14 +22,18 @@
113 #include <linux/init.h>
114 #include <linux/errno.h>
115 #include <linux/interrupt.h>
116 +#include <linux/kthread.h>
117 #include <linux/device.h>
118 #include <linux/mutex.h>
120 -#include <asm/dma.h>
121 -#include <asm/hardware.h>
123 #include "ucb1x00.h"
125 +#ifdef CONFIG_UCB1400
126 +#define UCB_IS_1400(id) ((id) == UCB_ID_1400)
127 +#else
128 +#define UCB_IS_1400(id) (0)
129 +#endif
131 static DEFINE_MUTEX(ucb1x00_mutex);
132 static LIST_HEAD(ucb1x00_drivers);
133 static LIST_HEAD(ucb1x00_devices);
134 @@ -57,9 +61,9 @@ void ucb1x00_io_set_dir(struct ucb1x00 *
135 spin_lock_irqsave(&ucb->io_lock, flags);
136 ucb->io_dir |= out;
137 ucb->io_dir &= ~in;
138 + spin_unlock_irqrestore(&ucb->io_lock, flags);
140 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
141 - spin_unlock_irqrestore(&ucb->io_lock, flags);
145 @@ -85,9 +89,9 @@ void ucb1x00_io_write(struct ucb1x00 *uc
146 spin_lock_irqsave(&ucb->io_lock, flags);
147 ucb->io_out |= set;
148 ucb->io_out &= ~clear;
149 + spin_unlock_irqrestore(&ucb->io_lock, flags);
151 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
152 - spin_unlock_irqrestore(&ucb->io_lock, flags);
156 @@ -177,7 +181,7 @@ unsigned int ucb1x00_adc_read(struct ucb
157 schedule_timeout(1);
160 - return UCB_ADC_DAT(val);
161 + return UCB_IS_1400(ucb->id) ? (val & 0x3ff) : ((val & 0x7fe0) >> 5);
165 @@ -222,6 +226,47 @@ static irqreturn_t ucb1x00_irq(int irqnr
166 return IRQ_HANDLED;
170 + * A restriction with interrupts exists when using the ucb1400, as
171 + * the codec read/write routines may sleep while waiting for codec
172 + * access completion and uses semaphores for access control to the
173 + * AC97 bus. A complete codec read cycle could take anywhere from
174 + * 60 to 100uSec so we *definitely* don't want to spin inside the
175 + * interrupt handler waiting for codec access. So, we handle the
176 + * interrupt by scheduling a RT kernel thread to run in process
177 + * context instead of interrupt context.
178 + */
179 +static int ucb1x00_thread(void *_ucb)
181 + struct task_struct *tsk = current;
182 + struct ucb1x00 *ucb = _ucb;
184 + tsk->policy = SCHED_FIFO;
185 + tsk->rt_priority = 1;
187 + while (!kthread_should_stop()) {
188 + wait_for_completion_interruptible(&ucb->irq_wait);
189 + if (try_to_freeze())
190 + continue;
191 + ucb1x00_irq(ucb->irq, ucb, NULL);
192 + enable_irq(ucb->irq);
195 + ucb->irq_task = NULL;
196 + return 0;
199 +static irqreturn_t ucb1x00_threaded_irq(int irqnr, void *devid, struct pt_regs *regs)
201 + struct ucb1x00 *ucb = devid;
202 + if (irqnr == ucb->irq) {
203 + disable_irq(ucb->irq);
204 + complete(&ucb->irq_wait);
205 + return IRQ_HANDLED;
207 + return IRQ_NONE;
211 * ucb1x00_hook_irq - hook a UCB1x00 interrupt
212 * @ucb: UCB1x00 structure describing chip
213 @@ -275,18 +320,22 @@ void ucb1x00_enable_irq(struct ucb1x00 *
215 if (idx < 16) {
216 spin_lock_irqsave(&ucb->lock, flags);
218 - ucb1x00_enable(ucb);
219 - if (edges & UCB_RISING) {
220 + if (edges & UCB_RISING)
221 ucb->irq_ris_enbl |= 1 << idx;
222 - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
224 - if (edges & UCB_FALLING) {
225 + if (edges & UCB_FALLING)
226 ucb->irq_fal_enbl |= 1 << idx;
227 - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
229 - ucb1x00_disable(ucb);
230 spin_unlock_irqrestore(&ucb->lock, flags);
232 + ucb1x00_enable(ucb);
234 + /* This prevents spurious interrupts on the UCB1400 */
235 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
236 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
238 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
239 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
241 + ucb1x00_disable(ucb);
245 @@ -304,18 +353,16 @@ void ucb1x00_disable_irq(struct ucb1x00
247 if (idx < 16) {
248 spin_lock_irqsave(&ucb->lock, flags);
250 - ucb1x00_enable(ucb);
251 - if (edges & UCB_RISING) {
252 + if (edges & UCB_RISING)
253 ucb->irq_ris_enbl &= ~(1 << idx);
254 - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
256 - if (edges & UCB_FALLING) {
257 + if (edges & UCB_FALLING)
258 ucb->irq_fal_enbl &= ~(1 << idx);
259 - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
261 - ucb1x00_disable(ucb);
262 spin_unlock_irqrestore(&ucb->lock, flags);
264 + ucb1x00_enable(ucb);
265 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
266 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
267 + ucb1x00_disable(ucb);
271 @@ -348,16 +395,17 @@ int ucb1x00_free_irq(struct ucb1x00 *ucb
272 ucb->irq_ris_enbl &= ~(1 << idx);
273 ucb->irq_fal_enbl &= ~(1 << idx);
275 - ucb1x00_enable(ucb);
276 - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
277 - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
278 - ucb1x00_disable(ucb);
280 irq->fn = NULL;
281 irq->devid = NULL;
282 ret = 0;
284 spin_unlock_irq(&ucb->lock);
286 + ucb1x00_enable(ucb);
287 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
288 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
289 + ucb1x00_disable(ucb);
291 return ret;
293 bad:
294 @@ -479,7 +527,7 @@ static int ucb1x00_probe(struct mcp *mcp
295 mcp_enable(mcp);
296 id = mcp_reg_read(mcp, UCB_ID);
298 - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
299 + if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143 && !UCB_IS_1400(id)) {
300 printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
301 goto err_disable;
303 @@ -492,12 +540,13 @@ static int ucb1x00_probe(struct mcp *mcp
304 memset(ucb, 0, sizeof(struct ucb1x00));
306 ucb->cdev.class = &ucb1x00_class;
307 - ucb->cdev.dev = &mcp->attached_device;
308 + ucb->cdev.dev = mcp->dev;
309 strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
311 spin_lock_init(&ucb->lock);
312 spin_lock_init(&ucb->io_lock);
313 sema_init(&ucb->adc_sem, 1);
314 + init_completion(&ucb->irq_wait);
316 ucb->id = id;
317 ucb->mcp = mcp;
318 @@ -508,13 +557,22 @@ static int ucb1x00_probe(struct mcp *mcp
319 goto err_free;
322 - ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
323 - "UCB1x00", ucb);
324 + ret = request_irq(ucb->irq,
325 + UCB_IS_1400(id) ? ucb1x00_threaded_irq : ucb1x00_irq,
326 + IRQF_TRIGGER_RISING, "UCB1x00", ucb);
327 if (ret) {
328 printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
329 ucb->irq, ret);
330 goto err_free;
332 + if (UCB_IS_1400(id)) {
333 + ucb->irq_task = kthread_run(ucb1x00_thread, ucb, "kUCB1x00d");
334 + if (IS_ERR(ucb->irq_task)) {
335 + ret = PTR_ERR(ucb->irq_task);
336 + ucb->irq_task = NULL;
337 + goto err_irq;
341 mcp_set_drvdata(mcp, ucb);
343 @@ -532,6 +590,8 @@ static int ucb1x00_probe(struct mcp *mcp
344 goto out;
346 err_irq:
347 + if (UCB_IS_1400(id) && ucb->irq_task)
348 + kthread_stop(ucb->irq_task);
349 free_irq(ucb->irq, ucb);
350 err_free:
351 kfree(ucb);
352 @@ -554,6 +614,8 @@ static void ucb1x00_remove(struct mcp *m
354 mutex_unlock(&ucb1x00_mutex);
356 + if (UCB_IS_1400(ucb->id) && ucb->irq_task)
357 + kthread_stop(ucb->irq_task);
358 free_irq(ucb->irq, ucb);
359 class_device_unregister(&ucb->cdev);
361 Index: linux-2.6.19/drivers/mfd/ucb1x00-ts.c
362 ===================================================================
363 --- linux-2.6.19.orig/drivers/mfd/ucb1x00-ts.c
364 +++ linux-2.6.19/drivers/mfd/ucb1x00-ts.c
365 @@ -32,10 +32,8 @@
366 #include <linux/slab.h>
367 #include <linux/kthread.h>
369 -#include <asm/dma.h>
370 -#include <asm/semaphore.h>
371 -#include <asm/arch/collie.h>
372 #include <asm/mach-types.h>
373 +#include <asm/arch-sa1100/collie.h>
375 #include "ucb1x00.h"
377 @@ -44,7 +42,7 @@ struct ucb1x00_ts {
378 struct input_dev *idev;
379 struct ucb1x00 *ucb;
381 - wait_queue_head_t irq_wait;
382 + struct completion irq_wait;
383 struct task_struct *rtask;
384 u16 x_res;
385 u16 y_res;
386 @@ -207,7 +205,6 @@ static int ucb1x00_thread(void *_ts)
388 struct ucb1x00_ts *ts = _ts;
389 struct task_struct *tsk = current;
390 - DECLARE_WAITQUEUE(wait, tsk);
391 int valid;
394 @@ -219,10 +216,8 @@ static int ucb1x00_thread(void *_ts)
396 valid = 0;
398 - add_wait_queue(&ts->irq_wait, &wait);
399 while (!kthread_should_stop()) {
400 unsigned int x, y, p;
401 - signed long timeout;
403 ts->restart = 0;
405 @@ -244,8 +239,6 @@ static int ucb1x00_thread(void *_ts)
408 if (ucb1x00_ts_pen_down(ts)) {
409 - set_task_state(tsk, TASK_INTERRUPTIBLE);
411 ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
412 ucb1x00_disable(ts->ucb);
414 @@ -258,7 +251,15 @@ static int ucb1x00_thread(void *_ts)
415 valid = 0;
418 - timeout = MAX_SCHEDULE_TIMEOUT;
419 + /*
420 + * Since ucb1x00_enable_irq() might sleep due
421 + * to the way the UCB1400 regs are accessed, we
422 + * can't use set_task_state() before that call,
423 + * and not changing state before enabling the
424 + * interrupt is racy. A completion handler avoids
425 + * the issue.
426 + */
427 + wait_for_completion_interruptible(&ts->irq_wait);
428 } else {
429 ucb1x00_disable(ts->ucb);
431 @@ -273,16 +274,12 @@ static int ucb1x00_thread(void *_ts)
434 set_task_state(tsk, TASK_INTERRUPTIBLE);
435 - timeout = HZ / 100;
436 + schedule_timeout(HZ/100);
439 try_to_freeze();
441 - schedule_timeout(timeout);
444 - remove_wait_queue(&ts->irq_wait, &wait);
446 ts->rtask = NULL;
447 return 0;
449 @@ -296,7 +293,7 @@ static void ucb1x00_ts_irq(int idx, void
450 struct ucb1x00_ts *ts = id;
452 ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
453 - wake_up(&ts->irq_wait);
454 + complete(&ts->irq_wait);
457 static int ucb1x00_ts_open(struct input_dev *idev)
458 @@ -306,7 +303,7 @@ static int ucb1x00_ts_open(struct input_
460 BUG_ON(ts->rtask);
462 - init_waitqueue_head(&ts->irq_wait);
463 + init_completion(&ts->irq_wait);
464 ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
465 if (ret < 0)
466 goto out;
467 @@ -361,7 +358,7 @@ static int ucb1x00_ts_resume(struct ucb1
468 * after sleep.
470 ts->restart = 1;
471 - wake_up(&ts->irq_wait);
472 + complete(&ts->irq_wait);
474 return 0;
476 Index: linux-2.6.19/drivers/mfd/ucb1x00.h
477 ===================================================================
478 --- linux-2.6.19.orig/drivers/mfd/ucb1x00.h
479 +++ linux-2.6.19/drivers/mfd/ucb1x00.h
480 @@ -94,6 +94,7 @@
481 #define UCB_ID 0x0c
482 #define UCB_ID_1200 0x1004
483 #define UCB_ID_1300 0x1005
484 +#define UCB_ID_1400 0x4304
485 #define UCB_ID_TC35143 0x9712
487 #define UCB_MODE 0x0d
488 @@ -111,6 +112,8 @@ struct ucb1x00 {
489 spinlock_t lock;
490 struct mcp *mcp;
491 unsigned int irq;
492 + struct task_struct *irq_task;
493 + struct completion irq_wait;
494 struct semaphore adc_sem;
495 spinlock_t io_lock;
496 u16 id;
497 @@ -123,6 +126,7 @@ struct ucb1x00 {
498 struct class_device cdev;
499 struct list_head node;
500 struct list_head devs;
504 struct ucb1x00_driver;
505 Index: linux-2.6.19/drivers/mfd/mcp-ac97.c
506 ===================================================================
507 --- /dev/null
508 +++ linux-2.6.19/drivers/mfd/mcp-ac97.c
509 @@ -0,0 +1,153 @@
511 + * linux/drivers/misc/mcp-ac97.c
513 + * Author: Nicolas Pitre
514 + * Created: Jan 14, 2005
515 + * Copyright: (C) MontaVista Software Inc.
517 + * This program is free software; you can redistribute it and/or
518 + * modify it under the terms of the GNU General Public License
519 + * version 2 as published by the Free Software Foundation.
521 + * This module provides the minimum replacement for mcp-core.c allowing for
522 + * the UCB1400 chip to be driven by the ucb1x00 driver over an AC97 link.
523 + */
525 +#include <linux/module.h>
526 +#include <linux/init.h>
527 +#include <linux/errno.h>
528 +#include <linux/device.h>
530 +#include <sound/driver.h>
531 +#include <sound/core.h>
532 +#include <sound/ac97_codec.h>
534 +#include "mcp.h"
536 +/* ucb1x00 SIB register to ucb1400 AC-link register mapping */
538 +static const unsigned char regmap[] = {
539 + 0x5a, /* UCB_IO_DATA */
540 + 0X5C, /* UCB_IO_DIR */
541 + 0X5E, /* UCB_IE_RIS */
542 + 0x60, /* UCB_IE_FAL */
543 + 0x62, /* UCB_IE_STATUS */
544 + 0, /* UCB_TC_A */
545 + 0, /* UCB_TC_B */
546 + 0, /* UCB_AC_A */
547 + 0, /* UCB_AC_B */
548 + 0x64, /* UCB_TS_CR */
549 + 0x66, /* UCB_ADC_CR */
550 + 0x68, /* UCB_ADC_DATA */
551 + 0x7e, /* UCB_ID */
552 + 0, /* UCB_MODE */
555 +unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
557 + ac97_t *ac97 = to_ac97_t(mcp->dev);
558 + if (reg < ARRAY_SIZE(regmap)) {
559 + reg = regmap[reg];
560 + if (reg)
561 + return ac97->bus->ops->read(ac97, reg);
563 + return -1;
565 +EXPORT_SYMBOL(mcp_reg_read);
567 +void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
569 + ac97_t *ac97 = to_ac97_t(mcp->dev);
570 + if (reg < ARRAY_SIZE(regmap)) {
571 + reg = regmap[reg];
572 + if (reg)
573 + ac97->bus->ops->write(ac97, reg, val);
576 +EXPORT_SYMBOL(mcp_reg_write);
578 +void mcp_enable(struct mcp *mcp)
581 +EXPORT_SYMBOL(mcp_enable);
583 +void mcp_disable(struct mcp *mcp)
586 +EXPORT_SYMBOL(mcp_disable);
588 +#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
590 +static int mcp_probe(struct device *dev)
592 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
593 + struct mcp *mcp;
594 + int ret;
596 + ret = -ENOMEM;
597 + mcp = kmalloc(sizeof(*mcp), GFP_KERNEL);
598 + if (mcp) {
599 + memset(mcp, 0, sizeof(*mcp));
600 + mcp->owner = THIS_MODULE;
601 + mcp->dev = dev;
602 + ret = drv->probe(mcp);
603 + if (ret)
604 + kfree(mcp);
606 + if (!ret)
607 + dev_set_drvdata(dev, mcp);
608 + return ret;
611 +static int mcp_remove(struct device *dev)
613 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
614 + struct mcp *mcp = dev_get_drvdata(dev);
616 + drv->remove(mcp);
617 + dev_set_drvdata(dev, NULL);
618 + kfree(mcp);
619 + return 0;
622 +static int mcp_suspend(struct device *dev, pm_message_t state)
624 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
625 + struct mcp *mcp = dev_get_drvdata(dev);
626 + int ret = 0;
628 + if (drv->suspend)
629 + ret = drv->suspend(mcp, state);
630 + return ret;
633 +static int mcp_resume(struct device *dev)
635 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
636 + struct mcp *mcp = dev_get_drvdata(dev);
637 + int ret = 0;
639 + if (drv->resume)
640 + ret = drv->resume(mcp);
641 + return ret;
644 +int mcp_driver_register(struct mcp_driver *mcpdrv)
646 + mcpdrv->drv.owner = THIS_MODULE;
647 + mcpdrv->drv.bus = &ac97_bus_type;
648 + mcpdrv->drv.probe = mcp_probe;
649 + mcpdrv->drv.remove = mcp_remove;
650 + mcpdrv->drv.suspend = mcp_suspend;
651 + mcpdrv->drv.resume = mcp_resume;
652 + return driver_register(&mcpdrv->drv);
654 +EXPORT_SYMBOL(mcp_driver_register);
656 +void mcp_driver_unregister(struct mcp_driver *mcpdrv)
658 + driver_unregister(&mcpdrv->drv);
660 +EXPORT_SYMBOL(mcp_driver_unregister);
662 +MODULE_LICENSE("GPL");
663 Index: linux-2.6.19/drivers/input/touchscreen/Kconfig
664 ===================================================================
665 --- linux-2.6.19.orig/drivers/input/touchscreen/Kconfig
666 +++ linux-2.6.19/drivers/input/touchscreen/Kconfig
667 @@ -24,6 +24,25 @@ config TOUCHSCREEN_ADS7846
668 To compile this driver as a module, choose M here: the
669 module will be called ads7846.
671 +config UCB1400
672 + bool
674 +config TOUCHSCREEN_UCB1400
675 + tristate "UCB1400 Touchscreen support"
676 + depends on ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_GUMSTIX
677 + select SND_AC97_BUS
678 + select UCB1400
679 + help
680 + Say Y here if you have a touchscreen connected to a UCB1400 ADC chip
681 + on the AC97 bus of a PXA255/PXA270 host.
683 + If unsure, say N.
685 + To compile this driver as a module, choose M here: the
686 + module will be called ucb1x00-ts. It will also build the modules
687 + ucb1x00-core and mcp-ac97 which provide the compatibility layers
688 + down to the AC97 bus.
690 config TOUCHSCREEN_BITSY
691 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
692 depends on SA1100_BITSY
693 Index: linux-2.6.19/drivers/input/Kconfig
694 ===================================================================
695 --- linux-2.6.19.orig/drivers/input/Kconfig
696 +++ linux-2.6.19/drivers/input/Kconfig
697 @@ -101,7 +101,7 @@ config INPUT_JOYDEV
698 module will be called joydev.
700 config INPUT_TSDEV
701 - tristate "Touchscreen interface"
702 + tristate "Compaq touchscreen interface"
703 ---help---
704 Say Y here if you have an application that only can understand the
705 Compaq touchscreen protocol for absolute pointer data. This is