hid-udraw-ps3.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * HID driver for THQ PS3 uDraw tablet
  4. *
  5. * Copyright (C) 2016 Red Hat Inc. All Rights Reserved
  6. */
  7. #include <linux/device.h>
  8. #include <linux/hid.h>
  9. #include <linux/module.h>
  10. #include "hid-ids.h"
  11. MODULE_AUTHOR("Bastien Nocera <[email protected]>");
  12. MODULE_DESCRIPTION("PS3 uDraw tablet driver");
  13. MODULE_LICENSE("GPL");
  14. /*
  15. * Protocol information from:
  16. * https://brandonw.net/udraw/
  17. * and the source code of:
  18. * https://vvvv.org/contribution/udraw-hid
  19. */
  20. /*
  21. * The device is setup with multiple input devices:
  22. * - the touch area which works as a touchpad
  23. * - the tablet area which works as a touchpad/drawing tablet
  24. * - a joypad with a d-pad, and 7 buttons
  25. * - an accelerometer device
  26. */
  27. enum {
  28. TOUCH_NONE,
  29. TOUCH_PEN,
  30. TOUCH_FINGER,
  31. TOUCH_TWOFINGER
  32. };
  33. enum {
  34. AXIS_X,
  35. AXIS_Y,
  36. AXIS_Z
  37. };
  38. /*
  39. * Accelerometer min/max values
  40. * in order, X, Y and Z
  41. */
  42. static struct {
  43. int min;
  44. int max;
  45. } accel_limits[] = {
  46. [AXIS_X] = { 490, 534 },
  47. [AXIS_Y] = { 490, 534 },
  48. [AXIS_Z] = { 492, 536 }
  49. };
  50. #define DEVICE_NAME "THQ uDraw Game Tablet for PS3"
  51. /* resolution in pixels */
  52. #define RES_X 1920
  53. #define RES_Y 1080
  54. /* size in mm */
  55. #define WIDTH 160
  56. #define HEIGHT 90
  57. #define PRESSURE_OFFSET 113
  58. #define MAX_PRESSURE (255 - PRESSURE_OFFSET)
  59. struct udraw {
  60. struct input_dev *joy_input_dev;
  61. struct input_dev *touch_input_dev;
  62. struct input_dev *pen_input_dev;
  63. struct input_dev *accel_input_dev;
  64. struct hid_device *hdev;
  65. /*
  66. * The device's two-finger support is pretty unreliable, as
  67. * the device could report a single touch when the two fingers
  68. * are too close together, and the distance between fingers, even
  69. * though reported is not in the same unit as the touches.
  70. *
  71. * We'll make do without it, and try to report the first touch
  72. * as reliably as possible.
  73. */
  74. int last_one_finger_x;
  75. int last_one_finger_y;
  76. int last_two_finger_x;
  77. int last_two_finger_y;
  78. };
  79. static int clamp_accel(int axis, int offset)
  80. {
  81. axis = clamp(axis,
  82. accel_limits[offset].min,
  83. accel_limits[offset].max);
  84. axis = (axis - accel_limits[offset].min) /
  85. ((accel_limits[offset].max -
  86. accel_limits[offset].min) * 0xFF);
  87. return axis;
  88. }
  89. static int udraw_raw_event(struct hid_device *hdev, struct hid_report *report,
  90. u8 *data, int len)
  91. {
  92. struct udraw *udraw = hid_get_drvdata(hdev);
  93. int touch;
  94. int x, y, z;
  95. if (len != 27)
  96. return 0;
  97. if (data[11] == 0x00)
  98. touch = TOUCH_NONE;
  99. else if (data[11] == 0x40)
  100. touch = TOUCH_PEN;
  101. else if (data[11] == 0x80)
  102. touch = TOUCH_FINGER;
  103. else
  104. touch = TOUCH_TWOFINGER;
  105. /* joypad */
  106. input_report_key(udraw->joy_input_dev, BTN_WEST, data[0] & 1);
  107. input_report_key(udraw->joy_input_dev, BTN_SOUTH, !!(data[0] & 2));
  108. input_report_key(udraw->joy_input_dev, BTN_EAST, !!(data[0] & 4));
  109. input_report_key(udraw->joy_input_dev, BTN_NORTH, !!(data[0] & 8));
  110. input_report_key(udraw->joy_input_dev, BTN_SELECT, !!(data[1] & 1));
  111. input_report_key(udraw->joy_input_dev, BTN_START, !!(data[1] & 2));
  112. input_report_key(udraw->joy_input_dev, BTN_MODE, !!(data[1] & 16));
  113. x = y = 0;
  114. switch (data[2]) {
  115. case 0x0:
  116. y = -127;
  117. break;
  118. case 0x1:
  119. y = -127;
  120. x = 127;
  121. break;
  122. case 0x2:
  123. x = 127;
  124. break;
  125. case 0x3:
  126. y = 127;
  127. x = 127;
  128. break;
  129. case 0x4:
  130. y = 127;
  131. break;
  132. case 0x5:
  133. y = 127;
  134. x = -127;
  135. break;
  136. case 0x6:
  137. x = -127;
  138. break;
  139. case 0x7:
  140. y = -127;
  141. x = -127;
  142. break;
  143. default:
  144. break;
  145. }
  146. input_report_abs(udraw->joy_input_dev, ABS_X, x);
  147. input_report_abs(udraw->joy_input_dev, ABS_Y, y);
  148. input_sync(udraw->joy_input_dev);
  149. /* For pen and touchpad */
  150. x = y = 0;
  151. if (touch != TOUCH_NONE) {
  152. if (data[15] != 0x0F)
  153. x = data[15] * 256 + data[17];
  154. if (data[16] != 0x0F)
  155. y = data[16] * 256 + data[18];
  156. }
  157. if (touch == TOUCH_FINGER) {
  158. /* Save the last one-finger touch */
  159. udraw->last_one_finger_x = x;
  160. udraw->last_one_finger_y = y;
  161. udraw->last_two_finger_x = -1;
  162. udraw->last_two_finger_y = -1;
  163. } else if (touch == TOUCH_TWOFINGER) {
  164. /*
  165. * We have a problem because x/y is the one for the
  166. * second finger but we want the first finger given
  167. * to user-space otherwise it'll look as if it jumped.
  168. *
  169. * See the udraw struct definition for why this was
  170. * implemented this way.
  171. */
  172. if (udraw->last_two_finger_x == -1) {
  173. /* Save the position of the 2nd finger */
  174. udraw->last_two_finger_x = x;
  175. udraw->last_two_finger_y = y;
  176. x = udraw->last_one_finger_x;
  177. y = udraw->last_one_finger_y;
  178. } else {
  179. /*
  180. * Offset the 2-finger coords using the
  181. * saved data from the first finger
  182. */
  183. x = x - (udraw->last_two_finger_x
  184. - udraw->last_one_finger_x);
  185. y = y - (udraw->last_two_finger_y
  186. - udraw->last_one_finger_y);
  187. }
  188. }
  189. /* touchpad */
  190. if (touch == TOUCH_FINGER || touch == TOUCH_TWOFINGER) {
  191. input_report_key(udraw->touch_input_dev, BTN_TOUCH, 1);
  192. input_report_key(udraw->touch_input_dev, BTN_TOOL_FINGER,
  193. touch == TOUCH_FINGER);
  194. input_report_key(udraw->touch_input_dev, BTN_TOOL_DOUBLETAP,
  195. touch == TOUCH_TWOFINGER);
  196. input_report_abs(udraw->touch_input_dev, ABS_X, x);
  197. input_report_abs(udraw->touch_input_dev, ABS_Y, y);
  198. } else {
  199. input_report_key(udraw->touch_input_dev, BTN_TOUCH, 0);
  200. input_report_key(udraw->touch_input_dev, BTN_TOOL_FINGER, 0);
  201. input_report_key(udraw->touch_input_dev, BTN_TOOL_DOUBLETAP, 0);
  202. }
  203. input_sync(udraw->touch_input_dev);
  204. /* pen */
  205. if (touch == TOUCH_PEN) {
  206. int level;
  207. level = clamp(data[13] - PRESSURE_OFFSET,
  208. 0, MAX_PRESSURE);
  209. input_report_key(udraw->pen_input_dev, BTN_TOUCH, (level != 0));
  210. input_report_key(udraw->pen_input_dev, BTN_TOOL_PEN, 1);
  211. input_report_abs(udraw->pen_input_dev, ABS_PRESSURE, level);
  212. input_report_abs(udraw->pen_input_dev, ABS_X, x);
  213. input_report_abs(udraw->pen_input_dev, ABS_Y, y);
  214. } else {
  215. input_report_key(udraw->pen_input_dev, BTN_TOUCH, 0);
  216. input_report_key(udraw->pen_input_dev, BTN_TOOL_PEN, 0);
  217. input_report_abs(udraw->pen_input_dev, ABS_PRESSURE, 0);
  218. }
  219. input_sync(udraw->pen_input_dev);
  220. /* accel */
  221. x = (data[19] + (data[20] << 8));
  222. x = clamp_accel(x, AXIS_X);
  223. y = (data[21] + (data[22] << 8));
  224. y = clamp_accel(y, AXIS_Y);
  225. z = (data[23] + (data[24] << 8));
  226. z = clamp_accel(z, AXIS_Z);
  227. input_report_abs(udraw->accel_input_dev, ABS_X, x);
  228. input_report_abs(udraw->accel_input_dev, ABS_Y, y);
  229. input_report_abs(udraw->accel_input_dev, ABS_Z, z);
  230. input_sync(udraw->accel_input_dev);
  231. /* let hidraw and hiddev handle the report */
  232. return 0;
  233. }
  234. static int udraw_open(struct input_dev *dev)
  235. {
  236. struct udraw *udraw = input_get_drvdata(dev);
  237. return hid_hw_open(udraw->hdev);
  238. }
  239. static void udraw_close(struct input_dev *dev)
  240. {
  241. struct udraw *udraw = input_get_drvdata(dev);
  242. hid_hw_close(udraw->hdev);
  243. }
  244. static struct input_dev *allocate_and_setup(struct hid_device *hdev,
  245. const char *name)
  246. {
  247. struct input_dev *input_dev;
  248. input_dev = devm_input_allocate_device(&hdev->dev);
  249. if (!input_dev)
  250. return NULL;
  251. input_dev->name = name;
  252. input_dev->phys = hdev->phys;
  253. input_dev->dev.parent = &hdev->dev;
  254. input_dev->open = udraw_open;
  255. input_dev->close = udraw_close;
  256. input_dev->uniq = hdev->uniq;
  257. input_dev->id.bustype = hdev->bus;
  258. input_dev->id.vendor = hdev->vendor;
  259. input_dev->id.product = hdev->product;
  260. input_dev->id.version = hdev->version;
  261. input_set_drvdata(input_dev, hid_get_drvdata(hdev));
  262. return input_dev;
  263. }
  264. static bool udraw_setup_touch(struct udraw *udraw,
  265. struct hid_device *hdev)
  266. {
  267. struct input_dev *input_dev;
  268. input_dev = allocate_and_setup(hdev, DEVICE_NAME " Touchpad");
  269. if (!input_dev)
  270. return false;
  271. input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
  272. input_set_abs_params(input_dev, ABS_X, 0, RES_X, 1, 0);
  273. input_abs_set_res(input_dev, ABS_X, RES_X / WIDTH);
  274. input_set_abs_params(input_dev, ABS_Y, 0, RES_Y, 1, 0);
  275. input_abs_set_res(input_dev, ABS_Y, RES_Y / HEIGHT);
  276. set_bit(BTN_TOUCH, input_dev->keybit);
  277. set_bit(BTN_TOOL_FINGER, input_dev->keybit);
  278. set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
  279. set_bit(INPUT_PROP_POINTER, input_dev->propbit);
  280. udraw->touch_input_dev = input_dev;
  281. return true;
  282. }
  283. static bool udraw_setup_pen(struct udraw *udraw,
  284. struct hid_device *hdev)
  285. {
  286. struct input_dev *input_dev;
  287. input_dev = allocate_and_setup(hdev, DEVICE_NAME " Pen");
  288. if (!input_dev)
  289. return false;
  290. input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
  291. input_set_abs_params(input_dev, ABS_X, 0, RES_X, 1, 0);
  292. input_abs_set_res(input_dev, ABS_X, RES_X / WIDTH);
  293. input_set_abs_params(input_dev, ABS_Y, 0, RES_Y, 1, 0);
  294. input_abs_set_res(input_dev, ABS_Y, RES_Y / HEIGHT);
  295. input_set_abs_params(input_dev, ABS_PRESSURE,
  296. 0, MAX_PRESSURE, 0, 0);
  297. set_bit(BTN_TOUCH, input_dev->keybit);
  298. set_bit(BTN_TOOL_PEN, input_dev->keybit);
  299. set_bit(INPUT_PROP_POINTER, input_dev->propbit);
  300. udraw->pen_input_dev = input_dev;
  301. return true;
  302. }
  303. static bool udraw_setup_accel(struct udraw *udraw,
  304. struct hid_device *hdev)
  305. {
  306. struct input_dev *input_dev;
  307. input_dev = allocate_and_setup(hdev, DEVICE_NAME " Accelerometer");
  308. if (!input_dev)
  309. return false;
  310. input_dev->evbit[0] = BIT(EV_ABS);
  311. /* 1G accel is reported as ~256, so clamp to 2G */
  312. input_set_abs_params(input_dev, ABS_X, -512, 512, 0, 0);
  313. input_set_abs_params(input_dev, ABS_Y, -512, 512, 0, 0);
  314. input_set_abs_params(input_dev, ABS_Z, -512, 512, 0, 0);
  315. set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);
  316. udraw->accel_input_dev = input_dev;
  317. return true;
  318. }
  319. static bool udraw_setup_joypad(struct udraw *udraw,
  320. struct hid_device *hdev)
  321. {
  322. struct input_dev *input_dev;
  323. input_dev = allocate_and_setup(hdev, DEVICE_NAME " Joypad");
  324. if (!input_dev)
  325. return false;
  326. input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
  327. set_bit(BTN_SOUTH, input_dev->keybit);
  328. set_bit(BTN_NORTH, input_dev->keybit);
  329. set_bit(BTN_EAST, input_dev->keybit);
  330. set_bit(BTN_WEST, input_dev->keybit);
  331. set_bit(BTN_SELECT, input_dev->keybit);
  332. set_bit(BTN_START, input_dev->keybit);
  333. set_bit(BTN_MODE, input_dev->keybit);
  334. input_set_abs_params(input_dev, ABS_X, -127, 127, 0, 0);
  335. input_set_abs_params(input_dev, ABS_Y, -127, 127, 0, 0);
  336. udraw->joy_input_dev = input_dev;
  337. return true;
  338. }
  339. static int udraw_probe(struct hid_device *hdev, const struct hid_device_id *id)
  340. {
  341. struct udraw *udraw;
  342. int ret;
  343. udraw = devm_kzalloc(&hdev->dev, sizeof(struct udraw), GFP_KERNEL);
  344. if (!udraw)
  345. return -ENOMEM;
  346. udraw->hdev = hdev;
  347. udraw->last_two_finger_x = -1;
  348. udraw->last_two_finger_y = -1;
  349. hid_set_drvdata(hdev, udraw);
  350. ret = hid_parse(hdev);
  351. if (ret) {
  352. hid_err(hdev, "parse failed\n");
  353. return ret;
  354. }
  355. if (!udraw_setup_joypad(udraw, hdev) ||
  356. !udraw_setup_touch(udraw, hdev) ||
  357. !udraw_setup_pen(udraw, hdev) ||
  358. !udraw_setup_accel(udraw, hdev)) {
  359. hid_err(hdev, "could not allocate interfaces\n");
  360. return -ENOMEM;
  361. }
  362. ret = input_register_device(udraw->joy_input_dev) ||
  363. input_register_device(udraw->touch_input_dev) ||
  364. input_register_device(udraw->pen_input_dev) ||
  365. input_register_device(udraw->accel_input_dev);
  366. if (ret) {
  367. hid_err(hdev, "failed to register interfaces\n");
  368. return ret;
  369. }
  370. ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW | HID_CONNECT_DRIVER);
  371. if (ret) {
  372. hid_err(hdev, "hw start failed\n");
  373. return ret;
  374. }
  375. return 0;
  376. }
  377. static const struct hid_device_id udraw_devices[] = {
  378. { HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
  379. { }
  380. };
  381. MODULE_DEVICE_TABLE(hid, udraw_devices);
  382. static struct hid_driver udraw_driver = {
  383. .name = "hid-udraw",
  384. .id_table = udraw_devices,
  385. .raw_event = udraw_raw_event,
  386. .probe = udraw_probe,
  387. };
  388. module_hid_driver(udraw_driver);