hid-wacom.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. /*
  2. * Bluetooth Wacom Tablet support
  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 <jirislaby@gmail.com>
  10. * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru>
  11. * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net>
  12. * Copyright (c) 2011 Przemysław Firszt <przemo@firszt.eu>
  13. */
  14. /*
  15. * This program is free software; you can redistribute it and/or modify it
  16. * under the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. */
  20. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  21. #include <linux/device.h>
  22. #include <linux/hid.h>
  23. #include <linux/module.h>
  24. #include <linux/leds.h>
  25. #include <linux/slab.h>
  26. #include <linux/power_supply.h>
  27. #include "hid-ids.h"
  28. #define PAD_DEVICE_ID 0x0F
  29. #define WAC_CMD_LED_CONTROL 0x20
  30. struct wacom_data {
  31. __u16 tool;
  32. __u16 butstate;
  33. __u8 whlstate;
  34. __u8 features;
  35. __u32 id;
  36. __u32 serial;
  37. unsigned char high_speed;
  38. __u8 battery_capacity;
  39. __u8 power_raw;
  40. __u8 ps_connected;
  41. struct power_supply battery;
  42. struct power_supply ac;
  43. __u8 led_selector;
  44. struct led_classdev *leds[4];
  45. };
  46. /*percent of battery capacity for Graphire
  47. 8th value means AC online and show 100% capacity */
  48. static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
  49. /*percent of battery capacity for Intuos4 WL, AC has a separate bit*/
  50. static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
  51. static enum power_supply_property wacom_battery_props[] = {
  52. POWER_SUPPLY_PROP_PRESENT,
  53. POWER_SUPPLY_PROP_CAPACITY,
  54. POWER_SUPPLY_PROP_SCOPE,
  55. };
  56. static enum power_supply_property wacom_ac_props[] = {
  57. POWER_SUPPLY_PROP_PRESENT,
  58. POWER_SUPPLY_PROP_ONLINE,
  59. POWER_SUPPLY_PROP_SCOPE,
  60. };
  61. static void wacom_leds_set_brightness(struct led_classdev *led_dev,
  62. enum led_brightness value)
  63. {
  64. struct device *dev = led_dev->dev->parent;
  65. struct hid_device *hdev;
  66. struct wacom_data *wdata;
  67. unsigned char *buf;
  68. __u8 led = 0;
  69. int i;
  70. hdev = container_of(dev, struct hid_device, dev);
  71. wdata = hid_get_drvdata(hdev);
  72. for (i = 0; i < 4; ++i) {
  73. if (wdata->leds[i] == led_dev)
  74. wdata->led_selector = i;
  75. }
  76. led = wdata->led_selector | 0x04;
  77. buf = kzalloc(9, GFP_KERNEL);
  78. if (buf) {
  79. buf[0] = WAC_CMD_LED_CONTROL;
  80. buf[1] = led;
  81. buf[2] = value;
  82. hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT);
  83. kfree(buf);
  84. }
  85. return;
  86. }
  87. static enum led_brightness wacom_leds_get_brightness(struct led_classdev *led_dev)
  88. {
  89. struct wacom_data *wdata;
  90. struct device *dev = led_dev->dev->parent;
  91. int value = 0;
  92. int i;
  93. wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
  94. for (i = 0; i < 4; ++i) {
  95. if (wdata->leds[i] == led_dev) {
  96. value = wdata->leds[i]->brightness;
  97. break;
  98. }
  99. }
  100. return value;
  101. }
  102. static int wacom_initialize_leds(struct hid_device *hdev)
  103. {
  104. struct wacom_data *wdata = hid_get_drvdata(hdev);
  105. struct led_classdev *led;
  106. struct device *dev = &hdev->dev;
  107. size_t namesz = strlen(dev_name(dev)) + 12;
  108. char *name;
  109. int i, ret;
  110. wdata->led_selector = 0;
  111. for (i = 0; i < 4; i++) {
  112. led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
  113. if (!led) {
  114. hid_warn(hdev,
  115. "can't allocate memory for LED selector\n");
  116. ret = -ENOMEM;
  117. goto err;
  118. }
  119. name = (void *)&led[1];
  120. snprintf(name, namesz, "%s:selector:%d", dev_name(dev), i);
  121. led->name = name;
  122. led->brightness = 0;
  123. led->max_brightness = 127;
  124. led->brightness_get = wacom_leds_get_brightness;
  125. led->brightness_set = wacom_leds_set_brightness;
  126. wdata->leds[i] = led;
  127. ret = led_classdev_register(dev, wdata->leds[i]);
  128. if (ret) {
  129. wdata->leds[i] = NULL;
  130. kfree(led);
  131. hid_warn(hdev, "can't register LED\n");
  132. goto err;
  133. }
  134. }
  135. err:
  136. return ret;
  137. }
  138. static void wacom_destroy_leds(struct hid_device *hdev)
  139. {
  140. struct wacom_data *wdata = hid_get_drvdata(hdev);
  141. struct led_classdev *led;
  142. int i;
  143. for (i = 0; i < 4; ++i) {
  144. if (wdata->leds[i]) {
  145. led = wdata->leds[i];
  146. wdata->leds[i] = NULL;
  147. led_classdev_unregister(led);
  148. kfree(led);
  149. }
  150. }
  151. }
  152. static int wacom_battery_get_property(struct power_supply *psy,
  153. enum power_supply_property psp,
  154. union power_supply_propval *val)
  155. {
  156. struct wacom_data *wdata = container_of(psy,
  157. struct wacom_data, battery);
  158. int ret = 0;
  159. switch (psp) {
  160. case POWER_SUPPLY_PROP_PRESENT:
  161. val->intval = 1;
  162. break;
  163. case POWER_SUPPLY_PROP_SCOPE:
  164. val->intval = POWER_SUPPLY_SCOPE_DEVICE;
  165. break;
  166. case POWER_SUPPLY_PROP_CAPACITY:
  167. val->intval = wdata->battery_capacity;
  168. break;
  169. default:
  170. ret = -EINVAL;
  171. break;
  172. }
  173. return ret;
  174. }
  175. static int wacom_ac_get_property(struct power_supply *psy,
  176. enum power_supply_property psp,
  177. union power_supply_propval *val)
  178. {
  179. struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
  180. int ret = 0;
  181. switch (psp) {
  182. case POWER_SUPPLY_PROP_PRESENT:
  183. /* fall through */
  184. case POWER_SUPPLY_PROP_ONLINE:
  185. val->intval = wdata->ps_connected;
  186. break;
  187. case POWER_SUPPLY_PROP_SCOPE:
  188. val->intval = POWER_SUPPLY_SCOPE_DEVICE;
  189. break;
  190. default:
  191. ret = -EINVAL;
  192. break;
  193. }
  194. return ret;
  195. }
  196. static void wacom_set_features(struct hid_device *hdev, u8 speed)
  197. {
  198. struct wacom_data *wdata = hid_get_drvdata(hdev);
  199. int limit, ret;
  200. __u8 rep_data[2];
  201. switch (hdev->product) {
  202. case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
  203. rep_data[0] = 0x03 ; rep_data[1] = 0x00;
  204. limit = 3;
  205. do {
  206. ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
  207. HID_FEATURE_REPORT);
  208. } while (ret < 0 && limit-- > 0);
  209. if (ret >= 0) {
  210. if (speed == 0)
  211. rep_data[0] = 0x05;
  212. else
  213. rep_data[0] = 0x06;
  214. rep_data[1] = 0x00;
  215. limit = 3;
  216. do {
  217. ret = hdev->hid_output_raw_report(hdev,
  218. rep_data, 2, HID_FEATURE_REPORT);
  219. } while (ret < 0 && limit-- > 0);
  220. if (ret >= 0) {
  221. wdata->high_speed = speed;
  222. return;
  223. }
  224. }
  225. /*
  226. * Note that if the raw queries fail, it's not a hard failure
  227. * and it is safe to continue
  228. */
  229. hid_warn(hdev, "failed to poke device, command %d, err %d\n",
  230. rep_data[0], ret);
  231. break;
  232. case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
  233. if (speed == 1)
  234. wdata->features &= ~0x20;
  235. else
  236. wdata->features |= 0x20;
  237. rep_data[0] = 0x03;
  238. rep_data[1] = wdata->features;
  239. ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
  240. HID_FEATURE_REPORT);
  241. if (ret >= 0)
  242. wdata->high_speed = speed;
  243. break;
  244. }
  245. return;
  246. }
  247. static ssize_t wacom_show_speed(struct device *dev,
  248. struct device_attribute
  249. *attr, char *buf)
  250. {
  251. struct wacom_data *wdata = dev_get_drvdata(dev);
  252. return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
  253. }
  254. static ssize_t wacom_store_speed(struct device *dev,
  255. struct device_attribute *attr,
  256. const char *buf, size_t count)
  257. {
  258. struct hid_device *hdev = container_of(dev, struct hid_device, dev);
  259. int new_speed;
  260. if (sscanf(buf, "%1d", &new_speed ) != 1)
  261. return -EINVAL;
  262. if (new_speed == 0 || new_speed == 1) {
  263. wacom_set_features(hdev, new_speed);
  264. return strnlen(buf, PAGE_SIZE);
  265. } else
  266. return -EINVAL;
  267. }
  268. static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
  269. wacom_show_speed, wacom_store_speed);
  270. static int wacom_gr_parse_report(struct hid_device *hdev,
  271. struct wacom_data *wdata,
  272. struct input_dev *input, unsigned char *data)
  273. {
  274. int tool, x, y, rw;
  275. tool = 0;
  276. /* Get X & Y positions */
  277. x = le16_to_cpu(*(__le16 *) &data[2]);
  278. y = le16_to_cpu(*(__le16 *) &data[4]);
  279. /* Get current tool identifier */
  280. if (data[1] & 0x90) { /* If pen is in the in/active area */
  281. switch ((data[1] >> 5) & 3) {
  282. case 0: /* Pen */
  283. tool = BTN_TOOL_PEN;
  284. break;
  285. case 1: /* Rubber */
  286. tool = BTN_TOOL_RUBBER;
  287. break;
  288. case 2: /* Mouse with wheel */
  289. case 3: /* Mouse without wheel */
  290. tool = BTN_TOOL_MOUSE;
  291. break;
  292. }
  293. /* Reset tool if out of active tablet area */
  294. if (!(data[1] & 0x10))
  295. tool = 0;
  296. }
  297. /* If tool changed, notify input subsystem */
  298. if (wdata->tool != tool) {
  299. if (wdata->tool) {
  300. /* Completely reset old tool state */
  301. if (wdata->tool == BTN_TOOL_MOUSE) {
  302. input_report_key(input, BTN_LEFT, 0);
  303. input_report_key(input, BTN_RIGHT, 0);
  304. input_report_key(input, BTN_MIDDLE, 0);
  305. input_report_abs(input, ABS_DISTANCE,
  306. input_abs_get_max(input, ABS_DISTANCE));
  307. } else {
  308. input_report_key(input, BTN_TOUCH, 0);
  309. input_report_key(input, BTN_STYLUS, 0);
  310. input_report_key(input, BTN_STYLUS2, 0);
  311. input_report_abs(input, ABS_PRESSURE, 0);
  312. }
  313. input_report_key(input, wdata->tool, 0);
  314. input_sync(input);
  315. }
  316. wdata->tool = tool;
  317. if (tool)
  318. input_report_key(input, tool, 1);
  319. }
  320. if (tool) {
  321. input_report_abs(input, ABS_X, x);
  322. input_report_abs(input, ABS_Y, y);
  323. switch ((data[1] >> 5) & 3) {
  324. case 2: /* Mouse with wheel */
  325. input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
  326. rw = (data[6] & 0x01) ? -1 :
  327. (data[6] & 0x02) ? 1 : 0;
  328. input_report_rel(input, REL_WHEEL, rw);
  329. /* fall through */
  330. case 3: /* Mouse without wheel */
  331. input_report_key(input, BTN_LEFT, data[1] & 0x01);
  332. input_report_key(input, BTN_RIGHT, data[1] & 0x02);
  333. /* Compute distance between mouse and tablet */
  334. rw = 44 - (data[6] >> 2);
  335. if (rw < 0)
  336. rw = 0;
  337. else if (rw > 31)
  338. rw = 31;
  339. input_report_abs(input, ABS_DISTANCE, rw);
  340. break;
  341. default:
  342. input_report_abs(input, ABS_PRESSURE,
  343. data[6] | (((__u16) (data[1] & 0x08)) << 5));
  344. input_report_key(input, BTN_TOUCH, data[1] & 0x01);
  345. input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  346. input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
  347. break;
  348. }
  349. input_sync(input);
  350. }
  351. /* Report the state of the two buttons at the top of the tablet
  352. * as two extra fingerpad keys (buttons 4 & 5). */
  353. rw = data[7] & 0x03;
  354. if (rw != wdata->butstate) {
  355. wdata->butstate = rw;
  356. input_report_key(input, BTN_0, rw & 0x02);
  357. input_report_key(input, BTN_1, rw & 0x01);
  358. input_report_key(input, BTN_TOOL_FINGER, 0xf0);
  359. input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
  360. input_sync(input);
  361. }
  362. /* Store current battery capacity and power supply state*/
  363. rw = (data[7] >> 2 & 0x07);
  364. if (rw != wdata->power_raw) {
  365. wdata->power_raw = rw;
  366. wdata->battery_capacity = batcap_gr[rw];
  367. if (rw == 7)
  368. wdata->ps_connected = 1;
  369. else
  370. wdata->ps_connected = 0;
  371. }
  372. return 1;
  373. }
  374. static void wacom_i4_parse_button_report(struct wacom_data *wdata,
  375. struct input_dev *input, unsigned char *data)
  376. {
  377. __u16 new_butstate;
  378. __u8 new_whlstate;
  379. __u8 sync = 0;
  380. new_whlstate = data[1];
  381. if (new_whlstate != wdata->whlstate) {
  382. wdata->whlstate = new_whlstate;
  383. if (new_whlstate & 0x80) {
  384. input_report_key(input, BTN_TOUCH, 1);
  385. input_report_abs(input, ABS_WHEEL, (new_whlstate & 0x7f));
  386. input_report_key(input, BTN_TOOL_FINGER, 1);
  387. } else {
  388. input_report_key(input, BTN_TOUCH, 0);
  389. input_report_abs(input, ABS_WHEEL, 0);
  390. input_report_key(input, BTN_TOOL_FINGER, 0);
  391. }
  392. sync = 1;
  393. }
  394. new_butstate = (data[3] << 1) | (data[2] & 0x01);
  395. if (new_butstate != wdata->butstate) {
  396. wdata->butstate = new_butstate;
  397. input_report_key(input, BTN_0, new_butstate & 0x001);
  398. input_report_key(input, BTN_1, new_butstate & 0x002);
  399. input_report_key(input, BTN_2, new_butstate & 0x004);
  400. input_report_key(input, BTN_3, new_butstate & 0x008);
  401. input_report_key(input, BTN_4, new_butstate & 0x010);
  402. input_report_key(input, BTN_5, new_butstate & 0x020);
  403. input_report_key(input, BTN_6, new_butstate & 0x040);
  404. input_report_key(input, BTN_7, new_butstate & 0x080);
  405. input_report_key(input, BTN_8, new_butstate & 0x100);
  406. input_report_key(input, BTN_TOOL_FINGER, 1);
  407. sync = 1;
  408. }
  409. if (sync) {
  410. input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
  411. input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
  412. input_sync(input);
  413. }
  414. }
  415. static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
  416. struct input_dev *input, unsigned char *data)
  417. {
  418. __u16 x, y, pressure;
  419. __u8 distance;
  420. __u8 tilt_x, tilt_y;
  421. switch (data[1]) {
  422. case 0x80: /* Out of proximity report */
  423. input_report_key(input, BTN_TOUCH, 0);
  424. input_report_abs(input, ABS_PRESSURE, 0);
  425. input_report_key(input, BTN_STYLUS, 0);
  426. input_report_key(input, BTN_STYLUS2, 0);
  427. input_report_key(input, wdata->tool, 0);
  428. input_report_abs(input, ABS_MISC, 0);
  429. input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
  430. wdata->tool = 0;
  431. input_sync(input);
  432. break;
  433. case 0xC2: /* Tool report */
  434. wdata->id = ((data[2] << 4) | (data[3] >> 4) |
  435. ((data[7] & 0x0f) << 20) |
  436. ((data[8] & 0xf0) << 12));
  437. wdata->serial = ((data[3] & 0x0f) << 28) +
  438. (data[4] << 20) + (data[5] << 12) +
  439. (data[6] << 4) + (data[7] >> 4);
  440. switch (wdata->id) {
  441. case 0x100802:
  442. wdata->tool = BTN_TOOL_PEN;
  443. break;
  444. case 0x10080A:
  445. wdata->tool = BTN_TOOL_RUBBER;
  446. break;
  447. }
  448. break;
  449. default: /* Position/pressure report */
  450. x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1);
  451. y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
  452. pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
  453. | (data[1] & 0x01);
  454. distance = (data[9] >> 2) & 0x3f;
  455. tilt_x = ((data[7] << 1) & 0x7e) | (data[8] >> 7);
  456. tilt_y = data[8] & 0x7f;
  457. input_report_key(input, BTN_TOUCH, pressure > 1);
  458. input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  459. input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
  460. input_report_key(input, wdata->tool, 1);
  461. input_report_abs(input, ABS_X, x);
  462. input_report_abs(input, ABS_Y, y);
  463. input_report_abs(input, ABS_PRESSURE, pressure);
  464. input_report_abs(input, ABS_DISTANCE, distance);
  465. input_report_abs(input, ABS_TILT_X, tilt_x);
  466. input_report_abs(input, ABS_TILT_Y, tilt_y);
  467. input_report_abs(input, ABS_MISC, wdata->id);
  468. input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
  469. input_report_key(input, wdata->tool, 1);
  470. input_sync(input);
  471. break;
  472. }
  473. return;
  474. }
  475. static void wacom_i4_parse_report(struct hid_device *hdev,
  476. struct wacom_data *wdata,
  477. struct input_dev *input, unsigned char *data)
  478. {
  479. switch (data[0]) {
  480. case 0x00: /* Empty report */
  481. break;
  482. case 0x02: /* Pen report */
  483. wacom_i4_parse_pen_report(wdata, input, data);
  484. break;
  485. case 0x03: /* Features Report */
  486. wdata->features = data[2];
  487. break;
  488. case 0x0C: /* Button report */
  489. wacom_i4_parse_button_report(wdata, input, data);
  490. break;
  491. default:
  492. hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]);
  493. break;
  494. }
  495. }
  496. static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
  497. u8 *raw_data, int size)
  498. {
  499. struct wacom_data *wdata = hid_get_drvdata(hdev);
  500. struct hid_input *hidinput;
  501. struct input_dev *input;
  502. unsigned char *data = (unsigned char *) raw_data;
  503. int i;
  504. __u8 power_raw;
  505. if (!(hdev->claimed & HID_CLAIMED_INPUT))
  506. return 0;
  507. hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
  508. input = hidinput->input;
  509. switch (hdev->product) {
  510. case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
  511. if (data[0] == 0x03) {
  512. return wacom_gr_parse_report(hdev, wdata, input, data);
  513. } else {
  514. hid_err(hdev, "Unknown report: %d,%d size:%d\n",
  515. data[0], data[1], size);
  516. return 0;
  517. }
  518. break;
  519. case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
  520. i = 1;
  521. switch (data[0]) {
  522. case 0x04:
  523. wacom_i4_parse_report(hdev, wdata, input, data + i);
  524. i += 10;
  525. /* fall through */
  526. case 0x03:
  527. wacom_i4_parse_report(hdev, wdata, input, data + i);
  528. i += 10;
  529. wacom_i4_parse_report(hdev, wdata, input, data + i);
  530. power_raw = data[i+10];
  531. if (power_raw != wdata->power_raw) {
  532. wdata->power_raw = power_raw;
  533. wdata->battery_capacity = batcap_i4[power_raw & 0x07];
  534. wdata->ps_connected = power_raw & 0x08;
  535. }
  536. break;
  537. default:
  538. hid_err(hdev, "Unknown report: %d,%d size:%d\n",
  539. data[0], data[1], size);
  540. return 0;
  541. }
  542. }
  543. return 1;
  544. }
  545. static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
  546. struct hid_field *field, struct hid_usage *usage, unsigned long **bit,
  547. int *max)
  548. {
  549. struct input_dev *input = hi->input;
  550. __set_bit(INPUT_PROP_POINTER, input->propbit);
  551. /* Basics */
  552. input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
  553. __set_bit(REL_WHEEL, input->relbit);
  554. __set_bit(BTN_TOOL_PEN, input->keybit);
  555. __set_bit(BTN_TOUCH, input->keybit);
  556. __set_bit(BTN_STYLUS, input->keybit);
  557. __set_bit(BTN_STYLUS2, input->keybit);
  558. __set_bit(BTN_LEFT, input->keybit);
  559. __set_bit(BTN_RIGHT, input->keybit);
  560. __set_bit(BTN_MIDDLE, input->keybit);
  561. /* Pad */
  562. input_set_capability(input, EV_MSC, MSC_SERIAL);
  563. __set_bit(BTN_0, input->keybit);
  564. __set_bit(BTN_1, input->keybit);
  565. __set_bit(BTN_TOOL_FINGER, input->keybit);
  566. /* Distance, rubber and mouse */
  567. __set_bit(BTN_TOOL_RUBBER, input->keybit);
  568. __set_bit(BTN_TOOL_MOUSE, input->keybit);
  569. switch (hdev->product) {
  570. case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
  571. input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
  572. input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
  573. input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
  574. input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
  575. break;
  576. case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
  577. __set_bit(ABS_WHEEL, input->absbit);
  578. __set_bit(ABS_MISC, input->absbit);
  579. __set_bit(BTN_2, input->keybit);
  580. __set_bit(BTN_3, input->keybit);
  581. __set_bit(BTN_4, input->keybit);
  582. __set_bit(BTN_5, input->keybit);
  583. __set_bit(BTN_6, input->keybit);
  584. __set_bit(BTN_7, input->keybit);
  585. __set_bit(BTN_8, input->keybit);
  586. input_set_abs_params(input, ABS_WHEEL, 0, 71, 0, 0);
  587. input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
  588. input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
  589. input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
  590. input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0);
  591. input_set_abs_params(input, ABS_TILT_X, 0, 127, 0, 0);
  592. input_set_abs_params(input, ABS_TILT_Y, 0, 127, 0, 0);
  593. break;
  594. }
  595. return 0;
  596. }
  597. static int wacom_probe(struct hid_device *hdev,
  598. const struct hid_device_id *id)
  599. {
  600. struct wacom_data *wdata;
  601. int ret;
  602. wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
  603. if (wdata == NULL) {
  604. hid_err(hdev, "can't alloc wacom descriptor\n");
  605. return -ENOMEM;
  606. }
  607. hid_set_drvdata(hdev, wdata);
  608. /* Parse the HID report now */
  609. ret = hid_parse(hdev);
  610. if (ret) {
  611. hid_err(hdev, "parse failed\n");
  612. goto err_free;
  613. }
  614. ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
  615. if (ret) {
  616. hid_err(hdev, "hw start failed\n");
  617. goto err_free;
  618. }
  619. ret = device_create_file(&hdev->dev, &dev_attr_speed);
  620. if (ret)
  621. hid_warn(hdev,
  622. "can't create sysfs speed attribute err: %d\n", ret);
  623. wdata->features = 0;
  624. wacom_set_features(hdev, 1);
  625. if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) {
  626. sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
  627. ret = wacom_initialize_leds(hdev);
  628. if (ret) {
  629. hid_warn(hdev,
  630. "can't create led attribute, err: %d\n", ret);
  631. goto destroy_leds;
  632. }
  633. }
  634. wdata->battery.properties = wacom_battery_props;
  635. wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
  636. wdata->battery.get_property = wacom_battery_get_property;
  637. wdata->battery.name = "wacom_battery";
  638. wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
  639. wdata->battery.use_for_apm = 0;
  640. ret = power_supply_register(&hdev->dev, &wdata->battery);
  641. if (ret) {
  642. hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
  643. ret);
  644. goto err_battery;
  645. }
  646. power_supply_powers(&wdata->battery, &hdev->dev);
  647. wdata->ac.properties = wacom_ac_props;
  648. wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
  649. wdata->ac.get_property = wacom_ac_get_property;
  650. wdata->ac.name = "wacom_ac";
  651. wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
  652. wdata->ac.use_for_apm = 0;
  653. ret = power_supply_register(&hdev->dev, &wdata->ac);
  654. if (ret) {
  655. hid_warn(hdev,
  656. "can't create ac battery attribute, err: %d\n", ret);
  657. goto err_ac;
  658. }
  659. power_supply_powers(&wdata->ac, &hdev->dev);
  660. return 0;
  661. err_ac:
  662. power_supply_unregister(&wdata->battery);
  663. err_battery:
  664. device_remove_file(&hdev->dev, &dev_attr_speed);
  665. hid_hw_stop(hdev);
  666. destroy_leds:
  667. wacom_destroy_leds(hdev);
  668. err_free:
  669. kfree(wdata);
  670. return ret;
  671. }
  672. static void wacom_remove(struct hid_device *hdev)
  673. {
  674. struct wacom_data *wdata = hid_get_drvdata(hdev);
  675. wacom_destroy_leds(hdev);
  676. device_remove_file(&hdev->dev, &dev_attr_speed);
  677. hid_hw_stop(hdev);
  678. power_supply_unregister(&wdata->battery);
  679. power_supply_unregister(&wdata->ac);
  680. kfree(hid_get_drvdata(hdev));
  681. }
  682. static const struct hid_device_id wacom_devices[] = {
  683. { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
  684. { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
  685. { }
  686. };
  687. MODULE_DEVICE_TABLE(hid, wacom_devices);
  688. static struct hid_driver wacom_driver = {
  689. .name = "wacom",
  690. .id_table = wacom_devices,
  691. .probe = wacom_probe,
  692. .remove = wacom_remove,
  693. .raw_event = wacom_raw_event,
  694. .input_mapped = wacom_input_mapped,
  695. };
  696. static int __init wacom_init(void)
  697. {
  698. int ret;
  699. ret = hid_register_driver(&wacom_driver);
  700. if (ret)
  701. pr_err("can't register wacom driver\n");
  702. return ret;
  703. }
  704. static void __exit wacom_exit(void)
  705. {
  706. hid_unregister_driver(&wacom_driver);
  707. }
  708. module_init(wacom_init);
  709. module_exit(wacom_exit);
  710. MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
  711. MODULE_LICENSE("GPL");