Commit d621f446 authored by Vojtech Pavlik's avatar Vojtech Pavlik

input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom

         button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input
         mappings, more mappings added, devices with reports larger than MaxPacketSize
         work again.
Signed-off-by: default avatarVojtech Pavlik <vojtech@suse.cz>
parent ac85c026
...@@ -1313,7 +1313,7 @@ void hid_init_reports(struct hid_device *hid) ...@@ -1313,7 +1313,7 @@ void hid_init_reports(struct hid_device *hid)
struct hid_report_enum *report_enum; struct hid_report_enum *report_enum;
struct hid_report *report; struct hid_report *report;
struct list_head *list; struct list_head *list;
int err, ret; int err, ret, size;
/* /*
* The Set_Idle request is supposed to affect only the * The Set_Idle request is supposed to affect only the
...@@ -1336,6 +1336,10 @@ void hid_init_reports(struct hid_device *hid) ...@@ -1336,6 +1336,10 @@ void hid_init_reports(struct hid_device *hid)
list = report_enum->report_list.next; list = report_enum->report_list.next;
while (list != &report_enum->report_list) { while (list != &report_enum->report_list) {
report = (struct hid_report *) list; report = (struct hid_report *) list;
size = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
if (size > hid->urbin->transfer_buffer_length)
hid->urbin->transfer_buffer_length = size;
hid_submit_report(hid, report, USB_DIR_IN); hid_submit_report(hid, report, USB_DIR_IN);
list = list->next; list = list->next;
} }
...@@ -1535,8 +1539,8 @@ static struct hid_blacklist { ...@@ -1535,8 +1539,8 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_BACK }, { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
...@@ -1657,17 +1661,12 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1657,17 +1661,12 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
interval = 1 << (interval - 1); interval = 1 << (interval - 1);
if (endpoint->bEndpointAddress & USB_DIR_IN) { if (endpoint->bEndpointAddress & USB_DIR_IN) {
int len;
if (hid->urbin) if (hid->urbin)
continue; continue;
if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
goto fail; goto fail;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
len = usb_maxpacket(dev, pipe, 0); usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
if (len > HID_BUFFER_SIZE)
len = HID_BUFFER_SIZE;
usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len,
hid_irq_in, hid, interval); hid_irq_in, hid, interval);
hid->urbin->transfer_dma = hid->inbuf_dma; hid->urbin->transfer_dma = hid->inbuf_dma;
hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
......
This diff is collapsed.
This diff is collapsed.
...@@ -171,6 +171,7 @@ struct hid_item { ...@@ -171,6 +171,7 @@ struct hid_item {
#define HID_USAGE_PAGE 0xffff0000 #define HID_USAGE_PAGE 0xffff0000
#define HID_UP_UNDEFINED 0x00000000
#define HID_UP_GENDESK 0x00010000 #define HID_UP_GENDESK 0x00010000
#define HID_UP_KEYBOARD 0x00070000 #define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000 #define HID_UP_LED 0x00080000
...@@ -187,7 +188,36 @@ struct hid_item { ...@@ -187,7 +188,36 @@ struct hid_item {
#define HID_GD_MOUSE 0x00010002 #define HID_GD_MOUSE 0x00010002
#define HID_GD_JOYSTICK 0x00010004 #define HID_GD_JOYSTICK 0x00010004
#define HID_GD_GAMEPAD 0x00010005 #define HID_GD_GAMEPAD 0x00010005
#define HID_GD_KEYBOARD 0x00010006
#define HID_GD_KEYPAD 0x00010007
#define HID_GD_MULTIAXIS 0x00010008
#define HID_GD_X 0x00010030
#define HID_GD_Y 0x00010031
#define HID_GD_Z 0x00010032
#define HID_GD_RX 0x00010033
#define HID_GD_RY 0x00010034
#define HID_GD_RZ 0x00010035
#define HID_GD_SLIDER 0x00010036
#define HID_GD_DIAL 0x00010037
#define HID_GD_WHEEL 0x00010038
#define HID_GD_HATSWITCH 0x00010039 #define HID_GD_HATSWITCH 0x00010039
#define HID_GD_BUFFER 0x0001003a
#define HID_GD_BYTECOUNT 0x0001003b
#define HID_GD_MOTION 0x0001003c
#define HID_GD_START 0x0001003d
#define HID_GD_SELECT 0x0001003e
#define HID_GD_VX 0x00010040
#define HID_GD_VY 0x00010041
#define HID_GD_VZ 0x00010042
#define HID_GD_VBRX 0x00010043
#define HID_GD_VBRY 0x00010044
#define HID_GD_VBRZ 0x00010045
#define HID_GD_VNO 0x00010046
#define HID_GD_FEATURE 0x00010047
#define HID_GD_UP 0x00010090
#define HID_GD_DOWN 0x00010091
#define HID_GD_RIGHT 0x00010092
#define HID_GD_LEFT 0x00010093
/* /*
* HID report types --- Ouch! HID spec says 1 2 3! * HID report types --- Ouch! HID spec says 1 2 3!
...@@ -208,8 +238,8 @@ struct hid_item { ...@@ -208,8 +238,8 @@ struct hid_item {
#define HID_QUIRK_HIDDEV 0x010 #define HID_QUIRK_HIDDEV 0x010
#define HID_QUIRK_BADPAD 0x020 #define HID_QUIRK_BADPAD 0x020
#define HID_QUIRK_MULTI_INPUT 0x040 #define HID_QUIRK_MULTI_INPUT 0x040
#define HID_QUIRK_2WHEEL_MOUSE_HACK_BACK 0x080 #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080
#define HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA 0x100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
/* /*
...@@ -262,12 +292,16 @@ struct hid_collection { ...@@ -262,12 +292,16 @@ struct hid_collection {
struct hid_usage { struct hid_usage {
unsigned hid; /* hid usage code */ unsigned hid; /* hid usage code */
unsigned collection_index; /* index into collection array */ unsigned collection_index; /* index into collection array */
/* hidinput data */
__u16 code; /* input driver code */ __u16 code; /* input driver code */
__u8 type; /* input driver type */ __u8 type; /* input driver type */
__s8 hat_min; /* hat switch fun */ __s8 hat_min; /* hat switch fun */
__s8 hat_max; /* ditto */ __s8 hat_max; /* ditto */
__s8 hat_dir; /* ditto */
}; };
struct hid_input;
struct hid_field { struct hid_field {
unsigned physical; /* physical usage for this field */ unsigned physical; /* physical usage for this field */
unsigned logical; /* logical usage for this field */ unsigned logical; /* logical usage for this field */
...@@ -288,6 +322,9 @@ struct hid_field { ...@@ -288,6 +322,9 @@ struct hid_field {
unsigned unit; unsigned unit;
struct hid_report *report; /* associated report */ struct hid_report *report; /* associated report */
unsigned index; /* index into report->field[] */ unsigned index; /* index into report->field[] */
/* hidinput data */
struct hid_input *hidinput; /* associated input structure */
__u16 dpad; /* dpad input code */
}; };
#define HID_MAX_FIELDS 64 #define HID_MAX_FIELDS 64
...@@ -423,6 +460,7 @@ struct hid_descriptor { ...@@ -423,6 +460,7 @@ struct hid_descriptor {
#define hid_dump_device(c) do { } while (0) #define hid_dump_device(c) do { } while (0)
#define hid_dump_field(a,b) do { } while (0) #define hid_dump_field(a,b) do { } while (0)
#define resolv_usage(a) do { } while (0) #define resolv_usage(a) do { } while (0)
#define resolv_event(a,b) do { } while (0)
#endif #endif
#endif #endif
...@@ -430,7 +468,7 @@ struct hid_descriptor { ...@@ -430,7 +468,7 @@ struct hid_descriptor {
#ifdef CONFIG_USB_HIDINPUT #ifdef CONFIG_USB_HIDINPUT
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */ /* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001)) #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs); extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
extern int hidinput_connect(struct hid_device *); extern int hidinput_connect(struct hid_device *);
......
...@@ -482,6 +482,9 @@ struct input_absinfo { ...@@ -482,6 +482,9 @@ struct input_absinfo {
#define REL_X 0x00 #define REL_X 0x00
#define REL_Y 0x01 #define REL_Y 0x01
#define REL_Z 0x02 #define REL_Z 0x02
#define REL_RX 0x03
#define REL_RY 0x04
#define REL_RZ 0x05
#define REL_HWHEEL 0x06 #define REL_HWHEEL 0x06
#define REL_DIAL 0x07 #define REL_DIAL 0x07
#define REL_WHEEL 0x08 #define REL_WHEEL 0x08
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment