linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vojtech Pavlik <vojtech@suse.cz>
To: akpm@osdl.org, dtor_core@ameritech.net, petero2@telia.com,
	Andries.Brouwer@cwi.nl, linux-kernel@vger.kernel.org
Subject: [PATCH 5/8] Rely less on sanity of AT keyboards.
Date: Thu, 25 Sep 2003 18:50:12 +0200	[thread overview]
Message-ID: <10645086121089@twilight.ucw.cz> (raw)
In-Reply-To: <10645086122209@twilight.ucw.cz>

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

===================================================================

ChangeSet@1.1345, 2003-09-25 18:26:39+02:00, vojtech@suse.cz
  input: Change AT keyboard to use hardware autorepeat and move
         untranslating to the AT keyboard driver as well. Lower
         PS/2 mouse default report rate. Fix repeat rate adjustment
         ioctls accordingly, and update other files to reflect the
         changes. This should fix most known keyboard problems in 2.6.


 drivers/char/keyboard.c            |   14 --
 drivers/input/evdev.c              |   10 -
 drivers/input/input.c              |   32 ++++--
 drivers/input/keyboard/atkbd.c     |  194 +++++++++++++++++++++++++++----------
 drivers/input/mouse/psmouse-base.c |   25 +++-
 drivers/input/serio/i8042.c        |   51 ---------
 include/linux/input.h              |    2 
 include/linux/serio.h              |    1 
 8 files changed, 193 insertions(+), 136 deletions(-)

===================================================================

diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/char/keyboard.c	Thu Sep 25 18:37:20 2003
@@ -264,12 +264,6 @@
 /*
  * Setting the keyboard rate.
  */
-static inline unsigned int ms_to_jiffies(unsigned int ms) {
-	unsigned int j;
-
-	j = (ms * HZ + 500) / 1000;
-	return (j > 0) ? j : 1;
-}
 
 int kbd_rate(struct kbd_repeat *rep)
 {
@@ -283,11 +277,11 @@
 
 		if (test_bit(EV_REP, dev->evbit)) {
 			if (rep->delay > 0)
-				dev->rep[REP_DELAY] = ms_to_jiffies(rep->delay);
+				input_event(dev, EV_REP, REP_DELAY, rep->delay);
 			if (rep->period > 0)
-				dev->rep[REP_PERIOD] = ms_to_jiffies(rep->period);
-			d = dev->rep[REP_DELAY]  * 1000 / HZ;
-			p = dev->rep[REP_PERIOD] * 1000 / HZ;
+				input_event(dev, EV_REP, REP_PERIOD, rep->period);
+			d = dev->rep[REP_DELAY];
+			p = dev->rep[REP_PERIOD];
 		}
 	}
 	rep->delay  = d;
diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c
--- a/drivers/input/evdev.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/input/evdev.c	Thu Sep 25 18:37:20 2003
@@ -220,16 +220,6 @@
 		case EVIOCGID:
 			return copy_to_user((void *) arg, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
 		
-		case EVIOCGREP:
-			if (put_user(dev->rep[0], ((int *) arg) + 0)) return -EFAULT;
-			if (put_user(dev->rep[1], ((int *) arg) + 1)) return -EFAULT;
-			return 0;
-
-		case EVIOCSREP:
-			if (get_user(dev->rep[0], ((int *) arg) + 0)) return -EFAULT;
-			if (get_user(dev->rep[1], ((int *) arg) + 1)) return -EFAULT;
-			return 0;
-
 		case EVIOCGKEYCODE:
 			if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
 			if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/input/input.c	Thu Sep 25 18:37:20 2003
@@ -55,6 +55,13 @@
 static int input_devices_state;
 #endif
 
+static inline unsigned int ms_to_jiffies(unsigned int ms)
+{
+        unsigned int j;
+        j = (ms * HZ + 500) / 1000;
+        return (j > 0) ? j : 1;
+}
+
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -93,9 +100,9 @@
 
 			change_bit(code, dev->key);
 
-			if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && value) {
+			if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && dev->timer.data && value) {
 				dev->repeat_key = code;
-				mod_timer(&dev->timer, jiffies + dev->rep[REP_DELAY]);
+				mod_timer(&dev->timer, jiffies + ms_to_jiffies(dev->rep[REP_DELAY]));
 			}
 
 			break;
@@ -162,7 +169,7 @@
 
 		case EV_REP:
 
-			if (code > REP_MAX || dev->rep[code] == value) return;
+			if (code > REP_MAX || value < 0 || dev->rep[code] == value) return;
 
 			dev->rep[code] = value;
 			if (dev->event) dev->event(dev, type, code, value);
@@ -195,7 +202,7 @@
 	input_event(dev, EV_KEY, dev->repeat_key, 2);
 	input_sync(dev);
 
-	mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]);
+	mod_timer(&dev->timer, jiffies + ms_to_jiffies(dev->rep[REP_PERIOD]));
 }
 
 int input_accept_process(struct input_handle *handle, struct file *file)
@@ -423,13 +430,18 @@
 
 	set_bit(EV_SYN, dev->evbit);
 
+	/*
+	 * If delay and period are pre-set by the driver, then autorepeating
+	 * is handled by the driver itself and we don't do it in input.c.
+	 */
+
 	init_timer(&dev->timer);
-	dev->timer.data = (long) dev;
-	dev->timer.function = input_repeat_key;
-	if (!dev->rep[REP_DELAY])
-		dev->rep[REP_DELAY] = HZ/4;
-	if (!dev->rep[REP_PERIOD])
-		dev->rep[REP_PERIOD] = HZ/33;
+	if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
+		dev->timer.data = (long) dev;
+		dev->timer.function = input_repeat_key;
+		dev->rep[REP_DELAY] = 250;
+		dev->rep[REP_PERIOD] = 33;
+	}
 
 	INIT_LIST_HEAD(&dev->h_list);
 	list_add_tail(&dev->node, &input_dev_list);
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/input/keyboard/atkbd.c	Thu Sep 25 18:37:20 2003
@@ -10,6 +10,13 @@
  * the Free Software Foundation.
  */
 
+/*
+ * This driver can handle standard AT keyboards and PS/2 keyboards in
+ * Translated and Raw Set 2 and Set 3, as well as AT keyboards on dumb
+ * input-only controllers and AT keyboards connected over a one way RS232
+ * converter.
+ */
+
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -24,6 +31,7 @@
 MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
 MODULE_PARM(atkbd_set, "1i");
 MODULE_PARM(atkbd_reset, "1i");
+MODULE_PARM(atkbd_softrepeat, "1i");
 MODULE_LICENSE("GPL");
 
 static int atkbd_set = 2;
@@ -32,6 +40,7 @@
 #else
 static int atkbd_reset = 1;
 #endif
+static int atkbd_softrepeat;
 
 /*
  * Scancode to keycode tables. These are just the default setting, and
@@ -47,19 +56,19 @@
 	122, 89, 40,120, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0,  0,
 	 85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121,  0,123,
 	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-	252,  0,  0, 65, 99,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0, 65, 99,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,251,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	252,253,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,
 	  0,  0, 92, 90, 85,  0,137,  0,  0,  0,  0, 91, 89,144,115,  0,
 	217,100,255,  0, 97,165,164,  0,156,  0,  0,140,115,  0,  0,125,
 	173,114,  0,113,152,163,151,126,128,166,  0,140,  0,147,  0,127,
 	159,167,115,160,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
-	157,  0,114,166,168,  0,  0,  0,155,  0, 98,113,  0,163,  0,138,
+	157,  0,114,166,168,  0,  0,213,155,  0, 98,113,  0,163,  0,138,
 	226,  0,  0,  0,  0,  0,153,140,  0,255, 96,  0,  0,  0,143,  0,
 	133,  0,116,  0,143,  0,174,133,  0,107,  0,105,102,  0,  0,112,
 	110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119
@@ -76,12 +85,23 @@
 	 82, 83, 80, 76, 77, 72, 69, 98,  0, 96, 81,  0, 78, 73, 55, 85,
 	 89, 90, 91, 92, 74,185,184,182,  0,  0,  0,125,126,127,112,  0,
 	  0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168,
-	148,149,147,140,  0,  0,  0,  0,  0,  0,251,  0,  0,  0,  0,  0,
+	148,149,147,140,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	252,253,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255
+};
+
+static unsigned char atkbd_unxlate_table[128] = {
+	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
+	 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
+	 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
+	 11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
+	114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
+	 71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+	 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
 };
 
 #define ATKBD_CMD_SETLEDS	0x10ed
@@ -99,12 +119,13 @@
 
 #define ATKBD_RET_ACK		0xfa
 #define ATKBD_RET_NAK		0xfe
+#define ATKBD_RET_BAT		0xaa
+#define ATKBD_RET_EMUL0		0xe0
+#define ATKBD_RET_EMULX		0x80
+#define ATKBD_RET_EMUL1		0xe1
+#define ATKBD_RET_RELEASE	0xf0
 
 #define ATKBD_KEY_UNKNOWN	  0
-#define ATKBD_KEY_BAT		251
-#define ATKBD_KEY_EMUL0		252
-#define ATKBD_KEY_EMUL1		253
-#define ATKBD_KEY_RELEASE	254
 #define ATKBD_KEY_NULL		255
 
 /*
@@ -127,7 +148,11 @@
 	unsigned char emul;
 	unsigned short id;
 	unsigned char write;
+	unsigned char translated;
 	unsigned char resend;
+	unsigned char bat_xl;
+	unsigned int last;
+	unsigned long time;
 };
 
 /*
@@ -139,7 +164,8 @@
 			unsigned int flags, struct pt_regs *regs)
 {
 	struct atkbd *atkbd = serio->private;
-	int code = data;
+	unsigned int code = data;
+	int value;
 
 #ifdef ATKBD_DEBUG
 	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
@@ -153,10 +179,38 @@
 		goto out;
 	}
 	
-	if (!flags)
+	if (!flags && data == ATKBD_RET_ACK)
 		atkbd->resend = 0;
 #endif
 
+	if (atkbd->translated) do {
+
+		if (atkbd->emul != 1) {
+			if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
+			    code == ATKBD_RET_ACK || code == ATKBD_RET_NAK)
+				break;
+			if (code == ATKBD_RET_BAT) {
+				if (!atkbd->bat_xl)
+					break;
+				atkbd->bat_xl = 0;
+			}
+			if (code == (ATKBD_RET_BAT & 0x7f))
+				atkbd->bat_xl = 1;
+		}
+
+		if (code < 0x80) {
+			code = atkbd_unxlate_table[code];
+			break;
+		}
+
+		if (atkbd->cmdcnt)
+			break;
+
+		code = atkbd_unxlate_table[code & 0x7f];
+		atkbd->release = 1;
+
+	} while (0);
+
 	switch (code) {
 		case ATKBD_RET_ACK:
 			atkbd->ack = 1;
@@ -171,17 +225,17 @@
 		goto out;
 	}
 
-	switch (atkbd->keycode[code]) {
-		case ATKBD_KEY_BAT:
+	switch (code) {
+		case ATKBD_RET_BAT:
 			serio_rescan(atkbd->serio);
 			goto out;
-		case ATKBD_KEY_EMUL0:
+		case ATKBD_RET_EMUL0:
 			atkbd->emul = 1;
 			goto out;
-		case ATKBD_KEY_EMUL1:
+		case ATKBD_RET_EMUL1:
 			atkbd->emul = 2;
 			goto out;
-		case ATKBD_KEY_RELEASE:
+		case ATKBD_RET_RELEASE:
 			atkbd->release = 1;
 			goto out;
 	}
@@ -196,21 +250,31 @@
 		case ATKBD_KEY_NULL:
 			break;
 		case ATKBD_KEY_UNKNOWN:
-			printk(KERN_WARNING "atkbd.c: Unknown key (set %d, scancode %#x, on %s) %s.\n",
-				atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
+			printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x, data %#x, on %s).\n",
+				atkbd->release ? "released" : "pressed",
+				atkbd->translated ? "translated" : "raw", 
+				atkbd->set, code, data, serio->phys);
 			break;
 		default:
-#if 0
-			if (!atkbd->release) {
-				mod_timer(&atkbd->timer,
-					jiffies + (test_bit(atkbd->keycode[code],
-						atkbd->dev.key) ? HZ/33 : HZ/4) + HZ/100);
-				atkbd->lastkey = atkbd->keycode[code];
+			value = atkbd->release ? 0 :
+				(1 + (!atkbd_softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
+
+			switch (value) { 	/* Workaround Toshiba laptop multiple keypress */
+				case 0:
+					atkbd->last = 0;
+					break;
+				case 1:
+					atkbd->last = code;
+					atkbd->time = jiffies + (atkbd->dev.rep[REP_DELAY] * HZ + 500) / 1000 / 2;
+					break;
+				case 2:
+					if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
+						value = 1;
+					break;
 			}
-#endif
 
 			input_regs(&atkbd->dev, regs);
