diff mbox

[5/7] Input: xpad: disconnect all Wireless controllers at init

Message ID 1391173414-6199-6-git-send-email-gregkh@linuxfoundation.org (mailing list archive)
State New, archived
Headers show

Commit Message

Greg Kroah-Hartman Jan. 31, 2014, 1:03 p.m. UTC
From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>

We initializing the driver/device, we really don't know how many
controllers are connected.  So send a "disconnect all" command to the
base-station, and let the user pair the controllers in the order in
which they want them assigned.

Note, this means we now do not "preallocate" all 4 devices when a single
wireless base station is seen, but require the device to be properly
connected to the base station before that can happen.  The allocation of
the device happens in the next patch, not here, so in a way, this patch
breaks all wireless devices...

Because we want to talk to the device, we have to set up the output urbs
no matter if we have CONFIG_JOYSTICK_XPAD_FF or
CONFIG_JOYSTICK_XPAD_LEDS enabled not, so take out the code that allows
those variables and code to be disabled (it's so small it should never
matter...)

Signed-off-by: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/joystick/xpad.c | 46 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 12 deletions(-)

Comments

Pierre-Loup A. Griffais Feb. 3, 2014, 10:22 p.m. UTC | #1
There's apparently a packet you can send to the receiver that prompts it 
to immediately send feedback about all the paired controllers that would 
be ideal as a replacement for this kludge. I will test it and send out a 
replacement patch for 5/7 in that series if it turns out to work well. 
Thanks a lot to Zachary Lund for pointing this out.

On 01/31/2014 05:03 AM, Greg Kroah-Hartman wrote:
> From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>
>
> We initializing the driver/device, we really don't know how many
> controllers are connected.  So send a "disconnect all" command to the
> base-station, and let the user pair the controllers in the order in
> which they want them assigned.
>
> Note, this means we now do not "preallocate" all 4 devices when a single
> wireless base station is seen, but require the device to be properly
> connected to the base station before that can happen.  The allocation of
> the device happens in the next patch, not here, so in a way, this patch
> breaks all wireless devices...
>
> Because we want to talk to the device, we have to set up the output urbs
> no matter if we have CONFIG_JOYSTICK_XPAD_FF or
> CONFIG_JOYSTICK_XPAD_LEDS enabled not, so take out the code that allows
> those variables and code to be disabled (it's so small it should never
> matter...)
>
> Signed-off-by: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>   drivers/input/joystick/xpad.c | 46 ++++++++++++++++++++++++++++++++-----------
>   1 file changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 7997ae89a877..7a07b95790d7 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -278,12 +278,10 @@ struct usb_xpad {
>   	struct urb *bulk_out;
>   	unsigned char *bdata;
>
> -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
>   	struct urb *irq_out;		/* urb for interrupt out report */
>   	unsigned char *odata;		/* output data */
>   	dma_addr_t odata_dma;
>   	struct mutex odata_mutex;
> -#endif
>
>   #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
>   	struct xpad_led *led;
> @@ -537,7 +535,6 @@ static void xpad_bulk_out(struct urb *urb)
>   	}
>   }
>
> -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
>   static void xpad_irq_out(struct urb *urb)
>   {
>   	struct usb_xpad *xpad = urb->context;
> @@ -623,11 +620,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
>   				xpad->odata, xpad->odata_dma);
>   	}
>   }
> -#else
> -static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
> -static void xpad_deinit_output(struct usb_xpad *xpad) {}
> -static void xpad_stop_output(struct usb_xpad *xpad) {}
> -#endif
>
>   #ifdef CONFIG_JOYSTICK_XPAD_FF
>   static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
> @@ -1091,11 +1083,41 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
>   			usb_kill_urb(xpad->irq_in);
>   			goto fail9;
>   		}
> +
> +		/*
> +		 * We don't know how to check the controller state at driver
> +		 * load, so just disconnect them all, requiring the user to
> +		 * repair the device in the order they want them used.  Good
> +		 * point is that we don't connect devices in "random" order,
> +		 * but the extra step seems a bit harsh as other operating
> +		 * systems don't require this at the moment.
> +		 *
> +		 * Power-off packet information came from an OS-X
> +		 * reverse-engineered driver located at:
> +		 * http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver#toc1
> +		 */
> +		mutex_lock(&xpad->odata_mutex);
> +		xpad->odata[0] = 0x00;
> +		xpad->odata[1] = 0x00;
> +		xpad->odata[2] = 0x08;
> +		xpad->odata[3] = 0xC0;
> +		xpad->odata[4] = 0x00;
> +		xpad->odata[5] = 0x00;
> +		xpad->odata[6] = 0x00;
> +		xpad->odata[7] = 0x00;
> +		xpad->odata[8] = 0x00;
> +		xpad->odata[9] = 0x00;
> +		xpad->odata[10] = 0x00;
> +		xpad->odata[11] = 0x00;
> +		xpad->irq_out->transfer_buffer_length = 12;
> +		usb_submit_urb(xpad->irq_out, GFP_KERNEL);
> +		mutex_unlock(&xpad->odata_mutex);
> +	} else {
> +		xpad->pad_present = 1;
> +		error = xpad_init_input(xpad);
> +		if (error)
> +			goto fail9;
>   	}
> -	xpad->pad_present = 1;
> -	error = xpad_init_input(xpad);
> -	if (error)
> -		goto fail9;
>
>   	return 0;
>
>

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 7997ae89a877..7a07b95790d7 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -278,12 +278,10 @@  struct usb_xpad {
 	struct urb *bulk_out;
 	unsigned char *bdata;
 
-#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
 	struct urb *irq_out;		/* urb for interrupt out report */
 	unsigned char *odata;		/* output data */
 	dma_addr_t odata_dma;
 	struct mutex odata_mutex;
-#endif
 
 #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
 	struct xpad_led *led;
@@ -537,7 +535,6 @@  static void xpad_bulk_out(struct urb *urb)
 	}
 }
 
