usbh_xbox.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) 2024 Till Harbaum
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbh_core.h"
  7. #include "usbh_xbox.h"
  8. #define DEV_FORMAT "/dev/xbox%d"
  9. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_xbox_buf[128];
  10. static struct usbh_xbox g_xbox_class[CONFIG_USBHOST_MAX_XBOX_CLASS];
  11. static uint32_t g_devinuse = 0;
  12. static struct usbh_xbox *usbh_xbox_class_alloc(void)
  13. {
  14. uint8_t devno;
  15. for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) {
  16. if ((g_devinuse & (1U << devno)) == 0) {
  17. g_devinuse |= (1U << devno);
  18. memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox));
  19. g_xbox_class[devno].minor = devno;
  20. return &g_xbox_class[devno];
  21. }
  22. }
  23. return NULL;
  24. }
  25. static void usbh_xbox_class_free(struct usbh_xbox *xbox_class)
  26. {
  27. uint8_t devno = xbox_class->minor;
  28. if (devno < 32) {
  29. g_devinuse &= ~(1U << devno);
  30. }
  31. memset(xbox_class, 0, sizeof(struct usbh_xbox));
  32. }
  33. int usbh_xbox_connect(struct usbh_hubport *hport, uint8_t intf)
  34. {
  35. struct usb_endpoint_descriptor *ep_desc;
  36. struct usbh_xbox *xbox_class = usbh_xbox_class_alloc();
  37. if (xbox_class == NULL) {
  38. USB_LOG_ERR("Fail to alloc xbox_class\r\n");
  39. return -USB_ERR_NOMEM;
  40. }
  41. xbox_class->hport = hport;
  42. xbox_class->intf = intf;
  43. hport->config.intf[intf].priv = xbox_class;
  44. for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
  45. ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
  46. if (ep_desc->bEndpointAddress & 0x80) {
  47. USBH_EP_INIT(xbox_class->intin, ep_desc);
  48. } else {
  49. USBH_EP_INIT(xbox_class->intout, ep_desc);
  50. }
  51. }
  52. snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, xbox_class->minor);
  53. USB_LOG_INFO("Register XBOX Class:%s\r\n", hport->config.intf[intf].devname);
  54. usbh_xbox_run(xbox_class);
  55. return 0;
  56. }
  57. int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf)
  58. {
  59. int ret = 0;
  60. struct usbh_xbox *xbox_class = (struct usbh_xbox *)hport->config.intf[intf].priv;
  61. if (xbox_class) {
  62. if (xbox_class->intin) {
  63. usbh_kill_urb(&xbox_class->intin_urb);
  64. }
  65. if (xbox_class->intout) {
  66. usbh_kill_urb(&xbox_class->intout_urb);
  67. }
  68. if (hport->config.intf[intf].devname[0] != '\0') {
  69. USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname);
  70. usbh_xbox_stop(xbox_class);
  71. }
  72. usbh_xbox_class_free(xbox_class);
  73. }
  74. return ret;
  75. }
  76. __WEAK void usbh_xbox_run(struct usbh_xbox *xbox_class)
  77. {
  78. }
  79. __WEAK void usbh_xbox_stop(struct usbh_xbox *xbox_class)
  80. {
  81. }
  82. const struct usbh_class_driver xbox_class_driver = {
  83. .driver_name = "xbox",
  84. .connect = usbh_xbox_connect,
  85. .disconnect = usbh_xbox_disconnect
  86. };
  87. static const uint16_t xbox_id_table[][2] = {
  88. { 0x0079, 0x18d4 }, // GPD Win 2 X-Box Controller
  89. { 0x03eb, 0xff01 }, // Wooting One (Legacy)
  90. { 0x03eb, 0xff02 }, // Wooting Two (Legacy)
  91. { 0x044f, 0xb326 }, // Thrustmaster Gamepad GP XID
  92. { 0x045e, 0x028e }, // Microsoft X-Box 360 pad
  93. { 0x045e, 0x028f }, // Microsoft X-Box 360 pad v2
  94. { 0x046d, 0xc21d }, // Logitech Gamepad F310
  95. { 0x046d, 0xc21e }, // Logitech Gamepad F510
  96. { 0x046d, 0xc21f }, // Logitech Gamepad F710
  97. { 0x046d, 0xc242 }, // Logitech Chillstream Controller
  98. { 0x046d, 0xcaa3 }, // Logitech DriveFx Racing Wheel
  99. { 0x056e, 0x2004 }, // Elecom JC-U3613M
  100. { 0x06a3, 0xf51a }, // Saitek P3600
  101. { 0x0738, 0x4716 }, // Mad Catz Wired Xbox 360 Controller
  102. { 0x0738, 0x4718 }, // Mad Catz Street Fighter IV FightStick SE
  103. { 0x0738, 0x4726 }, // Mad Catz Xbox 360 Controller
  104. { 0x0738, 0x4736 }, // Mad Catz MicroCon Gamepad
  105. { 0x0738, 0x4740 }, // Mad Catz Beat Pad
  106. { 0x0738, 0x9871 }, // Mad Catz Portable Drum
  107. { 0x0738, 0xb726 }, // Mad Catz Xbox controller - MW2
  108. { 0x0738, 0xbeef }, // Mad Catz JOYTECH NEO SE Advanced GamePad
  109. { 0x0738, 0xcb02 }, // Saitek Cyborg Rumble Pad - PC/Xbox 360
  110. { 0x0738, 0xcb03 }, // Saitek P3200 Rumble Pad - PC/Xbox 360
  111. { 0x0738, 0xcb29 }, // Saitek Aviator Stick AV8R02
  112. { 0x0738, 0xf738 }, // Super SFIV FightStick TE S
  113. { 0x07ff, 0xffff }, // Mad Catz GamePad
  114. { 0x0e6f, 0x0113 }, // Afterglow AX.1 Gamepad for Xbox 360
  115. { 0x0e6f, 0x011f }, // Rock Candy Gamepad Wired Controller
  116. { 0x0e6f, 0x0131 }, // PDP EA Sports Controller
  117. { 0x0e6f, 0x0133 }, // Xbox 360 Wired Controller
  118. { 0x0e6f, 0x0201 }, // Pelican PL-3601 'TSZ' Wired Xbox 360 Controller
  119. { 0x0e6f, 0x0213 }, // Afterglow Gamepad for Xbox 360
  120. { 0x0e6f, 0x021f }, // Rock Candy Gamepad for Xbox 360
  121. { 0x0e6f, 0x0301 }, // Logic3 Controller
  122. { 0x0e6f, 0x0401 }, // Logic3 Controller
  123. { 0x0e6f, 0x0413 }, // Afterglow AX.1 Gamepad for Xbox 360
  124. { 0x0e6f, 0x0501 }, // PDP Xbox 360 Controller
  125. { 0x0e6f, 0xf900 }, // PDP Afterglow AX.1
  126. { 0x0f0d, 0x000a }, // Hori Co. DOA4 FightStick
  127. { 0x0f0d, 0x000c }, // Hori PadEX Turbo
  128. { 0x1038, 0x1430 }, // SteelSeries Stratus Duo
  129. { 0x1038, 0x1431 }, // SteelSeries Stratus Duo
  130. { 0x11c9, 0x55f0 }, // Nacon GC-100XF
  131. { 0x1209, 0x2882 }, // Ardwiino Controller
  132. { 0x12ab, 0x0301 }, // PDP AFTERGLOW AX.1
  133. { 0x1430, 0x4748 }, // RedOctane Guitar Hero X-plorer
  134. { 0x1430, 0xf801 }, // RedOctane Controller
  135. { 0x146b, 0x0601 }, // BigBen Interactive XBOX 360 Controller
  136. { 0x1532, 0x0037 }, // Razer Sabertooth
  137. { 0x15e4, 0x3f00 }, // Power A Mini Pro Elite
  138. { 0x15e4, 0x3f0a }, // Xbox Airflo wired controller
  139. { 0x15e4, 0x3f10 }, // Batarang Xbox 360 controller
  140. { 0x162e, 0xbeef }, // Joytech Neo-Se Take2
  141. { 0x1689, 0xfd00 }, // Razer Onza Tournament Edition
  142. { 0x1689, 0xfd01 }, // Razer Onza Classic Edition
  143. { 0x1689, 0xfe00 }, // Razer Sabertooth
  144. { 0x1949, 0x041a }, // Amazon Game Controller
  145. { 0x1bad, 0x0002 }, // Harmonix Rock Band Guitar
  146. { 0x1bad, 0xf016 }, // Mad Catz Xbox 360 Controller
  147. { 0x1bad, 0xf021 }, // Mad Cats Ghost Recon FS GamePad
  148. { 0x1bad, 0xf023 }, // MLG Pro Circuit Controller (Xbox)
  149. { 0x1bad, 0xf025 }, // Mad Catz Call Of Duty
  150. { 0x1bad, 0xf027 }, // Mad Catz FPS Pro
  151. { 0x1bad, 0xf028 }, // Street Fighter IV FightPad
  152. { 0x1bad, 0xf030 }, // Mad Catz Xbox 360 MC2 MicroCon Racing Wheel
  153. { 0x1bad, 0xf036 }, // Mad Catz MicroCon GamePad Pro
  154. { 0x1bad, 0xf038 }, // Street Fighter IV FightStick TE
  155. { 0x1bad, 0xf501 }, // HoriPad EX2 Turbo
  156. { 0x1bad, 0xf506 }, // Hori Real Arcade Pro.EX Premium VLX
  157. { 0x1bad, 0xf900 }, // Harmonix Xbox 360 Controller
  158. { 0x1bad, 0xf901 }, // Gamestop Xbox 360 Controller
  159. { 0x1bad, 0xf903 }, // Tron Xbox 360 controller
  160. { 0x1bad, 0xf904 }, // PDP Versus Fighting Pad
  161. { 0x1bad, 0xfa01 }, // MadCatz GamePad
  162. { 0x1bad, 0xfd00 }, // Razer Onza TE
  163. { 0x1bad, 0xfd01 }, // Razer Onza
  164. { 0x20d6, 0x2001 }, // BDA Xbox Series X Wired Controller
  165. { 0x20d6, 0x281f }, // PowerA Wired Controller For Xbox 360
  166. { 0x24c6, 0x5300 }, // PowerA MINI PROEX Controller
  167. { 0x24c6, 0x5303 }, // Xbox Airflo wired controller
  168. { 0x24c6, 0x530a }, // Xbox 360 Pro EX Controller
  169. { 0x24c6, 0x531a }, // PowerA Pro Ex
  170. { 0x24c6, 0x5397 }, // FUS1ON Tournament Controller
  171. { 0x24c6, 0x5500 }, // Hori XBOX 360 EX 2 with Turbo
  172. { 0x24c6, 0x5501 }, // Hori Real Arcade Pro VX-SA
  173. { 0x24c6, 0x5506 }, // Hori SOULCALIBUR V Stick
  174. { 0x24c6, 0x550d }, // Hori GEM Xbox controller
  175. { 0x24c6, 0x5b00 }, // ThrustMaster Ferrari 458 Racing Wheel
  176. { 0x24c6, 0x5b02 }, // Thrustmaster, Inc. GPX Controller
  177. { 0x24c6, 0x5b03 }, // Thrustmaster Ferrari 458 Racing Wheel
  178. { 0x24c6, 0x5d04 }, // Razer Sabertooth
  179. { 0x24c6, 0xfafe }, // Rock Candy Gamepad for Xbox 360
  180. { 0x2563, 0x058d }, // OneXPlayer Gamepad
  181. { 0x2dc8, 0x3106 }, // 8BitDo Ultimate Wireless / Pro 2 Wired Controller
  182. { 0x2dc8, 0x3109 }, // 8BitDo Ultimate Wireless Bluetooth
  183. { 0x31e3, 0x1100 }, // Wooting One
  184. { 0x31e3, 0x1200 }, // Wooting Two
  185. { 0x31e3, 0x1210 }, // Wooting Lekker
  186. { 0x31e3, 0x1220 }, // Wooting Two HE
  187. { 0x31e3, 0x1230 }, // Wooting Two HE (ARM)
  188. { 0x31e3, 0x1300 }, // Wooting 60HE (AVR)
  189. { 0x31e3, 0x1310 }, // Wooting 60HE (ARM)
  190. { 0x3285, 0x0607 }, // Nacon GC-100
  191. { 0x413d, 0x2104 }, // Black Shark Green Ghost Gamepad
  192. { 0x0000, 0x0000 } // end of list
  193. };
  194. CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = {
  195. .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
  196. .bInterfaceClass = USB_DEVICE_CLASS_VEND_SPECIFIC,
  197. .bInterfaceSubClass = 0x5d,
  198. .bInterfaceProtocol = 0x01,
  199. .id_table = xbox_id_table,
  200. .class_driver = &xbox_class_driver
  201. };