HID: hid-sony.c: Fix sending Output reports to the Sixaxis

The Sixaxis does not want the report_id as part of the data packet in
Output reports, so we have to discard buf[0] when sending the actual
control message.

Add also some documentation about that and about why
hdev->hid_output_raw_report needs to be overridden.

Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
Antonio Ospite 2011-02-20 18:26:45 +01:00 committed by Jiri Kosina
parent 177900e8c9
commit 5710fabf31

View file

@ -46,6 +46,16 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
return rdesc; return rdesc;
} }
/*
* The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
* like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
* so we need to override that forcing HID Output Reports on the Control EP.
*
* There is also another issue about HID Output Reports via USB, the Sixaxis
* does not want the report_id as part of the data packet, so we have to
* discard buf[0] when sending the actual control message, even for numbered
* reports, humpf!
*/
static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
size_t count, unsigned char report_type) size_t count, unsigned char report_type)
{ {
@ -55,6 +65,12 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
int report_id = buf[0]; int report_id = buf[0];
int ret; int ret;
if (report_type == HID_OUTPUT_REPORT) {
/* Don't send the Report ID */
buf++;
count--;
}
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_REPORT, HID_REQ_SET_REPORT,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
@ -62,6 +78,10 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
interface->desc.bInterfaceNumber, buf, count, interface->desc.bInterfaceNumber, buf, count,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
/* Count also the Report ID, in case of an Output report. */
if (ret > 0 && report_type == HID_OUTPUT_REPORT)
ret++;
return ret; return ret;
} }