Skip to content

Instantly share code, notes, and snippets.

@raincode00
Last active January 29, 2018 22:17
Show Gist options
  • Save raincode00/2006b6cd3d5bbf9d39fd45f20abbe9c9 to your computer and use it in GitHub Desktop.
Save raincode00/2006b6cd3d5bbf9d39fd45f20abbe9c9 to your computer and use it in GitHub Desktop.
Xbox One S Controller Bluetooth Fixes on Ubuntu
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index ea36b55..bac17d9 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1984,6 +1984,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_2016) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b0ec840..bfe6b11 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -735,6 +735,8 @@
#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_2 0x07e8
#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP 0x07e9
#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+#define USB_DEVICE_ID_MS_XBOX_ONE_S_2016 0x02e0
+#define USB_DEVICE_ID_MS_XBOX_ONE_S 0x02fd
#define USB_VENDOR_ID_MOJO 0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 74b7b84..72ddcc4 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -28,6 +28,8 @@
#define MS_RDESC 0x08
#define MS_NOGET 0x10
#define MS_DUPLICATE_USAGES 0x20
+#define MS_RDESC_3K 0x40
+#define MS_XBOX_ONE_S 0x80
static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
@@ -44,6 +46,8 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[557] = 0x35;
rdesc[559] = 0x45;
}
+
+
return rdesc;
}
@@ -130,11 +134,57 @@ static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
return 1;
}
+static int ms_xbox_one_s_quirk(struct hid_input *hi, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ switch (usage->hid & HID_USAGE_PAGE) {
+
+ case HID_UP_GENDESK:
+ if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
+ switch (usage->hid & 0xf) {
+ case 0x5:
+ /* override the default mapping of KEY_MENU */
+ ms_map_key_clear(BTN_MODE);
+ return 1;
+ default:
+ break;
+ }
+ break;
+ }
+ break;
+ //case HID_UP_CONSUMER:
+ // /* overrides consumer HIDs */
+ // switch (usage->hid & HID_USAGE) {
+ // case 0x0223: /* AC Home */
+ // ms_map_key_clear(BTN_MODE);
+ // return 1;
+ // case 0x0224: /* AC Back */
+ // ms_map_key_clear(BTN_SELECT);
+ // return 1;
+ // default:
+ // break;
+ //
+ // }
+ // break;
+ default:
+ break;
+ }
+
+ /* Let the normal mapping happen for everything else */
+ return 0;
+}
+
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)
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+
+ printk(KERN_INFO KBUILD_MODNAME " ms_input_mapping %s HID: %#010x\n", hdev->name, usage->hid);
+ if (quirks & MS_XBOX_ONE_S) {
+ int ret = ms_xbox_one_s_quirk(hi, usage, bit, max);
+ return ret;
+ }
if (quirks & MS_ERGONOMY) {
int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
@@ -216,6 +266,29 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
return 1;
}
+ if (quirks & MS_XBOX_ONE_S) {
+ switch (usage->hid & HID_USAGE_PAGE) {
+ case HID_UP_CONSUMER:
+ /* overrides consumer HIDs */
+ switch (usage->hid & HID_USAGE) {
+ case 0x0223: /* AC Home */
+ input_report_key(input, KEY_HOMEPAGE, value);
+ input_report_key(input, BTN_MODE, value);
+ return 1;
+ case 0x0224: /* AC Back */
+ input_report_key(input, KEY_BACK, value);
+ input_report_key(input, BTN_SELECT, value);
+ return 1;
+ default:
+ break;
+
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
return 0;
}
@@ -293,6 +366,11 @@ static const struct hid_device_id ms_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
+
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S),
+ .driver_data = MS_XBOX_ONE_S },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_2016),
+ .driver_data = MS_XBOX_ONE_S },
{ }
};
MODULE_DEVICE_TABLE(hid, ms_devices);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ce0b5dd..cc616d0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3214,6 +3214,14 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
switch (chan->mode) {
case L2CAP_MODE_BASIC:
+ /* HACK FOR XBOX ONE S CONTROLLERS
+ * If we add options to the configuration request, the
+ * Xbox One S controller responds with:
+ * Result: Failure - unknown options (0x0003)
+ * For now, just don't send configuration options.
+ * Remove this hack once the controller supports it
+ */
+#if 0
if (disable_ertm)
break;
@@ -3230,6 +3238,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
+#endif
break;
case L2CAP_MODE_ERTM:
@@ -4217,6 +4226,16 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
goto done;
break;
}
+ case L2CAP_CONF_UNKNOWN:
+ /* Ignore unkwown option for RFC in case of basic mode as it
+ * is considered the default mode:
+ * BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part A] page 96:
+ * The Basic L2CAP mode is the default.
+ */
+ if (rsp->data == L2CAP_CONF_RFC &&
+ chan->mode == L2CAP_MODE_BASIC) {
+ break;
+ }
default:
l2cap_chan_set_err(chan, ECONNRESET);
@jontis
Copy link

jontis commented Sep 18, 2017

Id for another xbox one s controller that have the bluetooth problem
045e:02ea

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment