2004-03-16 14:20:46

by Vojtech Pavlik

[permalink] [raw]
Subject: [44 patches] Input update

Hi!

This is my current patchset against the 2.6 kernel. It's quite a number
of small patches so I hope the lkml people won't kill me. It's been a
while in Andrew Morton's kernels, too, so it's somewhat tested.

There are a few more csets in the BK tree
(bk://kernel.bkbits.net/vojtech/input) than I'm sending via e-mails, but
those are either merge csets or csets identical to ones already present
in the main tree.

Linus, please pull them from my tree (or apply the patches).

Thanks.

--
Vojtech Pavlik
SuSE Labs, SuSE CR


2004-03-16 14:23:58

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 21/44] Convert joystick drivers to new module parameters

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

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

[email protected], 2004-03-03 00:34:38-05:00, [email protected]
Input: Convert joystick modules to the new way of handling parameters and
document them in kernel-parameters.txt

The new names are:
amijoy.map=<a>,<b>
analog.map=<type1>,<type2>,...<type16>
db9.dev[2|3]=<parport#>,<type>
gamecon.map[2|3]=<parport#>,<pad1>,<pad2>,...<pad5>
turbografx.map[2|3]=<parport#>,<js1>,<js2>,...<js7>

Also there is a tiny change to mousedev and tsdev descriptions in
kernel-parameters, but no name changes.


Documentation/input/joystick-parport.txt | 16 +++---
Documentation/input/joystick.txt | 6 +-
Documentation/kernel-parameters.txt | 46 +++++++++++-------
drivers/input/joystick/amijoy.c | 17 ++----
drivers/input/joystick/analog.c | 26 ++--------
drivers/input/joystick/db9.c | 63 ++++++++++---------------
drivers/input/joystick/gamecon.c | 76 ++++++++++++-------------------
drivers/input/joystick/turbografx.c | 64 ++++++++++----------------
8 files changed, 130 insertions(+), 184 deletions(-)

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

diff -Nru a/Documentation/input/joystick-parport.txt b/Documentation/input/joystick-parport.txt
--- a/Documentation/input/joystick-parport.txt Tue Mar 16 13:18:48 2004
+++ b/Documentation/input/joystick-parport.txt Tue Mar 16 13:18:48 2004
@@ -434,7 +434,7 @@
Using gamecon.c you can connect up to five devices to one parallel port. It
uses the following kernel/module command line:

- gc=port,pad1,pad2,pad3,pad4,pad5
+ gamecon.map=port,pad1,pad2,pad3,pad4,pad5

Where 'port' the number of the parport interface (eg. 0 for parport0).

@@ -457,15 +457,15 @@
your controller plugged in before initializing.

Should you want to use more than one of parallel ports at once, you can use
-gc_2 and gc_3 as additional command line parameters for two more parallel
-ports.
+gamecon.map2 and gamecon.map3 as additional command line parameters for two
+more parallel ports.

3.2 db9.c
~~~~~~~~~
Apart from making an interface, there is nothing difficult on using the
db9.c driver. It uses the following kernel/module command line:

- db9=port,type
+ db9.dev=port,type

Where 'port' is the number of the parport interface (eg. 0 for parport0).

@@ -489,14 +489,14 @@
10 | Amiga CD32 pad

Should you want to use more than one of these joysticks/pads at once, you
-can use db9_2 and db9_3 as additional command line parameters for two
+can use db9.dev2 and db9.dev3 as additional command line parameters for two
more joysticks/pads.

3.3 turbografx.c
~~~~~~~~~~~~~~~~
The turbografx.c driver uses a very simple kernel/module command line:

- tgfx=port,js1,js2,js3,js4,js5,js6,js7
+ turbografx.map=port,js1,js2,js3,js4,js5,js6,js7

Where 'port' is the number of the parport interface (eg. 0 for parport0).

@@ -504,8 +504,8 @@
interface ports 1-7 have. For a standard multisystem joystick, this is 1.

Should you want to use more than one of these interfaces at once, you can
-use tgfx_2 and tgfx_3 as additional command line parameters for two more
-interfaces.
+use turbografx.map2 and turbografx.map3 as additional command line parameters
+for two more interfaces.

3.4 PC parallel port pinout
~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -Nru a/Documentation/input/joystick.txt b/Documentation/input/joystick.txt
--- a/Documentation/input/joystick.txt Tue Mar 16 13:18:48 2004
+++ b/Documentation/input/joystick.txt Tue Mar 16 13:18:48 2004
@@ -111,7 +111,7 @@
alias tty-ldisc-2 serport
alias char-major-13 input
above input joydev ns558 analog
- options analog js=gamepad
+ options analog map=gamepad,none,2btn

2.5 Verifying that it works
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -185,7 +185,7 @@
module command line, when inserting analog.o into the kernel. The
parameters are:

- js=type,type,type,....
+ analog.map=<type1>,<type2>,<type3>,....

'type' is type of the joystick from the table below, defining joysticks
present on gameports in the system, starting with gameport0, second 'type'
@@ -419,7 +419,7 @@
Amiga joysticks, connected to an Amiga, are supported by the amijoy.c
driver. Since they can't be autodetected, the driver has a command line.

- amijoy=a,b
+ amijoy.map=<a>,<b>

a and b define the joysticks connected to the JOY0DAT and JOY1DAT ports of
the Amiga.
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt Tue Mar 16 13:18:48 2004
+++ b/Documentation/kernel-parameters.txt Tue Mar 16 13:18:48 2004
@@ -151,7 +151,15 @@
Format: <host-scsi-id>,<target-scsi-id>,<max-rate>,<max-offset>
See also header of drivers/scsi/AM53C974.c.

- amijoy= [HW,JOY] Amiga joystick support
+ amijoy.map= [HW,JOY] Amiga joystick support
+ Map of devices attached to JOY0DAT and JOY1DAT
+ Format: <a>,<b>
+ See also Documentation/kernel/input/joystick.txt
+
+ analog.map= [HW,JOY] Analog joystick and gamepad support
+ Specifies type or capabilities of an analog joystick
+ connected to one of 16 gameports
+ Format: <type1>,<type2>,..<type16>

apc= [HW,SPARC] Power management functions (SPARCstation-4/5 + deriv.)
Format: noidle
@@ -280,10 +288,11 @@
dasd= [HW,NET]
See header of drivers/s390/block/dasd_devmap.c.

- db9= [HW,JOY]
- db9_2=
- db9_3=
-
+ db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
+ (one device per port)
+ Format: <port#>,<type>
+ See also Documentation/input/joystick-parport.txt
+
debug [KNL] Enable kernel debugging (events log level).

decnet= [HW,NET]
@@ -377,12 +386,14 @@
ftape= [HW] Floppy Tape subsystem debugging options.
See Documentation/ftape.txt.

+ gamecon.map[2|3]=
+ [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
+ support via parallel port (up to 5 devices per port)
+ Format: <port#>,<pad1>,<pad2>,<pad3>,<pad4>,<pad5>
+ See also Documentation/input/joystick-parport.txt
+
gamma= [HW,DRM]

- gc= [HW,JOY]
- gc_2= See Documentation/input/joystick-parport.txt.
- gc_3=
-
gdth= [HW,SCSI]
See header of drivers/scsi/gdth.c.

@@ -609,9 +620,9 @@

mga= [HW,DRM]

- mousedev.xres [MOUSE] Horizontal screen resolution, used for devices
+ mousedev.xres= [MOUSE] Horizontal screen resolution, used for devices
reporting absolute coordinates, such as tablets
- mousedev.yres [MOUSE] Vertical screen resolution, used for devices
+ mousedev.yres= [MOUSE] Vertical screen resolution, used for devices
reporting absolute coordinates, such as tablets

mpu401= [HW,OSS]
@@ -1156,10 +1167,6 @@
See header of drivers/scsi/t128.c.

tdfx= [HW,DRM]
-
- tgfx= [HW,JOY] TurboGraFX parallel port interface
- tgfx_2= See Documentation/input/joystick-parport.txt.
- tgfx_3=

thash_entries= [KNL,NET]
Set number of hash buckets for TCP connection
@@ -1182,8 +1189,13 @@
trix= [HW,OSS] MediaTrix AudioTrix Pro
Format: <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>

- tsdev.xres [TS] Horizontal screen resolution.
- tsdev.yres [TS] Vertical screen resolution.
+ tsdev.xres= [TS] Horizontal screen resolution.
+ tsdev.yres= [TS] Vertical screen resolution.
+
+ turbografx.map[2|3]=
+ [HW,JOY] TurboGraFX parallel port interface
+ Format: <port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
+ See also Documentation/input/joystick-parport.txt

u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
See header of drivers/scsi/u14-34f.c.
diff -Nru a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
--- a/drivers/input/joystick/amijoy.c Tue Mar 16 13:18:48 2004
+++ b/drivers/input/joystick/amijoy.c Tue Mar 16 13:18:48 2004
@@ -32,6 +32,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -42,10 +43,13 @@

MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
MODULE_DESCRIPTION("Driver for Amiga joysticks");
-MODULE_PARM(amijoy, "1-2i");
MODULE_LICENSE("GPL");

static int amijoy[2] = { 0, 1 };
+static int amijoy_nargs;
+module_param_array_named(map, amijoy, uint, amijoy_nargs, 0);
+MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
+
static int amijoy_used[2] = { 0, 0 };
static struct input_dev amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
@@ -100,17 +104,6 @@
if (!--(*used))
free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
}
-
-static int __init amijoy_setup(char *str)
-{
- int i;
- int ints[4];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 2; i++) amijoy[i] = ints[i+1];
- return 1;
-}
-__setup("amijoy=", amijoy_setup);