-			input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
+			input_event(&atkbd->dev, EV_KEY, atkbd->keycode[code], value);
 			input_sync(&atkbd->dev);
 	}
 
@@ -219,13 +283,6 @@
 	return IRQ_HANDLED;
 }
 
-static void atkbd_force_key_up(unsigned long data)
-{
-	struct atkbd *atkbd = (void *) data;
-	input_report_key(&atkbd->dev, atkbd->lastkey, 0);
-	input_sync(&atkbd->dev);
-}
-
 /*
  * atkbd_sendbyte() sends a byte to the keyboard, and waits for
  * acknowledge. It doesn't handle resends according to the keyboard
@@ -312,7 +369,12 @@
 static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct atkbd *atkbd = dev->private;
+	struct { int p; u8 v; } period[] =	
+		{ {30, 0x00}, {25, 0x02}, {20, 0x04}, {15, 0x08}, {10, 0x0c}, {7, 0x10}, {5, 0x14}, {0, 0x14} };
+	struct { int d; u8 v; } delay[] =
+        	{ {1000, 0x60}, {750, 0x40}, {500, 0x20}, {250, 0x00}, {0, 0x00} };
 	char param[2];
+	int i, j;
 
 	if (!atkbd->write)
 		return -1;
@@ -337,6 +399,21 @@
 			}
 
 			return 0;
+
+
+		case EV_REP:
+
+			if (atkbd_softrepeat) return 0;
+
+			i = j = 0;
+			while (period[i].p > dev->rep[REP_PERIOD]) i++;
+			while (delay[j].d > dev->rep[REP_DELAY]) j++;
+			dev->rep[REP_PERIOD] = period[i].p;
+			dev->rep[REP_DELAY] = delay[j].d;
+			param[0] = period[i].v | delay[j].v;
+			atkbd_command(atkbd, param, ATKBD_CMD_SETREP);
+
+			return 0;
 	}
 
 	return -1;
@@ -405,6 +482,9 @@
  * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards.
  */
 
+	if (atkbd->translated)
+		return 2;
+
 	if (atkbd->id == 0xaca1) {
 		param[0] = 3;
 		atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET);
@@ -434,8 +514,11 @@
 	if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
 		return 2;
 
-	if (param[0] != 3)
+	if (param[0] != 3) {
+		param[0] = 2;
+		if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
 		return 2;
+	}
 
 	return 3;
 }
@@ -508,25 +591,35 @@
 	struct atkbd *atkbd;
 	int i;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
-		(((serio->type & SERIO_TYPE) != SERIO_RS232) || (serio->type & SERIO_PROTO) != SERIO_PS2SER))
-		        return;
-
 	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
 		return;
-
 	memset(atkbd, 0, sizeof(struct atkbd));
 
-	if ((serio->type & SERIO_TYPE) == SERIO_8042 && serio->write)
-		atkbd->write = 1;
+	switch (serio->type & SERIO_TYPE) {
 
+		case SERIO_8042_XL: 
+			atkbd->translated = 1;
+		case SERIO_8042:
+			if (serio->write)
+				atkbd->write = 1;
+			break;
+		case SERIO_RS232:
+			if ((serio->type & SERIO_PROTO) == SERIO_PS2SER)
+				break;
+		default:
+			kfree(atkbd);
+			return;
+	}
+			
 	if (atkbd->write) {
 		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
 		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
 	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
 
-	atkbd->dev.rep[REP_DELAY] = HZ/4 + HZ/50;
-	atkbd->dev.rep[REP_PERIOD] = HZ/33;
+	if (!atkbd_softrepeat) {
+		atkbd->dev.rep[REP_DELAY] = 250;
+		atkbd->dev.rep[REP_PERIOD] = 33;
+	}
 
 	atkbd->serio = serio;
 
@@ -540,10 +633,6 @@
 
 	serio->private = atkbd;
 
-	init_timer(&atkbd->timer);
-	atkbd->timer.data = (long) atkbd;
-	atkbd->timer.function = atkbd_force_key_up;
-
 	if (serio_open(serio, dev)) {
 		kfree(atkbd);
 		return;
@@ -569,7 +658,8 @@
 		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
 		sprintf(atkbd->name, "AT Set 2 Extended keyboard");
 	} else
-		sprintf(atkbd->name, "AT Set %d keyboard", atkbd->set);
+		sprintf(atkbd->name, "AT %s Set %d keyboard",
+			atkbd->translated ? "Translated" : "Raw", atkbd->set);
 
 	sprintf(atkbd->phys, "%s/input0", serio->phys);
 
@@ -586,7 +676,7 @@
 	atkbd->dev.id.version = atkbd->id;
 
 	for (i = 0; i < 512; i++)
-		if (atkbd->keycode[i] && atkbd->keycode[i] <= 250)
+		if (atkbd->keycode[i] && atkbd->keycode[i] < 255)
 			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
 
 	input_register_device(&atkbd->dev);
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/input/mouse/psmouse-base.c	Thu Sep 25 18:37:20 2003
@@ -28,6 +28,8 @@
 MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
 MODULE_PARM(psmouse_resolution, "i");
 MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+MODULE_PARM(psmouse_rate, "i");
+MODULE_PARM_DESC(psmouse_rate, "Report rate, in reports per second.");
 MODULE_PARM(psmouse_smartscroll, "i");
 MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 MODULE_PARM(psmouse_resetafter, "i");
@@ -38,6 +40,7 @@
 
 static int psmouse_noext;
 int psmouse_resolution;
+unsigned int psmouse_rate = 60;
 int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
 unsigned int psmouse_resetafter;
 
@@ -443,22 +446,32 @@
 }
 
 /*
+ * Here we set the mouse report rate.
+ */
+
+static void psmouse_set_rate(struct psmouse *psmouse)
+{
+	unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+	int i = 0;
+
+	while (rates[i] > psmouse_rate) i++;
+	psmouse_command(psmouse, rates + i, PSMOUSE_CMD_SETRATE);
+}
+
+/*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
 
 static void psmouse_initialize(struct psmouse *psmouse)
 {
 	unsigned char param[2];
+	
 
 /*
- * We set the mouse report rate to a highest possible value.
- * We try 100 first in case mouse fails to set 200.
+ * We set the mouse report rate.
  */
-	param[0] = 100;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 
-	param[0] = 200;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	psmouse_set_rate(psmouse);
 
 /*
  * We also set the resolution and scaling.
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Sep 25 18:37:20 2003
+++ b/drivers/input/serio/i8042.c	Thu Sep 25 18:37:20 2003
@@ -58,8 +58,6 @@
 static struct serio i8042_aux_port;
 static unsigned char i8042_initial_ctr;
 static unsigned char i8042_ctr;
-static unsigned char i8042_last_e0;
-static unsigned char i8042_last_release;
 static unsigned char i8042_mux_open;
 struct timer_list i8042_timer;
 
@@ -69,18 +67,6 @@
  */
 #define i8042_request_irq_cookie (&i8042_timer)
 
-static unsigned long i8042_unxlate_seen[256 / BITS_PER_LONG];
-static unsigned char i8042_unxlate_table[128] = {
-	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
-	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
-	 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
-	 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
-	 11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
-	114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
-	 71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
-	 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-};
-
 static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /*
@@ -301,7 +287,7 @@
 
 static struct serio i8042_kbd_port =
 {
-	.type =		SERIO_8042,
+	.type =		SERIO_8042_XL,
 	.write =	i8042_kbd_write,
 	.open =		i8042_open,
 	.close =	i8042_close,
@@ -400,39 +386,10 @@
 		if (!i8042_kbd_values.exists)
 			continue;
 
-		if (i8042_direct) {
-			serio_interrupt(&i8042_kbd_port, data, dfl, regs);
-			continue;
-		}
-
-		if (data > 0x7f) {
-			unsigned char index = (data & 0x7f) | (i8042_last_e0 << 7);
-			/* work around hardware that doubles key releases */
-			if (index == i8042_last_release) {
-				dbg("i8042 skipped double release (%d)\n", index);
-				i8042_last_e0 = 0;
-				continue;
-			}
-			if (index == 0xaa || index == 0xb6)
-				set_bit(index, i8042_unxlate_seen);
-			if (test_and_clear_bit(index, i8042_unxlate_seen)) {
-				serio_interrupt(&i8042_kbd_port, 0xf0, dfl, regs);
-				data = i8042_unxlate_table[data & 0x7f];
-				i8042_last_release = index;
-			}
-		} else {
-			set_bit(data | (i8042_last_e0 << 7), i8042_unxlate_seen);
-			data = i8042_unxlate_table[data];
-			i8042_last_release = 0;
-		}
-
-		i8042_last_e0 = (data == 0xe0);
-
 		serio_interrupt(&i8042_kbd_port, data, dfl, regs);
 	}
 
-	/* FIXME - was it really ours? */
-	return IRQ_HANDLED;
+	return IRQ_RETVAL(j);
 }
 
 /*
@@ -511,8 +468,10 @@
  * BIOSes.
  */
 
-	if (i8042_direct)
+	if (i8042_direct) {
 		i8042_ctr &= ~I8042_CTR_XLATE;
+		i8042_kbd_port.type = SERIO_8042;
+	}
 
 /*
  * Write CTR back.
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	Thu Sep 25 18:37:20 2003
+++ b/include/linux/input.h	Thu Sep 25 18:37:20 2003
@@ -56,8 +56,6 @@
 
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
 #define EVIOCGID		_IOR('E', 0x02, struct input_id)	/* get device ID */
-#define EVIOCGREP		_IOR('E', 0x03, int[2])			/* get repeat settings */
-#define EVIOCSREP		_IOW('E', 0x03, int[2])			/* get repeat settings */
 #define EVIOCGKEYCODE		_IOR('E', 0x04, int[2])			/* get keycode */
 #define EVIOCSKEYCODE		_IOW('E', 0x04, int[2])			/* set keycode */
 
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Sep 25 18:37:20 2003
+++ b/include/linux/serio.h	Thu Sep 25 18:37:20 2003
@@ -107,6 +107,7 @@
 #define SERIO_HIL_MLC	0x03000000UL
 #define SERIO_PC9800	0x04000000UL
 #define SERIO_PS_PSTHRU	0x05000000UL
+#define SERIO_8042_XL	0x06000000UL
 
 #define SERIO_PROTO	0xFFUL
 #define SERIO_MSC	0x01


  reply	other threads:[~2003-09-25 16:53 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-25 16:48 My current patches Vojtech Pavlik
2003-09-25 16:50 ` [PATCH 1/8] Revert synaptics->pktcnt change Vojtech Pavlik
2003-09-25 16:50   ` [PATCH 2/8] Fix multibutton handling in synaptics.c Vojtech Pavlik
2003-09-25 16:50     ` [PATCH 3/8] Synaptics code cleanups Vojtech Pavlik
2003-09-25 16:50       ` [PATCH 4/8] Add touchpad support to mousedev.c Vojtech Pavlik
2003-09-25 16:50         ` Vojtech Pavlik [this message]
2003-09-25 16:50           ` [PATCH 6/8] Extend KD?BENT to handle > 256 keycodes Vojtech Pavlik
2003-09-25 16:50             ` [PATCH 7/8] Fix handling of rotated Synaptics touchpads Vojtech Pavlik
2003-09-25 16:50               ` [PATCH 8/8] Add BTN_TOUCH to Synaptics driver. Update mousedev Vojtech Pavlik
2003-09-25 18:23                 ` Dmitry Torokhov
2003-09-25 22:30                   ` Vojtech Pavlik
2003-09-26  5:24                     ` Peter Osterlund
2003-09-26  7:24                     ` Dmitry Torokhov
2003-09-26  7:54                       ` Vojtech Pavlik
2003-09-27  1:58                         ` Dmitry Torokhov
2003-09-27 20:19                         ` Pavel Machek
2003-09-27 21:05                           ` Vojtech Pavlik
2003-09-27 21:09                             ` Pavel Machek
2003-09-27 21:16                               ` Vojtech Pavlik
2003-09-27 21:18                                 ` Pavel Machek
2003-09-27 21:21                                   ` Vojtech Pavlik
2003-09-27 21:58                                     ` Matt Gibson
2003-09-28  9:49                                       ` Vojtech Pavlik
2003-09-25 22:57             ` [PATCH 6/8] Extend KD?BENT to handle > 256 keycodes Andrew Morton
2003-09-25 23:21               ` Vojtech Pavlik
2003-09-25 23:38             ` Andries Brouwer
2003-09-26  6:20               ` Vojtech Pavlik
2003-10-05 15:12           ` [PATCH 5/8] Rely less on sanity of AT keyboards Martin Josefsson
2003-09-25 18:13 ` My current patches Peter Osterlund

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=10645086121089@twilight.ucw.cz \
    --to=vojtech@suse.cz \
    --cc=Andries.Brouwer@cwi.nl \
    --cc=akpm@osdl.org \
    --cc=dtor_core@ameritech.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=petero2@telia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).