Skip to content

Commit

Permalink
HID: microsoft: map Xbox Series X buttons correctly
Browse files Browse the repository at this point in the history
The Xbox Series X controller connected over bluetooth maps to several
wrong buttons/axes. For the right joystick the axes are swapped to
RX/RY. The left and right triggers are correctly remapped from gas and
break. These mappings correspond to the xpad driver when the controller
is plugged in over USB.

Signed-off-by: Jelle van der Waa <jvanderwaa@redhat.com>
  • Loading branch information
jelly committed Mar 14, 2022
1 parent 09688c0 commit 4f00ccb
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@
#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
#define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de
#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
#define USB_DEVICE_ID_MS_XBOX_SERIES_X_CONTROLLER 0x0b13
#define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
#define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0

Expand Down
33 changes: 33 additions & 0 deletions drivers/hid/hid-microsoft.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define MS_DUPLICATE_USAGES BIT(5)
#define MS_SURFACE_DIAL BIT(6)
#define MS_QUIRK_FF BIT(7)
#define MS_XBOX_SERIES_X BIT(8)

struct ms_data {
unsigned long quirks;
Expand Down Expand Up @@ -179,6 +180,31 @@ static int ms_surface_dial_quirk(struct hid_input *hi, struct hid_field *field,
return 0;
}

#define ms_map_abs_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
EV_ABS, (c))
static int ms_xbox_series_x_quirk(struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max)
{
switch (usage->hid) {
case HID_GD_Z:
ms_map_abs_clear(ABS_RX);
break;
case HID_GD_RZ:
ms_map_abs_clear(ABS_RY);
break;
case (HID_UP_SIMULATION | 0x00c4): /* gas */
ms_map_abs_clear(ABS_RZ);
break;
case (HID_UP_SIMULATION | 0x00c5): /* break */
ms_map_abs_clear(ABS_Z);
break;
default:
return 0;
}

return 1;
}

static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
Expand All @@ -203,6 +229,11 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return ret;
}

if ((quirks & MS_XBOX_SERIES_X) &&
ms_xbox_series_x_quirk(hi, field, usage, bit, max)) {
return 1;
}

return 0;
}

Expand Down Expand Up @@ -448,6 +479,8 @@ static const struct hid_device_id ms_devices[] = {
.driver_data = MS_SURFACE_DIAL },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER),
.driver_data = MS_QUIRK_FF },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_SERIES_X_CONTROLLER),
.driver_data = MS_XBOX_SERIES_X },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS),
.driver_data = MS_QUIRK_FF },
{ }
Expand Down

0 comments on commit 4f00ccb

Please sign in to comment.