Index: linux-2.6.11/drivers/input/keyboard/corgikbd.c
===================================================================
--- linux-2.6.11.orig/drivers/input/keyboard/corgikbd.c	2005-04-16 23:10:10.000000000 +0100
+++ linux-2.6.11/drivers/input/keyboard/corgikbd.c	2005-04-16 23:14:08.000000000 +0100
@@ -32,7 +32,6 @@
 /* zero code, 124 scancodes + 3 hinge combinations */
 #define	NR_SCANCODES		( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 )
 #define SCAN_INTERVAL		(HZ/10)
-#define CORGIKBD_PRESSED	1
 
 #define HINGE_SCAN_INTERVAL		(HZ/4)
 
@@ -73,26 +72,12 @@
 	struct input_dev input;
 	char phys[32];
 
-	unsigned char state[ARRAY_SIZE(corgikbd_keycode)];
 	spinlock_t lock;
 
 	struct timer_list timer;
 	struct timer_list htimer;
 };
 
-static void handle_scancode(unsigned int pressed,unsigned int scancode, struct corgikbd *corgikbd_data)
-{
-	if (pressed && !(corgikbd_data->state[scancode] & CORGIKBD_PRESSED)) {
-		corgikbd_data->state[scancode] |= CORGIKBD_PRESSED;
-		input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 1);
-		if (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
-			input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
-	} else if (!pressed && corgikbd_data->state[scancode] & CORGIKBD_PRESSED) {
-		corgikbd_data->state[scancode] &= ~CORGIKBD_PRESSED;
-		input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 0);
-	}
-}
-
 #define KB_DISCHARGE_DELAY	10
 #define KB_ACTIVATE_DELAY	10
 
@@ -105,36 +90,36 @@
  */
 static inline void corgikbd_discharge_all(void)
 {
-	// STROBE All HiZ
+	/* STROBE All HiZ */
 	GPCR2  = CORGI_GPIO_ALL_STROBE_BIT;
 	GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT;
 }
 
 static inline void corgikbd_activate_all(void)
 {
-	// STROBE ALL -> High
+	/* STROBE ALL -> High */
 	GPSR2  = CORGI_GPIO_ALL_STROBE_BIT;
 	GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT;
 
 	udelay(KB_DISCHARGE_DELAY);
 
-	// Clear any interrupts we may have triggered when altering the GPIO lines
+	/* Clear any interrupts we may have triggered when altering the GPIO lines */
 	GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT;
 	GEDR2 = CORGI_GPIO_LOW_SENSE_BIT;
 }
 
 static inline void corgikbd_activate_col(int col)
 {
-	// STROBE col -> High, not col -> HiZ
+	/* STROBE col -> High, not col -> HiZ */
 	GPSR2 = CORGI_GPIO_STROBE_BIT(col);
 	GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
 }
 
 static inline void corgikbd_reset_col(int col)
 {
-	// STROBE col -> Low
+	/* STROBE col -> Low */
 	GPCR2 = CORGI_GPIO_STROBE_BIT(col);
-	// STROBE col -> out, not col -> HiZ
+	/* STROBE col -> out, not col -> HiZ */
 	GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
 }
 
@@ -174,9 +159,14 @@
 		rowd = GET_ROWS_STATUS(col);
 		for (row = 0; row < KB_ROWS; row++) {
 			scancode = SCANCODE(row, col);
-			handle_scancode((rowd & KB_ROWMASK(row)), scancode, corgikbd_data);
-			if (rowd & KB_ROWMASK(row))
+			if (rowd & KB_ROWMASK(row)) {
+				input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 1);
 				num_pressed++;
+				if (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
+					input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
+			} else {
+				input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 0);
+			}
 		}
 		corgikbd_reset_col(col);
 	}
@@ -221,8 +211,11 @@
  * The hinge switches generate no interrupt so they need to be
  * monitored by a timer.
  *
- * When we detect changes, we debounce it and then pass the three
- * positions the system can take as keypresses to the input system.
+ * We debounce the switches and pass them to the input system.
+ *   
+ *  gprr == 0x00 - Keyboard with Landscape Screen
+ *          0x08 - No Keyboard with Portrait Screen
+ *          0x0c - Keyboard and Screen Closed
  */
 
 #define HINGE_STABLE_COUNT 2
@@ -235,7 +228,7 @@
 	unsigned long gprr;
 	unsigned long flags;
 
-	gprr = read_scoop_reg(SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB);
+	gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB);
 	if (gprr != sharpsl_hinge_state) {
 		hinge_count = 0;
 		sharpsl_hinge_state = gprr;
@@ -244,9 +237,8 @@
 		if (hinge_count >= HINGE_STABLE_COUNT) {
 			spin_lock_irqsave(&corgikbd_data->lock, flags);
 
-			handle_scancode((sharpsl_hinge_state == 0x00), 125, corgikbd_data); /* Keyboard with Landscape Screen */
-			handle_scancode((sharpsl_hinge_state == 0x08), 126, corgikbd_data); /* No Keyboard with Portrait Screen */
-			handle_scancode((sharpsl_hinge_state == 0x0c), 127, corgikbd_data); /* Keyboard and Screen Closed  */
+			input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
+			input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
 			input_sync(&corgikbd_data->input);
 
 			spin_unlock_irqrestore(&corgikbd_data->lock, flags);
@@ -288,7 +280,7 @@
 	corgikbd->input.id.vendor = 0x0001;
 	corgikbd->input.id.product = 0x0001;
 	corgikbd->input.id.version = 0x0100;
-	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR);
+	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
 	corgikbd->input.keycode = corgikbd->keycode;
 	corgikbd->input.keycodesize = sizeof(unsigned char);
 	corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
@@ -297,6 +289,8 @@
 	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
 		set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
 	clear_bit(0, corgikbd->input.keybit);
+	set_bit(SW_0, corgikbd->input.swbit);
+	set_bit(SW_1, corgikbd->input.swbit);
 
 	input_register_device(&corgikbd->input);
 	mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
Index: linux-2.6.11/drivers/input/evdev.c
===================================================================
--- linux-2.6.11.orig/drivers/input/evdev.c	2005-04-16 23:10:10.000000000 +0100
+++ linux-2.6.11/drivers/input/evdev.c	2005-04-16 23:16:02.000000000 +0100
@@ -390,6 +390,7 @@
 						case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
 						case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
 						case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
+						case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
 						default: return -EINVAL;
 					}
 					len = NBITS(len) * sizeof(long);
@@ -418,6 +419,13 @@
 					return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
 				}
 
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) {
+					int len;
+					len = NBITS(SW_MAX) * sizeof(long);
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
+				}
+
 				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
 					int len;
 					if (!dev->name) return -ENOENT;
Index: linux-2.6.11/drivers/input/input.c
===================================================================
--- linux-2.6.11.orig/drivers/input/input.c	2005-04-16 23:10:10.000000000 +0100
+++ linux-2.6.11/drivers/input/input.c	2005-04-16 23:14:08.000000000 +0100
@@ -95,6 +95,15 @@
 
 			break;
 
+		case EV_SW:
+
+			if (code > SW_MAX || !test_bit(code, dev->swbit) || !!test_bit(code, dev->sw) == value)
+				return;
+
+			change_bit(code, dev->sw);
+
+			break;
+
 		case EV_ABS:
 
 			if (code > ABS_MAX || !test_bit(code, dev->absbit))
@@ -407,6 +416,7 @@
 	SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
 	SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
 	SPRINTF_BIT_A2(ffbit,  "FF=",  FF_MAX, EV_FF);
+	SPRINTF_BIT_A2(swbit,  "SW=",  SW_MAX, EV_SW);
 
 	envp[i++] = NULL;
 
@@ -640,6 +650,7 @@
 		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
 		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
 		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
+		SPRINTF_BIT_B2(swbit,  "SW=",  SW_MAX, EV_SW);
 
 		len += sprintf(buf + len, "\n");
 
Index: linux-2.6.11/include/linux/input.h
===================================================================
--- linux-2.6.11.orig/include/linux/input.h	2005-04-16 23:10:12.000000000 +0100
+++ linux-2.6.11/include/linux/input.h	2005-04-16 23:14:08.000000000 +0100
@@ -66,6 +66,7 @@
 #define EVIOCGKEY(len)		_IOC(_IOC_READ, 'E', 0x18, len)		/* get global keystate */
 #define EVIOCGLED(len)		_IOC(_IOC_READ, 'E', 0x19, len)		/* get all LEDs */
 #define EVIOCGSND(len)		_IOC(_IOC_READ, 'E', 0x1a, len)		/* get all sounds status */
+#define EVIOCGSW(len)		_IOC(_IOC_READ, 'E', 0x1b, len)		/* get all switch states */
 
 #define EVIOCGBIT(ev,len)	_IOC(_IOC_READ, 'E', 0x20 + ev, len)	/* get event bits */
 #define EVIOCGABS(abs)		_IOR('E', 0x40 + abs, struct input_absinfo)		/* get abs value/limits */
@@ -86,6 +87,7 @@
 #define EV_REL			0x02
 #define EV_ABS			0x03
 #define EV_MSC			0x04
+#define EV_SW			0x05
 #define EV_LED			0x11
 #define EV_SND			0x12
 #define EV_REP			0x14
@@ -546,6 +548,20 @@
 #define ABS_MAX			0x3f
 
 /*
+ * Switch events
+ */
+
+#define SW_0		0x00
+#define SW_1		0x01
+#define SW_2		0x02
+#define SW_3		0x03
+#define SW_4		0x04
+#define SW_5		0x05
+#define SW_6		0x06
+#define SW_7		0x07
+#define SW_MAX		0x0f
+
+/*
  * Misc events
  */
 
@@ -819,6 +835,7 @@
 	unsigned long ledbit[NBITS(LED_MAX)];
 	unsigned long sndbit[NBITS(SND_MAX)];
 	unsigned long ffbit[NBITS(FF_MAX)];
+	unsigned long swbit[NBITS(SW_MAX)];
 	int ff_effects_max;
 
 	unsigned int keycodemax;
@@ -839,6 +856,7 @@
 	unsigned long key[NBITS(KEY_MAX)];
 	unsigned long led[NBITS(LED_MAX)];
 	unsigned long snd[NBITS(SND_MAX)];
+	unsigned long sw[NBITS(SW_MAX)];
 
 	int absmax[ABS_MAX + 1];
 	int absmin[ABS_MAX + 1];
@@ -881,6 +899,7 @@
 #define INPUT_DEVICE_ID_MATCH_LEDBIT	0x200
 #define INPUT_DEVICE_ID_MATCH_SNDBIT	0x400
 #define INPUT_DEVICE_ID_MATCH_FFBIT	0x800
+#define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
 
 #define INPUT_DEVICE_ID_MATCH_DEVICE\
 	(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
@@ -901,6 +920,7 @@
 	unsigned long ledbit[NBITS(LED_MAX)];
 	unsigned long sndbit[NBITS(SND_MAX)];
 	unsigned long ffbit[NBITS(FF_MAX)];
+	unsigned long swbit[NBITS(SW_MAX)];
 
 	unsigned long driver_info;
 };
@@ -993,6 +1013,11 @@
 	input_event(dev, EV_FF_STATUS, code, value);
 }
 
+static inline void input_report_switch(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_SW, code, !!value);
+}
+
 static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
 {
 	dev->regs = regs;