-#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
 static void xpad_irq_out(struct urb *urb)
 {
 	struct usb_xpad *xpad = urb->context;
@@ -623,11 +620,6 @@  static void xpad_deinit_output(struct usb_xpad *xpad)
 				xpad->odata, xpad->odata_dma);
 	}
 }
-#else
-static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
-static void xpad_deinit_output(struct usb_xpad *xpad) {}
-static void xpad_stop_output(struct usb_xpad *xpad) {}
-#endif
 
 #ifdef CONFIG_JOYSTICK_XPAD_FF
 static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
@@ -1091,11 +1083,41 @@  static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 			usb_kill_urb(xpad->irq_in);
 			goto fail9;
 		}
+
+		/*
+		 * We don't know how to check the controller state at driver
+		 * load, so just disconnect them all, requiring the user to
+		 * repair the device in the order they want them used.  Good
+		 * point is that we don't connect devices in "random" order,
+		 * but the extra step seems a bit harsh as other operating
+		 * systems don't require this at the moment.
+		 *
+		 * Power-off packet information came from an OS-X
+		 * reverse-engineered driver located at:
+		 * http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver#toc1
+		 */
+		mutex_lock(&xpad->odata_mutex);
+		xpad->odata[0] = 0x00;
+		xpad->odata[1] = 0x00;
+		xpad->odata[2] = 0x08;
+		xpad->odata[3] = 0xC0;
+		xpad->odata[4] = 0x00;
+		xpad->odata[5] = 0x00;
+		xpad->odata[6] = 0x00;
+		xpad->odata[7] = 0x00;
+		xpad->odata[8] = 0x00;
+		xpad->odata[9] = 0x00;
+		xpad->odata[10] = 0x00;
+		xpad->odata[11] = 0x00;
+		xpad->irq_out->transfer_buffer_length = 12;
+		usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+		mutex_unlock(&xpad->odata_mutex);
+	} else {
+		xpad->pad_present = 1;
+		error = xpad_init_input(xpad);
+		if (error)
+			goto fail9;
 	}
-	xpad->pad_present = 1;
-	error = xpad_init_input(xpad);
-	if (error)
-		goto fail9;
 
 	return 0;