If you want to support me or accelerate the development of a special feature, consider a small donation :heart: Just leave a message if your donation is for a specific use (like a new hardware or a specific function).
Advanced Linux Driver for Xbox One Wireless Gamepad
Quote from @atar-axis (Florian Dollinger), creator of the initial driver:
This is the first driver for the Xbox One Wireless Gamepad (which is shipped with the Xbox One S). I wrote it for a student project at fortiss GmbH and it is fully functional but does only support the connection via Bluetooth as yet - more will follow.
Many thanks to Kai Krakow who sponsored me a Xbox One Wireless Controller :video_game: (including Wireless Adapter) and a pack of mouthwatering guarana cacao :coffee:
Other Projects
- xow is a driver for the Xbox One S controllers, too, and supports the native dongles packaged with the controller. Kudos to @medusalix for working together on finding some work-arounds for controller firmware bugs.
- xpad supports this and many other controllers in USB mode.
- xone is a driver aiming for fully supporting all Microsoft GIP devices thus replacing the xpad driver in the kernel while adding support for additional types of hardware.
- MissionControl aims to support the controller on Nintendo Switch via Bluetooth.
These other projects may not support some of the advanced features of xpadneo.
Breaking Changes
Kernel 4.18 or newer required
As of xpadneo v0.10, we require kernel 4.18 or later to utilize HID_QUIRK_INPUT_PER_APP
which splits the gamepad into
multiple sub-devices to fix problems and incompatibilities at several layers.
SDL2 2.28 Compatibility
Thanks to @slouken from SDL2, xpadneo mappings are now auto-detected in the upcoming SDL2 2.28 release. This will fix long-standing problems with Steam Input and SDL2 games. With this release, we will also have full paddle support.
If you still see problems, ensure that you didn’t create custom controllerdb entries. See also:
- https://github.com/atar-axis/xpadneo/issues/428
- https://github.com/libsdl-org/SDL/commit/9567989eb3ce9c858f0fe76806c5ccad69da89ba
- https://github.com/libsdl-org/SDL/commit/0f4b15e16b7f07a46db6dc8e651f8c1849d658c5
Known issues:
- The Share button will currently not be recognized by SDL2, scheduled to be fixed in xpadneo v0.11
- If SDL2 uses hidraw, mappings will be wrong, export
SDL_JOYSTICK_HIDAPI=0
in your profile or find which software enabled hidraw device access to all drivers
Quirks by Design
With BLE firmware, all models switched to a unified HID report descriptor, only the XBE2 controller identifies with PID 0x0B22 while the other models identify with PID 0x0B13. This has some known consequences:
- All non-XBE2 controllers will claim to have a Share button no matter if it physically exists. As HID doesn’t report the internal model number, xpadneo cannot fix it currently. The button is currently mapped to F12, so this has no consequences.
- All XBE2 controllers will claim to have a full keyboard and the Share button is actually the Profile button. Since Share is currently mapped to F12, this will have no consequences.
Advantages of this Driver
- Supports Bluetooth
- Supports most force feedback and all rumble effects through Linux
ff-memless
effect emulation - Supports Trigger Force Feedback in every game by applying a pressure-dependent effect intensity to the current rumble effect (not even supported in Windows)
- Supports adjusting rumble intensity including disabling rumble
- Offers a consistent mapping, even if the Gamepad was paired to Windows/Xbox before, and independent of software layers (SDL2, Stadia via Chrome Gamepad API, etc)
- Working paddles (buttons on the backside of the controller)
- Correct axis range (signed, important for e.g. RPCS3)
- Supports battery level indication (including the Play ‘n Charge Kit)
- Easy installation
- Supports customization through profiles (work in progress)
- Optional high-precision mode for Wine/Proton users (disables dead zones so games don’t apply an additional one)
- Share button support on supported controllers
Unavailable Features
Across all models, xpadneo won’t support audio features of the controllers because the firmware doesn’t support audio in Bluetooth mode. In the future, xpadneo may support audio when USB and dongle support will be added.
Xbox One S Wireless Controller
This is the initial controller supported from the first version of xpadneo. All features are fully supported. This controller uses emulated profile switching support (see below).
Xbox Elite Series 2 Wireless Controller
Basic support for the Xbox Elite Series 2 Wireless controller is present, covering all the features of the driver. The following features are missing:
- Upload of profile mappings and sensitivity curves is currently not supported.
This controller uses native profile switching support (see below).
Xbox Series X|S Wireless Controller
Full support for the Xbox Series X|S controller is present including the share button. This is currently statically
mapped to keyboard event KEY_F12
to take screenshots with Steam. It will be configurable in the future. This
controller uses emulated profile switching support (see below).
This controller uses BLE (Bluetooth low energy) and can only be supported if your Bluetooth dongle also supports BLE.
Known problems: The controller may not properly set its connection parameters, resulting in laggy and choppy input experience. See also: Troubleshooting.
8BitDo Controllers
This driver supports the Nintendo layout of those controllers to exposes them correctly as button A, B, X, and Y as labelled on the device. This is swapped compared to the original Xbox controller layout. However, this feature is not enabled by default. If you want to use this feature, you have to add a quirk flag to the module options:
# /etc/modprobe.conf
options hid_xpadneo quirks=E4:17:D8:xx:xx:xx+32
where you replace xx:xx:xx
with the values from your controller MAC (as shown in dmesg
). The value 32
enables
Nintendo layout. If you’ll want to add other quirk flags, simply add the values,
e.g. 32
+ 7
(default quirks for 8BitDo) = 39
. After changing this, reload the driver or reboot.
This controller uses emulated profile switching support (see below).
Breaking change: Users of previous versions of the driver may want to remove their custom SDL mappings. Full support has been added for these controllers and broken mapping of previously versions no longer needs to be applied. See also: SDL.
GuliKit KingKong Controller Family
This driver supports the GuliKit King Kong controller family, the driver was tested with model NS09 (using firmware v2.0) and NS39 (aka KK3 MAX, firmware v3.6) but should work just fine for the older models, too. If in doubt, follow the firmware upgrade guides on the GuliKit home page to receive the latest firmware. Both the Android mode and the X-Input mode are supported but it may depend on your Bluetooth stack which mode works better for you (Android mode didn’t pair for me).
This driver supports the Nintendo layout of those controllers to exposes them correctly as button A, B, X, and Y as labelled on the device. This is swapped compared to the original Xbox controller layout. However, this feature is not enabled by default. If you want to use this feature, you have to add a quirk flag to the module options:
# /etc/modprobe.conf
options hid_xpadneo quirks=98:B6:EA:xx:xx:xx+32
where you replace xx:xx:xx
with the values from your controller MAC (as shown in dmesg
). The value 32
enables
Nintendo layout. If you’ll want to add other quirk flags, simply add the values,
e.g. 32
+ 131
(default quirks for GuliKit) = 163
. After changing this, reload the driver or reboot.
However, alternatively the controller supports swapping the buttons on the fly, too: Just press and hold the settings button, the click the plus button. Thus, the quirks flag is just a matter of setting the defaults.
This controller uses emulated profile switching support (see below).
GameSir T4 Cyclone Family
This driver supports the GameSir T4 Cyclone controller family, tested by the community. The Pro-models also support trigger rumble but since we cannot distinguish both models by the Bluetooth MAC OUI, we simply enable the trigger rumble protocol for both variants. This should not introduce any problems but if it does, and your model does not have trigger rumble support, you can explicitly tell the driver to not use the trigger rumble motors by adding a quirk flag:
# /etc/modprobe.conf
options hid_xpadneo quirks=A0:5A:5D:xx:xx:xx+2
This controller uses emulated profile switching support (see below).
GameSir T4 Nova Lite Family
This driver supports the GameSir T4 Nova Lite controller family, tested by the community. These models have a quirk of only allowing rumble when all motor-enable bits are set and does not have trigger rumble motors. It looks like these models are available with different MAC OUIs, so your particular controller may not be automatically detected. In this case, manually add the quirk flags for your controller:
# /etc/modprobe.conf
options hid_xpadneo quirks=3E:42:6C:xx:xx:xx+6
This controller uses emulated profile switching support (see below).
This manufacturer uses random MAC addresses, so we cannot rely on known OUIs. Heuristics try to detect this controller.
Profile Switching
The driver supports switching between different profiles, either through emulation or by using the hardware switch that comes with some models. This switching can be done at any time even while in a game. The API for customizing each profile does not exist yet.
Native Profile Switching Support
The driver support native profile switching for the Xbox Elite Series 2 controller. However, the feature is not finalized yet:
- The default profile (no LED) exposes the paddles as extra buttons.
- The other three profiles behave the same way by default. While there is no support for modifying them currently, configurations set in the Xbox Accessories app (Windows only) will carry over and operate as intended.
Emulated Profile Switching Support
The driver emulates profile switching for controllers without a hardware profile switch by pressing buttons A, B, X, or Y while holding down the Xbox logo button. However, the following caveats apply:
- Profiles currently behave all the same, and there is no support for configuring them.
- Full support will be available once the Xbox Elite Series 2 controller is fully supported.
- If you hold the button for too long, the controller will turn off - we cannot prevent that.
Important: Emulated profile switching won’t work if you disabled the shift-mode of the Xbox logo button (module
parameter disable_shift_mode
).
Getting Started
Distribution Packages
If your distribution has a maintained package, you can just use that and do not need to follow the manual install instructions below:
Notes for Package Maintainers
To properly support module signing and UEFI secure boot, openssl
and mokutil
are required additionally to the
prerequisites below. The DKMS readme has more instructions.
Prerequisites
Make sure you have installed dkms, linux headers and a bluetooth implementation (e.g. bluez) and their dependencies.
Kernel maintainers should also include the uhid
module (CONFIG_UHID
) because otherwise Bluetooth LE devices (all
models with firmware 5.x or higher) cannot create the HID input device which is handled in user-space by the bluez
daemon.
- On Arch and Arch-based distros (like EndeavourOS), try
sudo pacman -S dkms linux-headers bluez bluez-utils
- On Debian based systems (like Ubuntu) you can install those packages by running
sudo apt-get install dkms linux-headers-`uname -r`
- On Fedora, it is
sudo dnf install dkms make bluez bluez-tools kernel-devel-`uname -r` kernel-headers
- On Manjaro try
sudo pacman -S dkms linux-latest-headers bluez bluez-utils
- On openSUSE (tested on Tumbleweed, should work for Leap), it is
sudo zypper install dkms make bluez kernel-devel kernel-source
- On OSMC you will have to run the following commands
sudo apt-get install dkms rbp2-headers-`uname -r`
sudo ln -s "/usr/src/rbp2-headers-`uname -r`" "/lib/modules/`uname -r`/build"
(as a workaround) - On Raspbian, it is
sudo apt-get install dkms raspberrypi-kernel-headers
If you recently updated your firmware usingrpi-update
the above package may not yet include the header files for your kernel. Please follow the steps described here in this case. - On generic distributions, it doesn’t need DKMS but requires a configured kernel source tree, then:
cd hid-xpadneo && make modules && sudo make modules_install
- Module singing and UEFI secure boot: If installing yourself, you may need to follow the instructions above for package maintainers.
Please feel free to add other distributions as well!
Installation
- Download the Repository to your local machine
git clone https://github.com/atar-axis/xpadneo.git
cd xpadneo
- If using DKMS, run
sudo ./install.sh
- If not using DKMS, follow steps above (generic distribution)
- Done!
Connection
sudo bluetoothctl
[bluetooth]# scan on
- wait until all available devices are listed (otherwise it may be hard to identify which one is the gamepad)
- push the connect button on upper side of the gamepad, and hold it down until the light starts flashing fast
- wait for the gamepad to show up in bluetoothctl, remember the
address (e.g. `C8:3F:26:XX:XX:XX`) [bluetooth]# scan off
to stop scanning as it may interfere with properly pairing the controller[bluetooth]# pair <MAC>
[bluetooth]# trust <MAC>
[bluetooth]# connect <MAC>
(should usually not be needed but there are open bugs)- The
<MAC>
parameter is optional if the command line already shows the controller name
You know that everything works fine when you feel the gamepad rumble ;)
Configuration
- If using DKMS: Use
sudo ./configure.sh
to configure the driver as you wish. The script will guide you through the available options.
Update
In order to update xpadneo, do the following
- Update your cloned repo:
git pull
- If using DKMS: Run
sudo ./update.sh
- otherwise follow the steps above (generic distribution)
Uninstallation
- If using DKMS: Run
sudo ./uninstall.sh
to remove all installed versions of hid-xpadneo - otherwise follow the steps above (generic distribution)
Further Information
For further information please visit the GitHub Page https://atar-axis.github.io/xpadneo/ which is generated
automatically from the content of the /docs
folder.
You will find there e.g. the following sections
BT Dongles
Please report your Dongles and how they work here
Bluetooth Low Energy
Some newer controller may work in Bluetooth low energy mode (BLE). One of those controllers is the XBOX Series X|S controller.
If your distribution supports the command, run btmgmt info
and look for
le
in supported and current settings, example:
# btmgmt info
Index list with 1 item
hci0: Primary controller
addr 00:1A:7D:XX:XX:XX version 6 manufacturer 10 class 0x100104
supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr phy-configuration
current settings: powered ssp br/edr le secure-conn
name jupiter
short name
If btmgmt
command is not available, try bluetoothctl mgmt.info
instead.
Cambridge Silicon Radio
- Panda Bluetooth 4.0 USB Nano Adapter
- Chipset: CSR ???
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
- Performance:
- Re-Connection Problems
- Reliable once connected
- Reported by @ugly95 here
- MIATONE Bluetooth Adapter Bluetooth CSR 4.0
- Chipset: CSR 8510
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
- Performance:
- Re-Connection Problems
- Reliable once connected
- Reported by @ugly95 here
- CSL - Bluetooth 4.0 USB Adapter
- Sabrent USB Bluetooth 4.0 Micro Adapter for PC
- Chipset CSR ???
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
- Performance:
- Re-Connection Problems
- Reliable once connected
- Reported by @ugly95 here
- Yizhet USB nano Bluetooth 4.0 Adapter
- Chipset CSR 8510 A10
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
- Performance:
- Re-Connection Problems
- Reliable once connected
- Reported by @NoXPhasma here
- TP-Link USB Bluetooth Adapter Bluetooth 4.0 (UB400)
- Chipset: CSR ???
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
- Performance:
- Connection is flawless
- Reported by @Arian8j2 here
Broadcom
- Plugable USB Bluetooth 4.0 Low Energy Micro Adapter
- Targus BT 4.0 USB adapter
- Chipset: BCM20702A0
ID 0a5c:21e8 Broadcom Corp. BCM20702A0 Bluetooth 4.0
- Performance:
- Connection flawless
- Sometimes laggy while Gameplay
- Reported by Zowayix here
Qualcomm
- Unspecified model (https://github.com/atar-axis/xpadneo/issues/180):
btmon
logs showed very low input report rate and high input lag (300ms+)
Intel
- Status: incompatible (https://github.com/atar-axis/xpadneo/issues/270)
- OUI: DC:1B:A1 (Intel)
- Used as on-board chipset: Gigabyte B450 Aorus Pro WiFi 1.0 with integrated Bluetooth
- Status: bluetoothd logs “Request attribute has encountered an unlikely error”
- Chipset: AX200
- Used as on-board chipset: ASUS B550-i
Realtek
Known bad firmware for RTL8761BU chipset is 0xdfc6d922. It causes frequent reconnects. Firmware version can be found in the kernel log:
$ sudo dmesg | grep 'RTL: fw version'
[ 21.193448] Bluetooth: hci0: RTL: fw version 0xdfc6d922
- TP-Link USB Bluetooth Adapter Bluetooth 5.0 (UB500)
- Chipset: RTL8761BU
ID 2357:0604 TP-Link TP-Link UB500 Adapter
- Performance:
- Disconnects after some random interval and reconnects
- When it’s connected, it’s good
- Reported by @Arian8j2 here
- Simplecom NB409 Bluetooth 5.0 USB Wireless Dongle with A2DP EDR
- Chipset: RTL8761BU
ID 0bda:8771 Realtek Semiconductor Corp. Bluetooth Radio
- Status: it works straight out of the box for a user on Manjaro KDE with kernel 5.15 and 6.1
- Reported by @mscharley here
- UGREEN Bluetooth 5.0 USB Adapter (CM390)
- Chipset: RTL8761BU
ID 0bda:8771 Realtek Semiconductor Corp. Bluetooth Radio
- Performance:
- Connection flawless if good firmware is being used
Configuration
Alternatively to using the config-script, you can also do it by hand:
The driver can be reconfigured at runtime by accessing the following sysfs
files in /sys/module/hid_xpadneo/parameters
:
disable_deadzones
(default0
)0
enables standard behavior to be compatible withjoydev
expectations1
enables raw passthrough of axis values without dead zones for high-precision use with modern Wine/Proton games
trigger_rumble_mode
(default0
)0
rumbles triggers by pressure and current rumble effect1
rumbles triggers by force direction (non-conformant)2
disables trigger rumble
rumble_attenuation
(default0,0
)- Attenuation the strength of the force feedback
0
(none, full rumble) to100
(max, no rumble)- If one or two values are given, the first value is the overall attenuation
- If two values are given, the second value applies an extra attenuation to the triggers
- Example 1:
0,100
turns trigger rumble off,100,0
or100
turn all rumble off - Example 2:
50,50
makes 50% rumble overall, and 25% for the triggers (50% of 50% = 25%) - Example 3:
50
makes 50% rumble overall (main and triggers) - Trigger-only rumble is not possible
quirks
(default empty)- Let’s you adjust the quirk mode of your controller
- Comma separated list of
address:flags
pairs (use+flags
or-flags
to change flags instead) - Specify your controller MAC address in the format
11:22:33:44:55:66
- Specify the flags as sum of the following:
1
if your controller does not support pulse parameters (i.e., 8BitDo controllers)2
if your controller does not support trigger rumble (most clones in compat-mode)4
if your controller does not support individual motor programming (i.e., 8BitDo controllers)8
if your controller supports hardware profiles (auto-detected, do not set manually)16
if your controller boots in Linux mode (auto-detected, do not change manually)32
if you prefer to use Nintendo button mappings (i.e., 8BitDo controllers, defaults to off)64
if your controller has a awkwardly mapped Share button (auto-detected, do not set manually)
- ‘disable_shift_mode’ (default 0)
- Let’s you disable Xbox logo button shift behavior
- ‘0’ Xbox logo button will be used as shift
- ‘1’ will pass through the Xbox logo button as is
Some settings may need to be changed at loading time of the module, take a look at the following example to see how that works:
Example
To disable trigger rumbling temporarily, run
echo 2 | sudo tee /sys/module/hid_xpadneo/parameters/trigger_rumble_mode
To make the setting permanent and applied at loading time, try
echo "options hid_xpadneo trigger_rumble_mode=2" | sudo tee /etc/modprobe.d/99-xpadneo-bluetooth.conf
Troubleshooting
Gamepad Does Not Connect Properly
High Latency or Lost Button Events with Bluetooth LE
Affected models: Xbox controllers using Bluetooth LE (Xbox Series X|S or later)
While using new Xbox Series X|S controller, you may experience laggy or choppy input, also button presses may be lost or delayed. This problem only affects Bluetooth LE controllers, the older models are not affected by these settings even if you think you may see such a problem.
A proper solution is still missing but we isolated it to the Bluetooth LE connection parameters for latency and intervals. The bluez developers say that the connected device should suggest the best settings, the bluez daemon only ships sensible default settings. It looks like the new Xbox controllers do not properly suggest their preferred connection parameters, some BLE mice show the same problem. You can work around it by changing the bluez defaults instead. This change is not recommended by the bluez developers but as long as you only use a very specific set of BLE devices, this change should be fine.
The controller uses 100 Hz internally for its protocol, so we decided to use intervals of 8.75..11.25ms. Each tick is
1.25ms, so we end up with MinConnectionInterval=7
and MaxConnectionInterval=9
. If you already use a similar
work-around for other devices, you may need to adjust your settings to the proper bounds, i.e. do not increase the
min value, do not lower the max value.
Edit the following file and restart the Bluetooth service or reboot:
# /etc/bluetooth/main.conf
[LE]
MinConnectionInterval=7
MaxConnectionInterval=9
ConnectionLatency=0
References:
- https://www.novelbits.io/ble-connection-intervals/
- https://github.com/bluez/bluez/issues/156
- https://wiki.archlinux.org/title/Bluetooth_mouse#Mouse_lag
Incompatible Bluetooth Chipset
Some chipsets, e.g. the CSR 85xx or Intel AX200 (and variants like 3xxx), do have problems when you try to reconnect the gamepad.
Some chipsets may need additional driver firmware to work correctly. Try installing
linux-firmware
from your distribution.
See below, if this happens since a firmware upgrade of the controller.
Gamepad Connects and Immediately Disconnects since Firmware Upgrade
After upgrading the controller firmware, it is essential to fully remove/forget the device from your Bluetooth device list, then reboot to ensure a clean state, then re-pair the controller.
Reference:
- https://github.com/atar-axis/xpadneo/issues/439
Gamepad Asks for a PIN During Pairing
A user found that with genuine Xbox controllers, the fix is often to use an external USB dongle instead of the internal chipset for pairing the controller (recommended to try first).
If it still asks for a PIN, try 0000
to connect the controller. It should happen just once.
Some third-party controllers and clones will still show the issue on later connects. The issue should be reported to the Bluez project to fix it, we only provide a work-around here.
To work around the issue, this solution was found. It may affect other devices and reduces security, use at your own risk:
# /etc/bluetooth/input.conf
[General]
UserspaceHID=true
ClassicBondedOnly=false
LEAutoSecurity=false
Reference:
- https://github.com/atar-axis/xpadneo/issues/262#issuecomment-1913918332
Gamepad Is Connected but Did not Rumble
If the gamepad does connect but it doesn’t rumble, then mosty probably the wrong driver is loaded,
or the gamepad is quirky and doesn’t fully support the protocol. Your kernel may also be missing the uhid
module
which is needed by all Bluetooth LE devices for input capabilities because the bluez daemon will handle HID data in
user-space. Most distributions include uhid
but if in doubt, ask your distribution kernel maintainers.
Check the output of zgrep UHID /proc/config.gz
to check whether your kernel has uhid support. This is only required
for Xbox controllers with firmware 5.x or higher.
Check the output of the dmesg
command to see whether xpadneo was loaded and logged your
gamepad.
Gamepad Has Quirks (i.e., wrong rumble behavior)
You may want to try serveral combinations of quirk flags added to the module paramters.
See Configuration and modinfo hid-xpadneo
for more information. You may also want to use the hidraw testing utility which bypasses the
driver and let’s you try different combination of parameters. The utility is located at
misc/examples/c_hidraw
.
Gamepad Does not Connect at All, Runs A Reconnect Loop, or Immediately Disconnects
Check whether ERTM was disabled (see above). Also, some newer models use a different Bluetooth protocol “Bluetooth
low energe” (BLE) which you may accidentally have disabled. Check the following settings in /etc/bluetooth/main.conf
:
[General]
ControllerMode = dual
JustWorksRepairing = confirm
Xbox Wireless Controller
The newest wireless controllers from Microsoft (Xbox One and Xbox Series X|S) are known to cause a reconnect loop and not pairing with Bluez. There are some specific workarounds:
- Plug your controller to a Windows 10 computer via a USB cord. Download
the Xbox Accessories application. When launching the app, it should ask you to
update the firmware of the controller. When it’s done, your controller should work just fine with any Linux system.
- If you paired your controller to your linux computer before updating the firmware, and the controller is still not connecting properly after the firmware update, try removing the bluetooth device and re-pairing through the usual process.
- If it didn’t work, you can try these two workarounds:
- Use a Windows 10 computer on the same Bluetooth adapter to pair with the controller. It must absolutly be on
the same Bluetooth adapter, i.e. the same computer (can be inside a virtual machine with Bluetooth passthrough)
if it’s an internal Bluetooth adapter, or the same Bluetooth dongle. Then, you can get the pairing keys and
install them within your Linux Bluetooth system.
- After pairing the controller on Windows, refer to the steps on the ArchLinux wiki for extracting the pairing keys from Windows.
- Reboot the computer and try connecting.
- If this fails, try removing the Xbox controller and re-pairing through the usual process.
- Update to a newer kernel. Kernel 5.13 and higher might have patched a fix.
- Use a different Bluetooth stack. Xbox controllers work fine with Fluoride (the bluetooth stack from Android). Sadly, it’s hard to install on another Linux, and Bluez is the only stack easily provided on most Linux distributions.
- Use a Windows 10 computer on the same Bluetooth adapter to pair with the controller. It must absolutly be on
the same Bluetooth adapter, i.e. the same computer (can be inside a virtual machine with Bluetooth passthrough)
if it’s an internal Bluetooth adapter, or the same Bluetooth dongle. Then, you can get the pairing keys and
install them within your Linux Bluetooth system.
- If none of these options worked, or you can’t try them, then the only solution is to plug the controller using a USB cord. As for now, it won’t load the xpadneo driver, but the default controller driver. USB support may be added soon to xpadneo.
Gamepad Axes Are Swapped, Seemingly Unresponsive or Strange Behavior
If you observe this problem with jstest
, systemsettings joystick
(KDE) or jstest-gtk
, there’s usually nothing
to do as these test programs use the old joydev
API while most (modern) games use the evdev
API. Some emulators,
tho, use the joydev
API and do not respect the axes naming from evdev
. In this case, please run the following
command to correct the axes mapping for the js interface:
jscal -u 8,0,1,3,4,2,5,16,17,10,304,305,307,308,310,311,314,315,317,318 /dev/input/js0
Explanation: -u
set the mapping for 8
axes to axes code 0,1,3,4,...
and for 10
buttons to button codes
304,305,307,308,...
. This only remaps the joydev
API, not the evdev
API. Making this change may have
unexpected consequences for applications using both APIs.
IMPORTANT: Now test all your axes to collect calibration data. You can then use the following command to store the settings permanently:
sudo jscal-store /dev/input/js0
If the gamepad does not restore the mapping after disconnecting and reconnecting it, i.e., your distribution doesn’t
ship a proper udev rule for that, you may want to add the this udev rule, then reboot (see also
/misc/examples/udev-rules/99-xpadneo-joydev.rules
):
# /etc/udev/rules.d/99-xpadneo-joydev.rules
KERNEL=="js*", ACTION=="add", DRIVERS=="xpadneo", RUN+="/usr/bin/jscal-restore %E{DEVNAME}"
From now on, connecting the gamepad should restore the values from /var/lib/joystick/joystick.state. If you messed up, simply remove your gamepad from the file and start over.
Please check, if jscal-restore
is really in /usr/bin
, otherwise use the correct path, found by running:
type -p jscal-restore
IMPORTANT NOTE: The Chrome gamepad API (used for Stadia and other browser games) is a hybrid user of both the
joydev
and the evdev
API bit it uses a hard-coded axes mapping for each controller model. Thus, when you run the
above commands, the API will be confused and now shows the problem you initially tried to fix. To use the Chrome
gamepad API, you’d need to revert that settings. There is currently no known work-around.
Debugging
If you are asked to send debug info or want to fix bugs, follow the guide
displayed when opening a new bug report.
This has all the hints to get you started with debugging. You may also want
to increase the kernel debug level if your distribution sets it very low.
Otherwise, the driver reports most incidents, quirks, and fixes to dmesg
.
Environment
Useful information can now be aquired with the commands:
dmesg
: I advise you to rundmesg -wdH
in a terminal while you connect your controller from a second terminal to get hardware information in realtime.modinfo hid_xpadneo
: get information on xpadneo as a kernel module.- When your gamepad is connected, get the HID report descriptor:
xxd -c20 -g1 /sys/module/hid_xpadneo/drivers/hid:xpadneo/0005:045E:*/report_descriptor | tee >(cksum)
Generated Events
If you are asked to supply the events generated by xpadneo, please run the following command:
perl -0777 -l -ne 'print "/dev/input/$1\n" if /Name="Xbox Wireless Controller".*Handlers.*(event[0-9]+)/s' /proc/bus/input/devices | xargs evtest
Do whatever you think does not behave correctly (e.g. move the sticks from left to right if you think the range is wrong) and upload the output.
HID Device Descriptor (including checksum)
If we ask you to supply the device descriptor, please post the output of the following command:
xxd -c20 -g1 /sys/module/hid_xpadneo/drivers/hid:xpadneo/0005:045E:*/report_descriptor | tee >(cksum)
Bluetooth Connection
Some debugging needs a deeper low level look. You can do this by running btmon
:
sudo btmon | tee xpadneo-btmon.txt
Then reproduce the problem you are observing.
We probably also need some information about the dongle:
- Run
lsusb
and pick the device number of your dongle. - Run
lsusb -v -s## | tee xpadneo-lsusb.txt
where##
is the device number picked in the previous step.
Third Party Bugs
While developing this driver we recognized some bugs in KDE and linux itself, some of which are fixed now - others are not:
- Broken Battery Indicator in KDE fixed! https://www.kde.org/announcements/kde-frameworks-5.45.0.php
- Cambridge Silicon Radio (CSR) chipsets do have problems while reconnecting (OUI 00:1A:7D)
- Most of these problems may be fixed in kernel 5.10
- Qualcomm chipsets may have performance and lag problems (OUI 9C:B6:D0)
- Some Bluetooth dongles may need additional firmware for proper operation
- Possible solution: try installing
linux-firmware
from your distribution
- Possible solution: try installing
SDL Mapping
We fixed the following problem by pretending we are in Windows wireless mode
by faking the input device PID to 0x02E0
. The original PID 0x02FD
triggeres several unwanted fixups at multiple layers, i.e. SDL or the HTML5
game controller API. The following paragraphs document the originally
wrong behaviour observed and we clearly don’t want our fixed mappings to be
“fixed” again by layers detected a seemingly wrong button mapping:
Since after libSDL2 2.0.8, SDL contains a fix for the wrong mapping introduced by the generic hid driver. Thus, you may experience wrong button mappings again.
Also, Wine since version 3.3 supports using SDL for xinput*.dll
, and with
version 3.4 it includes a patch to detect the Xbox One S controller. Games
running in Wine and using xinput may thus also see wrong mappings.
The Steam client includes a correction for SDL based games since some version, not depending on the SDL version. It provides a custom SDL mapping the same way we are describing here.
To fix this and have both SDL-based software and software using the legacy joystick interface using correct button mapping, you need to export an environment variable which then overrides default behavior:
export SDL_GAMECONTROLLERCONFIG="\
050000005e040000fd02000003090000,Xbox One Wireless Controller,\
a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,\
guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,\
rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,\
start:b7,x:b2,y:b3,"
You need to set this before starting the software. To apply it globally, put this line into your logon scripts.
The id 050000005e040000fd02000003090000
is crafted from your device
id as four 32-bit words. It is, in LSB order, the bus number 5, the
vendor id 045e
, the device id 02fd
, and the interface version
or serial 0903
which is not a running number but firmware dependent.
This version number is not the same as shown in dmesg as the fourth
component.
You can find the values by looking at dmesg when xpadneo
detects
your device. In dmesg, find the device path, then change to the
device path below /sys
and look for the files in the id
directory.
The name value after the id is purely cosmetical, you can name it whatever you like. It may show up in games as a visual identifier.
If running Wine games, to properly support xpadneo, ensure you have
removed any previous xinput hacks (which includes redirecting
xinput*.dll
to native and placing a hacked xinput dll in the
game directory. Also ensure your Wine built comes with SDL support
compiled in.
If you do not want to apply this setting globally, you can instead
put the SDL mapping inside Steam config.vdf
. You can find this
file in $STEAM_BASE/config/config.vdf
. Find the line containing
"SDL_GamepadBind"
and adjust or add your own controller (see
above). Ensure correct quoting, and Steam is not running
while editing the file. This may not work for Steam in Wine
because the Wine SDL layer comes first, you still need to export
the variable before running Wine. An example with multiple
controllers looks like this:
"SDL_GamepadBind" "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,"
An alternative store location of user-defined mappings can be found here:
$HOME/.local/share/gamecontrollerdb.local.txt