summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Pavlik <vojtech@suse.cz>2004-02-09 11:54:13 +0100
committerVojtech Pavlik <vojtech@suse.cz>2004-02-09 11:54:13 +0100
commitdd394d1a89f59dd50158876ebbb28c896adc3691 (patch)
treebf6010602989ba4e8f2e35a1fab49085cd614187
parenta6eebfd5c5e94e2d94a672407795e2d1a9045315 (diff)
parentdca0c12169b479611a4e75fc1d542ad4f70c4f35 (diff)
Manual merge.
-rw-r--r--Documentation/kernel-parameters.txt13
-rw-r--r--Documentation/usb/acm.txt8
-rw-r--r--arch/arm26/Kconfig5
-rw-r--r--drivers/char/Kconfig24
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/input/gameport/ns558.c35
-rw-r--r--drivers/input/keyboard/Kconfig1
-rw-r--r--drivers/input/keyboard/atkbd.c132
-rw-r--r--drivers/input/keyboard/hpps2atkbd.h174
-rw-r--r--drivers/input/keyboard/sunkbd.c22
-rw-r--r--drivers/input/misc/Kconfig9
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/gsc_ps2.c712
-rw-r--r--drivers/input/mouse/Kconfig1
-rw-r--r--drivers/input/serio/Kconfig16
-rw-r--r--drivers/input/serio/Makefile1
-rw-r--r--drivers/input/serio/gscps2.c470
-rw-r--r--drivers/input/serio/i8042.c3
-rw-r--r--drivers/usb/input/hid-core.c63
-rw-r--r--drivers/usb/input/hid-input.c7
-rw-r--r--drivers/usb/input/hiddev.c79
-rw-r--r--drivers/usb/input/wacom.c4
-rw-r--r--include/linux/hiddev.h74
-rw-r--r--include/linux/miscdevice.h1
24 files changed, 859 insertions, 997 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 28ad9de65a29..1e539053a107 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -174,11 +174,18 @@ running once the system is up.
atascsi= [HW,SCSI] Atari SCSI
- atkbd.set= [HW] Select keyboard code set
- Format: <int>
+ atkbd.extra= [HW] Enable extra LEDs and keys on IBM RapidAccess, EzKey
+ and similar keyboards
+
+ atkbd.reset= [HW] Reset keyboard during initialization
+
+ atkbd.set= [HW] Select keyboard code set
+ Format: <int> (2 = AT (default) 3 = PS/2)
+
+ atkbd.scroll= [HW] Enable scroll wheel on MS Office and similar keyboards
+
atkbd.softrepeat=
[HW] Use software keyboard repeat
- atkbd.reset= [HW] Reset keyboard during initialization
autotest [IA64]
diff --git a/Documentation/usb/acm.txt b/Documentation/usb/acm.txt
index e4fced658923..8ef45ea8f691 100644
--- a/Documentation/usb/acm.txt
+++ b/Documentation/usb/acm.txt
@@ -28,7 +28,7 @@ in the package: See the file COPYING.
1. Usage
~~~~~~~~
- The drivers/usb/acm.c drivers works with USB modems and USB ISDN terminal
+ The drivers/usb/class/cdc-acm.c drivers works with USB modems and USB ISDN terminal
adapters that conform to the Universal Serial Bus Communication Device Class
Abstract Control Model (USB CDC ACM) specification.
@@ -65,9 +65,9 @@ minor/major numbers anywhere you want, but either the above location or
To use the modems you need these modules loaded:
- usbcore.o
- usb-[uo]hci.o or uhci.o
- acm.o
+ usbcore.ko
+ uhci-hcd.ko ohci-hcd.ko or ehci-hcd.ko
+ cdc-acm.ko
After that, the modem[s] should be accessible. You should be able to use
minicom, ppp and mgetty with them.
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 05a9a2e55667..2862f0afa2cb 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -216,11 +216,6 @@ source "drivers/input/Kconfig"
source "drivers/char/Kconfig"
-config KBDMOUSE
- bool
- depends on ARCH_ACORN && BUSMOUSE=y
- default y
-
source "drivers/media/Kconfig"
source "fs/Kconfig"
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 811395acf4e6..1b49d61528fd 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -588,30 +588,6 @@ config PC9800_OLDLP_CONSOLE
bool "Support for console on line printer"
depends on PC9800_OLDLP
-
-menu "Mice"
-
-config BUSMOUSE
- tristate "Bus Mouse Support"
- ---help---
- Say Y here if your machine has a bus mouse as opposed to a serial
- mouse. Most people have a regular serial MouseSystem or
- Microsoft mouse (made by Logitech) that plugs into a COM port
- (rectangular with 9 or 25 pins). These people say N here.
-
- If you have a laptop, you either have to check the documentation or
- experiment a bit to find out whether the trackball is a serial mouse
- or not; it's best to say Y here for you.
-
- This is the generic bus mouse driver code. If you have a bus mouse,
- you will have to say Y here and also to the specific driver for your
- mouse below.
-
- To compile this driver as a module, choose M here: the
- module will be called busmouse.
-
-endmenu
-
config QIC02_TAPE
tristate "QIC-02 tape support"
help
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 302afc35f077..5fd3cad7f104 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
obj-$(CONFIG_PC9800_OLDLP) += lp_old98.o
-obj-$(CONFIG_BUSMOUSE) += busmouse.o
obj-$(CONFIG_DTLK) += dtlk.o
obj-$(CONFIG_R3964) += n_r3964.o
obj-$(CONFIG_APPLICOM) += applicom.o
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index c3de56ebe194..e85706281d37 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -77,7 +77,7 @@ static void ns558_isa_probe(int io)
* No one should be using this address.
*/
- if (check_region(io, 1))
+ if (!request_region(io, 1, "ns558-isa"))
return;
/*
@@ -89,7 +89,8 @@ static void ns558_isa_probe(int io)
outb(~c & ~3, io);
if (~(u = v = inb(io)) & 3) {
outb(c, io);
- return;
+ i = 0;
+ goto out;
}
/*
* After a trigger, there must be at least some bits changing.
@@ -99,7 +100,8 @@ static void ns558_isa_probe(int io)
if (u == v) {
outb(c, io);
- return;
+ i = 0;
+ goto out;
}
wait_ms(3);
/*
@@ -110,7 +112,8 @@ static void ns558_isa_probe(int io)
for (i = 0; i < 1000; i++)
if ((u ^ inb(io)) & 0xf) {
outb(c, io);
- return;
+ i = 0;
+ goto out;
}
/*
* And now find the number of mirrors of the port.
@@ -118,7 +121,9 @@ static void ns558_isa_probe(int io)
for (i = 1; i < 5; i++) {
- if (check_region(io & (-1 << i), (1 << i))) /* Don't disturb anyone */
+ release_region(io & (-1 << (i-1)), (1 << (i-1)));
+
+ if (!request_region(io & (-1 << i), (1 << i), "ns558-isa")) /* Don't disturb anyone */
break;
outb(0xff, io & (-1 << i));
@@ -126,18 +131,25 @@ static void ns558_isa_probe(int io)
if (inb(io & (-1 << i)) != inb((io & (-1 << i)) + (1 << i) - 1)) b++;
wait_ms(3);
- if (b > 300) /* We allow 30% difference */
+ if (b > 300) { /* We allow 30% difference */
+ release_region(io & (-1 << i), (1 << i));
break;
+ }
}
i--;
+ if (i != 4) {
+ if (!request_region(io & (-1 << i), (1 << i), "ns558-isa"))
+ return;
+ }
+
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
- return;
+ goto out;
}
- memset(port, 0, sizeof(struct ns558));
-
+ memset(port, 0, sizeof(struct ns558));
+
port->type = NS558_ISA;
port->size = (1 << i);
port->gameport.io = io;
@@ -148,8 +160,6 @@ static void ns558_isa_probe(int io)
sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i));
sprintf(port->name, "NS558 ISA");
- request_region(io & (-1 << i), (1 << i), "ns558-isa");
-
gameport_register_port(&port->gameport);
printk(KERN_INFO "gameport: NS558 ISA at %#x", port->gameport.io);
@@ -157,6 +167,9 @@ static void ns558_isa_probe(int io)
printk(" speed %d kHz\n", port->gameport.speed);
list_add(&port->node, &ns558_list);
+ return;
+out:
+ release_region(io & (-1 << i), (1 << i));
}
#ifdef CONFIG_PNP
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index d385e4e208df..142b96c58a36 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -17,6 +17,7 @@ config KEYBOARD_ATKBD
depends on INPUT && INPUT_KEYBOARD
select SERIO
select SERIO_I8042 if PC
+ select SERIO_GSCPS2 if GSC
help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
you'll need this, unless you have a different type keyboard (USB, ADB
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 3c9106d87065..e1e52dbdbff4 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -37,14 +37,13 @@ MODULE_LICENSE("GPL");
static int atkbd_set = 2;
module_param_named(set, atkbd_set, int, 0);
-MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3, 4)");
+MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)");
+
#if defined(__i386__) || defined(__x86_64__) || defined(__hppa__)
static int atkbd_reset;
#else
static int atkbd_reset = 1;
#endif
-static int atkbd_softrepeat;
-
module_param_named(reset, atkbd_reset, bool, 0);
MODULE_PARM_DESC(reset, "Reset keyboard during initialization");
@@ -52,6 +51,14 @@ static int atkbd_softrepeat;
module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
+static int atkbd_scroll;
+module_param_named(scroll, atkbd_scroll, bool, 0);
+MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
+
+static int atkbd_extra;
+module_param_named(extra, atkbd_extra, bool, 0);
+MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
+
/*
* Scancode to keycode tables. These are just the default setting, and
* are loadable via an userland utility.
@@ -127,11 +134,11 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_CMD_EX_SETLEDS 0x20eb
#define ATKBD_CMD_OK_GETID 0x02e8
+
#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_RET_HANGUEL 0xf1
@@ -141,6 +148,22 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_KEY_UNKNOWN 0
#define ATKBD_KEY_NULL 255
+#define ATKBD_SCR_1 254
+#define ATKBD_SCR_2 253
+#define ATKBD_SCR_4 252
+#define ATKBD_SCR_8 251
+#define ATKBD_SCR_CLICK 250
+
+#define ATKBD_SPECIAL 250
+
+static unsigned char atkbd_scroll_keys[5][2] = {
+ { ATKBD_SCR_1, 0x45 },
+ { ATKBD_SCR_2, 0x29 },
+ { ATKBD_SCR_4, 0x36 },
+ { ATKBD_SCR_8, 0x27 },
+ { ATKBD_SCR_CLICK, 0x60 },
+};
+
/*
* The atkbd control structure
*/
@@ -155,6 +178,7 @@ struct atkbd {
unsigned char cmdbuf[4];
unsigned char cmdcnt;
unsigned char set;
+ unsigned char extra;
unsigned char release;
int lastkey;
volatile signed char ack;
@@ -189,6 +213,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
{
struct atkbd *atkbd = serio->private;
unsigned int code = data;
+ int scroll = 0, click = -1;
int value;
#ifdef ATKBD_DEBUG
@@ -284,6 +309,21 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
else
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f);
break;
+ case ATKBD_SCR_1:
+ scroll = 1 - atkbd->release * 2;
+ break;
+ case ATKBD_SCR_2:
+ scroll = 2 - atkbd->release * 4;
+ break;
+ case ATKBD_SCR_4:
+ scroll = 4 - atkbd->release * 8;
+ break;
+ case ATKBD_SCR_8:
+ scroll = 8 - atkbd->release * 16;
+ break;
+ case ATKBD_SCR_CLICK:
+ click = !atkbd->release;
+ break;
default:
value = atkbd->release ? 0 :
(1 + (!atkbd_softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
@@ -305,6 +345,13 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
}
+ if (scroll || click != -1) {
+ input_regs(&atkbd->dev, regs);
+ input_report_key(&atkbd->dev, BTN_MIDDLE, click);
+ input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
+ input_sync(&atkbd->dev);
+ }
+
atkbd->release = 0;
out:
return IRQ_HANDLED;
@@ -420,7 +467,7 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
| (test_bit(LED_CAPSL, dev->led) ? 4 : 0);
atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS);
- if (atkbd->set == 4) {
+ if (atkbd->extra) {
param[0] = 0;
param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
| (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0)
@@ -529,21 +576,22 @@ static int atkbd_set_3(struct atkbd *atkbd)
return 3;
}
- if (atkbd_set != 2)
- if (!atkbd_command(atkbd, param, ATKBD_CMD_OK_GETID)) {
- atkbd->id = param[0] << 8 | param[1];
+ if (atkbd_extra) {
+ param[0] = 0x71;
+ if (!atkbd_command(atkbd, param, ATKBD_CMD_EX_ENABLE)) {
+ atkbd->extra = 1;
return 2;
}
-
- if (atkbd_set == 4) {
- param[0] = 0x71;
- if (!atkbd_command(atkbd, param, ATKBD_CMD_EX_ENABLE))
- return 4;
}
if (atkbd_set != 3)
return 2;
+ if (!atkbd_command(atkbd, param, ATKBD_CMD_OK_GETID)) {
+ atkbd->id = param[0] << 8 | param[1];
+ return 2;
+ }
+
param[0] = 3;
if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
return 2;
@@ -696,24 +744,32 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->id = 0xab00;
}
- if (atkbd->set == 4) {
+ if (atkbd->extra) {
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");
+ sprintf(atkbd->name, "AT Set 2 Extra keyboard");
} else
sprintf(atkbd->name, "AT %s Set %d keyboard",
atkbd->translated ? "Translated" : "Raw", atkbd->set);
sprintf(atkbd->phys, "%s/input0", serio->phys);
+ if (atkbd_scroll) {
+ for (i = 0; i < 5; i++)
+ atkbd_set2_keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0];
+ atkbd->dev.evbit[0] |= BIT(EV_REL);
+ atkbd->dev.relbit[0] = BIT(REL_WHEEL);
+ set_bit(BTN_MIDDLE, atkbd->dev.keybit);
+ }
+
if (atkbd->translated) {
for (i = 0; i < 128; i++) {
atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
}
- } else if (atkbd->set == 2) {
- memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
- } else {
+ } else if (atkbd->set == 3) {
memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
+ } else {
+ memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
}
atkbd->dev.name = atkbd->name;
@@ -724,7 +780,7 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->dev.id.version = atkbd->id;
for (i = 0; i < 512; i++)
- if (atkbd->keycode[i] && atkbd->keycode[i] < 255)
+ if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
set_bit(atkbd->keycode[i], atkbd->dev.keybit);
input_register_device(&atkbd->dev);
@@ -741,46 +797,20 @@ static int atkbd_reconnect(struct serio *serio)
{
struct atkbd *atkbd = serio->private;
struct serio_dev *dev = serio->dev;
- int i;
- if (!dev) {
- printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
- return -1;
- }
+ if (!dev) {
+ printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
+ return -1;
+ }
if (atkbd->write) {
if (atkbd_probe(atkbd))
return -1;
-
- atkbd->set = atkbd_set_3(atkbd);
+ if (atkbd->set != atkbd_set_3(atkbd))
+ return -1;
atkbd_enable(atkbd);
- } else {
- atkbd->set = 2;
- atkbd->id = 0xab00;
- }
-
- /*
- * Here we probably should check if the keyboard has the same set that
- * it had before and bail out if it's different. But this will most likely
- * cause new keyboard device be created... and for the user it will look
- * like keyboard is lost
- */
-
- if (atkbd->translated) {
- for (i = 0; i < 128; i++) {
- atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
- atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
- }
- } else if (atkbd->set == 2) {
- memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
- } else {
- memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
}
- for (i = 0; i < 512; i++)
- if (atkbd->keycode[i] && atkbd->keycode[i] < 255)
- set_bit(atkbd->keycode[i], atkbd->dev.keybit);
-
return 0;
}
diff --git a/drivers/input/keyboard/hpps2atkbd.h b/drivers/input/keyboard/hpps2atkbd.h
index 2086ff7945d7..92f6e8b98b40 100644
--- a/drivers/input/keyboard/hpps2atkbd.h
+++ b/drivers/input/keyboard/hpps2atkbd.h
@@ -4,14 +4,9 @@
* Copyright (c) 2004 Helge Deller <deller@gmx.de>
* Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
* Copyright (c) 2002 Thibaut Varene <varenet@esiee.fr>
+ * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
*
- * based on linux-2.4's hp_mouse.c & hp_keyb.c
- * Copyright (c) 1999 Alex deVries <adevries@thepuffingroup.com>
- * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
- * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
- *
- * HP PS/2 AT-compatible Keyboard, found in PA/RISC Workstations
+ * HP PS/2 AT-compatible Keyboard, found in PA/RISC Workstations & Laptops
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -19,87 +14,100 @@
*/
-#define KBD_UNKNOWN 0
-
-/* Raw SET 2 scancode table */
+/* undefine if you have a RDI PRECISIONBOOK */
+#define STANDARD_KEYBOARD
-#if 0
- /* conflicting keys between a RDI Precisionbook keyboard and a normal HP keyboard */
- keytable[0x07] = KEY_F1; /* KEY_F12 */
- keytable[0x11] = KEY_LEFTCTRL; /* KEY_LEFTALT */
- keytable[0x14] = KEY_CAPSLOCK; /* KEY_LEFTCTRL */
- keytable[0x61] = KEY_LEFT; /* KEY_102ND */
+#if defined(STANDARD_KEYBOARD)
+# define CONFLICT(x,y) x
+#else
+# define CONFLICT(x,y) y
#endif
+/* sadly RDI (Tadpole) decided to ship a different keyboard layout
+ than HP for their PS/2 laptop keyboard which leads to conflicting
+ keycodes between a normal HP PS/2 keyboard and a RDI Precisionbook.
+ HP: RDI: */
+#define C_07 CONFLICT( KEY_F12, KEY_F1 )
+#define C_11 CONFLICT( KEY_LEFTALT, KEY_LEFTCTRL )
+#define C_14 CONFLICT( KEY_LEFTCTRL, KEY_CAPSLOCK )
+#define C_58 CONFLICT( KEY_CAPSLOCK, KEY_RIGHTCTRL )
+#define C_61 CONFLICT( KEY_102ND, KEY_LEFT )
+
+/* Raw SET 2 scancode table */
-static unsigned char atkbd_set2_keycode[512] = {
+/* 00 */ KEY_RESERVED, KEY_F9, KEY_RESERVED, KEY_F5, KEY_F3, KEY_F1, KEY_F2, C_07,
+/* 08 */ KEY_ESC, KEY_F10, KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_GRAVE, KEY_F2,
+/* 10 */ KEY_RESERVED, C_11, KEY_LEFTSHIFT, KEY_RESERVED, C_14, KEY_Q, KEY_1, KEY_F3,
+/* 18 */ KEY_RESERVED, KEY_LEFTALT, KEY_Z, KEY_S, KEY_A, KEY_W, KEY_2, KEY_F4,
+/* 20 */ KEY_RESERVED, KEY_C, KEY_X, KEY_D, KEY_E, KEY_4, KEY_3, KEY_F5,
+/* 28 */ KEY_RESERVED, KEY_SPACE, KEY_V, KEY_F, KEY_T, KEY_R, KEY_5, KEY_F6,
+/* 30 */ KEY_RESERVED, KEY_N, KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, KEY_F7,
+/* 38 */ KEY_RESERVED, KEY_RIGHTALT, KEY_M, KEY_J, KEY_U, KEY_7, KEY_8, KEY_F8,
+/* 40 */ KEY_RESERVED, KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, KEY_9, KEY_F9,
+/* 48 */ KEY_RESERVED, KEY_DOT, KEY_SLASH, KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_F10,
+/* 50 */ KEY_RESERVED, KEY_RESERVED, KEY_APOSTROPHE,KEY_RESERVED, KEY_LEFTBRACE, KEY_EQUAL, KEY_F11, KEY_SYSRQ,
+/* 58 */ C_58, KEY_RIGHTSHIFT,KEY_ENTER, KEY_RIGHTBRACE,KEY_BACKSLASH, KEY_BACKSLASH,KEY_F12, KEY_SCROLLLOCK,
+/* 60 */ KEY_DOWN, C_61, KEY_PAUSE, KEY_UP, KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT,
+/* 68 */ KEY_RESERVED, KEY_KP1, KEY_RIGHT, KEY_KP4, KEY_KP7, KEY_PAGEDOWN, KEY_HOME, KEY_PAGEUP,
+/* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
+/* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_103RD,
+/* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 90 */ KEY_RESERVED, KEY_RIGHTALT, KEY_SYSRQ, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_CAPSLOCK, KEY_RESERVED, KEY_LEFTMETA,
+/* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTMETA,
+/* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_COMPOSE,
+/* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPSLASH, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPENTER, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* e8 */ KEY_RESERVED, KEY_END, KEY_RESERVED, KEY_LEFT, KEY_HOME, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* f0 */ KEY_INSERT, KEY_DELETE, KEY_DOWN, KEY_RESERVED, KEY_RIGHT, KEY_UP, KEY_RESERVED, KEY_PAUSE,
+/* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_PAGEDOWN, KEY_RESERVED, KEY_SYSRQ, KEY_PAGEUP, KEY_RESERVED, KEY_RESERVED,
- /* 00 */ KBD_UNKNOWN, KEY_F9, KBD_UNKNOWN, KEY_F5, KEY_F3, KEY_F1, KEY_F2, KEY_F1,
- /* 08 */ KEY_ESC, KEY_F10, KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_GRAVE, KEY_F2,
- /* 10 */ KBD_UNKNOWN, KEY_LEFTCTRL, KEY_LEFTSHIFT, KBD_UNKNOWN, KEY_CAPSLOCK, KEY_Q, KEY_1, KEY_F3,
- /* 18 */ KBD_UNKNOWN, KEY_LEFTALT, KEY_Z, KEY_S, KEY_A, KEY_W, KEY_2, KEY_F4,
- /* 20 */ KBD_UNKNOWN, KEY_C, KEY_X, KEY_D, KEY_E, KEY_4, KEY_3, KEY_F5,
- /* 28 */ KBD_UNKNOWN, KEY_SPACE, KEY_V, KEY_F, KEY_T, KEY_R, KEY_5, KEY_F6,
- /* 30 */ KBD_UNKNOWN, KEY_N, KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, KEY_F7,
- /* 38 */ KBD_UNKNOWN, KEY_RIGHTALT, KEY_M, KEY_J, KEY_U, KEY_7, KEY_8, KEY_F8,
- /* 40 */ KBD_UNKNOWN, KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, KEY_9, KEY_F9,
- /* 48 */ KBD_UNKNOWN, KEY_DOT, KEY_SLASH, KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_F10,
- /* 50 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_APOSTROPHE,KBD_UNKNOWN, KEY_LEFTBRACE, KEY_EQUAL, KEY_F11, KEY_SYSRQ,
- /* 58 */ KEY_CAPSLOCK, KEY_RIGHTSHIFT,KEY_ENTER, KEY_RIGHTBRACE,KEY_BACKSLASH, KEY_BACKSLASH,KEY_F12, KEY_SCROLLLOCK,
- /* 60 */ KEY_DOWN, KEY_LEFT, KEY_PAUSE, KEY_UP, KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT,
- /* 68 */ KBD_UNKNOWN, KEY_KP1, KEY_RIGHT, KEY_KP4, KEY_KP7, KEY_PAGEDOWN, KEY_HOME, KEY_PAGEUP,
- /* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
- /* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_103RD,
- /* 80 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 88 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 90 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 98 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
+/* These are offset for escaped keycodes: */
- /* These are offset for escaped keycodes: */
+/* 00 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_F7, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 08 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 10 */ KEY_RESERVED, KEY_RIGHTALT, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 18 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 20 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 28 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 30 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 38 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 40 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 48 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 50 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 58 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 60 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 68 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 70 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 78 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 90 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* e8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* f0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+/* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
- /* 00 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KEY_F7, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 08 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KEY_LEFTMETA, KEY_RIGHTMETA, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 10 */ KBD_UNKNOWN, KEY_RIGHTALT, KBD_UNKNOWN, KBD_UNKNOWN, KEY_RIGHTCTRL, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 18 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 20 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 28 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 30 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 38 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 40 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 48 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_KPSLASH, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 50 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 58 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_KPENTER, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 60 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 68 */ KBD_UNKNOWN, KEY_END, KBD_UNKNOWN, KEY_LEFT, KEY_HOME, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 70 */ KEY_INSERT, KEY_DELETE, KEY_DOWN, KBD_UNKNOWN, KEY_RIGHT, KEY_UP, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 78 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_PAGEDOWN, KBD_UNKNOWN, KEY_SYSRQ, KEY_PAGEUP, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 80 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 88 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 90 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 98 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN
+#undef STANDARD_KEYBOARD
+#undef CONFLICT
+#undef C_07
+#undef C_11
+#undef C_14
+#undef C_58
+#undef C_61
-};
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index fafab609b45d..d2f70364a8c2 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -77,6 +77,7 @@ struct sunkbd {
struct input_dev dev;
struct serio *serio;
struct work_struct tq;
+ wait_queue_head_t wait;
char name[64];
char phys[32];
char type;
@@ -96,11 +97,13 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
if (sunkbd->reset <= -1) { /* If cp[i] is 0xff, sunkbd->reset will stay -1. */
sunkbd->reset = data; /* The keyboard sends 0xff 0xff 0xID on powerup */
+ wake_up_interruptible(&sunkbd->wait);
goto out;
}
if (sunkbd->layout == -1) {
sunkbd->layout = data;
+ wake_up_interruptible(&sunkbd->wait);
goto out;
}
@@ -176,22 +179,19 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
static int sunkbd_initialize(struct sunkbd *sunkbd)
{
- int t;
-
- t = 1000;
sunkbd->reset = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
- while (sunkbd->reset < 0 && --t) mdelay(1);
- if (!t) return -1;
+ wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
+ if (sunkbd->reset <0)
+ return -1;
sunkbd->type = sunkbd->reset;
if (sunkbd->type == 4) { /* Type 4 keyboard */
- t = 250;
sunkbd->layout = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
- while (sunkbd->layout < 0 && --t) mdelay(1);
- if (!t) return -1;
+ wait_event_interruptible_timeout(sunkbd->wait, sunkbd->layout >= 0, HZ/4);
+ if (sunkbd->layout < 0) return -1;
if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) sunkbd->type = 5;
}
@@ -206,9 +206,8 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
static void sunkbd_reinit(void *data)
{
struct sunkbd *sunkbd = data;
- int t = 1000;
- while (sunkbd->reset < 0 && --t) mdelay(1);
+ wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
@@ -239,6 +238,7 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
memset(sunkbd, 0, sizeof(struct sunkbd));
init_input_dev(&sunkbd->dev);
+ init_waitqueue_head(&sunkbd->wait);
sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
@@ -275,7 +275,7 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
clear_bit(0, sunkbd->dev.keybit);
- sprintf(sunkbd->name, "%s/input", serio->phys);
+ sprintf(sunkbd->phys, "%s/input0", serio->phys);
sunkbd->dev.name = sunkbd->name;
sunkbd->dev.phys = sunkbd->phys;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 16008a3eee8a..347660ca16f9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -54,12 +54,3 @@ config INPUT_UINPUT
To compile this driver as a module, choose M here: the
module will be called uinput.
-config INPUT_GSC
- tristate "PA-RISC GSC PS/2 keyboard/mouse support"
- depends on GSC && INPUT && INPUT_MISC
- help
- Say Y here if you have a PS/2 keyboard and/or mouse attached
- to your PA-RISC box. HP run the keyboard in AT mode rather than
- XT mode like everyone else, so we need our own driver.
- Furthermore, the GSC PS/2 controller shares IRQ between mouse and
- keyboard.
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 3dd91a1f968b..82e5de21939d 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -9,4 +9,3 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-obj-$(CONFIG_INPUT_GSC) += gsc_ps2.o
diff --git a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c
deleted file mode 100644
index c16c98c2f02d..000000000000
--- a/drivers/input/misc/gsc_ps2.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * drivers/input/misc/gsc_ps2.c
- *
- * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
- * Copyright (c) 2002 Thibaut Varene <varenet@esiee.fr>
- *
- * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
- * Copyright (c) 1999 Alex deVries <adevries@thepuffingroup.com>
- * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
- * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
- *
- * HP PS/2 Keyboard, found in PA/RISC Workstations
- * very similar to AT keyboards, but without i8042
- *
- * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * STATUS:
- * 11/09: lc: Only basic keyboard is supported, mouse still needs to be done.
- * 11/12: tv: switching iomapping; cleaning code; improving module stuff.
- * 11/13: lc & tv: leds aren't working. auto_repeat/meta are. Generaly good behavior.
- * 11/15: tv: 2AM: leds ARE working !
- * 11/16: tv: 3AM: escaped keycodes emulation *handled*, some keycodes are
- * still deliberately ignored (18), what are they used for ?
- * 11/21: lc: mouse is now working
- * 11/29: tv: first try for error handling in init sequence
- *
- * TODO:
- * Error handling in init sequence
- * SysRq handling
- * Pause key handling
- * Intellimouse & other rodents handling (at least send an error when
- * such a mouse is plugged : it will totally fault)
- * Mouse: set scaling / Dino testing
- * Bug chasing...
- *
- */
-
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ptrace.h> /* interrupt.h wants struct pt_regs defined */
-#include <linux/interrupt.h>
-#include <linux/sched.h> /* for request_irq/free_irq */
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/kd.h>
-#include <linux/pci_ids.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/parisc-device.h>
-
-/* Debugging stuff */
-#undef KBD_DEBUG
-#ifdef KBD_DEBUG
- #define DPRINTK(fmt,args...) printk(KERN_DEBUG __FILE__ ":" fmt, ##args)
-#else
- #define DPRINTK(x,...)
-#endif
-
-
-/*
- * Driver constants
- */
-
-/* PS/2 keyboard and mouse constants */
-#define AUX_RECONNECT 0xAA /* PS/2 Mouse end of test successful */
-#define AUX_REPLY_ACK 0xFA
-#define AUX_ENABLE_DEV 0xF4 /* Enables aux device */
-
-/* Order of the mouse bytes coming to the host */
-#define PACKET_X 1
-#define PACKET_Y 2
-#define PACKET_CTRL 0
-
-#define GSC_MOUSE_OFFSET 0x0100 /* offset from keyboard to mouse port */
-#define GSC_DINO_OFFSET 0x800 /* offset for DINO controller versus LASI one */
-
-#define GSC_ID 0x00 /* ID and reset port offsets */
-#define GSC_RESET 0x00
-#define GSC_RCVDATA 0x04 /* receive and transmit port offsets */
-#define GSC_XMTDATA 0x04
-#define GSC_CONTROL 0x08 /* see: control register bits */
-#define GSC_STATUS 0x0C /* see: status register bits */
-
-/* Control register bits */
-#define GSC_CTRL_ENBL 0x01 /* enable interface */
-#define GSC_CTRL_LPBXR 0x02 /* loopback operation */
-#define GSC_CTRL_DIAG 0x20 /* directly control clock/data line */
-#define GSC_CTRL_DATDIR 0x40 /* data line direct control */
-#define GSC_CTRL_CLKDIR 0x80 /* clock line direct control */
-
-/* Status register bits */
-#define GSC_STAT_RBNE 0x01 /* Receive Buffer Not Empty */
-#define GSC_STAT_TBNE 0x02 /* Transmit Buffer Not Empty */
-#define GSC_STAT_TERR 0x04 /* Timeout Error */
-#define GSC_STAT_PERR 0x08 /* Parity Error */
-#define GSC_STAT_CMPINTR 0x10 /* Composite Interrupt */
-#define GSC_STAT_DATSHD 0x40 /* Data Line Shadow */
-#define GSC_STAT_CLKSHD 0x80 /* Clock Line Shadow */
-
-/* Keycode map */
-#define KBD_ESCAPE0 0xe0
-#define KBD_ESCAPE1 0xe1
-#define KBD_RELEASE 0xf0
-#define KBD_ACK 0xfa
-#define KBD_RESEND 0xfe
-#define KBD_UNKNOWN 0
-
-#define KBD_TBLSIZE 512
-
-/* Mouse */
-#define MOUSE_LEFTBTN 0x1
-#define MOUSE_MIDBTN 0x4
-#define MOUSE_RIGHTBTN 0x2
-#define MOUSE_ALWAYS1 0x8
-#define MOUSE_XSIGN 0x10
-#define MOUSE_YSIGN 0x20
-#define MOUSE_XOVFLOW 0x40
-#define MOUSE_YOVFLOW 0x80
-
-/* Remnant of pc_keyb.h */
-#define KBD_CMD_SET_LEDS 0xED /* Sets keyboard leds */
-#define KBD_CMD_SET_RATE 0xF3 /* Sets typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enables scanning */
-#define KBD_CMD_DISABLE 0xF5
-#define KBD_CMD_RESET 0xFF
-
-static unsigned char hpkeyb_keycode[KBD_TBLSIZE] =
-{
- /* 00 */ KBD_UNKNOWN, KEY_F9, KBD_UNKNOWN, KEY_F5, KEY_F3, KEY_F1, KEY_F2, KEY_F12,
- /* 08 */ KBD_UNKNOWN, KEY_F10, KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_GRAVE, KBD_UNKNOWN,
- /* 10 */ KBD_UNKNOWN, KEY_LEFTALT, KEY_LEFTSHIFT, KBD_UNKNOWN, KEY_LEFTCTRL, KEY_Q, KEY_1, KBD_UNKNOWN,
- /* 18 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_Z, KEY_S, KEY_A, KEY_W, KEY_2, KBD_UNKNOWN,
- /* 20 */ KBD_UNKNOWN, KEY_C, KEY_X, KEY_D, KEY_E, KEY_4, KEY_3, KBD_UNKNOWN,
- /* 28 */ KBD_UNKNOWN, KEY_SPACE, KEY_V, KEY_F, KEY_T, KEY_R, KEY_5, KBD_UNKNOWN,
- /* 30 */ KBD_UNKNOWN, KEY_N, KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, KBD_UNKNOWN,
- /* 38 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_M, KEY_J, KEY_U, KEY_7, KEY_8, KBD_UNKNOWN,
- /* 40 */ KBD_UNKNOWN, KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, KEY_9, KBD_UNKNOWN,
- /* 48 */ KBD_UNKNOWN, KEY_DOT, KEY_SLASH, KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KBD_UNKNOWN,
- /* 50 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_APOSTROPHE,KBD_UNKNOWN, KEY_LEFTBRACE, KEY_EQUAL, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 58 */ KEY_CAPSLOCK, KEY_RIGHTSHIFT,KEY_ENTER, KEY_RIGHTBRACE,KBD_UNKNOWN, KEY_BACKSLASH,KBD_UNKNOWN, KBD_UNKNOWN,
- /* 60 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KEY_BACKSPACE, KBD_UNKNOWN,
- /* 68 */ KBD_UNKNOWN, KEY_KP1, KBD_UNKNOWN, KEY_KP4, KEY_KP7, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
- /* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_103RD,
- /* 80 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KEY_F7, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 88 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 90 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 98 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e0 */ KBD_ESCAPE0, KBD_ESCAPE1, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f0 */ KBD_RELEASE, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_ACK, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_RESEND, KBD_UNKNOWN,
-/* These are offset for escaped keycodes */
- /* 00 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 08 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 10 */ KBD_UNKNOWN, KEY_RIGHTALT, KBD_UNKNOWN, KBD_UNKNOWN, KEY_RIGHTCTRL, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 18 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 20 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 28 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 30 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 38 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 40 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 48 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_KPSLASH, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 50 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 58 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_KPENTER, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 60 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 68 */ KBD_UNKNOWN, KEY_END, KBD_UNKNOWN, KEY_LEFT, KEY_HOME, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 70 */ KEY_INSERT, KEY_DELETE, KEY_DOWN, KBD_UNKNOWN, KEY_RIGHT, KEY_UP, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 78 */ KBD_UNKNOWN, KBD_UNKNOWN, KEY_PAGEDOWN, KBD_UNKNOWN, KEY_SYSRQ, KEY_PAGEUP, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 80 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 88 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 90 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* 98 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* a8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* b8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* c8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* d8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e0 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* e8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f0 */ KBD_RELEASE, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN,
- /* f8 */ KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN, KBD_UNKNOWN
-};
-
-
-/* Keyboard struct */
-static struct {
- struct input_dev dev;
- char * addr;
- unsigned int irq;
- unsigned int scancode;
- unsigned int escaped;
- unsigned int released;
- unsigned int initialized;
-}
-hpkeyb = {
- .escaped = 0,
- .released = 0,
- .initialized = 0
-};
-
-/* Mouse struct */
-static struct {
- struct input_dev dev;
- char * addr;
- unsigned long irq;
- unsigned long initialized;
- int nbread;
- unsigned char bytes[3];
- unsigned long last;
-}
-hpmouse = {
- .initialized = 0,
- .nbread = 0
-};
-
-static spinlock_t gscps2_lock = SPIN_LOCK_UNLOCKED;
-
-
-/*
- * Various HW level routines
- */
-
-#define gscps2_readb_input(x) readb(x+GSC_RCVDATA)
-#define gscps2_readb_control(x) readb(x+GSC_CONTROL)
-#define gscps2_readb_status(x) readb(x+GSC_STATUS)
-#define gscps2_writeb_control(x, y) writeb(x, y+GSC_CONTROL)
-
-static inline void gscps2_writeb_output(u8 val, char * addr)
-{
- int wait = 250; /* Keyboard is expected to react within 250ms */
-
- while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
- if (!--wait)
- return; /* This should not happen */
- mdelay(1);
- }
- writeb(val, addr+GSC_XMTDATA);
-}
-
-static inline unsigned char gscps2_wait_input(char * addr)
-{
- int wait = 250; /* Keyboard is expected to react within 250ms */
-
- while (!(gscps2_readb_status(addr) & GSC_STAT_RBNE)) {
- if (!--wait)
- return 0; /* This should not happen */
- mdelay(1);
- }
- return gscps2_readb_input(addr);
-}
-
-static int gscps2_writeb_safe_output(u8 val)
-{
- /* This function waits for keyboard's ACK */
- u8 scanread = KBD_UNKNOWN;
- int loop = 5;
-
- while (hpkeyb_keycode[scanread]!=KBD_ACK && --loop > 0) {
- gscps2_writeb_output(val, hpkeyb.addr);
- mdelay(5);
- scanread = gscps2_wait_input(hpkeyb.addr);
- }
-
- if (loop <= 0)
- return -1;
-
- return 0;
-}
-
-/* Reset the PS2 port */
-static void __init gscps2_reset(char * addr)
-{
- /* reset the interface */
- writeb(0xff, addr+GSC_RESET);
- writeb(0x0 , addr+GSC_RESET);
-
- /* enable it */
- gscps2_writeb_control(gscps2_readb_control(addr) | GSC_CTRL_ENBL, addr);
-}
-
-
-/**
- * gscps2_kbd_docode() - PS2 Keyboard basic handler
- *
- * Receives a keyboard scancode, analyses it and sends it to the input layer.
- */
-
-static void gscps2_kbd_docode(struct pt_regs *regs)
-{
- int scancode = gscps2_readb_input(hpkeyb.addr);
- DPRINTK("rel=%d scancode=%d, esc=%d ", hpkeyb.released, scancode, hpkeyb.escaped);
-
- /* Handle previously escaped scancodes */
- if (hpkeyb.escaped == KBD_ESCAPE0)
- scancode |= 0x100; /* jump to the next 256 chars of the table */
-
- switch (hpkeyb_keycode[scancode]) {
- case KBD_RELEASE:
- DPRINTK("release\n");
- hpkeyb.released = 1;
- break;
- case KBD_RESEND:
- DPRINTK("resend request\n");
- break;
- case KBD_ACK:
- DPRINTK("ACK\n");
- break;
- case KBD_ESCAPE0:
- case KBD_ESCAPE1:
- DPRINTK("escape code %d\n", hpkeyb_keycode[scancode]);
- hpkeyb.escaped = hpkeyb_keycode[scancode];
- break;
- case KBD_UNKNOWN:
- DPRINTK("received unknown scancode %d, escape %d.\n",
- scancode, hpkeyb.escaped); /* This is a DPRINTK atm since we do not handle escaped scancodes cleanly */
- if (hpkeyb.escaped)
- hpkeyb.escaped = 0;
- if (hpkeyb.released)
- hpkeyb.released = 0;
- return;
- default:
- hpkeyb.scancode = scancode;
- DPRINTK("sent=%d, rel=%d\n",hpkeyb.scancode, hpkeyb.released);
- /*input_regs(regs);*/
- input_report_key(&hpkeyb.dev, hpkeyb_keycode[hpkeyb.scancode], !hpkeyb.released);
- input_sync(&hpkeyb.dev);
- if (hpkeyb.escaped)
- hpkeyb.escaped = 0;
- if (hpkeyb.released)
- hpkeyb.released = 0;
- break;
- }
-}
-
-
-/**
- * gscps2_mouse_docode() - PS2 Mouse basic handler
- *
- * Receives mouse codes, processes them by packets of three, and sends
- * correct events to the input layer.
- */
-
-static void gscps2_mouse_docode(struct pt_regs *regs)
-{
- int xrel, yrel;
-
- /* process BAT (end of basic tests) command */
- if ((hpmouse.nbread == 1) && (hpmouse.bytes[0] == AUX_RECONNECT))
- hpmouse.nbread--;
-
- /* stolen from psmouse.c */
- if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/2)) {
- printk(KERN_DEBUG "%s:%d : Lost mouse synchronization, throwing %d bytes away.\n", __FILE__, __LINE__,
- hpmouse.nbread);
- hpmouse.nbread = 0;
- }
-
- hpmouse.last = jiffies;
- hpmouse.bytes[hpmouse.nbread++] = gscps2_readb_input(hpmouse.addr);
-
- /* process packet */
- if (hpmouse.nbread == 3) {
-
- if (!(hpmouse.bytes[PACKET_CTRL] & MOUSE_ALWAYS1))
- DPRINTK("Mouse: error on packet always1 bit checking\n");
- /* XXX should exit now, bad data on the line! */
-
- if ((hpmouse.bytes[PACKET_CTRL] & (MOUSE_XOVFLOW | MOUSE_YOVFLOW)))
- DPRINTK("Mouse: position overflow\n");
-
- /*input_regs(regs);*/
-
- input_report_key(&hpmouse.dev, BTN_LEFT, hpmouse.bytes[PACKET_CTRL] & MOUSE_LEFTBTN);
- input_report_key(&hpmouse.dev, BTN_MIDDLE, hpmouse.bytes[PACKET_CTRL] & MOUSE_MIDBTN);
- input_report_key(&hpmouse.dev, BTN_RIGHT, hpmouse.bytes[PACKET_CTRL] & MOUSE_RIGHTBTN);
-
- xrel = hpmouse.bytes[PACKET_X];
- yrel = hpmouse.bytes[PACKET_Y];
-
- /* Data sent by mouse are 9-bit signed, the sign bit is in the control packet */
- if (xrel && (hpmouse.bytes[PACKET_CTRL] & MOUSE_XSIGN))
- xrel = xrel - 0x100;
- if (yrel && (hpmouse.bytes[PACKET_CTRL] & MOUSE_YSIGN))
- yrel = yrel - 0x100;
-
- input_report_rel(&hpmouse.dev, REL_X, xrel);
- input_report_rel(&hpmouse.dev, REL_Y, -yrel); /* Y axis is received upside-down */
-
- input_sync(&hpmouse.dev);
-
- hpmouse.nbread = 0;
- }
-}
-
-
-/**
- * gscps2_interrupt() - Interruption service routine
- *
- * This processes the list of scancodes queued and sends appropriate
- * key value to the system.
- */
-
-static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *reg)
-{
- /* process mouse actions */
- while (gscps2_readb_status(hpmouse.addr) & GSC_STAT_RBNE)
- gscps2_mouse_docode(reg);
-
- /* process keyboard scancode */
- while (gscps2_readb_status(hpkeyb.addr) & GSC_STAT_RBNE)
- gscps2_kbd_docode(reg);
-
- return IRQ_HANDLED;
-}
-
-
-/**
- * gscps2_hpkeyb_event() - Event handler
- * @return: success/error report
- *
- * Currently only updates leds on keyboard
- */
-
-int gscps2_hpkeyb_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
- DPRINTK("Calling %s, type=%d, code=%d, value=%d\n",
- __FUNCTION__, type, code, value);
-
- if (!hpkeyb.initialized)
- return -1;
-
- if (type == EV_LED) {
- u8 leds[2];
-
- if (gscps2_writeb_safe_output(KBD_CMD_SET_LEDS)) {
- printk(KERN_ERR "gsckbd_leds: timeout\n");
- return -1;
- }
- DPRINTK("KBD_CMD_SET_LEDS\n");
-
- *leds = (test_bit(LED_SCROLLL, dev->led) ? LED_SCR : 0)
- | (test_bit(LED_NUML, dev->led) ? LED_NUM : 0)
- | (test_bit(LED_CAPSL, dev->led) ? LED_CAP : 0);
- DPRINTK("Sending leds=%x\n", *leds);
-
- if (gscps2_writeb_safe_output(*leds)) {
- printk(KERN_ERR "gsckbd_leds: timeout\n");
- return -1;
- }
- DPRINTK("leds sent\n");
-
- if (gscps2_writeb_safe_output(KBD_CMD_ENABLE)) {
- printk(KERN_ERR "gsckbd_leds: timeout\n");
- return -1;
- }
- DPRINTK("End\n");
-
- return 0;
-
- }
- return -1;
-}
-
-
-/**
- * gscps2_kbd_probe() - Probes keyboard device and init input_dev structure
- * @return: number of device initialized (1, 0 on error)
- */
-
-static int __init gscps2_kbd_probe(void)
-{
- int i, res = 0;
- unsigned long flags;
-
- if (hpkeyb.initialized) {
- printk(KERN_ERR "GSC PS/2 keyboard driver already registered\n");
- return 0;
- }
-
- spin_lock_irqsave(&gscps2_lock, flags);
-
- if (!gscps2_writeb_safe_output(KBD_CMD_SET_LEDS) &&
- !gscps2_writeb_safe_output(0) &&
- !gscps2_writeb_safe_output(KBD_CMD_ENABLE))
- res = 1;
-
- spin_unlock_irqrestore(&gscps2_lock, flags);
-
- if (!res)
- printk(KERN_ERR "Keyboard initialization sequence failled\n");
-
- init_input_dev(&hpkeyb.dev);
-
- for (i = 0; i < KBD_TBLSIZE; i++)
- if (hpkeyb_keycode[i] != KBD_UNKNOWN)
- set_bit(hpkeyb_keycode[i], hpkeyb.dev.keybit);
-
- hpkeyb.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- hpkeyb.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
- hpkeyb.dev.keycode = hpkeyb_keycode;
- hpkeyb.dev.keycodesize = sizeof(unsigned char);
- hpkeyb.dev.keycodemax = KBD_TBLSIZE;
- hpkeyb.dev.name = "GSC Keyboard";
- hpkeyb.dev.phys = "hpkbd/input0";
-
- hpkeyb.dev.event = gscps2_hpkeyb_event;
-
- /* TODO These need some adjustement, are they really useful ? */
- hpkeyb.dev.id.bustype = BUS_GSC;
- hpkeyb.dev.id.vendor = PCI_VENDOR_ID_HP;
- hpkeyb.dev.id.product = 0x0001;
- hpkeyb.dev.id.version = 0x0010;
- hpkeyb.initialized = 1;
-
- return 1;
-}
-
-
-/**
- * gscps2_mouse_probe() - Probes mouse device and init input_dev structure
- * @return: number of device initialized (1, 0 on error)
- *
- * Currently no check on initialization is performed
- */
-
-static int __init gscps2_mouse_probe(void)
-{
- if (hpmouse.initialized) {
- printk(KERN_ERR "GSC PS/2 Mouse driver already registered\n");
- return 0;
- }
-
- init_input_dev(&hpmouse.dev);
-
- hpmouse.dev.name = "GSC Mouse";
- hpmouse.dev.phys = "hpmouse/input0";
- hpmouse.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- hpmouse.dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- hpmouse.dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- hpmouse.last = 0;
-
- gscps2_writeb_output(AUX_ENABLE_DEV, hpmouse.addr);
- /* Try it a second time, this will give status if the device is available */
- gscps2_writeb_output(AUX_ENABLE_DEV, hpmouse.addr);
-
- /* TODO These need some adjustement, are they really useful ? */
- hpmouse.dev.id.bustype = BUS_GSC;
- hpmouse.dev.id.vendor = 0x0001;
- hpmouse.dev.id.product = 0x0001;
- hpmouse.dev.id.version = 0x0010;
- hpmouse.initialized = 1;
- return 1; /* XXX: we don't check if initialization failed */
-}
-
-
-/**
- * gscps2_probe() - Probes PS2 devices
- * @return: success/error report
- */
-
-static int __init gscps2_probe(struct parisc_device *dev)
-{
- u8 id;
- char *addr, *name;
- int ret = 0, device_found = 0;
- unsigned long hpa = dev->hpa;
-
- if (!dev->irq)
- goto fail_pitifully;
-
- /* Offset for DINO PS/2. Works with LASI even */
- if (dev->id.sversion == 0x96)
- hpa += GSC_DINO_OFFSET;
-
- addr = ioremap(hpa, 256);
-
- if (!hpmouse.initialized || !hpkeyb.initialized)
- gscps2_reset(addr);
-
- ret = -EINVAL;
- id = readb(addr+GSC_ID) & 0x0f;
- switch (id) {
- case 0: /* keyboard */
- hpkeyb.addr = addr;
- name = "keyboard";
- device_found = gscps2_kbd_probe();
- break;
- case 1: /* mouse */
- hpmouse.addr = addr;
- name = "mouse";
- device_found = gscps2_mouse_probe();
- break;
- default:
- printk(KERN_WARNING "%s: Unsupported PS/2 port (id=%d) ignored\n",
- __FUNCTION__, id);
- goto fail_miserably;
- }
-
- /* No valid device found */
- ret = -ENODEV;
- if (!device_found)
- goto fail_miserably;
-
- /* Here we claim only if we have a device attached */
- /* Allocate the irq and memory region for that device */
- ret = -EBUSY;
- if (request_irq(dev->irq, gscps2_interrupt, 0, name, NULL))
- goto fail_miserably;
-
- if (!request_mem_region(hpa, GSC_STATUS + 4, name))
- goto fail_request_mem;
-
- /* Finalize input struct and register it */
- switch (id) {
- case 0: /* keyboard */
- hpkeyb.irq = dev->irq;
- input_register_device(&hpkeyb.dev);
- break;
- case 1: /* mouse */
- hpmouse.irq = dev->irq;
- input_register_device(&hpmouse.dev);
- break;
- default:
- break;
- }
-
- printk(KERN_INFO "input: PS/2 %s port at 0x%08lx (irq %d) found and attached\n",
- name, hpa, dev->irq);
-
- return 0;
-
-fail_request_mem: free_irq(dev->irq, NULL);
-fail_miserably: iounmap(addr);
-fail_pitifully: return ret;
-}
-
-
-
-static struct parisc_device_id gscps2_device_tbl[] = {
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
-/* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, DINO PS/2 (XXX Not yet tested) */
- { 0, } /* 0 terminated list */
-};
-
-static struct parisc_driver gscps2_driver = {
- .name = "GSC PS2",
- .id_table = gscps2_device_tbl,
- .probe = gscps2_probe,
-};
-
-static int __init gscps2_init(void)
-{
- if (register_parisc_driver(&gscps2_driver))
- return -EBUSY;
- return 0;
-}
-
-static void __exit gscps2_exit(void)
-{
- /* TODO this is probably not very good and needs to be checked */
- if (hpkeyb.initialized) {
- free_irq(hpkeyb.irq, gscps2_interrupt);
- iounmap(hpkeyb.addr);
- hpkeyb.initialized = 0;
- input_unregister_device(&hpkeyb.dev);
- }
- if (hpmouse.initialized) {
- free_irq(hpmouse.irq, gscps2_interrupt);
- iounmap(hpmouse.addr);
- hpmouse.initialized = 0;
- input_unregister_device(&hpmouse.dev);
- }
- unregister_parisc_driver(&gscps2_driver);
-}
-
-
-MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@esiee.fr>");
-MODULE_DESCRIPTION("GSC PS/2 keyboard/mouse driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
-
-
-module_init(gscps2_init);
-module_exit(gscps2_exit);
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 7eb8567ec1b2..752ad1aa357b 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -17,6 +17,7 @@ config MOUSE_PS2
depends on INPUT && INPUT_MOUSE
select SERIO
select SERIO_I8042 if PC
+ select SERIO_GSCPS2 if GSC
---help---
Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index eaed728f1a2a..10a54ddd2540 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -20,6 +20,7 @@ config SERIO_I8042
tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
default y
select SERIO
+ depends on !PARISC
---help---
i8042 is the chip over which the standard AT keyboard and PS/2
mouse are connected to the computer. If you use these devices,
@@ -48,6 +49,7 @@ config SERIO_SERPORT
config SERIO_CT82C710
tristate "ct82c710 Aux port controller"
depends on SERIO
+ depends on !PARISC
---help---
Say Y here if you have a Texas Instruments TravelMate notebook
equipped with the ct82c710 chip and want to use a mouse connected
@@ -105,6 +107,20 @@ config SERIO_98KBD
To compile this driver as a module, choose M here: the
module will be called 98kbd-io.
+config SERIO_GSCPS2
+ tristate "HP GSC PS/2 keyboard and PS/2 mouse controller"
+ depends on GSC && SERIO
+ default y
+ help
+ This driver provides support for the PS/2 ports on PA-RISC machines
+ over which HP PS/2 keyboards and PS/2 mice may be connected.
+ If you use these devices, you'll need to say Y here.
+
+ It's safe to enable this driver, so if unsure, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gscps2.
+
config SERIO_PCIPS2
tristate "PCI PS/2 keyboard and PS/2 mouse controller"
depends on PCI && SERIO
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 4677f4ea7c38..2eb86eba6ed9 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o
+obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o
obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
new file mode 100644
index 000000000000..6f6bf4296312
--- /dev/null
+++ b/drivers/input/serio/gscps2.c
@@ -0,0 +1,470 @@
+/*
+ * drivers/input/serio/gscps2.c
+ *
+ * Copyright (c) 2004 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
+ * Copyright (c) 2002 Thibaut Varene <varenet@esiee.fr>
+ *
+ * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
+ * Copyright (c) 1999 Alex deVries <adevries@thepuffingroup.com>
+ * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
+ * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
+ *
+ * HP GSC PS/2 port driver, found in PA/RISC Workstations
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * TODO:
+ * - Dino testing (did HP ever shipped a machine on which this port
+ * was usable/enabled ?)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/pci_ids.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/parisc-device.h>
+
+MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@esiee.fr>, Helge Deller <deller@gmx.de>");
+MODULE_DESCRIPTION("HP GSC PS/2 port driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
+
+#define PFX "gscps2.c: "
+
+/*
+ * Driver constants
+ */
+
+/* various constants */
+#define ENABLE 1
+#define DISABLE 0
+
+#define GSC_DINO_OFFSET 0x0800 /* offset for DINO controller versus LASI one */
+
+/* PS/2 IO port offsets */
+#define GSC_ID 0x00 /* device ID offset (see: GSC_ID_XXX) */
+#define GSC_RESET 0x00 /* reset port offset */
+#define GSC_RCVDATA 0x04 /* receive port offset */
+#define GSC_XMTDATA 0x04 /* transmit port offset */
+#define GSC_CONTROL 0x08 /* see: Control register bits */
+#define GSC_STATUS 0x0C /* see: Status register bits */
+
+/* Control register bits */
+#define GSC_CTRL_ENBL 0x01 /* enable interface */
+#define GSC_CTRL_LPBXR 0x02 /* loopback operation */
+#define GSC_CTRL_DIAG 0x20 /* directly control clock/data line */
+#define GSC_CTRL_DATDIR 0x40 /* data line direct control */
+#define GSC_CTRL_CLKDIR 0x80 /* clock line direct control */
+
+/* Status register bits */
+#define GSC_STAT_RBNE 0x01 /* Receive Buffer Not Empty */
+#define GSC_STAT_TBNE 0x02 /* Transmit Buffer Not Empty */
+#define GSC_STAT_TERR 0x04 /* Timeout Error */
+#define GSC_STAT_PERR 0x08 /* Parity Error */
+#define GSC_STAT_CMPINTR 0x10 /* Composite Interrupt = irq on any port */
+#define GSC_STAT_DATSHD 0x40 /* Data Line Shadow */
+#define GSC_STAT_CLKSHD 0x80 /* Clock Line Shadow */
+
+/* IDs returned by GSC_ID port register */
+#define GSC_ID_KEYBOARD 0 /* device ID values */
+#define GSC_ID_MOUSE 1
+
+
+static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs);
+
+#define BUFFER_SIZE 0x0f
+
+/* GSC PS/2 port device struct */
+struct gscps2port {
+ struct list_head node;
+ struct parisc_device *padev;
+ struct serio port;
+ spinlock_t lock;
+ char *addr;
+ u8 act, append; /* position in buffer[] */
+ struct {
+ u8 data;
+ u8 str;
+ } buffer[BUFFER_SIZE+1];
+ int id;
+ char name[32];
+};
+
+/*
+ * Various HW level routines
+ */
+
+#define gscps2_readb_input(x) readb((x)+GSC_RCVDATA)
+#define gscps2_readb_control(x) readb((x)+GSC_CONTROL)
+#define gscps2_readb_status(x) readb((x)+GSC_STATUS)
+#define gscps2_writeb_control(x, y) writeb((x), (y)+GSC_CONTROL)
+
+
+/*
+ * wait_TBE() - wait for Transmit Buffer Empty
+ */
+
+static int wait_TBE(char *addr)
+{
+ int timeout = 25000; /* device is expected to react within 250 msec */
+ while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
+ if (!--timeout)
+ return 0; /* This should not happen */
+ udelay(10);
+ }
+ return 1;
+}
+
+
+/*
+ * gscps2_flush() - flush the receive buffer
+ */
+
+static void gscps2_flush(struct gscps2port *ps2port)
+{
+ while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
+ gscps2_readb_input(ps2port->addr);
+ ps2port->act = ps2port->append = 0;
+}
+
+/*
+ * gscps2_writeb_output() - write a byte to the port
+ *
+ * returns 1 on sucess, 0 on error
+ */
+
+static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
+{
+ unsigned long flags;
+ char *addr = ps2port->addr;
+
+ if (!wait_TBE(addr)) {
+ printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
+ return 0;
+ }
+
+ while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
+ /* wait */;
+
+ spin_lock_irqsave(&ps2port->lock, flags);
+ writeb(data, addr+GSC_XMTDATA);
+ spin_unlock_irqrestore(&ps2port->lock, flags);
+
+ /* this is ugly, but due to timing of the port it seems to be necessary. */
+ mdelay(6);
+
+ /* make sure any received data is returned as fast as possible */
+ /* this is important e.g. when we set the LEDs on the keyboard */
+ gscps2_interrupt(0, NULL, NULL);
+
+ return 1;
+}
+
+
+/*
+ * gscps2_enable() - enables or disables the port
+ */
+
+static void gscps2_enable(struct gscps2port *ps2port, int enable)
+{
+ unsigned long flags;
+ u8 data;
+
+ /* now enable/disable the port */
+ spin_lock_irqsave(&ps2port->lock, flags);
+ gscps2_flush(ps2port);
+ data = gscps2_readb_control(ps2port->addr);
+ if (enable)
+ data |= GSC_CTRL_ENBL;
+ else
+ data &= ~GSC_CTRL_ENBL;
+ gscps2_writeb_control(data, ps2port->addr);
+ spin_unlock_irqrestore(&ps2port->lock, flags);
+ wait_TBE(ps2port->addr);
+ gscps2_flush(ps2port);
+}
+
+/*
+ * gscps2_reset() - resets the PS/2 port
+ */
+
+static void gscps2_reset(struct gscps2port *ps2port)
+{
+ char *addr = ps2port->addr;
+ unsigned long flags;
+
+ /* reset the interface */
+ spin_lock_irqsave(&ps2port->lock, flags);
+ gscps2_flush(ps2port);
+ writeb(0xff, addr+GSC_RESET);
+ gscps2_flush(ps2port);
+ spin_unlock_irqrestore(&ps2port->lock, flags);
+
+ /* enable it */
+ gscps2_enable(ps2port, ENABLE);
+}
+
+static LIST_HEAD(ps2port_list);
+
+/**
+ * gscps2_interrupt() - Interruption service routine
+ *
+ * This function reads received PS/2 bytes and processes them on
+ * all interfaces.
+ * The problematic part here is, that the keyboard and mouse PS/2 port
+ * share the same interrupt and it's not possible to send data if any
+ * one of them holds input data. To solve this problem we try to receive
+ * the data as fast as possible and handle the reporting to the upper layer
+ * later.
+ */
+
+static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+ struct gscps2port *ps2port;
+
+ list_for_each_entry(ps2port, &ps2port_list, node) {
+
+ unsigned long flags;
+ spin_lock_irqsave(&ps2port->lock, flags);
+
+ while ( (ps2port->buffer[ps2port->append].str =
+ gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
+ ps2port->buffer[ps2port->append].data =
+ gscps2_readb_input(ps2port->addr);
+ ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
+ }
+
+ spin_unlock_irqrestore(&ps2port->lock, flags);
+
+ } /* list_for_each_entry */
+
+ /* all data was read from the ports - now report the data to upper layer */
+
+ list_for_each_entry(ps2port, &ps2port_list, node) {
+
+ while (ps2port->act != ps2port->append) {
+
+ unsigned int rxflags;
+ u8 data, status;
+
+ /* Did new data arrived while we read existing data ?
+ If yes, exit now and let the new irq handler start over again */
+ if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
+ return IRQ_HANDLED;
+
+ status = ps2port->buffer[ps2port->act].str;
+ data = ps2port->buffer[ps2port->act].data;
+
+ ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
+ rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
+ ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 );
+
+ serio_interrupt(&ps2port->port, data, rxflags, regs);
+
+ } /* while() */
+
+ } /* list_for_each_entry */
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * gscps2_write() - send a byte out through the aux interface.
+ */
+
+static int gscps2_write(struct serio *port, unsigned char data)
+{
+ struct gscps2port *ps2port = port->driver;
+
+ if (!gscps2_writeb_output(ps2port, data)) {
+ printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * gscps2_open() is called when a port is opened by the higher layer.
+ * It resets and enables the port.
+ */
+
+static int gscps2_open(struct serio *port)
+{
+ struct gscps2port *ps2port = port->driver;
+
+ gscps2_reset(ps2port);
+
+ gscps2_interrupt(0, NULL, NULL);
+
+ return 0;
+}
+
+/*
+ * gscps2_close() disables the port
+ */
+
+static void gscps2_close(struct serio *port)
+{
+ struct gscps2port *ps2port = port->driver;
+ gscps2_enable(ps2port, DISABLE);
+}
+
+static struct serio gscps2_serio_port =
+{
+ .name = "GSC PS/2",
+ .idbus = BUS_GSC,
+ .idvendor = PCI_VENDOR_ID_HP,
+ .idproduct = 0x0001,
+ .idversion = 0x0010,
+ .type = SERIO_8042,
+ .write = gscps2_write,
+ .open = gscps2_open,
+ .close = gscps2_close,
+};
+
+/**
+ * gscps2_probe() - Probes PS2 devices
+ * @return: success/error report
+ */
+
+static int __init gscps2_probe(struct parisc_device *dev)
+{
+ struct gscps2port *ps2port;
+ unsigned long hpa = dev->hpa;
+ int ret;
+
+ if (!dev->irq)
+ return -ENODEV;
+
+ /* Offset for DINO PS/2. Works with LASI even */
+ if (dev->id.sversion == 0x96)
+ hpa += GSC_DINO_OFFSET;
+
+ ps2port = kmalloc(sizeof(struct gscps2port), GFP_KERNEL);
+ if (!ps2port)
+ return -ENOMEM;
+
+ dev_set_drvdata(&dev->dev, ps2port);
+
+ memset(ps2port, 0, sizeof(struct gscps2port));
+ ps2port->padev = dev;
+ ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
+ spin_lock_init(&ps2port->lock);
+
+ gscps2_reset(ps2port);
+ ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
+ snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
+ gscps2_serio_port.name,
+ (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
+
+ memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
+ ps2port->port.driver = ps2port;
+ ps2port->port.name = ps2port->name;
+ ps2port->port.phys = dev->dev.bus_id;
+
+ list_add_tail(&ps2port->node, &ps2port_list);
+
+ ret = -EBUSY;
+ if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->name, ps2port))
+ goto fail_miserably;
+
+ if ( (ps2port->id != GSC_ID_KEYBOARD) && (ps2port->id != GSC_ID_MOUSE) ) {
+ printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
+ hpa, ps2port->id);
+ ret = -ENODEV;
+ goto fail;
+ }
+
+#if 0
+ if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
+ goto fail;
+#endif
+
+ printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
+ ps2port->name,
+ ps2port->addr,
+ ps2port->padev->irq,
+ ps2port->port.phys);
+
+ serio_register_port(&ps2port->port);
+
+ return 0;
+
+fail:
+ free_irq(dev->irq, ps2port);
+
+fail_miserably:
+ list_del(&ps2port->node);
+ iounmap(ps2port->addr);
+ release_mem_region(dev->hpa, GSC_STATUS + 4);
+ kfree(ps2port);
+ return ret;
+}
+
+/**
+ * gscps2_remove() - Removes PS2 devices
+ * @return: success/error report
+ */
+
+static int __devexit gscps2_remove(struct parisc_device *dev)
+{
+ struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
+
+ serio_unregister_port(&ps2port->port);
+ free_irq(dev->irq, ps2port);
+ gscps2_flush(ps2port);
+ list_del(&ps2port->node);
+ iounmap(ps2port->addr);
+#if 0
+ release_mem_region(dev->hpa, GSC_STATUS + 4);
+#endif
+ dev_set_drvdata(&dev->dev, NULL);
+ kfree(ps2port);
+ return 0;
+}
+
+
+static struct parisc_device_id gscps2_device_tbl[] = {
+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
+#ifdef DINO_TESTED
+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
+#endif
+ { 0, } /* 0 terminated list */
+};
+
+static struct parisc_driver parisc_ps2_driver = {
+ .name = "GSC PS/2",
+ .id_table = gscps2_device_tbl,
+ .probe = gscps2_probe,
+ .remove = gscps2_remove,
+};
+
+static int __init gscps2_init(void)
+{
+ register_parisc_driver(&parisc_ps2_driver);
+ return 0;
+}
+
+static void __exit gscps2_exit(void)
+{
+ unregister_parisc_driver(&parisc_ps2_driver);
+}
+
+
+module_init(gscps2_init);
+module_exit(gscps2_exit);
+
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 144bb86256fb..d36cd1736789 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -379,6 +379,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned int dfl;
int ret;
+ mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+
spin_lock_irqsave(&i8042_lock, flags);
str = i8042_read_status();
if (str & I8042_STR_OBF)
@@ -433,7 +435,6 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irq_ret:
ret = 1;
out:
- mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
return IRQ_RETVAL(ret);
}
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 7da47127e6d2..52893df049a3 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -224,6 +224,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
offset = report->size;
report->size += parser->global.report_size * parser->global.report_count;
+ if (usages < parser->global.report_count)
+ usages = parser->global.report_count;
+
if (usages == 0)
return 0; /* ignore padding fields */
@@ -235,9 +238,13 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
for (i = 0; i < usages; i++) {
- field->usage[i].hid = parser->local.usage[i];
+ int j = i;
+ /* Duplicate the last usage we parsed if we have excess values */
+ if (i >= parser->local.usage_index)
+ j = parser->local.usage_index - 1;
+ field->usage[i].hid = parser->local.usage[j];
field->usage[i].collection_index =
- parser->local.collection_index[i];
+ parser->local.collection_index[j];
}
field->maxusage = usages;
@@ -1315,7 +1322,6 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
-
#define USB_VENDOR_ID_AIPTEK 0x08ca
#define USB_DEVICE_ID_AIPTEK_6000 0x0020
@@ -1354,17 +1360,40 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_A4TECH 0x09DA
#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
+#define USB_VENDOR_ID_CYPRESS 0x04b4
+#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
+
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
#define USB_VENDOR_ID_ALPS 0x0433
#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
+#define USB_VENDOR_ID_SAITEK 0x06a3
+#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
+
struct hid_blacklist {
__u16 idVendor;
__u16 idProduct;
unsigned quirks;
} hid_blacklist[] = {
+
+ { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
+
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
+
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
@@ -1386,32 +1415,24 @@ struct hid_blacklist {
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
+
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
+
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK },
- { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK },
+
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
+
{ 0, 0 }
};
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 3db55a44da58..1215339805ed 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -432,20 +432,21 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
input_regs(input, regs);
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK)
- && (usage->code == BTN_BACK)) {
+ && (usage->code == BTN_BACK || usage->code == BTN_EXTRA)) {
if (value)
hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
else
hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
return;
}
+
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON)
&& (usage->code == REL_WHEEL)) {
input_event(input, usage->type, REL_HWHEEL, value);
return;
}
- if (usage->hat_min != usage->hat_max) {
+ if (usage->hat_min != usage->hat_max ) { /* FIXME: hat_max can be 0 and hat_min 1 */
value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
if (value < 0 || value > 8) value = 0;
input_event(input, usage->type, usage->code , hid_hat_to_axis[value].x);
@@ -484,7 +485,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
return;
}
- if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UKNOWN */
+ if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
return;
input_event(input, usage->type, usage->code, value);
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 3c74a4d6fd04..27fa9350dfc5 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -403,7 +403,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct hiddev_collection_info cinfo;
struct hiddev_report_info rinfo;
struct hiddev_field_info finfo;
- struct hiddev_usage_ref uref;
+ struct hiddev_usage_ref_multi uref_multi;
+ struct hiddev_usage_ref *uref = &uref_multi.uref;
struct hiddev_devinfo dinfo;
struct hid_report *report;
struct hid_field *field;
@@ -575,68 +576,98 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return 0;
case HIDIOCGUCODE:
- if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
+ if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
return -EFAULT;
- rinfo.report_type = uref.report_type;
- rinfo.report_id = uref.report_id;
+ rinfo.report_type = uref->report_type;
+ rinfo.report_id = uref->report_id;
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL;
- if (uref.field_index >= report->maxfield)
+ if (uref->field_index >= report->maxfield)
return -EINVAL;
- field = report->field[uref.field_index];
- if (uref.usage_index >= field->maxusage)
+ field = report->field[uref->field_index];
+ if (uref->usage_index >= field->maxusage)
return -EINVAL;
- uref.usage_code = field->usage[uref.usage_index].hid;
+ uref->usage_code = field->usage[uref->usage_index].hid;
- if (copy_to_user((void *) arg, &uref, sizeof(uref)))
+ if (copy_to_user((void *) arg, uref, sizeof(*uref)))
return -EFAULT;
return 0;
case HIDIOCGUSAGE:
case HIDIOCSUSAGE:
+ case HIDIOCGUSAGES:
+ case HIDIOCSUSAGES:
case HIDIOCGCOLLECTIONINDEX:
- if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
- return -EFAULT;
+ if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
+ if (copy_from_user(&uref_multi, (void *) arg,
+ sizeof(uref_multi)))
+ return -EFAULT;
+ } else {
+ if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
+ return -EFAULT;
+ }
- if (cmd != HIDIOCGUSAGE && uref.report_type == HID_REPORT_TYPE_INPUT)
- return -EINVAL;
+ if (cmd != HIDIOCGUSAGE &&
+ cmd != HIDIOCGUSAGES &&
+ uref->report_type == HID_REPORT_TYPE_INPUT)
+ return -EINVAL;
- if (uref.report_id == HID_REPORT_ID_UNKNOWN) {
- field = hiddev_lookup_usage(hid, &uref);
+ if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
+ field = hiddev_lookup_usage(hid, uref);
if (field == NULL)
return -EINVAL;
} else {
- rinfo.report_type = uref.report_type;
- rinfo.report_id = uref.report_id;
+ rinfo.report_type = uref->report_type;
+ rinfo.report_id = uref->report_id;
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
return -EINVAL;
- if (uref.field_index >= report->maxfield)
+ if (uref->field_index >= report->maxfield)
return -EINVAL;
- field = report->field[uref.field_index];
- if (uref.usage_index >= field->maxusage)
+ field = report->field[uref->field_index];
+ if (uref->usage_index >= field->maxusage)
return -EINVAL;
+
+ if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
+ if (uref_multi.num_values >= HID_MAX_USAGES ||
+ uref->usage_index >= field->maxusage ||
+ (uref->usage_index + uref_multi.num_values) >= field->maxusage)
+ return -EINVAL;
+ }
}
switch (cmd) {
case HIDIOCGUSAGE:
- uref.value = field->value[uref.usage_index];
- if (copy_to_user((void *) arg, &uref, sizeof(uref)))
+ uref->value = field->value[uref->usage_index];
+ if (copy_to_user((void *) arg, uref, sizeof(*uref)))
return -EFAULT;
return 0;
case HIDIOCSUSAGE:
- field->value[uref.usage_index] = uref.value;
+ field->value[uref->usage_index] = uref->value;
return 0;
case HIDIOCGCOLLECTIONINDEX:
- return field->usage[uref.usage_index].collection_index;
+ return field->usage[uref->usage_index].collection_index;
+ case HIDIOCGUSAGES:
+ for (i = 0; i < uref_multi.num_values; i++)
+ uref_multi.values[i] =
+ field->value[uref->usage_index + i];
+ if (copy_to_user((void *) arg, &uref_multi,
+ sizeof(uref_multi)))
+ return -EFAULT;
+ return 0;
+ case HIDIOCSUSAGES:
+ for (i = 0; i < uref_multi.num_values; i++)
+ field->value[uref->usage_index + i] =
+ uref_multi.values[i];
+ return 0;
}
return 0;
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index 607de56262d2..306fa2a19de6 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -1,7 +1,7 @@
/*
* USB Wacom Graphire and Wacom Intuos tablet support
*
- * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
+ * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
* Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
* Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
* Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
@@ -9,6 +9,7 @@
* Copyright (c) 2000 Daniel Egger <egger@suse.de>
* Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
* Copyright (c) 2002 Ping Cheng <pingc@wacom.com>
+ * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
*
* ChangeLog:
* v0.1 (vp) - Initial release
@@ -48,6 +49,7 @@
* v1.30 (vp) - Merge 2.4 and 2.5 drivers
* - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
* - Cleanups here and there
+ * v1.30.1 (pi) - Added Graphire3 support
*/
/*
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index 9e6d27476a74..75c1fa0d2189 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -39,33 +39,33 @@ struct hiddev_event {
};
struct hiddev_devinfo {
- unsigned int bustype;
- unsigned int busnum;
- unsigned int devnum;
- unsigned int ifnum;
- short vendor;
- short product;
- short version;
- unsigned num_applications;
+ __u32 bustype;
+ __u32 busnum;
+ __u32 devnum;
+ __u32 ifnum;
+ __s16 vendor;
+ __s16 product;
+ __s16 version;
+ __u32 num_applications;
};
struct hiddev_collection_info {
- unsigned index;
- unsigned type;
- unsigned usage;
- unsigned level;
+ __u32 index;
+ __u32 type;
+ __u32 usage;
+ __u32 level;
};
#define HID_STRING_SIZE 256
struct hiddev_string_descriptor {
- int index;
+ __s32 index;
char value[HID_STRING_SIZE];
};
struct hiddev_report_info {
- unsigned report_type;
- unsigned report_id;
- unsigned num_fields;
+ __u32 report_type;
+ __u32 report_id;
+ __u32 num_fields;
};
/* To do a GUSAGE/SUSAGE, fill in at least usage_code, report_type and
@@ -88,20 +88,20 @@ struct hiddev_report_info {
#define HID_REPORT_TYPE_MAX 3
struct hiddev_field_info {
- unsigned report_type;
- unsigned report_id;
- unsigned field_index;
- unsigned maxusage;
- unsigned flags;
- unsigned physical; /* physical usage for this field */
- unsigned logical; /* logical usage for this field */
- unsigned application; /* application usage for this field */
+ __u32 report_type;
+ __u32 report_id;
+ __u32 field_index;
+ __u32 maxusage;
+ __u32 flags;
+ __u32 physical; /* physical usage for this field */
+ __u32 logical; /* logical usage for this field */
+ __u32 application; /* application usage for this field */
__s32 logical_minimum;
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
- unsigned unit_exponent;
- unsigned unit;
+ __u32 unit_exponent;
+ __u32 unit;
};
/* Fill in report_type, report_id and field_index to get the information on a
@@ -118,14 +118,22 @@ struct hiddev_field_info {
#define HID_FIELD_BUFFERED_BYTE 0x100
struct hiddev_usage_ref {
- unsigned report_type;
- unsigned report_id;
- unsigned field_index;
- unsigned usage_index;
- unsigned usage_code;
+ __u32 report_type;
+ __u32 report_id;
+ __u32 field_index;
+ __u32 usage_index;
+ __u32 usage_code;
__s32 value;
};
+/* hiddev_usage_ref_multi is used for sending multiple bytes to a control.
+ * It really manifests itself as setting the value of consecutive usages */
+struct hiddev_usage_ref_multi {
+ struct hiddev_usage_ref uref;
+ __u32 num_values;
+ __s32 values[HID_MAX_USAGES];
+};
+
/* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
* is set to (HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT) and a new report has
* been sent by the device
@@ -161,6 +169,10 @@ struct hiddev_usage_ref {
#define HIDIOCGCOLLECTIONINFO _IOWR('H', 0x11, struct hiddev_collection_info)
#define HIDIOCGPHYS(len) _IOC(_IOC_READ, 'H', 0x12, len)
+/* For writing/reading to multiple/consecutive usages */
+#define HIDIOCGUSAGES _IOWR('H', 0x13, struct hiddev_usage_ref_multi)
+#define HIDIOCSUSAGES _IOW('H', 0x14, struct hiddev_usage_ref_multi)
+
/*
* Flags to be used in HIDIOCSFLAG
*/
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 98f61665d4c2..89b87832c769 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -3,7 +3,6 @@
#include <linux/module.h>
#include <linux/major.h>
-#define BUSMOUSE_MINOR 0
#define PSMOUSE_MINOR 1
#define MS_BUSMOUSE_MINOR 2
#define ATIXL_BUSMOUSE_MINOR 3