aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/usbhid/hid-core.c27
-rw-r--r--drivers/hid/usbhid/hid-quirks.c5
-rw-r--r--include/linux/hid.h1
3 files changed, 33 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 91d610358d57..1c0bd481219c 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -692,6 +692,30 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
692 } 692 }
693} 693}
694 694
695/*
696 * Some USB barcode readers from cypress have usage min and usage max in
697 * the wrong order
698 */
699static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
700{
701 short fixed = 0;
702 int i;
703
704 for (i = 0; i < rsize - 4; i++) {
705 if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
706 unsigned char tmp;
707
708 rdesc[i] = 0x19; rdesc[i+2] = 0x29;
709 tmp = rdesc[i+3];
710 rdesc[i+3] = rdesc[i+1];
711 rdesc[i+1] = tmp;
712 }
713 }
714
715 if (fixed)
716 info("Fixing up Cypress report descriptor");
717}
718
695static struct hid_device *usb_hid_configure(struct usb_interface *intf) 719static struct hid_device *usb_hid_configure(struct usb_interface *intf)
696{ 720{
697 struct usb_host_interface *interface = intf->cur_altsetting; 721 struct usb_host_interface *interface = intf->cur_altsetting;
@@ -758,6 +782,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
758 if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR) 782 if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
759 hid_fixup_logitech_descriptor(rdesc, rsize); 783 hid_fixup_logitech_descriptor(rdesc, rsize);
760 784
785 if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
786 hid_fixup_cypress_descriptor(rdesc, rsize);
787
761#ifdef CONFIG_HID_DEBUG 788#ifdef CONFIG_HID_DEBUG
762 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); 789 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
763 for (n = 0; n < rsize; n++) 790 for (n = 0; n < rsize; n++)
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 17a87555e32f..6216f6049ecd 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -92,6 +92,8 @@
92#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 92#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
93#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 93#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
94#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 94#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
95#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
96#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
95 97
96#define USB_VENDOR_ID_DELL 0x413c 98#define USB_VENDOR_ID_DELL 0x413c
97#define USB_DEVICE_ID_DELL_W7658 0x2005 99#define USB_DEVICE_ID_DELL_W7658 0x2005
@@ -445,6 +447,9 @@ static const struct hid_blacklist {
445 447
446 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, 448 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
447 449
450 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX },
451 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX },
452
448 { 0, 0 } 453 { 0, 0 }
449}; 454};
450 455
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 37076b116ed0..827ee748fd4c 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -275,6 +275,7 @@ struct hid_item {
275#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 275#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000
276#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 276#define HID_QUIRK_DUPLICATE_USAGES 0x00200000
277#define HID_QUIRK_RESET_LEDS 0x00400000 277#define HID_QUIRK_RESET_LEDS 0x00400000
278#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000
278 279
279/* 280/*
280 * This is the global environment of the parser. This information is 281 * This is the global environment of the parser. This information is