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
@@ -304,6 +311,7 @@ static const struct xpad_device {
304311 { 0x12ab , 0x0301 , "PDP AFTERGLOW AX.1" , 0 , XTYPE_XBOX360 },
305312 { 0x12ab , 0x0303 , "Mortal Kombat Klassic FightStick" , MAP_TRIGGERS_TO_BUTTONS , XTYPE_XBOX360 },
306313 { 0x12ab , 0x8809 , "Xbox DDR dancepad" , MAP_DPAD_TO_BUTTONS , XTYPE_XBOX },
314+ { 0x1430 , 0x079B , "RedOctane GHL Controller" , 0 , XTYPE_XBOXONE , QUIRK_GHL_XBOXONE },
307315 { 0x1430 , 0x4748 , "RedOctane Guitar Hero X-plorer" , 0 , XTYPE_XBOX360 },
308316 { 0x1430 , 0x8888 , "TX6500+ Dance Pad (first generation)" , MAP_DPAD_TO_BUTTONS , XTYPE_XBOX },
309317 { 0x1430 , 0xf801 , "RedOctane Controller" , 0 , XTYPE_XBOX360 },
@@ -472,6 +480,12 @@ static const signed short xpad_btn_paddles[] = {
472480 -1 /* terminating entry */
473481};
474482
483+ /* used for GHL dpad mapping */
484+ static const struct {int x ; int y ; } dpad_mapping [] = {
485+ {0 , -1 }, {1 , -1 }, {1 , 0 }, {1 , 1 }, {0 , 1 }, {-1 , 1 }, {-1 , 0 }, {-1 , -1 },
486+ {0 , 0 }
487+ };
488+
475489/*
476490 * Xbox 360 has a vendor-specific class, so we cannot match it with only
477491 * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
@@ -533,6 +547,7 @@ static const struct usb_device_id xpad_table[] = {
533547 XPAD_XBOX360_VENDOR (0x1209 ), /* Ardwiino Controllers */
534548 XPAD_XBOX360_VENDOR (0x12ab ), /* Xbox 360 dance pads */
535549 XPAD_XBOX360_VENDOR (0x1430 ), /* RedOctane Xbox 360 controllers */
550+ XPAD_XBOXONE_VENDOR (0x1430 ), /* RedOctane X-Box One controllers */
536551 XPAD_XBOX360_VENDOR (0x146b ), /* Bigben Interactive controllers */
537552 XPAD_XBOX360_VENDOR (0x1532 ), /* Razer Sabertooth */
538553 XPAD_XBOXONE_VENDOR (0x1532 ), /* Razer Wildcat */
@@ -701,6 +716,11 @@ static const u8 xboxone_rumbleend_init[] = {
701716 0x00 , GIP_MOTOR_ALL , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
702717};
703718
719+ /* GHL Xbox One magic data */
720+ static const char ghl_xboxone_magic_data [] = {
721+ 0x22 , 0x00 , 0x00 , 0x08 , 0x02 , 0x08 , 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
722+ };
723+
704724/*
705725 * This specifies the selection of init packets that a gamepad
706726 * will be sent on init *and* the order in which they will be
@@ -710,13 +730,16 @@ static const u8 xboxone_rumbleend_init[] = {
710730static const struct xboxone_init_packet xboxone_init_packets [] = {
711731 XBOXONE_INIT_PKT (0x0e6f , 0x0165 , xboxone_hori_ack_id ),
712732 XBOXONE_INIT_PKT (0x0f0d , 0x0067 , xboxone_hori_ack_id ),
733+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_hori_ack_id ),
713734 XBOXONE_INIT_PKT (0x0000 , 0x0000 , xboxone_power_on ),
714735 XBOXONE_INIT_PKT (0x045e , 0x02ea , xboxone_s_init ),
715736 XBOXONE_INIT_PKT (0x045e , 0x0b00 , xboxone_s_init ),
716737 XBOXONE_INIT_PKT (0x045e , 0x0b00 , extra_input_packet_init ),
717738 XBOXONE_INIT_PKT (0x0e6f , 0x0000 , xboxone_pdp_led_on ),
739+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_pdp_led_on ),
718740 XBOXONE_INIT_PKT (0x20d6 , 0xa01a , xboxone_pdp_led_on ),
719741 XBOXONE_INIT_PKT (0x0e6f , 0x0000 , xboxone_pdp_auth ),
742+ XBOXONE_INIT_PKT (0x1430 , 0x079b , xboxone_pdp_auth ),
720743 XBOXONE_INIT_PKT (0x20d6 , 0xa01a , xboxone_pdp_auth ),
721744 XBOXONE_INIT_PKT (0x24c6 , 0x541a , xboxone_rumblebegin_init ),
722745 XBOXONE_INIT_PKT (0x24c6 , 0x542a , xboxone_rumblebegin_init ),
@@ -779,13 +802,72 @@ struct usb_xpad {
779802 struct work_struct work ; /* init/remove device from callback */
780803 struct delayed_work poweroff_work ; /* work struct for poweroff on mode long press */
781804 time64_t mode_btn_down_ts ;
805+ struct urb * ghl_urb ; /* URB for GHL Xbox One magic data */
806+ struct timer_list ghl_poke_timer ; /* Timer for periodic poke of GHL magic data */
782807};
783808
784809static int xpad_init_input (struct usb_xpad * xpad );
785810static void xpad_deinit_input (struct usb_xpad * xpad );
786811static void xpadone_ack_mode_report (struct usb_xpad * xpad , u8 seq_num );
787812static void xpad360w_poweroff_controller (struct usb_xpad * xpad );
788813
814+ /*
815+ * ghl_magic_poke_cb
816+ *
817+ * Call back function that resets the timer for the next magic data poke.
818+ */
819+ static void ghl_magic_poke_cb (struct urb * urb )
820+ {
821+ struct usb_xpad * xpad = urb -> context ;
822+
823+ if (urb -> status < 0 )
824+ pr_warn ("URB transfer failed.\n" );
825+
826+ mod_timer (& xpad -> ghl_poke_timer , jiffies + GHL_GUITAR_POKE_INTERVAL * HZ );
827+ }
828+
829+ /*
830+ * ghl_magic_poke
831+ *
832+ * Submits the GHL magic_data URB.
833+ */
834+ static void ghl_magic_poke (struct timer_list * t )
835+ {
836+ int ret ;
837+ struct usb_xpad * xpad = from_timer (xpad , t , ghl_poke_timer );
838+
839+ ret = usb_submit_urb (xpad -> ghl_urb , GFP_ATOMIC );
840+ if (ret < 0 )
841+ pr_warn ("URB transfer failed.\n" );
842+ }
843+
844+ /*
845+ * ghl_init_urb
846+ *
847+ * Prepares the interrupt URB for GHL magic_data.
848+ */
849+ static int ghl_init_urb (struct usb_xpad * xpad , struct usb_device * usbdev ,
850+ const char ghl_magic_data [], u16 poke_size , struct usb_endpoint_descriptor * ep_irq_out )
851+ {
852+ u8 * databuf ;
853+ unsigned int pipe ;
854+
855+ pipe = usb_sndintpipe (usbdev , ep_irq_out -> bEndpointAddress );
856+
857+ databuf = devm_kzalloc (& xpad -> udev -> dev , poke_size , GFP_ATOMIC );
858+ if (databuf == NULL )
859+ return - ENOMEM ;
860+
861+ memcpy (databuf , ghl_magic_data , poke_size );
862+
863+ usb_fill_int_urb (
864+ xpad -> ghl_urb , usbdev , pipe ,
865+ databuf , poke_size ,
866+ ghl_magic_poke_cb , xpad , ep_irq_out -> bInterval );
867+
868+ return 0 ;
869+ }
870+
789871/*
790872 * xpad_process_packet
791873 *
@@ -1043,6 +1125,7 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
10431125{
10441126 struct input_dev * dev = xpad -> dev ;
10451127 bool do_sync = false;
1128+ int dpad_value ;
10461129
10471130 /* the xbox button has its own special report */
10481131 if (data [0 ] == GIP_CMD_VIRTUAL_KEY ) {
@@ -1189,6 +1272,48 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
11891272 }
11901273 }
11911274
1275+ do_sync = true;
1276+
1277+ } else if (data [0 ] == 0X21 ) { /* The main valid packet type for GHL inputs */
1278+ /* Mapping chosen to be coherent with GHL dongles of other consoles */
1279+
1280+ /* The 6 fret buttons */
1281+ input_report_key (dev , BTN_B , data [4 ] & BIT (1 ));
1282+ input_report_key (dev , BTN_X , data [4 ] & BIT (2 ));
1283+ input_report_key (dev , BTN_Y , data [4 ] & BIT (3 ));
1284+ input_report_key (dev , BTN_A , data [4 ] & BIT (0 ));
1285+ input_report_key (dev , BTN_TL , data [4 ] & BIT (4 ));
1286+ input_report_key (dev , BTN_TR , data [4 ] & BIT (5 ));
1287+
1288+ /* D-pad */
1289+ dpad_value = data [6 ] & 0xF ;
1290+ if (dpad_value > 7 )
1291+ dpad_value = 8 ;
1292+
1293+ input_report_abs (dev , ABS_HAT0X , dpad_mapping [dpad_value ].x );
1294+ input_report_abs (dev , ABS_HAT0Y , dpad_mapping [dpad_value ].y );
1295+
1296+ /* Strum bar */
1297+ input_report_abs (dev , ABS_Y , ((data [8 ] - 0x80 ) << 9 ));
1298+
1299+ /* Tilt Sensor */
1300+ input_report_abs (dev , ABS_Z , ((data [9 ] - 0x80 ) << 9 ));
1301+
1302+ /* Whammy bar */
1303+ input_report_abs (dev , ABS_RZ , ((data [10 ] - 0x80 ) << 9 ));
1304+
1305+ /* Power Button */
1306+ input_report_key (dev , BTN_THUMBR , data [5 ] & BIT (4 ));
1307+
1308+ /* GHTV button */
1309+ input_report_key (dev , BTN_START , data [5 ] & BIT (2 ));
1310+
1311+ /* Hero Power button */
1312+ input_report_key (dev , BTN_MODE , data [5 ] & BIT (0 ));
1313+
1314+ /* Pause button */
1315+ input_report_key (dev , BTN_THUMBL , data [5 ] & BIT (1 ));
1316+
11921317 do_sync = true;
11931318 }
11941319
@@ -2018,15 +2143,29 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
20182143 switch (abs ) {
20192144 case ABS_X :
20202145 case ABS_Y :
2146+ /* GHL Strum bar */
2147+ if ((xpad -> xtype == XTYPE_XBOXONE ) && (xpad -> quirks & QUIRK_GHL_XBOXONE )) {
2148+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2149+ break ;
2150+ }
20212151 case ABS_RX :
20222152 case ABS_RY : /* the two sticks */
20232153 input_set_abs_params (input_dev , abs , -32768 , 32767 , 16 , 128 );
20242154 break ;
20252155 case ABS_Z :
2156+ /* GHL Tilt sensor */
2157+ if ((xpad -> xtype == XTYPE_XBOXONE ) && (xpad -> quirks & QUIRK_GHL_XBOXONE )) {
2158+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2159+ break ;
2160+ }
20262161 case ABS_RZ : /* the triggers (if mapped to axes) */
2027- if (xpad -> xtype == XTYPE_XBOXONE )
2028- input_set_abs_params (input_dev , abs , 0 , 1023 , 0 , 0 );
2029- else
2162+ if (xpad -> xtype == XTYPE_XBOXONE ) {
2163+ /* GHL Whammy bar */
2164+ if (xpad -> quirks & QUIRK_GHL_XBOXONE )
2165+ input_set_abs_params (input_dev , abs , -32767 , 32767 , 0 , 0 );
2166+ else
2167+ input_set_abs_params (input_dev , abs , 0 , 1023 , 0 , 0 );
2168+ } else
20302169 input_set_abs_params (input_dev , abs , 0 , 255 , 0 , 0 );
20312170 break ;
20322171 case ABS_HAT0X :
@@ -2326,6 +2465,21 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
23262465 if (error )
23272466 goto err_deinit_output ;
23282467 }
2468+
2469+ if (xpad -> quirks & QUIRK_GHL_XBOXONE ) {
2470+
2471+ xpad -> ghl_urb = usb_alloc_urb (0 , GFP_ATOMIC );
2472+ if (!xpad -> ghl_urb )
2473+ return - ENOMEM ;
2474+
2475+ error = ghl_init_urb (xpad , udev , ghl_xboxone_magic_data , ARRAY_SIZE (ghl_xboxone_magic_data ), ep_irq_out );
2476+
2477+ if (error )
2478+ return error ;
2479+
2480+ timer_setup (& xpad -> ghl_poke_timer , ghl_magic_poke , 0 );
2481+ mod_timer (& xpad -> ghl_poke_timer , jiffies + GHL_GUITAR_POKE_INTERVAL * HZ );
2482+ }
23292483 return 0 ;
23302484
23312485err_deinit_output :
@@ -2357,6 +2511,12 @@ static void xpad_disconnect(struct usb_interface *intf)
23572511 xpad_deinit_output (xpad );
23582512
23592513 usb_free_urb (xpad -> irq_in );
2514+
2515+ if (xpad -> quirks & QUIRK_GHL_XBOXONE ) {
2516+ usb_free_urb (xpad -> ghl_urb );
2517+ del_timer_sync (& xpad -> ghl_poke_timer );
2518+ }
2519+
23602520 usb_free_coherent (xpad -> udev , XPAD_PKT_LEN ,
23612521 xpad -> idata , xpad -> idata_dma );
23622522
0 commit comments