hid-ps3remote.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * HID driver for Sony PS3 BD Remote Control
  3. *
  4. * Copyright (c) 2012 David Dillow <dave@thedillows.org>
  5. * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann
  6. * and other kernel HID drivers.
  7. */
  8. /*
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the Free
  11. * Software Foundation; either version 2 of the License, or (at your option)
  12. * any later version.
  13. */
  14. /* NOTE: in order for the Sony PS3 BD Remote Control to be found by
  15. * a Bluetooth host, the key combination Start+Enter has to be kept pressed
  16. * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
  17. *
  18. * There will be no PIN request from the device.
  19. */
  20. #include <linux/device.h>
  21. #include <linux/hid.h>
  22. #include <linux/module.h>
  23. #include "hid-ids.h"
  24. static __u8 ps3remote_rdesc[] = {
  25. 0x05, 0x01, /* GUsagePage Generic Desktop */
  26. 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
  27. 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
  28. /* Use collection 1 for joypad buttons */
  29. 0xA1, 0x02, /* MCollection Logical (interrelated data) */
  30. /* Ignore the 1st byte, maybe it is used for a controller
  31. * number but it's not needed for correct operation */
  32. 0x75, 0x08, /* GReportSize 0x08 [8] */
  33. 0x95, 0x01, /* GReportCount 0x01 [1] */
  34. 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
  35. /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
  36. * buttons multiple keypresses are allowed */
  37. 0x05, 0x09, /* GUsagePage Button */
  38. 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
  39. 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
  40. 0x14, /* GLogicalMinimum [0] */
  41. 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
  42. 0x75, 0x01, /* GReportSize 0x01 [1] */
  43. 0x95, 0x18, /* GReportCount 0x18 [24] */
  44. 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
  45. 0xC0, /* MEndCollection */
  46. /* Use collection 2 for remote control buttons */
  47. 0xA1, 0x02, /* MCollection Logical (interrelated data) */
  48. /* 5th byte is used for remote control buttons */
  49. 0x05, 0x09, /* GUsagePage Button */
  50. 0x18, /* LUsageMinimum [No button pressed] */
  51. 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
  52. 0x14, /* GLogicalMinimum [0] */
  53. 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
  54. 0x75, 0x08, /* GReportSize 0x08 [8] */
  55. 0x95, 0x01, /* GReportCount 0x01 [1] */
  56. 0x80, /* MInput */
  57. /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
  58. * 0xff and 11th is for press indication */
  59. 0x75, 0x08, /* GReportSize 0x08 [8] */
  60. 0x95, 0x06, /* GReportCount 0x06 [6] */
  61. 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
  62. /* 12th byte is for battery strength */
  63. 0x05, 0x06, /* GUsagePage Generic Device Controls */
  64. 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
  65. 0x14, /* GLogicalMinimum [0] */
  66. 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
  67. 0x75, 0x08, /* GReportSize 0x08 [8] */
  68. 0x95, 0x01, /* GReportCount 0x01 [1] */
  69. 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
  70. 0xC0, /* MEndCollection */
  71. 0xC0 /* MEndCollection [Game Pad] */
  72. };
  73. static const unsigned int ps3remote_keymap_joypad_buttons[] = {
  74. [0x01] = KEY_SELECT,
  75. [0x02] = BTN_THUMBL, /* L3 */
  76. [0x03] = BTN_THUMBR, /* R3 */
  77. [0x04] = BTN_START,
  78. [0x05] = KEY_UP,
  79. [0x06] = KEY_RIGHT,
  80. [0x07] = KEY_DOWN,
  81. [0x08] = KEY_LEFT,
  82. [0x09] = BTN_TL2, /* L2 */
  83. [0x0a] = BTN_TR2, /* R2 */
  84. [0x0b] = BTN_TL, /* L1 */
  85. [0x0c] = BTN_TR, /* R1 */
  86. [0x0d] = KEY_OPTION, /* options/triangle */
  87. [0x0e] = KEY_BACK, /* back/circle */
  88. [0x0f] = BTN_0, /* cross */
  89. [0x10] = KEY_SCREEN, /* view/square */
  90. [0x11] = KEY_HOMEPAGE, /* PS button */
  91. [0x14] = KEY_ENTER,
  92. };
  93. static const unsigned int ps3remote_keymap_remote_buttons[] = {
  94. [0x00] = KEY_1,
  95. [0x01] = KEY_2,
  96. [0x02] = KEY_3,
  97. [0x03] = KEY_4,
  98. [0x04] = KEY_5,
  99. [0x05] = KEY_6,
  100. [0x06] = KEY_7,
  101. [0x07] = KEY_8,
  102. [0x08] = KEY_9,
  103. [0x09] = KEY_0,
  104. [0x0e] = KEY_ESC, /* return */
  105. [0x0f] = KEY_CLEAR,
  106. [0x16] = KEY_EJECTCD,
  107. [0x1a] = KEY_MENU, /* top menu */
  108. [0x28] = KEY_TIME,
  109. [0x30] = KEY_PREVIOUS,
  110. [0x31] = KEY_NEXT,
  111. [0x32] = KEY_PLAY,
  112. [0x33] = KEY_REWIND, /* scan back */
  113. [0x34] = KEY_FORWARD, /* scan forward */
  114. [0x38] = KEY_STOP,
  115. [0x39] = KEY_PAUSE,
  116. [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
  117. [0x60] = KEY_FRAMEBACK, /* slow/step back */
  118. [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
  119. [0x63] = KEY_SUBTITLE,
  120. [0x64] = KEY_AUDIO,
  121. [0x65] = KEY_ANGLE,
  122. [0x70] = KEY_INFO, /* display */
  123. [0x80] = KEY_BLUE,
  124. [0x81] = KEY_RED,
  125. [0x82] = KEY_GREEN,
  126. [0x83] = KEY_YELLOW,
  127. };
  128. static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
  129. unsigned int *rsize)
  130. {
  131. *rsize = sizeof(ps3remote_rdesc);
  132. return ps3remote_rdesc;
  133. }
  134. static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
  135. struct hid_field *field, struct hid_usage *usage,
  136. unsigned long **bit, int *max)
  137. {
  138. unsigned int key = usage->hid & HID_USAGE;
  139. if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
  140. return -1;
  141. switch (usage->collection_index) {
  142. case 1:
  143. if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
  144. return -1;
  145. key = ps3remote_keymap_joypad_buttons[key];
  146. if (!key)
  147. return -1;
  148. break;
  149. case 2:
  150. if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
  151. return -1;
  152. key = ps3remote_keymap_remote_buttons[key];
  153. if (!key)
  154. return -1;
  155. break;
  156. default:
  157. return -1;
  158. }
  159. hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  160. return 1;
  161. }
  162. static const struct hid_device_id ps3remote_devices[] = {
  163. /* PS3 BD Remote Control */
  164. { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
  165. /* Logitech Harmony Adapter for PS3 */
  166. { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
  167. { }
  168. };
  169. MODULE_DEVICE_TABLE(hid, ps3remote_devices);
  170. static struct hid_driver ps3remote_driver = {
  171. .name = "ps3_remote",
  172. .id_table = ps3remote_devices,
  173. .report_fixup = ps3remote_fixup,
  174. .input_mapping = ps3remote_mapping,
  175. };
  176. module_hid_driver(ps3remote_driver);
  177. MODULE_LICENSE("GPL");
  178. MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");