aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@gmail.com>2008-04-03 16:17:52 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-04-03 16:17:52 -0400
commit8a0f83eacc1bb8899094b17483de95ddf2d8fcc6 (patch)
tree65260075061391f84223aaab025c47fc22b64dde
parent3797fec17193e05dee9666b990d6c84e16b188b3 (diff)
Input: xpad - match xbox 360 devices with interface info
Match Xbox 360 controllers using the interface info, i.e. interface class 255 (Vendor specific), subclass 93 and protocol 1, instead of specifying the device ids individually. As the class is vendor-specific, we have to still match against vendor id as well, though. Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/joystick/xpad.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 0380597249bb..8804ad30dae2 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -91,6 +91,7 @@
91 91
92#define XTYPE_XBOX 0 92#define XTYPE_XBOX 0
93#define XTYPE_XBOX360 1 93#define XTYPE_XBOX360 1
94#define XTYPE_UNKNOWN 2
94 95
95static int dpad_to_buttons; 96static int dpad_to_buttons;
96module_param(dpad_to_buttons, bool, S_IRUGO); 97module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -138,7 +139,7 @@ static const struct xpad_device {
138 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 139 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
139 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, 140 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
140 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 141 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
141 { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } 142 { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
142}; 143};
143 144
144static const signed short xpad_btn[] = { 145static const signed short xpad_btn[] = {
@@ -173,12 +174,20 @@ static const signed short xpad_abs_pad[] = {
173 -1 /* terminating entry */ 174 -1 /* terminating entry */
174}; 175};
175 176
176/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only 177/* Xbox 360 has a vendor-specific class, so we cannot match it with only
177 * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, 178 * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
178 * but we need only one of them. */ 179 * match against vendor id as well. Also, some Xbox 360 devices have multiple
180 * interface protocols, we only need protocol 1. */
181#define XPAD_XBOX360_VENDOR(vend) \
182 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
183 .idVendor = (vend), \
184 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
185 .bInterfaceSubClass = 93, \
186 .bInterfaceProtocol = 1
187
179static struct usb_device_id xpad_table [] = { 188static struct usb_device_id xpad_table [] = {
180 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ 189 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
181 { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ 190 { XPAD_XBOX360_VENDOR(0x045e) }, /* Microsoft X-Box 360 controllers */
182 { } 191 { }
183}; 192};
184 193
@@ -645,6 +654,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
645 xpad->xtype = xpad_device[i].xtype; 654 xpad->xtype = xpad_device[i].xtype;
646 if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) 655 if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
647 xpad->dpad_mapping = dpad_to_buttons; 656 xpad->dpad_mapping = dpad_to_buttons;
657 if (xpad->xtype == XTYPE_UNKNOWN)
658 xpad->xtype = (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC);
648 xpad->dev = input_dev; 659 xpad->dev = input_dev;
649 usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); 660 usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
650 strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); 661 strlcat(xpad->phys, "/input0", sizeof(xpad->phys));