Re: [PATCH] xpad.c: Send necessary control transfer to certain Xbox controllers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.salvatore@xxxxxxxxxxxxx>
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.salvatore@xxxxxxxxxxxxx>
---
 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.salvatore@xxxxxxxxxxxxx>
> 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.salvatore@xxxxxxxxxxxxx>
> ---
>  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


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux