aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-03-01 03:54:44 -0500
committerJiri Kosina <jkosina@suse.cz>2007-03-01 03:54:44 -0500
commit25914662b7e86f8cf8abdde0497e7fe8bdddf2ae (patch)
tree63abd15444fd5a3c04e8d3429950653b8ca7044f /drivers
parenta4dff3980697fc374008d005f56da3d8bab8c316 (diff)
HID: fix Logitech DiNovo Edge touchwheel and Logic3 /SpectraVideo middle button
Dongle shipped with Logitech DiNovo Edge (0x046d/0xc714) behaves in a weird non-standard way - it contains multiple reports with the same usage, which results in remapping of GenericDesktop.X and GenericDesktop.Y usages to GenericDesktop.Z and GenericDesktop.RX respectively, thus rendering the touchwheel unusable. The commit 35068976916fdef82d6e69ef1f8c9a1c47732759 solved this in a way that it didn't remap certain usages. This however breaks (at least) middle button of Logic3 / SpectraVideo (0x1267/0x0210), which in contrary requires the remapping. To make both of the harware work, allow remapping of these usages again, and introduce a quirk for Logitech DiNovo Edge "touchwheel" instead - we disable remapping for key, abs and rel events only for this hardware. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-input.c15
-rw-r--r--drivers/usb/input/hid-core.c3
2 files changed, 13 insertions, 5 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index eeba66513997..c8434023ba65 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -71,7 +71,6 @@ static const struct {
71#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0) 71#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
72 72
73#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) 73#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
74#define map_rel_clear(c) do { map_rel(c); clear_bit(c, bit); } while (0)
75#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) 74#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
76 75
77#ifdef CONFIG_USB_HIDINPUT_POWERBOOK 76#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
@@ -296,7 +295,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
296 } 295 }
297 } 296 }
298 297
299 map_key_clear(code); 298 map_key(code);
300 break; 299 break;
301 300
302 301
@@ -347,9 +346,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
347 case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: 346 case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
348 case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: 347 case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
349 if (field->flags & HID_MAIN_ITEM_RELATIVE) 348 if (field->flags & HID_MAIN_ITEM_RELATIVE)
350 map_rel_clear(usage->hid & 0xf); 349 map_rel(usage->hid & 0xf);
351 else 350 else
352 map_abs_clear(usage->hid & 0xf); 351 map_abs(usage->hid & 0xf);
353 break; 352 break;
354 353
355 case HID_GD_HATSWITCH: 354 case HID_GD_HATSWITCH:
@@ -519,7 +518,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
519 case 0x22f: map_key_clear(KEY_ZOOMRESET); break; 518 case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
520 case 0x233: map_key_clear(KEY_SCROLLUP); break; 519 case 0x233: map_key_clear(KEY_SCROLLUP); break;
521 case 0x234: map_key_clear(KEY_SCROLLDOWN); break; 520 case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
522 case 0x238: map_rel_clear(REL_HWHEEL); break; 521 case 0x238: map_rel(REL_HWHEEL); break;
523 case 0x25f: map_key_clear(KEY_CANCEL); break; 522 case 0x25f: map_key_clear(KEY_CANCEL); break;
524 case 0x279: map_key_clear(KEY_REDO); break; 523 case 0x279: map_key_clear(KEY_REDO); break;
525 524
@@ -667,6 +666,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
667 666
668 set_bit(usage->type, input->evbit); 667 set_bit(usage->type, input->evbit);
669 668
669 if (device->quirks & HID_QUIRK_DUPLICATE_USAGES &&
670 (usage->type == EV_KEY ||
671 usage->type == EV_REL ||
672 usage->type == EV_ABS))
673 clear_bit(usage->code, bit);
674
670 while (usage->code <= max && test_and_set_bit(usage->code, bit)) 675 while (usage->code <= max && test_and_set_bit(usage->code, bit))
671 usage->code = find_next_zero_bit(bit, max + 1, usage->code); 676 usage->code = find_next_zero_bit(bit, max + 1, usage->code);
672 677
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 5d5221324e63..12ec8b432953 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -756,6 +756,7 @@ void usbhid_init_reports(struct hid_device *hid)
756#define USB_VENDOR_ID_LOGITECH 0x046d 756#define USB_VENDOR_ID_LOGITECH 0x046d
757#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 757#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101
758#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER_2 0xc517 758#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER_2 0xc517
759#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
759 760
760#define USB_VENDOR_ID_IMATION 0x0718 761#define USB_VENDOR_ID_IMATION 0x0718
761#define USB_DEVICE_ID_DISC_STAKKA 0xd000 762#define USB_DEVICE_ID_DISC_STAKKA 0xd000
@@ -776,6 +777,8 @@ static const struct hid_blacklist {
776 unsigned quirks; 777 unsigned quirks;
777} hid_blacklist[] = { 778} hid_blacklist[] = {
778 779
780 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
781
779 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, 782 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
780 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, 783 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
781 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, 784 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },