blob: ec1e05dca479957253cc46dfa20c6e8cfb1b201a [file] [log] [blame]
From foo@baz Fri Jan 24 11:58:18 PST 2014
Date: Fri, 24 Jan 2014 11:58:18 -0800
To: Greg KH <gregkh@linuxfoundation.org>
From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>
Subject: [PATCH] Input: xpad: disconnect all Wireless controllers at init
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(-)
--- 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 *ur
}
}
-#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 us
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_interfa
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;