static int __init amijoy_init(void)
{
diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- a/drivers/input/joystick/analog.c Tue Mar 16 13:18:48 2004
+++ b/drivers/input/joystick/analog.c Tue Mar 16 13:18:48 2004
@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/init.h>
@@ -50,9 +51,10 @@
#define ANALOG_PORTS 16

static char *js[ANALOG_PORTS];
+static int js_nargs;
static int analog_options[ANALOG_PORTS];
-MODULE_PARM(js, "1-" __MODULE_STRING(ANALOG_PORTS) "s");
-MODULE_PARM_DESC(js, "Analog joystick options");
+module_param_array_named(map, js, charp, js_nargs, 0);
+MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");

/*
* Times, feature definitions.
@@ -711,7 +713,7 @@
int i, j;
char *end;

- for (i = 0; i < ANALOG_PORTS && js[i]; i++) {
+ for (i = 0; i < js_nargs; i++) {

for (j = 0; analog_types[j].name; j++)
if (!strcmp(analog_types[j].name, js[i])) {
@@ -741,24 +743,6 @@
.connect = analog_connect,
.disconnect = analog_disconnect,
};
-
-#ifndef MODULE
-static int __init analog_setup(char *str)
-{
- char *s = str;
- int i = 0;
-
- if (!str || !*str) return 0;
-
- while ((str = s) && (i < ANALOG_PORTS)) {
- if ((s = strchr(str,','))) *s++ = 0;
- js[i++] = str;
- }
-
- return 1;
-}
-__setup("js=", analog_setup);
-#endif

int __init analog_init(void)
{
diff -Nru a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
--- a/drivers/input/joystick/db9.c Tue Mar 16 13:18:48 2004
+++ b/drivers/input/joystick/db9.c Tue Mar 16 13:18:48 2004
@@ -33,6 +33,7 @@

#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/parport.h>
@@ -42,9 +43,20 @@
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
MODULE_LICENSE("GPL");

-MODULE_PARM(db9, "2i");
-MODULE_PARM(db9_2, "2i");
-MODULE_PARM(db9_3, "2i");
+static int db9[] __initdata = { -1, 0 };
+static int db9_nargs __initdata = 0;
+module_param_array_named(dev, db9, int, db9_nargs, 0);
+MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
+
+static int db9_2[] __initdata = { -1, 0 };
+static int db9_nargs_2 __initdata = 0;
+module_param_array_named(dev2, db9_2, int, db9_nargs_2, 0);
+MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
+
+static int db9_3[] __initdata = { -1, 0 };
+static int db9_nargs_3 __initdata = 0;
+module_param_array_named(dev3, db9_3, int, db9_nargs_3, 0);
+MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");

#define DB9_MULTI_STICK 0x01
#define DB9_MULTI2_STICK 0x02
@@ -76,10 +88,6 @@
#define DB9_GENESIS6_DELAY 14
#define DB9_REFRESH_TIME HZ/100

-static int db9[] __initdata = { -1, 0 };
-static int db9_2[] __initdata = { -1, 0 };
-static int db9_3[] __initdata = { -1, 0 };
-
struct db9 {
struct input_dev dev[DB9_MAX_DEVICES];
struct timer_list timer;
@@ -518,7 +526,7 @@
}
}

-static struct db9 __init *db9_probe(int *config)
+static struct db9 __init *db9_probe(int *config, int nargs)
{
struct db9 *db9;
struct parport *pp;
@@ -526,6 +534,12 @@

if (config[0] < 0)
return NULL;
+
+ if (nargs < 2) {
+ printk(KERN_ERR "db9.c: Device type must be specified.\n");
+ return NULL;
+ }
+
if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
printk(KERN_ERR "db9.c: bad config\n");
return NULL;
@@ -601,38 +615,11 @@
return db9;
}

-#ifndef MODULE
-static int __init db9_setup(char *str)
-{
- int i, ints[3];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 2; i++) db9[i] = ints[i + 1];
- return 1;
-}
-static int __init db9_setup_2(char *str)
-{
- int i, ints[3];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 2; i++) db9_2[i] = ints[i + 1];
- return 1;
-}
-static int __init db9_setup_3(char *str)
-{
- int i, ints[3];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 2; i++) db9_3[i] = ints[i + 1];
- return 1;
-}
-__setup("db9=", db9_setup);
-__setup("db9_2=", db9_setup_2);
-__setup("db9_3=", db9_setup_3);
-#endif
-
int __init db9_init(void)
{
- db9_base[0] = db9_probe(db9);
- db9_base[1] = db9_probe(db9_2);
- db9_base[2] = db9_probe(db9_3);
+ db9_base[0] = db9_probe(db9, db9_nargs);
+ db9_base[1] = db9_probe(db9_2, db9_nargs_2);
+ db9_base[2] = db9_probe(db9_3, db9_nargs_3);

if (db9_base[0] || db9_base[1] || db9_base[2])
return 0;
diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c Tue Mar 16 13:18:48 2004
+++ b/drivers/input/joystick/gamecon.c Tue Mar 16 13:18:48 2004
@@ -35,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/parport.h>
#include <linux/input.h>
@@ -43,10 +44,22 @@
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
MODULE_LICENSE("GPL");

-MODULE_PARM(gc, "2-6i");
-MODULE_PARM(gc_2,"2-6i");
-MODULE_PARM(gc_3,"2-6i");
-MODULE_PARM(gc_psx_delay, "i");
+static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
+static int gc_nargs __initdata = 0;
+module_param_array_named(map, gc, int, gc_nargs, 0);
+MODULE_PARM_DESC(map, "Describers first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+
+static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
+static int gc_nargs_2 __initdata = 0;
+module_param_array_named(map2, gc_2, int, gc_nargs_2, 0);
+MODULE_PARM_DESC(map2, "Describers second set of devices");
+
+static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
+static int gc_nargs_3 __initdata = 0;
+module_param_array_named(map3, gc_3, int, gc_nargs_3, 0);
+MODULE_PARM_DESC(map3, "Describers third set of devices");
+
+/* see also gs_psx_delay parameter in PSX support section */

#define GC_SNES 1
#define GC_NES 2
@@ -71,10 +84,6 @@

static struct gc *gc_base[3];

-static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
-
static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };

static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
@@ -232,6 +241,9 @@
#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */

static int gc_psx_delay = GC_PSX_DELAY;
+module_param_named(psx_delay, gc_psx_delay, uint, 0);
+MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
+
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
@@ -468,7 +480,7 @@
}
}

-static struct gc __init *gc_probe(int *config)
+static struct gc __init *gc_probe(int *config, int nargs)
{
struct gc *gc;
struct parport *pp;
@@ -478,6 +490,11 @@
if (config[0] < 0)
return NULL;

+ if (nargs < 2) {
+ printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+ return NULL;
+ }
+
pp = parport_find_number(config[0]);

if (!pp) {
@@ -507,7 +524,7 @@
gc->timer.data = (long) gc;
gc->timer.function = gc_timer;

- for (i = 0; i < 5; i++) {
+ for (i = 0; i < nargs - 1; i++) {

if (!config[i + 1])
continue;
@@ -632,44 +649,11 @@
return gc;
}

-#ifndef MODULE
-static int __init gc_setup(char *str)
-{
- int i, ints[7];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 6; i++) gc[i] = ints[i + 1];
- return 1;
-}
-static int __init gc_setup_2(char *str)
-{
- int i, ints[7];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 6; i++) gc_2[i] = ints[i + 1];
- return 1;
-}
-static int __init gc_setup_3(char *str)
-{
- int i, ints[7];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1];
- return 1;
-}
-static int __init gc_psx_setup(char *str)
-{
- get_option(&str, &gc_psx_delay);
- return 1;
-}
-__setup("gc=", gc_setup);
-__setup("gc_2=", gc_setup_2);
-__setup("gc_3=", gc_setup_3);
-__setup("gc_psx_delay=", gc_psx_setup);
-#endif
-
int __init gc_init(void)
{
- gc_base[0] = gc_probe(gc);
- gc_base[1] = gc_probe(gc_2);
- gc_base[2] = gc_probe(gc_3);
+ gc_base[0] = gc_probe(gc, gc_nargs);
+ gc_base[1] = gc_probe(gc_2, gc_nargs_2);
+ gc_base[2] = gc_probe(gc_3, gc_nargs_3);

if (gc_base[0] || gc_base[1] || gc_base[2])
return 0;
diff -Nru a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
--- a/drivers/input/joystick/turbografx.c Tue Mar 16 13:18:48 2004
+++ b/drivers/input/joystick/turbografx.c Tue Mar 16 13:18:48 2004
@@ -35,15 +35,27 @@
#include <linux/parport.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/init.h>

MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
MODULE_LICENSE("GPL");

-MODULE_PARM(tgfx, "2-8i");
-MODULE_PARM(tgfx_2, "2-8i");
-MODULE_PARM(tgfx_3, "2-8i");
+static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+static int tgfx_nargs __initdata = 0;
+module_param_array_named(map, tgfx, int, tgfx_nargs, 0);
+MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
+
+static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+static int tgfx_nargs_2 __initdata = 0;
+module_param_array_named(map2, tgfx_2, int, tgfx_nargs_2, 0);
+MODULE_PARM_DESC(map2, "Describes second set of devices");
+
+static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+static int tgfx_nargs_3 __initdata = 0;
+module_param_array_named(map3, tgfx_3, int, tgfx_nargs_3, 0);
+MODULE_PARM_DESC(map3, "Describes third set of devices");

#define TGFX_REFRESH_TIME HZ/100 /* 10 ms */

@@ -58,10 +70,6 @@
#define TGFX_TOP 0x01
#define TGFX_TOP2 0x08

-static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-
static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
static char *tgfx_name = "TurboGraFX Multisystem joystick";

@@ -133,7 +141,7 @@
* tgfx_probe() probes for tg gamepads.
*/

-static struct tgfx __init *tgfx_probe(int *config)
+static struct tgfx __init *tgfx_probe(int *config, int nargs)
{
struct tgfx *tgfx;
struct parport *pp;
@@ -142,6 +150,11 @@
if (config[0] < 0)
return NULL;

+ if (nargs < 2) {
+ printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
+ return NULL;
+ }
+
pp = parport_find_number(config[0]);

if (!pp) {
@@ -171,7 +184,7 @@

tgfx->sticks = 0;

- for (i = 0; i < 7; i++)
+ for (i = 0; i < nargs - 1; i++)
if (config[i+1] > 0 && config[i+1] < 6) {

tgfx->sticks |= (1 << i);
@@ -212,38 +225,11 @@
return tgfx;
}

-#ifndef MODULE
-static int __init tgfx_setup(char *str)
-{
- int i, ints[9];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 8; i++) tgfx[i] = ints[i + 1];
- return 1;
-}
-static int __init tgfx_setup_2(char *str)
-{
- int i, ints[9];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 8; i++) tgfx_2[i] = ints[i + 1];
- return 1;
-}
-static int __init tgfx_setup_3(char *str)
-{
- int i, ints[9];
- get_options(str, ARRAY_SIZE(ints), ints);
- for (i = 0; i <= ints[0] && i < 8; i++) tgfx_3[i] = ints[i + 1];
- return 1;
-}
-__setup("tgfx=", tgfx_setup);
-__setup("tgfx_2=", tgfx_setup_2);
-__setup("tgfx_3=", tgfx_setup_3);
-#endif
-
int __init tgfx_init(void)
{
- tgfx_base[0] = tgfx_probe(tgfx);
- tgfx_base[1] = tgfx_probe(tgfx_2);
- tgfx_base[2] = tgfx_probe(tgfx_3);
+ tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs);
+ tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2);
+ tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3);

if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
return 0;

2004-03-16 14:34:38

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 23/44] Use __obsolete_setup() in input drivers to warn about obsolete kernel params

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

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

[email protected], 2004-03-03 00:36:59-05:00, [email protected]
Input: use __obsolete_setup to document removed (renamed)
options so users will have a clue why the options
do not work anymore


joystick/amijoy.c | 2 ++
joystick/analog.c | 2 ++
joystick/db9.c | 4 ++++
joystick/gamecon.c | 6 ++++++
joystick/turbografx.c | 4 ++++
keyboard/atkbd.c | 4 ++++
mouse/98busmouse.c | 2 ++
mouse/inport.c | 2 ++
mouse/logibm.c | 2 ++
mouse/psmouse-base.c | 6 ++++++
serio/i8042.c | 7 +++++++
11 files changed, 41 insertions(+)

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

diff -Nru a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
--- a/drivers/input/joystick/amijoy.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/joystick/amijoy.c Tue Mar 16 13:18:41 2004
@@ -50,6 +50,8 @@
module_param_array_named(map, amijoy, uint, amijoy_nargs, 0);
MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");

+__obsolete_setup("amijoy=");
+
static int amijoy_used[2] = { 0, 0 };
static struct input_dev amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- a/drivers/input/joystick/analog.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/joystick/analog.c Tue Mar 16 13:18:41 2004
@@ -56,6 +56,8 @@
module_param_array_named(map, js, charp, js_nargs, 0);
MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");

