diff -urN linux-test10-pre5-old/drivers/char/joystick/adi.c linux/drivers/char/joystick/adi.c --- linux-test10-pre5-old/drivers/char/joystick/adi.c Thu Jun 22 15:59:58 2000 +++ linux/drivers/char/joystick/adi.c Thu Oct 26 23:02:11 2000 @@ -1,5 +1,5 @@ /* - * $Id: adi.c,v 1.12 2000/06/03 20:18:52 vojtech Exp $ + * $Id: adi.c,v 1.14 2000/10/23 07:28:57 vojtech Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * @@ -418,7 +418,7 @@ adi->dev.private = port; adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (i = 0; i < adi->axes10 + adi->axes8 + adi->hats * 2; i++) + for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad > 0)) * 2; i++) set_bit(adi->abs[i], &adi->dev.absbit); for (i = 0; i < adi->buttons; i++) @@ -431,7 +431,7 @@ if (!adi->length) return; - for (i = 0; i < adi->axes10 + adi->axes8 + adi->hats * 2; i++) { + for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad > 0)) * 2; i++) { t = adi->abs[i]; x = adi->dev.abs[t]; diff -urN linux-test10-pre5-old/drivers/char/joystick/gamecon.c linux/drivers/char/joystick/gamecon.c --- linux-test10-pre5-old/drivers/char/joystick/gamecon.c Mon Aug 14 22:55:01 2000 +++ linux/drivers/char/joystick/gamecon.c Thu Oct 26 23:02:11 2000 @@ -1,11 +1,11 @@ /* - * $Id: gamecon.c,v 1.5 2000/06/25 09:56:58 vojtech Exp $ + * $Id: gamecon.c,v 1.10 2000/08/19 19:51:02 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * * Based on the work of: * Andree Borrmann John Dahlstrom - * David Kuder + * David Kuder Nathan Hand * * Sponsored by SuSE */ @@ -75,8 +75,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", - "Multisystem 2-button joystick", "N64 controller", "PSX pad", - "PSX NegCon", "PSX Analog contoller" }; + "Multisystem 2-button joystick", "N64 controller", "PSX controller" }; /* * N64 support. */ @@ -205,22 +204,30 @@ /* * PSX support - */ - -#define GC_PSX_DELAY 10 -#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */ + * + * See documentation at: + * http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt + * http://www.gamesx.com/controldata/psxcont/psxcont.htm + * ftp://milano.usal.es/pablo/ + * + */ + +#define GC_PSX_DELAY 60 /* 60 usec */ +#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */ + +#define GC_PSX_MOUSE 1 /* Mouse */ +#define GC_PSX_NEGCON 2 /* NegCon */ +#define GC_PSX_NORMAL 4 /* Digital / Analog or Rumble in Digital mode */ +#define GC_PSX_ANALOG 5 /* Analog in Analog mode / Rumble in Green mode */ +#define GC_PSX_RUMBLE 7 /* Rumble in Red mode */ + +#define GC_PSX_CLOCK 0x04 /* Pin 4 */ +#define GC_PSX_COMMAND 0x01 /* Pin 1 */ +#define GC_PSX_POWER 0xf8 /* Pins 5-9 */ +#define GC_PSX_SELECT 0x02 /* Pin 3 */ -#define GC_PSX_MOUSE 0x12 /* PSX Mouse */ -#define GC_PSX_NEGCON 0x23 /* NegCon pad */ -#define GC_PSX_NORMAL 0x41 /* Standard Digital controller */ -#define GC_PSX_ANALOGR 0x73 /* Analog controller in Red mode */ -#define GC_PSX_ANALOGG 0x53 /* Analog controller in Green mode */ - -#define GC_PSX_CLOCK 0x04 /* Pin 3 */ -#define GC_PSX_COMMAND 0x01 /* Pin 1 */ -#define GC_PSX_POWER 0xf8 /* Pins 5-9 */ -#define GC_PSX_SELECT 0x02 /* Pin 2 */ -#define GC_PSX_NOPOWER 0x04 +#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */ +#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */ 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, @@ -233,19 +240,18 @@ static int gc_psx_command(struct gc *gc, int b) { - int i, cmd, ret = 0; + int i, cmd, data = 0; - cmd = (b & 1) ? GC_PSX_COMMAND : 0; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++, b >>= 1) { + cmd = (b & 1) ? GC_PSX_COMMAND : 0; parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); udelay(GC_PSX_DELAY); - ret |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0; - cmd = (b & 1) ? GC_PSX_COMMAND : 0; + if (parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) + data |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0; parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); udelay(GC_PSX_DELAY); - b >>= 1; } - return ret; + return data; } /* @@ -253,29 +259,31 @@ * device identifier code. */ -static int gc_psx_read_packet(struct gc *gc, int length, unsigned char *data) +static int gc_psx_read_packet(struct gc *gc, unsigned char *data) { - int i, ret; + int i, id; unsigned long flags; + parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ + udelay(GC_PSX_DELAY * 2); + parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ + udelay(GC_PSX_DELAY * 2); + __save_flags(flags); __cli(); - parport_write_data(gc->pd->port, GC_PSX_POWER); - - parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ - udelay(GC_PSX_DELAY * 2); gc_psx_command(gc, 0x01); /* Access pad */ - ret = gc_psx_command(gc, 0x42); /* Get device id */ - if (gc_psx_command(gc, 0) == 'Z') /* okay? */ - for (i = 0; i < length; i++) + id = gc_psx_command(gc, 0x42); /* Get device id */ + if (gc_psx_command(gc, 0) == 0x5a) { /* Okay? */ + for (i = 0; i < GC_PSX_LEN(id) * 2; i++) data[i] = gc_psx_command(gc, 0); - else ret = -1; + } else id = 0; - parport_write_data(gc->pd->port, GC_PSX_SELECT | GC_PSX_CLOCK | GC_PSX_POWER); __restore_flags(flags); - return ret; + parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); + + return GC_PSX_ID(id); } /* @@ -316,8 +324,8 @@ input_report_abs(dev + i, ABS_X, axes[0]); input_report_abs(dev + i, ABS_Y, -axes[1]); - input_report_abs(dev + i, ABS_HAT0X, !!(s & data[7]) - !!(s & data[6])); - input_report_abs(dev + i, ABS_HAT0Y, !!(s & data[5]) - !!(s & data[4])); + input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); + input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); for (j = 0; j < 10; j++) input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); @@ -338,8 +346,8 @@ s = gc_status_bit[i]; if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { - input_report_abs(dev + i, ABS_X, !!(s & data[7]) - !!(s & data[6])); - input_report_abs(dev + i, ABS_Y, !!(s & data[5]) - !!(s & data[4])); + input_report_abs(dev + i, ABS_X, ! - !(s & data[6]) - !(s & data[7])); + input_report_abs(dev + i, ABS_Y, ! - !(s & data[4]) - !(s & data[5])); } if (s & gc->pads[GC_NES]) @@ -365,8 +373,8 @@ s = gc_status_bit[i]; if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { - input_report_abs(dev + i, ABS_X, !!(s & data[3]) - !!(s & data[2])); - input_report_abs(dev + i, ABS_Y, !!(s & data[1]) - !!(s & data[0])); + input_report_abs(dev + i, ABS_X, !(s & data[2]) - !(s & data[3])); + input_report_abs(dev + i, ABS_Y, !(s & data[0]) - !(s & data[1])); input_report_key(dev + i, BTN_TRIGGER, s & data[4]); } @@ -385,37 +393,37 @@ if (gc->pads[GC_PSX] & gc_status_bit[i]) break; - switch (gc_psx_read_packet(gc, 6, data)) { + switch (gc_psx_read_packet(gc, data)) { + + case GC_PSX_RUMBLE: + + input_report_key(dev + i, BTN_THUMB, ~data[0] & 0x04); + input_report_key(dev + i, BTN_THUMB2, ~data[0] & 0x02); + + case GC_PSX_NEGCON: + case GC_PSX_ANALOG: - case GC_PSX_ANALOGG: - for (j = 0; j < 4; j++) input_report_abs(dev + i, gc_psx_abs[j], data[j + 2]); - input_report_abs(dev + i, ABS_HAT0X, !!(data[0]&0x20) - !!(data[0]&0x80)); - input_report_abs(dev + i, ABS_HAT0Y, !!(data[0]&0x40) - !!(data[0]&0x10)); + input_report_abs(dev + i, ABS_HAT0X, !(data[0] & 0x20) - !(data[0] & 0x80)); + input_report_abs(dev + i, ABS_HAT0Y, !(data[0] & 0x40) - !(data[0] & 0x10)); for (j = 0; j < 8; j++) - input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << i)); + input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j)); input_report_key(dev + i, BTN_START, ~data[0] & 0x08); input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); break; - case GC_PSX_ANALOGR: - - input_report_key(dev + i, BTN_THUMB, ~data[0] & 0x04); - input_report_key(dev + i, BTN_THUMB2, ~data[0] & 0x02); - case GC_PSX_NORMAL: - case GC_PSX_NEGCON: - input_report_abs(dev + i, ABS_X, 128 + !!(data[0] & 0x20) * 127 - !!(data[0] & 0x80) * 128); - input_report_abs(dev + i, ABS_Y, 128 + !!(data[0] & 0x40) * 127 - !!(data[0] & 0x10) * 128); + input_report_abs(dev + i, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); + input_report_abs(dev + i, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); for (j = 0; j < 8; j++) - input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << i)); + input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j)); input_report_key(dev + i, BTN_START, ~data[0] & 0x08); input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); @@ -448,14 +456,12 @@ } } - - static struct gc __init *gc_probe(int *config) { struct gc *gc; struct parport *pp; - int i, j, psx, pbtn; - unsigned char data[2]; + int i, j, psx; + unsigned char data[32]; if (config[0] < 0) return NULL; @@ -545,44 +551,42 @@ case GC_PSX: - psx = gc_psx_read_packet(gc, 2, data); + psx = gc_psx_read_packet(gc, data); switch(psx) { case GC_PSX_NEGCON: - config[i + 1] += 1; case GC_PSX_NORMAL: - pbtn = 10; - break; + case GC_PSX_ANALOG: + case GC_PSX_RUMBLE: - case GC_PSX_ANALOGG: - case GC_PSX_ANALOGR: - config[i + 1] += 2; - pbtn = 12; for (j = 0; j < 6; j++) { psx = gc_psx_abs[j]; set_bit(psx, gc->dev[i].absbit); - gc->dev[i].absmin[psx] = 4; - gc->dev[i].absmax[psx] = 252; - gc->dev[i].absflat[psx] = 2; + if (j < 4) { + gc->dev[i].absmin[psx] = 4; + gc->dev[i].absmax[psx] = 252; + gc->dev[i].absflat[psx] = 2; + } else { + gc->dev[i].absmin[psx] = -1; + gc->dev[i].absmax[psx] = 1; + } } + + for (j = 0; j < 12; j++) + set_bit(gc_psx_btn[j], gc->dev[i].keybit); + break; - case -1: + case 0: gc->pads[GC_PSX] &= ~gc_status_bit[i]; - pbtn = 0; printk(KERN_ERR "gamecon.c: No PSX controller found.\n"); break; default: gc->pads[GC_PSX] &= ~gc_status_bit[i]; - pbtn = 0; printk(KERN_WARNING "gamecon.c: Unsupported PSX controller %#x," " please report to .\n", psx); } - - for (j = 0; j < pbtn; j++) - set_bit(gc_psx_btn[j], gc->dev[i].keybit); - break; } diff -urN linux-test10-pre5-old/drivers/char/joystick/iforce.c linux/drivers/char/joystick/iforce.c --- linux-test10-pre5-old/drivers/char/joystick/iforce.c Tue Aug 22 20:41:14 2000 +++ linux/drivers/char/joystick/iforce.c Thu Oct 26 23:13:29 2000 @@ -54,6 +54,7 @@ struct iforce { signed char data[IFORCE_MAX_LENGTH]; + struct usb_device *usbdev; struct input_dev dev; struct urb irq; int open; @@ -113,9 +114,11 @@ { struct iforce *iforce = dev->private; - if (dev->idbus == BUS_USB && !iforce->open++) + if (dev->idbus == BUS_USB && !iforce->open++) { + iforce->irq.dev = iforce->usbdev; if (usb_submit_urb(&iforce->irq)) return -EIO; + } return 0; } diff -urN linux-test10-pre5-old/drivers/char/joystick/ns558.c linux/drivers/char/joystick/ns558.c --- linux-test10-pre5-old/drivers/char/joystick/ns558.c Thu Oct 26 23:04:19 2000 +++ linux/drivers/char/joystick/ns558.c Thu Oct 26 23:02:53 2000 @@ -1,5 +1,5 @@ /* - * $Id: ns558.c,v 1.16 2000/08/17 20:03:56 vojtech Exp $ + * $Id: ns558.c,v 1.21 2000/10/18 12:29:35 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999 Brian Gerst @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,7 @@ #define NS558_PNP 2 #define NS558_PCI 3 -static int ns558_isa_portlist[] = { 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209, +static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209, 0x20b, 0x20c, 0x20e, 0x20f, 0x211, 0x219, 0x101, 0 }; struct ns558 { @@ -58,7 +59,7 @@ }; static struct ns558 *ns558; -static int have_pci_devices; +static int ns558_pci; /* * ns558_isa_probe() tries to find an isa gameport at the @@ -188,12 +189,10 @@ } memset(port, 0, sizeof(struct ns558)); - port->next = ns558; port->type = NS558_PCI; port->gameport.io = ioport; port->gameport.size = iolen; port->dev = pdev; - ns558 = port; pdev->driver_data = port; @@ -312,13 +311,10 @@ #endif /* - * Probe for PCI ports. Always probe for PCI first, - * it is the least-invasive probe. + * Probe for PCI ports. */ - i = pci_module_init(&ns558_pci_driver); - if (i == 0) - have_pci_devices = 1; + ns558_pci = !pci_module_init(&ns558_pci_driver); /* * Probe for ISA ports. @@ -339,12 +335,15 @@ } #endif - return ns558 ? 0 : -ENODEV; + return (ns558 || ns558_pci) ? 0 : -ENODEV; } void __exit ns558_exit(void) { - struct ns558 *port = ns558; + struct ns558 *next, *port = ns558; + + if (ns558_pci) + pci_unregister_driver(&ns558_pci_driver); while (port) { gameport_unregister_port(&port->gameport); @@ -365,11 +364,10 @@ break; } - port = port->next; + next = port->next; + kfree(port); + port = next; } - - if (have_pci_devices) - pci_unregister_driver(&ns558_pci_driver); } module_init(ns558_init); diff -urN linux-test10-pre5-old/drivers/char/joystick/sidewinder.c linux/drivers/char/joystick/sidewinder.c --- linux-test10-pre5-old/drivers/char/joystick/sidewinder.c Mon Aug 14 22:55:01 2000 +++ linux/drivers/char/joystick/sidewinder.c Thu Oct 26 23:02:53 2000 @@ -1,5 +1,5 @@ /* - * $Id: sidewinder.c,v 1.16 2000/07/14 09:02:41 vojtech Exp $ + * $Id: sidewinder.c,v 1.17 2000/10/25 09:56:09 vojtech Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * @@ -102,7 +102,7 @@ { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT }, { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT }, { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START, BTN_MODE, BTN_SELECT }, - { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3 }}; + { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4 }}; static struct { int x; diff -urN linux-test10-pre5-old/drivers/char/joystick/tmdc.c linux/drivers/char/joystick/tmdc.c --- linux-test10-pre5-old/drivers/char/joystick/tmdc.c Wed Jun 21 17:22:21 2000 +++ linux/drivers/char/joystick/tmdc.c Thu Oct 26 23:24:34 2000 @@ -1,5 +1,5 @@ /* - * $Id: tmdc.c,v 1.18 2000/06/08 19:59:59 vojtech Exp $ + * $Id: tmdc.c,v 1.20 2000/08/25 16:28:03 vojtech Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * @@ -49,6 +49,7 @@ #define TMDC_MODE_M3DI 1 #define TMDC_MODE_3DRP 3 +#define TMDC_MODE_FM 8 #define TMDC_MODE_FGP 163 #define TMDC_BYTE_ID 10 @@ -192,6 +193,15 @@ break; + case TMDC_MODE_FM: + + for (i = 0; i < 8; i++) + input_report_key(dev, tmdc_btn_joy[i], + (data[j][tmdc_byte_d[0]] >> (i + 0)) & 1); + for (i = 0; i < 2; i++) + input_report_key(dev, tmdc_btn_joy[i + 8], + (data[j][tmdc_byte_d[1]] >> (i + 6)) & 1); + default: for (i = 0; i < ((data[j][TMDC_BYTE_DEF] & 0xf) << 3) && i < TMDC_BTN_JOY; i++) @@ -239,6 +249,7 @@ char padbtn; } models[] = { { 1, "ThrustMaster Millenium 3D Inceptor", 6, 0, 6, 0 }, { 3, "ThrustMaster Rage 3D Gamepad", 2, 0, 0, 10 }, + { 8, "ThrustMaster FragMaster", 4, 0, 0, 10 }, { 163, "Thrustmaster Fusion GamePad", 2, 0, 0, 10 }, { 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, 0, 0 }}; unsigned char data[2][TMDC_MAX_LENGTH]; diff -urN linux-test10-pre5-old/drivers/input/evdev.c linux/drivers/input/evdev.c --- linux-test10-pre5-old/drivers/input/evdev.c Fri Jul 28 03:36:54 2000 +++ linux/drivers/input/evdev.c Thu Oct 26 23:02:53 2000 @@ -1,5 +1,5 @@ /* - * $Id: evdev.c,v 1.10 2000/06/23 09:23:00 vojtech Exp $ + * $Id: evdev.c,v 1.16 2000/10/17 07:41:53 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -123,7 +123,7 @@ struct evdev_list *list; int i = MINOR(inode->i_rdev) - EVDEV_MINOR_BASE; - if (i > EVDEV_MINORS || !evdev_table[i]) + if (i >= EVDEV_MINORS || !evdev_table[i]) return -ENODEV; if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) @@ -145,7 +145,19 @@ static ssize_t evdev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) { - return -EINVAL; + struct evdev_list *list = file->private_data; + struct input_event event; + int retval = 0; + + while (retval < count) { + + if (copy_from_user(&event, buffer + retval, sizeof(struct input_event))) + return -EFAULT; + input_event(list->evdev->handle.dev, event.type, event.code, event.value); + retval += sizeof(struct input_event); + } + + return retval; } static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_t *ppos) @@ -288,7 +300,7 @@ int minor; for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); - if (evdev_table[minor]) { + if (minor == EVDEV_MINORS) { printk(KERN_ERR "evdev: no more free evdev devices\n"); return NULL; } diff -urN linux-test10-pre5-old/drivers/input/joydev.c linux/drivers/input/joydev.c --- linux-test10-pre5-old/drivers/input/joydev.c Tue Aug 22 18:06:31 2000 +++ linux/drivers/input/joydev.c Thu Oct 26 23:02:53 2000 @@ -1,5 +1,5 @@ /* - * $Id: joydev.c,v 1.13 2000/08/14 21:05:26 vojtech Exp $ + * $Id: joydev.c,v 1.15 2000/10/17 07:41:53 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999 Colin Van Dyke @@ -193,7 +193,7 @@ struct joydev_list *list; int i = MINOR(inode->i_rdev) - JOYDEV_MINOR_BASE; - if (i > JOYDEV_MINORS || !joydev_table[i]) + if (i >= JOYDEV_MINORS || !joydev_table[i]) return -ENODEV; if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL))) @@ -395,7 +395,7 @@ || test_bit(BTN_1, dev->keybit)))) return NULL; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); - if (joydev_table[minor]) { + if (minor == JOYDEV_MINORS) { printk(KERN_ERR "joydev: no more free joydev devices\n"); return NULL; } diff -urN linux-test10-pre5-old/drivers/input/mousedev.c linux/drivers/input/mousedev.c --- linux-test10-pre5-old/drivers/input/mousedev.c Tue Aug 22 18:06:31 2000 +++ linux/drivers/input/mousedev.c Thu Oct 26 23:02:53 2000 @@ -1,9 +1,9 @@ /* - * $Id: mousedev.c,v 1.15 2000/08/14 21:05:26 vojtech Exp $ + * $Id: mousedev.c,v 1.20 2000/10/18 12:12:26 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * - * Input driver to PS/2 or ImPS/2 device driver module. + * Input driver to ImExPS/2 device driver module. * * Sponsored by SuSE */ @@ -65,20 +65,22 @@ signed char ps2[6]; unsigned long buttons; unsigned char ready, buffer, bufsiz; - unsigned char mode, genseq, impseq; + unsigned char mode, imexseq, impsseq; }; -#define MOUSEDEV_GENIUS_LEN 5 -#define MOUSEDEV_IMPS_LEN 6 +#define MOUSEDEV_SEQ_LEN 6 -static unsigned char mousedev_genius_seq[] = { 0xe8, 3, 0xe6, 0xe6, 0xe6 }; static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; +static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; static struct input_handler mousedev_handler; static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev mousedev_mix; +static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; +static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; + static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL }; @@ -96,12 +98,12 @@ switch (code) { case ABS_X: size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; - list->dx += (value * CONFIG_INPUT_MOUSEDEV_SCREEN_X - list->oldx) / size; + list->dx += (value * xres - list->oldx) / size; list->oldx += list->dx * size; break; case ABS_Y: size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; - list->dy -= (value * CONFIG_INPUT_MOUSEDEV_SCREEN_Y - list->oldy) / size; + list->dy -= (value * yres - list->oldy) / size; list->oldy -= list->dy * size; break; } @@ -121,12 +123,12 @@ case BTN_TOUCH: case BTN_LEFT: index = 0; break; case BTN_4: - case BTN_EXTRA: if (list->mode > 1) { index = 4; break; } + case BTN_EXTRA: if (list->mode == 2) { index = 4; break; } case BTN_STYLUS: case BTN_1: case BTN_RIGHT: index = 1; break; case BTN_3: - case BTN_SIDE: if (list->mode > 1) { index = 3; break; } + case BTN_SIDE: if (list->mode == 2) { index = 3; break; } case BTN_2: case BTN_STYLUS2: case BTN_MIDDLE: index = 2; break; @@ -213,7 +215,7 @@ struct mousedev_list *list; int i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE; - if (i > MOUSEDEV_MINORS || !mousedev_table[i]) + if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL))) @@ -254,14 +256,19 @@ list->dy -= list->ps2[off + 2]; list->bufsiz = off + 3; - if (list->mode > 1) - list->ps2[off] |= ((list->buttons & 0x18) << 3); + if (list->mode == 2) { + list->ps2[off + 3] = (list->dz > 7 ? 7 : (list->dz < -7 ? -7 : list->dz)) & 0x0f; + list->dz -= list->ps2[off + 3]; + list->ps2[off + 3] |= ((list->buttons & 0x18) << 1); + list->bufsiz++; + } - if (list->mode) { + if (list->mode == 1) { list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz)); - list->bufsiz++; list->dz -= list->ps2[off + 3]; + list->bufsiz++; } + if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready = 0; list->buffer = list->bufsiz; } @@ -277,24 +284,23 @@ c = buffer[i]; - if (c == mousedev_genius_seq[list->genseq]) { - if (++list->genseq == MOUSEDEV_GENIUS_LEN) { - list->genseq = 0; - list->ready = 1; + if (c == mousedev_imex_seq[list->imexseq]) { + if (++list->imexseq == MOUSEDEV_SEQ_LEN) { + list->imexseq = 0; list->mode = 2; } - } else list->genseq = 0; + } else list->imexseq = 0; - if (c == mousedev_imps_seq[list->impseq]) { - if (++list->impseq == MOUSEDEV_IMPS_LEN) { - list->impseq = 0; - list->ready = 1; + if (c == mousedev_imps_seq[list->impsseq]) { + if (++list->impsseq == MOUSEDEV_SEQ_LEN) { + list->impsseq = 0; list->mode = 1; } - } else list->impseq = 0; + } else list->impsseq = 0; list->ps2[0] = 0xfa; list->bufsiz = 1; + list->ready = 1; switch (c) { @@ -303,16 +309,16 @@ break; case 0xf2: /* Get ID */ - list->ps2[1] = (list->mode == 1) ? 3 : 0; + switch (list->mode) { + case 0: list->ps2[1] = 0; + case 1: list->ps2[1] = 3; + case 2: list->ps2[1] = 4; + } list->bufsiz = 2; break; case 0xe9: /* Get info */ - if (list->mode == 2) { - list->ps2[1] = 0x00; list->ps2[2] = 0x33; list->ps2[3] = 0x55; - } else { - list->ps2[1] = 0x60; list->ps2[2] = 3; list->ps2[3] = 200; - } + list->ps2[1] = 0x60; list->ps2[2] = 3; list->ps2[3] = 200; list->bufsiz = 4; break; } @@ -407,7 +413,7 @@ return NULL; for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); - if (mousedev_table[minor]) { + if (minor == MOUSEDEV_MINORS) { printk(KERN_ERR "mousedev: no more free mousedev devices\n"); return NULL; } @@ -487,3 +493,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver"); +MODULE_PARM(xres, "i"); +MODULE_PARM_DESC(xres, "Horizontal screen resolution"); +MODULE_PARM(yres, "i"); +MODULE_PARM_DESC(yres, "Vertical screen resolution"); diff -urN linux-test10-pre5-old/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c --- linux-test10-pre5-old/drivers/usb/usbkbd.c Wed Aug 23 00:19:52 2000 +++ linux/drivers/usb/usbkbd.c Thu Oct 26 23:11:19 2000 @@ -59,6 +59,7 @@ struct usb_kbd { struct input_dev dev; + struct usb_device *usbdev; unsigned char new[8]; unsigned char old[8]; struct urb irq, led; @@ -116,6 +117,7 @@ return 0; kbd->leds = kbd->newleds; + kbd->led.dev = kbd->usbdev; if (usb_submit_urb(&kbd->led)) err("usb_submit_urb(leds) failed"); @@ -133,6 +135,7 @@ return; kbd->leds = kbd->newleds; + kbd->led.dev = kbd->usbdev; if (usb_submit_urb(&kbd->led)) err("usb_submit_urb(leds) failed"); } @@ -144,6 +147,7 @@ if (kbd->open++) return 0; + kbd->irq.dev = kbd->usbdev; if (usb_submit_urb(&kbd->irq)) return -EIO; @@ -186,6 +190,8 @@ if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); + + kbd->usbdev = dev; kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); diff -urN linux-test10-pre5-old/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c --- linux-test10-pre5-old/drivers/usb/usbmouse.c Thu Oct 26 23:04:25 2000 +++ linux/drivers/usb/usbmouse.c Thu Oct 26 23:10:38 2000 @@ -1,5 +1,5 @@ /* - * $Id: usbmouse.c,v 1.5 2000/05/29 09:01:52 vojtech Exp $ + * $Id: usbmouse.c,v 1.6 2000/08/14 21:05:26 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -41,9 +41,9 @@ struct usb_mouse { signed char data[8]; char name[128]; + struct usb_device *usbdev; struct input_dev dev; struct urb irq; - struct usb_device *my_usb_device; // for resubmitting my urb int open; }; @@ -73,7 +73,7 @@ if (mouse->open++) return 0; - mouse->irq.dev = mouse->my_usb_device; + mouse->irq.dev = mouse->usbdev; if (usb_submit_urb(&mouse->irq)) return -EIO; @@ -116,6 +116,8 @@ if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; memset(mouse, 0, sizeof(struct usb_mouse)); + mouse->usbdev = dev; + mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); @@ -150,7 +152,6 @@ kfree(buf); - mouse->my_usb_device = dev; FILL_INT_URB(&mouse->irq, dev, pipe, mouse->data, maxp > 8 ? 8 : maxp, usb_mouse_irq, mouse, endpoint->bInterval); diff -urN linux-test10-pre5-old/drivers/usb/wacom.c linux/drivers/usb/wacom.c --- linux-test10-pre5-old/drivers/usb/wacom.c Thu Oct 26 23:04:25 2000 +++ linux/drivers/usb/wacom.c Thu Oct 26 23:27:27 2000 @@ -1,10 +1,11 @@ /* - * $Id: wacom.c,v 1.9 2000/05/29 09:01:52 vojtech Exp $ + * $Id: wacom.c,v 1.11 2000/10/18 12:12:26 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * Copyright (c) 2000 Andreas Bach Aaen * Copyright (c) 2000 Clifford Wolf * Copyright (c) 2000 Sam Mosel + * Copyright (c) 2000 James E. Blair * * USB Wacom Graphire and Wacom Intuos tablet support * @@ -21,23 +22,25 @@ * v1.8 (vp) - Submit URB only when operating, moved to CVS, * use input_report_key instead of report_btn and * other cleanups + * v1.11 (vp) - Add URB ->dev setting for new kernels + * v1.11 (jb) - Add support for the 4D Mouse & Lens */ /* * 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 + * 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 * e-mail - mail your message to , or by paper mail: * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic @@ -70,17 +73,17 @@ * byte 5: Y high bits * byte 6: pen pressure low bits / mouse wheel * byte 7: pen presure high bits / mouse distance - * + * * There are also two single-byte feature reports (2 and 3). * * Wacom Intuos status packet: * * byte 0: report ID (2) - * byte 1: bit7 1 - sync bit + * byte 1: bit7 1 - sync bit * bit6 pointer in range * bit5 pointer type report * bit4 0 ? - * bit3 0 ? + * bit3 mouse packet type * bit2 pen button2 * bit1 pen button1 * bit0 0 ? @@ -88,12 +91,38 @@ * byte 3: X low bits * byte 4: Y high bits * byte 5: Y low bits + * + * Pen packet: + * * byte 6: bits 0-7: pressure (bits 2-9) * byte 7: bits 6-7: pressure (bits 0-1) * byte 7: bits 0-5: X tilt (bits 1-6) * byte 8: bit 7: X tilt (bit 0) * byte 8: bits 0-6: Y tilt (bits 0-6) * byte 9: bits 4-7: distance + * + * Mouse packet type 0: + * + * byte 6: bits 0-7: wheel (bits 2-9) + * byte 7: bits 6-7: wheel (bits 0-1) + * byte 7: bits 0-5: 0 + * byte 8: bits 6-7: 0 + * byte 8: bit 5: left extra button + * byte 8: bit 4: right extra button + * byte 8: bit 3: wheel (sign) + * byte 8: bit 2: right button + * byte 8: bit 1: middle button + * byte 8: bit 0: left button + * byte 9: bits 4-7: distance + * + * Mouse packet type 1: + * + * byte 6: bits 0-7: rotation (bits 2-9) + * byte 7: bits 6-7: rotation (bits 0-1) + * byte 7: bit 5: rotation (sign) + * byte 7: bits 0-4: 0 + * byte 8: bits 0-7: 0 + * byte 9: bits 4-7: distance */ #define USB_VENDOR_ID_WACOM 0x056a @@ -192,7 +221,7 @@ case 0x0fa: wacom->tool = BTN_TOOL_RUBBER; break; /* Eraser */ case 0x112: wacom->tool = BTN_TOOL_AIRBRUSH; break; /* Airbrush */ default: wacom->tool = BTN_TOOL_PEN; break; /* Unknown tool */ - } + } input_report_key(dev, wacom->tool, 1); return; } @@ -205,31 +234,63 @@ input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]); input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]); - input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(dev, ABS_DISTANCE, data[9] >> 4); - input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - input_report_key(dev, BTN_STYLUS, data[1] & 2); - input_report_key(dev, BTN_STYLUS2, data[1] & 4); - input_report_key(dev, BTN_TOUCH, t > 10); + switch (wacom->tool) { + + case BTN_TOOL_PENCIL: + case BTN_TOOL_PEN: + case BTN_TOOL_BRUSH: + case BTN_TOOL_RUBBER: + case BTN_TOOL_AIRBRUSH: + + input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); + input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); + input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); + input_report_key(dev, BTN_STYLUS, data[1] & 2); + input_report_key(dev, BTN_STYLUS2, data[1] & 4); + input_report_key(dev, BTN_TOUCH, t > 10); + break; + + case BTN_TOOL_MOUSE: + case BTN_TOOL_LENS: + + if (data[1] & 0x02) { /* Rotation packet */ + input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? + ((__u32)data[6] << 2) | ((data[7] >> 6) & 3): + (-(((__u32)data[6] << 2) | ((data[7] >> 6) & 3))) - 1); + break; + } + + input_report_key(dev, BTN_LEFT, data[8] & 0x01); + input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); + input_report_key(dev, BTN_RIGHT, data[8] & 0x04); + input_report_key(dev, BTN_SIDE, data[8] & 0x20); + input_report_key(dev, BTN_EXTRA, data[8] & 0x10); + input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? + ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) : + -((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); + break; + } } #define WACOM_INTUOS_TOOLS (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS)) +#define WACOM_INTUOS_BUTTONS (BIT(BTN_SIDE) | BIT(BTN_EXTRA)) +#define WACOM_INTUOS_ABS (BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE)) struct wacom_features wacom_features[] = { { "Wacom Graphire", 0x10, 8, 10206, 7422, 511, 32, wacom_graphire_irq, - BIT(EV_REL), 0, BIT(REL_WHEEL), BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE), 0 }, + BIT(EV_REL), 0, 0, 0 }, { "Wacom Intuos 4x5", 0x20, 10, 12700, 10360, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 6x8", 0x21, 10, 20320, 15040, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 9x12", 0x22, 10, 30480, 23060, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 12x12", 0x23, 10, 30480, 30480, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 12x18", 0x24, 10, 47720, 30480, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { NULL , 0 } }; @@ -275,7 +336,7 @@ wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | wacom->features->evbit; wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE) | wacom->features->absbit; wacom->dev.relbit[0] |= wacom->features->relbit; - wacom->dev.keybit[LONG(BTN_LEFT)] |= wacom->features->btnbit; + wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | wacom->features->btnbit; wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | wacom->features->digibit; @@ -285,6 +346,14 @@ wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; wacom->dev.absmax[ABS_TILT_X] = 127; wacom->dev.absmax[ABS_TILT_Y] = 127; + + wacom->dev.absmin[ABS_RZ] = -900; + wacom->dev.absmax[ABS_RZ] = 899; + wacom->dev.absmin[ABS_THROTTLE] = -1023; + wacom->dev.absmax[ABS_THROTTLE] = 1023; + + wacom->dev.absfuzz[ABS_X] = 4; + wacom->dev.absfuzz[ABS_Y] = 4; wacom->dev.private = wacom; wacom->dev.open = wacom_open;