summaryrefslogtreecommitdiff
path: root/packages/linux/linux-ezx-2.6.21
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2007-05-01 21:14:47 +0000
committerKoen Kooi <koen@openembedded.org>2007-05-01 21:14:47 +0000
commit23a69763708f6c95528a47ac5a4ba36c43d5e106 (patch)
tree01eb3d1b193f2d4e334403e8bdad8b69a134333e /packages/linux/linux-ezx-2.6.21
parentecf440c620921904d155cd66d4ac1dd630e10e99 (diff)
linux-ezx 2.6.21: update patches to r1995, gives you working ts, keys and some powermanagement
Diffstat (limited to 'packages/linux/linux-ezx-2.6.21')
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-core.patch54
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-emu.patch51
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-kbd.patch139
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-pcap.patch34
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-pm.patch58
-rw-r--r--packages/linux/linux-ezx-2.6.21/ezx-ts.patch399
-rw-r--r--packages/linux/linux-ezx-2.6.21/mux-linux-2.6.20.7-fix.patch224
-rw-r--r--packages/linux/linux-ezx-2.6.21/mux-linux-2.6.21-fix.patch11
-rw-r--r--packages/linux/linux-ezx-2.6.21/pcap_ts.c.patch237
-rw-r--r--packages/linux/linux-ezx-2.6.21/pxa-kbd.patch463
-rw-r--r--packages/linux/linux-ezx-2.6.21/touchscreen-fix-r0.patch21
-rw-r--r--packages/linux/linux-ezx-2.6.21/wyrm-ts.diff124
12 files changed, 1752 insertions, 63 deletions
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-core.patch b/packages/linux/linux-ezx-2.6.21/ezx-core.patch
index 81be0ef159..8423db6e00 100644
--- a/packages/linux/linux-ezx-2.6.21/ezx-core.patch
+++ b/packages/linux/linux-ezx-2.6.21/ezx-core.patch
@@ -1,7 +1,7 @@
Index: linux-2.6.21/arch/arm/boot/compressed/head-xscale.S
===================================================================
---- linux-2.6.21.orig/arch/arm/boot/compressed/head-xscale.S 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/arch/arm/boot/compressed/head-xscale.S 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/boot/compressed/head-xscale.S 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/arch/arm/boot/compressed/head-xscale.S 2007-05-01 00:21:34.000000000 -0300
@@ -53,3 +53,6 @@
str r1, [r0, #0x18]
#endif
@@ -11,8 +11,8 @@ Index: linux-2.6.21/arch/arm/boot/compressed/head-xscale.S
+#endif
Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig
===================================================================
---- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/arch/arm/mach-pxa/Kconfig 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Kconfig 2007-05-01 01:39:12.000000000 -0300
@@ -37,6 +37,10 @@
bool "Keith und Koep Trizeps4 DIMM-Module"
select PXA27x
@@ -60,8 +60,8 @@ Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig
endif
Index: linux-2.6.21/arch/arm/mach-pxa/Makefile
===================================================================
---- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-05-01 01:39:13.000000000 -0300
@@ -18,6 +18,7 @@
obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
@@ -73,8 +73,8 @@ Index: linux-2.6.21/arch/arm/mach-pxa/Makefile
Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-04-26 20:27:42.000000000 -0300
-@@ -0,0 +1,379 @@
++++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-05-01 01:39:14.000000000 -0300
+@@ -0,0 +1,378 @@
+/*
+ * linux/arch/arm/mach-ezx/a780.c
+ *
@@ -97,7 +97,6 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
+#include <linux/bitops.h>
+#include <linux/apm_bios.h>
+#include <linux/platform_device.h>
-+#include <linux/input.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
@@ -379,7 +378,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
+
+static void __init a780_init(void)
+{
-+//FIXME CKEN = CKEN9_OSTIMER | CKEN22_MEMC | CKEN5_STUART;
++ CKEN = CKEN9_OSTIMER | CKEN22_MEMC;
+
+ ezx_ssp_set_machinfo(&ezx_ssp_machinfo);
+
@@ -457,7 +456,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
Index: linux-2.6.21/include/asm-arm/arch-pxa/ezx.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.21/include/asm-arm/arch-pxa/ezx.h 2007-04-26 20:27:42.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/ezx.h 2007-05-01 00:21:34.000000000 -0300
@@ -0,0 +1,225 @@
+/*
+ * linux/include/asm-arm/arch-pxa/ezx.h
@@ -686,8 +685,8 @@ Index: linux-2.6.21/include/asm-arm/arch-pxa/ezx.h
+
Index: linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h
===================================================================
---- linux-2.6.21.orig/include/asm-arm/arch-pxa/pxa-regs.h 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h 2007-04-26 20:28:45.000000000 -0300
+--- linux-2.6.21.orig/include/asm-arm/arch-pxa/pxa-regs.h 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h 2007-05-01 01:39:11.000000000 -0300
@@ -849,6 +849,8 @@
#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */
#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */
@@ -803,8 +802,8 @@ Index: linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h
#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
Index: linux-2.6.21/arch/arm/boot/compressed/head.S
===================================================================
---- linux-2.6.21.orig/arch/arm/boot/compressed/head.S 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/arch/arm/boot/compressed/head.S 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/boot/compressed/head.S 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/arch/arm/boot/compressed/head.S 2007-05-01 00:21:34.000000000 -0300
@@ -117,6 +117,9 @@
mov r0, r0
.endr
@@ -817,8 +816,8 @@ Index: linux-2.6.21/arch/arm/boot/compressed/head.S
.word start @ absolute load/run zImage address
Index: linux-2.6.21/include/asm-arm/arch-pxa/uncompress.h
===================================================================
---- linux-2.6.21.orig/include/asm-arm/arch-pxa/uncompress.h 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/include/asm-arm/arch-pxa/uncompress.h 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/include/asm-arm/arch-pxa/uncompress.h 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/uncompress.h 2007-05-01 00:21:34.000000000 -0300
@@ -14,14 +14,14 @@
#define STUART ((volatile unsigned long *)0x40700000)
#define HWUART ((volatile unsigned long *)0x41600000)
@@ -840,7 +839,7 @@ Index: linux-2.6.21/include/asm-arm/arch-pxa/uncompress.h
Index: linux-2.6.21/arch/arm/mach-pxa/ezx_ssp.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.21/arch/arm/mach-pxa/ezx_ssp.c 2007-04-26 20:27:42.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/ezx_ssp.c 2007-05-01 00:21:34.000000000 -0300
@@ -0,0 +1,126 @@
+/*
+ * SSP control code for Motorola EZX phones
@@ -971,7 +970,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_ssp.c
Index: linux-2.6.21/arch/arm/mach-pxa/ezx.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.21/arch/arm/mach-pxa/ezx.h 2007-04-26 20:27:42.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/ezx.h 2007-05-01 00:21:34.000000000 -0300
@@ -0,0 +1,9 @@
+#include <asm/arch/ezx.h>
+
@@ -985,8 +984,8 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx.h
Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c 2007-04-26 20:27:42.000000000 -0300
-@@ -0,0 +1,112 @@
++++ linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c 2007-05-01 01:51:20.000000000 -0300
+@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-ezx/a780.c
+ *
@@ -1028,8 +1027,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
+ }
+}
+
-+#ifdef CONFIG_PXA_E2
-+static void sumatra_backlight_power(int on)
++static void ezx_backlight_power(int on)
+{
+ if (on) {
+ pxa_gpio_mode(GPIO16_PWM0_MD);
@@ -1045,6 +1043,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
+ }
+}
+
++#ifdef CONFIG_PXA_E2
+static struct pxafb_mode_info mode_ezx = {
+ .pixclock = 192308,
+ .xres = 240,
@@ -1064,7 +1063,7 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
+ .num_modes = 1,
+ .lccr0 = 0x022008B8,
+ .lccr3 = 0xC130FF13,
-+ .pxafb_backlight_power = sumatra_backlight_power,
++ .pxafb_backlight_power = ezx_backlight_power,
+ .pxafb_lcd_power = &pxafb_lcd_power,
+};
+
@@ -1088,7 +1087,8 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
+ .num_modes = 1,
+ .lccr0 = 0x002008F8,
+ .lccr3 = 0x0430FF09,
-+ .pxafb_lcd_power= &pxafb_lcd_power,
++ .pxafb_backlight_power = ezx_backlight_power,
++ .pxafb_lcd_power = &pxafb_lcd_power,
+};
+#endif
+
@@ -1101,8 +1101,8 @@ Index: linux-2.6.21/arch/arm/mach-pxa/ezx_lcd.c
+arch_initcall(__ezx_lcd_init);
Index: linux-2.6.21/arch/arm/mm/init.c
===================================================================
---- linux-2.6.21.orig/arch/arm/mm/init.c 2007-04-26 00:08:32.000000000 -0300
-+++ linux-2.6.21/arch/arm/mm/init.c 2007-04-26 20:27:42.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mm/init.c 2007-05-01 00:21:30.000000000 -0300
++++ linux-2.6.21/arch/arm/mm/init.c 2007-05-01 00:21:34.000000000 -0300
@@ -241,6 +241,10 @@
*/
reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-emu.patch b/packages/linux/linux-ezx-2.6.21/ezx-emu.patch
index cb3bfc53e7..95fdd96fc1 100644
--- a/packages/linux/linux-ezx-2.6.21/ezx-emu.patch
+++ b/packages/linux/linux-ezx-2.6.21/ezx-emu.patch
@@ -1,8 +1,8 @@
-Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx-emu.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c 2007-04-23 01:14:40.000000000 -0300
-@@ -0,0 +1,200 @@
++++ linux-2.6.21/arch/arm/mach-pxa/ezx-emu.c 2007-05-01 03:58:42.000000000 -0300
+@@ -0,0 +1,215 @@
+/*
+ * EMU Driver for Motorola EZX phones
+ *
@@ -135,7 +135,10 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c
+
+ pxa_set_udc_info(&ezx_udc_info);
+
-+ emu_switch_to_default();
++ if(ezx_pcap_read_bit(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V))
++ emu_switch_to_default();
++ else
++ emu_switch_to_nothing();
+
+ return 0;
+}
@@ -148,6 +151,18 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c
+ return 0;
+}
+
++static int ezx_emu_suspend(struct platform_device *dev)
++{
++ emu_switch_to_nothing();
++ return 0;
++}
++
++static int ezx_emu_resume(struct platform_device *dev)
++{
++ emu_switch_to_default();
++ return 0;
++}
++
+/* USB Device Controller */
+static int udc_connected_status;
+static void ezx_udc_command(int cmd)
@@ -179,8 +194,8 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c
+static struct platform_driver ezxemu_driver = {
+ .probe = ezx_emu_probe,
+ .remove = ezx_emu_remove,
-+ //.suspend = ezx_emu_suspend,
-+ //.resume = ezx_emu_resume,
++ .suspend = ezx_emu_suspend,
++ .resume = ezx_emu_resume,
+ .driver = {
+ .name = "ezx-emu",
+ .owner = THIS_MODULE,
@@ -203,10 +218,10 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-emu.c
+MODULE_DESCRIPTION("Motorola Enchanced Mini Usb driver");
+MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.20.7/arch/arm/mach-pxa/Kconfig
+Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig
===================================================================
---- linux-2.6.20.7.orig/arch/arm/mach-pxa/Kconfig 2007-04-22 15:02:54.000000000 -0300
-+++ linux-2.6.20.7/arch/arm/mach-pxa/Kconfig 2007-04-22 15:23:10.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig 2007-05-01 01:39:12.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Kconfig 2007-05-01 02:07:23.000000000 -0300
@@ -94,6 +94,27 @@
endchoice
@@ -235,10 +250,10 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/Kconfig
endif
endmenu
-Index: linux-2.6.20.7/arch/arm/mach-pxa/Makefile
+Index: linux-2.6.21/arch/arm/mach-pxa/Makefile
===================================================================
---- linux-2.6.20.7.orig/arch/arm/mach-pxa/Makefile 2007-04-22 15:23:01.000000000 -0300
-+++ linux-2.6.20.7/arch/arm/mach-pxa/Makefile 2007-04-22 15:23:10.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-05-01 02:07:23.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-05-01 04:10:48.000000000 -0300
@@ -19,6 +19,7 @@
obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
@@ -247,11 +262,11 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/Makefile
# Support for blinky lights
led-y := leds.o
-Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
===================================================================
---- linux-2.6.20.7.orig/arch/arm/mach-pxa/ezx.c 2007-04-22 15:22:55.000000000 -0300
-+++ linux-2.6.20.7/arch/arm/mach-pxa/ezx.c 2007-04-23 01:02:05.000000000 -0300
-@@ -36,6 +36,7 @@
+--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx.c 2007-05-01 02:07:23.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-05-01 02:07:23.000000000 -0300
+@@ -35,6 +35,7 @@
#include <asm/arch/ohci.h>
#include <asm/arch/pxa-regs.h>
@@ -259,7 +274,7 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
#include "ezx.h"
#include "generic.h"
#include <linux/tty.h>
-@@ -92,6 +93,30 @@
+@@ -91,6 +92,30 @@
.resource = ezxpcap_resources,
};
@@ -290,7 +305,7 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
/* OHCI Controller */
static int ezx_ohci_init(struct device *dev)
-@@ -317,6 +342,7 @@
+@@ -316,6 +341,7 @@
&ezxssp_device,
&ezxpcap_device,
&ezxbp_device,
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-kbd.patch b/packages/linux/linux-ezx-2.6.21/ezx-kbd.patch
new file mode 100644
index 0000000000..7c020a2d96
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/ezx-kbd.patch
@@ -0,0 +1,139 @@
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx-kbd.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.21/arch/arm/mach-pxa/ezx-kbd.c 2007-04-30 20:33:19.000000000 -0300
+@@ -0,0 +1,109 @@
++#include <linux/input.h>
++#include <asm/arch/kbd.h>
++#include <asm/arch/pxa-regs.h>
++
++extern void __init pxa_set_kbd_info(struct pxakbd_platform_data *);
++
++#if defined(CONFIG_PXA_EZX_E680)
++static unsigned char ezx_keycode[] = {
++ /* row 0 */
++ KEY_UP, KEY_RIGHT, KEY_RESERVED, KEY_PHONE,
++ /* row 1 */
++ KEY_DOWN, KEY_LEFT, KEY_VOLUMEUP, KEY_VOLUMEDOWN,
++ /* row 2 */
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPENTER,
++};
++
++static unsigned char ezx_direct_keycode[] = {
++ KEY_CAMERA,
++ KEYPAD_RESERVED,
++ KEYPAD_RESERVED,
++ KEYPAD_HOME,
++ KEY_POWER,
++ KEYPAD_MENU,
++};
++#elif defined(CONFIG_PXA_EZX_A780)
++static unsigned char ezx_keycode[] = {
++ /* row 0 */
++ KEY_KPENTER, KEY_MENU, KEY_CANCEL, KEY_PAGEUP, KEY_UP,
++ /* row 1 */
++ KEY_KP1, KEY_KP2, KEY_KP3, KEY_ENTER, KEY_KPENTER, /*center joypad */
++ /* row 2 */
++ KEY_KP4, KEY_KP5, KEY_KP6, KEY_PAGEDOWN, KEY_PHONE,
++ /* row 3 */
++ KEY_KP7, KEY_KP8, KEY_KP9, KEY_PHONE, KEY_LEFT,
++ /* row 4 */
++ KEY_KPASTERISK, KEY_KP0, KEY_KPDOT, KEY_PAGEDOWN, KEY_DOWN,
++};
++static unsigned char ezx_direct_keycode[] = {
++ KEY_CAMERA,
++};
++#else
++#error "no EZX subarchitecture defined"
++#endif
++
++static int ezx_kbd_init(void)
++{
++#if defined(CONFIG_PXA_EZX_E680)
++ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */
++ pxa_gpio_mode(96 | GPIO_ALT_FN_1_IN); /* KP_DKIN<3>, GAME_A */
++ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */
++ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_DKIN<5>, GAME_B */
++ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */
++ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */
++ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */
++ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */
++ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */
++ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */
++ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */
++ pxa_gpio_mode(GPIO_TC_MM_EN);
++ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN);
++ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN);
++ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN);
++#elif defined(CONFIG_PXA_EZX_A780)
++ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, voice_rec */
++ pxa_gpio_mode(97 | GPIO_ALT_FN_3_IN); /* KP_MKIN<3> */
++ pxa_gpio_mode(98 | GPIO_ALT_FN_3_IN); /* KP_MKIN<4> */
++ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */
++ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */
++ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */
++ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */
++ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */
++ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */
++ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */
++ pxa_gpio_mode(107 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<4> */
++#endif
++ return 0;
++}
++
++static struct pxakbd_platform_data ezx_kbd_platform_data = {
++ .init = &ezx_kbd_init,
++ .scan_interval = HZ/40,
++ .matrix = {
++ .keycode = ezx_keycode,
++#if defined(CONFIG_PXA_EZX_E680)
++ .cols = 4,
++ .rows = 3,
++#elif defined(CONFIG_PXA_EZX_A780)
++ .cols = 5,
++ .rows = 5,
++#endif
++ },
++ .direct = {
++ .keycode = ezx_direct_keycode,
++#if defined(CONFIG_PXA_EZX_E680)
++ .num = 6,
++#elif defined(CONFIG_PXA_EZX_A780)
++ .num = 1,
++#endif
++ },
++};
++
++
++int __init __ezx_kbd_init (void)
++{
++ pxa_set_kbd_info(&ezx_kbd_platform_data);
++ return 0;
++}
++
++arch_initcall(__ezx_kbd_init);
+Index: linux-2.6.21/arch/arm/mach-pxa/Makefile
+===================================================================
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-04-30 20:09:21.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-04-30 20:09:34.000000000 -0300
+@@ -18,7 +18,7 @@
+ obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
+ obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
+ obj-$(CONFIG_MACH_TOSA) += tosa.o
+-obj-$(CONFIG_PXA_EZX) += ezx.o ezx_lcd.o ezx_ssp.o ezx-pcap.o ezx-mci.o
++obj-$(CONFIG_PXA_EZX) += ezx.o ezx_lcd.o ezx_ssp.o ezx-pcap.o ezx-mci.o ezx-kbd.o
+ obj-$(CONFIG_PXA_EZX_EMU) += ezx-emu.o
+
+ # Support for blinky lights
+Index: linux-2.6.21/drivers/input/keyboard/pxakbd.c
+===================================================================
+--- linux-2.6.21.orig/drivers/input/keyboard/pxakbd.c 2007-04-30 20:47:29.000000000 -0300
++++ linux-2.6.21/drivers/input/keyboard/pxakbd.c 2007-04-30 20:49:32.000000000 -0300
+@@ -213,6 +213,7 @@
+ if (!input_dev)
+ goto out_pxa;
+
++ spin_lock_init(&pxakbd->lock);
+ pxakbd->irq = platform_get_irq(pdev, 0);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r || pxakbd->irq == NO_IRQ) {
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-pcap.patch b/packages/linux/linux-ezx-2.6.21/ezx-pcap.patch
index 22c5d44f36..de64d722e9 100644
--- a/packages/linux/linux-ezx-2.6.21/ezx-pcap.patch
+++ b/packages/linux/linux-ezx-2.6.21/ezx-pcap.patch
@@ -1,7 +1,7 @@
-Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-pcap.c
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx-pcap.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.20.7/arch/arm/mach-pxa/ezx-pcap.c 2007-04-21 08:26:37.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/ezx-pcap.c 2007-05-01 14:00:50.000000000 -0300
@@ -0,0 +1,411 @@
+/* Driver for Motorola PCAP2 as present in EZX phones
+ *
@@ -414,10 +414,10 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx-pcap.c
+MODULE_AUTHOR("Harald Welte");
+MODULE_DESCRIPTION("SPI Driver for Motorola PCAP2");
+
-Index: linux-2.6.20.7/include/asm-arm/arch-pxa/ezx-pcap.h
+Index: linux-2.6.21/include/asm-arm/arch-pxa/ezx-pcap.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.20.7/include/asm-arm/arch-pxa/ezx-pcap.h 2007-04-21 08:26:37.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/ezx-pcap.h 2007-05-01 14:00:50.000000000 -0300
@@ -0,0 +1,665 @@
+/* (c) Copyright Motorola Beijing 2002 all rights reserved.
+
@@ -1084,10 +1084,10 @@ Index: linux-2.6.20.7/include/asm-arm/arch-pxa/ezx-pcap.h
+extern void ssp_pcap_screenlock_unlock(u32 data);
+
+#endif
-Index: linux-2.6.20.7/include/asm-arm/arch-pxa/irqs.h
+Index: linux-2.6.21/include/asm-arm/arch-pxa/irqs.h
===================================================================
---- linux-2.6.20.7.orig/include/asm-arm/arch-pxa/irqs.h 2007-04-21 08:26:32.000000000 -0300
-+++ linux-2.6.20.7/include/asm-arm/arch-pxa/irqs.h 2007-04-21 08:26:37.000000000 -0300
+--- linux-2.6.21.orig/include/asm-arm/arch-pxa/irqs.h 2007-05-01 14:00:24.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/irqs.h 2007-05-01 14:00:50.000000000 -0300
@@ -176,7 +176,8 @@
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
#elif defined(CONFIG_ARCH_LUBBOCK) || \
@@ -1115,10 +1115,10 @@ Index: linux-2.6.20.7/include/asm-arm/arch-pxa/irqs.h
+#define EZX_IRQ_ONOFF EZX_IRQ(7)
+#define EZX_IRQ_ONOFF2 EZX_IRQ(8)
+
-Index: linux-2.6.20.7/arch/arm/mach-pxa/Makefile
+Index: linux-2.6.21/arch/arm/mach-pxa/Makefile
===================================================================
---- linux-2.6.20.7.orig/arch/arm/mach-pxa/Makefile 2007-04-21 08:26:37.000000000 -0300
-+++ linux-2.6.20.7/arch/arm/mach-pxa/Makefile 2007-04-21 08:45:09.000000000 -0300
+--- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-05-01 14:00:48.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-05-01 14:00:50.000000000 -0300
@@ -18,7 +18,7 @@
obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
@@ -1128,11 +1128,11 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/Makefile
# Support for blinky lights
led-y := leds.o
-Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
===================================================================
---- linux-2.6.20.7.orig/arch/arm/mach-pxa/ezx.c 2007-04-21 08:26:37.000000000 -0300
-+++ linux-2.6.20.7/arch/arm/mach-pxa/ezx.c 2007-04-21 08:51:15.000000000 -0300
-@@ -73,6 +73,24 @@
+--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx.c 2007-05-01 14:00:48.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-05-01 14:00:50.000000000 -0300
+@@ -72,6 +72,24 @@
.clk_pcap = 1,
};
@@ -1157,7 +1157,7 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
/* OHCI Controller */
-@@ -236,7 +254,7 @@
+@@ -235,7 +253,7 @@
};
@@ -1166,7 +1166,7 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
[0] = {
.start = GPIO_BP_RDY,
.end = GPIO_BP_RDY,
-@@ -256,15 +274,15 @@
+@@ -255,15 +273,15 @@
#endif
};
@@ -1185,7 +1185,7 @@ Index: linux-2.6.20.7/arch/arm/mach-pxa/ezx.c
};
static void __init ezx_init_gpio_irq(void)
-@@ -297,7 +315,8 @@
+@@ -296,7 +314,8 @@
static struct platform_device *devices[] __initdata = {
&ezxssp_device,
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-pm.patch b/packages/linux/linux-ezx-2.6.21/ezx-pm.patch
new file mode 100644
index 0000000000..2b498c8b8c
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/ezx-pm.patch
@@ -0,0 +1,58 @@
+Index: linux-2.6.21/arch/arm/mach-pxa/pxa27x.c
+===================================================================
+--- linux-2.6.21.orig/arch/arm/mach-pxa/pxa27x.c 2007-04-26 00:08:32.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/pxa27x.c 2007-04-30 18:29:49.000000000 -0300
+@@ -22,6 +22,10 @@
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/ohci.h>
+
++#ifdef CONFIG_PXA_EZX
++#include <asm/arch/ezx.h>
++#endif
++
+ #include "generic.h"
+
+ /* Crystal clock: 13MHz */
+@@ -156,7 +160,13 @@
+ break;
+ case PM_SUSPEND_MEM:
+ /* set resume return address */
++#ifdef CONFIG_PXA_EZX
++ /* set EZX flags for blob - WM */
++ *(unsigned long *)(phys_to_virt(RESUME_ADDR)) = virt_to_phys(pxa_cpu_resume);
++ *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = SLEEP_FLAG;
++#else
+ PSPR = virt_to_phys(pxa_cpu_resume);
++#endif
+ pxa_cpu_suspend(PWRMODE_SLEEP);
+ break;
+ }
+Index: linux-2.6.21/arch/arm/mach-pxa/pm.c
+===================================================================
+--- linux-2.6.21.orig/arch/arm/mach-pxa/pm.c 2007-04-26 00:08:32.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/pm.c 2007-04-30 18:29:49.000000000 -0300
+@@ -24,6 +24,10 @@
+ #include <asm/arch/lubbock.h>
+ #include <asm/mach/time.h>
+
++#ifdef CONFIG_PXA_EZX
++#include <asm/arch/ezx.h>
++#endif
++
+
+ /*
+ * Debug macros
+@@ -152,8 +156,12 @@
+ }
+
+ /* ensure not to come back here if it wasn't intended */
++#ifdef CONFIG_PXA_EZX
++ *(unsigned long *)(phys_to_virt(RESUME_ADDR)) = 0;
++ *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = OFF_FLAG;
++#else
+ PSPR = 0;
+-
++#endif
+ /* restore registers */
+ RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
+ RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
diff --git a/packages/linux/linux-ezx-2.6.21/ezx-ts.patch b/packages/linux/linux-ezx-2.6.21/ezx-ts.patch
new file mode 100644
index 0000000000..1dd88efd6e
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/ezx-ts.patch
@@ -0,0 +1,399 @@
+Index: linux-2.6.21/drivers/input/touchscreen/Kconfig
+===================================================================
+--- linux-2.6.21.orig/drivers/input/touchscreen/Kconfig 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/input/touchscreen/Kconfig 2007-04-26 23:27:05.000000000 +0200
+@@ -164,4 +164,16 @@
+ To compile this driver as a module, choose M here: the
+ module will be called ucb1400_ts.
+
++config TOUCHSCREEN_PCAP
++ tristate "Motorola PCAP touchscreen"
++ depends on PXA_EZX_PCAP
++ help
++ Say Y here if you have a Motorola EZX (E680, A780) telephone
++ and want to support the built-in touchscreen.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called hp680_ts_input.
++
+ endif
+Index: linux-2.6.21/drivers/input/touchscreen/Makefile
+===================================================================
+--- linux-2.6.21.orig/drivers/input/touchscreen/Makefile 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/input/touchscreen/Makefile 2007-04-26 23:27:52.000000000 +0200
+@@ -16,3 +16,4 @@
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
+ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
++obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
+Index: linux-2.6.21/drivers/input/touchscreen/pcap_ts.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.21/drivers/input/touchscreen/pcap_ts.c 2007-04-26 23:27:05.000000000 +0200
+@@ -0,0 +1,364 @@
++/*
++ * pcap_ts.c - Touchscreen driver for Motorola PCAP2 based touchscreen as found
++ * in the EZX phone platform.
++ *
++ * Copyright (C) 2006 Harald Welte <laforge@openezx.org>
++ *
++ * Based on information found in the original Motorola 2.4.x ezx-ts.c driver.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * TODO:
++ * split this in a hardirq handler and a tasklet/bh
++ * suspend/resume support
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/string.h>
++#include <linux/pm.h>
++#include <linux/timer.h>
++#include <linux/config.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/input.h>
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++#include "../../misc/ezx/ssp_pcap.h"
++
++#if 1
++#define DEBUGP(x, args ...) printk(KERN_DEBUG "%s: " x, __FUNCTION__, ## args)
++#else
++#define DEBUGP(x, args ...)
++#endif
++
++#define PRESSURE 1
++#define COORDINATE 2
++
++struct pcap_ts {
++ int irq_xy;
++ int irq_touch;
++ struct input_dev *input;
++ struct timer_list timer;
++
++ u_int16_t x, y;
++ u_int16_t pressure, pressure_last;
++
++ u_int8_t read_state;
++};
++
++#define X_AXIS_MIN 0
++#define X_AXIS_MAX 1023
++
++#define Y_AXIS_MAX X_AXIS_MAX
++#define Y_AXIS_MIN X_AXIS_MIN
++
++#define PRESSURE_MAX X_AXIS_MAX
++#define PRESSURE_MIN X_AXIS_MIN
++
++static int pcap_ts_mode(u_int32_t mode)
++{
++ int ret;
++
++ u_int32_t tmp;
++
++ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC1_REGISTER, &tmp);
++ if (ret < 0)
++ return ret;
++
++ tmp &= ~SSP_PCAP_TOUCH_PANEL_POSITION_DETECT_MODE_MASK;
++ tmp |= mode;
++ ret = ezx_pcap_write(SSP_PCAP_ADJ_ADC1_REGISTER, tmp);
++
++ DEBUGP("set ts mode ");
++ if (mode == PCAP_TS_POSITION_XY_MEASUREMENT)
++ DEBUGP("COORD\n");
++ else if (mode == PCAP_TS_PRESSURE_MEASUREMENT)
++ DEBUGP("PRESS\n");
++ else if (mode == PCAP_TS_STANDBY_MODE)
++ DEBUGP("STANDBY\n");
++ else
++ printk("UNKNOWN\n");
++
++ return ret;
++}
++
++/* issue a XY read command to the ADC of PCAP2. Well get an ADCDONE2 interrupt
++ * once the result of the conversion is available */
++static int pcap_ts_start_xy_read(struct pcap_ts *pcap_ts)
++{
++ int ret;
++ u_int32_t tmp;
++ DEBUGP("start xy read in mode %s\n",
++ pcap_ts->read_state == COORDINATE ? "COORD" : "PRESS");
++
++ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC1_REGISTER, &tmp);
++ if (ret < 0)
++ return ret;
++
++ tmp &= SSP_PCAP_ADC_START_VALUE_SET_MASK;
++ tmp |= SSP_PCAP_ADC_START_VALUE;
++
++ ret = ezx_pcap_write(SSP_PCAP_ADJ_ADC1_REGISTER, tmp);
++ if (ret < 0)
++ return ret;
++
++ ret = ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_ADC2_ASC, 1);
++
++ return ret;
++}
++
++/* read the XY result from the ADC of PCAP2 */
++static int pcap_ts_get_xy_value(struct pcap_ts *pcap_ts)
++{
++ int ret;
++ u_int32_t tmp;
++
++ DEBUGP("get xy value in mode %s\n",
++ pcap_ts->read_state == COORDINATE ? "COORD" : "PRESS");
++
++ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC2_REGISTER, &tmp);
++ if (ret < 0)
++ return ret;
++
++ if (tmp & 0x00400000)
++ return -EIO;
++
++ if (pcap_ts->read_state == COORDINATE) {
++ pcap_ts->x = (tmp & SSP_PCAP_ADD1_VALUE_MASK);
++ pcap_ts->y = (tmp & SSP_PCAP_ADD2_VALUE_MASK)
++ >>SSP_PCAP_ADD2_VALUE_SHIFT;
++ } else {
++ pcap_ts->pressure_last = pcap_ts->pressure;
++ pcap_ts->pressure = (tmp & SSP_PCAP_ADD2_VALUE_MASK)
++ >>SSP_PCAP_ADD2_VALUE_SHIFT;
++ }
++
++ return 0;
++}
++
++/* PCAP2 interrupts us when ADC conversion result is available */
++static irqreturn_t pcap_ts_irq_xy(int irq, void *dev_id, struct pt_regs *regs)
++{
++ struct pcap_ts *pcap_ts = dev_id;
++
++ if (pcap_ts_get_xy_value(pcap_ts) < 0) {
++ printk("pcap_ts: error reading XY value\n");
++ return IRQ_HANDLED;
++ }
++
++ DEBUGP("%s X=%4d, Y=%4d Z=%4d\n",
++ pcap_ts->read_state == COORDINATE ? "COORD" : "PRESS",
++ pcap_ts->x, pcap_ts->y, pcap_ts->pressure);
++
++ if (pcap_ts->read_state == PRESSURE) {
++ input_report_abs(pcap_ts->input, ABS_PRESSURE,
++ pcap_ts->pressure);
++ if ((pcap_ts->pressure >= PRESSURE_MAX ||
++ pcap_ts->pressure <= PRESSURE_MIN ) &&
++ pcap_ts->pressure == pcap_ts->pressure_last) {
++ /* pen has been released */
++ input_report_key(pcap_ts->input, BTN_TOUCH, 0);
++ input_sync(pcap_ts->input);
++
++ pcap_ts->x = pcap_ts->y = 0;
++
++ /* ask PCAP2 to interrupt us if touch event happens
++ * again */
++ pcap_ts->read_state = PRESSURE;
++ pcap_ts_mode(PCAP_TS_STANDBY_MODE);
++ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
++
++ /* no need for timer, we'll get interrupted with
++ * next touch down event */
++ del_timer(&pcap_ts->timer);
++ } else {
++ /* pen has been touched down */
++ input_report_key(pcap_ts->input, BTN_TOUCH, 1);
++ /* don't input_sync(), we don't know position yet */
++
++ /* switch state machine into coordinate read mode */
++ pcap_ts->read_state = COORDINATE;
++ pcap_ts_mode(PCAP_TS_POSITION_XY_MEASUREMENT);
++ pcap_ts_start_xy_read(pcap_ts);
++
++ mod_timer(&pcap_ts->timer, jiffies + HZ/20);
++ }
++ } else {
++ /* we are in coordinate mode */
++ if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX ||
++ pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) {
++ DEBUGP("invalid x/y coordinate position: PEN_UP?\n");
++#if 0
++ input_report_key(pcap_ts->input, BTN_TOUCH, 0);
++ pcap_ts->x = pcap_ts->y = 0;
++#endif
++ } else {
++ input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x);
++ input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y);
++ }
++ input_sync(pcap_ts->input);
++
++ /* switch back to pressure read mode */
++ pcap_ts->read_state = PRESSURE;
++ pcap_ts_mode(PCAP_TS_STANDBY_MODE);
++ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/* PCAP2 interrupts us if the pen touches down */
++static irqreturn_t pcap_ts_irq_touch(int irq, void *dev_id, struct pt_regs *regs)
++{
++ struct pcap_ts *pcap_ts = dev_id;
++ DEBUGP("entered\n");
++
++ /* mask Touchscreen interrupt bit, prevents further touch events
++ * from being reported to us until we're finished with reading
++ * both pressure and x/y from ADC */
++ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 1);
++ pcap_ts_mode(PCAP_TS_PRESSURE_MEASUREMENT);
++ pcap_ts->read_state = PRESSURE;
++ pcap_ts_start_xy_read(pcap_ts);
++
++ return IRQ_HANDLED;
++}
++
++static void pcap_ts_timer_fn(unsigned long data)
++{
++ struct pcap_ts *pcap_ts = (struct pcap_ts *) data;
++
++ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 1);
++ pcap_ts_mode(PCAP_TS_PRESSURE_MEASUREMENT);
++ pcap_ts->read_state = PRESSURE;
++ pcap_ts_start_xy_read(pcap_ts);
++}
++
++static int __init ezxts_probe(struct platform_device *pdev)
++{
++ struct pcap_ts *pcap_ts;
++ struct input_dev *input_dev;
++ int err = -ENOMEM;
++
++ pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL);
++ input_dev = input_allocate_device();
++ if (!pcap_ts || !input_dev)
++ goto fail;
++
++ pcap_ts->irq_xy = platform_get_irq(pdev, 0);
++ if (pcap_ts->irq_xy < 0) {
++ err = pcap_ts->irq_xy;
++ goto fail;
++ }
++
++ pcap_ts->irq_touch = platform_get_irq(pdev, 1);
++ if (pcap_ts->irq_touch < 0) {
++ err = pcap_ts->irq_touch;
++ goto fail;
++ }
++
++ ssp_pcap_open(SSP_PCAP_TS_OPEN);
++
++ err = request_irq(pcap_ts->irq_xy, pcap_ts_irq_xy, SA_INTERRUPT,
++ "PCAP Touchscreen XY", pcap_ts);
++ if (err < 0) {
++ printk(KERN_ERR "pcap_ts: can't grab xy irq %d: %d\n",
++ pcap_ts->irq_xy, err);
++ goto fail;
++ }
++
++ err = request_irq(pcap_ts->irq_touch, pcap_ts_irq_touch, SA_INTERRUPT,
++ "PCAP Touchscreen Touch", pcap_ts);
++ if (err < 0) {
++ printk(KERN_ERR "pcap_ts: can't grab touch irq %d: %d\n",
++ pcap_ts->irq_touch, err);
++ goto fail_xy;
++ }
++
++ pcap_ts->input = input_dev;
++ pcap_ts->read_state = PRESSURE;
++ init_timer(&pcap_ts->timer);
++ pcap_ts->timer.data = (unsigned long) pcap_ts;
++ pcap_ts->timer.function = &pcap_ts_timer_fn;
++
++ platform_set_drvdata(pdev, pcap_ts);
++
++ /* enable pressure interrupt */
++ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
++
++ input_dev->name = "EZX PCAP2 Touchscreen";
++ input_dev->phys = "ezxts/input0";
++ input_dev->id.bustype = BUS_HOST;
++ input_dev->id.vendor = 0x0001;
++ input_dev->id.product = 0x0002;
++ input_dev->id.version = 0x0100;
++ input_dev->cdev.dev = &pdev->dev;
++ input_dev->private = pcap_ts;
++
++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++ input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
++ input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
++ input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN,
++ PRESSURE_MAX, 0, 0);
++
++ input_register_device(pcap_ts->input);
++
++ return 0;
++
++fail_xy:
++ free_irq(pcap_ts->irq_xy, pcap_ts);
++fail:
++ input_free_device(input_dev);
++ kfree(pcap_ts);
++
++ return err;
++}
++
++static int ezxts_remove(struct platform_device *pdev)
++{
++ struct pcap_ts *pcap_ts = platform_get_drvdata(pdev);
++
++ del_timer_sync(&pcap_ts->timer);
++
++ free_irq(pcap_ts->irq_touch, pcap_ts);
++ free_irq(pcap_ts->irq_xy, pcap_ts);
++
++ input_unregister_device(pcap_ts->input);
++ kfree(pcap_ts);
++
++ return 0;
++}
++
++static struct platform_driver ezxts_driver = {
++ .probe = ezxts_probe,
++ .remove = ezxts_remove,
++ //.suspend = ezxts_suspend,
++ //.resume = ezxts_resume,
++ .driver = {
++ .name = "pcap-ts",
++ },
++};
++
++static int __devinit ezxts_init(void)
++{
++ return platform_driver_register(&ezxts_driver);
++}
++
++static void __exit ezxts_exit(void)
++{
++ platform_driver_unregister(&ezxts_driver);
++}
++
++module_init(ezxts_init);
++module_exit(ezxts_exit);
++
++MODULE_DESCRIPTION("Motorola PCAP2 touchscreen driver");
++MODULE_AUTHOR("Harald Welte <laforge@openezx.org>");
++MODULE_LICENSE("GPL");
diff --git a/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.20.7-fix.patch b/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.20.7-fix.patch
new file mode 100644
index 0000000000..cab7490118
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.20.7-fix.patch
@@ -0,0 +1,224 @@
+Index: linux-2.6.20.7/drivers/char/ts0710.h
+===================================================================
+--- linux-2.6.20.7.orig/drivers/char/ts0710.h 2007-04-24 16:04:23.000000000 +0200
++++ linux-2.6.20.7/drivers/char/ts0710.h 2007-04-24 16:04:23.000000000 +0200
+@@ -45,7 +45,7 @@
+ * 11/18/2002 Modified
+ */
+
+-#include <linux/config.h>
++//#include <linux/config.h>
+ #include <linux/module.h>
+
+ #include <linux/errno.h>
+@@ -58,7 +58,7 @@
+ #include <linux/major.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+-#include <linux/devfs_fs_kernel.h>
++//#include <linux/devfs_fs_kernel.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+Index: linux-2.6.20.7/drivers/char/ts0710_mux.c
+===================================================================
+--- linux-2.6.20.7.orig/drivers/char/ts0710_mux.c 2007-04-24 16:04:23.000000000 +0200
++++ linux-2.6.20.7/drivers/char/ts0710_mux.c 2007-04-24 16:26:58.000000000 +0200
+@@ -46,7 +46,7 @@
+ * 11/18/2002 Second version
+ * 04/21/2004 Add GPRS PROC
+ */
+-#include <linux/config.h>
++//#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+
+@@ -70,7 +70,7 @@
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+-#include <linux/devfs_fs_kernel.h>
++//#include <linux/devfs_fs_kernel.h>
+ //#include <syslog.h>
+
+ #include <asm/uaccess.h>
+@@ -268,8 +268,8 @@
+ static struct work_struct post_recv_tqueue;
+
+ static struct tty_struct *mux_table[NR_MUXS];
+-static struct termios *mux_termios[NR_MUXS];
+-static struct termios *mux_termios_locked[NR_MUXS];
++static struct ktermios *mux_termios[NR_MUXS];
++static struct ktermios *mux_termios_locked[NR_MUXS];
+ static volatile short int mux_tty[NR_MUXS];
+
+ #ifdef min
+@@ -1894,11 +1894,14 @@
+ if (test_bit(TTY_THROTTLED, &tty->flags)) {
+ queue_data = 1;
+ } else {
++ /*
+ if (test_bit
+ (TTY_DONT_FLIP, &tty->flags)) {
+ queue_data = 1;
+ post_recv = 1;
+- } else if (recv_info->total) {
++ } else
++ */
++ if (recv_info->total) {
+ queue_data = 1;
+ post_recv = 1;
+ } else if (recv_room < uih_len) {
+@@ -3149,7 +3152,7 @@
+
+ /*For BP UART problem End*/
+
+-static void receive_worker(void *private_)
++static void receive_worker(struct work_struct *private_)
+ {
+ struct tty_struct *tty = COMM_FOR_MUX_TTY;
+ int i, count, tbuf_free, tbuf_read;
+@@ -3440,7 +3443,7 @@
+ clear_bit(RECV_RUNNING, &mux_recv_flags);
+ }
+
+-static void post_recv_worker(void *private_)
++static void post_recv_worker(struct work_struct *private_)
+ {
+ ts0710_con *ts0710 = &ts0710_connection;
+ int tty_idx;
+@@ -3499,11 +3502,14 @@
+ if (test_bit(TTY_THROTTLED, &tty->flags)) {
+ add_post_recv_queue(&post_recv_q, recv_info);
+ continue;
+- } else if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
++ }
++ /*
++ else if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
+ post_recv = 1;
+ add_post_recv_queue(&post_recv_q, recv_info);
+ continue;
+ }
++ */
+
+ flow_control = 0;
+ recv_packet2 = recv_info->mux_packet;
+@@ -3635,7 +3641,7 @@
+ }
+ }
+
+-static void send_worker(void *private_)
++static void send_worker(struct work_struct *private_)
+ {
+ ts0710_con *ts0710 = &ts0710_connection;
+ __u8 j;
+@@ -3893,9 +3899,9 @@
+ }
+ post_recv_count_flag = 0;
+
+- INIT_WORK(&send_tqueue, send_worker, NULL);
+- INIT_WORK(&receive_tqueue, receive_worker, NULL);
+- INIT_WORK(&post_recv_tqueue, post_recv_worker, NULL);
++ INIT_WORK(&send_tqueue, send_worker);
++ INIT_WORK(&receive_tqueue, receive_worker);
++ INIT_WORK(&post_recv_tqueue, post_recv_worker);
+
+ mux_driver = alloc_tty_driver(NR_MUXS);
+ if (!mux_driver)
+@@ -3904,12 +3910,12 @@
+ mux_driver->owner = THIS_MODULE;
+ mux_driver->driver_name = "ts0710mux";
+ mux_driver->name = "mux";
+- mux_driver->devfs_name = "mux";
++ //mux_driver->devfs_name = "mux";
+ mux_driver->major = TS0710MUX_MAJOR;
+ mux_driver->minor_start = TS0710MUX_MINOR_START;
+ mux_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ mux_driver->subtype = SERIAL_TYPE_NORMAL;
+- mux_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
++ mux_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+
+ mux_driver->init_termios = tty_std_termios;
+ mux_driver->init_termios.c_iflag = 0;
+@@ -3917,10 +3923,10 @@
+ mux_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+ mux_driver->init_termios.c_lflag = 0;
+
+-// mux_driver.ttys = mux_table;
++ //mux_driver.ttys = mux_table;
+ mux_driver->termios = mux_termios;
+ mux_driver->termios_locked = mux_termios_locked;
+-// mux_driver.driver_state = mux_state;
++ //mux_driver.driver_state = mux_state;
+ mux_driver->other = NULL;
+
+ mux_driver->open = mux_open;
+Index: linux-2.6.20.7/drivers/char/ts0710_mux_usb.c
+===================================================================
+--- linux-2.6.20.7.orig/drivers/char/ts0710_mux_usb.c 2007-04-24 16:27:30.000000000 +0200
++++ linux-2.6.20.7/drivers/char/ts0710_mux_usb.c 2007-04-24 16:31:51.000000000 +0200
+@@ -86,8 +86,8 @@
+ struct tty_struct *usb_for_mux_tty = NULL;
+ void (*usb_mux_dispatcher)(struct tty_struct *tty) = NULL;
+ void (*usb_mux_sender)(void) = NULL;
+-void (*ipcusb_ap_to_bp)(unsigned char*, int) = NULL;
+-void (*ipcusb_bp_to_ap)(unsigned char*, int) = NULL;
++void (*ipcusb_ap_to_bp)(const unsigned char*, int) = NULL;
++void (*ipcusb_bp_to_ap)(const unsigned char*, int) = NULL;
+ EXPORT_SYMBOL(usb_for_mux_driver);
+ EXPORT_SYMBOL(usb_for_mux_tty);
+ EXPORT_SYMBOL(usb_mux_dispatcher);
+@@ -222,7 +222,7 @@
+ inbuf = list_entry(ptr, buf_list_t, list);
+ src_count = inbuf->size;
+ if (dst_count >= src_count) {
+- memcpy(buf, inbuf->body, src_count);
++ memcpy((char *)buf, inbuf->body, src_count);
+ ret = src_count;
+ list_del(ptr);
+ kfree(inbuf->body);
+@@ -282,7 +282,7 @@
+ spin_unlock(&bvd_ipc->in_buf_lock);
+ }
+
+-static void usb_ipc_read_bulk(struct urb *urb, struct pt_regs *regs)
++static void usb_ipc_read_bulk(struct urb *urb)
+ {
+ buf_list_t *inbuf;
+ int count = urb->actual_length;
+@@ -319,7 +319,7 @@
+ bvd_dbg("usb_ipc_read_bulk: completed!!!");
+ }
+
+-static void usb_ipc_write_bulk(struct urb *urb, struct pt_regs *regs)
++static void usb_ipc_write_bulk(struct urb *urb)
+ {
+ callback_times++;
+ bvd_ipc->write_finished_flag = 1;
+@@ -437,7 +437,7 @@
+ /*send IN token*/
+ bvd_ipc->readurb_mux.actual_length = 0;
+ bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev;
+- if (ret = usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC))
++ if ( (ret = usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC)) )
+ printk("ipcusb_xmit_data: usb_submit_urb(read mux bulk)"
+ "failed! status=%d\n", ret);
+ bvd_dbg("ipcusb_xmit_data: Send a IN token successfully!");
+@@ -447,7 +447,7 @@
+ bvd_ipc->write_finished_flag = 0;
+ //printk("%s: clear write_finished_flag:%d\n", __FUNCTION__, bvd_ipc->write_finished_flag);
+ bvd_ipc->writeurb_mux.dev = bvd_ipc->ipc_dev;
+- if (result = usb_submit_urb(&bvd_ipc->writeurb_mux, GFP_ATOMIC))
++ if ( (result = usb_submit_urb(&bvd_ipc->writeurb_mux, GFP_ATOMIC)) )
+ warn("ipcusb_xmit_data: funky result! result=%d\n", result);
+
+ bvd_dbg("ipcusb_xmit_data: usb_submit_urb finished! result:%d", result);
+@@ -556,7 +556,7 @@
+ struct usb_config_descriptor *ipccfg;
+ struct usb_interface_descriptor *interface;
+ struct usb_endpoint_descriptor *endpoint;
+- int ep_cnt, readsize, writesize;
++ int ep_cnt, readsize=0, writesize=0;
+ char have_bulk_in_mux, have_bulk_out_mux;
+
+ bvd_dbg("usb_ipc_probe: vendor id 0x%x, device id 0x%x",
diff --git a/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.21-fix.patch b/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.21-fix.patch
index 79f48ae581..8d5299e3bd 100644
--- a/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.21-fix.patch
+++ b/packages/linux/linux-ezx-2.6.21/mux-linux-2.6.21-fix.patch
@@ -202,7 +202,7 @@ Index: linux-2.6.21/drivers/char/ts0710_mux.c
Index: linux-2.6.21/drivers/char/ts0710_mux_usb.c
===================================================================
--- linux-2.6.21.orig/drivers/char/ts0710_mux_usb.c 2007-04-27 20:35:44.000000000 -0300
-+++ linux-2.6.21/drivers/char/ts0710_mux_usb.c 2007-04-27 22:28:55.000000000 -0300
++++ linux-2.6.21/drivers/char/ts0710_mux_usb.c 2007-04-27 22:34:31.000000000 -0300
@@ -188,7 +188,8 @@
buf_list_t *inbuf;
int count = urb->actual_length;
@@ -213,6 +213,15 @@ Index: linux-2.6.21/drivers/char/ts0710_mux_usb.c
if (!inbuf) {
printk("append_to_inbuf_list: (%d) out of memory!\n",
sizeof(buf_list_t));
+@@ -196,7 +197,7 @@
+ }
+
+ inbuf->size = count;
+- inbuf->body = kmalloc(sizeof(char)*count, GFP_KERNEL);
++ inbuf->body = kmalloc(sizeof(char)*count, GFP_ATOMIC);
+ if (!inbuf->body) {
+ kfree(inbuf);
+ printk("append_to_inbuf_list: (%d) out of memory!\n",
@@ -222,7 +223,7 @@
inbuf = list_entry(ptr, buf_list_t, list);
src_count = inbuf->size;
diff --git a/packages/linux/linux-ezx-2.6.21/pcap_ts.c.patch b/packages/linux/linux-ezx-2.6.21/pcap_ts.c.patch
new file mode 100644
index 0000000000..d46033bc80
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/pcap_ts.c.patch
@@ -0,0 +1,237 @@
+Index: linux-2.6.21/drivers/input/touchscreen/pcap_ts.c
+===================================================================
+--- linux-2.6.21.orig/drivers/input/touchscreen/pcap_ts.c 2007-05-01 16:28:00.000000000 +0200
++++ linux-2.6.21/drivers/input/touchscreen/pcap_ts.c 2007-05-01 16:28:03.000000000 +0200
+@@ -21,15 +21,14 @@
+ #include <linux/string.h>
+ #include <linux/pm.h>
+ #include <linux/timer.h>
+-#include <linux/config.h>
++//#include <linux/config.h>
+ #include <linux/interrupt.h>
+ #include <linux/platform_device.h>
+ #include <linux/input.h>
+
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/pxa-regs.h>
+-
+-#include "../../misc/ezx/ssp_pcap.h"
++#include <asm/arch/ezx-pcap.h>
+
+ #if 1
+ #define DEBUGP(x, args ...) printk(KERN_DEBUG "%s: " x, __FUNCTION__, ## args)
+@@ -61,6 +60,9 @@
+ #define PRESSURE_MAX X_AXIS_MAX
+ #define PRESSURE_MIN X_AXIS_MIN
+
++#define SAMPLE_INTERVAL (HZ/100)
++
++
+ static int pcap_ts_mode(u_int32_t mode)
+ {
+ int ret;
+@@ -157,8 +159,6 @@
+ pcap_ts->x, pcap_ts->y, pcap_ts->pressure);
+
+ if (pcap_ts->read_state == PRESSURE) {
+- input_report_abs(pcap_ts->input, ABS_PRESSURE,
+- pcap_ts->pressure);
+ if ((pcap_ts->pressure >= PRESSURE_MAX ||
+ pcap_ts->pressure <= PRESSURE_MIN ) &&
+ pcap_ts->pressure == pcap_ts->pressure_last) {
+@@ -166,6 +166,8 @@
+ input_report_key(pcap_ts->input, BTN_TOUCH, 0);
+ input_sync(pcap_ts->input);
+
++ input_report_abs(pcap_ts->input, ABS_PRESSURE, 0);
++
+ pcap_ts->x = pcap_ts->y = 0;
+
+ /* ask PCAP2 to interrupt us if touch event happens
+@@ -182,18 +184,24 @@
+ input_report_key(pcap_ts->input, BTN_TOUCH, 1);
+ /* don't input_sync(), we don't know position yet */
+
++ if (pcap_ts->pressure == 0)
++ pcap_ts->pressure = pcap_ts->pressure_last;
++
++ input_report_abs(pcap_ts->input, ABS_PRESSURE,
++ pcap_ts->pressure);
++
+ /* switch state machine into coordinate read mode */
+ pcap_ts->read_state = COORDINATE;
+ pcap_ts_mode(PCAP_TS_POSITION_XY_MEASUREMENT);
+ pcap_ts_start_xy_read(pcap_ts);
+-
+- mod_timer(&pcap_ts->timer, jiffies + HZ/20);
+ }
+ } else {
+ /* we are in coordinate mode */
+ if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX ||
+ pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) {
+ DEBUGP("invalid x/y coordinate position: PEN_UP?\n");
++
++ pcap_ts->pressure = 0;
+ #if 0
+ input_report_key(pcap_ts->input, BTN_TOUCH, 0);
+ pcap_ts->x = pcap_ts->y = 0;
+@@ -206,8 +214,8 @@
+
+ /* switch back to pressure read mode */
+ pcap_ts->read_state = PRESSURE;
+- pcap_ts_mode(PCAP_TS_STANDBY_MODE);
+- ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
++ pcap_ts_mode(PCAP_TS_PRESSURE_MEASUREMENT);
++ mod_timer(&pcap_ts->timer, jiffies + SAMPLE_INTERVAL);
+ }
+
+ return IRQ_HANDLED;
+@@ -234,18 +242,19 @@
+ {
+ struct pcap_ts *pcap_ts = (struct pcap_ts *) data;
+
+- ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 1);
+- pcap_ts_mode(PCAP_TS_PRESSURE_MEASUREMENT);
+- pcap_ts->read_state = PRESSURE;
+ pcap_ts_start_xy_read(pcap_ts);
+ }
+
+ static int __init ezxts_probe(struct platform_device *pdev)
+ {
++ int ret;
++ u_int32_t tmp;
+ struct pcap_ts *pcap_ts;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
+
++ printk(KERN_DEBUG "Start probing TS!\n");
++
+ pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!pcap_ts || !input_dev)
+@@ -263,7 +272,46 @@
+ goto fail;
+ }
+
+- ssp_pcap_open(SSP_PCAP_TS_OPEN);
++ // Some initialization before done in ssp_pcap_open()
++ //ssp_pcap_open(SSP_PCAP_TS_OPEN);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_TS_REFENB, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I, 1);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ISR_TSI, 1);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC2_ADINC1, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC2_ADINC2, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_ATO0, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_ATO1, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_ATO2, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_ATO3, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_ATOX, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_MTR1, 0);
++ ezx_pcap_bit_set( SSP_PCAP_ADJ_BIT_ADC1_MTR2, 0);
++
++ //SSP_PCAP_TSI_mode_set(PCAP_TS_STANDBY_MODE);
++ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC1_REGISTER, &tmp);
++ if (ret < 0)
++ return ret;
++
++ tmp &= (~SSP_PCAP_TOUCH_PANEL_POSITION_DETECT_MODE_MASK);
++ tmp |= PCAP_TS_STANDBY_MODE;
++
++ ret = ezx_pcap_write(SSP_PCAP_ADJ_ADC1_REGISTER, tmp);
++ if (ret < 0)
++ return ret;
++
++ /* send the usb accessory infomation to PM */
++ /*
++ if((ACCESSORY_TYPE) sspUsbAccessoryInfo.type == ACCESSORY_DEVICE_USB_PORT)
++ {
++ if( (ACCESSORY_DEVICE_STATUS )sspUsbAccessoryInfo.status == ACCESSORY_DEVICE_STATUS_ATTACHED )
++ apm_queue_event(KRNL_ACCS_ATTACH);
++ else
++ apm_queue_event(KRNL_ACCS_DETACH);
++ }
++ */
++
+
+ err = request_irq(pcap_ts->irq_xy, pcap_ts_irq_xy, SA_INTERRUPT,
+ "PCAP Touchscreen XY", pcap_ts);
+@@ -343,10 +391,11 @@
+ //.resume = ezxts_resume,
+ .driver = {
+ .name = "pcap-ts",
++ .owner = THIS_MODULE,
+ },
+ };
+
+-static int __devinit ezxts_init(void)
++static int __init ezxts_init(void)
+ {
+ return platform_driver_register(&ezxts_driver);
+ }
+Index: linux-2.6.21/drivers/input/touchscreen/Kconfig
+===================================================================
+--- linux-2.6.21.orig/drivers/input/touchscreen/Kconfig 2007-05-01 16:28:00.000000000 +0200
++++ linux-2.6.21/drivers/input/touchscreen/Kconfig 2007-05-01 16:28:03.000000000 +0200
+@@ -166,7 +166,7 @@
+
+ config TOUCHSCREEN_PCAP
+ tristate "Motorola PCAP touchscreen"
+- depends on PXA_EZX_PCAP
++ depends on PXA_EZX
+ help
+ Say Y here if you have a Motorola EZX (E680, A780) telephone
+ and want to support the built-in touchscreen.
+@@ -174,6 +174,6 @@
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+- module will be called hp680_ts_input.
++ module will be called pcap_ts.
+
+ endif
+Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
+===================================================================
+--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx.c 2007-05-01 16:28:00.000000000 +0200
++++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-05-01 16:28:03.000000000 +0200
+@@ -116,6 +116,31 @@
+ .resource = ezxemu_resources,
+ };
+
++/* PCAP_TS */
++struct resource pcap_ts_resources[] = {
++ [0] = {
++ .start = EZX_IRQ_ADCDONE2,
++ .end = EZX_IRQ_ADCDONE2,
++ .flags = IORESOURCE_IRQ,
++ },
++ [1] = {
++ .start = EZX_IRQ_TS,
++ .end = EZX_IRQ_TS,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++struct platform_device pcap_ts_device = {
++ .name = "pcap-ts",
++ .id = -1,
++ .dev = {
++ .parent = &ezxpcap_device.dev,
++ },
++ .num_resources = ARRAY_SIZE(pcap_ts_resources),
++ .resource = pcap_ts_resources,
++};
++
++
+ /* OHCI Controller */
+
+ static int ezx_ohci_init(struct device *dev)
+@@ -342,6 +367,7 @@
+ &ezxpcap_device,
+ &ezxbp_device,
+ &ezxemu_device,
++ &pcap_ts_device,
+ };
+
+ static void __init a780_init(void)
diff --git a/packages/linux/linux-ezx-2.6.21/pxa-kbd.patch b/packages/linux/linux-ezx-2.6.21/pxa-kbd.patch
new file mode 100644
index 0000000000..9bc6be656a
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/pxa-kbd.patch
@@ -0,0 +1,463 @@
+Index: linux-2.6.21/arch/arm/mach-pxa/generic.c
+===================================================================
+--- linux-2.6.21.orig/arch/arm/mach-pxa/generic.c 2007-04-30 19:19:58.000000000 -0300
++++ linux-2.6.21/arch/arm/mach-pxa/generic.c 2007-04-30 19:45:20.000000000 -0300
+@@ -42,6 +42,7 @@
+ #include <asm/arch/mmc.h>
+ #include <asm/arch/irda.h>
+ #include <asm/arch/i2c.h>
++#include <asm/arch/kbd.h>
+
+ #include "generic.h"
+
+@@ -430,6 +431,30 @@
+ .id = -1,
+ };
+
++static struct resource pxa_kbd_resources[] = {
++ {
++ .start = IRQ_KEYPAD,
++ .end = IRQ_KEYPAD,
++ .flags = IORESOURCE_IRQ,
++ }, {
++ .start = 0x41500000,
++ .end = 0x4150004c,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device kbd_device = {
++ .name = "pxa-keyboard",
++ .id = -1,
++ .resource = pxa_kbd_resources,
++ .num_resources = ARRAY_SIZE(pxa_kbd_resources),
++};
++
++void __init pxa_set_kbd_info(struct pxakbd_platform_data *info)
++{
++ kbd_device.dev.platform_data = info;
++}
++
+ static struct platform_device *devices[] __initdata = {
+ &pxamci_device,
+ &udc_device,
+@@ -444,6 +469,7 @@
+ #endif
+ &i2s_device,
+ &pxartc_device,
++ &kbd_device,
+ };
+
+ static int __init pxa_init(void)
+Index: linux-2.6.21/drivers/input/keyboard/Kconfig
+===================================================================
+--- linux-2.6.21.orig/drivers/input/keyboard/Kconfig 2007-04-30 19:15:26.000000000 -0300
++++ linux-2.6.21/drivers/input/keyboard/Kconfig 2007-04-30 19:43:53.000000000 -0300
+@@ -229,4 +229,11 @@
+ To compile this driver as a module, choose M here: the
+ module will be called gpio-keys.
+
++config KEYBOARD_PXA
++ tristate "Intel PXA keyboard support"
++ depends on ARCH_PXA
++ help
++ This add support for a driver of the Intel PXA2xx keyboard
++ controller.
++
+ endif
+Index: linux-2.6.21/drivers/input/keyboard/Makefile
+===================================================================
+--- linux-2.6.21.orig/drivers/input/keyboard/Makefile 2007-04-30 19:17:25.000000000 -0300
++++ linux-2.6.21/drivers/input/keyboard/Makefile 2007-04-30 19:46:54.000000000 -0300
+@@ -19,4 +19,4 @@
+ obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+ obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
+ obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
+-
++obj-$(CONFIG_KEYBOARD_PXA) += pxakbd.o
+Index: linux-2.6.21/include/asm-arm/arch-pxa/kbd.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.21/include/asm-arm/arch-pxa/kbd.h 2007-04-30 19:27:58.000000000 -0300
+@@ -0,0 +1,28 @@
++/*
++ * kbd_pxa.h
++ *
++ * Copyright (C) 2006 Harald Welte <laforge@openezx.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++#ifndef _KBD_PXA_H_
++#define _KBD_PXA_H_
++
++struct pxakbd_platform_data {
++ int (*init)(void); /* init gpio, etc. */
++ unsigned int scan_interval;
++ struct {
++ unsigned int rows;
++ unsigned int cols;
++ unsigned char *keycode;
++ } matrix;
++ struct {
++ unsigned int num;
++ unsigned char *keycode;
++ } direct;
++};
++
++#endif
+Index: linux-2.6.21/drivers/input/keyboard/pxakbd.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.21/drivers/input/keyboard/pxakbd.c 2007-04-30 19:48:13.000000000 -0300
+@@ -0,0 +1,332 @@
++/*
++ * Driver for Motorola EZX phone "keyboard"
++ *
++ * (C) 2006 by Harald Welte <laforge@openezx.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/spinlock.h>
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include <asm/arch/kbd.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/pxa-regs.h>
++
++#if 1
++#define DEBUGP(x, args ...) printk(x, ## args)
++#else
++#define DEBUGP(x, args ...)
++#endif
++
++/* per-keyboard private data structure */
++struct pxakbd {
++ struct input_dev *input;
++ struct timer_list timer;
++ spinlock_t lock;
++
++ struct resource *res;
++ unsigned int irq;
++
++ struct pxakbd_platform_data *pd;
++};
++
++static int pxakbd_scan_direct(struct pxakbd *pxakbd)
++{
++ u_int32_t kpdk;
++ unsigned int i;
++ int num_pressed = 0;
++
++ kpdk = KPDK & 0x000000ff;
++ for (i = 0; i < pxakbd->pd->direct.num; i++) {
++ int pressed = 0;
++
++ if (kpdk & (1 << i)) {
++ pressed = 1;
++ num_pressed++;
++ DEBUGP("pxakbd: pressed: direct %u\n", i);
++ }
++ if (pxakbd->pd->direct.keycode[i] != KEY_RESERVED) {
++ DEBUGP( "pxakbd: sending to input layer: keycode = %d, pressed = %d\n", pxakbd->pd->direct.keycode[i], pressed );
++ input_report_key(pxakbd->input, pxakbd->pd->direct.keycode[i],
++ pressed);
++ }
++ }
++ return num_pressed;
++}
++
++/* read the full 8x8 matrix from the PXA27x keypad controller */
++static void __read_matrix(u_int8_t *matrix)
++{
++ u_int32_t tmp;
++
++ tmp = KPASMKP0;
++ matrix[0] = tmp & 0x000000ff;
++ matrix[1] = (tmp & 0x00ff0000) >> 16;
++
++ tmp = KPASMKP1;
++ matrix[2] = tmp & 0x000000ff;
++ matrix[3] = (tmp & 0x00ff0000) >> 16;
++
++ tmp = KPASMKP2;
++ matrix[4] = tmp & 0x000000ff;
++ matrix[5] = (tmp & 0x00ff0000) >> 16;
++
++ tmp = KPASMKP3;
++ matrix[6] = tmp & 0x000000ff;
++ matrix[7] = (tmp & 0x00ff0000) >> 16;
++}
++
++/* compare current matrix with last, generate 'diff' events */
++static int __cmp_matrix_gen_events(struct pxakbd *pxakbd, u_int8_t *matrix)
++{
++ unsigned int i;
++ int num_pressed = 0;
++
++ /* iterate over the matrix */
++ for (i = 0; i < pxakbd->pd->matrix.rows; i++) {
++ unsigned int j;
++ for (j = 0; j < pxakbd->pd->matrix.cols; j++) {
++ u_int32_t scancode =
++ (i * pxakbd->pd->matrix.cols) + j;
++ int pressed = matrix[i] & (1 << j);
++
++ if (pressed) {
++ DEBUGP("pxakbd: pressed: %u/%u\n", i, j);
++ num_pressed++;
++ }
++
++ input_report_key(pxakbd->input,
++ pxakbd->pd->matrix.keycode[scancode], pressed);
++ }
++ }
++
++ return num_pressed;
++}
++
++/* scan the matrix keypad */
++static int pxakbd_scan_matrix(struct pxakbd *pxakbd)
++{
++ int num_pressed;
++ u_int32_t kpas;
++ u_int8_t matrix[8];
++
++ kpas = KPAS;
++
++ if ((kpas & KPAS_MUKP) == KPAS_MUKP_NONE) {
++ /* no keys pressed */
++ memset(matrix, 0, sizeof(matrix));
++ } else if ((kpas & KPAS_MUKP) == KPAS_MUKP_ONE) {
++ /* one key pressed */
++ u_int8_t row = (kpas & KPAS_RP) >> 4;
++ u_int8_t col = kpas & KPAS_CP;
++
++ if (row == 0x0f || col == 0x0f) {
++ printk(KERN_WARNING "pxakbd: col or row invalid!\n");
++ return -1;
++ }
++
++ /* clear the matrix and set the single pressed key */
++ memset(matrix, 0, sizeof(matrix));
++ matrix[row] |= (1 << col);
++ } else {
++ /* multiple keys pressed */
++ __read_matrix(matrix);
++ }
++
++ num_pressed = __cmp_matrix_gen_events(pxakbd, matrix);
++
++ return num_pressed;
++}
++
++static void pxakbd_timer_callback(unsigned long data)
++{
++ unsigned long flags;
++ struct pxakbd *pxakbd = (struct pxakbd *) data;
++ unsigned int num_pressed;
++
++ spin_lock_irqsave(&pxakbd->lock, flags);
++
++ num_pressed = pxakbd_scan_direct(pxakbd);
++ num_pressed += pxakbd_scan_matrix(pxakbd);
++
++ spin_unlock_irqrestore(&pxakbd->lock, flags);
++
++ /* propagate events up the input stack */
++ input_sync(pxakbd->input);
++}
++
++static irqreturn_t pxakbd_interrupt(int irq, void *dummy)
++{
++ struct pxakbd *pxakbd = dummy;
++ u_int32_t kpc;
++ int handled = 0;
++ int num_pressed = 0;
++
++ /* read and clear interrupt */
++ kpc = KPC;
++
++ if (kpc & KPC_DI) {
++ num_pressed += pxakbd_scan_direct(pxakbd);
++ handled = 1;
++ }
++
++ if (kpc & KPC_MI) {
++ while (KPAS & KPAS_SO) {
++ /* wait for scan to complete beforereading scan regs */
++ cpu_relax();
++ }
++ num_pressed += pxakbd_scan_matrix(pxakbd);
++ handled = 1;
++ }
++
++ /* If any keys are currently pressed, we need to start the timer to detect
++ * key release. */
++ if (num_pressed)
++ mod_timer(&pxakbd->timer, jiffies + pxakbd->pd->scan_interval);
++
++ /* propagate events up the input stack */
++ input_sync(pxakbd->input);
++
++ return IRQ_RETVAL(handled);
++}
++
++static int __init pxakbd_probe(struct platform_device *pdev)
++{
++ struct pxakbd *pxakbd;
++ struct input_dev *input_dev;
++ struct resource *r;
++ int i;
++ int ret = -ENOMEM;
++
++ pxakbd = kzalloc(sizeof(*pxakbd), GFP_KERNEL);
++ if (!pxakbd)
++ goto out;
++
++ input_dev = input_allocate_device();
++ if (!input_dev)
++ goto out_pxa;
++
++ pxakbd->irq = platform_get_irq(pdev, 0);
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!r || pxakbd->irq == NO_IRQ) {
++ printk(KERN_ERR "pxakbd: invalid resources\n");
++ ret = -EBUSY;
++ goto out_idev;
++ }
++
++ pxakbd->input = input_dev;
++ init_timer(&pxakbd->timer);
++ pxakbd->timer.function = pxakbd_timer_callback;
++ pxakbd->timer.data = (unsigned long) pxakbd;
++ pxakbd->pd = pdev->dev.platform_data;
++ pxakbd->res = r;
++
++ input_dev->name = "PXA Keyboard";
++ input_dev->phys = "pxakbd/input0";
++ input_dev->id.bustype = BUS_HOST;
++ input_dev->id.vendor = 0x0001;
++ input_dev->id.product = 0x0001;
++ input_dev->id.version = 0x0001;
++ input_dev->cdev.dev = &pdev->dev;
++ input_dev->private = pxakbd;
++
++ input_dev->evbit[0] = BIT(EV_KEY)|BIT(EV_REP);
++ input_dev->keycode = pxakbd->pd->matrix.keycode;
++ input_dev->keycodesize = sizeof(unsigned char);
++ input_dev->keycodemax = pxakbd->pd->matrix.rows
++ *pxakbd->pd->matrix.cols;
++
++ for (i = 0; i < input_dev->keycodemax; i++)
++ set_bit(pxakbd->pd->matrix.keycode[i], input_dev->keybit);
++ clear_bit(0, input_dev->keybit);
++
++ if (request_irq(pxakbd->irq, pxakbd_interrupt, 0, "pxakbd", pxakbd)) {
++ printk(KERN_ERR "pxakbd: can't request irq %d\n", pxakbd->irq);
++ ret = -EBUSY;
++ goto out_idev;
++ }
++
++ r = request_mem_region(r->start, 0x4c, "pxakbd");
++ if (!r) {
++ printk(KERN_ERR "pxakbd: can't request memregion\n");
++ ret = -EBUSY;
++ goto out_irq;
++ }
++
++ /* set up gpio */
++ pxakbd->pd->init();
++
++ /* set keypad control register */
++ KPC = (KPC_ASACT | /* automatic scan on activity */
++ KPC_ME | KPC_DE | /* matrix and direct keypad enabled */
++ ((pxakbd->pd->matrix.cols-1)<<23) | /* columns */
++ ((pxakbd->pd->matrix.rows-1)<<26) | /* rows */
++ ((pxakbd->pd->direct.num-1)<<6) | /* direct keys */
++ KPC_MS_ALL); /* scan all columns */
++
++ pxa_set_cken(CKEN19_KEYPAD, 1);
++
++ KPC |= (KPC_DIE | KPC_MIE); /* enable matrix and direct keyboard */
++
++ KPKDI = 0x40; /* matrix key debounce interval: 0x40 */
++
++ platform_set_drvdata(pdev, pxakbd);
++
++ return input_register_device(pxakbd->input);
++
++out_drvdata:
++ platform_set_drvdata(pdev, NULL);
++out_mem:
++ release_resource(r);
++out_irq:
++ free_irq(pxakbd->irq, pxakbd);
++out_idev:
++ input_free_device(input_dev);
++out_pxa:
++ kfree(pxakbd);
++out:
++ return ret;
++}
++
++static int pxakbd_remove(struct platform_device *pdev)
++{
++ struct pxakbd *pxakbd = platform_get_drvdata(pdev);
++ input_unregister_device(pxakbd->input);
++ platform_set_drvdata(pdev, NULL);
++ release_resource(pxakbd->res);
++ free_irq(pxakbd->irq, pxakbd);
++ kfree(pxakbd);
++ return 0;
++}
++
++static struct platform_driver pxakbd_driver = {
++ .probe = &pxakbd_probe,
++ .remove = &pxakbd_remove,
++ .driver = {
++ .name = "pxa-keyboard",
++ },
++};
++
++static int __devinit pxakbd_init(void)
++{
++ return platform_driver_register(&pxakbd_driver);
++}
++
++static void __exit pxakbd_exit(void)
++{
++ platform_driver_unregister(&pxakbd_driver);
++}
++
++module_init(pxakbd_init);
++module_exit(pxakbd_exit);
++
++MODULE_AUTHOR("Harald Welte <laforge@openezx.org>");
++MODULE_DESCRIPTION("Driver for Intel PXA27x keypad controller");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h
+===================================================================
+--- linux-2.6.21.orig/include/asm-arm/arch-pxa/pxa-regs.h 2007-04-30 19:39:30.000000000 -0300
++++ linux-2.6.21/include/asm-arm/arch-pxa/pxa-regs.h 2007-04-30 19:42:34.000000000 -0300
+@@ -2165,6 +2165,11 @@
+ #define KPMK_MKP (0x1 << 31)
+ #define KPAS_SO (0x1 << 31)
+ #define KPASMKPx_SO (0x1 << 31)
++#define KPAS_RP (0x000000f0)
++#define KPAS_CP (0x0000000f)
++#define KPAS_MUKP (0x7c000000)
++#define KPAS_MUKP_ONE (0x04000000)
++#define KPAS_MUKP_NONE (0x00000000)
+
+ /*
+ * UHC: USB Host Controller (OHCI-like) register definitions
diff --git a/packages/linux/linux-ezx-2.6.21/touchscreen-fix-r0.patch b/packages/linux/linux-ezx-2.6.21/touchscreen-fix-r0.patch
new file mode 100644
index 0000000000..9f4ce980ad
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/touchscreen-fix-r0.patch
@@ -0,0 +1,21 @@
+
+#
+# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
+#
+
+Index: linux-2.6.21/drivers/input/touchscreen/pcap_ts.c
+===================================================================
+--- linux-2.6.21.orig/drivers/input/touchscreen/pcap_ts.c 2007-04-30 21:55:41.000000000 +0200
++++ linux-2.6.21/drivers/input/touchscreen/pcap_ts.c 2007-04-30 21:55:41.000000000 +0200
+@@ -128,10 +128,7 @@
+ if (ret < 0)
+ return ret;
+
+- if (tmp & 0x00400000)
+- return -EIO;
+-
+- if (pcap_ts->read_state == COORDINATE) {
++ if (pcap_ts->read_state == COORDINATE && !(tmp & 0x00400000)) {
+ pcap_ts->x = (tmp & SSP_PCAP_ADD1_VALUE_MASK);
+ pcap_ts->y = (tmp & SSP_PCAP_ADD2_VALUE_MASK)
+ >>SSP_PCAP_ADD2_VALUE_SHIFT;
diff --git a/packages/linux/linux-ezx-2.6.21/wyrm-ts.diff b/packages/linux/linux-ezx-2.6.21/wyrm-ts.diff
new file mode 100644
index 0000000000..6e424c626c
--- /dev/null
+++ b/packages/linux/linux-ezx-2.6.21/wyrm-ts.diff
@@ -0,0 +1,124 @@
+Ignores read interrupts after penUP events until a penDOWN interrupt arrives.
+Some other changes i dont remember exactly. :)
+Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com>
+Index: linux-2.6.16/drivers/input/touchscreen/pcap_ts.c
+===================================================================
+--- linux-2.6.16.orig/drivers/input/touchscreen/pcap_ts.c 2007-03-09 21:26:25.000000000 -0300
++++ linux-2.6.16/drivers/input/touchscreen/pcap_ts.c 2007-03-09 21:26:42.000000000 -0300
+@@ -31,7 +31,7 @@
+
+ #include "../../misc/ezx/ssp_pcap.h"
+
+-#if 1
++#if 0
+ #define DEBUGP(x, args ...) printk(KERN_DEBUG "%s: " x, __FUNCTION__, ## args)
+ #else
+ #define DEBUGP(x, args ...)
+@@ -39,6 +39,7 @@
+
+ #define PRESSURE 1
+ #define COORDINATE 2
++#define STANDBY 3
+
+ struct pcap_ts {
+ int irq_xy;
+@@ -97,7 +98,7 @@
+ int ret;
+ u_int32_t tmp;
+ DEBUGP("start xy read in mode %s\n",
+- pcap_ts->read_state == COORDINATE ? "COORD" : "PRESS");
++ pcap_ts->read_state == COORDINATE ? "COORD" : (pcap_ts->read_state == PRESSURE ? "PRESS" : "STANDBY"));
+
+ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC1_REGISTER, &tmp);
+ if (ret < 0)
+@@ -122,7 +123,7 @@
+ u_int32_t tmp;
+
+ DEBUGP("get xy value in mode %s\n",
+- pcap_ts->read_state == COORDINATE ? "COORD" : "PRESS");
++ pcap_ts->read_state == COORDINATE ? "COORD" : (pcap_ts->read_state == PRESSURE ? "PRESS" : "STANDBY"));
+
+ ret = ezx_pcap_read(SSP_PCAP_ADJ_ADC2_REGISTER, &tmp);
+ if (ret < 0)
+@@ -145,7 +146,16 @@
+ static irqreturn_t pcap_ts_irq_xy(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ struct pcap_ts *pcap_ts = dev_id;
++// DEBUGP("read_state: %d\n", pcap_ts->read_state);
+
++ /*
++ * Ignore further read interrupts after we set STANDBY - WM
++ */
++ if (pcap_ts->read_state == STANDBY)
++ {
++ DEBUGP("ignored\n");
++ return IRQ_HANDLED;
++ }
+ if (pcap_ts_get_xy_value(pcap_ts) < 0) {
+ printk("pcap_ts: error reading XY value\n");
+ return IRQ_HANDLED;
+@@ -160,33 +170,32 @@
+ pcap_ts->pressure <= PRESSURE_MIN ) &&
+ pcap_ts->pressure == pcap_ts->pressure_last) {
+ /* pen has been released */
++ DEBUGP("UP\n");
+ input_report_key(pcap_ts->input, BTN_TOUCH, 0);
+- input_sync(pcap_ts->input);
+-
+ input_report_abs(pcap_ts->input, ABS_PRESSURE, 0);
++ input_sync(pcap_ts->input);
+
+ pcap_ts->x = pcap_ts->y = 0;
+
++ /* no need for timer, we'll get interrupted with
++ * next touch down event */
++ del_timer(&pcap_ts->timer);
++
+ /* ask PCAP2 to interrupt us if touch event happens
+ * again */
+- pcap_ts->read_state = PRESSURE;
++ pcap_ts->read_state = STANDBY;
+ pcap_ts_mode(PCAP_TS_STANDBY_MODE);
+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_MSR_TSM, 0);
+-
+- /* no need for timer, we'll get interrupted with
+- * next touch down event */
+- del_timer(&pcap_ts->timer);
+ } else {
+ /* pen has been touched down */
++ DEBUGP("DOWN\n");
++
+ input_report_key(pcap_ts->input, BTN_TOUCH, 1);
+ /* don't input_sync(), we don't know position yet */
+
+ if (pcap_ts->pressure == 0)
+ pcap_ts->pressure = pcap_ts->pressure_last;
+
+- input_report_abs(pcap_ts->input, ABS_PRESSURE,
+- pcap_ts->pressure);
+-
+ /* switch state machine into coordinate read mode */
+ pcap_ts->read_state = COORDINATE;
+ pcap_ts_mode(PCAP_TS_POSITION_XY_MEASUREMENT);
+@@ -196,18 +205,14 @@
+ /* we are in coordinate mode */
+ if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX ||
+ pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) {
+- DEBUGP("invalid x/y coordinate position: PEN_UP?\n");
+-
++ DEBUGP("PEN_UP?\n");
+ pcap_ts->pressure = 0;
+-#if 0
+- input_report_key(pcap_ts->input, BTN_TOUCH, 0);
+- pcap_ts->x = pcap_ts->y = 0;
+-#endif
+ } else {
++ input_report_abs(pcap_ts->input, ABS_PRESSURE, pcap_ts->pressure);
+ input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x);
+ input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y);
++ input_sync(pcap_ts->input);
+ }
+- input_sync(pcap_ts->input);
+
+ /* switch back to pressure read mode */
+ pcap_ts->read_state = PRESSURE;