diff -Naur clean-2.6.9/drivers/usb/input/Kconfig dirty-2.6.9/drivers/usb/input/Kconfig --- clean-2.6.9/drivers/usb/input/Kconfig 2004-10-18 23:54:54.000000000 +0200 +++ dirty-2.6.9/drivers/usb/input/Kconfig 2004-10-24 22:25:43.392270112 +0200 @@ -23,6 +23,62 @@ To compile this driver as a module, choose M here: the module will be called usbhid. +config USB_HID_CHMP + bool "Configurable USB HID Mouse Polling (CHMP)" + default n + depends on USB_HID + help + + Say Y here if you want to active this little hack. + + It gives you the possibility to change the interval between each + interrupt poll done to your USB HID mouse. + + You can set interval to 100 ms, to get a very unprecise mouse, or + set it to 1 ms, to get a very very precise mouse. + + If you compile USBHID as a module, you are able to pass the parameter + called "chmp" to it. You can use the chmp paramter to specifiy the + interval. If you compile USBHID into your kernel (and not as a module) + you can pass the same parameter as a boot parameter, with the same result. + + Use the option named "USB HID Mouse Polling Interval" below to + define the "default" interval. This interval is only used if you don't + specifiy a boot/module parameter. + + Beware that any value below the "real" default of low speed HID devices + (which is 8 ms) breaks the HID standard. This hack might not work on your + hardware. + + Hardware known to be able to handle at least 2 ms polling includes: + + * The Logitech MX-series of mice + * The Logitech iFeel mouse + * The Logitech MouseMan Dual Optical + * The Microsoft Intellimouse-series (probably any mouse using the + intellieye technology. + + ...and various OEM mice produced by either Logitech or Microsoft. + + For more information, please visit: + + + BUT REMEMBER: + THIS FEATURE CAN BE DANGEROUS, YOU HAVE BEEN WARNED! + + If unsure, say N. + +config USB_HID_CHMP_VALUE + int "USB HID Mouse Polling Interval" + default 8 + depends on USB_HID_CHMP + help + + The default value of this option is 8 ms. + You can decrease this option to improve the precision of your mouse. + + Setting it to 2 ms will give you a very precise mouse. + comment "Input core support is needed for USB HID input layer or HIDBP support" depends on USB && INPUT=n diff -Naur clean-2.6.9/drivers/usb/input/hid-core.c dirty-2.6.9/drivers/usb/input/hid-core.c --- clean-2.6.9/drivers/usb/input/hid-core.c 2004-10-18 23:54:32.000000000 +0200 +++ dirty-2.6.9/drivers/usb/input/hid-core.c 2004-10-25 11:11:03.558507368 +0200 @@ -3,6 +3,9 @@ * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2001 Vojtech Pavlik + * + * Configurable USB HID Mouse Polling (CHMP) + * Copyright (c) 2004 Mikkel Krautz */ /* @@ -33,12 +36,20 @@ #include "hid.h" #include +#ifdef CONFIG_USB_HID_CHMP +#include +#endif + /* * Version Information */ #define DRIVER_VERSION "v2.0" +#ifdef CONFIG_USB_HID_CHMP +#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Mikkel Krautz" +#else #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" +#endif #define DRIVER_DESC "USB HID core driver" #define DRIVER_LICENSE "GPL" @@ -46,6 +57,49 @@ "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; /* + * CHMP status and error messages. + */ + +#ifdef CONFIG_USB_HID_CHMP + +#define CHMPMSG_USING_PARAM "chmp: The parameter 'chmp' was passed to usbhid... Using it's value as the polling interval.\n" +#define CHMPMSG_ERROR_PARAM "chmp: You didn't use a module/boot parameter... Trying the value defined in CONFIG instead.\n" +#define CHMPMSG_USING_CONFIG "chmp: The interval set in CONFIG seems to be OK. Using it as the polling interval.\n" +#define CHMPMSG_ERROR_CONFIG "chmp: Error! CONFIG_USB_HID_CHMP_VALUE is set to 0! Using the default polling interval instead.\n" + +/* FIXME: Is it safe to use the HZ constant in a situation like this? */ +#define CHMPMSG_STATUS_CHANGE "chmp: Polling interval of HID mouse \"0x%x\" changed from %i ms to %i ms! (%i Hz)\n", \ + dev->descriptor.idProduct, originterval, endpoint->bInterval, (HZ / endpoint->bInterval) +#define CHMPMSG_STATUS_NOCHANGE "chmp: Polling interval not changed. The old value equals the new value. Still using %i.\n", \ + originterval +#endif + +/* + * CHMP boot/module parameter setup. + */ + +#ifdef CONFIG_USB_HID_CHMP + +static int chmp = 0; + +#ifdef MODULE + +module_param(chmp, int, 0); + +#else + +static int __init hid_chmp_setup(char *str) +{ + chmp = simple_strtol(str, (char **)(str + sizeof(str)), 10); + return 0; +} +__setup("chmp=", hid_chmp_setup); + +#endif +#endif + + +/* * Register a new report for a device. */ @@ -1639,13 +1693,50 @@ for (n = 0; n < interface->desc.bNumEndpoints; n++) { struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; + int pipe, interval; +#ifdef CONFIG_USB_HID_CHMP + int originterval; +#endif endpoint = &interface->endpoint[n].desc; if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ continue; + +/* + * CHMP interval changer. + */ + +#ifdef CONFIG_USB_HID_CHMP + + if (dev->speed == USB_SPEED_LOW) { + if (hid->collection[0].usage == 0x10002) { + + originterval = endpoint->bInterval; + + if (chmp != 0) { + printk(CHMPMSG_USING_PARAM); + endpoint->bInterval = chmp; + } else { + + printk(CHMPMSG_ERROR_PARAM); + + if (CONFIG_USB_HID_CHMP_VALUE == 0) + printk(CHMPMSG_ERROR_CONFIG); + else { + printk(CHMPMSG_USING_CONFIG); + endpoint->bInterval = CONFIG_USB_HID_CHMP_VALUE; + } + } + + if (endpoint->bInterval != originterval) + printk(CHMPMSG_STATUS_CHANGE); + else + printk(CHMPMSG_STATUS_NOCHANGE); + } + } +#endif + /* handle potential highspeed HID correctly */ interval = endpoint->bInterval; if (dev->speed == USB_SPEED_HIGH)