Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: xpad - allow delaying init packets

Some Xbox One controllers will only start processing the init packets after
sending the GIP announce packet. While most controllers send this packet
immediately, others will delay for some time, e.g. if a dongle needs to connect
to an actual controller first. In those cases, we want to delay until we
receive the announce packet before sending the init sequence.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Link: https://lore.kernel.org/r/20250513225411.2718072-2-vi@endrift.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Vicki Pfau and committed by
Dmitry Torokhov
036ec442 d51b9d81

+30
+30
drivers/input/joystick/xpad.c
··· 105 105 #define PKT_XBE2_FW_5_EARLY 3 106 106 #define PKT_XBE2_FW_5_11 4 107 107 108 + #define FLAG_DELAY_INIT BIT(0) 109 + 108 110 static bool dpad_to_buttons; 109 111 module_param(dpad_to_buttons, bool, S_IRUGO); 110 112 MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); ··· 129 127 char *name; 130 128 u8 mapping; 131 129 u8 xtype; 130 + u8 flags; 132 131 } xpad_device[] = { 133 132 /* Please keep this list sorted by vendor and product ID. */ 134 133 { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, ··· 599 596 * - https://github.com/medusalix/xone/blob/master/bus/protocol.c 600 597 */ 601 598 #define GIP_CMD_ACK 0x01 599 + #define GIP_CMD_ANNOUNCE 0x02 602 600 #define GIP_CMD_IDENTIFY 0x04 603 601 #define GIP_CMD_POWER 0x05 604 602 #define GIP_CMD_AUTHENTICATE 0x06 ··· 789 785 const char *name; /* name of the device */ 790 786 struct work_struct work; /* init/remove device from callback */ 791 787 time64_t mode_btn_down_ts; 788 + bool delay_init; /* init packets should be delayed */ 789 + bool delayed_init_done; 792 790 }; 793 791 794 792 static int xpad_init_input(struct usb_xpad *xpad); 795 793 static void xpad_deinit_input(struct usb_xpad *xpad); 794 + static int xpad_start_input(struct usb_xpad *xpad); 796 795 static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num); 797 796 static void xpad360w_poweroff_controller(struct usb_xpad *xpad); 798 797 ··· 1080 1073 1081 1074 do_sync = true; 1082 1075 } 1076 + } else if (data[0] == GIP_CMD_ANNOUNCE) { 1077 + int error; 1078 + 1079 + if (xpad->delay_init && !xpad->delayed_init_done) { 1080 + xpad->delayed_init_done = true; 1081 + error = xpad_start_input(xpad); 1082 + if (error) 1083 + dev_warn(&xpad->dev->dev, 1084 + "unable to start delayed input: %d\n", 1085 + error); 1086 + } 1083 1087 } else if (data[0] == GIP_CMD_INPUT) { /* The main valid packet type for inputs */ 1084 1088 /* menu/view buttons */ 1085 1089 input_report_key(dev, BTN_START, data[4] & BIT(2)); ··· 1267 1249 const struct xboxone_init_packet *init_packet; 1268 1250 1269 1251 if (xpad->xtype != XTYPE_XBOXONE) 1252 + return false; 1253 + 1254 + /* 1255 + * Some dongles will discard init packets if they're sent before the 1256 + * controller connects. In these cases, we need to wait until we get 1257 + * an announce packet from them to send the init packet sequence. 1258 + */ 1259 + if (xpad->delay_init && !xpad->delayed_init_done) 1270 1260 return false; 1271 1261 1272 1262 /* Perform initialization sequence for Xbox One pads that require it */ ··· 2092 2066 xpad->mapping = xpad_device[i].mapping; 2093 2067 xpad->xtype = xpad_device[i].xtype; 2094 2068 xpad->name = xpad_device[i].name; 2069 + if (xpad_device[i].flags & FLAG_DELAY_INIT) 2070 + xpad->delay_init = true; 2071 + 2095 2072 xpad->packet_type = PKT_XB; 2096 2073 INIT_WORK(&xpad->work, xpad_presence_work); 2097 2074 ··· 2294 2265 struct usb_xpad *xpad = usb_get_intfdata(intf); 2295 2266 struct input_dev *input = xpad->dev; 2296 2267 2268 + xpad->delayed_init_done = false; 2297 2269 if (xpad->xtype == XTYPE_XBOX360W) 2298 2270 return xpad360w_start_input(xpad); 2299 2271