+__obsolete_setup("js=");
+
/*
* Times, feature definitions.
*/
diff -Nru a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
--- a/drivers/input/joystick/db9.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/joystick/db9.c Tue Mar 16 13:18:41 2004
@@ -58,6 +58,10 @@
module_param_array_named(dev3, db9_3, int, db9_nargs_3, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");

+__obsolete_setup("db9=");
+__obsolete_setup("db9_2=");
+__obsolete_setup("db9_3=");
+
#define DB9_MULTI_STICK 0x01
#define DB9_MULTI2_STICK 0x02
#define DB9_GENESIS_PAD 0x03
diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/joystick/gamecon.c Tue Mar 16 13:18:41 2004
@@ -59,6 +59,10 @@
module_param_array_named(map3, gc_3, int, gc_nargs_3, 0);
MODULE_PARM_DESC(map3, "Describers third set of devices");

+__obsolete_setup("gc=");
+__obsolete_setup("gc_2=");
+__obsolete_setup("gc_3=");
+
/* see also gs_psx_delay parameter in PSX support section */

#define GC_SNES 1
@@ -243,6 +247,8 @@
static int gc_psx_delay = GC_PSX_DELAY;
module_param_named(psx_delay, gc_psx_delay, uint, 0);
MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
+
+__obsolete_setup("gc_psx_delay=");

static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
diff -Nru a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
--- a/drivers/input/joystick/turbografx.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/joystick/turbografx.c Tue Mar 16 13:18:41 2004
@@ -57,6 +57,10 @@
module_param_array_named(map3, tgfx_3, int, tgfx_nargs_3, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");

+__obsolete_setup("tgfx=");
+__obsolete_setup("tgfx_2=");
+__obsolete_setup("tgfx_3=");
+
#define TGFX_REFRESH_TIME HZ/100 /* 10 ms */

#define TGFX_TRIGGER 0x08
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:18:41 2004
@@ -48,6 +48,10 @@
module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");

+__obsolete_setup("atkbd_set=");
+__obsolete_setup("atkbd_reset");
+__obsolete_setup("atkbd_softrepeat=");
+
/*
* Scancode to keycode tables. These are just the default setting, and
* are loadable via an userland utility.
diff -Nru a/drivers/input/mouse/98busmouse.c b/drivers/input/mouse/98busmouse.c
--- a/drivers/input/mouse/98busmouse.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/mouse/98busmouse.c Tue Mar 16 13:18:41 2004
@@ -74,6 +74,8 @@
module_param_named(irq, pc98bm_irq, uint, 0);
MODULE_PARM_DESC(irq, "IRQ number (13=default)");

+__obsolete_setup("pc98bm_irq=");
+
static int pc98bm_used = 0;

static irqreturn_t pc98bm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff -Nru a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
--- a/drivers/input/mouse/inport.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/mouse/inport.c Tue Mar 16 13:18:41 2004
@@ -85,6 +85,8 @@
module_param_named(irq, inport_irq, uint, 0);
MODULE_PARM_DESC(irq, "IRQ number (5=default)");

+__obsolete_setup("inport_irq=");
+
static int inport_used;

static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff -Nru a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
--- a/drivers/input/mouse/logibm.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/mouse/logibm.c Tue Mar 16 13:18:41 2004
@@ -75,6 +75,8 @@
module_param_named(irq, logibm_irq, uint, 0);
MODULE_PARM_DESC(irq, "IRQ number (5=default)");

+__obsolete_setup("logibm_irq=");
+
static int logibm_used = 0;

static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:41 2004
@@ -47,6 +47,12 @@
module_param_named(resetafter, psmouse_resetafter, uint, 0);
MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");

+__obsolete_setup("psmouse_noext");
+__obsolete_setup("psmouse_resolution=");
+__obsolete_setup("psmouse_smartscroll=");
+__obsolete_setup("psmouse_resetafter=");
+__obsolete_setup("psmouse_rate=");
+
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};

/*
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Tue Mar 16 13:18:41 2004
+++ b/drivers/input/serio/i8042.c Tue Mar 16 13:18:41 2004
@@ -52,6 +52,13 @@
module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");

+__obsolete_setup("i8042_noaux");
+__obsolete_setup("i8042_nomux");
+__obsolete_setup("i8042_unlock");
+__obsolete_setup("i8042_reset");
+__obsolete_setup("i8042_direct");
+__obsolete_setup("i8042_dumbkbd");
+
#undef DEBUG
#include "i8042.h"


2004-03-16 14:38:48

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 22/44] Create __obsolete_setup() macro to warn users about obsolete kernel params

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

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

[email protected], 2004-03-03 00:35:47-05:00, [email protected]
Setup: introduce __obsolete_setup macro to denote truly obsolete
parameters. Whenever such parameter is specified kernel
will complain that "Parameter %s is obsolete, ignored"


include/linux/init.h | 22 +++++++++++++++++-----
init/main.c | 7 +++++--
2 files changed, 22 insertions(+), 7 deletions(-)

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

diff -Nru a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h Tue Mar 16 13:18:44 2004
+++ b/include/linux/init.h Tue Mar 16 13:18:44 2004
@@ -110,12 +110,21 @@
};

/* OBSOLETE: see moduleparam.h for the right way. */
-#define __setup(str, fn) \
- static char __setup_str_##fn[] __initdata = str; \
- static struct obs_kernel_param __setup_##fn \
+#define __setup_param(str, unique_id, fn) \
+ static char __setup_str_##unique_id[] __initdata = str; \
+ static struct obs_kernel_param __setup_##unique_id \
__attribute_used__ \
__attribute__((__section__(".init.setup"))) \
- = { __setup_str_##fn, fn }
+ = { __setup_str_##unique_id, fn }
+
+#define __setup_null_param(str, unique_id) \
+ __setup_param(str, unique_id, NULL)
+
+#define __setup(str, fn) \
+ __setup_param(str, fn, fn)
+
+#define __obsolete_setup(str) \
+ __setup_null_param(str, __LINE__)

#endif /* __ASSEMBLY__ */

@@ -172,7 +181,10 @@
{ return exitfn; } \
void cleanup_module(void) __attribute__((alias(#exitfn)));

-#define __setup(str,func) /* nothing */
+#define __setup_param(str, unique_id, fn) /* nothing */
+#define __setup_null_param(str, unique_id) /* nothing */
+#define __setup(str, func) /* nothing */
+#define __obsolete_setup(str) /* nothing */
#endif

/* Data marked not to be saved by software_suspend() */
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c Tue Mar 16 13:18:44 2004
+++ b/init/main.c Tue Mar 16 13:18:44 2004
@@ -155,8 +155,11 @@
p = &__setup_start;
do {
int n = strlen(p->str);
- if (!strncmp(line,p->str,n)) {
- if (p->setup_func(line+n))
+ if (!strncmp(line, p->str, n)) {
+ if (!p->setup_func) {
+ printk(KERN_WARNING "Parameter %s is obsolete, ignored\n", p->str);
+ return 1;
+ } else if (p->setup_func(line + n))
return 1;
}
p++;

2004-03-16 14:38:48

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 25/44] Only reprobe on PS/2 HW when the HW sends 0xaa

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

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

[email protected], 2004-03-03 11:50:22+01:00, [email protected]
input: Only do hotplug on PS/2 HW when the HW sends 0xaa. This
avoids problems with broken USB->PS/2 legacy emulation
in certain BIOSes.


serio.c | 3 +++
1 files changed, 3 insertions(+)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c Tue Mar 16 13:18:33 2004
+++ b/drivers/input/serio/serio.c Tue Mar 16 13:18:33 2004
@@ -195,6 +195,9 @@
ret = serio->dev->interrupt(serio, data, flags, regs);
} else {
if (!flags) {
+ if ((serio->type == SERIO_8042 ||
+ serio->type == SERIO_8042_XL) && (data != 0xaa))
+ return ret;
serio_rescan(serio);
ret = IRQ_HANDLED;
}

2004-03-16 14:42:48

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 12/44] Credit to Panagiotis Issaris for Graphire 3 support

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

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

[email protected], 2004-01-26 18:35:00+01:00, [email protected]
input: Credit to Panagiotis Issaris for Graphire 3 support.


wacom.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletion(-)

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

diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c Tue Mar 16 13:19:36 2004
+++ b/drivers/usb/input/wacom.c Tue Mar 16 13:19:36 2004
@@ -1,7 +1,7 @@
/*
* USB Wacom Graphire and Wacom Intuos tablet support
*
- * Copyright (c) 2000-2002 Vojtech Pavlik <[email protected]>
+ * Copyright (c) 2000-2004 Vojtech Pavlik <[email protected]>
* Copyright (c) 2000 Andreas Bach Aaen <[email protected]>
* Copyright (c) 2000 Clifford Wolf <[email protected]>
* Copyright (c) 2000 Sam Mosel <[email protected]>
@@ -9,6 +9,7 @@
* Copyright (c) 2000 Daniel Egger <[email protected]>
* Copyright (c) 2001 Frederic Lepied <[email protected]>
* Copyright (c) 2002 Ping Cheng <[email protected]>
+ * Copyright (c) 2004 Panagiotis Issaris <[email protected]>
*
* 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
*/

/*

2004-03-16 14:42:49

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 9/44] Support for scroll wheel on Office keyboards

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

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

[email protected], 2004-01-26 13:56:47+01:00, [email protected]
input: Add support for scroll wheel on MS Office and similar keyboards.


atkbd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 58 insertions(+), 7 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:47 2004
+++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:47 2004
@@ -33,18 +33,18 @@
MODULE_PARM(atkbd_set, "1i");
MODULE_PARM(atkbd_reset, "1i");
MODULE_PARM(atkbd_softrepeat, "1i");
+MODULE_PARM(atkbd_scroll, "1i");
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)");
+
#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 +52,10 @@
module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");

+static int atkbd_scroll;
+module_parm_named(scroll, atkbd_scroll, bool, 0);
+MODULE_PARM_DESC_(scroll, "Enable scroll-wheel on office keyboards");
+
/*
* Scancode to keycode tables. These are just the default setting, and
* are loadable via an userland utility.
@@ -127,11 +131,11 @@
#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 +145,22 @@
#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
*/
@@ -189,6 +209,7 @@
{
struct atkbd *atkbd = serio->private;
unsigned int code = data;
+ int scroll = 0, click = -1;
int value;

#ifdef ATKBD_DEBUG
@@ -284,6 +305,21 @@
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 +341,13 @@
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;
@@ -705,15 +748,23 @@

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 +775,7 @@
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);

2004-03-16 14:47:15

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 6/44] Fix sunkbd.c to work with serport

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

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

[email protected], 2004-01-26 13:25:24+01:00, [email protected]
input: Fix sunkbd.c to work with serport. Must sleep.


sunkbd.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)

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

diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c Tue Mar 16 13:19:57 2004
+++ b/drivers/input/keyboard/sunkbd.c Tue Mar 16 13:19:57 2004
@@ -77,6 +77,7 @@
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 @@

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_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 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 @@
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 @@
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;

2004-03-16 14:42:48

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 13/44] Remove the obsolete busmouse.c helper driver

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

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

[email protected], 2004-01-27 21:01:27+01:00, [email protected]
input: Remove the obsolete "busmouse.c" helper driver.


arch/arm26/Kconfig | 5 -----
drivers/char/Kconfig | 24 ------------------------
drivers/char/Makefile | 1 -
include/linux/miscdevice.h | 1 -
4 files changed, 31 deletions(-)

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

diff -Nru a/arch/arm26/Kconfig b/arch/arm26/Kconfig
--- a/arch/arm26/Kconfig Tue Mar 16 13:19:32 2004
+++ b/arch/arm26/Kconfig Tue Mar 16 13:19:32 2004
@@ -216,11 +216,6 @@

source "drivers/char/Kconfig"

-config KBDMOUSE
- bool
- depends on ARCH_ACORN && BUSMOUSE=y
- default y
-
source "drivers/media/Kconfig"

source "fs/Kconfig"
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig Tue Mar 16 13:19:32 2004
+++ b/drivers/char/Kconfig Tue Mar 16 13:19:32 2004
@@ -588,30 +588,6 @@
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 -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile Tue Mar 16 13:19:32 2004
+++ b/drivers/char/Makefile Tue Mar 16 13:19:32 2004
@@ -49,7 +49,6 @@
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 -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h Tue Mar 16 13:19:32 2004
+++ b/include/linux/miscdevice.h Tue Mar 16 13:19:32 2004
@@ -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

2004-03-16 14:47:14

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 7/44] request_region() instead of check_region() in ns558.c

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

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

[email protected], 2004-01-26 13:25:57+01:00, [email protected]
input: Use request_region() instead of check_region() in ns558.c
it's both safer and correct.


ns558.c | 35 ++++++++++++++++++++++++-----------
1 files changed, 24 insertions(+), 11 deletions(-)

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

diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
--- a/drivers/input/gameport/ns558.c Tue Mar 16 13:19:54 2004
+++ b/drivers/input/gameport/ns558.c Tue Mar 16 13:19:54 2004
@@ -77,7 +77,7 @@
* No one should be using this address.
*/

- if (check_region(io, 1))
+ if (!request_region(io, 1, "ns558-isa"))
return;

/*
@@ -89,7 +89,8 @@
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 @@

if (u == v) {
outb(c, io);
- return;
+ i = 0;
+ goto out;
}
wait_ms(3);
/*
@@ -110,7 +112,8 @@
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 @@

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 @@
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 @@
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 @@
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

2004-03-16 14:47:13

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 1/44] Fix hid-core for devices with #usages < #values

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

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

[email protected], 2004-01-26 13:15:32+01:00, [email protected]
input: Fix hid-core for devices that have less usages than values
in a hid report. We could iterate beyond the end of array of
usages before.


hid-core.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Tue Mar 16 13:20:15 2004
+++ b/drivers/usb/input/hid-core.c Tue Mar 16 13:20:15 2004
@@ -224,6 +224,9 @@
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 @@
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;

2004-03-16 14:47:13

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 3/44] HID quirk (badpad) for Saitek Rumblepad

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

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

[email protected], 2004-01-26 13:17:44+01:00, [email protected]
input: It looks like the Saitek RumblePad needs a BADPAD entry.


hid-core.c | 4 ++++
1 files changed, 4 insertions(+)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Tue Mar 16 13:20:08 2004
+++ b/drivers/usb/input/hid-core.c Tue Mar 16 13:20:08 2004
@@ -1367,6 +1367,9 @@
#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;
@@ -1419,6 +1422,7 @@
{ 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_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ 0, 0 }
};


2004-03-16 14:47:12

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 5/44] .ko module names for acm.txt

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

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

[email protected], 2004-01-26 13:23:40+01:00, [email protected]
usb: Minor documentation fix reflecting new USB module names in acm.txt


acm.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

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

diff -Nru a/Documentation/usb/acm.txt b/Documentation/usb/acm.txt
--- a/Documentation/usb/acm.txt Tue Mar 16 13:20:01 2004
+++ b/Documentation/usb/acm.txt Tue Mar 16 13:20:01 2004
@@ -28,7 +28,7 @@

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 @@

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.

2004-03-16 14:47:11

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 4/44] HID quirk for another A4Tech dual-wheel mouse

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

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

[email protected], 2004-01-26 13:18:17+01:00, [email protected]
input: Add support for another a4tech 2-wheel USB mouse, with
a Cypress ID this time. Also rearrange the HID blacklist
a bit - it has grown too long.


hid-core.c | 48 +++++++++++++++++++++++++++++-------------------
hid-input.c | 7 ++++---
2 files changed, 33 insertions(+), 22 deletions(-)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Tue Mar 16 13:20:05 2004
+++ b/drivers/usb/input/hid-core.c Tue Mar 16 13:20:05 2004
@@ -1322,7 +1322,6 @@
#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

@@ -1361,6 +1360,9 @@
#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

@@ -1375,6 +1377,23 @@
__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 },
@@ -1396,33 +1415,24 @@
{ 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 -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c Tue Mar 16 13:20:05 2004
+++ b/drivers/usb/input/hid-input.c Tue Mar 16 13:20:05 2004
@@ -432,20 +432,21 @@
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 @@
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);

2004-03-16 14:47:09

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 2/44] Add ioctl to hiddev to set multiple usages at once

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

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

[email protected], 2004-01-26 13:16:54+01:00, [email protected]
input: Add a new ioctl to hiddev, which allows multiple usages to
be set in a single request. Also fixes sizes of fields
in hiddev structs to use _uXX types.


drivers/usb/input/hiddev.c | 79 +++++++++++++++++++++++++++++++--------------
include/linux/hiddev.h | 74 ++++++++++++++++++++++++------------------
2 files changed, 98 insertions(+), 55 deletions(-)

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

diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c Tue Mar 16 13:20:12 2004
+++ b/drivers/usb/input/hiddev.c Tue Mar 16 13:20:12 2004
@@ -403,7 +403,8 @@
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 @@
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 -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
--- a/include/linux/hiddev.h Tue Mar 16 13:20:12 2004
+++ b/include/linux/hiddev.h Tue Mar 16 13:20:12 2004
@@ -39,33 +39,33 @@
};

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 @@
#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 @@
#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
@@ -160,6 +168,10 @@
#define HIDIOCGCOLLECTIONINDEX _IOW('H', 0x10, 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

2004-03-16 15:20:10

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 8/44] Don't reinitialize scancode map after sleep in atkbd.c

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

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

[email protected], 2004-01-26 13:29:36+01:00, [email protected]
input: Bail out in atkbd.c if scancode set is changed, don't
reinitialize scancode map. This is even more anoying than
a new keyboard device in the unlikely case of set change.


atkbd.c | 38 ++++++--------------------------------
1 files changed, 6 insertions(+), 32 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:50 2004
+++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:50 2004
@@ -741,45 +741,19 @@
{
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;
}

2004-03-16 15:26:10

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 10/44] Make enabling IBM RapidAccess special features its own option

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

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

[email protected], 2004-01-26 13:57:19+01:00, [email protected]
input: Create an extra option for enabling IBM RapidAccess keyboard
special features (atkbd.extra), instead of abusing the
atkbd.set option for this.


Documentation/kernel-parameters.txt | 13 ++++++++++---
drivers/input/keyboard/atkbd.c | 35 ++++++++++++++++++++---------------
2 files changed, 30 insertions(+), 18 deletions(-)

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

diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt Tue Mar 16 13:19:43 2004
+++ b/Documentation/kernel-parameters.txt Tue Mar 16 13:19:43 2004
@@ -157,11 +157,18 @@

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 -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:43 2004
+++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:43 2004
@@ -33,12 +33,11 @@
MODULE_PARM(atkbd_set, "1i");
MODULE_PARM(atkbd_reset, "1i");
MODULE_PARM(atkbd_softrepeat, "1i");
-MODULE_PARM(atkbd_scroll, "1i");
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;
@@ -53,8 +52,12 @@
MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");

static int atkbd_scroll;
-module_parm_named(scroll, atkbd_scroll, bool, 0);
-MODULE_PARM_DESC_(scroll, "Enable scroll-wheel on office keyboards");
+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
@@ -175,6 +178,7 @@
unsigned char cmdbuf[4];
unsigned char cmdcnt;
unsigned char set;
+ unsigned char extra;
unsigned char release;
int lastkey;
volatile signed char ack;
@@ -463,7 +467,7 @@
| (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)
@@ -572,21 +576,22 @@
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;
@@ -739,9 +744,9 @@
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);

2004-03-16 15:29:17

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 16/44] Whitespace in atkbd.c

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

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

[email protected], 2004-03-03 00:25:49-05:00, [email protected]
Atkbd: whitespace fixes


atkbd.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:10 2004
+++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:10 2004
@@ -202,7 +202,7 @@
atkbd->resend = 1;
goto out;
}
-
+
if (!flags && data == ATKBD_RET_ACK)
atkbd->resend = 0;
#endif
@@ -276,7 +276,7 @@
case ATKBD_KEY_UNKNOWN:
printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
atkbd->release ? "released" : "pressed",
- atkbd->translated ? "translated" : "raw",
+ atkbd->translated ? "translated" : "raw",
atkbd->set, code, serio->phys);
if (atkbd->translated && atkbd->set == 2 && code == 0x7a)
printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access"
@@ -353,7 +353,7 @@
if (receive && param)
for (i = 0; i < receive; i++)
atkbd->cmdbuf[(receive - 1) - i] = param[i];
-
+
if (command & 0xff)
if (atkbd_sendbyte(atkbd, command & 0xff))
return (atkbd->cmdcnt = 0) - 1;
@@ -373,7 +373,7 @@
atkbd->cmdcnt = 0;
break;
}
-
+
udelay(1);
}

@@ -466,7 +466,7 @@
*/

if (atkbd_reset)
- if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
+ if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);

/*
@@ -529,7 +529,7 @@
return 3;
}

- if (atkbd_set != 2)
+ if (atkbd_set != 2)
if (!atkbd_command(atkbd, param, ATKBD_CMD_OK_GETID)) {
atkbd->id = param[0] << 8 | param[1];
return 2;
@@ -541,7 +541,7 @@
return 4;
}

- if (atkbd_set != 3)
+ if (atkbd_set != 3)
return 2;

param[0] = 3;
@@ -637,7 +637,7 @@

switch (serio->type & SERIO_TYPE) {

- case SERIO_8042_XL:
+ case SERIO_8042_XL:
atkbd->translated = 1;
case SERIO_8042:
if (serio->write)
@@ -650,7 +650,7 @@
kfree(atkbd);
return;
}
-
+
if (atkbd->write) {
atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
@@ -687,7 +687,7 @@
kfree(atkbd);
return;
}
-
+
atkbd->set = atkbd_set_3(atkbd);
atkbd_enable(atkbd);


2004-03-16 15:28:52

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 14/44] Fix a warning in i8042.c

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

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

[email protected], 2004-02-09 02:10:02+01:00, [email protected]
input: Fix a warning in i8042.c


i8042.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Tue Mar 16 13:19:25 2004
+++ b/drivers/input/serio/i8042.c Tue Mar 16 13:19:25 2004
@@ -375,7 +375,7 @@
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
- unsigned char str, data;
+ unsigned char str, data = 0;
unsigned int dfl;
int ret;


2004-03-16 15:29:16

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 15/44] Add serio entries for LK keyboards.

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

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

[email protected], 2004-03-02 13:47:14+01:00, [email protected]
input: Add serio entries for LK keyboards.


serio.h | 2 ++
1 files changed, 2 insertions(+)

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

diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h Tue Mar 16 13:19:14 2004
+++ b/include/linux/serio.h Tue Mar 16 13:19:14 2004
@@ -117,6 +117,7 @@
#define SERIO_MZ 0x05
#define SERIO_MZP 0x06
#define SERIO_MZPP 0x07
+#define SERIO_VSXXXAA 0x08
#define SERIO_SUNKBD 0x10
#define SERIO_WARRIOR 0x18
#define SERIO_SPACEORB 0x19
@@ -134,6 +135,7 @@
#define SERIO_HIL 0x25
#define SERIO_SNES232 0x26
#define SERIO_SEMTECH 0x27
+#define SERIO_LKKBD 0x28

#define SERIO_ID 0xff00UL
#define SERIO_EXTRA 0xff0000UL

2004-03-16 14:38:49

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 17/44] Automatically decide how strictly to check the protocol in synaptics

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

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

[email protected], 2004-03-03 00:29:09-05:00, [email protected]
Input: Switch between strict/relaxed synaptics protocol checks based on
data in the first full data packet. Having strict checks helps
getting rid of bad data after losing sync, but not all harware
implements strict protocol.


synaptics.c | 53 +++++++++++++++++++++++++++++++++++++++++------------
synaptics.h | 7 +++++++
2 files changed, 48 insertions(+), 12 deletions(-)

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

diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c Tue Mar 16 13:19:03 2004
+++ b/drivers/input/mouse/synaptics.c Tue Mar 16 13:19:03 2004
@@ -435,6 +435,8 @@
goto init_fail;
}

+ priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
+
if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
synaptics_pt_create(psmouse);

@@ -602,19 +604,42 @@
input_sync(dev);
}

-static int synaptics_validate_byte(struct psmouse *psmouse)
+static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
{
- static unsigned char newabs_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
- static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
- static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
- static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
- struct synaptics_data *priv = psmouse->private;
- int idx = psmouse->pktcnt - 1;
+ static unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
+ static unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
+ static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
+ static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
+ static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+
+ switch (pkt_type) {
+ case SYN_NEWABS:
+ case SYN_NEWABS_RELAXED:
+ return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx];
+
+ case SYN_NEWABS_STRICT:
+ return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
+
+ case SYN_OLDABS:
+ return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];

- if (SYN_MODEL_NEWABS(priv->model_id))
- return (psmouse->packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
- else
- return (psmouse->packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
+ default:
+ printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type);
+ return 0;
+ }
+}
+
+static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
+{
+ int i;
+
+ for (i = 0; i < 5; i++)
+ if (!synaptics_validate_byte(psmouse->packet, i, SYN_NEWABS_STRICT)) {
+ printk(KERN_INFO "synaptics: using relaxed packet validation\n");
+ return SYN_NEWABS_RELAXED;
+ }
+
+ return SYN_NEWABS_STRICT;
}

void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
@@ -630,13 +655,17 @@
printk(KERN_NOTICE "Synaptics driver resynced.\n");
}

+ if (unlikely(priv->pkt_type == SYN_NEWABS))
+ priv->pkt_type = synaptics_detect_pkt_type(psmouse);
+
if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
else
synaptics_process_packet(psmouse);
psmouse->pktcnt = 0;

- } else if (psmouse->pktcnt && !synaptics_validate_byte(psmouse)) {
+ } else if (psmouse->pktcnt &&
+ !synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) {
printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
psmouse->pktcnt = 0;
if (++priv->out_of_sync == psmouse_resetafter) {
diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
--- a/drivers/input/mouse/synaptics.h Tue Mar 16 13:19:03 2004
+++ b/drivers/input/mouse/synaptics.h Tue Mar 16 13:19:03 2004
@@ -70,6 +70,12 @@
#define SYN_PS_SET_MODE2 0x14
#define SYN_PS_CLIENT_CMD 0x28

+/* synaptics packet types */
+#define SYN_NEWABS 0
+#define SYN_NEWABS_STRICT 1
+#define SYN_NEWABS_RELAXED 2
+#define SYN_OLDABS 3
+
/*
* A structure to describe the state of the touchpad hardware (buttons and pad)
*/
@@ -103,6 +109,7 @@
/* Data for normal processing */
unsigned int out_of_sync; /* # of packets out of sync */
int old_w; /* Previous w value */
+ unsigned char pkt_type; /* packet type - old, new, etc */
};

#endif /* _SYNAPTICS_H */

2004-03-16 15:35:23

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 19/44] Don't fail when mouse reset doesn't work

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

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

[email protected], 2004-03-03 00:31:24-05:00, [email protected]
Psmouse: some hardware does not ACK "disable streaming mode" command.
Since we already have an idea that it's a mouse device that
is present (from its response to GET ID command), instead of
aborting, issue a warning and continue.


psmouse-base.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:55 2004
+++ b/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:55 2004
@@ -442,7 +442,7 @@
*/

if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
- return -1;
+ printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);

/*
* And here we try to determine if it has any extensions over the

2004-03-16 15:35:24

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

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

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

[email protected], 2004-03-03 11:49:20+01:00, [email protected]
input: Workaround i8042 chips with broken MUX mode.


i8042.c | 5 +++++
1 files changed, 5 insertions(+)

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Tue Mar 16 13:18:37 2004
+++ b/drivers/input/serio/i8042.c Tue Mar 16 13:18:37 2004
@@ -530,6 +530,11 @@

if (i8042_enable_mux_mode(values, &mux_version))
return -1;
+
+ /* Workaround for broken chips which seem to support MUX, but in reality don't. */
+ /* They all report version 12.10 */
+ if (mux_version == 0xCA)
+ return -1;

printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
(mux_version >> 4) & 0xf, mux_version & 0xf);

2004-03-16 15:35:22

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 20/44] Add module_parm_array() helper

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

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

