hid-wacom.c 25 KB

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