diff -urN -X /home/arm/dontdiff_tml_arm /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/char/keyboard_psion.c linux-2.4.19-rmk2/drivers/char/keyboard_psion.c
diff -urN -X /home/arm/dontdiff_tml_arm /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/char/keyboard_psion.c linux-2.4.19-rmk2/drivers/char/keyboard_psion.c
--- /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/char/keyboard_psion.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.19-rmk2/drivers/char/keyboard_psion.c	2002-10-02 22:07:30.000000000 -0700
@@ -0,0 +1,337 @@
+/*
+ * arch/arm/drivers/char/keyboard_psion.c - Keyboard Driver for Psion
+ *
+ * Copyright (C) 1998 Roger Gammans
+ * Copyright (C) 2001 Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/arch/keyboard.h>
+#include <linux/tqueue.h>
+#include <linux/kbd_ll.h>
+#include <linux/tty_flip.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/hardware/psionw.h>
+#include "keyboard_psion.h"
+
+/* callback function for auto sleep */
+void (*psion_sleep_set_callback)(void);
+
+extern void psionw_lcd_powerdown(int lock);
+extern void psionw_lcd_powerup(int lock);
+
+unsigned int kbd_delay[] = KB_DELAY;
+static int keysdown = 0;
+static struct tq_struct kbdhw_task;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char kbdpsion_sysrq_xlate[] =
+    "\000" "6"	  "5"	 "4"	"3"    "2"    "1"    "\000"
+    "\000" "'"	  "\000" "0"	"9"    "8"    "7"    "\000"
+    "\000" "y"	  "t"	 "r"	"e"    "w"    "q"    "\000"
+    "\000" "\012" "l"	 "p"	"o"    "i"    "u"    "\000"
+    "\000" "g"	  "f"	 "d"	"s"    "a"    "\011" "\000"
+    "\000" "\000" "."	 "m"	"k"    "j"    "h"    "\000"
+    "\000" "n"	  "b"	 "v"	"c"    "x"    "z"    "\000"
+    "\000" "\000" "\000" ","	"\000" " "    "\000";
+#endif
+
+void psion_cleartable(void) 
+{
+	int key;
+	unsigned int t;
+
+	for (key = 0; key < NR_KEYCODES; key++) {
+		if (!kbdstate[key].in)
+			continue;
+
+		/*
+		 * dont worry these ops are commutative and
+		 * assoicative 
+		 */
+		t = (jiffies - kbdstate[key].jif) & KB_JIFMASK; 
+		if (t>KB_DEB_JIFFY) {
+
+			/* Keboard could have changed meanwhile */
+			kbdstate[key].in = 0;
+			keysdown--;
+			/* printk("Releasing key:%x\n",key); */
+			handle_scancode(key, 0);
+		}
+	}
+}
+
+static void kbd_press(int keycode)
+{
+	unsigned char newpress = 0;
+
+	if (!kbdstate[keycode].in) {
+		keysdown++; 
+		newpress = 1;
+		/* printk("Keycode: %d (0x%x)\n", keycode, keycode); */
+	}
+
+	/*
+	 * We approximate a retriggable monostable
+	 * action.
+	 */
+	kbdstate[keycode].in=1;
+
+	/* We only need to ensure keysdown consistent */
+	kbdstate[keycode].jif = jiffies & KB_JIFMASK;
+	if (newpress) {
+		handle_scancode(keycode, 1);
+		if (psion_sleep_set_callback != 0)
+			(*psion_sleep_set_callback)();
+	}
+}
+
+static void psion_tick(void* dummy)
+{
+	int col,row;
+	int rowd;
+	int count=0;
+	unsigned char state;
+
+	/*
+	 * Check if any keys are depressed
+	 */
+	for (col = 0; col < 8; col++) {
+		udelay(kbd_delay[8]);
+		state =	 psionw_readl(KSCAN);
+		state &= ~KBDSCAN;
+		state |= (KBSC_COL0 + col);
+		psionw_writel(state, KSCAN);
+		udelay(kbd_delay[col]);
+		rowd = psionw_readl(PADR) & 0xff;
+		if (!rowd)
+			continue;
+		for (row=0; row < KB_LASTROW; row++) {
+			if (rowd & KB_ROWMASK(row)) {
+				kbd_press(KEYCODE(row,col));
+				count++;
+			}
+		}
+	};
+ 
+	if (count != keysdown) {
+		psion_cleartable();
+	}
+
+	/*
+	 * Re-queue ourselves
+	 */
+	queue_task(&kbdhw_task,&tq_timer);
+}
+
+void kbdpsion_hw_init(void)
+{ 
+	kbdhw_task.routine = psion_tick;
+	kbdhw_task.sync = 0;
+	queue_task(&kbdhw_task,&tq_timer);
+}
+
+int kbdpsion_translate(unsigned char scancode, unsigned char *keycode_p)
+{
+	*keycode_p = scancode & ~(KBDOWN | KBUP);
+	return 1;
+}
+
+#if defined(CONFIG_VT) && defined(CONFIG_MAGIC_SYSRQ)
+extern int sysrq_pressed;
+#endif
+
+void psion_arch_handler(unsigned char value, char up_flag)
+{
+#if defined(CONFIG_VT) && defined(CONFIG_MAGIC_SYSRQ)
+	if (value == 1) {
+		sysrq_pressed = !up_flag;
+		return;
+	}
+#endif
+	if (up_flag) return;
+	switch (value) {
+
+#ifdef KBD_ARCHKEY_2
+		case 2:
+			KBD_ARCHKEY_2;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_3
+		case 3:
+			KBD_ARCHKEY_3;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_4
+		case 4:
+			KBD_ARCHKEY_4;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_5
+		case 5:
+			KBD_ARCHKEY_5;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_6
+		case 6:
+			KBD_ARCHKEY_6;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_7
+		case 7:
+			KBD_ARCHKEY_7;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_8
+		case 8:
+			KBD_ARCHKEY_8;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_9
+		case 9:
+			KBD_ARCHKEY_9;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_10
+		case 10:
+			KBD_ARCHKEY_10;
+			break;
+#endif
+#ifdef KBD_ARCHKEY_11
+		case 11:
+			KBD_ARCHKEY_11;
+			break;
+#endif
+
+		default:
+			return;
+	}
+}
+
+void psion_toggle_backlight()
+{
+	int pcdr;
+	long flags;
+
+	if ((psionw_readl(LCDCTL) & LCDCTL_EN) == 0)
+		psionw_lcd_powerup(1);
+
+	save_flags_cli(flags);
+	pcdr = psionw_readl(PCDR);
+	pcdr ^= PCDR_LIGHT;
+	psionw_writel(pcdr, PCDR);
+	restore_flags(flags);
+}
+
+/*
+ * Contrast table. Upper four bits: output value, lower four bits: direction
+ * (0 = in = Z)
+ */
+#define V0 0
+#define V1 1
+#define VZ 0
+#define D0 1
+#define D1 1
+#define DZ 0
+
+#define C(a,b,c,d) \
+	((V##a << 7) | (V##b << 6) | (V##c << 5) | (V##d << 4) | \
+	(D##a << 3) | (D##b << 2) | (D##c << 1) | D##d)
+    
+static __u8 contrast_table[] = {
+	C(1,1,1,1), C(1,1,1,Z), C(1,1,1,0), C(1,1,Z,1),	/*  1- 4 */
+	C(1,1,Z,Z), C(1,1,0,1), C(1,1,Z,0), C(1,Z,1,1),	/*  5- 8 */
+	C(1,1,0,0), C(1,Z,1,Z), C(1,Z,1,0), C(1,Z,Z,1),	/*  9-12 */
+	C(1,0,1,1), C(1,Z,Z,Z), C(1,Z,0,1), C(1,0,1,Z),	/* 13-16 */
+	C(1,0,1,0), C(1,0,Z,1), C(1,Z,0,0), C(Z,1,1,Z),	/* 17-20 */
+	C(1,0,Z,Z), C(1,0,0,1), C(1,0,Z,0), C(1,0,0,Z),	/* 21-24 */
+	C(Z,1,Z,Z), C(1,0,0,0), C(Z,1,Z,0), C(Z,1,0,Z),	/* 25-28 */
+	C(Z,1,0,0), C(Z,Z,1,Z), C(Z,Z,1,0), C(Z,Z,Z,1),	/* 29-32 */
+	C(0,1,1,0), C(0,1,Z,1), C(Z,Z,0,1), C(Z,0,1,Z),	/* 33-36 */
+	C(0,1,Z,Z), C(Z,Z,0,Z), C(0,1,Z,0), C(Z,Z,0,0),	/* 37-40 */
+	C(0,1,0,Z), C(Z,0,Z,Z), C(0,1,0,0), C(Z,0,Z,0),	/* 41-44 */
+	C(0,Z,1,0), C(0,Z,Z,1), C(Z,0,0,0), C(0,0,1,1),	/* 45-48 */
+	C(0,Z,Z,Z), C(0,Z,0,1), C(0,Z,Z,0), C(0,0,1,0),	/* 49-52 */
+	C(0,0,Z,1), C(0,Z,0,0), C(0,0,Z,Z), C(0,0,0,1),	/* 53-56 */
+	C(0,0,Z,0), C(0,0,0,Z), C(0,0,0,0)		/* 57-60 */
+};
+
+static int contrast = 40;
+
+int psion_get_contrast(void)
+{
+	return contrast;
+}
+
+int psion_set_contrast(int new_contrast, int lock)
+{
+	long flags = 0;
+
+	if ((new_contrast >= 0) && (new_contrast < sizeof(contrast_table))) {
+		contrast = new_contrast;
+	}
+	else {
+		printk("Bad contrast value: %i, should be between 0 - %d\n",
+		       new_contrast, sizeof(contrast_table) - 1);
+		return -EINVAL;
+	}
+
+	if (lock)
+		save_flags_cli(flags);
+
+        psionw_writeb((psionw_readb(PBDR) & ~PBDR_VLD_MASK) |
+                      ((contrast_table[contrast] >> 4) << PBDR_VLD_SHIFT),
+                      PBDR);
+        psionw_writeb((psionw_readb(PBDDR) & ~PBDR_VLD_MASK) |
+                      ((contrast_table[contrast] & 0xf) << PBDR_VLD_SHIFT),
+                      PBDDR);
+
+	if (lock)
+		restore_flags(flags);
+
+	return 0;
+}
+
+void psion_contrast(int increase)
+{
+
+	if (increase)
+		if (contrast == sizeof(contrast_table)-1) return;
+		else contrast++;
+	else if (!contrast) return;
+	else contrast--;
+
+	psion_set_contrast(contrast, 1);
+}
+
+void debug_gpio(void)
+{
+	printk("\nPADR=0x%02x PBDR=0x%02x PCDR=0x%02x PDDR=0x%02x PEDR=0x%02x ",
+	       psionw_readb(PADR),
+	       psionw_readb(PBDR),
+	       psionw_readb(PCDR),
+	       psionw_readb(PDDR),
+	       psionw_readb(PEDR));
+
+	printk("PADDR=0x%02x PBDDR=0x%02x\n",
+	       psionw_readb(PADDR),
+	       psionw_readb(PBDDR));
+}
