paroj / xpad

Linux Kernel Driver for the Xbox/ Xbox 360/ Xbox One Controllers
801 stars 178 forks source link

(Better) support for 8BitDo Ultimate Wired Controller [PC/Switch] #256

Open fallenguru opened 10 months ago

fallenguru commented 10 months ago

This is about the 8BitDo Ultimate Wired Controller [PC/Switch]. This one: https://www.8bitdo.com/ultimate-wired-controller/ There's an Xbox version of this as well, and a stripped-down "C" version, as well as multiple wireless versions, but those are different beasts.

In XInput mode it reports as:

[819132.362641] usb 5-1: new full-speed USB device number 53 using xhci_hcd
[819132.523298] usb 5-1: New USB device found, idVendor=2dc8, idProduct=3106, bcdDevice= 1.14
[819132.523305] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[819132.523308] usb 5-1: Product: 8BitDo Ultimate Wired Controller
[819132.523310] usb 5-1: Manufacturer: 8BitDo
[819132.523312] usb 5-1: SerialNumber: XXXXXXXXXXXX

The current driver has the vendor and device ID alright, the description is "8BitDo Ultimate Wireless / Pro 2 Wired Controller", except I don't think these three models are actually identical as far as behaviour is concerned.

The biggest issue is that the Ultimate Wired needs some sort of keepalive. Without something accessing it, it will disconnect & reconnect every 6 s (looks like this is a carry-over from some overzealous power management for a wireless version or other). Every time it does this, it will vibrate and flash its LED. This also affects DInput mode, but not the Switch mode.

[846050.127746] usb 1-2: USB disconnect, device number 115
[846050.127806] xpad 1-2:1.0: xpad_try_sending_next_out_packet - usb_submit_urb failed with result -19
[846050.375498] usb 1-2: new full-speed USB device number 116 using xhci_hcd
[continues as above, rinse, repeat]

As long as Steam or Retroarch are running, it's fine. catting its /dev/input entry works, too, but that's just too ugly for words. The problem doesn't occur with xboxdrv, either.


If xpad is active, Steam Input needs to be disabled, otherwise (some?) games pick up the Steam Input controller alongside the "raw" xpad one, each keypress being detected as coming from both simultaneously. This does not happen with xboxdrv, nor in the other modes.


The thumb buttons (on the bottom) do not work in XInput mode no matter what, and neither does the home button.

Ketrel commented 10 months ago

As long as Steam or Retroarch are running, it's fine. catting its /dev/input entry works, too, but that's just too ugly for words. The problem doesn't occur with xboxdrv, either.

I found this issue here with this controller from the exact same symptoms, the constant disconnect/reconnect unless something was accessing it somehow.

(Switch mode is working in the interim)

b1337xyz commented 5 months ago

Not sure if it helps.. but i wrote a script to avoid keeping steam open

https://github.com/b1337xyz/scripts/blob/main/python/8bitdo_attach.py

tobiasjakobi commented 5 months ago

I'm also seeing the exact same issue on an Ayaneo Kun (a handheld device). The integrated controller identifies itself as a Xbox360 controller. The USB device of the controller quickly performs a reset, if one should not open the corresponding event device within a second or so. Looking at the kernel level opening the event device trigger periodic USB transfers to and from the device (to query button state, etc.). It seems like that these transfer make the watchdog in the controller firmware happy.

I have written my own set of workaround for this problem. You can find stuff here: https://github.com/tobiasjakobi/ayaneo_kun/tree/master/controller

Consists of an UDev rule that triggers a systemd unit when the device appears. The unit itself just launches a small application that opens the event device and then waits for a Unix signal (SIGTERM, issued by systemd when the unit stops).

This is clearly a workaround, and IMHO a fix in the kernel driver would be much more appropriate. However I don't know what implications it would have to talk to the USB device regardless if the evdev is open or not. At least from a powersaving perspective it's probably not a good idea.

In particular I don't really get this decision to implement this watchdog in the firmware in the first place. Why would you perform a USB reset when the watchdog hits? This just results in the device dropping from the bus, only to come back a little while later. And this way you never get any powersaving at all, since it's connect, probe, disconnect, connect, probe, ad infinitum.

The only way I would get the controller to sleep is to manually disable the bus port which it is connected to. Then you wait for some minutes (I'm not sure how many exactly), power up the bus port again and then device is quiet (it doesn't appear on the bus anymore). Pressing a button reactivates it again.

EDIT: Forgot to mention that I also saw a report about this issue on the LKML: https://lore.kernel.org/linux-input/unufo3$det$1@ciao.gmane.io/T/