USB: ps3 controller hid quirk
Add the USB HID quirk HID_QUIRK_SONY_PS3_CONTROLLER. This sends an HID_REQ_GET_REPORT to the the PS3 controller to put the device into 'operational mode'. Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
ad75a41085
commit
4a1a4d8b87
@@ -768,6 +768,9 @@ void usbhid_init_reports(struct hid_device *hid)
|
|||||||
#define USB_VENDOR_ID_PANTHERLORD 0x0810
|
#define USB_VENDOR_ID_PANTHERLORD 0x0810
|
||||||
#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
|
#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_SONY 0x054c
|
||||||
|
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alphabetically sorted blacklist by quirk type.
|
* Alphabetically sorted blacklist by quirk type.
|
||||||
*/
|
*/
|
||||||
@@ -949,6 +952,8 @@ static const struct hid_blacklist {
|
|||||||
|
|
||||||
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
||||||
|
|
||||||
|
{ USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1013,6 +1018,32 @@ static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
|
||||||
|
* to "operational". Without this, the ps3 controller will not report any
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
char *buf = kmalloc(18, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||||
|
HID_REQ_GET_REPORT,
|
||||||
|
USB_DIR_IN | USB_TYPE_CLASS |
|
||||||
|
USB_RECIP_INTERFACE,
|
||||||
|
(3 << 8) | 0xf2, ifnum, buf, 17,
|
||||||
|
USB_CTRL_GET_TIMEOUT);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
err("%s failed: %d\n", __func__, result);
|
||||||
|
|
||||||
|
kfree(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static struct hid_device *usb_hid_configure(struct usb_interface *intf)
|
static struct hid_device *usb_hid_configure(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct usb_host_interface *interface = intf->cur_altsetting;
|
struct usb_host_interface *interface = intf->cur_altsetting;
|
||||||
@@ -1303,6 +1334,10 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||||||
if ((hid->claimed & HID_CLAIMED_INPUT))
|
if ((hid->claimed & HID_CLAIMED_INPUT))
|
||||||
hid_ff_init(hid);
|
hid_ff_init(hid);
|
||||||
|
|
||||||
|
if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER)
|
||||||
|
hid_fixup_sony_ps3_controller(interface_to_usbdev(intf),
|
||||||
|
intf->cur_altsetting->desc.bInterfaceNumber);
|
||||||
|
|
||||||
printk(KERN_INFO);
|
printk(KERN_INFO);
|
||||||
|
|
||||||
if (hid->claimed & HID_CLAIMED_INPUT)
|
if (hid->claimed & HID_CLAIMED_INPUT)
|
||||||
|
@@ -266,6 +266,7 @@ struct hid_item {
|
|||||||
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
|
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
|
||||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000
|
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000
|
||||||
#define HID_QUIRK_IGNORE_MOUSE 0x00040000
|
#define HID_QUIRK_IGNORE_MOUSE 0x00040000
|
||||||
|
#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the global environment of the parser. This information is
|
* This is the global environment of the parser. This information is
|
||||||
|
Reference in New Issue
Block a user