aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorPekka Sarnila <sarnila@adit.fi>2008-03-06 07:23:14 -0500
committerJiri Kosina <jkosina@suse.cz>2008-04-22 05:34:56 -0400
commitf345c37c37641beceb0e52f61bb4cbc72904ee09 (patch)
treeedc6113daaef0218fd83c952b6b5a2146845dbc3 /drivers/hid
parentcf2a299e48cbeb6c942e1f765b92ca6058355f68 (diff)
HID: fixup fullspeed interval on highspeed Afatech DVB-T IR kbd
Many vendors highspeed devices give erroneously fullspeed interval value in endpoint descriptor for interrupt endpoints. This quirk fixes up that by recalculating the right value for highspeed device. At the time of hid configuration this quirk calculates which highspeed interval value gives same interval delay as, or next smaller then, what it would be if the original value would be interpreted as fullspeed value. In subsequent urbs that new value is used instead. Forming the 'hid->name' in usb_hid_config() was moved up to accommodate more descriptive printk reporting the fixup. In this patch the quirk is set for one such device: Afatech DVB-T 2 infrared HID-keyboard. It reports value 16 which means 4,069s in highspeed while obviously 16ms was intended. In this case quirk calculates new value to be 8 which gives when interpreted as highspeed value 16ms as wanted. The behavior of the device was verified to be what expected both before and after the patch. Signed-off-by: Pekka Sarnila <sarnila@adit.fi> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/usbhid/hid-core.c40
-rw-r--r--drivers/hid/usbhid/hid-quirks.c5
2 files changed, 29 insertions, 16 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index d95979f0e028..b4ad5d175280 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -800,6 +800,22 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
800 goto fail; 800 goto fail;
801 } 801 }
802 802
803 hid->name[0] = 0;
804
805 if (dev->manufacturer)
806 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
807
808 if (dev->product) {
809 if (dev->manufacturer)
810 strlcat(hid->name, " ", sizeof(hid->name));
811 strlcat(hid->name, dev->product, sizeof(hid->name));
812 }
813
814 if (!strlen(hid->name))
815 snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
816 le16_to_cpu(dev->descriptor.idVendor),
817 le16_to_cpu(dev->descriptor.idProduct));
818
803 for (n = 0; n < interface->desc.bNumEndpoints; n++) { 819 for (n = 0; n < interface->desc.bNumEndpoints; n++) {
804 820
805 struct usb_endpoint_descriptor *endpoint; 821 struct usb_endpoint_descriptor *endpoint;
@@ -812,6 +828,14 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
812 828
813 interval = endpoint->bInterval; 829 interval = endpoint->bInterval;
814 830
831 /* Some vendors give fullspeed interval on highspeed devides */
832 if (quirks & HID_QUIRK_FULLSPEED_INTERVAL &&
833 dev->speed == USB_SPEED_HIGH) {
834 interval = fls(endpoint->bInterval*8);
835 printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n",
836 hid->name, endpoint->bInterval, interval);
837 }
838
815 /* Change the polling interval of mice. */ 839 /* Change the polling interval of mice. */
816 if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) 840 if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
817 interval = hid_mousepoll_interval; 841 interval = hid_mousepoll_interval;
@@ -859,22 +883,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
859 usbhid->intf = intf; 883 usbhid->intf = intf;
860 usbhid->ifnum = interface->desc.bInterfaceNumber; 884 usbhid->ifnum = interface->desc.bInterfaceNumber;
861 885
862 hid->name[0] = 0;
863
864 if (dev->manufacturer)
865 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
866
867 if (dev->product) {
868 if (dev->manufacturer)
869 strlcat(hid->name, " ", sizeof(hid->name));
870 strlcat(hid->name, dev->product, sizeof(hid->name));
871 }
872
873 if (!strlen(hid->name))
874 snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
875 le16_to_cpu(dev->descriptor.idVendor),
876 le16_to_cpu(dev->descriptor.idProduct));
877
878 hid->bus = BUS_USB; 886 hid->bus = BUS_USB;
879 hid->vendor = le16_to_cpu(dev->descriptor.idVendor); 887 hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
880 hid->product = le16_to_cpu(dev->descriptor.idProduct); 888 hid->product = le16_to_cpu(dev->descriptor.idProduct);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index e29a057cbea2..54b8f8311f94 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -32,6 +32,9 @@
32#define USB_VENDOR_ID_ADS_TECH 0x06e1 32#define USB_VENDOR_ID_ADS_TECH 0x06e1
33#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 33#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
34 34
35#define USB_VENDOR_ID_AFATECH 0x15a4
36#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
37
35#define USB_VENDOR_ID_AIPTEK 0x08ca 38#define USB_VENDOR_ID_AIPTEK 0x08ca
36#define USB_DEVICE_ID_AIPTEK_01 0x0001 39#define USB_DEVICE_ID_AIPTEK_01 0x0001
37#define USB_DEVICE_ID_AIPTEK_10 0x0010 40#define USB_DEVICE_ID_AIPTEK_10 0x0010
@@ -436,6 +439,8 @@ static const struct hid_blacklist {
436 439
437 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, 440 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
438 441
442 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
443
439 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, 444 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
440 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, 445 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
441 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, 446 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },