hid-wacom.c 18 KB

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