Last active
January 29, 2018 22:17
-
-
Save raincode00/2006b6cd3d5bbf9d39fd45f20abbe9c9 to your computer and use it in GitHub Desktop.
Xbox One S Controller Bluetooth Fixes on Ubuntu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Id for another xbox one s controller that have the bluetooth problem
045e:02ea