Advertisement
xerpi

SIXAXIS/DS3 enable, mode operational

Dec 9th, 2012
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.55 KB | None | 0 0
  1. /*
  2.  * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
  3.  * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
  4.  * so we need to override that forcing HID Output Reports on the Control EP.
  5.  *
  6.  * There is also another issue about HID Output Reports via USB, the Sixaxis
  7.  * does not want the report_id as part of the data packet, so we have to
  8.  * discard buf[0] when sending the actual control message, even for numbered
  9.  * reports, humpf!
  10.  */
  11. static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
  12.                 size_t count, unsigned char report_type)
  13. {
  14.         struct usb_interface *intf = to_usb_interface(hid->dev.parent);
  15.         struct usb_device *dev = interface_to_usbdev(intf);
  16.         struct usb_host_interface *interface = intf->cur_altsetting;
  17.         int report_id = buf[0];
  18.         int ret;
  19.  
  20.         if (report_type == HID_OUTPUT_REPORT) {
  21.                 /* Don't send the Report ID */
  22.                 buf++;
  23.                 count--;
  24.         }
  25.  
  26.         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  27.                 HID_REQ_SET_REPORT,
  28.                 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
  29.                 ((report_type + 1) << 8) | report_id,
  30.                 interface->desc.bInterfaceNumber, buf, count,
  31.                 USB_CTRL_SET_TIMEOUT);
  32.  
  33.         /* Count also the Report ID, in case of an Output report. */
  34.         if (ret > 0 && report_type == HID_OUTPUT_REPORT)
  35.                 ret++;
  36.  
  37.         return ret;
  38. }
  39.  
  40. /*
  41.  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
  42.  * to "operational".  Without this, the ps3 controller will not report any
  43.  * events.
  44.  */
  45. static int sixaxis_set_operational_usb(struct hid_device *hdev)
  46. {
  47.         struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  48.         struct usb_device *dev = interface_to_usbdev(intf);
  49.         __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
  50.         int ret;
  51.         char *buf = kmalloc(18, GFP_KERNEL);
  52.  
  53.         if (!buf)
  54.                 return -ENOMEM;
  55.  
  56.         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  57.                                  HID_REQ_GET_REPORT,
  58.                                  USB_DIR_IN | USB_TYPE_CLASS |
  59.                                  USB_RECIP_INTERFACE,
  60.                                  (3 << 8) | 0xf2, ifnum, buf, 17,
  61.                                  USB_CTRL_GET_TIMEOUT);
  62.         if (ret < 0)
  63.                 hid_err(hdev, "can't set operational mode\n");
  64.  
  65.         kfree(buf);
  66.  
  67.         return ret;
  68. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement