hid-sony.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * HID driver for some sony "special" devices
  3. *
  4. * Copyright (c) 1999 Andreas Gal
  5. * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  6. * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
  7. * Copyright (c) 2006-2007 Jiri Kosina
  8. * Copyright (c) 2007 Paul Walmsley
  9. * Copyright (c) 2008 Jiri Slaby
  10. */
  11. /*
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU General Public License as published by the Free
  14. * Software Foundation; either version 2 of the License, or (at your option)
  15. * any later version.
  16. */
  17. #include <linux/device.h>
  18. #include <linux/hid.h>
  19. #include <linux/module.h>
  20. #include <linux/usb.h>
  21. #include "hid-ids.h"
  22. /*
  23. * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
  24. * to "operational". Without this, the ps3 controller will not report any
  25. * events.
  26. */
  27. static int sony_set_operational(struct hid_device *hdev)
  28. {
  29. struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  30. struct usb_device *dev = interface_to_usbdev(intf);
  31. __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
  32. int ret;
  33. char *buf = kmalloc(18, GFP_KERNEL);
  34. if (!buf)
  35. return -ENOMEM;
  36. ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  37. HID_REQ_GET_REPORT,
  38. USB_DIR_IN | USB_TYPE_CLASS |
  39. USB_RECIP_INTERFACE,
  40. (3 << 8) | 0xf2, ifnum, buf, 17,
  41. USB_CTRL_GET_TIMEOUT);
  42. if (ret < 0)
  43. dev_err(&hdev->dev, "can't set operational mode\n");
  44. kfree(buf);
  45. return ret;
  46. }
  47. static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
  48. {
  49. int ret;
  50. hdev->quirks |= HID_QUIRK_HIDDEV;
  51. ret = hid_parse(hdev);
  52. if (ret) {
  53. dev_err(&hdev->dev, "parse failed\n");
  54. goto err_free;
  55. }
  56. ret = hid_hw_start(hdev);
  57. if (ret) {
  58. dev_err(&hdev->dev, "hw start failed\n");
  59. goto err_free;
  60. }
  61. ret = sony_set_operational(hdev);
  62. if (ret)
  63. goto err_stop;
  64. return 0;
  65. err_stop:
  66. hid_hw_stop(hdev);
  67. err_free:
  68. return ret;
  69. }
  70. static const struct hid_device_id sony_devices[] = {
  71. { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
  72. { }
  73. };
  74. MODULE_DEVICE_TABLE(hid, sony_devices);
  75. static struct hid_driver sony_driver = {
  76. .name = "sony",
  77. .id_table = sony_devices,
  78. .probe = sony_probe,
  79. };
  80. static int sony_init(void)
  81. {
  82. return hid_register_driver(&sony_driver);
  83. }
  84. static void sony_exit(void)
  85. {
  86. hid_unregister_driver(&sony_driver);
  87. }
  88. module_init(sony_init);
  89. module_exit(sony_exit);
  90. MODULE_LICENSE("GPL");
  91. HID_COMPAT_LOAD_DRIVER(sony);