[email protected], 2004-03-03 00:32:43-05:00, [email protected]
Introduce module_param_array_named to allow for module options with
name different form corresponding array variable. Allows using short
(but descriptive) option names without hurting code readability.

Modeled after module_param_named.


moduleparam.h | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)

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

diff -Nru a/include/linux/moduleparam.h b/include/linux/moduleparam.h
--- a/include/linux/moduleparam.h Tue Mar 16 13:18:52 2004
+++ b/include/linux/moduleparam.h Tue Mar 16 13:18:52 2004
@@ -126,12 +126,15 @@
#define param_check_invbool(name, p) __param_check(name, p, int)

/* Comma-separated array: num is set to number they actually specified. */
-#define module_param_array(name, type, num, perm) \
+#define module_param_array_named(name, array, type, num, perm) \
static struct kparam_array __param_arr_##name \
- = { ARRAY_SIZE(name), &num, param_set_##type, param_get_##type, \
- sizeof(name[0]), name }; \
+ = { ARRAY_SIZE(array), &num, param_set_##type, param_get_##type,\
+ sizeof(array[0]), array }; \
module_param_call(name, param_array_set, param_array_get, \
&__param_arr_##name, perm)
+
+#define module_param_array(name, type, num, perm) \
+ module_param_array_named(name, name, type, num, perm)

extern int param_array_set(const char *val, struct kernel_param *kp);
extern int param_array_get(char *buffer, struct kernel_param *kp);

2004-03-16 15:35:21

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 26/44] Always assume i8042 is in XLATE mode

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

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

[email protected], 2004-03-03 15:14:01+01:00, [email protected]
input: i8042.c:
Assume the chip always is in XLATE mode, even when it doesn't
have the XLATE bit set - apparently IBM PS/2 model 70 behaves
this way.


i8042.c | 8 --------
1 files changed, 8 deletions(-)

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Tue Mar 16 13:18:29 2004
+++ b/drivers/input/serio/i8042.c Tue Mar 16 13:18:29 2004
@@ -722,14 +722,6 @@
}

