hid-synaptics-bt.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #include <linux/kernel.h>
  2. #include <linux/errno.h>
  3. #include <linux/init.h>
  4. #include <linux/slab.h>
  5. #include <linux/module.h>
  6. #include <linux/hid.h>
  7. #include <linux/mutex.h>
  8. #include <linux/input.h>
  9. #include <linux/input/mt.h>
  10. #include "hid-ids.h"
  11. #define MAX_NUM_OF_FINGERS 5
  12. #define FINGER_DATA_SIZE 8
  13. #define DEFAULT_MAX_ABS_MT_PRESSURE 255
  14. static int debug = 0;
  15. module_param(debug, int, 0644);
  16. MODULE_PARM_DESC(debug, "Activate debugging output");
  17. struct syntp_finger {
  18. int x;
  19. int y;
  20. int z;
  21. int w;
  22. int dribble_count;
  23. };
  24. struct hid_synaptics_data {
  25. char phys[64];
  26. struct input_dev *input; /* input dev */
  27. struct syntp_finger fingers[MAX_NUM_OF_FINGERS];
  28. int button_down;
  29. };
  30. #define samsung_kbd_mouse_map_key_clear(c) \
  31. hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
  32. static int hid_synaptics_raw_event(struct hid_device *hdev,
  33. struct hid_report *report, u8 *data, int size)
  34. {
  35. struct hid_synaptics_data *syntp_data = hid_get_drvdata(hdev);
  36. struct input_dev *input = syntp_data->input;
  37. int raw_z, raw_w, raw_x, raw_y, i = 0;
  38. int inverted_y;
  39. int send_packet;
  40. /* make sure this report has the right report id */
  41. if (data[0] != 9 || ((size - 1) < (MAX_NUM_OF_FINGERS * FINGER_DATA_SIZE)))
  42. return 0;
  43. ++data;
  44. for (i = 0; i < MAX_NUM_OF_FINGERS; ++i, data += FINGER_DATA_SIZE) {
  45. raw_w = data[0] & 0x0f;
  46. raw_x = be16_to_cpup((__be16 *)&data[2]);
  47. raw_y = be16_to_cpup((__be16 *)&data[4]);
  48. raw_z = data[6];
  49. send_packet = 0;
  50. if (raw_z == 0 && raw_w == 0) {
  51. /* dribble packet */
  52. if (syntp_data->fingers[i].dribble_count == 0) {
  53. raw_x = syntp_data->fingers[i].x;
  54. raw_y = syntp_data->fingers[i].y;
  55. raw_z = 0;
  56. raw_w = 0;
  57. ++syntp_data->fingers[i].dribble_count;
  58. send_packet = 1;
  59. }
  60. } else {
  61. /* real packet */
  62. syntp_data->fingers[i].dribble_count = 0;
  63. send_packet = 1;
  64. /* update with last real packet */
  65. syntp_data->fingers[i].x = raw_x;
  66. syntp_data->fingers[i].y = raw_y;
  67. syntp_data->fingers[i].z = raw_z;
  68. syntp_data->fingers[i].w = raw_w;
  69. }
  70. if (send_packet) {
  71. inverted_y = (5888 - 1024) - raw_y;
  72. dev_dbg(&hdev->dev, "Finger Count = %d\n", data[7] >> 4);
  73. dev_dbg(&hdev->dev, "ID=%d X=%d Y=%d W=%d Z=%d "
  74. "button=%d\n", i, raw_x, raw_y,
  75. raw_w, raw_z, data[1]);
  76. input_mt_slot(input, i);
  77. input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
  78. input_report_abs(input, ABS_MT_PRESSURE, raw_z);
  79. input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw_w);
  80. input_report_abs(input, ABS_MT_TOUCH_MINOR, raw_w);
  81. input_report_abs(input, ABS_MT_ORIENTATION, 0);
  82. input_report_abs(input, ABS_MT_POSITION_X, raw_x);
  83. input_report_abs(input, ABS_MT_POSITION_Y, inverted_y);
  84. input_mt_report_pointer_emulation(input, true);
  85. }
  86. if (data[1] & 0x02) {
  87. if (!syntp_data->button_down) {
  88. dev_dbg(&hdev->dev, "Button Down!\n");
  89. syntp_data->button_down = 1;
  90. input_report_key(input, BTN_LEFT, 1);
  91. }
  92. } else if (syntp_data->button_down) {
  93. dev_dbg(&hdev->dev, "Button Up!\n");
  94. syntp_data->button_down = 0;
  95. input_report_key(input, BTN_LEFT, 0);
  96. }
  97. }
  98. input_sync(input);
  99. return 0;
  100. }
  101. static int hid_synaptics_event(struct hid_device *hdev, struct hid_field *field,
  102. struct hid_usage *usage, __s32 value)
  103. {
  104. if (field->report->id == 9)
  105. return 1;
  106. return 0;
  107. }
  108. static int hid_synaptics_probe(struct hid_device *hdev, const struct hid_device_id *id)
  109. {
  110. struct hid_synaptics_data *syntp_data;
  111. struct input_dev * input_dev;
  112. unsigned int connect_mask = HID_CONNECT_DEFAULT;
  113. int ret;
  114. dev_dbg(&hdev->dev, "%s\n", __func__);
  115. ret = hid_parse(hdev);
  116. if (ret) {
  117. hid_err(hdev, "parse failed\n");
  118. goto err_free;
  119. }
  120. ret = hid_hw_start(hdev, connect_mask);
  121. if (ret) {
  122. hid_err(hdev, "hw start failed\n");
  123. goto err_free;
  124. }
  125. syntp_data = devm_kzalloc(&hdev->dev, sizeof(struct hid_synaptics_data), GFP_KERNEL);
  126. if (!syntp_data) {
  127. ret =-ENOMEM;
  128. goto hid_stop;
  129. }
  130. input_dev = input_allocate_device();
  131. if (!input_dev) {
  132. ret = -ENOMEM;
  133. kfree(syntp_data);
  134. goto hid_stop;
  135. }
  136. input_dev->name = "Synaptics HID TouchPad";
  137. snprintf(syntp_data->phys, 64, "%s/input0", dev_name(&hdev->dev));
  138. input_dev->phys = syntp_data->phys;
  139. /* Setup Events to Report */
  140. set_bit(EV_SYN, input_dev->evbit);
  141. set_bit(EV_KEY, input_dev->evbit);
  142. set_bit(EV_ABS, input_dev->evbit);
  143. set_bit(BTN_LEFT, input_dev->keybit);
  144. set_bit(INPUT_PROP_POINTER, input_dev->propbit);
  145. input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
  146. set_bit(BTN_TOOL_FINGER, input_dev->keybit);
  147. set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
  148. set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
  149. set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
  150. input_set_abs_params(input_dev, ABS_X, 1024, 5888, 0, 0);
  151. input_set_abs_params(input_dev, ABS_Y, 1024, 5888, 0, 0);
  152. input_set_abs_params(input_dev, ABS_PRESSURE, 0, DEFAULT_MAX_ABS_MT_PRESSURE, 0, 0);
  153. input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
  154. input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
  155. 0, 15, 0, 0);
  156. input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
  157. 0, 15, 0, 0);
  158. input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
  159. 0, 1, 0, 0);
  160. input_set_abs_params(input_dev, ABS_MT_TRACKING_ID,
  161. 1, 5, 0, 0);
  162. input_set_abs_params(input_dev, ABS_MT_POSITION_X,
  163. 1024, 5888, 0, 0);
  164. input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
  165. 1024, 5888, 0, 0);
  166. input_mt_init_slots(input_dev, 5);
  167. syntp_data->input = input_dev;
  168. ret = input_register_device(syntp_data->input);
  169. if (ret)
  170. {
  171. input_free_device(syntp_data->input);
  172. goto hid_init_failed;
  173. }
  174. hid_set_drvdata(hdev, syntp_data);
  175. dev_dbg(&hdev->dev, "Opening low level driver\n");
  176. hdev->ll_driver->open(hdev);
  177. dev_info(&hdev->dev, "registered rmi hid driver for %s\n", hdev->phys);
  178. return 0;
  179. hid_init_failed:
  180. hdev->ll_driver->close(hdev);
  181. hid_stop:
  182. hid_hw_stop(hdev);
  183. err_free:
  184. return ret;
  185. }
  186. static void hid_synaptics_remove(struct hid_device *hdev)
  187. {
  188. hdev->ll_driver->close(hdev);
  189. hid_hw_stop(hdev);
  190. }
  191. static int samsung_bookcover_input_mapping(struct hid_device *hdev,
  192. struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
  193. unsigned long **bit, int *max)
  194. {
  195. if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
  196. HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
  197. return 0;
  198. dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
  199. usage->hid & HID_USAGE);
  200. if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
  201. switch (usage->hid & HID_USAGE) {
  202. set_bit(EV_REP, hi->input->evbit);
  203. /* Only for UK keyboard */
  204. /* key found */
  205. #ifdef CONFIG_HID_KK_UPGRADE
  206. case 0x32: samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE); break;
  207. case 0x64: samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); break;
  208. #else
  209. case 0x32: samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); break;
  210. case 0x64: samsung_kbd_mouse_map_key_clear(KEY_102ND); break;
  211. #endif
  212. /* Only for BR keyboard */
  213. case 0x87: samsung_kbd_mouse_map_key_clear(KEY_RO); break;
  214. default:
  215. return 0;
  216. }
  217. }
  218. if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
  219. switch (usage->hid & HID_USAGE) {
  220. /* report 2 */
  221. /* MENU */
  222. case 0x040: samsung_kbd_mouse_map_key_clear(KEY_MENU); break;
  223. case 0x18a: samsung_kbd_mouse_map_key_clear(KEY_MAIL); break;
  224. case 0x196: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
  225. case 0x19e: samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK); break;
  226. case 0x221: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
  227. case 0x223: samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE); break;
  228. /* RECENTAPPS */
  229. case 0x301: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1); break;
  230. /* APPLICATION */
  231. case 0x302: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2); break;
  232. /* Voice search */
  233. case 0x305: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4); break;
  234. /* QPANEL on/off */
  235. case 0x306: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5); break;
  236. /* SIP on/off */
  237. case 0x307: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3); break;
  238. /* LANG */
  239. case 0x308: samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE); break;
  240. case 0x30a: samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN); break;
  241. case 0x070: samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN); break;
  242. case 0x30b: samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP); break;
  243. case 0x06f: samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP); break;
  244. /* S-Finder */
  245. case 0x304: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY7); break;
  246. /* Screen Capture */
  247. case 0x303: samsung_kbd_mouse_map_key_clear(KEY_SYSRQ); break;
  248. /* Multi Window */
  249. case 0x309: samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY9); break;
  250. default:
  251. return 0;
  252. }
  253. }
  254. return 1;
  255. }
  256. static int hid_synaptics_mapping(struct hid_device *hdev, struct hid_input *hi,
  257. struct hid_field *field, struct hid_usage *usage,
  258. unsigned long **bit, int *max)
  259. {
  260. int ret = 0;
  261. if (USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER == hdev->product)
  262. ret = samsung_bookcover_input_mapping(hdev,
  263. hi, field, usage, bit, max);
  264. return ret;
  265. }
  266. static const struct hid_device_id hid_synaptics_id[] = {
  267. { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER),
  268. .driver_data = 0 },
  269. { HID_USB_DEVICE(0x06cb, 0x5555),
  270. .driver_data = 0 },
  271. {}
  272. };
  273. MODULE_DEVICE_TABLE(hid, hid_synaptics_id);
  274. static struct hid_driver hid_synaptics_driver = {
  275. .name = "hid-synaptics-bt",
  276. .driver = {
  277. .owner = THIS_MODULE,
  278. .name = "hid-synaptics-bt",
  279. },
  280. .id_table = hid_synaptics_id,
  281. .probe = hid_synaptics_probe,
  282. .remove = hid_synaptics_remove,
  283. .raw_event = hid_synaptics_raw_event,
  284. .event = hid_synaptics_event,
  285. .input_mapping = hid_synaptics_mapping,
  286. };
  287. static int __init hid_synaptics_init(void)
  288. {
  289. int ret;
  290. ret = hid_register_driver(&hid_synaptics_driver);
  291. if (ret)
  292. pr_err("Failed to register hid_synaptics_driver (%d)\n", ret);
  293. else
  294. pr_info("Successfully registered hid_synaptics_driver\n");
  295. return ret;
  296. }
  297. static void __exit hid_synaptics_exit(void)
  298. {
  299. hid_unregister_driver(&hid_synaptics_driver);
  300. }
  301. module_init(hid_synaptics_init);
  302. module_exit(hid_synaptics_exit);
  303. MODULE_AUTHOR("Andrew Duggan");
  304. MODULE_DESCRIPTION("Synaptics HID Bluetooth Dock Driver");
  305. MODULE_LICENSE("GPL");