aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorBart Massey <bart@cs.pdx.edu>2006-05-08 17:40:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 18:04:10 -0400
commita82e49b8aeb9f8dafdf6cf2e617c8b95bf056257 (patch)
treec264d2e4193d76a68468c42ee36cb33affe018fa /drivers/usb
parent2775562ad2af2fc131ef7987166db6e42217528f (diff)
[PATCH] USB HID/HIDBP, INPUT DRIVERS: fix various usb/input/hid-input.c bugs that make Apple Mighty Mouse work poorly
Transposed lines of code in drivers/usb/input/hid-input.c causes the capability bits for a new HID device to be set before quirks are applied at configuration time. When an HID event is then sent up to the input layer, it may then be discarded as irrelevant because the wrong capability bit is set. Further, the quirks for the Apple Mighty Mouse are not quite right: the horizontal scrolling needs its axis reversed, and the left and center buttons are transposed. Also, the mouse is labeled in the kernel with its earlier name (I think) of Apple PowerMouse. Steps to reproduce problem: Plug in an Apple Mighty Mouse. Note that horizontal scrolling doesn't work at all, and in fact doesn't generate any input events on /dev/input/eventN. Note also that pushing the middle button performs the right button action, and vice versa. Once you have the horizontal scrolling working, note that it is backward WRT both to vertical scrolling and to common sense. This patch maybe should be broken up, as it does address two problems. The transposed code in hidinput_configure_usage() probably creates bugs beyond just the Mighty Mouse. The rest of the patch renames POWERMOUSE to MIGHTYMOUSE everywhere (which I *believe* is correct), fixes the MIGHTYMOUSE quirk to swap the center and right mouse buttons, and adds a new quirk HID_QUIRK_INVERT_HWHEEL also assigned to the MIGHTYMOUSE with code in hidinput_hid_event() to implement it. Signed-off-by: Bart Massey <bart@cs.pdx.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/input/hid-core.c4
-rw-r--r--drivers/usb/input/hid-input.c32
-rw-r--r--drivers/usb/input/hid.h3
3 files changed, 26 insertions, 13 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 4f7e9214de0e..bb1f5211ff9d 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1549,7 +1549,7 @@ void hid_init_reports(struct hid_device *hid)
1549#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 1549#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
1550 1550
1551#define USB_VENDOR_ID_APPLE 0x05ac 1551#define USB_VENDOR_ID_APPLE 0x05ac
1552#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 1552#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
1553 1553
1554#define USB_VENDOR_ID_CHERRY 0x046a 1554#define USB_VENDOR_ID_CHERRY 0x046a
1555#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 1555#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@@ -1692,7 +1692,7 @@ static const struct hid_blacklist {
1692 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 1692 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
1693 { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, 1693 { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET },
1694 1694
1695 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, 1695 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
1696 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, 1696 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
1697 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, 1697 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
1698 1698
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 25bc85f8ce39..2f665195f4ac 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -567,16 +567,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
567 break; 567 break;
568 } 568 }
569 569
570 set_bit(usage->type, input->evbit); 570 if (device->quirks & HID_QUIRK_MIGHTYMOUSE) {
571 571 if (usage->hid == HID_GD_Z)
572 while (usage->code <= max && test_and_set_bit(usage->code, bit)) 572 map_rel(REL_HWHEEL);
573 usage->code = find_next_zero_bit(bit, max + 1, usage->code); 573 else if (usage->code == BTN_1)
574 574 map_key(BTN_2);
575 if (usage->code > max) 575 else if (usage->code == BTN_2)
576 goto ignore; 576 map_key(BTN_1);
577 577 }
578 if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032)))
579 map_rel(REL_HWHEEL);
580 578
581 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && 579 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
582 (usage->type == EV_REL) && (usage->code == REL_WHEEL)) 580 (usage->type == EV_REL) && (usage->code == REL_WHEEL))
@@ -586,6 +584,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
586 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) 584 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
587 goto ignore; 585 goto ignore;
588 586
587 set_bit(usage->type, input->evbit);
588
589 while (usage->code <= max && test_and_set_bit(usage->code, bit))
590 usage->code = find_next_zero_bit(bit, max + 1, usage->code);
591
592 if (usage->code > max)
593 goto ignore;
594
595
589 if (usage->type == EV_ABS) { 596 if (usage->type == EV_ABS) {
590 597
591 int a = field->logical_minimum; 598 int a = field->logical_minimum;
@@ -647,6 +654,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
647 return; 654 return;
648 } 655 }
649 656
657 if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
658 input_event(input, usage->type, usage->code, -value);
659 return;
660 }
661
650 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { 662 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
651 input_event(input, usage->type, REL_HWHEEL, value); 663 input_event(input, usage->type, REL_HWHEEL, value);
652 return; 664 return;
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 9c62837b5b89..7efbfff8adde 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -247,10 +247,11 @@ struct hid_item {
247#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 247#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
248#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 248#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
249#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 249#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
250#define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400 250#define HID_QUIRK_MIGHTYMOUSE 0x00000400
251#define HID_QUIRK_CYMOTION 0x00000800 251#define HID_QUIRK_CYMOTION 0x00000800
252#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 252#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
253#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 253#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
254#define HID_QUIRK_INVERT_HWHEEL 0x00004000
254 255
255/* 256/*
256 * This is the global environment of the parser. This information is 257 * This is the global environment of the parser. This information is