/*
- * If the chip is configured into nontranslated mode by the BIOS, don't
- * bother enabling translating and be happy.
- */
-
- if (~i8042_ctr & I8042_CTR_XLATE)
- i8042_direct = 1;
-
-/*
* Set nontranslated mode for the kbd interface if requested by an option.
* After this the kbd interface becomes a simple serial in/out, like the aux
* interface is. We don't do this by default, since it can confuse notebook

2004-03-16 15:35:20

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 18/44] Whitespace fixes in psmouse.c

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

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

[email protected], 2004-03-03 00:30:04-05:00, [email protected]
Psmouse: whitespace fixes


psmouse-base.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)

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

diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:59 2004
+++ b/drivers/input/mouse/psmouse-base.c Tue Mar 16 13:18:59 2004
@@ -163,14 +163,14 @@
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->pktcnt = 0;
}
-
+
psmouse->last = jiffies;
psmouse->packet[psmouse->pktcnt++] = data;

if (psmouse->packet[0] == PSMOUSE_RET_BAT) {
if (psmouse->pktcnt == 1)
goto out;
-
+
if (psmouse->pktcnt == 2) {
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
psmouse->state = PSMOUSE_IGNORE;
@@ -258,7 +258,7 @@
return (psmouse->cmdcnt = 0) - 1;

while (psmouse->cmdcnt && timeout--) {
-
+
if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT &&
timeout > 100000) /* do not run in a endless loop */
timeout = 100000; /* 1 sec */
@@ -497,7 +497,7 @@
static void psmouse_initialize(struct psmouse *psmouse)
{
unsigned char param[2];
-
+
/*
* We set the mouse report rate, resolution and scaling.
*/
@@ -571,7 +571,7 @@
static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
{
struct psmouse *psmouse;
-
+
if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
(serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
return;
@@ -603,7 +603,7 @@
serio->private = NULL;
return;
}
-
+
sprintf(psmouse->devname, "%s %s %s",
psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
sprintf(psmouse->phys, "%s/input0",
@@ -617,7 +617,7 @@
psmouse->dev.id.version = psmouse->model;

input_register_device(&psmouse->dev);
-
+
printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);

psmouse_initialize(psmouse);

2004-03-16 15:49:10

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 11/44] Convert HP/PARISC Lasi/Dino PS/2 driver to a serio driver

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

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

[email protected], 2004-01-26 13:59:12+01:00, [email protected]
input: Convert HP/PARISC Lasi/Dino PS/2 keyboard/mouse driver
from an input driver to a serio driver.


b/drivers/input/keyboard/Kconfig | 1
b/drivers/input/keyboard/hpps2atkbd.h | 178 ++++----
b/drivers/input/misc/Kconfig | 9
b/drivers/input/misc/Makefile | 1
b/drivers/input/mouse/Kconfig | 1
b/drivers/input/serio/Kconfig | 16
b/drivers/input/serio/Makefile | 1
b/drivers/input/serio/gscps2.c | 470 ++++++++++++++++++++++
drivers/input/misc/gsc_ps2.c | 712 ----------------------------------
9 files changed, 582 insertions(+), 807 deletions(-)

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

diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
--- a/drivers/input/keyboard/Kconfig Tue Mar 16 13:19:39 2004
+++ b/drivers/input/keyboard/Kconfig Tue Mar 16 13:19:39 2004
@@ -17,6 +17,7 @@
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 -Nru a/drivers/input/keyboard/hpps2atkbd.h b/drivers/input/keyboard/hpps2atkbd.h
--- a/drivers/input/keyboard/hpps2atkbd.h Tue Mar 16 13:19:39 2004
+++ b/drivers/input/keyboard/hpps2atkbd.h Tue Mar 16 13:19:39 2004
@@ -4,14 +4,9 @@
* Copyright (c) 2004 Helge Deller <[email protected]>
* Copyright (c) 2002 Laurent Canet <[email protected]>
* Copyright (c) 2002 Thibaut Varene <[email protected]>
+ * Copyright (c) 2000 Xavier Debacker <[email protected]>
*
- * based on linux-2.4's hp_mouse.c & hp_keyb.c
- * Copyright (c) 1999 Alex deVries <[email protected]>
- * Copyright (c) 1999-2000 Philipp Rumpf <[email protected]>
- * Copyright (c) 2000 Xavier Debacker <[email protected]>
- * Copyright (c) 2000-2001 Thomas Marteau <[email protected]>
- *
- * 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 )

-static unsigned char atkbd_set2_keycode[512] = {
+/* Raw SET 2 scancode table */

- /* 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: */
-
- /* 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
+/* 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,
+
+/* 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
+
+#undef STANDARD_KEYBOARD
+#undef CONFLICT
+#undef C_07
+#undef C_11
+#undef C_14
+#undef C_58
+#undef C_61

-};
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig Tue Mar 16 13:19:39 2004
+++ b/drivers/input/misc/Kconfig Tue Mar 16 13:19:39 2004
@@ -54,12 +54,3 @@
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 -Nru a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
--- a/drivers/input/misc/Makefile Tue Mar 16 13:19:39 2004
+++ b/drivers/input/misc/Makefile Tue Mar 16 13:19:39 2004
@@ -9,4 +9,3 @@
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 -Nru a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c
--- a/drivers/input/misc/gsc_ps2.c Tue Mar 16 13:19:39 2004
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,712 +0,0 @@
-/*
- * drivers/input/misc/gsc_ps2.c
- *
- * Copyright (c) 2002 Laurent Canet <[email protected]>
- * Copyright (c) 2002 Thibaut Varene <[email protected]>
- *
- * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
- * Copyright (c) 1999 Alex deVries <[email protected]>
- * Copyright (c) 1999-2000 Philipp Rumpf <[email protected]>
- * Copyright (c) 2000 Xavier Debacker <[email protected]>
- * Copyright (c) 2000-2001 Thomas Marteau <[email protected]>
- *
- * 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 <[email protected]>, Thibaut Varene <[email protected]>");
-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 -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig Tue Mar 16 13:19:39 2004
+++ b/drivers/input/mouse/Kconfig Tue Mar 16 13:19:39 2004
@@ -17,6 +17,7 @@
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 -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig Tue Mar 16 13:19:39 2004
+++ b/drivers/input/serio/Kconfig Tue Mar 16 13:19:39 2004
@@ -20,6 +20,7 @@
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_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
@@ -104,6 +106,20 @@

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"
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile Tue Mar 16 13:19:39 2004
+++ b/drivers/input/serio/Makefile Tue Mar 16 13:19:39 2004
@@ -14,4 +14,5 @@
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 -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/input/serio/gscps2.c Tue Mar 16 13:19:39 2004
@@ -0,0 +1,470 @@
+/*
+ * drivers/input/serio/gscps2.c
+ *
+ * Copyright (c) 2004 Helge Deller <[email protected]>
+ * Copyright (c) 2002 Laurent Canet <[email protected]>
+ * Copyright (c) 2002 Thibaut Varene <[email protected]>
+ *
+ * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
+ * Copyright (c) 1999 Alex deVries <[email protected]>
+ * Copyright (c) 1999-2000 Philipp Rumpf <[email protected]>
+ * Copyright (c) 2000 Xavier Debacker <[email protected]>
+ * Copyright (c) 2000-2001 Thomas Marteau <[email protected]>
+ *
+ * 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 <[email protected]>, Thibaut Varene <[email protected]>, Helge Deller <[email protected]>");
+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);
+

2004-03-16 16:01:37

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 27/44] Add DEC LK201/LK401 keyboard support

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

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

[email protected], 2004-03-03 17:16:24+01:00, [email protected]
input: Add DEC LK201/LK401 keyboard support


Kconfig | 13 +
Makefile | 1
lkkbd.c | 625 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 639 insertions(+)

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

diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
--- a/drivers/input/keyboard/Kconfig Tue Mar 16 13:18:26 2004
+++ b/drivers/input/keyboard/Kconfig Tue Mar 16 13:18:26 2004
@@ -41,6 +41,19 @@
To compile this driver as a module, choose M here: the
module will be called sunkbd.

+config KEYBOARD_LKKBD
+ tristate "DECstation/VAXstation LK201/LK401 keyboard support"
+ depends on INPUT && INPUT_KEYBOARD
+ select SERIO
+ help
+ Say Y here if you want to use a LK201 or LK401 style serial
+ keyboard. This keyboard is also useable on PCs if you attach
+ it with the inputattach program. The connector pinout is
+ described within lkkbd.c.
+
+ To compile this driver as a module, choose M here: the
+ module will be called lkkbd.
+
config KEYBOARD_XTKBD
tristate "XT Keyboard support"
depends on INPUT && INPUT_KEYBOARD
diff -Nru a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
--- a/drivers/input/keyboard/Makefile Tue Mar 16 13:18:26 2004
+++ b/drivers/input/keyboard/Makefile Tue Mar 16 13:18:26 2004
@@ -7,6 +7,7 @@
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
+obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/input/keyboard/lkkbd.c Tue Mar 16 13:18:26 2004
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2004 by Jan-Benedict Glaw <[email protected]>
+ */
+
+/*
+ * LK keyboard driver for Linux, based on sunkbd.c (C) by Vojtech Pavlik
+ */
+
+/*
+ * DEC LK201 and LK401 keyboard driver for Linux (primary for DECstations
+ * and VAXstations, but can also be used on any standard RS232 with an
+ * adaptor).
+ *
+ * DISCLAUNER: This works for _me_. If you break anything by using the
+ * information given below, I will _not_ be lieable!
+ *
+ * RJ11 pinout: To DB9: Or DB25:
+ * 1 - RxD <----> Pin 3 (TxD) <-> Pin 2 (TxD)
+ * 2 - GND <----> Pin 5 (GND) <-> Pin 7 (GND)
+ * 4 - TxD <----> Pin 2 (RxD) <-> Pin 3 (RxD)
+ * 3 - +12V (from HDD drive connector), DON'T connect to DB9 or DB25!!!
+ *
+ * Pin numbers for DB9 and DB25 are noted on the plug (quite small:). For
+ * RJ11, it's like this:
+ *
+ * __=__ Hold the plug in front of you, cable downwards,
+ * /___/| nose is hidden behind the plug. Now, pin 1 is at
+ * |1234|| the left side, pin 4 at the right and 2 and 3 are
+ * |IIII|| in between, of course:)
+ * | ||
+ * |____|/
+ * || So the adaptor consists of three connected cables
+ * || for data transmission (RxD and TxD) and signal ground.
+ * Additionally, you have to get +12V from somewhere.
+ * Most easily, you'll get that from a floppy or HDD power connector.
+ * It's the yellow cable there (black is ground and red is +5V).
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * email or by paper mail:
+ * Jan-Benedict Glaw, Lilienstra?e 16, 33790 H?rste (near Halle/Westf.),
+ * Germany.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/workqueue.h>
+
+
+MODULE_AUTHOR ("Jan-Benedict Glaw <[email protected]>");
+MODULE_DESCRIPTION ("LK keyboard driver");
+MODULE_LICENSE ("GPL");
+
+/*
+ * Known parameters:
+ * bell_volume
+ * keyclick_volume
+ * ctrlclick_volume
+ *
+ * Please notice that there's not yet an API to set these at runtime.
+ */
+static int bell_volume = 100; /* % */
+module_param (bell_volume, int, 0);
+MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%");
+
+static int keyclick_volume = 100; /* % */
+module_param (keyclick_volume, int, 0);
+MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%");
+
+static int ctrlclick_volume = 100; /* % */
+module_param (ctrlclick_volume, int, 0);
+MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
+
+
+
+#undef LKKBD_DEBUG
+#ifdef LKKBD_DEBUG
+#define DBG(x...) printk (x)
+#else
+#define DBG(x...) do {} while (0)
+#endif
+
+/* LED control */
+#define LK_LED_WAIT 0x81
+#define LK_LED_COMPOSE 0x82
+#define LK_LED_SHIFTLOCK 0x84
+#define LK_LED_SCROLLLOCK 0x88
+#define LK_CMD_LED_ON 0x13
+#define LK_CMD_LED_OFF 0x11
+
+/* Mode control */
+#define LK_MODE_DOWN 0x80
+#define LK_MODE_AUTODOWN 0x82
+#define LK_MODE_UPDOWN 0x86
+#define LK_CMD_SET_MODE(mode,div) ((mode) | ((div) << 3))
+
+/* Misc commands */
+#define LK_CMD_ENABLE_KEYCLICK 0x1b
+#define LK_CMD_DISABLE_KEYCLICK 0x99
+#define LK_CMD_DISABLE_BELL 0xa1
+#define LK_CMD_SOUND_BELL 0xa7
+#define LK_CMD_ENABLE_BELL 0x23
+#define LK_CMD_DISABLE_CTRCLICK 0xb9
+#define LK_CMD_ENABLE_CTRCLICK 0xbb
+#define LK_CMD_SET_DEFAULTS 0xd3
+#define LK_CMD_POWERCYCLE_RESET 0xfd
+#define LK_CMD_ENABLE_LK401 0xe9
+
+/* Misc responses from keyboard */
+#define LK_ALL_KEYS_UP 0xb3
+#define LK_METRONOME 0xb4
+#define LK_OUTPUT_ERROR 0xb5
+#define LK_INPUT_ERROR 0xb6
+#define LK_KBD_LOCKED 0xb7
+#define LK_KBD_TEST_MODE_ACK 0xb8
+#define LK_PREFIX_KEY_DOWN 0xb9
+#define LK_MODE_CHANGE_ACK 0xba
+#define LK_RESPONSE_RESERVED 0xbb
+
+#define LK_NUM_KEYCODES 256
+typedef u_int16_t lk_keycode_t;
+
+
+
+static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
+ [0x56] = KEY_F1,
+ [0x57] = KEY_F2,
+ [0x58] = KEY_F3,
+ [0x59] = KEY_F4,
+ [0x5a] = KEY_F5,
+ [0x64] = KEY_F6,
+ [0x65] = KEY_F7,
+ [0x66] = KEY_F8,
+ [0x67] = KEY_F9,
+ [0x68] = KEY_F10,
+ [0x71] = KEY_F11,
+ [0x72] = KEY_F12,
+ [0x73] = KEY_F13,
+ [0x74] = KEY_F14,
+ [0x7c] = KEY_F15,
+ [0x7d] = KEY_F16,
+ [0x80] = KEY_F17,
+ [0x81] = KEY_F18,
+ [0x82] = KEY_F19,
+ [0x83] = KEY_F20,
+ [0x8a] = KEY_FIND,
+ [0x8b] = KEY_INSERT,
+ [0x8c] = KEY_DELETE,
+ [0x8d] = KEY_SELECT,
+ [0x8e] = KEY_PAGEUP,
+ [0x8f] = KEY_PAGEDOWN,
+ [0x92] = KEY_KP0,
+ [0x94] = KEY_KPDOT,
+ [0x95] = KEY_KPENTER,
+ [0x96] = KEY_KP1,
+ [0x97] = KEY_KP2,
+ [0x98] = KEY_KP3,
+ [0x99] = KEY_KP4,
+ [0x9a] = KEY_KP5,
+ [0x9b] = KEY_KP6,
+ [0x9c] = KEY_KPCOMMA,
+ [0x9d] = KEY_KP7,
+ [0x9e] = KEY_KP8,
+ [0x9f] = KEY_KP9,
+ [0xa0] = KEY_KPMINUS,
+ [0xa1] = KEY_PROG1,
+ [0xa2] = KEY_PROG2,
+ [0xa3] = KEY_PROG3,
+ [0xa4] = KEY_PROG4,
+ [0xa7] = KEY_LEFT,
+ [0xa8] = KEY_RIGHT,
+ [0xa9] = KEY_DOWN,
+ [0xaa] = KEY_UP,
+ [0xab] = KEY_RIGHTSHIFT,
+ [0xac] = KEY_LEFTALT,
+ [0xad] = KEY_COMPOSE, /* Right Compose, that is. */
+ [0xae] = KEY_LEFTSHIFT, /* Same as KEY_RIGHTSHIFT on LK201 */
+ [0xaf] = KEY_LEFTCTRL,
+ [0xb0] = KEY_CAPSLOCK,
+ [0xb1] = KEY_COMPOSE, /* Left Compose, that is. */
+ [0xb2] = KEY_RIGHTALT,
+ [0xbc] = KEY_BACKSPACE,
+ [0xbd] = KEY_ENTER,
+ [0xbe] = KEY_TAB,
+ [0xbf] = KEY_ESC,
+ [0xc0] = KEY_1,
+ [0xc1] = KEY_Q,
+ [0xc2] = KEY_A,
+ [0xc3] = KEY_Z,
+ [0xc5] = KEY_2,
+ [0xc6] = KEY_W,
+ [0xc7] = KEY_S,
+ [0xc8] = KEY_X,
+ [0xc9] = KEY_102ND,
+ [0xcb] = KEY_3,
+ [0xcc] = KEY_E,
+ [0xcd] = KEY_D,
+ [0xce] = KEY_C,
+ [0xd0] = KEY_4,
+ [0xd1] = KEY_R,
+ [0xd2] = KEY_F,
+ [0xd3] = KEY_V,
+ [0xd4] = KEY_SPACE,
+ [0xd6] = KEY_5,
+ [0xd7] = KEY_T,
+ [0xd8] = KEY_G,
+ [0xd9] = KEY_B,
+ [0xdb] = KEY_6,
+ [0xdc] = KEY_Y,
+ [0xdd] = KEY_H,
+ [0xde] = KEY_N,
+ [0xe0] = KEY_7,
+ [0xe1] = KEY_U,
+ [0xe2] = KEY_J,
+ [0xe3] = KEY_M,
+ [0xe5] = KEY_8,
+ [0xe6] = KEY_I,
+ [0xe7] = KEY_K,
+ [0xe8] = KEY_COMMA,
+ [0xea] = KEY_9,
+ [0xeb] = KEY_O,
+ [0xec] = KEY_L,
+ [0xed] = KEY_DOT,
+ [0xef] = KEY_0,
+ [0xf0] = KEY_P,
+ [0xf2] = KEY_SEMICOLON,
+ [0xf3] = KEY_SLASH,
+ [0xf5] = KEY_EQUAL,
+ [0xf6] = KEY_RIGHTBRACE,
+ [0xf7] = KEY_BACKSLASH,
+ [0xf9] = KEY_MINUS,
+ [0xfa] = KEY_LEFTBRACE,
+ [0xfb] = KEY_APOSTROPHE,
+};
+
+#define CHECK_LED(LED, BITS) do { \
+ if (test_bit (LED, lk->dev.led)) \
+ leds_on |= BITS; \
+ else \
+ leds_off |= BITS; \
+ } while (0)
+
+/*
+ * Per-keyboard data
+ */
+struct lkkbd {
+ lk_keycode_t keycode[LK_NUM_KEYCODES];
+ int ignore_bytes;
+ struct input_dev dev;
+ struct serio *serio;
+ struct work_struct tq;
+ char name[64];
+ char phys[32];
+ char type;
+ int bell_volume;
+ int keyclick_volume;
+ int ctrlclick_volume;
+};
+
+/*
+ * Calculate volume parameter byte for a given volume.
+ */
+static unsigned char
+volume_to_hw (int volume_percent)
+{
+ unsigned char ret = 0;
+
+ if (volume_percent < 0)
+ volume_percent = 0;
+ if (volume_percent > 100)
+ volume_percent = 100;
+
+ if (volume_percent >= 0)
+ ret = 7;
+ if (volume_percent >= 13) /* 12.5 */
+ ret = 6;
+ if (volume_percent >= 25)
+ ret = 5;
+ if (volume_percent >= 38) /* 37.5 */
+ ret = 4;
+ if (volume_percent >= 50)
+ ret = 3;
+ if (volume_percent >= 63) /* 62.5 */
+ ret = 2; /* This is the default volume */
+ if (volume_percent >= 75)
+ ret = 1;
+ if (volume_percent >= 88) /* 87.5 */
+ ret = 0;
+
+ ret |= 0x80;
+
+ return ret;
+}
+
+/*
+ * lkkbd_interrupt() is called by the low level driver when a character
+ * is received.
+ */
+static irqreturn_t
+lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
+ struct pt_regs *regs)
+{
+ struct lkkbd *lk = serio->private;
+ int i;
+
+ DBG (KERN_INFO "Got byte 0x%02x\n", data);
+
+ if (lk->ignore_bytes > 0) {
+ DBG (KERN_INFO "Ignoring a byte on %s\n",
+ lk->name);
+ lk->ignore_bytes--;
+ return IRQ_HANDLED;
+ }
+
+ switch (data) {
+ case LK_ALL_KEYS_UP:
+ input_regs (&lk->dev, regs);
+ for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
+ if (lk->keycode[i] != KEY_RESERVED)
+ input_report_key (&lk->dev, lk->keycode[i], 0);
+ input_sync (&lk->dev);
+ break;
+ case LK_METRONOME:
+ DBG (KERN_INFO "Got LK_METRONOME and don't "
+ "know how to handle...\n");
+ break;
+ case LK_OUTPUT_ERROR:
+ DBG (KERN_INFO "Got LK_OUTPUT_ERROR and don't "
+ "know how to handle...\n");
+ break;
+ case LK_INPUT_ERROR:
+ DBG (KERN_INFO "Got LK_INPUT_ERROR and don't "
+ "know how to handle...\n");
+ break;
+ case LK_KBD_LOCKED:
+ DBG (KERN_INFO "Got LK_KBD_LOCKED and don't "
+ "know how to handle...\n");
+ break;
+ case LK_KBD_TEST_MODE_ACK:
+ DBG (KERN_INFO "Got LK_KBD_TEST_MODE_ACK and don't "
+ "know how to handle...\n");
+ break;
+ case LK_PREFIX_KEY_DOWN:
+ DBG (KERN_INFO "Got LK_PREFIX_KEY_DOWN and don't "
+ "know how to handle...\n");
+ break;
+ case LK_MODE_CHANGE_ACK:
+ DBG (KERN_INFO "Got LK_MODE_CHANGE_ACK and ignored "
+ "it properly...\n");
+ break;
+ case LK_RESPONSE_RESERVED:
+ DBG (KERN_INFO "Got LK_RESPONSE_RESERVED and don't "
+ "know how to handle...\n");
+ break;
+ case 0x01:
+ DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
+ lk->ignore_bytes = 3;
+ schedule_work (&lk->tq);
+ break;
+
+ default:
+ if (lk->keycode[data] != KEY_RESERVED) {
+ input_regs (&lk->dev, regs);
+ if (!test_bit (lk->keycode[data], lk->dev.key))
+ input_report_key (&lk->dev, lk->keycode[data], 1);
+ else
+ input_report_key (&lk->dev, lk->keycode[data], 0);
+ input_sync (&lk->dev);
+ } else
+ printk (KERN_WARNING "%s: Unknown key with "
+ "scancode %02x on %s.\n",
+ __FILE__, data, lk->name);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * lkkbd_event() handles events from the input module.
+ */
+static int
+lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
+ int value)
+{
+ struct lkkbd *lk = dev->private;
+ unsigned char leds_on = 0;
+ unsigned char leds_off = 0;
+
+ switch (type) {
+ case EV_LED:
+ CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
+ CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
+ CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
+ CHECK_LED (LED_SLEEP, LK_LED_WAIT);
+ if (leds_on != 0) {
+ lk->serio->write (lk->serio, LK_CMD_LED_ON);
+ lk->serio->write (lk->serio, leds_on);
+ }
+ if (leds_off != 0) {
+ lk->serio->write (lk->serio, LK_CMD_LED_OFF);
+ lk->serio->write (lk->serio, leds_off);
+ }
+ return 0;
+
+ case EV_SND:
+ switch (code) {
+ case SND_CLICK:
+ if (value == 0) {
+ DBG ("%s: Deactivating key clicks\n", __FUNCTION__);
+ lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
+ lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
+ } else {
+ DBG ("%s: Activating key clicks\n", __FUNCTION__);
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
+ lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
+ lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
+ }
+ return 0;
+
+ case SND_BELL:
+ if (value != 0)
+ lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
+
+ return 0;
+ }
+ break;
+
+ default:
+ printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
+ __FUNCTION__, type, code, value);
+ }
+
+ return -1;
+}
+
+/*
+ * lkkbd_reinit() sets leds and beeps to a state the computer remembers they
+ * were in.
+ */
+static void
+lkkbd_reinit (void *data)
+{
+ struct lkkbd *lk = data;
+ int division;
+ unsigned char leds_on = 0;
+ unsigned char leds_off = 0;
+
+ /* Reset parameters */
+ lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
+
+ /* Set LEDs */
+ CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
+ CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
+ CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
+ CHECK_LED (LED_SLEEP, LK_LED_WAIT);
+ if (leds_on != 0) {
+ lk->serio->write (lk->serio, LK_CMD_LED_ON);
+ lk->serio->write (lk->serio, leds_on);
+ }
+ if (leds_off != 0) {
+ lk->serio->write (lk->serio, LK_CMD_LED_OFF);
+ lk->serio->write (lk->serio, leds_off);
+ }
+
+ /*
+ * Try to activate extended LK401 mode. This command will
+ * only work with a LK401 keyboard and grants access to
+ * LAlt, RAlt, RCompose and RShift.
+ */
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401);
+
+ /* Set all keys to UPDOWN mode */
+ for (division = 1; division <= 14; division++)
+ lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
+ division));
+
+ /* Enable bell and set volume */
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL);
+ lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
+
+ /* Enable/disable keyclick (and possibly set volume) */
+ if (test_bit (SND_CLICK, lk->dev.snd)) {
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
+ lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
+ lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
+ lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
+ } else {
+ lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
+ lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
+ }
+
+ /* Sound the bell if needed */
+ if (test_bit (SND_BELL, lk->dev.snd))
+ lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
+}
+
+/*
+ * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
+ */
+static void
+lkkbd_connect (struct serio *serio, struct serio_dev *dev)
+{
+ struct lkkbd *lk;
+ int i;
+
+ if ((serio->type & SERIO_TYPE) != SERIO_RS232)
+ return;
+ if (!(serio->type & SERIO_PROTO))
+ return;
+ if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_LKKBD)
+ return;
+
+ if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
+ return;
+ memset (lk, 0, sizeof (struct lkkbd));
+
+ init_input_dev (&lk->dev);
+
+ lk->dev.evbit[0] = BIT (EV_KEY) | BIT (EV_LED) | BIT (EV_SND) | BIT (EV_REP);
+ lk->dev.ledbit[0] = BIT (LED_CAPSL) | BIT (LED_COMPOSE) | BIT (LED_SCROLLL) | BIT (LED_SLEEP);
+ lk->dev.sndbit[0] = BIT (SND_CLICK) | BIT (SND_BELL);
+
+ lk->serio = serio;
+
+ INIT_WORK (&lk->tq, lkkbd_reinit, lk);
+
+ lk->bell_volume = bell_volume;
+ lk->keyclick_volume = keyclick_volume;
+ lk->ctrlclick_volume = ctrlclick_volume;
+
+ lk->dev.keycode = lk->keycode;
+ lk->dev.keycodesize = sizeof (lk_keycode_t);
+ lk->dev.keycodemax = LK_NUM_KEYCODES;
+
+ lk->dev.event = lkkbd_event;
+ lk->dev.private = lk;
+
+ serio->private = lk;
+
+ if (serio_open (serio, dev)) {
+ kfree (lk);
+ return;
+ }
+
+ sprintf (lk->name, "LK keyboard");
+
+ memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
+ for (i = 0; i < LK_NUM_KEYCODES; i++)
+ set_bit (lk->keycode[i], lk->dev.keybit);
+
+ sprintf (lk->name, "%s/input0", serio->phys);
+
+ lk->dev.name = lk->name;
+ lk->dev.phys = lk->phys;
+ lk->dev.id.bustype = BUS_RS232;
+ lk->dev.id.vendor = SERIO_LKKBD;
+ lk->dev.id.product = 0;
+ lk->dev.id.version = 0x0100;
+
+ input_register_device (&lk->dev);
+
+ printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
+ lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+}
+
+/*
+ * lkkbd_disconnect() unregisters and closes behind us.
+ */
+static void
+lkkbd_disconnect (struct serio *serio)
+{
+ struct lkkbd *lk = serio->private;
+
+ input_unregister_device (&lk->dev);
+ serio_close (serio);
+ kfree (lk);
+}
+
+static struct serio_dev lkkbd_dev = {
+ .interrupt = lkkbd_interrupt,
+ .connect = lkkbd_connect,
+ .disconnect = lkkbd_disconnect,
+};
+
+/*
+ * The functions for insering/removing us as a module.
+ */
+int __init
+lkkbd_init (void)
+{
+ serio_register_device (&lkkbd_dev);
+ return 0;
+}
+
+void __exit
+lkkbd_exit (void)
+{
+ serio_unregister_device (&lkkbd_dev);
+}
+
+module_init (lkkbd_init);
+module_exit (lkkbd_exit);
+

