105105#define PKT_XBE2_FW_5_EARLY 3
106106#define PKT_XBE2_FW_5_11 4
107107
108+ #define QUIRK_360_START_PKT_1 (1 << 0)
109+ #define QUIRK_360_START_PKT_2 (1 << 1)
110+ #define QUIRK_360_START_PKT_3 (1 << 2)
111+ #define QUIRK_360_START (QUIRK_360_START_PKT_1 | \
112+ QUIRK_360_START_PKT_2 | QUIRK_360_START_PKT_3)
113+
108114static bool dpad_to_buttons ;
109115module_param (dpad_to_buttons , bool , S_IRUGO );
110116MODULE_PARM_DESC (dpad_to_buttons , "Map D-PAD to buttons rather than axes for unknown pads" );
@@ -127,6 +133,7 @@ static const struct xpad_device {
127133 char * name ;
128134 u8 mapping ;
129135 u8 xtype ;
136+ u8 quirks ;
130137} xpad_device [] = {
131138 /* Please keep this list sorted by vendor and product ID. */
132139 { 0x0079 , 0x18d4 , "GPD Win 2 X-Box Controller" , 0 , XTYPE_XBOX360 },
@@ -168,6 +175,7 @@ static const struct xpad_device {
168175 { 0x046d , 0xca8a , "Logitech Precision Vibration Feedback Wheel" , 0 , XTYPE_XBOX },
169176 { 0x046d , 0xcaa3 , "Logitech DriveFx Racing Wheel" , 0 , XTYPE_XBOX360 },
170177 { 0x056e , 0x2004 , "Elecom JC-U3613M" , 0 , XTYPE_XBOX360 },
178+ { 0x05ac , 0x055b , "Gamesir-G3w" , 0 , XTYPE_XBOX360 , QUIRK_360_START },
171179 { 0x05fd , 0x1007 , "Mad Catz Controller (unverified)" , 0 , XTYPE_XBOX },
172180 { 0x05fd , 0x107a , "InterAct 'PowerPad Pro' X-Box pad (Germany)" , 0 , XTYPE_XBOX },
173181 { 0x05fe , 0x3030 , "Chic Controller" , 0 , XTYPE_XBOX },
@@ -755,6 +763,7 @@ struct usb_xpad {
755763 int xtype ; /* type of xbox device */
756764 int packet_type ; /* type of the extended packet */
757765 int pad_nr ; /* the order x360 pads were attached */
766+ int quirks ;
758767 const char * name ; /* name of the device */
759768 struct work_struct work ; /* init/remove device from callback */
760769 struct delayed_work poweroff_work ; /* work struct for poweroff on mode long press */
@@ -1489,6 +1498,98 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
14891498 return retval ;
14901499}
14911500
1501+ static int xpad_start_xbox_360 (struct usb_xpad * xpad )
1502+ {
1503+ int status ;
1504+
1505+ char * data = kzalloc (20 , GFP_KERNEL );
1506+
1507+ int TIMEOUT = 100 ;
1508+
1509+ /*
1510+ this init sequence is needed for the gamesir g3w controller
1511+ and for shanwan controllers in xpad mode.
1512+ Unfortunately, in this mode they identify as 0x045e, 0x028e, so we
1513+ have to inspect the manufacturer string.
1514+ Sending this sequence to other controllers will break initialization.
1515+ */
1516+ bool is_shanwan = xpad -> udev -> manufacturer && strcasecmp ("shanwan" , xpad -> udev -> manufacturer ) == 0 ;
1517+ if (!(xpad -> quirks & QUIRK_360_START ) && !is_shanwan ) {
1518+ status = 0 ;
1519+ goto err_free_ctrl_data ;
1520+ }
1521+
1522+ if ((xpad -> quirks & QUIRK_360_START_PKT_1 ) || is_shanwan ) {
1523+ status = usb_control_msg (xpad -> udev ,
1524+ usb_rcvctrlpipe (xpad -> udev , 0 ),
1525+ 0x1 , 0xc1 ,
1526+ cpu_to_le16 (0x100 ), cpu_to_le16 (0x0 ), data , cpu_to_le16 (20 ),
1527+ TIMEOUT );
1528+
1529+ #ifdef DEBUG
1530+ dev_dbg (& xpad -> intf -> dev ,
1531+ "%s - control message 1 returned %d\n" , __func__ , status );
1532+ #endif
1533+
1534+ if (status < 0 ) {
1535+ goto err_free_ctrl_data ;
1536+ }
1537+ #ifdef DEBUG
1538+ else {
1539+ print_hex_dump (KERN_DEBUG , "xpad-dbg: " , DUMP_PREFIX_OFFSET , 32 , 1 , data , 20 , 0 );
1540+ }
1541+ #endif
1542+ }
1543+
1544+ if ((xpad -> quirks & QUIRK_360_START_PKT_2 ) || is_shanwan ) {
1545+ status = usb_control_msg (xpad -> udev ,
1546+ usb_rcvctrlpipe (xpad -> udev , 0 ),
1547+ 0x1 , 0xc1 ,
1548+ cpu_to_le16 (0x0 ), cpu_to_le16 (0x0 ), data , cpu_to_le16 (8 ),
1549+ TIMEOUT );
1550+ #ifdef DEBUG
1551+ dev_dbg (& xpad -> intf -> dev ,
1552+ "%s - control message 2 returned %d\n" , __func__ , status );
1553+ #endif
1554+
1555+ if (status < 0 ) {
1556+ goto err_free_ctrl_data ;
1557+ }
1558+ #ifdef DEBUG
1559+ else {
1560+ print_hex_dump (KERN_DEBUG , "xpad-dbg: " , DUMP_PREFIX_OFFSET , 32 , 1 , data , 8 , 0 );
1561+ }
1562+ #endif
1563+ }
1564+
1565+ if ((xpad -> quirks & QUIRK_360_START_PKT_3 ) || is_shanwan ) {
1566+ status = usb_control_msg (xpad -> udev ,
1567+ usb_rcvctrlpipe (xpad -> udev , 0 ),
1568+ 0x1 , 0xc0 ,
1569+ cpu_to_le16 (0x0 ), cpu_to_le16 (0x0 ), data , cpu_to_le16 (4 ),
1570+ TIMEOUT );
1571+ #ifdef DEBUG
1572+ dev_dbg (& xpad -> intf -> dev ,
1573+ "%s - control message 3 returned %d\n" , __func__ , status );
1574+ #endif
1575+
1576+ if (status < 0 ) {
1577+ goto err_free_ctrl_data ;
1578+ }
1579+ #ifdef DEBUG
1580+ else {
1581+ print_hex_dump (KERN_DEBUG , "xpad-dbg: " , DUMP_PREFIX_OFFSET , 32 , 1 , data , 4 , 0 );
1582+ }
1583+ #endif
1584+ }
1585+
1586+ status = 0 ;
1587+
1588+ err_free_ctrl_data :
1589+ kfree (data );
1590+ return status ;
1591+ }
1592+
14921593static void xpadone_ack_mode_report (struct usb_xpad * xpad , u8 seq_num )
14931594{
14941595 unsigned long flags ;
@@ -1774,6 +1875,12 @@ static int xpad_start_input(struct usb_xpad *xpad)
17741875{
17751876 int error ;
17761877
1878+ if (xpad -> xtype == XTYPE_XBOX360 ) {
1879+ error = xpad_start_xbox_360 (xpad );
1880+ if (error )
1881+ return error ;
1882+ }
1883+
17771884 if (usb_submit_urb (xpad -> irq_in , GFP_KERNEL ))
17781885 return - EIO ;
17791886
@@ -2085,6 +2192,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
20852192 xpad -> mapping = xpad_device [i ].mapping ;
20862193 xpad -> xtype = xpad_device [i ].xtype ;
20872194 xpad -> name = xpad_device [i ].name ;
2195+ xpad -> quirks = xpad_device [i ].quirks ;
20882196 xpad -> packet_type = PKT_XB ;
20892197 INIT_WORK (& xpad -> work , xpad_presence_work );
20902198
0 commit comments