All, I took another look at this patch and realized it was missing a #include. I've added the appropriate #include to a new version of the patch. Thanks, Mike Salvatore From 6fbf80fa3d5bc39fa054350a663080e1380046f8 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 13 Mar 2019 22:11:37 -0400 Subject: [PATCH] Input: xpad - send control init message to certain Xbox controllers The Xbox controller with idVendor == 0x045e and idProduct == 0x028e requires that a specific control transfer be sent from the host to the device before the device will send data to the host. This patch introduces an xboxone_control_packet struct and a mechanism for sending control packets to devices that require them at initialization. Signed-off-by: Mike Salvatore --- drivers/input/joystick/xpad.c | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index cfc8b94527b9..756df325bfa6 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include @@ -460,6 +461,25 @@ struct xboxone_init_packet { .len = ARRAY_SIZE(_data), \ } +struct xboxone_control_packet { + u16 idVendor; + u16 idProduct; + struct usb_ctrlrequest ctrlrequest; +}; + +#define XBOXONE_CONTROL_PKT(_vid, _pid, _reqtype, _req, _value, _index, _len) \ + { \ + .idVendor = (_vid), \ + .idProduct = (_pid), \ + .ctrlrequest = { \ + .bRequestType = (_reqtype), \ + .bRequest = (_req), \ + .wValue = (_value), \ + .wIndex = (_index), \ + .wLength = (_len), \ + }, \ + } + /* * This packet is required for all Xbox One pads with 2015 @@ -537,6 +557,13 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init), }; +static const struct xboxone_control_packet xboxone_control_packets[] = { + XBOXONE_CONTROL_PKT(0x045e, 0x028e, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + USB_REQ_CLEAR_FEATURE, + USB_DEVICE_REMOTE_WAKEUP, 0, 0), +}; + struct xpad_output_packet { u8 data[XPAD_PKT_LEN]; u8 len; @@ -1119,6 +1146,31 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad, return error; } +static int xpad_init_control_msg(struct usb_xpad *xpad) +{ + struct usb_device *udev = xpad->udev; + size_t i; + + for (i = 0; i < ARRAY_SIZE(xboxone_control_packets); i++) { + u16 idVendor = xboxone_control_packets[i].idVendor; + u16 idProduct = xboxone_control_packets[i].idProduct; + + if (le16_to_cpu(udev->descriptor.idVendor) == idVendor + && le16_to_cpu(udev->descriptor.idProduct) == idProduct) { + const struct usb_ctrlrequest *ctrlrequest = + &(xboxone_control_packets[i].ctrlrequest); + + return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + ctrlrequest->bRequest, + ctrlrequest->bRequestType, ctrlrequest->wValue, + ctrlrequest->wIndex, NULL, ctrlrequest->wLength, + 2 * HZ); + } + } + + return 0; +} + static void xpad_stop_output(struct usb_xpad *xpad) { if (xpad->xtype != XTYPE_UNKNOWN) { @@ -1839,6 +1891,11 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id if (error) goto err_deinit_output; } + + error = xpad_init_control_msg(xpad); + if (error) + goto err_deinit_output; + return 0; err_deinit_output: -- 2.17.1 On 3/23/19 12:46 PM, Mike Salvatore wrote: > From 3051524e62d68b920019bcb50a713e736fcf4234 Mon Sep 17 00:00:00 2001 > From: Mike Salvatore > Date: Wed, 13 Mar 2019 22:11:37 -0400 > Subject: [PATCH] Input: xpad - send control init message to certain Xbox > controllers > > The Xbox controller with idVendor == 0x045e and idProduct == 0x028e > requires that a specific control transfer be sent from the host to the > device before the device will send data to the host. > > This patch introduces an xboxone_control_packet struct and a mechanism > for sending control packets to devices that require them at > initialization. > > Signed-off-by: Mike Salvatore > --- > drivers/input/joystick/xpad.c | 56 +++++++++++++++++++++++++++++++++++ > 1 file changed, 56 insertions(+) > > diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c > index cfc8b94527b9..f45522b9ff1f 100644 > --- a/drivers/input/joystick/xpad.c > +++ b/drivers/input/joystick/xpad.c > @@ -460,6 +460,25 @@ struct xboxone_init_packet { > .len = ARRAY_SIZE(_data), \ > } > > +struct xboxone_control_packet { > + u16 idVendor; > + u16 idProduct; > + struct usb_ctrlrequest ctrlrequest; > +}; > + > +#define XBOXONE_CONTROL_PKT(_vid, _pid, _reqtype, _req, _value, _index, _len) \ > + { \ > + .idVendor = (_vid), \ > + .idProduct = (_pid), \ > + .ctrlrequest = { \ > + .bRequestType = (_reqtype), \ > + .bRequest = (_req), \ > + .wValue = (_value), \ > + .wIndex = (_index), \ > + .wLength = (_len), \ > + }, \ > + } > + > > /* > * This packet is required for all Xbox One pads with 2015 > @@ -537,6 +556,13 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { > XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init), > }; > > +static const struct xboxone_control_packet xboxone_control_packets[] = { > + XBOXONE_CONTROL_PKT(0x045e, 0x028e, > + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, > + USB_REQ_CLEAR_FEATURE, > + USB_DEVICE_REMOTE_WAKEUP, 0, 0), > +}; > + > struct xpad_output_packet { > u8 data[XPAD_PKT_LEN]; > u8 len; > @@ -1119,6 +1145,31 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad, > return error; > } > > +static int xpad_init_control_msg(struct usb_xpad *xpad) > +{ > + struct usb_device *udev = xpad->udev; > + size_t i; > + > + for (i = 0; i < ARRAY_SIZE(xboxone_control_packets); i++) { > + u16 idVendor = xboxone_control_packets[i].idVendor; > + u16 idProduct = xboxone_control_packets[i].idProduct; > + > + if (le16_to_cpu(udev->descriptor.idVendor) == idVendor > + && le16_to_cpu(udev->descriptor.idProduct) == idProduct) { > + const struct usb_ctrlrequest *ctrlrequest = > + &(xboxone_control_packets[i].ctrlrequest); > + > + return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), > + ctrlrequest->bRequest, > + ctrlrequest->bRequestType, ctrlrequest->wValue, > + ctrlrequest->wIndex, NULL, ctrlrequest->wLength, > + 2 * HZ); > + } > + } > + > + return 0; > +} > + > static void xpad_stop_output(struct usb_xpad *xpad) > { > if (xpad->xtype != XTYPE_UNKNOWN) { > @@ -1839,6 +1890,11 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id > if (error) > goto err_deinit_output; > } > + > + error = xpad_init_control_msg(xpad); > + if (error) > + goto err_deinit_output; > + > return 0; > > err_deinit_output: > -- 2.17.1