2004-03-16 18:24:12

by Dmitry Torokhov

[permalink] [raw]
Subject: RE: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

Vojtech Pavlik wrote:
> +
> + /* Workaround for broken chips which seem to
support MUX, but in reality don't. */
> + /* They all report version 12.10 */
> + if (mux_version == 0xCA)
> + return -1;

Hi,

I think it should be 0xAC (0xA4 with 4th bit flipped)
as the version reported is 10.12:

i8042.c: Detected active multiplexing controller, rev
10.12.

>From little debug info that I've been sent ThinkPad's
controllers seem to be flipping 4th bit sometimes, I
can't quite pinpoint the exact sequence.

Dmitry

P.S. Sorry for breaking the threading...

2004-03-16 18:49:47

by Aubin LaBrosse

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

On Tue, 2004-03-16 at 09:19, Vojtech Pavlik wrote:
> You can pull this changeset from:
> bk://kernel.bkbits.net/vojtech/input
>
> ===================================================================
>
> [email protected], 2004-01-26 13:56:47+01:00, [email protected]
> input: Add support for scroll wheel on MS Office and similar keyboards.
>
>
> atkbd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 58 insertions(+), 7 deletions(-)
>
> ===================================================================
>
> diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
> --- a/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:47 2004
> +++ b/drivers/input/keyboard/atkbd.c Tue Mar 16 13:19:47 2004
> @@ -33,18 +33,18 @@
> MODULE_PARM(atkbd_set, "1i");
> MODULE_PARM(atkbd_reset, "1i");
> MODULE_PARM(atkbd_softrepeat, "1i");
> +MODULE_PARM(atkbd_scroll, "1i");
> 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)");
> +
> #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 +52,10 @@
> module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
> MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
>
> +static int atkbd_scroll;
> +module_parm_named(scroll, atkbd_scroll, bool, 0);
> +MODULE_PARM_DESC_(scroll, "Enable scroll-wheel on office keyboards");
^^forgive me if i am wrong, but should that not be
module_param_named, like the rest? (eg the second 'a' is missing).
also, why MODULE_PARM_DESC_ instead of MODULE_PARM_DESC? (extra
underscore)

--aubin

2004-03-17 19:08:27

by Maciej W. Rozycki

[permalink] [raw]
Subject: Re: [PATCH 27/44] Add DEC LK201/LK401 keyboard support

On Tue, 16 Mar 2004, Vojtech Pavlik wrote:

> You can pull this changeset from:
> bk://kernel.bkbits.net/vojtech/input
>
> ===================================================================
>
> [email protected], 2004-03-03 17:16:24+01:00, [email protected]
> input: Add DEC LK201/LK401 keyboard support

Jan-Benedict, are you going to maintain this driver or should I do that?
There's a lot of functionality missing comparing to the old one and I want
to see it merged.

Maciej

--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: [email protected], PGP key available +

2004-03-18 20:36:07

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Tue, Mar 16, 2004 at 10:24:09AM -0800, Dmitry Torokhov wrote:

> Vojtech Pavlik wrote:
> > +
> > + /* Workaround for broken chips which seem to
> support MUX, but in reality don't. */
> > + /* They all report version 12.10 */
> > + if (mux_version == 0xCA)
> > + return -1;
>
> Hi,
>
> I think it should be 0xAC (0xA4 with 4th bit flipped)
> as the version reported is 10.12:
>
> i8042.c: Detected active multiplexing controller, rev
> 10.12.
>
> From little debug info that I've been sent ThinkPad's
> controllers seem to be flipping 4th bit sometimes, I
> can't quite pinpoint the exact sequence.

Could this be the bit that indicates whether the report is coming from
an internal or external device?

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-19 13:58:08

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Fri, Mar 19, 2004 at 12:05:36AM -0500, Dmitry Torokhov wrote:

> > Could this be the bit that indicates whether the report is coming from
> > an internal or external device?
>
> That is what I suspect, but I can not prove it and in fact I am quite
> surprised that KBC would mangle data requested via CMD_AUX_LOOP. So far
> I have seen the following sequences (* denotes 4th bit flipped):
>
> 2.6.1:
> IN: FO
> OUT: F8*
>
> 2.6.2-rc1-bk1:
> IN: 5A F0 56 A4
> OUT: 5A F0 56 AC*
>
> 2.6.3 + my debug
> IN: 5A A4 5B A4 53 F0 56
> OUT: 5A A4 5B AC* AC F0 5E*
>
> 2.6.3 + my other debug
> IN: 5A A4 A4 A4 A4 F0 56 A4 A4 A4 A4
> OUT: 5A A4 A4 A4 A4 F0 56 A4 A4 A4 A4
>
> ... and I am waiting on sequence:
> 5A 00 00 00 00 F0 56 A4 00 00 00 00
>
> As you can see it does not always flip that bit, but if it will mangle the
> last sequence I think we can claim that we see "hidden multiplexor" and
> abort active multiplexor test.

So far on every machine I've got a report from it was caused by BIOS
emulation of PS/2 mouse using an USB mouse (even when USB mouse wasn't
present). Compiling the USB modules into the kernel fixes the problem.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-19 13:56:38

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Tue, Mar 16, 2004 at 10:24:09AM -0800, Dmitry Torokhov wrote:
> Vojtech Pavlik wrote:
> > +
> > + /* Workaround for broken chips which seem to
> support MUX, but in reality don't. */
> > + /* They all report version 12.10 */
> > + if (mux_version == 0xCA)
> > + return -1;
>
> Hi,
>
> I think it should be 0xAC (0xA4 with 4th bit flipped)
> as the version reported is 10.12:
>
> i8042.c: Detected active multiplexing controller, rev
> 10.12.
>
> From little debug info that I've been sent ThinkPad's
> controllers seem to be flipping 4th bit sometimes, I
> can't quite pinpoint the exact sequence.

Thanks, fixed.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-19 14:00:44

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

On Tue, Mar 16, 2004 at 01:46:59PM -0500, Aubin LaBrosse wrote:

> > @@ -52,6 +52,10 @@
> > module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
> > MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
> >
> > +static int atkbd_scroll;
> > +module_parm_named(scroll, atkbd_scroll, bool, 0);
> > +MODULE_PARM_DESC_(scroll, "Enable scroll-wheel on office keyboards");

> ^^forgive me if i am wrong, but should that not be
> module_param_named, like the rest? (eg the second 'a' is missing).
> also, why MODULE_PARM_DESC_ instead of MODULE_PARM_DESC? (extra
> underscore)

It's a bug, but it's fixed in the next changeset (also submitted). It
wouldn't even compile. You can check that it's correct in the final
file.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-19 14:21:43

by Stefan Smietanowski

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

Hi.

> So far on every machine I've got a report from it was caused by BIOS
> emulation of PS/2 mouse using an USB mouse (even when USB mouse wasn't
> present). Compiling the USB modules into the kernel fixes the problem.

Could this have anything to do with the fact that my x86-64 kernel nukes
on startup if USB keyboard/mouse emul is enabled in the BIOS?

This is on an ASUS K8T800 and an MSI K8T800 board.

If you don't know what I'm talking about I'll give more info of course.

// Stefan

2004-03-19 14:29:59

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Fri, Mar 19, 2004 at 03:21:27PM +0100, Stefan Smietanowski wrote:
> Hi.
>
> >So far on every machine I've got a report from it was caused by BIOS
> >emulation of PS/2 mouse using an USB mouse (even when USB mouse wasn't
> >present). Compiling the USB modules into the kernel fixes the problem.
>
> Could this have anything to do with the fact that my x86-64 kernel nukes
> on startup if USB keyboard/mouse emul is enabled in the BIOS?

Yes, and no. USB keyboard/mouse emulation is simply broken in most
BIOSes. It's even more broken on AMD64 BIOSes, because usually noone
tests its interaction with 64-bit longmode. And thus when it is invoked
in 64-bit longmode, it crashes the machine.

On x86 it just causes problems with PS/2 mouse and keyboard.

So it's caused by the same thing, but these are two different problems.

> This is on an ASUS K8T800 and an MSI K8T800 board.
>
> If you don't know what I'm talking about I'll give more info of course.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-27 19:55:40

by Andries Brouwer

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

On Tue, Mar 16, 2004 at 03:19:36PM +0100, Vojtech Pavlik wrote:

> input: Add support for scroll wheel on MS Office and similar keyboards.

> +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 },
> +};

Hi Vojtech,

Can you tell me what keyboard model uses these codes?
(I have different codes for the scroll wheel on certain MS Office
keyboards. See also somewhere below
http://www.win.tue.nl/~aeb/linux/kbd/scancodes-5.html#ss5.4 )

Apart from this concrete question - the number of keyboards and
mice is very large and growing by the day. I think it is hopeless
to try and teach the kernel about all details of each of them.
I think we should try to go for a keyboard/mouse definition file
maintained in user space and fed to the kernel.

Andries

2004-03-28 00:29:45

by Andries Brouwer

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Tue, Mar 16, 2004 at 10:24:09AM -0800, Dmitry Torokhov wrote:
> Vojtech Pavlik wrote:

> > + /* Workaround for broken chips which seem to
> support MUX, but in reality don't. */

Why call them "broken"? Better to delete that word.

> > + /* They all report version 12.10 */
> > + if (mux_version == 0xCA)
> > + return -1;
>
> I think it should be 0xAC (0xA4 with 4th bit flipped)
> as the version reported is 10.12.

Yes. I have seen one such report. Have there been more?

The Synaptics multiplexing proposal uses 0xf0, 0x56, 0xa4
to activate and 0xf0, 0x56, 0xa5 to deactivate.
In both cases the replies must be 0xf0, 0x56, version.

Thus, I suppose one might get a more robust detection
by checking that both the activation and deactivation
sequences yield the same version.

Andries

2004-03-28 00:40:46

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Saturday 27 March 2004 07:29 pm, Andries Brouwer wrote:
> On Tue, Mar 16, 2004 at 10:24:09AM -0800, Dmitry Torokhov wrote:
> > Vojtech Pavlik wrote:
>
> > > + /* Workaround for broken chips which seem to
> > support MUX, but in reality don't. */
>
> Why call them "broken"? Better to delete that word.
>
> > > + /* They all report version 12.10 */
> > > + if (mux_version == 0xCA)
> > > + return -1;
> >
> > I think it should be 0xAC (0xA4 with 4th bit flipped)
> > as the version reported is 10.12.
>
> Yes. I have seen one such report. Have there been more?
>

As it turned out its not the chip but USB legacy emulation that
gets in the way of synaptics query. Actually alot of problems were
linked to broken legacy emulation implementations, Vojtech mentioned
that PCI quirk to turn legacy emulation off may be appropriate.

> The Synaptics multiplexing proposal uses 0xf0, 0x56, 0xa4
> to activate and 0xf0, 0x56, 0xa5 to deactivate.
> In both cases the replies must be 0xf0, 0x56, version.
>
> Thus, I suppose one might get a more robust detection
> by checking that both the activation and deactivation
> sequences yield the same version.
>

Unfortunately in this particular case it looks like something flips
4th bit on some (but not all, like every 3rd) bytes, so it may very
well respond with 0xAC to both queries.

--
Dmitry

2004-03-28 01:25:15

by Andries Brouwer

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Sat, Mar 27, 2004 at 07:40:39PM -0500, Dmitry Torokhov wrote:

> > The Synaptics multiplexing proposal uses 0xf0, 0x56, 0xa4
> > to activate and 0xf0, 0x56, 0xa5 to deactivate.
> > In both cases the replies must be 0xf0, 0x56, version.
> >
> > Thus, I suppose one might get a more robust detection
> > by checking that both the activation and deactivation
> > sequences yield the same version.
> >
>
> Unfortunately in this particular case it looks like something flips
> 4th bit on some (but not all, like every 3rd) bytes, so it may very
> well respond with 0xAC to both queries.

If one flips that bit on 0xa5 the result is 0xad, not 0xac.

That the bit is set is not strange.
The standard PS/2 protocol requires bit 3 in the first word of
every 3-byte packet to be 1.

Andries

2004-03-28 03:11:18

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

On Saturday 27 March 2004 08:25 pm, Andries Brouwer wrote:
> On Sat, Mar 27, 2004 at 07:40:39PM -0500, Dmitry Torokhov wrote:
>
> > > The Synaptics multiplexing proposal uses 0xf0, 0x56, 0xa4
> > > to activate and 0xf0, 0x56, 0xa5 to deactivate.
> > > In both cases the replies must be 0xf0, 0x56, version.
> > >
> > > Thus, I suppose one might get a more robust detection
> > > by checking that both the activation and deactivation
> > > sequences yield the same version.
> > >
> >
> > Unfortunately in this particular case it looks like something flips
> > 4th bit on some (but not all, like every 3rd) bytes, so it may very
> > well respond with 0xAC to both queries.
>
> If one flips that bit on 0xa5 the result is 0xad, not 0xac.

Yes, you are right.

>
> That the bit is set is not strange.
> The standard PS/2 protocol requires bit 3 in the first word of
> every 3-byte packet to be 1.

If it did it in every 3rd byte and not in response to loopback requiest
but to real data stream coming from a device I would agree...

--
Dmitry

2004-03-28 07:46:16

by Stefan Smietanowski

[permalink] [raw]
Subject: Re: [PATCH 24/44] Workaround i8042 chips with broken MUX mode

Hi.

> linked to broken legacy emulation implementations, Vojtech mentioned
> that PCI quirk to turn legacy emulation off may be appropriate.

Is there any code available that can do that as it is now?

This would be useful especially right now under x86-64.

As it is right now I either have the keyboard plugged into
both ps/2 and usb, plug it in only into usb (can't operate
grub) or plug it only into usb (enable emulation, can't
run linux ... ) and if the kernel could have a way of
disabling the emulation that would be good at least in
my case.

// Stefan

2004-03-30 13:59:50

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

Hi!

> Apart from this concrete question - the number of keyboards and
> mice is very large and growing by the day. I think it is hopeless
> to try and teach the kernel about all details of each of them.
> I think we should try to go for a keyboard/mouse definition file
> maintained in user space and fed to the kernel.

Well, if it can be maintained in userspace, it should be possible to maintain, too.
Plus it seems to me that some keyboards are compatible with others... for example arima
seems to generate same keycodes for "vol+" and "vol-" as compaq nx5000...
Pavel
--
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms

2004-03-30 17:06:05

by Paul Wagland

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards


On Mar 30, 2004, at 15:09, Pavel Machek wrote:

> Hi!
>
>> Apart from this concrete question - the number of keyboards and
>> mice is very large and growing by the day. I think it is hopeless
>> to try and teach the kernel about all details of each of them.
>> I think we should try to go for a keyboard/mouse definition file
>> maintained in user space and fed to the kernel.
>
> Well, if it can be maintained in userspace, it should be possible to
> maintain, too.
> Plus it seems to me that some keyboards are compatible with others...
> for example arima
> seems to generate same keycodes for "vol+" and "vol-" as compaq
> nx5000...

Sure, it is possible to keep up, but if something is constantly
updating then surely it is better to put that in userspace? That way if
I buy a new (not currently supported) keyboard, all as I have to do is
to update the userspace text file, and everything works. If it is in
the kernel, then I have to upgrade my kernel, and for many users, this
is not a trivial task. Indeed, for many users this then causes support
issues (think enterprise distributions).

Just my thoughts,
Paul


Attachments:
PGP.sig (186.00 B)
This is a digitally signed message part

2004-03-30 18:53:51

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

On Sat, Mar 27, 2004 at 08:55:35PM +0100, Andries Brouwer wrote:

> On Tue, Mar 16, 2004 at 03:19:36PM +0100, Vojtech Pavlik wrote:
>
> > input: Add support for scroll wheel on MS Office and similar keyboards.
>
> > +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 },
> > +};
>
> Hi Vojtech,
>
> Can you tell me what keyboard model uses these codes?
> (I have different codes for the scroll wheel on certain MS Office
> keyboards. See also somewhere below
> http://www.win.tue.nl/~aeb/linux/kbd/scancodes-5.html#ss5.4 )

Hmm, I'll re-check it, but I believe I based my original design on your
description. It was tested on a Samsung keyboard IIRC.

> Apart from this concrete question - the number of keyboards and
> mice is very large and growing by the day. I think it is hopeless
> to try and teach the kernel about all details of each of them.
> I think we should try to go for a keyboard/mouse definition file
> maintained in user space and fed to the kernel.

That's my plan, too.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2004-03-30 18:57:20

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH 9/44] Support for scroll wheel on Office keyboards

On Tue, Mar 30, 2004 at 03:09:43PM +0200, Pavel Machek wrote:
> Hi!
>
> > Apart from this concrete question - the number of keyboards and
> > mice is very large and growing by the day. I think it is hopeless
> > to try and teach the kernel about all details of each of them.
> > I think we should try to go for a keyboard/mouse definition file
> > maintained in user space and fed to the kernel.
>
> Well, if it can be maintained in userspace, it should be possible to maintain, too.
> Plus it seems to me that some keyboards are compatible with others... for example arima
> seems to generate same keycodes for "vol+" and "vol-" as compaq nx5000...

I'm not interested in maintaining this in the kernel - the database
would be rather large (say 100 kbyte) ...

--
Vojtech Pavlik
SuSE Labs, SuSE CR