7171#include <linux/module.h>
7272#include <linux/usb/input.h>
7373#include <linux/usb/quirks.h>
74+ #include <linux/timer.h>
7475
7576#define XPAD_PKT_LEN 64
7677
78+ /* The Guitar Hero Live (GHL) Xbox One dongles require a poke
79+ * every 8 seconds.
80+ */
81+ #define GHL_GUITAR_POKE_INTERVAL 8 /* In seconds */
82+
7783/*
7884 * xbox d-pads should map to buttons, as is required for DDR pads
7985 * but we map them to axes when possible to simplify things
108114#define QUIRK_360_START_PKT_1 (1 << 0)
109115#define QUIRK_360_START_PKT_2 (1 << 1)
110116#define QUIRK_360_START_PKT_3 (1 << 2)
117+ #define QUIRK_GHL_XBOXONE (1 << 3)
111118#define QUIRK_360_START (QUIRK_360_START_PKT_1 | \
112119 QUIRK_360_START_PKT_2 | QUIRK_360_START_PKT_3)
113120
@@ -300,6 +307,7 @@ static const struct xpad_device {
300307 { 0x12ab , 0x0301 , "PDP AFTERGLOW AX.1" , 0 , XTYPE_XBOX360 },
301308 { 0x12ab , 0x0303 , "Mortal Kombat Klassic FightStick" , MAP_TRIGGERS_TO_BUTTONS , XTYPE_XBOX360 },
302309 { 0x12ab , 0x8809 , "Xbox DDR dancepad" , MAP_DPAD_TO_BUTTONS , XTYPE_XBOX },
310+ { 0x1430 , 0x079B , "RedOctane GHL Controller" , 0 , XTYPE_XBOXONE , QUIRK_GHL_XBOXONE },
303311 { 0x1430 , 0x4748 , "RedOctane Guitar Hero X-plorer" , 0 , XTYPE_XBOX360 },
304312 { 0x1430 , 0x8888 , "TX6500+ Dance Pad (first generation)" , MAP_DPAD_TO_BUTTONS , XTYPE_XBOX },
305313 { 0x1430 , 0xf801 , "RedOctane Controller" , 0 , XTYPE_XBOX360 },
@@ -465,6 +473,12 @@ static const signed short xpad_btn_paddles[] = {
465473 -1 /* terminating entry */
466474};
467475
476+ /* used for GHL dpad mapping */
477+ static const struct {int x ; int y ; } dpad_mapping [] = {
478+ {0 , -1 }, {1 , -1 }, {1 , 0 }, {1 , 1 }, {0 , 1 }, {-1 , 1 }, {-1 , 0 }, {-1 , -1 },
479+ {0 , 0 }
480+ };
481+
468482/*
469483 * Xbox 360 has a vendor-specific class, so we cannot match it with only
470484 * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
@@ -524,6 +538,7 @@ static const struct usb_device_id xpad_table[] = {
524538 XPAD_XBOX360_VENDOR (0x1209 ), /* Ardwiino Controllers */
525539 XPAD_XBOX360_VENDOR (0x12ab ), /* Xbox 360 dance pads */
526540 XPAD_XBOX360_VENDOR (0x1430 ), /* RedOctane Xbox 360 controllers */
541+ XPAD_XBOXONE_VENDOR (0x1430 ), /* RedOctane X-Box One controllers */
527542 XPAD_XBOX360_VENDOR (0x146b ), /* Bigben Interactive controllers */
528543 XPAD_XBOX360_VENDOR (0x1532 ), /* Razer Sabertooth */
529544 XPAD_XBOXONE_VENDOR (0x1532 ), /* Razer Wildcat */
@@ -690,6 +705,11 @@ static const u8 xboxone_rumbleend_init[] = {
690705 0x00 , GIP_MOTOR_ALL , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
691706};
692707
708+ /* GHL Xbox One magic data */
709+ static const char ghl_xboxone_magic_data [] = {
710+ 0x22 , 0x00 , 0x00 , 0x08 , 0x02 , 0x08 , 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
711+ };
712+
693713/*
694714 * This specifies the selection of init packets that a gamepad
695715 * will be sent on init *and* the order in which they will be
@@ -699,13 +719,16 @@ static const u8 xboxone_rumbleend_init[] = {
699719static const struct xboxone_init_packet xboxone_init_packets [] = {
700720 XBOXONE_INIT_PKT (0x0e6f , 0x0165 , xboxone_hori_ack_id ),
701721 XBOXONE_INIT_PKT (0x0f0d , 0x0067 , xboxone_hori_ack_id ),
722+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_hori_ack_id ),
702723 XBOXONE_INIT_PKT (0x0000 , 0x0000 , xboxone_power_on ),
703724 XBOXONE_INIT_PKT (0x045e , 0x02ea , xboxone_s_init ),
704725 XBOXONE_INIT_PKT (0x045e , 0x0b00 , xboxone_s_init ),
705726 XBOXONE_INIT_PKT (0x045e , 0x0b00 , extra_input_packet_init ),
706727 XBOXONE_INIT_PKT (0x0e6f , 0x0000 , xboxone_pdp_led_on ),
728+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_pdp_led_on ),
707729 XBOXONE_INIT_PKT (0x20d6 , 0xa01a , xboxone_pdp_led_on ),
708730 XBOXONE_INIT_PKT (0x0e6f , 0x0000 , xboxone_pdp_auth ),
731+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_pdp_auth ),
709732 XBOXONE_INIT_PKT (0x20d6 , 0xa01a , xboxone_pdp_auth ),
710733 XBOXONE_INIT_PKT (0x24c6 , 0x541a , xboxone_rumblebegin_init ),
711734 XBOXONE_INIT_PKT (0x24c6 , 0x542a , xboxone_rumblebegin_init ),
@@ -768,13 +791,72 @@ struct usb_xpad {
768791 struct work_struct work ; /* init/remove device from callback */
769792 struct delayed_work poweroff_work ; /* work struct for poweroff on mode long press */
770793 time64_t mode_btn_down_ts ;
794+ struct urb * ghl_urb ; /* URB for GHL Xbox One magic data */
795+ struct timer_list ghl_poke_timer ; /* Timer for periodic poke of GHL magic data */
771796};
772797
773798static int xpad_init_input (struct usb_xpad * xpad );
774799static void xpad_deinit_input (struct usb_xpad * xpad );
775800static void xpadone_ack_mode_report (struct usb_xpad * xpad , u8 seq_num );
776801static void xpad360w_poweroff_controller (struct usb_xpad * xpad );
777802
803+ /*
804+ * ghl_magic_poke_cb
805+ *
806+ * Call back function that resets the timer for the next magic data poke.
807+ */
808+ static void ghl_magic_poke_cb (struct urb * urb )
809+ {
810+ struct usb_xpad * xpad = urb -> context ;
811+
812+ if (urb -> status < 0 )
813+ pr_warn ("URB transfer failed.\n" );
814+
815+ mod_timer (& xpad -> ghl_poke_timer , jiffies + GHL_GUITAR_POKE_INTERVAL * HZ );
816+ }
817+
818+ /*
819+ * ghl_magic_poke
820+ *
821+ * Submits the GHL magic_data URB.
822+ */
823+ static void ghl_magic_poke (struct timer_list * t )
824+ {
825+ int ret ;
826+ struct usb_xpad * xpad = from_timer (xpad , t , ghl_poke_timer );
827+
828+ ret = usb_submit_urb (xpad -> ghl_urb , GFP_ATOMIC );
829+ if (ret < 0 )
830+ pr_warn ("URB transfer failed.\n" );
831+ }
832+
833+ /*
834+ * ghl_init_urb
835+ *
836+ * Prepares the interrupt URB for GHL magic_data.
837+ */
838+ static int ghl_init_urb (struct usb_xpad * xpad , struct usb_device * usbdev ,
839+ const char ghl_magic_data [], u16 poke_size , struct usb_endpoint_descriptor * ep_irq_out )
840+ {
841+ u8 * databuf ;
842+ unsigned int pipe ;
843+
844+ pipe = usb_sndintpipe (usbdev , ep_irq_out -> bEndpointAddress );
845+
846+ databuf = devm_kzalloc (& xpad -> udev -> dev , poke_size , GFP_ATOMIC );
847+ if (databuf == NULL )
848+ return - ENOMEM ;
849+
850+ memcpy (databuf , ghl_magic_data , poke_size );
851+
852+ usb_fill_int_urb (
853+ xpad -> ghl_urb , usbdev , pipe ,
854+ databuf , poke_size ,
855+ ghl_magic_poke_cb , xpad , ep_irq_out -> bInterval );
856+
857+ return 0 ;
858+ }
859+
778860/*
779861 * xpad_process_packet
780862 *
@@ -1032,6 +1114,7 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
10321114{
10331115 struct input_dev * dev = xpad -> dev ;
10341116 bool do_sync = false;
1117+ int dpad_value ;
10351118
10361119 /* the xbox button has its own special report */
10371120 if (data [0 ] == GIP_CMD_VIRTUAL_KEY ) {
@@ -1178,6 +1261,48 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
11781261 }
11791262 }
11801263
1264+ do_sync = true;
1265+
1266+ } else if (data [0 ] == 0X21 ) { /* The main valid packet type for GHL inputs */
1267+ /* Mapping chosen to be coherent with GHL dongles of other consoles */
1268+
1269+ /* The 6 fret buttons */
1270+ input_report_key (dev , BTN_B , data [4 ] & BIT (1 ));
1271+ input_report_key (dev , BTN_X , data [4 ] & BIT (2 ));
1272+ input_report_key (dev , BTN_Y , data [4 ] & BIT (3 ));
1273+ input_report_key (dev , BTN_A , data [4 ] & BIT (0 ));
1274+ input_report_key (dev , BTN_TL , data [4 ] & BIT (4 ));
1275+ input_report_key (dev , BTN_TR , data [4 ] & BIT (5 ));
1276+
1277+ /* D-pad */
1278+ dpad_value = data [6 ] & 0xF ;
1279+ if (dpad_value > 7 )
1280+ dpad_value = 8 ;
1281+
1282+ input_report_abs (dev , ABS_HAT0X , dpad_mapping [dpad_value ].x );
1283+ input_report_abs (dev , ABS_HAT0Y , dpad_mapping [dpad_value ].y );
1284+
1285+ /* Strum bar */
1286+ input_report_abs (dev , ABS_Y , ((data [8 ] - 0x80 ) << 9 ));
1287+
1288+ /* Tilt Sensor */
1289+ input_report_abs (dev , ABS_Z , ((data [9 ] - 0x80 ) << 9 ));
1290+
1291+ /* Whammy bar */
1292+ input_report_abs (dev , ABS_RZ , ((data [10 ] - 0x80 ) << 9 ));
1293+
1294+ /* Power Button */
1295+ input_report_key (dev , BTN_THUMBR , data [5 ] & BIT (4 ));
1296+
1297+ /* GHTV button */
1298+ input_report_key (dev , BTN_START , data [5 ] & BIT (2 ));
1299+
1300+ /* Hero Power button */
1301+ input_report_key (dev , BTN_MODE , data [5 ] & BIT (0 ));
1302+
1303+ /* Pause button */
1304+ input_report_key (dev , BTN_THUMBL , data [5 ] & BIT (1 ));
1305+
11811306 do_sync = true;
11821307 }
11831308
@@ -2007,15 +2132,29 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
20072132 switch (abs ) {
20082133 case ABS_X :
20092134 case ABS_Y :
2135+ /* GHL Strum bar */
2136+ if ((xpad -> xtype == XTYPE_XBOXONE ) && (xpad -> quirks & QUIRK_GHL_XBOXONE )) {
2137+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2138+ break ;
2139+ }
20102140 case ABS_RX :
20112141 case ABS_RY : /* the two sticks */
20122142 input_set_abs_params (input_dev , abs , -32768 , 32767 , 16 , 128 );
20132143 break ;
20142144 case ABS_Z :
2145+ /* GHL Tilt sensor */
2146+ if ((xpad -> xtype == XTYPE_XBOXONE ) && (xpad -> quirks & QUIRK_GHL_XBOXONE )) {
2147+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2148+ break ;
2149+ }
20152150 case ABS_RZ : /* the triggers (if mapped to axes) */
2016- if (xpad -> xtype == XTYPE_XBOXONE )
2017- input_set_abs_params (input_dev , abs , 0 , 1023 , 0 , 0 );
2018- else
2151+ if (xpad -> xtype == XTYPE_XBOXONE ) {
2152+ /* GHL Whammy bar */
2153+ if (xpad -> quirks & QUIRK_GHL_XBOXONE )
2154+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2155+ else
2156+ input_set_abs_params (input_dev , abs , 0 , 1023 , 0 , 0 );
2157+ } else
20192158 input_set_abs_params (input_dev , abs , 0 , 255 , 0 , 0 );
20202159 break ;
20212160 case ABS_HAT0X :
@@ -2315,6 +2454,21 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
23152454 if (error )
23162455 goto err_deinit_output ;
23172456 }
2457+
2458+ if (xpad -> quirks & QUIRK_GHL_XBOXONE ) {
2459+
2460+ xpad -> ghl_urb = usb_alloc_urb (0 , GFP_ATOMIC );
2461+ if (!xpad -> ghl_urb )
2462+ return - ENOMEM ;
2463+
2464+ error = ghl_init_urb (xpad , udev , ghl_xboxone_magic_data , ARRAY_SIZE (ghl_xboxone_magic_data ), ep_irq_out );
2465+
2466+ if (error )
2467+ return error ;
2468+
2469+ timer_setup (& xpad -> ghl_poke_timer , ghl_magic_poke , 0 );
2470+ mod_timer (& xpad -> ghl_poke_timer , jiffies + GHL_GUITAR_POKE_INTERVAL * HZ );
2471+ }
23182472 return 0 ;
23192473
23202474err_deinit_output :
@@ -2346,6 +2500,12 @@ static void xpad_disconnect(struct usb_interface *intf)
23462500 xpad_deinit_output (xpad );
23472501
23482502 usb_free_urb (xpad -> irq_in );
2503+
2504+ if (xpad -> quirks & QUIRK_GHL_XBOXONE ) {
2505+ usb_free_urb (xpad -> ghl_urb );
2506+ del_timer_sync (& xpad -> ghl_poke_timer );
2507+ }
2508+
23492509 usb_free_coherent (xpad -> udev , XPAD_PKT_LEN ,
23502510 xpad -> idata , xpad -> idata_dma );
23512511
0 commit comments