| From foo@baz Fri Jan 24 09:30:08 PST 2014 |
| Date: Fri, 24 Jan 2014 09:30:08 -0800 |
| To: Greg KH <gregkh@linuxfoundation.org> |
| From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| Subject: [PATCH] Input: xpad: set the LEDs properly on XBox Wireless controllers |
| |
| From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| |
| Add the logic to set the LEDs on XBox Wireless controllers. Command |
| sequence found by sniffing the Windows data stream when plugging the |
| device in. |
| |
| Signed-off-by: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/input/joystick/xpad.c | 32 +++++++++++++++++++++++++++----- |
| 1 file changed, 27 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/input/joystick/xpad.c |
| +++ b/drivers/input/joystick/xpad.c |
| @@ -864,15 +864,37 @@ struct xpad_led { |
| |
| static void xpad_send_led_command(struct usb_xpad *xpad, int command) |
| { |
| - if (command >= 0 && command < 14) { |
| - mutex_lock(&xpad->odata_mutex); |
| + if (command > 15) |
| + return; |
| + |
| + mutex_lock(&xpad->odata_mutex); |
| + |
| + switch (xpad->xtype) { |
| + case XTYPE_XBOX360: |
| xpad->odata[0] = 0x01; |
| xpad->odata[1] = 0x03; |
| xpad->odata[2] = command; |
| xpad->irq_out->transfer_buffer_length = 3; |
| - usb_submit_urb(xpad->irq_out, GFP_KERNEL); |
| - mutex_unlock(&xpad->odata_mutex); |
| + break; |
| + case XTYPE_XBOX360W: |
| + xpad->odata[0] = 0x00; |
| + xpad->odata[1] = 0x00; |
| + xpad->odata[2] = 0x08; |
| + xpad->odata[3] = 0x40 + (command % 0x0e); |
| + 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; |
| + break; |
| } |
| + |
| + usb_submit_urb(xpad->irq_out, GFP_KERNEL); |
| + mutex_unlock(&xpad->odata_mutex); |
| } |
| |
| static void xpad_led_set(struct led_classdev *led_cdev, |
| @@ -892,7 +914,7 @@ static int xpad_led_probe(struct usb_xpa |
| struct led_classdev *led_cdev; |
| int error; |
| |
| - if (xpad->xtype != XTYPE_XBOX360) |
| + if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W) |
| return 0; |
| |
| xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); |