aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Mielczarek <ted@mielczarek.org>2014-08-08 14:21:59 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-13 13:30:01 -0400
commit1a48ff81b3912be5fadae3fafde6c2f632246a4c (patch)
treedee47146fc9f21262499c1aeaab1b3fb5615d895
parent041fa15951d0fb349d24c5619f35de1878bd030e (diff)
Input: xpad - add support for Xbox One controllers
Xbox One controllers require an initialization message to start sending data, so xpad_init_output becomes a required function. The Xbox One controller does not have LEDs like the Xbox 360 controller, so that functionality is not implemented. The format of messages controlling rumble is currently undocumented, so rumble support is not yet implemented. Note that Xbox One controller advertises three interfaces with the same interface class, subclass and protocol, so we have to also match against interface number. Signed-off-by: Ted Mielczarek <ted@mielczarek.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/joystick/xpad.c174
1 files changed, 157 insertions, 17 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 603fe0dd3682..177602cf7079 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -95,7 +95,8 @@
95#define XTYPE_XBOX 0 95#define XTYPE_XBOX 0
96#define XTYPE_XBOX360 1 96#define XTYPE_XBOX360 1
97#define XTYPE_XBOX360W 2 97#define XTYPE_XBOX360W 2
98#define XTYPE_UNKNOWN 3 98#define XTYPE_XBOXONE 3
99#define XTYPE_UNKNOWN 4
99 100
100static bool dpad_to_buttons; 101static bool dpad_to_buttons;
101module_param(dpad_to_buttons, bool, S_IRUGO); 102module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -121,6 +122,7 @@ static const struct xpad_device {
121 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, 122 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
122 { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, 123 { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
123 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, 124 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
125 { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
124 { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 126 { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
125 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 127 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
126 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, 128 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
@@ -231,10 +233,12 @@ static const signed short xpad_abs_triggers[] = {
231 -1 233 -1
232}; 234};
233 235
234/* Xbox 360 has a vendor-specific class, so we cannot match it with only 236/*
237 * Xbox 360 has a vendor-specific class, so we cannot match it with only
235 * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we 238 * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
236 * match against vendor id as well. Wired Xbox 360 devices have protocol 1, 239 * match against vendor id as well. Wired Xbox 360 devices have protocol 1,
237 * wireless controllers have protocol 129. */ 240 * wireless controllers have protocol 129.
241 */
238#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ 242#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
239 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ 243 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
240 .idVendor = (vend), \ 244 .idVendor = (vend), \
@@ -245,9 +249,20 @@ static const signed short xpad_abs_triggers[] = {
245 { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ 249 { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
246 { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } 250 { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
247 251
252/* The Xbox One controller uses subclass 71 and protocol 208. */
253#define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \
254 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
255 .idVendor = (vend), \
256 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
257 .bInterfaceSubClass = 71, \
258 .bInterfaceProtocol = (pr)
259#define XPAD_XBOXONE_VENDOR(vend) \
260 { XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) }
261
248static struct usb_device_id xpad_table[] = { 262static struct usb_device_id xpad_table[] = {
249 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ 263 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
250 XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ 264 XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
265 XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */
251 XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ 266 XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
252 XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ 267 XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
253 { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ 268 { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
@@ -278,12 +293,10 @@ struct usb_xpad {
278 struct urb *bulk_out; 293 struct urb *bulk_out;
279 unsigned char *bdata; 294 unsigned char *bdata;
280 295
281#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
282 struct urb *irq_out; /* urb for interrupt out report */ 296 struct urb *irq_out; /* urb for interrupt out report */
283 unsigned char *odata; /* output data */ 297 unsigned char *odata; /* output data */
284 dma_addr_t odata_dma; 298 dma_addr_t odata_dma;
285 struct mutex odata_mutex; 299 struct mutex odata_mutex;
286#endif
287 300
288#if defined(CONFIG_JOYSTICK_XPAD_LEDS) 301#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
289 struct xpad_led *led; 302 struct xpad_led *led;
@@ -470,6 +483,105 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
470 xpad360_process_packet(xpad, cmd, &data[4]); 483 xpad360_process_packet(xpad, cmd, &data[4]);
471} 484}
472 485
486/*
487 * xpadone_process_buttons
488 *
489 * Process a button update packet from an Xbox one controller.
490 */
491static void xpadone_process_buttons(struct usb_xpad *xpad,
492 struct input_dev *dev,
493 unsigned char *data)
494{
495 /* menu/view buttons */
496 input_report_key(dev, BTN_START, data[4] & 0x04);
497 input_report_key(dev, BTN_SELECT, data[4] & 0x08);
498
499 /* buttons A,B,X,Y */
500 input_report_key(dev, BTN_A, data[4] & 0x10);
501 input_report_key(dev, BTN_B, data[4] & 0x20);
502 input_report_key(dev, BTN_X, data[4] & 0x40);
503 input_report_key(dev, BTN_Y, data[4] & 0x80);
504
505 /* digital pad */
506 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
507 /* dpad as buttons (left, right, up, down) */
508 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04);
509 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08);
510 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01);
511 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02);
512 } else {
513 input_report_abs(dev, ABS_HAT0X,
514 !!(data[5] & 0x08) - !!(data[5] & 0x04));
515 input_report_abs(dev, ABS_HAT0Y,
516 !!(data[5] & 0x02) - !!(data[5] & 0x01));
517 }
518
519 /* TL/TR */
520 input_report_key(dev, BTN_TL, data[5] & 0x10);
521 input_report_key(dev, BTN_TR, data[5] & 0x20);
522
523 /* stick press left/right */
524 input_report_key(dev, BTN_THUMBL, data[5] & 0x40);
525 input_report_key(dev, BTN_THUMBR, data[5] & 0x80);
526
527 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
528 /* left stick */
529 input_report_abs(dev, ABS_X,
530 (__s16) le16_to_cpup((__le16 *)(data + 10)));
531 input_report_abs(dev, ABS_Y,
532 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
533
534 /* right stick */
535 input_report_abs(dev, ABS_RX,
536 (__s16) le16_to_cpup((__le16 *)(data + 14)));
537 input_report_abs(dev, ABS_RY,
538 ~(__s16) le16_to_cpup((__le16 *)(data + 16)));
539 }
540
541 /* triggers left/right */
542 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
543 input_report_key(dev, BTN_TL2,
544 (__u16) le16_to_cpup((__le16 *)(data + 6)));
545 input_report_key(dev, BTN_TR2,
546 (__u16) le16_to_cpup((__le16 *)(data + 8)));
547 } else {
548 input_report_abs(dev, ABS_Z,
549 (__u16) le16_to_cpup((__le16 *)(data + 6)));
550 input_report_abs(dev, ABS_RZ,
551 (__u16) le16_to_cpup((__le16 *)(data + 8)));
552 }
553
554 input_sync(dev);
555}
556
557/*
558 * xpadone_process_packet
559 *
560 * Completes a request by converting the data into events for the
561 * input subsystem. This version is for the Xbox One controller.
562 *
563 * The report format was gleaned from
564 * https://github.com/kylelemons/xbox/blob/master/xbox.go
565 */
566
567static void xpadone_process_packet(struct usb_xpad *xpad,
568 u16 cmd, unsigned char *data)
569{
570 struct input_dev *dev = xpad->dev;
571
572 switch (data[0]) {
573 case 0x20:
574 xpadone_process_buttons(xpad, dev, data);
575 break;
576
577 case 0x07:
578 /* the xbox button has its own special report */
579 input_report_key(dev, BTN_MODE, data[4] & 0x01);
580 input_sync(dev);
581 break;
582 }
583}
584
473static void xpad_irq_in(struct urb *urb) 585static void xpad_irq_in(struct urb *urb)
474{ 586{
475 struct usb_xpad *xpad = urb->context; 587 struct usb_xpad *xpad = urb->context;
@@ -502,6 +614,9 @@ static void xpad_irq_in(struct urb *urb)
502 case XTYPE_XBOX360W: 614 case XTYPE_XBOX360W:
503 xpad360w_process_packet(xpad, 0, xpad->idata); 615 xpad360w_process_packet(xpad, 0, xpad->idata);
504 break; 616 break;
617 case XTYPE_XBOXONE:
618 xpadone_process_packet(xpad, 0, xpad->idata);
619 break;
505 default: 620 default:
506 xpad_process_packet(xpad, 0, xpad->idata); 621 xpad_process_packet(xpad, 0, xpad->idata);
507 } 622 }
@@ -535,7 +650,6 @@ static void xpad_bulk_out(struct urb *urb)
535 } 650 }
536} 651}
537 652
538#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
539static void xpad_irq_out(struct urb *urb) 653static void xpad_irq_out(struct urb *urb)
540{ 654{
541 struct usb_xpad *xpad = urb->context; 655 struct usb_xpad *xpad = urb->context;
@@ -573,6 +687,7 @@ exit:
573static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) 687static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
574{ 688{
575 struct usb_endpoint_descriptor *ep_irq_out; 689 struct usb_endpoint_descriptor *ep_irq_out;
690 int ep_irq_out_idx;
576 int error; 691 int error;
577 692
578 if (xpad->xtype == XTYPE_UNKNOWN) 693 if (xpad->xtype == XTYPE_UNKNOWN)
@@ -593,7 +708,10 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
593 goto fail2; 708 goto fail2;
594 } 709 }
595 710
596 ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; 711 /* Xbox One controller has in/out endpoints swapped. */
712 ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
713 ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
714
597 usb_fill_int_urb(xpad->irq_out, xpad->udev, 715 usb_fill_int_urb(xpad->irq_out, xpad->udev,
598 usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), 716 usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
599 xpad->odata, XPAD_PKT_LEN, 717 xpad->odata, XPAD_PKT_LEN,
@@ -621,11 +739,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
621 xpad->odata, xpad->odata_dma); 739 xpad->odata, xpad->odata_dma);
622 } 740 }
623} 741}
624#else
625static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
626static void xpad_deinit_output(struct usb_xpad *xpad) {}
627static void xpad_stop_output(struct usb_xpad *xpad) {}
628#endif
629 742
630#ifdef CONFIG_JOYSTICK_XPAD_FF 743#ifdef CONFIG_JOYSTICK_XPAD_FF
631static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) 744static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
@@ -692,7 +805,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
692 805
693static int xpad_init_ff(struct usb_xpad *xpad) 806static int xpad_init_ff(struct usb_xpad *xpad)
694{ 807{
695 if (xpad->xtype == XTYPE_UNKNOWN) 808 if (xpad->xtype == XTYPE_UNKNOWN || xpad->xtype == XTYPE_XBOXONE)
696 return 0; 809 return 0;
697 810
698 input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); 811 input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
@@ -801,6 +914,14 @@ static int xpad_open(struct input_dev *dev)
801 if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) 914 if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
802 return -EIO; 915 return -EIO;
803 916
917 if (xpad->xtype == XTYPE_XBOXONE) {
918 /* Xbox one controller needs to be initialized. */
919 xpad->odata[0] = 0x05;
920 xpad->odata[1] = 0x20;
921 xpad->irq_out->transfer_buffer_length = 2;
922 return usb_submit_urb(xpad->irq_out, GFP_KERNEL);
923 }
924
804 return 0; 925 return 0;
805} 926}
806 927
@@ -816,6 +937,7 @@ static void xpad_close(struct input_dev *dev)
816 937
817static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) 938static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
818{ 939{
940 struct usb_xpad *xpad = input_get_drvdata(input_dev);
819 set_bit(abs, input_dev->absbit); 941 set_bit(abs, input_dev->absbit);
820 942
821 switch (abs) { 943 switch (abs) {
@@ -827,7 +949,10 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
827 break; 949 break;
828 case ABS_Z: 950 case ABS_Z:
829 case ABS_RZ: /* the triggers (if mapped to axes) */ 951 case ABS_RZ: /* the triggers (if mapped to axes) */
830 input_set_abs_params(input_dev, abs, 0, 255, 0, 0); 952 if (xpad->xtype == XTYPE_XBOXONE)
953 input_set_abs_params(input_dev, abs, 0, 1023, 0, 0);
954 else
955 input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
831 break; 956 break;
832 case ABS_HAT0X: 957 case ABS_HAT0X:
833 case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ 958 case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */
@@ -842,6 +967,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
842 struct usb_xpad *xpad; 967 struct usb_xpad *xpad;
843 struct input_dev *input_dev; 968 struct input_dev *input_dev;
844 struct usb_endpoint_descriptor *ep_irq_in; 969 struct usb_endpoint_descriptor *ep_irq_in;
970 int ep_irq_in_idx;
845 int i, error; 971 int i, error;
846 972
847 for (i = 0; xpad_device[i].idVendor; i++) { 973 for (i = 0; xpad_device[i].idVendor; i++) {
@@ -850,6 +976,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
850 break; 976 break;
851 } 977 }
852 978
979 if (xpad_device[i].xtype == XTYPE_XBOXONE &&
980 intf->cur_altsetting->desc.bInterfaceNumber != 0) {
981 /*
982 * The Xbox One controller lists three interfaces all with the
983 * same interface class, subclass and protocol. Differentiate by
984 * interface number.
985 */
986 return -ENODEV;
987 }
988
853 xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); 989 xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
854 input_dev = input_allocate_device(); 990 input_dev = input_allocate_device();
855 if (!xpad || !input_dev) { 991 if (!xpad || !input_dev) {
@@ -920,7 +1056,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
920 __set_bit(xpad_common_btn[i], input_dev->keybit); 1056 __set_bit(xpad_common_btn[i], input_dev->keybit);
921 1057
922 /* set up model-specific ones */ 1058 /* set up model-specific ones */
923 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { 1059 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
1060 xpad->xtype == XTYPE_XBOXONE) {
924 for (i = 0; xpad360_btn[i] >= 0; i++) 1061 for (i = 0; xpad360_btn[i] >= 0; i++)
925 __set_bit(xpad360_btn[i], input_dev->keybit); 1062 __set_bit(xpad360_btn[i], input_dev->keybit);
926 } else { 1063 } else {
@@ -933,7 +1070,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
933 __set_bit(xpad_btn_pad[i], input_dev->keybit); 1070 __set_bit(xpad_btn_pad[i], input_dev->keybit);
934 } else { 1071 } else {
935 for (i = 0; xpad_abs_pad[i] >= 0; i++) 1072 for (i = 0; xpad_abs_pad[i] >= 0; i++)
936 xpad_set_up_abs(input_dev, xpad_abs_pad[i]); 1073 xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
937 } 1074 }
938 1075
939 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 1076 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -956,7 +1093,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
956 if (error) 1093 if (error)
957 goto fail5; 1094 goto fail5;
958 1095
959 ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; 1096 /* Xbox One controller has in/out endpoints swapped. */
1097 ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
1098 ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
1099
960 usb_fill_int_urb(xpad->irq_in, udev, 1100 usb_fill_int_urb(xpad->irq_in, udev,
961 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), 1101 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
962 xpad->idata, XPAD_PKT_LEN, xpad_irq_in, 1102 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,