#
# Patch managed by http://www.holgerschurig.de/patcher.html
#

--- linux-2.4.27/drivers/misc/switches.h~simpad-switches-input
+++ linux-2.4.27/drivers/misc/switches.h
@@ -25,4 +25,14 @@
 extern int  switches_ucb1x00_init(void);
 extern void switches_ucb1x00_exit(void);
 
+#ifdef CONFIG_SA1100_SIMPAD	
+#define SIMPAD_KEY_SUSPEND	0x0002
+#define SIMPAD_KEY_WWW		0x0008
+#define SIMPAD_KEY_ENTER	0x0010
+#define SIMPAD_KEY_UP		0x0020
+#define SIMPAD_KEY_DOWN		0x0040
+#define SIMPAD_KEY_LEFT		0x0080
+#define SIMPAD_KEY_RIGHT	0x0100
+#endif
+
 #endif  /* !defined(_SWITCHES_H) */
--- linux-2.4.27/drivers/misc/switches-core.c~simpad-switches-input
+++ linux-2.4.27/drivers/misc/switches-core.c
@@ -16,6 +16,9 @@
  *  11 September 2001 - UCB1200 driver framework support added.
  *
  *  19 December 2001 - separated out SA-1100 and UCB1x00 code.
+ *
+ *  3 July 2004 - Added generating of keyboard events. 
+ *                Florian Boor <florian@handhelds.org>
  */
 
 #include <linux/config.h>
@@ -30,7 +33,11 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 
+#include <linux/input.h>
+
 #include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/keyboard.h>
 
 #include "switches.h"
 
@@ -53,6 +60,19 @@
 DECLARE_WAIT_QUEUE_HEAD(switches_wait);
 LIST_HEAD(switches_event_queue);
 
+#ifdef CONFIG_INPUT
+static struct input_dev idev;
+	
+int 
+dummy_k_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
+{
+	*keycode = scancode;
+	return 1;
+}
+
+extern int (*k_translate)(unsigned char, unsigned char *, char);
+
+#endif
 
 static ssize_t switches_read(struct file *file, char *buffer,
 			     size_t count, loff_t *pos)
@@ -148,6 +168,31 @@
 {
 	struct switches_action *action;
 
+#ifdef CONFIG_INPUT
+	/* create input events, the events to send depends on the platform */
+#ifdef CONFIG_SA1100_SIMPAD	
+	if (machine_is_simpad()) {
+		if (SWITCHES_COUNT(mask) > 0)
+		{
+			if (mask->events[0] & SIMPAD_KEY_SUSPEND)
+				input_report_key(&idev, KEY_POWER, (mask->states[0] & SIMPAD_KEY_SUSPEND) ? 0 : 1);
+			if (mask->events[0] & SIMPAD_KEY_ENTER)
+				input_report_key(&idev, KEY_ENTER, (mask->states[0] & SIMPAD_KEY_ENTER) ? 1 : 0);
+			if (mask->events[0] & SIMPAD_KEY_UP)
+				input_report_key(&idev, KEY_UP, (mask->states[0] & SIMPAD_KEY_UP) ? 1 : 0);
+			if (mask->events[0] & SIMPAD_KEY_DOWN)
+				input_report_key(&idev, KEY_DOWN, (mask->states[0] & SIMPAD_KEY_DOWN) ? 1 : 0);
+			if (mask->events[0] & SIMPAD_KEY_LEFT)
+				input_report_key(&idev, KEY_LEFT, (mask->states[0] & SIMPAD_KEY_LEFT) ? 1 : 0);
+			if (mask->events[0] & SIMPAD_KEY_RIGHT)
+				input_report_key(&idev, KEY_RIGHT, (mask->states[0] & SIMPAD_KEY_RIGHT) ? 1 : 0);
+			if (mask->events[0] & SIMPAD_KEY_WWW)
+				input_report_key(&idev, KEY_F10, (mask->states[0] & SIMPAD_KEY_WWW) ? 1 : 0);
+		}
+	}
+#endif
+#endif
+	/* take care of switches device */
 	if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
 
 		if ((action = (struct switches_action *)
@@ -197,6 +242,21 @@
 		return -EIO;
 	}
 
+#ifdef CONFIG_INPUT
+	/* init input driver stuff */
+	k_translate = dummy_k_translate;
+	idev.evbit[0] = BIT(EV_KEY); /* handle key events */
+
+	idev.keybit[LONG(KEY_POWER)] |= BIT(KEY_POWER);
+	idev.keybit[LONG(KEY_UP)] |= BIT(KEY_UP);
+	idev.keybit[LONG(KEY_DOWN)] |= BIT(KEY_DOWN);
+	idev.keybit[LONG(KEY_LEFT)] |= BIT(KEY_LEFT);
+	idev.keybit[LONG(KEY_RIGHT)] |= BIT(KEY_RIGHT);
+	idev.keybit[LONG(KEY_ENTER)] |= BIT(KEY_ENTER);
+	idev.keybit[LONG(KEY_F10)] |= BIT(KEY_F10);
+
+	input_register_device(&idev);
+#endif	
 	printk("Console switches initialized\n");
 
 	return 0;
@@ -214,6 +274,10 @@
 	switches_ucb1x00_exit();
 #endif
 
+#ifdef CONFIG_INPUT
+	input_unregister_device(&idev);
+#endif
+	
 	if (misc_deregister(&switches_misc) < 0)
 		printk(KERN_ERR "%s: unable to deregister misc device\n",
 		       SWITCHES_NAME);