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 <mike.salvat...@canonical.com>
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 <mike.salvat...@canonical.com>
---
 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 <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/module.h>
+#include <linux/usb/ch9.h>
 #include <linux/usb/input.h>
 #include <linux/usb/quirks.h>
 
@@ -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 <mike.salvat...@canonical.com>
> 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 <mike.salvat...@canonical.com>
> ---
>  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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to