| 1 | |
| 2 | |
| 3 | * Xbox gamepad driver
|
| 4 | *
|
| 5 | * Copyright (c) 2002 Marko Friedemann <[email protected]>
|
| 6 | * 2004 Oliver Schwartz <[email protected]>,
|
| 7 | * Steven Toth <[email protected]>,
|
| 8 | * Franz Lehner <[email protected]>,
|
| 9 | * Ivan Hawkes <[email protected]>
|
| 10 | * 2005 Dominic Cerquetti <[email protected]>
|
| 11 | * 2006 Adam Buchbinder <[email protected]>
|
| 12 | * 2007 Jan Kratochvil <[email protected]>
|
| 13 | * 2010 Christoph Fritz <[email protected]>
|
| 14 | *
|
| 15 | * This driver is based on:
|
| 16 | * - information from http://euc.jp/periphs/xbox-controller.ja.html
|
| 17 | * - the iForce driver drivers/char/joystick/iforce.c
|
| 18 | * - the skeleton-driver drivers/usb/usb-skeleton.c
|
| 19 | * - Xbox 360 information http://www.free60.org/wiki/Gamepad
|
| 20 | * - Xbox One information https://github.com/quantus/xbox-one-controller-protocol
|
| 21 | *
|
| 22 | * Thanks to:
|
| 23 | * - ITO Takayuki for providing essential xpad information on his website
|
| 24 | * - Vojtech Pavlik - iforce driver / input subsystem
|
| 25 | * - Greg Kroah-Hartman - usb-skeleton driver
|
| 26 | * - Xbox Linux project - extra USB IDs
|
| 27 | * - Pekka Pöyry (quantus) - Xbox One controller reverse-engineering
|
| 28 |
|
| 29 |
|
| 30 | #include <linux/bits.h>
|
| 31 | #include <linux/kernel.h>
|
| 32 | #include <linux/input.h>
|
| 33 | #include <linux/rcupdate.h>
|
| 34 | #include <linux/slab.h>
|
| 35 | #include <linux/stat.h>
|
| 36 | #include <linux/module.h>
|
| 37 | #include <linux/usb/input.h>
|
| 38 | #include <linux/usb/quirks.h>
|
| 39 |
|
| 40 | #define XPAD_PKT_LEN 64
|
| 41 |
|
| 42 | |
| 43 | * xbox d-pads should map to buttons, as is required for DDR pads
|
| 44 | * but we map them to axes when possible to simplify things
|
| 45 |
|
| 46 | #define MAP_DPAD_TO_BUTTONS BIT(0)
|
| 47 | #define MAP_TRIGGERS_TO_BUTTONS BIT(1)
|
| 48 | #define MAP_STICKS_TO_NULL BIT(2)
|
| 49 | #define MAP_SHARE_BUTTON BIT(3)
|
| 50 | #define MAP_PADDLES BIT(4)
|
| 51 | #define MAP_PROFILE_BUTTON BIT(5)
|
| 52 | #define MAP_SHARE_OFFSET BIT(6)
|
| 53 |
|
| 54 | #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
|
| 55 | MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
|
| 56 |
|
| 57 | #define XTYPE_XBOX 0
|
| 58 | #define XTYPE_XBOX360 1
|
| 59 | #define XTYPE_XBOX360W 2
|
| 60 | #define XTYPE_XBOXONE 3
|
| 61 | #define XTYPE_UNKNOWN 4
|
| 62 |
|
| 63 | |
| 64 | * seconds
|
| 65 |
|
| 66 | #define XPAD360W_POWEROFF_TIMEOUT 5
|
| 67 |
|
| 68 | #define PKT_XB 0
|
| 69 | #define PKT_XBE1 1
|
| 70 | #define PKT_XBE2_FW_OLD 2
|
| 71 | #define PKT_XBE2_FW_5_EARLY 3
|
| 72 | #define PKT_XBE2_FW_5_11 4
|
| 73 |
|
| 74 | #define FLAG_DELAY_INIT BIT(0)
|
| 75 |
|
| 76 | static bool dpad_to_buttons;
|
| 77 | module_param(dpad_to_buttons, bool, S_IRUGO);
|
| 78 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
|
| 79 |
|
| 80 | static bool triggers_to_buttons;
|
| 81 | module_param(triggers_to_buttons, bool, S_IRUGO);
|
| 82 | MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
|
| 83 |
|
| 84 | static bool sticks_to_null;
|
| 85 | module_param(sticks_to_null, bool, S_IRUGO);
|
| 86 | MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
|
| 87 |
|
| 88 | static bool auto_poweroff = true;
|
| 89 | module_param(auto_poweroff, bool, S_IWUSR | S_IRUGO);
|
| 90 | MODULE_PARM_DESC(auto_poweroff, "Power off wireless controllers on suspend");
|
| 91 |
|
| 92 | static const struct xpad_device {
|
| 93 | u16 idVendor;
|
| 94 | u16 idProduct;
|
| 95 | char *name;
|
| 96 | u8 mapping;
|
| 97 | u8 xtype;
|
| 98 | u8 flags;
|
| 99 | } xpad_device[] = {
|
| 100 |
|
| 101 | { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
|
| 102 | { 0x0351, 0x1000, "CRKD LP Blueberry Burst Pro Edition (Xbox)", 0, XTYPE_XBOX360 },
|
| 103 | { 0x0351, 0x2000, "CRKD LP Black Tribal Edition (Xbox) ", 0, XTYPE_XBOX360 },
|
| 104 | { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 },
|
| 105 | { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 },
|
| 106 | { 0x03f0, 0x038D, "HyperX Clutch", 0, XTYPE_XBOX360 },
|
| 107 | { 0x03f0, 0x048D, "HyperX Clutch", 0, XTYPE_XBOX360 },
|
| 108 | { 0x03f0, 0x0495, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE },
|
| 109 | { 0x03f0, 0x07A0, "HyperX Clutch Gladiate RGB", 0, XTYPE_XBOXONE },
|
| 110 | { 0x03f0, 0x08B6, "HyperX Clutch Gladiate", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 111 | { 0x03f0, 0x09B4, "HyperX Clutch Tanto", 0, XTYPE_XBOXONE },
|
| 112 | { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
|
| 113 | { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
|
| 114 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
|
| 115 | { 0x044f, 0x0f10, "Thrustmaster Modena GT Wheel", 0, XTYPE_XBOX },
|
| 116 | { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 },
|
| 117 | { 0x044f, 0xd01e, "ThrustMaster, Inc. ESWAP X 2 ELDEN RING EDITION", 0, XTYPE_XBOXONE },
|
| 118 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
|
| 119 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
|
| 120 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
|
| 121 | { 0x045e, 0x0288, "Microsoft Xbox Controller S v2", 0, XTYPE_XBOX },
|
| 122 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
|
| 123 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
| 124 | { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
|
| 125 | { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
| 126 | { 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
| 127 | { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
| 128 | { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
|
| 129 | { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
|
| 130 | { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
|
| 131 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
| 132 | { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE },
|
| 133 | { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE },
|
| 134 | { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SHARE_BUTTON | MAP_SHARE_OFFSET, XTYPE_XBOXONE },
|
| 135 | { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
|
| 136 | { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 },
|
| 137 | { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
|
| 138 | { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
|
| 139 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
|
| 140 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
|
| 141 | { 0x046d, 0xca8a, "Logitech Precision Vibration Feedback Wheel", 0, XTYPE_XBOX },
|
| 142 | { 0x046d, 0xcaa3, "Logitech DriveFx Racing Wheel", 0, XTYPE_XBOX360 },
|
| 143 | { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX360 },
|
| 144 | { 0x056e, 0x2004, "Elecom JC-U3613M", 0, XTYPE_XBOX360 },
|
| 145 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
|
| 146 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
|
| 147 | { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX },
|
| 148 | { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX },
|
| 149 | { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX },
|
| 150 | { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX },
|
| 151 | { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX },
|
| 152 | { 0x06a3, 0x0201, "Saitek Adrenalin", 0, XTYPE_XBOX },
|
| 153 | { 0x06a3, 0xf51a, "Saitek P3600", 0, XTYPE_XBOX360 },
|
| 154 | { 0x0738, 0x4503, "Mad Catz Racing Wheel", 0, XTYPE_XBOXONE },
|
| 155 | { 0x0738, 0x4506, "Mad Catz 4506 Wireless Controller", 0, XTYPE_XBOX },
|
| 156 | { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
|
| 157 | { 0x0738, 0x4520, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
|
| 158 | { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
|
| 159 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
|
| 160 | { 0x0738, 0x4530, "Mad Catz Universal MC2 Racing Wheel and Pedals", 0, XTYPE_XBOX },
|
| 161 | { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
|
| 162 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 163 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
|
| 164 | { 0x0738, 0x4586, "Mad Catz MicroCon Wireless Controller", 0, XTYPE_XBOX },
|
| 165 | { 0x0738, 0x4588, "Mad Catz Blaster", 0, XTYPE_XBOX },
|
| 166 | { 0x0738, 0x45ff, "Mad Catz Beat Pad (w/ Handle)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 167 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 168 | { 0x0738, 0x4718, "Mad Catz Street Fighter IV FightStick SE", 0, XTYPE_XBOX360 },
|
| 169 | { 0x0738, 0x4726, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 170 | { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 171 | { 0x0738, 0x4736, "Mad Catz MicroCon Gamepad", 0, XTYPE_XBOX360 },
|
| 172 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 173 | { 0x0738, 0x4740, "Mad Catz Beat Pad", 0, XTYPE_XBOX360 },
|
| 174 | { 0x0738, 0x4743, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 175 | { 0x0738, 0x4758, "Mad Catz Arcade Game Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 176 | { 0x0738, 0x4a01, "Mad Catz FightStick TE 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 177 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 178 | { 0x0738, 0x9871, "Mad Catz Portable Drum", 0, XTYPE_XBOX360 },
|
| 179 | { 0x0738, 0xb726, "Mad Catz Xbox controller - MW2", 0, XTYPE_XBOX360 },
|
| 180 | { 0x0738, 0xb738, "Mad Catz MVC2TE Stick 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 181 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", 0, XTYPE_XBOX360 },
|
| 182 | { 0x0738, 0xcb02, "Saitek Cyborg Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
|
| 183 | { 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
|
| 184 | { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
|
| 185 | { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
|
| 186 | { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
|
| 187 | { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 188 | { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
|
| 189 | { 0x0b05, 0x1c91, "ASUS ROG RAIKIRI II", 0, XTYPE_XBOX360 },
|
| 190 | { 0x0b05, 0x1c92, "ASUS ROG RAIKIRI II WIRELESS", 0, XTYPE_XBOX360 },
|
| 191 | { 0x0b05, 0x1c96, "ASUS ROG RAIKIRI II XBOX", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 192 | { 0x0b05, 0x1d04, "ASUS ROG RAIKIRI II XBOX WIRELESS", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 193 | { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
|
| 194 | { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
|
| 195 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
|
| 196 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
|
| 197 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
|
| 198 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
|
| 199 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
|
| 200 | { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 201 | { 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 },
|
| 202 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
|
| 203 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
|
| 204 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
|
| 205 | { 0x0e4c, 0x3510, "Radica Gamester", 0, XTYPE_XBOX },
|
| 206 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
|
| 207 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
|
| 208 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
|
| 209 | { 0x0e6f, 0x0008, "After Glow Pro Controller", 0, XTYPE_XBOX },
|
| 210 | { 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
|
| 211 | { 0x0e6f, 0x0113, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
| 212 | { 0x0e6f, 0x011f, "Rock Candy Gamepad Wired Controller", 0, XTYPE_XBOX360 },
|
| 213 | { 0x0e6f, 0x0131, "PDP EA Sports Controller", 0, XTYPE_XBOX360 },
|
| 214 | { 0x0e6f, 0x0133, "Xbox 360 Wired Controller", 0, XTYPE_XBOX360 },
|
| 215 | { 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
|
| 216 | { 0x0e6f, 0x013a, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 217 | { 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
|
| 218 | { 0x0e6f, 0x0147, "PDP Marvel Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 219 | { 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 220 | { 0x0e6f, 0x015d, "PDP Mirror's Edge Official Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
|
| 221 | { 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 222 | { 0x0e6f, 0x0162, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 223 | { 0x0e6f, 0x0163, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 224 | { 0x0e6f, 0x0164, "PDP Battlefield One", 0, XTYPE_XBOXONE },
|
| 225 | { 0x0e6f, 0x0165, "PDP Titanfall 2", 0, XTYPE_XBOXONE },
|
| 226 | { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 227 | { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
| 228 | { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
| 229 | { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
|
| 230 | { 0x0e6f, 0x024c, "PDP Victrix Pro BFG Wired Controller for Xbox", 0, XTYPE_XBOXONE },
|
| 231 | { 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 232 | { 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 233 | { 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE },
|
| 234 | { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
|
| 235 | { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, XTYPE_XBOXONE },
|
| 236 | { 0x0e6f, 0x02a7, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 237 | { 0x0e6f, 0x02a8, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
|
| 238 | { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
|
| 239 | { 0x0e6f, 0x02ad, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
|
| 240 | { 0x0e6f, 0x02b3, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
|
| 241 | { 0x0e6f, 0x02b8, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
|
| 242 | { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
|
| 243 | { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
|
| 244 | { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
|
| 245 | { 0x0e6f, 0x0413, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
| 246 | { 0x0e6f, 0x0501, "PDP Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 247 | { 0x0e6f, 0xf900, "PDP Afterglow AX.1", 0, XTYPE_XBOX360 },
|
| 248 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
|
| 249 | { 0x0e8f, 0x3008, "Generic xbox control (dealextreme)", 0, XTYPE_XBOX },
|
| 250 | { 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick", 0, XTYPE_XBOX360 },
|
| 251 | { 0x0f0d, 0x000c, "Hori PadEX Turbo", 0, XTYPE_XBOX360 },
|
| 252 | { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 253 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 254 | { 0x0f0d, 0x001b, "Hori Real Arcade Pro VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 255 | { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 256 | { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
|
| 257 | { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 258 | { 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 259 | { 0x0f0d, 0x00dc, "HORIPAD FPS for Nintendo Switch", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 260 | { 0x0f0d, 0x0151, "Hori Racing Wheel Overdrive for Xbox Series X", 0, XTYPE_XBOXONE },
|
| 261 | { 0x0f0d, 0x0152, "Hori Racing Wheel Overdrive for Xbox Series X", 0, XTYPE_XBOXONE },
|
| 262 | { 0x0f0d, 0x01b2, "HORI Taiko No Tatsujin Drum Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 263 | { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
|
| 264 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
|
| 265 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
|
| 266 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
|
| 267 | { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
| 268 | { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
| 269 | { 0x10f5, 0x7005, "Turtle Beach Recon Controller", 0, XTYPE_XBOXONE },
|
| 270 | { 0x10f5, 0x7008, "Turtle Beach Recon Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 271 | { 0x10f5, 0x7073, "Turtle Beach Stealth Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 272 | { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
|
| 273 | { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 },
|
| 274 | { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
|
| 275 | { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
|
| 276 | { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 },
|
| 277 | { 0x12ab, 0x0303, "Mortal Kombat Klassic FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 278 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 279 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
|
| 280 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
| 281 | { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
|
| 282 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
|
| 283 | { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 284 | { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
| 285 | { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
|
| 286 | { 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE },
|
| 287 | { 0x1532, 0x0a57, "Razer Wolverine V3 Pro (Wired)", 0, XTYPE_XBOX360 },
|
| 288 | { 0x1532, 0x0a59, "Razer Wolverine V3 Pro (2.4 GHz Dongle)", 0, XTYPE_XBOX360 },
|
| 289 | { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
|
| 290 | { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
|
| 291 | { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
|
| 292 | { 0x162e, 0xbeef, "Joytech Neo-Se Take2", 0, XTYPE_XBOX360 },
|
| 293 | { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
|
| 294 | { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
|
| 295 | { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
|
| 296 | { 0x16d0, 0x1103, "Azeron Cyro", 0, XTYPE_XBOX360 },
|
| 297 | { 0x16d0, 0x113c, "Azeron Cyborg", 0, XTYPE_XBOX360 },
|
| 298 | { 0x16d0, 0x1192, "Azeron Classic/Compact", 0, XTYPE_XBOX360 },
|
| 299 | { 0x16d0, 0x1212, "Azeron Cyro Lefty", 0, XTYPE_XBOX360 },
|
| 300 | { 0x16d0, 0x12f7, "Azeron Cyborg II", 0, XTYPE_XBOX360 },
|
| 301 | { 0x16d0, 0x13ea, "Azeron Keyzen", 0, XTYPE_XBOX360 },
|
| 302 | { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
|
| 303 | { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
|
| 304 | { 0x1a86, 0xe310, "Legion Go S", 0, XTYPE_XBOX360 },
|
| 305 | { 0x1b1c, 0x2b1f, "Corsair Novablade Pro (Wired)", 0, XTYPE_XBOX360 },
|
| 306 | { 0x1b1c, 0x2b2b, "Corsair Novablade Pro (2.4 GHz Receiver)", 0, XTYPE_XBOX360 },
|
| 307 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
|
| 308 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
|
| 309 | { 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
|
| 310 | { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 311 | { 0x1bad, 0xf018, "Mad Catz Street Fighter IV SE Fighting Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 312 | { 0x1bad, 0xf019, "Mad Catz Brawlstick for Xbox 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 313 | { 0x1bad, 0xf021, "Mad Cats Ghost Recon FS GamePad", 0, XTYPE_XBOX360 },
|
| 314 | { 0x1bad, 0xf023, "MLG Pro Circuit Controller (Xbox)", 0, XTYPE_XBOX360 },
|
| 315 | { 0x1bad, 0xf025, "Mad Catz Call Of Duty", 0, XTYPE_XBOX360 },
|
| 316 | { 0x1bad, 0xf027, "Mad Catz FPS Pro", 0, XTYPE_XBOX360 },
|
| 317 | { 0x1bad, 0xf028, "Street Fighter IV FightPad", 0, XTYPE_XBOX360 },
|
| 318 | { 0x1bad, 0xf02e, "Mad Catz Fightpad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 319 | { 0x1bad, 0xf030, "Mad Catz Xbox 360 MC2 MicroCon Racing Wheel", 0, XTYPE_XBOX360 },
|
| 320 | { 0x1bad, 0xf036, "Mad Catz MicroCon GamePad Pro", 0, XTYPE_XBOX360 },
|
| 321 | { 0x1bad, 0xf038, "Street Fighter IV FightStick TE", 0, XTYPE_XBOX360 },
|
| 322 | { 0x1bad, 0xf039, "Mad Catz MvC2 TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 323 | { 0x1bad, 0xf03a, "Mad Catz SFxT Fightstick Pro", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 324 | { 0x1bad, 0xf03d, "Street Fighter IV Arcade Stick TE - Chun Li", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 325 | { 0x1bad, 0xf03e, "Mad Catz MLG FightStick TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 326 | { 0x1bad, 0xf03f, "Mad Catz FightStick SoulCaliber", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 327 | { 0x1bad, 0xf042, "Mad Catz FightStick TES+", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 328 | { 0x1bad, 0xf080, "Mad Catz FightStick TE2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 329 | { 0x1bad, 0xf501, "HoriPad EX2 Turbo", 0, XTYPE_XBOX360 },
|
| 330 | { 0x1bad, 0xf502, "Hori Real Arcade Pro.VX SA", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 331 | { 0x1bad, 0xf503, "Hori Fighting Stick VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 332 | { 0x1bad, 0xf504, "Hori Real Arcade Pro. EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 333 | { 0x1bad, 0xf505, "Hori Fighting Stick EX2B", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 334 | { 0x1bad, 0xf506, "Hori Real Arcade Pro.EX Premium VLX", 0, XTYPE_XBOX360 },
|
| 335 | { 0x1bad, 0xf900, "Harmonix Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 336 | { 0x1bad, 0xf901, "Gamestop Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
| 337 | { 0x1bad, 0xf903, "Tron Xbox 360 controller", 0, XTYPE_XBOX360 },
|
| 338 | { 0x1bad, 0xf904, "PDP Versus Fighting Pad", 0, XTYPE_XBOX360 },
|
| 339 | { 0x1bad, 0xf906, "MortalKombat FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 340 | { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 },
|
| 341 | { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
|
| 342 | { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
|
| 343 | { 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
|
| 344 | { 0x20bc, 0x5134, "BETOP BTP-KP50B Xinput Dongle", 0, XTYPE_XBOX360 },
|
| 345 | { 0x20bc, 0x514a, "BETOP BTP-KP50C Xinput Dongle", 0, XTYPE_XBOX360 },
|
| 346 | { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
|
| 347 | { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
|
| 348 | { 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 349 | { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
|
| 350 | { 0x20d6, 0x400b, "PowerA FUSION Pro 4 Wired Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 351 | { 0x20d6, 0x890b, "PowerA MOGA XP-Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 352 | { 0x2345, 0xe00b, "Machenike G5 Pro Controller", 0, XTYPE_XBOX360 },
|
| 353 | { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 354 | { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
|
| 355 | { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
|
| 356 | { 0x24c6, 0x530a, "Xbox 360 Pro EX Controller", 0, XTYPE_XBOX360 },
|
| 357 | { 0x24c6, 0x531a, "PowerA Pro Ex", 0, XTYPE_XBOX360 },
|
| 358 | { 0x24c6, 0x5397, "FUS1ON Tournament Controller", 0, XTYPE_XBOX360 },
|
| 359 | { 0x24c6, 0x541a, "PowerA Xbox One Mini Wired Controller", 0, XTYPE_XBOXONE },
|
| 360 | { 0x24c6, 0x542a, "Xbox ONE spectra", 0, XTYPE_XBOXONE },
|
| 361 | { 0x24c6, 0x543a, "PowerA Xbox One wired controller", 0, XTYPE_XBOXONE },
|
| 362 | { 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 },
|
| 363 | { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 },
|
| 364 | { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 365 | { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 366 | { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
|
| 367 | { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
|
| 368 | { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 369 | { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
| 370 | { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
|
| 371 | { 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE },
|
| 372 | { 0x24c6, 0x581a, "ThrustMaster XB1 Classic Controller", 0, XTYPE_XBOXONE },
|
| 373 | { 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
|
| 374 | { 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller", 0, XTYPE_XBOX360 },
|
| 375 | { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
|
| 376 | { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
|
| 377 | { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
| 378 | { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 },
|
| 379 | { 0x294b, 0x3303, "Snakebyte GAMEPAD BASE X", 0, XTYPE_XBOXONE },
|
| 380 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
|
| 381 | { 0x2993, 0x2001, "TECNO Pocket Go", 0, XTYPE_XBOX360 },
|
| 382 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
|
| 383 | { 0x2dc8, 0x200f, "8BitDo Ultimate 3-mode Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 384 | { 0x2dc8, 0x201e, "8BitDo Pro 2 Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 385 | { 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
|
| 386 | { 0x2dc8, 0x3109, "8BitDo Ultimate Wireless Bluetooth", 0, XTYPE_XBOX360 },
|
| 387 | { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
|
| 388 | { 0x2dc8, 0x310b, "8BitDo Ultimate 2 Wireless Controller", 0, XTYPE_XBOX360 },
|
| 389 | { 0x2dc8, 0x6001, "8BitDo SN30 Pro", 0, XTYPE_XBOX360 },
|
| 390 | { 0x2e24, 0x0423, "Hyperkin DuchesS Xbox One pad", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 391 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
|
| 392 | { 0x2e24, 0x1688, "Hyperkin X91 X-Box One pad", 0, XTYPE_XBOXONE },
|
| 393 | { 0x2e95, 0x0504, "SCUF Gaming Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
| 394 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
|
| 395 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
|
| 396 | { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
|
| 397 | { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
|
| 398 | { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 },
|
| 399 | { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
|
| 400 | { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
|
| 401 | { 0x3285, 0x0603, "Nacon Pro Compact controller for Xbox", 0, XTYPE_XBOXONE },
|
| 402 | { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
|
| 403 | { 0x3285, 0x0614, "Nacon Pro Compact", 0, XTYPE_XBOXONE },
|
| 404 | { 0x3285, 0x0646, "Nacon Pro Compact", 0, XTYPE_XBOXONE },
|
| 405 | { 0x3285, 0x0662, "Nacon Revolution5 Pro", 0, XTYPE_XBOX360 },
|
| 406 | { 0x3285, 0x0663, "Nacon Evol-X", 0, XTYPE_XBOXONE },
|
| 407 | { 0x3507, 0x000b, "ZENAIM LEVERLESS", 0, XTYPE_XBOX360 },
|
| 408 | { 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 },
|
| 409 | { 0x3537, 0x100f, "GameSir Nova 2 Lite", 0, XTYPE_XBOX360 },
|
| 410 | { 0x3537, 0x1010, "GameSir G7 SE", 0, XTYPE_XBOXONE },
|
| 411 | { 0x3651, 0x1000, "CRKD SG", 0, XTYPE_XBOX360 },
|
| 412 | { 0x366c, 0x0005, "ByoWave Proteus Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE, FLAG_DELAY_INIT },
|
| 413 | { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
|
| 414 | { 0x37d7, 0x2501, "Flydigi Apex 5", 0, XTYPE_XBOX360 },
|
| 415 | { 0x413d, 0x2104, "Black Shark Green Ghost Gamepad", 0, XTYPE_XBOX360 },
|
| 416 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
|
| 417 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
|
| 418 | };
|
| 419 |
|
| 420 |
|
| 421 | static const signed short xpad_common_btn[] = {
|
| 422 | BTN_A, BTN_B, BTN_X, BTN_Y,
|
| 423 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR,
|
| 424 | -1
|
| 425 | };
|
| 426 |
|
| 427 |
|
| 428 | static const signed short xpad_btn[] = {
|
| 429 | BTN_C, BTN_Z,
|
| 430 | -1
|
| 431 | };
|
| 432 |
|
| 433 |
|
| 434 | static const signed short xpad_btn_pad[] = {
|
| 435 | BTN_DPAD_LEFT, BTN_DPAD_RIGHT,
|
| 436 | BTN_DPAD_UP, BTN_DPAD_DOWN,
|
| 437 | -1
|
| 438 | };
|
| 439 |
|
| 440 |
|
| 441 | static const signed short xpad_btn_triggers[] = {
|
| 442 | BTN_TL2, BTN_TR2,
|
| 443 | -1
|
| 444 | };
|
| 445 |
|
| 446 | static const signed short xpad360_btn[] = {
|
| 447 | BTN_TL, BTN_TR,
|
| 448 | BTN_MODE,
|
| 449 | -1
|
| 450 | };
|
| 451 |
|
| 452 | static const signed short xpad_abs[] = {
|
| 453 | ABS_X, ABS_Y,
|
| 454 | ABS_RX, ABS_RY,
|
| 455 | -1
|
| 456 | };
|
| 457 |
|
| 458 |
|
| 459 | static const signed short xpad_abs_pad[] = {
|
| 460 | ABS_HAT0X, ABS_HAT0Y,
|
| 461 | -1
|
| 462 | };
|
| 463 |
|
| 464 |
|
| 465 | static const signed short xpad_abs_triggers[] = {
|
| 466 | ABS_Z, ABS_RZ,
|
| 467 | -1
|
| 468 | };
|
| 469 |
|
| 470 |
|
| 471 | static const signed short xpad_btn_paddles[] = {
|
| 472 | BTN_GRIPR, BTN_GRIPR2,
|
| 473 | BTN_GRIPL, BTN_GRIPL2,
|
| 474 | -1
|
| 475 | };
|
| 476 |
|
| 477 | |
| 478 | * Xbox 360 has a vendor-specific class, so we cannot match it with only
|
| 479 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
|
| 480 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1,
|
| 481 | * wireless controllers have protocol 129.
|
| 482 |
|
| 483 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend, pr) \
|
| 484 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
|
| 485 | .idVendor = (vend), \
|
| 486 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
|
| 487 | .bInterfaceSubClass = 93, \
|
| 488 | .bInterfaceProtocol = (pr)
|
| 489 | #define XPAD_XBOX360_VENDOR(vend) \
|
| 490 | { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 1) }, \
|
| 491 | { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 129) }
|
| 492 |
|
| 493 |
|
| 494 | #define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \
|
| 495 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
|
| 496 | .idVendor = (vend), \
|
| 497 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
|
| 498 | .bInterfaceSubClass = 71, \
|
| 499 | .bInterfaceProtocol = (pr)
|
| 500 | #define XPAD_XBOXONE_VENDOR(vend) \
|
| 501 | { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) }
|
| 502 |
|
| 503 | static const struct usb_device_id xpad_table[] = {
|
| 504 | |
| 505 | * Please keep this list sorted by vendor ID. Note that there are 2
|
| 506 | * macros - XPAD_XBOX360_VENDOR and XPAD_XBOXONE_VENDOR.
|
| 507 |
|
| 508 | { USB_INTERFACE_INFO('X', 'B', 0) },
|
| 509 | XPAD_XBOX360_VENDOR(0x0079),
|
| 510 | XPAD_XBOX360_VENDOR(0x0351),
|
| 511 | XPAD_XBOX360_VENDOR(0x03eb),
|
| 512 | XPAD_XBOX360_VENDOR(0x03f0),
|
| 513 | XPAD_XBOXONE_VENDOR(0x03f0),
|
| 514 | XPAD_XBOX360_VENDOR(0x044f),
|
| 515 | XPAD_XBOXONE_VENDOR(0x044f),
|
| 516 | XPAD_XBOX360_VENDOR(0x045e),
|
| 517 | XPAD_XBOXONE_VENDOR(0x045e),
|
| 518 | XPAD_XBOX360_VENDOR(0x046d),
|
| 519 | XPAD_XBOX360_VENDOR(0x0502),
|
| 520 | XPAD_XBOX360_VENDOR(0x056e),
|
| 521 | XPAD_XBOX360_VENDOR(0x06a3),
|
| 522 | XPAD_XBOX360_VENDOR(0x0738),
|
| 523 | { USB_DEVICE(0x0738, 0x4540) },
|
| 524 | XPAD_XBOXONE_VENDOR(0x0738),
|
| 525 | XPAD_XBOX360_VENDOR(0x07ff),
|
| 526 | XPAD_XBOX360_VENDOR(0x0b05),
|
| 527 | XPAD_XBOXONE_VENDOR(0x0b05),
|
| 528 | XPAD_XBOX360_VENDOR(0x0c12),
|
| 529 | XPAD_XBOX360_VENDOR(0x0db0),
|
| 530 | XPAD_XBOX360_VENDOR(0x0e6f),
|
| 531 | XPAD_XBOXONE_VENDOR(0x0e6f),
|
| 532 | XPAD_XBOX360_VENDOR(0x0f0d),
|
| 533 | XPAD_XBOXONE_VENDOR(0x0f0d),
|
| 534 | XPAD_XBOX360_VENDOR(0x1038),
|
| 535 | XPAD_XBOXONE_VENDOR(0x10f5),
|
| 536 | XPAD_XBOX360_VENDOR(0x11c9),
|
| 537 | XPAD_XBOX360_VENDOR(0x11ff),
|
| 538 | XPAD_XBOX360_VENDOR(0x1209),
|
| 539 | XPAD_XBOX360_VENDOR(0x12ab),
|
| 540 | XPAD_XBOX360_VENDOR(0x1430),
|
| 541 | XPAD_XBOX360_VENDOR(0x146b),
|
| 542 | XPAD_XBOX360_VENDOR(0x1532),
|
| 543 | XPAD_XBOXONE_VENDOR(0x1532),
|
| 544 | XPAD_XBOX360_VENDOR(0x15e4),
|
| 545 | XPAD_XBOX360_VENDOR(0x162e),
|
| 546 | XPAD_XBOX360_VENDOR(0x1689),
|
| 547 | XPAD_XBOX360_VENDOR(0x16d0),
|
| 548 | XPAD_XBOX360_VENDOR(0x17ef),
|
| 549 | XPAD_XBOX360_VENDOR(0x1949),
|
| 550 | XPAD_XBOX360_VENDOR(0x1a86),
|
| 551 | XPAD_XBOX360_VENDOR(0x1b1c),
|
| 552 | XPAD_XBOX360_VENDOR(0x1bad),
|
| 553 | XPAD_XBOX360_VENDOR(0x1ee9),
|
| 554 | XPAD_XBOX360_VENDOR(0x20bc),
|
| 555 | XPAD_XBOX360_VENDOR(0x20d6),
|
| 556 | XPAD_XBOXONE_VENDOR(0x20d6),
|
| 557 | XPAD_XBOX360_VENDOR(0x2345),
|
| 558 | XPAD_XBOX360_VENDOR(0x24c6),
|
| 559 | XPAD_XBOXONE_VENDOR(0x24c6),
|
| 560 | XPAD_XBOX360_VENDOR(0x2563),
|
| 561 | XPAD_XBOX360_VENDOR(0x260d),
|
| 562 | XPAD_XBOXONE_VENDOR(0x294b),
|
| 563 | XPAD_XBOX360_VENDOR(0x2993),
|
| 564 | XPAD_XBOX360_VENDOR(0x2c22),
|
| 565 | XPAD_XBOX360_VENDOR(0x2dc8),
|
| 566 | XPAD_XBOXONE_VENDOR(0x2dc8),
|
| 567 | XPAD_XBOXONE_VENDOR(0x2e24),
|
| 568 | XPAD_XBOX360_VENDOR(0x2f24),
|
| 569 | XPAD_XBOXONE_VENDOR(0x2e95),
|
| 570 | XPAD_XBOX360_VENDOR(0x31e3),
|
| 571 | XPAD_XBOX360_VENDOR(0x3285),
|
| 572 | XPAD_XBOXONE_VENDOR(0x3285),
|
| 573 | XPAD_XBOX360_VENDOR(0x3507),
|
| 574 | XPAD_XBOX360_VENDOR(0x3537),
|
| 575 | XPAD_XBOXONE_VENDOR(0x3537),
|
| 576 | XPAD_XBOX360_VENDOR(0x3651),
|
| 577 | XPAD_XBOXONE_VENDOR(0x366c),
|
| 578 | XPAD_XBOX360_VENDOR(0x37d7),
|
| 579 | XPAD_XBOX360_VENDOR(0x3958),
|
| 580 | XPAD_XBOX360_VENDOR(0x413d),
|
| 581 | { }
|
| 582 | };
|
| 583 |
|
| 584 | MODULE_DEVICE_TABLE(usb, xpad_table);
|
| 585 |
|
| 586 | struct xboxone_init_packet {
|
| 587 | u16 idVendor;
|
| 588 | u16 idProduct;
|
| 589 | const u8 *data;
|
| 590 | u8 len;
|
| 591 | };
|
| 592 |
|
| 593 | #define XBOXONE_INIT_PKT(_vid, _pid, _data) \
|
| 594 | { \
|
| 595 | .idVendor = (_vid), \
|
| 596 | .idProduct = (_pid), \
|
| 597 | .data = (_data), \
|
| 598 | .len = ARRAY_SIZE(_data), \
|
| 599 | }
|
| 600 |
|
| 601 | |
| 602 | * starting with xbox one, the game input protocol is used
|
| 603 | * magic numbers are taken from
|
| 604 | * - https://github.com/xpadneo/gip-dissector/blob/main/src/gip-dissector.lua
|
| 605 | * - https://github.com/medusalix/xone/blob/master/bus/protocol.c
|
| 606 |
|
| 607 | #define GIP_CMD_ACK 0x01
|
| 608 | #define GIP_CMD_ANNOUNCE 0x02
|
| 609 | #define GIP_CMD_IDENTIFY 0x04
|
| 610 | #define GIP_CMD_POWER 0x05
|
| 611 | #define GIP_CMD_AUTHENTICATE 0x06
|
| 612 | #define GIP_CMD_VIRTUAL_KEY 0x07
|
| 613 | #define GIP_CMD_RUMBLE 0x09
|
| 614 | #define GIP_CMD_LED 0x0a
|
| 615 | #define GIP_CMD_FIRMWARE 0x0c
|
| 616 | #define GIP_CMD_INPUT 0x20
|
| 617 |
|
| 618 | #define GIP_SEQ0 0x00
|
| 619 |
|
| 620 | #define GIP_OPT_ACK 0x10
|
| 621 | #define GIP_OPT_INTERNAL 0x20
|
| 622 |
|
| 623 | |
| 624 | * length of the command payload encoded with
|
| 625 | * https://en.wikipedia.org/wiki/LEB128
|
| 626 | * which is a no-op for N < 128
|
| 627 |
|
| 628 | #define GIP_PL_LEN(N) (N)
|
| 629 |
|
| 630 | |
| 631 | * payload specific defines
|
| 632 |
|
| 633 | #define GIP_PWR_ON 0x00
|
| 634 | #define GIP_LED_ON 0x01
|
| 635 |
|
| 636 | #define GIP_MOTOR_R BIT(0)
|
| 637 | #define GIP_MOTOR_L BIT(1)
|
| 638 | #define GIP_MOTOR_RT BIT(2)
|
| 639 | #define GIP_MOTOR_LT BIT(3)
|
| 640 | #define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT)
|
| 641 |
|
| 642 | #define GIP_WIRED_INTF_DATA 0
|
| 643 | #define GIP_WIRED_INTF_AUDIO 1
|
| 644 |
|
| 645 | |
| 646 | * This packet is required for all Xbox One pads with 2015
|
| 647 | * or later firmware installed (or present from the factory).
|
| 648 |
|
| 649 | static const u8 xboxone_power_on[] = {
|
| 650 | GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(1), GIP_PWR_ON
|
| 651 | };
|
| 652 |
|
| 653 | |
| 654 | * This packet is required for Xbox One S (0x045e:0x02ea)
|
| 655 | * and Xbox One Elite Series 2 (0x045e:0x0b00) pads to
|
| 656 | * initialize the controller that was previously used in
|
| 657 | * Bluetooth mode.
|
| 658 |
|
| 659 | static const u8 xboxone_s_init[] = {
|
| 660 | GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, 0x0f, 0x06
|
| 661 | };
|
| 662 |
|
| 663 | |
| 664 | * This packet is required to get additional input data
|
| 665 | * from Xbox One Elite Series 2 (0x045e:0x0b00) pads.
|
| 666 | * We mostly do this right now to get paddle data
|
| 667 |
|
| 668 | static const u8 extra_input_packet_init[] = {
|
| 669 | 0x4d, 0x10, 0x01, 0x02, 0x07, 0x00
|
| 670 | };
|
| 671 |
|
| 672 | |
| 673 | * This packet is required for the Titanfall 2 Xbox One pads
|
| 674 | * (0x0e6f:0x0165) to finish initialization and for Hori pads
|
| 675 | * (0x0f0d:0x0067) to make the analog sticks work.
|
| 676 |
|
| 677 | static const u8 xboxone_hori_ack_id[] = {
|
| 678 | GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9),
|
| 679 | 0x00, GIP_CMD_IDENTIFY, GIP_OPT_INTERNAL, 0x3a, 0x00, 0x00, 0x00, 0x80, 0x00
|
| 680 | };
|
| 681 |
|
| 682 | |
| 683 | * This packet is sent by default on Windows, and is required for some pads to
|
| 684 | * start sending input reports, including most (all?) of the PDP. These pads
|
| 685 | * include: (0x0e6f:0x02ab), (0x0e6f:0x02a4), (0x0e6f:0x02a6).
|
| 686 |
|
| 687 | static const u8 xboxone_led_on[] = { GIP_CMD_LED, GIP_OPT_INTERNAL, GIP_SEQ0,
|
| 688 | GIP_PL_LEN(3), 0x00, GIP_LED_ON, 0x14 };
|
| 689 |
|
| 690 | |
| 691 | * This packet is required for most (all?) of the PDP pads to start
|
| 692 | * sending input reports. These pads include: (0x0e6f:0x02ab),
|
| 693 | * (0x0e6f:0x02a4), (0x0e6f:0x02a6).
|
| 694 |
|
| 695 | static const u8 xboxone_auth_done[] = {
|
| 696 | GIP_CMD_AUTHENTICATE, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(2), 0x01, 0x00
|
| 697 | };
|
| 698 |
|
| 699 | |
| 700 | * A specific rumble packet is required for some PowerA pads to start
|
| 701 | * sending input reports. One of those pads is (0x24c6:0x543a).
|
| 702 |
|
| 703 | static const u8 xboxone_rumblebegin_init[] = {
|
| 704 | GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9),
|
| 705 | 0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x1D, 0x1D, 0xFF, 0x00, 0x00
|
| 706 | };
|
| 707 |
|
| 708 | |
| 709 | * A rumble packet with zero FF intensity will immediately
|
| 710 | * terminate the rumbling required to init PowerA pads.
|
| 711 | * This should happen fast enough that the motors don't
|
| 712 | * spin up to enough speed to actually vibrate the gamepad.
|
| 713 |
|
| 714 | static const u8 xboxone_rumbleend_init[] = {
|
| 715 | GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9),
|
| 716 | 0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
| 717 | };
|
| 718 |
|
| 719 | |
| 720 | * This specifies the selection of init packets that a gamepad
|
| 721 | * will be sent on init *and* the order in which they will be
|
| 722 | * sent. The correct sequence number will be added when the
|
| 723 | * packet is going to be sent.
|
| 724 |
|
| 725 | static const struct xboxone_init_packet xboxone_init_packets[] = {
|
| 726 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_ack_id),
|
| 727 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_ack_id),
|
| 728 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_power_on),
|
| 729 | XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
|
| 730 | XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
|
| 731 | XBOXONE_INIT_PKT(0x045e, 0x0b00, extra_input_packet_init),
|
| 732 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_led_on),
|
| 733 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_auth_done),
|
| 734 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
|
| 735 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
|
| 736 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
|
| 737 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumbleend_init),
|
| 738 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumbleend_init),
|
| 739 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init),
|
| 740 | };
|
| 741 |
|
| 742 | struct xpad_output_packet {
|
| 743 | u8 data[XPAD_PKT_LEN];
|
| 744 | u8 len;
|
| 745 | bool pending;
|
| 746 | };
|
| 747 |
|
| 748 | #define XPAD_OUT_CMD_IDX 0
|
| 749 | #define XPAD_OUT_FF_IDX 1
|
| 750 | #define XPAD_OUT_LED_IDX (1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
|
| 751 | #define XPAD_NUM_OUT_PACKETS (1 + \
|
| 752 | IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF) + \
|
| 753 | IS_ENABLED(CONFIG_JOYSTICK_XPAD_LEDS))
|
| 754 |
|
| 755 | struct usb_xpad {
|
| 756 | struct input_dev *dev;
|
| 757 | struct input_dev __rcu *x360w_dev;
|
| 758 | struct usb_device *udev;
|
| 759 | struct usb_interface *intf;
|
| 760 |
|
| 761 | bool pad_present;
|
| 762 | bool input_created;
|
| 763 |
|
| 764 | struct urb *irq_in;
|
| 765 | unsigned char *idata;
|
| 766 | dma_addr_t idata_dma;
|
| 767 |
|
| 768 | struct urb *irq_out;
|
| 769 | struct usb_anchor irq_out_anchor;
|
| 770 | bool irq_out_active;
|
| 771 | u8 odata_serial;
|
| 772 | unsigned char *odata;
|
| 773 | dma_addr_t odata_dma;
|
| 774 | spinlock_t odata_lock;
|
| 775 |
|
| 776 | struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
|
| 777 | int last_out_packet;
|
| 778 | int init_seq;
|
| 779 |
|
| 780 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
| 781 | struct xpad_led *led;
|
| 782 | #endif
|
| 783 |
|
| 784 | char phys[64];
|
| 785 |
|
| 786 | int mapping;
|
| 787 | int xtype;
|
| 788 | int packet_type;
|
| 789 | int pad_nr;
|
| 790 | const char *name;
|
| 791 | struct work_struct work;
|
| 792 | time64_t mode_btn_down_ts;
|
| 793 | bool delay_init;
|
| 794 | bool delayed_init_done;
|
| 795 | };
|
| 796 |
|
| 797 | static int xpad_init_input(struct usb_xpad *xpad);
|
| 798 | static void xpad_deinit_input(struct usb_xpad *xpad);
|
| 799 | static int xpad_start_input(struct usb_xpad *xpad);
|
| 800 | static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
|
| 801 | static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
|
| 802 |
|
| 803 | |
| 804 | * xpad_process_packet
|
| 805 | *
|
| 806 | * Completes a request by converting the data into events for the
|
| 807 | * input subsystem.
|
| 808 | *
|
| 809 | * The used report descriptor was taken from ITO Takayuki's website:
|
| 810 | * http://euc.jp/periphs/xbox-controller.ja.html
|
| 811 |
|
| 812 | static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
|
| 813 | {
|
| 814 | struct input_dev *dev = xpad->dev;
|
| 815 |
|
| 816 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
|
| 817 |
|
| 818 | input_report_abs(dev, ABS_X,
|
| 819 | (__s16) le16_to_cpup((__le16 *)(data + 12)));
|
| 820 | input_report_abs(dev, ABS_Y,
|
| 821 | ~(__s16) le16_to_cpup((__le16 *)(data + 14)));
|
| 822 |
|
| 823 |
|
| 824 | input_report_abs(dev, ABS_RX,
|
| 825 | (__s16) le16_to_cpup((__le16 *)(data + 16)));
|
| 826 | input_report_abs(dev, ABS_RY,
|
| 827 | ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
|
| 828 | }
|
| 829 |
|
| 830 |
|
| 831 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
| 832 | input_report_key(dev, BTN_TL2, data[10]);
|
| 833 | input_report_key(dev, BTN_TR2, data[11]);
|
| 834 | } else {
|
| 835 | input_report_abs(dev, ABS_Z, data[10]);
|
| 836 | input_report_abs(dev, ABS_RZ, data[11]);
|
| 837 | }
|
| 838 |
|
| 839 |
|
| 840 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
| 841 |
|
| 842 | input_report_key(dev, BTN_DPAD_LEFT, data[2] & BIT(2));
|
| 843 | input_report_key(dev, BTN_DPAD_RIGHT, data[2] & BIT(3));
|
| 844 | input_report_key(dev, BTN_DPAD_UP, data[2] & BIT(0));
|
| 845 | input_report_key(dev, BTN_DPAD_DOWN, data[2] & BIT(1));
|
| 846 | } else {
|
| 847 | input_report_abs(dev, ABS_HAT0X,
|
| 848 | !!(data[2] & 0x08) - !!(data[2] & 0x04));
|
| 849 | input_report_abs(dev, ABS_HAT0Y,
|
| 850 | !!(data[2] & 0x02) - !!(data[2] & 0x01));
|
| 851 | }
|
| 852 |
|
| 853 |
|
| 854 | input_report_key(dev, BTN_START, data[2] & BIT(4));
|
| 855 | input_report_key(dev, BTN_SELECT, data[2] & BIT(5));
|
| 856 | input_report_key(dev, BTN_THUMBL, data[2] & BIT(6));
|
| 857 | input_report_key(dev, BTN_THUMBR, data[2] & BIT(7));
|
| 858 |
|
| 859 |
|
| 860 | input_report_key(dev, BTN_A, data[4]);
|
| 861 | input_report_key(dev, BTN_B, data[5]);
|
| 862 | input_report_key(dev, BTN_X, data[6]);
|
| 863 | input_report_key(dev, BTN_Y, data[7]);
|
| 864 |
|
| 865 |
|
| 866 | input_report_key(dev, BTN_C, data[8]);
|
| 867 | input_report_key(dev, BTN_Z, data[9]);
|
| 868 |
|
| 869 |
|
| 870 | input_sync(dev);
|
| 871 | }
|
| 872 |
|
| 873 | |
| 874 | * xpad360_process_packet
|
| 875 | *
|
| 876 | * Completes a request by converting the data into events for the
|
| 877 | * input subsystem. It is version for xbox 360 controller
|
| 878 | *
|
| 879 | * The used report descriptor was taken from:
|
| 880 | * http://www.free60.org/wiki/Gamepad
|
| 881 |
|
| 882 |
|
| 883 | static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
|
| 884 | u16 cmd, unsigned char *data)
|
| 885 | {
|
| 886 |
|
| 887 | if (data[0] != 0x00)
|
| 888 | return;
|
| 889 |
|
| 890 |
|
| 891 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
| 892 |
|
| 893 | input_report_key(dev, BTN_DPAD_LEFT, data[2] & BIT(2));
|
| 894 | input_report_key(dev, BTN_DPAD_RIGHT, data[2] & BIT(3));
|
| 895 | input_report_key(dev, BTN_DPAD_UP, data[2] & BIT(0));
|
| 896 | input_report_key(dev, BTN_DPAD_DOWN, data[2] & BIT(1));
|
| 897 | }
|
| 898 |
|
| 899 | |
| 900 | * This should be a simple else block. However historically
|
| 901 | * xbox360w has mapped DPAD to buttons while xbox360 did not. This
|
| 902 | * made no sense, but now we can not just switch back and have to
|
| 903 | * support both behaviors.
|
| 904 |
|
| 905 | if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) ||
|
| 906 | xpad->xtype == XTYPE_XBOX360W) {
|
| 907 | input_report_abs(dev, ABS_HAT0X,
|
| 908 | !!(data[2] & 0x08) - !!(data[2] & 0x04));
|
| 909 | input_report_abs(dev, ABS_HAT0Y,
|
| 910 | !!(data[2] & 0x02) - !!(data[2] & 0x01));
|
| 911 | }
|
| 912 |
|
| 913 |
|
| 914 | input_report_key(dev, BTN_START, data[2] & BIT(4));
|
| 915 | input_report_key(dev, BTN_SELECT, data[2] & BIT(5));
|
| 916 |
|
| 917 |
|
| 918 | input_report_key(dev, BTN_THUMBL, data[2] & BIT(6));
|
| 919 | input_report_key(dev, BTN_THUMBR, data[2] & BIT(7));
|
| 920 |
|
| 921 |
|
| 922 | input_report_key(dev, BTN_A, data[3] & BIT(4));
|
| 923 | input_report_key(dev, BTN_B, data[3] & BIT(5));
|
| 924 | input_report_key(dev, BTN_X, data[3] & BIT(6));
|
| 925 | input_report_key(dev, BTN_Y, data[3] & BIT(7));
|
| 926 | input_report_key(dev, BTN_TL, data[3] & BIT(0));
|
| 927 | input_report_key(dev, BTN_TR, data[3] & BIT(1));
|
| 928 | input_report_key(dev, BTN_MODE, data[3] & BIT(2));
|
| 929 |
|
| 930 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
|
| 931 |
|
| 932 | input_report_abs(dev, ABS_X,
|
| 933 | (__s16) le16_to_cpup((__le16 *)(data + 6)));
|
| 934 | input_report_abs(dev, ABS_Y,
|
| 935 | ~(__s16) le16_to_cpup((__le16 *)(data + 8)));
|
| 936 |
|
| 937 |
|
| 938 | input_report_abs(dev, ABS_RX,
|
| 939 | (__s16) le16_to_cpup((__le16 *)(data + 10)));
|
| 940 | input_report_abs(dev, ABS_RY,
|
| 941 | ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
|
| 942 | }
|
| 943 |
|
| 944 |
|
| 945 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
| 946 | input_report_key(dev, BTN_TL2, data[4]);
|
| 947 | input_report_key(dev, BTN_TR2, data[5]);
|
| 948 | } else {
|
| 949 | input_report_abs(dev, ABS_Z, data[4]);
|
| 950 | input_report_abs(dev, ABS_RZ, data[5]);
|
| 951 | }
|
| 952 |
|
| 953 | input_sync(dev);
|
| 954 |
|
| 955 |
|
| 956 | if (xpad->xtype == XTYPE_XBOX360W) {
|
| 957 | if (xpad->mode_btn_down_ts > 0 && xpad->pad_present &&
|
| 958 | ((ktime_get_seconds() - xpad->mode_btn_down_ts) >=
|
| 959 | XPAD360W_POWEROFF_TIMEOUT)) {
|
| 960 | xpad360w_poweroff_controller(xpad);
|
| 961 | xpad->mode_btn_down_ts = 0;
|
| 962 | return;
|
| 963 | }
|
| 964 |
|
| 965 |
|
| 966 | if (data[3] & BIT(2))
|
| 967 | xpad->mode_btn_down_ts = ktime_get_seconds();
|
| 968 | else
|
| 969 | xpad->mode_btn_down_ts = 0;
|
| 970 | }
|
| 971 | }
|
| 972 |
|
| 973 | static void xpad_presence_work(struct work_struct *work)
|
| 974 | {
|
| 975 | struct usb_xpad *xpad = container_of(work, struct usb_xpad, work);
|
| 976 | int error;
|
| 977 |
|
| 978 | if (xpad->pad_present) {
|
| 979 | error = xpad_init_input(xpad);
|
| 980 | if (error) {
|
| 981 |
|
| 982 | dev_err(&xpad->dev->dev,
|
| 983 | "unable to init device: %d\n", error);
|
| 984 | } else {
|
| 985 | rcu_assign_pointer(xpad->x360w_dev, xpad->dev);
|
| 986 | }
|
| 987 | } else {
|
| 988 | RCU_INIT_POINTER(xpad->x360w_dev, NULL);
|
| 989 | synchronize_rcu();
|
| 990 | |
| 991 | * Now that we are sure xpad360w_process_packet is not
|
| 992 | * using input device we can get rid of it.
|
| 993 |
|
| 994 | xpad_deinit_input(xpad);
|
| 995 | }
|
| 996 | }
|
| 997 |
|
| 998 | |
| 999 | * xpad360w_process_packet
|
| 1000 | *
|
| 1001 | * Completes a request by converting the data into events for the
|
| 1002 | * input subsystem. It is version for xbox 360 wireless controller.
|
| 1003 | *
|
| 1004 | * Byte.Bit
|
| 1005 | * 00.1 - Status change: The controller or headset has connected/disconnected
|
| 1006 | * Bits 01.7 and 01.6 are valid
|
| 1007 | * 01.7 - Controller present
|
| 1008 | * 01.6 - Headset present
|
| 1009 | * 01.1 - Pad state (Bytes 4+) valid
|
| 1010 | *
|
| 1011 |
|
| 1012 | static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
|
| 1013 | {
|
| 1014 | struct input_dev *dev;
|
| 1015 | bool present;
|
| 1016 |
|
| 1017 |
|
| 1018 | if (data[0] & 0x08) {
|
| 1019 | present = (data[1] & 0x80) != 0;
|
| 1020 |
|
| 1021 | if (xpad->pad_present != present) {
|
| 1022 | xpad->pad_present = present;
|
| 1023 | schedule_work(&xpad->work);
|
| 1024 | }
|
| 1025 | }
|
| 1026 |
|
| 1027 |
|
| 1028 | if (data[1] != 0x1)
|
| 1029 | return;
|
| 1030 |
|
| 1031 | rcu_read_lock();
|
| 1032 | dev = rcu_dereference(xpad->x360w_dev);
|
| 1033 | if (dev)
|
| 1034 | xpad360_process_packet(xpad, dev, cmd, &data[4]);
|
| 1035 | rcu_read_unlock();
|
| 1036 | }
|
| 1037 |
|
| 1038 | |
| 1039 | * xpadone_process_packet
|
| 1040 | *
|
| 1041 | * Completes a request by converting the data into events for the
|
| 1042 | * input subsystem. This version is for the Xbox One controller.
|
| 1043 | *
|
| 1044 | * The report format was gleaned from
|
| 1045 | * https://github.com/kylelemons/xbox/blob/master/xbox.go
|
| 1046 |
|
| 1047 | static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, u32 len)
|
| 1048 | {
|
| 1049 | struct input_dev *dev = xpad->dev;
|
| 1050 | bool do_sync = false;
|
| 1051 |
|
| 1052 |
|
| 1053 | if (data[0] == GIP_CMD_VIRTUAL_KEY) {
|
| 1054 | |
| 1055 | * The Xbox One S controller requires these reports to be
|
| 1056 | * acked otherwise it continues sending them forever and
|
| 1057 | * won't report further mode button events.
|
| 1058 |
|
| 1059 | if (data[1] == (GIP_OPT_ACK | GIP_OPT_INTERNAL))
|
| 1060 | xpadone_ack_mode_report(xpad, data[2]);
|
| 1061 |
|
| 1062 | input_report_key(dev, BTN_MODE, data[4] & GENMASK(1, 0));
|
| 1063 | input_sync(dev);
|
| 1064 |
|
| 1065 | do_sync = true;
|
| 1066 | } else if (data[0] == GIP_CMD_FIRMWARE) {
|
| 1067 |
|
| 1068 | if (xpad->packet_type == PKT_XBE2_FW_5_11) {
|
| 1069 | |
| 1070 | * Checked by looking at the active profile slot to
|
| 1071 | * verify it's the default slot
|
| 1072 |
|
| 1073 | if (data[19] != 0)
|
| 1074 | data[18] = 0;
|
| 1075 |
|
| 1076 |
|
| 1077 | input_report_key(dev, BTN_GRIPR, data[18] & BIT(0));
|
| 1078 | input_report_key(dev, BTN_GRIPR2, data[18] & BIT(1));
|
| 1079 | input_report_key(dev, BTN_GRIPL, data[18] & BIT(2));
|
| 1080 | input_report_key(dev, BTN_GRIPL2, data[18] & BIT(3));
|
| 1081 |
|
| 1082 | do_sync = true;
|
| 1083 | }
|
| 1084 | } else if (data[0] == GIP_CMD_ANNOUNCE) {
|
| 1085 | int error;
|
| 1086 |
|
| 1087 | if (xpad->delay_init && !xpad->delayed_init_done) {
|
| 1088 | xpad->delayed_init_done = true;
|
| 1089 | error = xpad_start_input(xpad);
|
| 1090 | if (error)
|
| 1091 | dev_warn(&xpad->dev->dev,
|
| 1092 | "unable to start delayed input: %d\n",
|
| 1093 | error);
|
| 1094 | }
|
| 1095 | } else if (data[0] == GIP_CMD_INPUT) {
|
| 1096 |
|
| 1097 | input_report_key(dev, BTN_START, data[4] & BIT(2));
|
| 1098 | input_report_key(dev, BTN_SELECT, data[4] & BIT(3));
|
| 1099 | if (xpad->mapping & MAP_SHARE_BUTTON) {
|
| 1100 | u32 offset = (xpad->mapping & MAP_SHARE_OFFSET) ? 26 : 18;
|
| 1101 |
|
| 1102 | if (len >= offset)
|
| 1103 | input_report_key(dev, KEY_RECORD, data[len - offset] & BIT(0));
|
| 1104 | }
|
| 1105 |
|
| 1106 |
|
| 1107 | input_report_key(dev, BTN_A, data[4] & BIT(4));
|
| 1108 | input_report_key(dev, BTN_B, data[4] & BIT(5));
|
| 1109 | input_report_key(dev, BTN_X, data[4] & BIT(6));
|
| 1110 | input_report_key(dev, BTN_Y, data[4] & BIT(7));
|
| 1111 |
|
| 1112 |
|
| 1113 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
| 1114 |
|
| 1115 | input_report_key(dev, BTN_DPAD_LEFT, data[5] & BIT(2));
|
| 1116 | input_report_key(dev, BTN_DPAD_RIGHT, data[5] & BIT(3));
|
| 1117 | input_report_key(dev, BTN_DPAD_UP, data[5] & BIT(0));
|
| 1118 | input_report_key(dev, BTN_DPAD_DOWN, data[5] & BIT(1));
|
| 1119 | } else {
|
| 1120 | input_report_abs(dev, ABS_HAT0X,
|
| 1121 | !!(data[5] & 0x08) - !!(data[5] & 0x04));
|
| 1122 | input_report_abs(dev, ABS_HAT0Y,
|
| 1123 | !!(data[5] & 0x02) - !!(data[5] & 0x01));
|
| 1124 | }
|
| 1125 |
|
| 1126 |
|
| 1127 | input_report_key(dev, BTN_TL, data[5] & BIT(4));
|
| 1128 | input_report_key(dev, BTN_TR, data[5] & BIT(5));
|
| 1129 |
|
| 1130 |
|
| 1131 | input_report_key(dev, BTN_THUMBL, data[5] & BIT(6));
|
| 1132 | input_report_key(dev, BTN_THUMBR, data[5] & BIT(7));
|
| 1133 |
|
| 1134 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
|
| 1135 |
|
| 1136 | input_report_abs(dev, ABS_X,
|
| 1137 | (__s16) le16_to_cpup((__le16 *)(data + 10)));
|
| 1138 | input_report_abs(dev, ABS_Y,
|
| 1139 | ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
|
| 1140 |
|
| 1141 |
|
| 1142 | input_report_abs(dev, ABS_RX,
|
| 1143 | (__s16) le16_to_cpup((__le16 *)(data + 14)));
|
| 1144 | input_report_abs(dev, ABS_RY,
|
| 1145 | ~(__s16) le16_to_cpup((__le16 *)(data + 16)));
|
| 1146 | }
|
| 1147 |
|
| 1148 |
|
| 1149 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
| 1150 | input_report_key(dev, BTN_TL2,
|
| 1151 | (__u16) le16_to_cpup((__le16 *)(data + 6)));
|
| 1152 | input_report_key(dev, BTN_TR2,
|
| 1153 | (__u16) le16_to_cpup((__le16 *)(data + 8)));
|
| 1154 | } else {
|
| 1155 | input_report_abs(dev, ABS_Z,
|
| 1156 | (__u16) le16_to_cpup((__le16 *)(data + 6)));
|
| 1157 | input_report_abs(dev, ABS_RZ,
|
| 1158 | (__u16) le16_to_cpup((__le16 *)(data + 8)));
|
| 1159 | }
|
| 1160 |
|
| 1161 |
|
| 1162 | if (xpad->mapping & MAP_PROFILE_BUTTON)
|
| 1163 | input_report_abs(dev, ABS_PROFILE, data[34]);
|
| 1164 |
|
| 1165 |
|
| 1166 |
|
| 1167 | if (xpad->mapping & MAP_PADDLES) {
|
| 1168 | if (xpad->packet_type == PKT_XBE1) {
|
| 1169 | |
| 1170 | * Checked by comparing the current mapping
|
| 1171 | * config against the factory mapping config
|
| 1172 |
|
| 1173 | if (memcmp(&data[4], &data[18], 2) != 0)
|
| 1174 | data[32] = 0;
|
| 1175 |
|
| 1176 |
|
| 1177 | input_report_key(dev, BTN_GRIPR, data[32] & BIT(1));
|
| 1178 | input_report_key(dev, BTN_GRIPR2, data[32] & BIT(3));
|
| 1179 | input_report_key(dev, BTN_GRIPL, data[32] & BIT(0));
|
| 1180 | input_report_key(dev, BTN_GRIPL2, data[32] & BIT(2));
|
| 1181 | } else if (xpad->packet_type == PKT_XBE2_FW_OLD) {
|
| 1182 | |
| 1183 | * Checked by comparing the current mapping
|
| 1184 | * config against the factory mapping config
|
| 1185 |
|
| 1186 | if (data[19] != 0)
|
| 1187 | data[18] = 0;
|
| 1188 |
|
| 1189 |
|
| 1190 | input_report_key(dev, BTN_GRIPR, data[18] & BIT(0));
|
| 1191 | input_report_key(dev, BTN_GRIPR2, data[18] & BIT(1));
|
| 1192 | input_report_key(dev, BTN_GRIPL, data[18] & BIT(2));
|
| 1193 | input_report_key(dev, BTN_GRIPL2, data[18] & BIT(3));
|
| 1194 | } else if (xpad->packet_type == PKT_XBE2_FW_5_EARLY) {
|
| 1195 | |
| 1196 | * Checked by comparing the current mapping
|
| 1197 | * config against the factory mapping config
|
| 1198 |
|
| 1199 | if (data[23] != 0)
|
| 1200 | data[22] = 0;
|
| 1201 |
|
| 1202 | |
| 1203 | * (before the packet was split)
|
| 1204 |
|
| 1205 | input_report_key(dev, BTN_GRIPR, data[22] & BIT(0));
|
| 1206 | input_report_key(dev, BTN_GRIPR2, data[22] & BIT(1));
|
| 1207 | input_report_key(dev, BTN_GRIPL, data[22] & BIT(2));
|
| 1208 | input_report_key(dev, BTN_GRIPL2, data[22] & BIT(3));
|
| 1209 | }
|
| 1210 | }
|
| 1211 |
|
| 1212 | do_sync = true;
|
| 1213 | }
|
| 1214 |
|
| 1215 | if (do_sync)
|
| 1216 | input_sync(dev);
|
| 1217 | }
|
| 1218 |
|
| 1219 | static void xpad_irq_in(struct urb *urb)
|
| 1220 | {
|
| 1221 | struct usb_xpad *xpad = urb->context;
|
| 1222 | struct device *dev = &xpad->intf->dev;
|
| 1223 | int retval, status;
|
| 1224 |
|
| 1225 | status = urb->status;
|
| 1226 |
|
| 1227 | switch (status) {
|
| 1228 | case 0:
|
| 1229 |
|
| 1230 | break;
|
| 1231 | case -ECONNRESET:
|
| 1232 | case -ENOENT:
|
| 1233 | case -ESHUTDOWN:
|
| 1234 |
|
| 1235 | dev_dbg(dev, "%s - urb shutting down with status: %d\n",
|
| 1236 | __func__, status);
|
| 1237 | return;
|
| 1238 | default:
|
| 1239 | dev_dbg(dev, "%s - nonzero urb status received: %d\n",
|
| 1240 | __func__, status);
|
| 1241 | goto exit;
|
| 1242 | }
|
| 1243 |
|
| 1244 | switch (xpad->xtype) {
|
| 1245 | case XTYPE_XBOX360:
|
| 1246 | xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);
|
| 1247 | break;
|
| 1248 | case XTYPE_XBOX360W:
|
| 1249 | xpad360w_process_packet(xpad, 0, xpad->idata);
|
| 1250 | break;
|
| 1251 | case XTYPE_XBOXONE:
|
| 1252 | xpadone_process_packet(xpad, 0, xpad->idata, urb->actual_length);
|
| 1253 | break;
|
| 1254 | default:
|
| 1255 | xpad_process_packet(xpad, 0, xpad->idata);
|
| 1256 | }
|
| 1257 |
|
| 1258 | exit:
|
| 1259 | retval = usb_submit_urb(urb, GFP_ATOMIC);
|
| 1260 | if (retval)
|
| 1261 | dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
|
| 1262 | __func__, retval);
|
| 1263 | }
|
| 1264 |
|
| 1265 |
|
| 1266 | static bool xpad_prepare_next_init_packet(struct usb_xpad *xpad)
|
| 1267 | {
|
| 1268 | const struct xboxone_init_packet *init_packet;
|
| 1269 |
|
| 1270 | if (xpad->xtype != XTYPE_XBOXONE)
|
| 1271 | return false;
|
| 1272 |
|
| 1273 | |
| 1274 | * Some dongles will discard init packets if they're sent before the
|
| 1275 | * controller connects. In these cases, we need to wait until we get
|
| 1276 | * an announce packet from them to send the init packet sequence.
|
| 1277 |
|
| 1278 | if (xpad->delay_init && !xpad->delayed_init_done)
|
| 1279 | return false;
|
| 1280 |
|
| 1281 |
|
| 1282 | while (xpad->init_seq < ARRAY_SIZE(xboxone_init_packets)) {
|
| 1283 | init_packet = &xboxone_init_packets[xpad->init_seq++];
|
| 1284 |
|
| 1285 | if (init_packet->idVendor != 0 &&
|
| 1286 | init_packet->idVendor != xpad->dev->id.vendor)
|
| 1287 | continue;
|
| 1288 |
|
| 1289 | if (init_packet->idProduct != 0 &&
|
| 1290 | init_packet->idProduct != xpad->dev->id.product)
|
| 1291 | continue;
|
| 1292 |
|
| 1293 |
|
| 1294 | memcpy(xpad->odata, init_packet->data, init_packet->len);
|
| 1295 | xpad->irq_out->transfer_buffer_length = init_packet->len;
|
| 1296 |
|
| 1297 |
|
| 1298 | xpad->odata[2] = xpad->odata_serial++;
|
| 1299 | return true;
|
| 1300 | }
|
| 1301 |
|
| 1302 | return false;
|
| 1303 | }
|
| 1304 |
|
| 1305 |
|
| 1306 | static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
|
| 1307 | {
|
| 1308 | struct xpad_output_packet *pkt, *packet = NULL;
|
| 1309 | int i;
|
| 1310 |
|
| 1311 |
|
| 1312 | if (xpad_prepare_next_init_packet(xpad))
|
| 1313 | return true;
|
| 1314 |
|
| 1315 | for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
|
| 1316 | if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
|
| 1317 | xpad->last_out_packet = 0;
|
| 1318 |
|
| 1319 | pkt = &xpad->out_packets[xpad->last_out_packet];
|
| 1320 | if (pkt->pending) {
|
| 1321 | dev_dbg(&xpad->intf->dev,
|
| 1322 | "%s - found pending output packet %d\n",
|
| 1323 | __func__, xpad->last_out_packet);
|
| 1324 | packet = pkt;
|
| 1325 | break;
|
| 1326 | }
|
| 1327 | }
|
| 1328 |
|
| 1329 | if (packet) {
|
| 1330 | memcpy(xpad->odata, packet->data, packet->len);
|
| 1331 | xpad->irq_out->transfer_buffer_length = packet->len;
|
| 1332 | packet->pending = false;
|
| 1333 | return true;
|
| 1334 | }
|
| 1335 |
|
| 1336 | return false;
|
| 1337 | }
|
| 1338 |
|
| 1339 |
|
| 1340 | static int xpad_try_sending_next_out_packet(struct usb_xpad *xpad)
|
| 1341 | {
|
| 1342 | int error;
|
| 1343 |
|
| 1344 | if (!xpad->irq_out_active && xpad_prepare_next_out_packet(xpad)) {
|
| 1345 | usb_anchor_urb(xpad->irq_out, &xpad->irq_out_anchor);
|
| 1346 | error = usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
|
| 1347 | if (error) {
|
| 1348 | if (error != -ENODEV)
|
| 1349 | dev_err(&xpad->intf->dev,
|
| 1350 | "%s - usb_submit_urb failed with result %d\n",
|
| 1351 | __func__, error);
|
| 1352 | usb_unanchor_urb(xpad->irq_out);
|
| 1353 | return error;
|
| 1354 | }
|
| 1355 |
|
| 1356 | xpad->irq_out_active = true;
|
| 1357 | }
|
| 1358 |
|
| 1359 | return 0;
|
| 1360 | }
|
| 1361 |
|
| 1362 | static void xpad_irq_out(struct urb *urb)
|
| 1363 | {
|
| 1364 | struct usb_xpad *xpad = urb->context;
|
| 1365 | struct device *dev = &xpad->intf->dev;
|
| 1366 | int status = urb->status;
|
| 1367 | int error;
|
| 1368 |
|
| 1369 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1370 |
|
| 1371 | switch (status) {
|
| 1372 | case 0:
|
| 1373 |
|
| 1374 | xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
|
| 1375 | break;
|
| 1376 |
|
| 1377 | case -ECONNRESET:
|
| 1378 | case -ENOENT:
|
| 1379 | case -ESHUTDOWN:
|
| 1380 |
|
| 1381 | dev_dbg(dev, "%s - urb shutting down with status: %d\n",
|
| 1382 | __func__, status);
|
| 1383 | xpad->irq_out_active = false;
|
| 1384 | break;
|
| 1385 |
|
| 1386 | default:
|
| 1387 | dev_dbg(dev, "%s - nonzero urb status received: %d\n",
|
| 1388 | __func__, status);
|
| 1389 | break;
|
| 1390 | }
|
| 1391 |
|
| 1392 | if (xpad->irq_out_active) {
|
| 1393 | usb_anchor_urb(urb, &xpad->irq_out_anchor);
|
| 1394 | error = usb_submit_urb(urb, GFP_ATOMIC);
|
| 1395 | if (error) {
|
| 1396 | dev_err(dev,
|
| 1397 | "%s - usb_submit_urb failed with result %d\n",
|
| 1398 | __func__, error);
|
| 1399 | usb_unanchor_urb(urb);
|
| 1400 | xpad->irq_out_active = false;
|
| 1401 | }
|
| 1402 | }
|
| 1403 | }
|
| 1404 |
|
| 1405 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
|
| 1406 | struct usb_endpoint_descriptor *ep_irq_out)
|
| 1407 | {
|
| 1408 | int error;
|
| 1409 |
|
| 1410 | if (xpad->xtype == XTYPE_UNKNOWN)
|
| 1411 | return 0;
|
| 1412 |
|
| 1413 | init_usb_anchor(&xpad->irq_out_anchor);
|
| 1414 |
|
| 1415 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
|
| 1416 | GFP_KERNEL, &xpad->odata_dma);
|
| 1417 | if (!xpad->odata)
|
| 1418 | return -ENOMEM;
|
| 1419 |
|
| 1420 | spin_lock_init(&xpad->odata_lock);
|
| 1421 |
|
| 1422 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
|
| 1423 | if (!xpad->irq_out) {
|
| 1424 | error = -ENOMEM;
|
| 1425 | goto err_free_coherent;
|
| 1426 | }
|
| 1427 |
|
| 1428 | usb_fill_int_urb(xpad->irq_out, xpad->udev,
|
| 1429 | usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
|
| 1430 | xpad->odata, XPAD_PKT_LEN,
|
| 1431 | xpad_irq_out, xpad, ep_irq_out->bInterval);
|
| 1432 | xpad->irq_out->transfer_dma = xpad->odata_dma;
|
| 1433 | xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
| 1434 |
|
| 1435 | return 0;
|
| 1436 |
|
| 1437 | err_free_coherent:
|
| 1438 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
|
| 1439 | return error;
|
| 1440 | }
|
| 1441 |
|
| 1442 | static void xpad_stop_output(struct usb_xpad *xpad)
|
| 1443 | {
|
| 1444 | if (xpad->xtype != XTYPE_UNKNOWN) {
|
| 1445 | if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
|
| 1446 | 5000)) {
|
| 1447 | dev_warn(&xpad->intf->dev,
|
| 1448 | "timed out waiting for output URB to complete, killing\n");
|
| 1449 | usb_kill_anchored_urbs(&xpad->irq_out_anchor);
|
| 1450 | }
|
| 1451 | }
|
| 1452 | }
|
| 1453 |
|
| 1454 | static void xpad_deinit_output(struct usb_xpad *xpad)
|
| 1455 | {
|
| 1456 | if (xpad->xtype != XTYPE_UNKNOWN) {
|
| 1457 | usb_free_urb(xpad->irq_out);
|
| 1458 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
|
| 1459 | xpad->odata, xpad->odata_dma);
|
| 1460 | }
|
| 1461 | }
|
| 1462 |
|
| 1463 | static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
|
| 1464 | {
|
| 1465 | struct xpad_output_packet *packet =
|
| 1466 | &xpad->out_packets[XPAD_OUT_CMD_IDX];
|
| 1467 |
|
| 1468 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1469 |
|
| 1470 | packet->data[0] = 0x08;
|
| 1471 | packet->data[1] = 0x00;
|
| 1472 | packet->data[2] = 0x0F;
|
| 1473 | packet->data[3] = 0xC0;
|
| 1474 | packet->data[4] = 0x00;
|
| 1475 | packet->data[5] = 0x00;
|
| 1476 | packet->data[6] = 0x00;
|
| 1477 | packet->data[7] = 0x00;
|
| 1478 | packet->data[8] = 0x00;
|
| 1479 | packet->data[9] = 0x00;
|
| 1480 | packet->data[10] = 0x00;
|
| 1481 | packet->data[11] = 0x00;
|
| 1482 | packet->len = 12;
|
| 1483 | packet->pending = true;
|
| 1484 |
|
| 1485 |
|
| 1486 | xpad->last_out_packet = -1;
|
| 1487 | return xpad_try_sending_next_out_packet(xpad);
|
| 1488 | }
|
| 1489 |
|
| 1490 | static int xpad_start_xbox_one(struct usb_xpad *xpad)
|
| 1491 | {
|
| 1492 | int error;
|
| 1493 |
|
| 1494 | if (usb_ifnum_to_if(xpad->udev, GIP_WIRED_INTF_AUDIO)) {
|
| 1495 | |
| 1496 | * Explicitly disable the audio interface. This is needed
|
| 1497 | * for some controllers, such as the PowerA Enhanced Wired
|
| 1498 | * Controller for Series X|S (0x20d6:0x200e) to report the
|
| 1499 | * guide button.
|
| 1500 |
|
| 1501 | error = usb_set_interface(xpad->udev,
|
| 1502 | GIP_WIRED_INTF_AUDIO, 0);
|
| 1503 | if (error)
|
| 1504 | dev_warn(&xpad->dev->dev,
|
| 1505 | "unable to disable audio interface: %d\n",
|
| 1506 | error);
|
| 1507 | }
|
| 1508 |
|
| 1509 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1510 |
|
| 1511 | |
| 1512 | * Begin the init sequence by attempting to send a packet.
|
| 1513 | * We will cycle through the init packet sequence before
|
| 1514 | * sending any packets from the output ring.
|
| 1515 |
|
| 1516 | xpad->init_seq = 0;
|
| 1517 | return xpad_try_sending_next_out_packet(xpad);
|
| 1518 | }
|
| 1519 |
|
| 1520 | static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
|
| 1521 | {
|
| 1522 | struct xpad_output_packet *packet =
|
| 1523 | &xpad->out_packets[XPAD_OUT_CMD_IDX];
|
| 1524 | static const u8 mode_report_ack[] = {
|
| 1525 | GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9),
|
| 1526 | 0x00, GIP_CMD_VIRTUAL_KEY, GIP_OPT_INTERNAL, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
|
| 1527 | };
|
| 1528 |
|
| 1529 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1530 |
|
| 1531 | packet->len = sizeof(mode_report_ack);
|
| 1532 | memcpy(packet->data, mode_report_ack, packet->len);
|
| 1533 | packet->data[2] = seq_num;
|
| 1534 | packet->pending = true;
|
| 1535 |
|
| 1536 |
|
| 1537 | xpad->last_out_packet = -1;
|
| 1538 | xpad_try_sending_next_out_packet(xpad);
|
| 1539 | }
|
| 1540 |
|
| 1541 | #ifdef CONFIG_JOYSTICK_XPAD_FF
|
| 1542 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
|
| 1543 | {
|
| 1544 | struct usb_xpad *xpad = input_get_drvdata(dev);
|
| 1545 | struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX];
|
| 1546 | __u16 strong;
|
| 1547 | __u16 weak;
|
| 1548 |
|
| 1549 | if (effect->type != FF_RUMBLE)
|
| 1550 | return 0;
|
| 1551 |
|
| 1552 | strong = effect->u.rumble.strong_magnitude;
|
| 1553 | weak = effect->u.rumble.weak_magnitude;
|
| 1554 |
|
| 1555 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1556 |
|
| 1557 | switch (xpad->xtype) {
|
| 1558 | case XTYPE_XBOX:
|
| 1559 | packet->data[0] = 0x00;
|
| 1560 | packet->data[1] = 0x06;
|
| 1561 | packet->data[2] = 0x00;
|
| 1562 | packet->data[3] = strong / 256;
|
| 1563 | packet->data[4] = 0x00;
|
| 1564 | packet->data[5] = weak / 256;
|
| 1565 | packet->len = 6;
|
| 1566 | packet->pending = true;
|
| 1567 | break;
|
| 1568 |
|
| 1569 | case XTYPE_XBOX360:
|
| 1570 | packet->data[0] = 0x00;
|
| 1571 | packet->data[1] = 0x08;
|
| 1572 | packet->data[2] = 0x00;
|
| 1573 | packet->data[3] = strong / 256;
|
| 1574 | packet->data[4] = weak / 256;
|
| 1575 | packet->data[5] = 0x00;
|
| 1576 | packet->data[6] = 0x00;
|
| 1577 | packet->data[7] = 0x00;
|
| 1578 | packet->len = 8;
|
| 1579 | packet->pending = true;
|
| 1580 | break;
|
| 1581 |
|
| 1582 | case XTYPE_XBOX360W:
|
| 1583 | packet->data[0] = 0x00;
|
| 1584 | packet->data[1] = 0x01;
|
| 1585 | packet->data[2] = 0x0F;
|
| 1586 | packet->data[3] = 0xC0;
|
| 1587 | packet->data[4] = 0x00;
|
| 1588 | packet->data[5] = strong / 256;
|
| 1589 | packet->data[6] = weak / 256;
|
| 1590 | packet->data[7] = 0x00;
|
| 1591 | packet->data[8] = 0x00;
|
| 1592 | packet->data[9] = 0x00;
|
| 1593 | packet->data[10] = 0x00;
|
| 1594 | packet->data[11] = 0x00;
|
| 1595 | packet->len = 12;
|
| 1596 | packet->pending = true;
|
| 1597 | break;
|
| 1598 |
|
| 1599 | case XTYPE_XBOXONE:
|
| 1600 | packet->data[0] = GIP_CMD_RUMBLE;
|
| 1601 | packet->data[1] = 0x00;
|
| 1602 | packet->data[2] = xpad->odata_serial++;
|
| 1603 | packet->data[3] = GIP_PL_LEN(9);
|
| 1604 | packet->data[4] = 0x00;
|
| 1605 | packet->data[5] = GIP_MOTOR_ALL;
|
| 1606 | packet->data[6] = 0x00;
|
| 1607 | packet->data[7] = 0x00;
|
| 1608 | packet->data[8] = strong / 512;
|
| 1609 | packet->data[9] = weak / 512;
|
| 1610 | packet->data[10] = 0xFF;
|
| 1611 | packet->data[11] = 0x00;
|
| 1612 | packet->data[12] = 0xFF;
|
| 1613 | packet->len = 13;
|
| 1614 | packet->pending = true;
|
| 1615 | break;
|
| 1616 |
|
| 1617 | default:
|
| 1618 | dev_dbg(&xpad->dev->dev,
|
| 1619 | "%s - rumble command sent to unsupported xpad type: %d\n",
|
| 1620 | __func__, xpad->xtype);
|
| 1621 | return -EINVAL;
|
| 1622 | }
|
| 1623 |
|
| 1624 | return xpad_try_sending_next_out_packet(xpad);
|
| 1625 | }
|
| 1626 |
|
| 1627 | static int xpad_init_ff(struct usb_xpad *xpad)
|
| 1628 | {
|
| 1629 | if (xpad->xtype == XTYPE_UNKNOWN)
|
| 1630 | return 0;
|
| 1631 |
|
| 1632 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
|
| 1633 |
|
| 1634 | return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
|
| 1635 | }
|
| 1636 |
|
| 1637 | #else
|
| 1638 | static int xpad_init_ff(struct usb_xpad *xpad) { return 0; }
|
| 1639 | #endif
|
| 1640 |
|
| 1641 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
| 1642 | #include <linux/leds.h>
|
| 1643 | #include <linux/idr.h>
|
| 1644 |
|
| 1645 | static DEFINE_IDA(xpad_pad_seq);
|
| 1646 |
|
| 1647 | struct xpad_led {
|
| 1648 | char name[16];
|
| 1649 | struct led_classdev led_cdev;
|
| 1650 | struct usb_xpad *xpad;
|
| 1651 | };
|
| 1652 |
|
| 1653 | |
| 1654 | * set the LEDs on Xbox 360 / Wireless Controllers
|
| 1655 | * @param command
|
| 1656 | * 0: off
|
| 1657 | * 1: all blink, then previous setting
|
| 1658 | * 2: 1/top-left blink, then on
|
| 1659 | * 3: 2/top-right blink, then on
|
| 1660 | * 4: 3/bottom-left blink, then on
|
| 1661 | * 5: 4/bottom-right blink, then on
|
| 1662 | * 6: 1/top-left on
|
| 1663 | * 7: 2/top-right on
|
| 1664 | * 8: 3/bottom-left on
|
| 1665 | * 9: 4/bottom-right on
|
| 1666 | * 10: rotate
|
| 1667 | * 11: blink, based on previous setting
|
| 1668 | * 12: slow blink, based on previous setting
|
| 1669 | * 13: rotate with two lights
|
| 1670 | * 14: persistent slow all blink
|
| 1671 | * 15: blink once, then previous setting
|
| 1672 |
|
| 1673 | static void xpad_send_led_command(struct usb_xpad *xpad, int command)
|
| 1674 | {
|
| 1675 | struct xpad_output_packet *packet =
|
| 1676 | &xpad->out_packets[XPAD_OUT_LED_IDX];
|
| 1677 |
|
| 1678 | command %= 16;
|
| 1679 |
|
| 1680 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1681 |
|
| 1682 | switch (xpad->xtype) {
|
| 1683 | case XTYPE_XBOX360:
|
| 1684 | packet->data[0] = 0x01;
|
| 1685 | packet->data[1] = 0x03;
|
| 1686 | packet->data[2] = command;
|
| 1687 | packet->len = 3;
|
| 1688 | packet->pending = true;
|
| 1689 | break;
|
| 1690 |
|
| 1691 | case XTYPE_XBOX360W:
|
| 1692 | packet->data[0] = 0x00;
|
| 1693 | packet->data[1] = 0x00;
|
| 1694 | packet->data[2] = 0x08;
|
| 1695 | packet->data[3] = 0x40 + command;
|
| 1696 | packet->data[4] = 0x00;
|
| 1697 | packet->data[5] = 0x00;
|
| 1698 | packet->data[6] = 0x00;
|
| 1699 | packet->data[7] = 0x00;
|
| 1700 | packet->data[8] = 0x00;
|
| 1701 | packet->data[9] = 0x00;
|
| 1702 | packet->data[10] = 0x00;
|
| 1703 | packet->data[11] = 0x00;
|
| 1704 | packet->len = 12;
|
| 1705 | packet->pending = true;
|
| 1706 | break;
|
| 1707 | }
|
| 1708 |
|
| 1709 | xpad_try_sending_next_out_packet(xpad);
|
| 1710 | }
|
| 1711 |
|
| 1712 | |
| 1713 | * Light up the segment corresponding to the pad number on
|
| 1714 | * Xbox 360 Controllers.
|
| 1715 |
|
| 1716 | static void xpad_identify_controller(struct usb_xpad *xpad)
|
| 1717 | {
|
| 1718 | led_set_brightness(&xpad->led->led_cdev, (xpad->pad_nr % 4) + 2);
|
| 1719 | }
|
| 1720 |
|
| 1721 | static void xpad_led_set(struct led_classdev *led_cdev,
|
| 1722 | enum led_brightness value)
|
| 1723 | {
|
| 1724 | struct xpad_led *xpad_led = container_of(led_cdev,
|
| 1725 | struct xpad_led, led_cdev);
|
| 1726 |
|
| 1727 | xpad_send_led_command(xpad_led->xpad, value);
|
| 1728 | }
|
| 1729 |
|
| 1730 | static int xpad_led_probe(struct usb_xpad *xpad)
|
| 1731 | {
|
| 1732 | struct xpad_led *led;
|
| 1733 | struct led_classdev *led_cdev;
|
| 1734 | int error;
|
| 1735 |
|
| 1736 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W)
|
| 1737 | return 0;
|
| 1738 |
|
| 1739 | xpad->led = led = kzalloc_obj(*led);
|
| 1740 | if (!led)
|
| 1741 | return -ENOMEM;
|
| 1742 |
|
| 1743 | xpad->pad_nr = ida_alloc(&xpad_pad_seq, GFP_KERNEL);
|
| 1744 | if (xpad->pad_nr < 0) {
|
| 1745 | error = xpad->pad_nr;
|
| 1746 | goto err_free_mem;
|
| 1747 | }
|
| 1748 |
|
| 1749 | snprintf(led->name, sizeof(led->name), "xpad%d", xpad->pad_nr);
|
| 1750 | led->xpad = xpad;
|
| 1751 |
|
| 1752 | led_cdev = &led->led_cdev;
|
| 1753 | led_cdev->name = led->name;
|
| 1754 | led_cdev->brightness_set = xpad_led_set;
|
| 1755 | led_cdev->flags = LED_CORE_SUSPENDRESUME;
|
| 1756 |
|
| 1757 | error = led_classdev_register(&xpad->udev->dev, led_cdev);
|
| 1758 | if (error)
|
| 1759 | goto err_free_id;
|
| 1760 |
|
| 1761 | xpad_identify_controller(xpad);
|
| 1762 |
|
| 1763 | return 0;
|
| 1764 |
|
| 1765 | err_free_id:
|
| 1766 | ida_free(&xpad_pad_seq, xpad->pad_nr);
|
| 1767 | err_free_mem:
|
| 1768 | kfree(led);
|
| 1769 | xpad->led = NULL;
|
| 1770 | return error;
|
| 1771 | }
|
| 1772 |
|
| 1773 | static void xpad_led_disconnect(struct usb_xpad *xpad)
|
| 1774 | {
|
| 1775 | struct xpad_led *xpad_led = xpad->led;
|
| 1776 |
|
| 1777 | if (xpad_led) {
|
| 1778 | led_classdev_unregister(&xpad_led->led_cdev);
|
| 1779 | ida_free(&xpad_pad_seq, xpad->pad_nr);
|
| 1780 | kfree(xpad_led);
|
| 1781 | }
|
| 1782 | }
|
| 1783 | #else
|
| 1784 | static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
|
| 1785 | static void xpad_led_disconnect(struct usb_xpad *xpad) { }
|
| 1786 | #endif
|
| 1787 |
|
| 1788 | static int xpad_start_input(struct usb_xpad *xpad)
|
| 1789 | {
|
| 1790 | int error;
|
| 1791 |
|
| 1792 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
|
| 1793 | return -EIO;
|
| 1794 |
|
| 1795 | if (xpad->xtype == XTYPE_XBOXONE) {
|
| 1796 | error = xpad_start_xbox_one(xpad);
|
| 1797 | if (error) {
|
| 1798 | usb_kill_urb(xpad->irq_in);
|
| 1799 | return error;
|
| 1800 | }
|
| 1801 | }
|
| 1802 | if (xpad->xtype == XTYPE_XBOX360) {
|
| 1803 | |
| 1804 | * Some third-party controllers Xbox 360-style controllers
|
| 1805 | * require this message to finish initialization.
|
| 1806 |
|
| 1807 | u8 dummy[20];
|
| 1808 |
|
| 1809 | error = usb_control_msg_recv(xpad->udev, 0,
|
| 1810 | 0x01,
|
| 1811 |
|
| 1812 | USB_TYPE_VENDOR | USB_DIR_IN |
|
| 1813 | USB_RECIP_INTERFACE,
|
| 1814 | 0x100,
|
| 1815 | 0x00,
|
| 1816 | dummy, sizeof(dummy),
|
| 1817 | 25, GFP_KERNEL);
|
| 1818 | if (error)
|
| 1819 | dev_warn(&xpad->dev->dev,
|
| 1820 | "unable to receive magic message: %d\n",
|
| 1821 | error);
|
| 1822 | }
|
| 1823 |
|
| 1824 | return 0;
|
| 1825 | }
|
| 1826 |
|
| 1827 | static void xpad_stop_input(struct usb_xpad *xpad)
|
| 1828 | {
|
| 1829 | usb_kill_urb(xpad->irq_in);
|
| 1830 | }
|
| 1831 |
|
| 1832 | static void xpad360w_poweroff_controller(struct usb_xpad *xpad)
|
| 1833 | {
|
| 1834 | struct xpad_output_packet *packet =
|
| 1835 | &xpad->out_packets[XPAD_OUT_CMD_IDX];
|
| 1836 |
|
| 1837 | guard(spinlock_irqsave)(&xpad->odata_lock);
|
| 1838 |
|
| 1839 | packet->data[0] = 0x00;
|
| 1840 | packet->data[1] = 0x00;
|
| 1841 | packet->data[2] = 0x08;
|
| 1842 | packet->data[3] = 0xC0;
|
| 1843 | packet->data[4] = 0x00;
|
| 1844 | packet->data[5] = 0x00;
|
| 1845 | packet->data[6] = 0x00;
|
| 1846 | packet->data[7] = 0x00;
|
| 1847 | packet->data[8] = 0x00;
|
| 1848 | packet->data[9] = 0x00;
|
| 1849 | packet->data[10] = 0x00;
|
| 1850 | packet->data[11] = 0x00;
|
| 1851 | packet->len = 12;
|
| 1852 | packet->pending = true;
|
| 1853 |
|
| 1854 |
|
| 1855 | xpad->last_out_packet = -1;
|
| 1856 | xpad_try_sending_next_out_packet(xpad);
|
| 1857 | }
|
| 1858 |
|
| 1859 | static int xpad360w_start_input(struct usb_xpad *xpad)
|
| 1860 | {
|
| 1861 | int error;
|
| 1862 |
|
| 1863 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
|
| 1864 | if (error)
|
| 1865 | return -EIO;
|
| 1866 |
|
| 1867 | |
| 1868 | * Send presence packet.
|
| 1869 | * This will force the controller to resend connection packets.
|
| 1870 | * This is useful in the case we activate the module after the
|
| 1871 | * adapter has been plugged in, as it won't automatically
|
| 1872 | * send us info about the controllers.
|
| 1873 |
|
| 1874 | error = xpad_inquiry_pad_presence(xpad);
|
| 1875 | if (error) {
|
| 1876 | usb_kill_urb(xpad->irq_in);
|
| 1877 | return error;
|
| 1878 | }
|
| 1879 |
|
| 1880 | return 0;
|
| 1881 | }
|
| 1882 |
|
| 1883 | static void xpad360w_stop_input(struct usb_xpad *xpad)
|
| 1884 | {
|
| 1885 | usb_kill_urb(xpad->irq_in);
|
| 1886 |
|
| 1887 |
|
| 1888 | flush_work(&xpad->work);
|
| 1889 | }
|
| 1890 |
|
| 1891 | static int xpad_open(struct input_dev *dev)
|
| 1892 | {
|
| 1893 | struct usb_xpad *xpad = input_get_drvdata(dev);
|
| 1894 |
|
| 1895 | return xpad_start_input(xpad);
|
| 1896 | }
|
| 1897 |
|
| 1898 | static void xpad_close(struct input_dev *dev)
|
| 1899 | {
|
| 1900 | struct usb_xpad *xpad = input_get_drvdata(dev);
|
| 1901 |
|
| 1902 | xpad_stop_input(xpad);
|
| 1903 | }
|
| 1904 |
|
| 1905 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
|
| 1906 | {
|
| 1907 | struct usb_xpad *xpad = input_get_drvdata(input_dev);
|
| 1908 |
|
| 1909 | switch (abs) {
|
| 1910 | case ABS_X:
|
| 1911 | case ABS_Y:
|
| 1912 | case ABS_RX:
|
| 1913 | case ABS_RY:
|
| 1914 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
|
| 1915 | break;
|
| 1916 | case ABS_Z:
|
| 1917 | case ABS_RZ:
|
| 1918 | if (xpad->xtype == XTYPE_XBOXONE)
|
| 1919 | input_set_abs_params(input_dev, abs, 0, 1023, 0, 0);
|
| 1920 | else
|
| 1921 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
|
| 1922 | break;
|
| 1923 | case ABS_HAT0X:
|
| 1924 | case ABS_HAT0Y:
|
| 1925 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
|
| 1926 | break;
|
| 1927 | case ABS_PROFILE:
|
| 1928 | input_set_abs_params(input_dev, abs, 0, 4, 0, 0);
|
| 1929 | break;
|
| 1930 | default:
|
| 1931 | input_set_abs_params(input_dev, abs, 0, 0, 0, 0);
|
| 1932 | break;
|
| 1933 | }
|
| 1934 | }
|
| 1935 |
|
| 1936 | static void xpad_deinit_input(struct usb_xpad *xpad)
|
| 1937 | {
|
| 1938 | if (xpad->input_created) {
|
| 1939 | xpad->input_created = false;
|
| 1940 | xpad_led_disconnect(xpad);
|
| 1941 | input_unregister_device(xpad->dev);
|
| 1942 | }
|
| 1943 | }
|
| 1944 |
|
| 1945 | static int xpad_init_input(struct usb_xpad *xpad)
|
| 1946 | {
|
| 1947 | struct input_dev *input_dev;
|
| 1948 | int i, error;
|
| 1949 |
|
| 1950 | input_dev = input_allocate_device();
|
| 1951 | if (!input_dev)
|
| 1952 | return -ENOMEM;
|
| 1953 |
|
| 1954 | xpad->dev = input_dev;
|
| 1955 | input_dev->name = xpad->name;
|
| 1956 | input_dev->phys = xpad->phys;
|
| 1957 | usb_to_input_id(xpad->udev, &input_dev->id);
|
| 1958 |
|
| 1959 | if (xpad->xtype == XTYPE_XBOX360W) {
|
| 1960 |
|
| 1961 | input_dev->id.product = 0x02a1;
|
| 1962 | }
|
| 1963 |
|
| 1964 | input_dev->dev.parent = &xpad->intf->dev;
|
| 1965 |
|
| 1966 | input_set_drvdata(input_dev, xpad);
|
| 1967 |
|
| 1968 | if (xpad->xtype != XTYPE_XBOX360W) {
|
| 1969 | input_dev->open = xpad_open;
|
| 1970 | input_dev->close = xpad_close;
|
| 1971 | }
|
| 1972 |
|
| 1973 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
|
| 1974 |
|
| 1975 | for (i = 0; xpad_abs[i] >= 0; i++)
|
| 1976 | xpad_set_up_abs(input_dev, xpad_abs[i]);
|
| 1977 | }
|
| 1978 |
|
| 1979 |
|
| 1980 | for (i = 0; xpad_common_btn[i] >= 0; i++)
|
| 1981 | input_set_capability(input_dev, EV_KEY, xpad_common_btn[i]);
|
| 1982 |
|
| 1983 |
|
| 1984 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
|
| 1985 | xpad->xtype == XTYPE_XBOXONE) {
|
| 1986 | for (i = 0; xpad360_btn[i] >= 0; i++)
|
| 1987 | input_set_capability(input_dev, EV_KEY, xpad360_btn[i]);
|
| 1988 | if (xpad->mapping & MAP_SHARE_BUTTON)
|
| 1989 | input_set_capability(input_dev, EV_KEY, KEY_RECORD);
|
| 1990 | } else {
|
| 1991 | for (i = 0; xpad_btn[i] >= 0; i++)
|
| 1992 | input_set_capability(input_dev, EV_KEY, xpad_btn[i]);
|
| 1993 | }
|
| 1994 |
|
| 1995 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
| 1996 | for (i = 0; xpad_btn_pad[i] >= 0; i++)
|
| 1997 | input_set_capability(input_dev, EV_KEY,
|
| 1998 | xpad_btn_pad[i]);
|
| 1999 | }
|
| 2000 |
|
| 2001 |
|
| 2002 | if (xpad->mapping & MAP_PADDLES) {
|
| 2003 | for (i = 0; xpad_btn_paddles[i] >= 0; i++)
|
| 2004 | input_set_capability(input_dev, EV_KEY, xpad_btn_paddles[i]);
|
| 2005 | }
|
| 2006 |
|
| 2007 | |
| 2008 | * This should be a simple else block. However historically
|
| 2009 | * xbox360w has mapped DPAD to buttons while xbox360 did not. This
|
| 2010 | * made no sense, but now we can not just switch back and have to
|
| 2011 | * support both behaviors.
|
| 2012 |
|
| 2013 | if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) ||
|
| 2014 | xpad->xtype == XTYPE_XBOX360W) {
|
| 2015 | for (i = 0; xpad_abs_pad[i] >= 0; i++)
|
| 2016 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
|
| 2017 | }
|
| 2018 |
|
| 2019 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
| 2020 | for (i = 0; xpad_btn_triggers[i] >= 0; i++)
|
| 2021 | input_set_capability(input_dev, EV_KEY,
|
| 2022 | xpad_btn_triggers[i]);
|
| 2023 | } else {
|
| 2024 | for (i = 0; xpad_abs_triggers[i] >= 0; i++)
|
| 2025 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
|
| 2026 | }
|
| 2027 |
|
| 2028 |
|
| 2029 | if (xpad->mapping & MAP_PROFILE_BUTTON)
|
| 2030 | xpad_set_up_abs(input_dev, ABS_PROFILE);
|
| 2031 |
|
| 2032 | error = xpad_init_ff(xpad);
|
| 2033 | if (error)
|
| 2034 | goto err_free_input;
|
| 2035 |
|
| 2036 | error = xpad_led_probe(xpad);
|
| 2037 | if (error)
|
| 2038 | goto err_destroy_ff;
|
| 2039 |
|
| 2040 | error = input_register_device(xpad->dev);
|
| 2041 | if (error)
|
| 2042 | goto err_disconnect_led;
|
| 2043 |
|
| 2044 | xpad->input_created = true;
|
| 2045 | return 0;
|
| 2046 |
|
| 2047 | err_disconnect_led:
|
| 2048 | xpad_led_disconnect(xpad);
|
| 2049 | err_destroy_ff:
|
| 2050 | input_ff_destroy(input_dev);
|
| 2051 | err_free_input:
|
| 2052 | input_free_device(input_dev);
|
| 2053 | return error;
|
| 2054 | }
|
| 2055 |
|
| 2056 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
| 2057 | {
|
| 2058 | struct usb_device *udev = interface_to_usbdev(intf);
|
| 2059 | struct usb_xpad *xpad;
|
| 2060 | struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
|
| 2061 | int i, error;
|
| 2062 |
|
| 2063 | if (intf->cur_altsetting->desc.bNumEndpoints != 2)
|
| 2064 | return -ENODEV;
|
| 2065 |
|
| 2066 | for (i = 0; xpad_device[i].idVendor; i++) {
|
| 2067 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
|
| 2068 | (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
|
| 2069 | break;
|
| 2070 | }
|
| 2071 |
|
| 2072 | xpad = kzalloc_obj(*xpad);
|
| 2073 | if (!xpad)
|
| 2074 | return -ENOMEM;
|
| 2075 |
|
| 2076 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
|
| 2077 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
|
| 2078 |
|
| 2079 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
|
| 2080 | GFP_KERNEL, &xpad->idata_dma);
|
| 2081 | if (!xpad->idata) {
|
| 2082 | error = -ENOMEM;
|
| 2083 | goto err_free_mem;
|
| 2084 | }
|
| 2085 |
|
| 2086 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
|
| 2087 | if (!xpad->irq_in) {
|
| 2088 | error = -ENOMEM;
|
| 2089 | goto err_free_idata;
|
| 2090 | }
|
| 2091 |
|
| 2092 | xpad->udev = udev;
|
| 2093 | xpad->intf = intf;
|
| 2094 | xpad->mapping = xpad_device[i].mapping;
|
| 2095 | xpad->xtype = xpad_device[i].xtype;
|
| 2096 | xpad->name = xpad_device[i].name;
|
| 2097 | if (xpad_device[i].flags & FLAG_DELAY_INIT)
|
| 2098 | xpad->delay_init = true;
|
| 2099 |
|
| 2100 | xpad->packet_type = PKT_XB;
|
| 2101 | INIT_WORK(&xpad->work, xpad_presence_work);
|
| 2102 |
|
| 2103 | if (xpad->xtype == XTYPE_UNKNOWN) {
|
| 2104 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
|
| 2105 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
|
| 2106 | xpad->xtype = XTYPE_XBOX360W;
|
| 2107 | else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208)
|
| 2108 | xpad->xtype = XTYPE_XBOXONE;
|
| 2109 | else
|
| 2110 | xpad->xtype = XTYPE_XBOX360;
|
| 2111 | } else {
|
| 2112 | xpad->xtype = XTYPE_XBOX;
|
| 2113 | }
|
| 2114 |
|
| 2115 | if (dpad_to_buttons)
|
| 2116 | xpad->mapping |= MAP_DPAD_TO_BUTTONS;
|
| 2117 | if (triggers_to_buttons)
|
| 2118 | xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
|
| 2119 | if (sticks_to_null)
|
| 2120 | xpad->mapping |= MAP_STICKS_TO_NULL;
|
| 2121 | }
|
| 2122 |
|
| 2123 | if (xpad->xtype == XTYPE_XBOXONE &&
|
| 2124 | intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) {
|
| 2125 | |
| 2126 | * The Xbox One controller lists three interfaces all with the
|
| 2127 | * same interface class, subclass and protocol. Differentiate by
|
| 2128 | * interface number.
|
| 2129 |
|
| 2130 | error = -ENODEV;
|
| 2131 | goto err_free_in_urb;
|
| 2132 | }
|
| 2133 |
|
| 2134 | ep_irq_in = ep_irq_out = NULL;
|
| 2135 |
|
| 2136 | for (i = 0; i < 2; i++) {
|
| 2137 | struct usb_endpoint_descriptor *ep =
|
| 2138 | &intf->cur_altsetting->endpoint[i].desc;
|
| 2139 |
|
| 2140 | if (usb_endpoint_xfer_int(ep)) {
|
| 2141 | if (usb_endpoint_dir_in(ep))
|
| 2142 | ep_irq_in = ep;
|
| 2143 | else
|
| 2144 | ep_irq_out = ep;
|
| 2145 | }
|
| 2146 | }
|
| 2147 |
|
| 2148 | if (!ep_irq_in || !ep_irq_out) {
|
| 2149 | error = -ENODEV;
|
| 2150 | goto err_free_in_urb;
|
| 2151 | }
|
| 2152 |
|
| 2153 | error = xpad_init_output(intf, xpad, ep_irq_out);
|
| 2154 | if (error)
|
| 2155 | goto err_free_in_urb;
|
| 2156 |
|
| 2157 | usb_fill_int_urb(xpad->irq_in, udev,
|
| 2158 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
|
| 2159 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
|
| 2160 | xpad, ep_irq_in->bInterval);
|
| 2161 | xpad->irq_in->transfer_dma = xpad->idata_dma;
|
| 2162 | xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
| 2163 |
|
| 2164 | usb_set_intfdata(intf, xpad);
|
| 2165 |
|
| 2166 |
|
| 2167 | if (le16_to_cpu(udev->descriptor.idVendor) == 0x045e) {
|
| 2168 | if (le16_to_cpu(udev->descriptor.idProduct) == 0x02e3) {
|
| 2169 | |
| 2170 | * type of extended packet
|
| 2171 |
|
| 2172 | xpad->packet_type = PKT_XBE1;
|
| 2173 | } else if (le16_to_cpu(udev->descriptor.idProduct) == 0x0b00) {
|
| 2174 | |
| 2175 | * revisions. These are tied to specific firmware
|
| 2176 | * versions
|
| 2177 |
|
| 2178 | if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x0500) {
|
| 2179 | |
| 2180 | * prior to the BLE update
|
| 2181 |
|
| 2182 | xpad->packet_type = PKT_XBE2_FW_OLD;
|
| 2183 | } else if (le16_to_cpu(udev->descriptor.bcdDevice) <
|
| 2184 | 0x050b) {
|
| 2185 | |
| 2186 | * prior to the update that split the packet
|
| 2187 |
|
| 2188 | xpad->packet_type = PKT_XBE2_FW_5_EARLY;
|
| 2189 | } else {
|
| 2190 | |
| 2191 | * in firmware v5.11
|
| 2192 |
|
| 2193 | xpad->packet_type = PKT_XBE2_FW_5_11;
|
| 2194 | }
|
| 2195 | }
|
| 2196 | }
|
| 2197 |
|
| 2198 | if (xpad->xtype == XTYPE_XBOX360W) {
|
| 2199 | |
| 2200 | * Submit the int URB immediately rather than waiting for open
|
| 2201 | * because we get status messages from the device whether
|
| 2202 | * or not any controllers are attached. In fact, it's
|
| 2203 | * exactly the message that a controller has arrived that
|
| 2204 | * we're waiting for.
|
| 2205 |
|
| 2206 | error = xpad360w_start_input(xpad);
|
| 2207 | if (error)
|
| 2208 | goto err_deinit_output;
|
| 2209 | |
| 2210 | * Wireless controllers require RESET_RESUME to work properly
|
| 2211 | * after suspend. Ideally this quirk should be in usb core
|
| 2212 | * quirk list, but we have too many vendors producing these
|
| 2213 | * controllers and we'd need to maintain 2 identical lists
|
| 2214 | * here in this driver and in usb core.
|
| 2215 |
|
| 2216 | udev->quirks |= USB_QUIRK_RESET_RESUME;
|
| 2217 | } else {
|
| 2218 | error = xpad_init_input(xpad);
|
| 2219 | if (error)
|
| 2220 | goto err_deinit_output;
|
| 2221 | }
|
| 2222 | return 0;
|
| 2223 |
|
| 2224 | err_deinit_output:
|
| 2225 | xpad_deinit_output(xpad);
|
| 2226 | err_free_in_urb:
|
| 2227 | usb_free_urb(xpad->irq_in);
|
| 2228 | err_free_idata:
|
| 2229 | usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
|
| 2230 | err_free_mem:
|
| 2231 | kfree(xpad);
|
| 2232 | return error;
|
| 2233 | }
|
| 2234 |
|
| 2235 | static void xpad_disconnect(struct usb_interface *intf)
|
| 2236 | {
|
| 2237 | struct usb_xpad *xpad = usb_get_intfdata(intf);
|
| 2238 |
|
| 2239 | if (xpad->xtype == XTYPE_XBOX360W)
|
| 2240 | xpad360w_stop_input(xpad);
|
| 2241 |
|
| 2242 | xpad_deinit_input(xpad);
|
| 2243 |
|
| 2244 | |
| 2245 | * Now that both input device and LED device are gone we can
|
| 2246 | * stop output URB.
|
| 2247 |
|
| 2248 | xpad_stop_output(xpad);
|
| 2249 |
|
| 2250 | xpad_deinit_output(xpad);
|
| 2251 |
|
| 2252 | usb_free_urb(xpad->irq_in);
|
| 2253 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
|
| 2254 | xpad->idata, xpad->idata_dma);
|
| 2255 |
|
| 2256 | kfree(xpad);
|
| 2257 |
|
| 2258 | usb_set_intfdata(intf, NULL);
|
| 2259 | }
|
| 2260 |
|
| 2261 | static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
|
| 2262 | {
|
| 2263 | struct usb_xpad *xpad = usb_get_intfdata(intf);
|
| 2264 | struct input_dev *input = xpad->dev;
|
| 2265 |
|
| 2266 | if (xpad->xtype == XTYPE_XBOX360W) {
|
| 2267 | |
| 2268 | * Wireless controllers always listen to input so
|
| 2269 | * they are notified when controller shows up
|
| 2270 | * or goes away.
|
| 2271 |
|
| 2272 | xpad360w_stop_input(xpad);
|
| 2273 |
|
| 2274 | |
| 2275 | * The wireless adapter is going off now, so the
|
| 2276 | * gamepads are going to become disconnected.
|
| 2277 | * Unless explicitly disabled, power them down
|
| 2278 | * so they don't just sit there flashing.
|
| 2279 |
|
| 2280 | if (auto_poweroff && xpad->pad_present)
|
| 2281 | xpad360w_poweroff_controller(xpad);
|
| 2282 | } else {
|
| 2283 | guard(mutex)(&input->mutex);
|
| 2284 |
|
| 2285 | if (input_device_enabled(input))
|
| 2286 | xpad_stop_input(xpad);
|
| 2287 | }
|
| 2288 |
|
| 2289 | xpad_stop_output(xpad);
|
| 2290 |
|
| 2291 | return 0;
|
| 2292 | }
|
| 2293 |
|
| 2294 | static int xpad_resume(struct usb_interface *intf)
|
| 2295 | {
|
| 2296 | struct usb_xpad *xpad = usb_get_intfdata(intf);
|
| 2297 | struct input_dev *input = xpad->dev;
|
| 2298 |
|
| 2299 | xpad->delayed_init_done = false;
|
| 2300 | if (xpad->xtype == XTYPE_XBOX360W)
|
| 2301 | return xpad360w_start_input(xpad);
|
| 2302 |
|
| 2303 | guard(mutex)(&input->mutex);
|
| 2304 |
|
| 2305 | if (input_device_enabled(input))
|
| 2306 | return xpad_start_input(xpad);
|
| 2307 |
|
| 2308 | if (xpad->xtype == XTYPE_XBOXONE) {
|
| 2309 | |
| 2310 | * Even if there are no users, we'll send Xbox One pads
|
| 2311 | * the startup sequence so they don't sit there and
|
| 2312 | * blink until somebody opens the input device again.
|
| 2313 |
|
| 2314 | return xpad_start_xbox_one(xpad);
|
| 2315 | }
|
| 2316 |
|
| 2317 | return 0;
|
| 2318 | }
|
| 2319 |
|
| 2320 | static struct usb_driver xpad_driver = {
|
| 2321 | .name = "xpad",
|
| 2322 | .probe = xpad_probe,
|
| 2323 | .disconnect = xpad_disconnect,
|
| 2324 | .suspend = xpad_suspend,
|
| 2325 | .resume = xpad_resume,
|
| 2326 | .id_table = xpad_table,
|
| 2327 | };
|
| 2328 |
|
| 2329 | module_usb_driver(xpad_driver);
|
| 2330 |
|
| 2331 | MODULE_AUTHOR("Marko Friedemann <[email protected]>");
|
| 2332 | MODULE_DESCRIPTION("Xbox pad driver");
|
| 2333 | MODULE_LICENSE("GPL");
|