aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 20:39:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 20:39:48 -0400
commit664fb23070ae66a023250a83870a5bae7cd0efeb (patch)
treefb2c18fcd1742ece0813d4c316f42ac23c01cd04 /drivers/hid
parent8065be8d032f38da25b54bf077a05a30d9ce9f2a (diff)
parentc704b4ef1a819b053fd33617e861da1932077314 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov: - big update to Wacom driver by Benjamin Tissoires, converting it to HID infrastructure and unifying USB and Bluetooth models - large update to ALPS driver by Hans de Goede, which adds support for newer touchpad models as well as cleans up and restructures the code - more changes to Atmel MXT driver, including device tree support - new driver for iPaq x3xxx touchscreen - driver for serial Wacom tablets - driver for Microchip's CAP1106 - assorted cleanups and improvements to existing drover and input core * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (93 commits) Input: wacom - update the ABI doc according to latest changes Input: wacom - only register once the MODULE_* macros Input: HID - remove hid-wacom Bluetooth driver Input: wacom - add copyright note and bump version to 2.0 Input: wacom - remove passing id for wacom_set_report Input: wacom - check for bluetooth protocol while setting OLEDs Input: wacom - handle Intuos 4 BT in wacom.ko Input: wacom - handle Graphire BT tablets in wacom.ko Input: wacom - prepare the driver to include BT devices Input: hyperv-keyboard - register as a wakeup source Input: imx_keypad - remove ifdef round PM methods Input: jornada720_ts - get rid of space indentation and use tab Input: jornada720_ts - switch to using managed resources Input: alps - Rushmore and v7 resolution support Input: mcs5000_ts - remove ifdef around power management methods Input: mcs5000_ts - protect PM functions with CONFIG_PM_SLEEP Input: ads7846 - release resources on failure for clean exit Input: wacom - add support for 0x12C ISDv4 sensor Input: atmel_mxt_ts - use deep sleep mode when stopped ARM: dts: am437x-gp-evm: Update binding for touchscreen size ...
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig13
-rw-r--r--drivers/hid/Makefile4
-rw-r--r--drivers/hid/hid-core.c12
-rw-r--r--drivers/hid/hid-wacom.c973
-rw-r--r--drivers/hid/wacom.h146
-rw-r--r--drivers/hid/wacom_sys.c1456
-rw-r--r--drivers/hid/wacom_wac.c2721
-rw-r--r--drivers/hid/wacom_wac.h179
8 files changed, 4523 insertions, 981 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index ec48c823b157..c18d5d71062d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -764,12 +764,17 @@ config THRUSTMASTER_FF
764 Rumble Force or Force Feedback Wheel. 764 Rumble Force or Force Feedback Wheel.
765 765
766config HID_WACOM 766config HID_WACOM
767 tristate "Wacom Bluetooth devices support" 767 tristate "Wacom Intuos/Graphire tablet support (USB)"
768 depends on HID 768 depends on HID
769 depends on LEDS_CLASS
770 select POWER_SUPPLY 769 select POWER_SUPPLY
771 ---help--- 770 select NEW_LEDS
772 Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. 771 select LEDS_CLASS
772 help
773 Say Y here if you want to use the USB or BT version of the Wacom Intuos
774 or Graphire tablet.
775
776 To compile this driver as a module, choose M here: the
777 module will be called wacom.
773 778
774config HID_WIIMOTE 779config HID_WIIMOTE
775 tristate "Nintendo Wii / Wii U peripherals" 780 tristate "Nintendo Wii / Wii U peripherals"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a69f0adb5c76..4dbac7f8530c 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -116,7 +116,9 @@ obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
116obj-$(CONFIG_HID_XINMO) += hid-xinmo.o 116obj-$(CONFIG_HID_XINMO) += hid-xinmo.o
117obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o 117obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
118obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o 118obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
119obj-$(CONFIG_HID_WACOM) += hid-wacom.o 119
120wacom-objs := wacom_wac.o wacom_sys.o
121obj-$(CONFIG_HID_WACOM) += wacom.o
120obj-$(CONFIG_HID_WALTOP) += hid-waltop.o 122obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
121obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o 123obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
122obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o 124obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b52baa120ffa..12b6e67d9de0 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -789,6 +789,15 @@ static int hid_scan_report(struct hid_device *hid)
789 /* hid-rmi should take care of them, not hid-generic */ 789 /* hid-rmi should take care of them, not hid-generic */
790 hid->group = HID_GROUP_RMI; 790 hid->group = HID_GROUP_RMI;
791 791
792 /*
793 * Vendor specific handlings
794 */
795 switch (hid->vendor) {
796 case USB_VENDOR_ID_WACOM:
797 hid->group = HID_GROUP_WACOM;
798 break;
799 }
800
792 vfree(parser); 801 vfree(parser);
793 return 0; 802 return 0;
794} 803}
@@ -1938,8 +1947,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
1938 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, 1947 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
1939 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, 1948 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
1940 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, 1949 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
1941 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1942 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
1943 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, 1950 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
1944 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, 1951 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
1945 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) }, 1952 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) },
@@ -2345,7 +2352,6 @@ static const struct hid_device_id hid_ignore_list[] = {
2345 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, 2352 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
2346 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, 2353 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
2347 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, 2354 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
2348 { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) },
2349 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, 2355 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) },
2350 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, 2356 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
2351 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, 2357 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
deleted file mode 100644
index 902013ec041b..000000000000
--- a/drivers/hid/hid-wacom.c
+++ /dev/null
@@ -1,973 +0,0 @@
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/*
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
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/device.h>
24#include <linux/hid.h>
25#include <linux/module.h>
26#include <linux/leds.h>
27#include <linux/slab.h>
28#include <linux/power_supply.h>
29
30#include "hid-ids.h"
31
32#define PAD_DEVICE_ID 0x0F
33
34#define WAC_CMD_LED_CONTROL 0x20
35#define WAC_CMD_ICON_START_STOP 0x21
36#define WAC_CMD_ICON_TRANSFER 0x26
37
38struct wacom_data {
39 __u16 tool;
40 __u16 butstate;
41 __u8 whlstate;
42 __u8 features;
43 __u32 id;
44 __u32 serial;
45 unsigned char high_speed;
46 __u8 battery_capacity;
47 __u8 power_raw;
48 __u8 ps_connected;
49 __u8 bat_charging;
50 struct power_supply battery;
51 struct power_supply ac;
52 __u8 led_selector;
53 struct led_classdev *leds[4];
54};
55
56/*percent of battery capacity for Graphire
57 8th value means AC online and show 100% capacity */
58static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
59/*percent of battery capacity for Intuos4 WL, AC has a separate bit*/
60static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
61
62static enum power_supply_property wacom_battery_props[] = {
63 POWER_SUPPLY_PROP_PRESENT,
64 POWER_SUPPLY_PROP_CAPACITY,
65 POWER_SUPPLY_PROP_SCOPE,
66 POWER_SUPPLY_PROP_STATUS,
67};
68
69static enum power_supply_property wacom_ac_props[] = {
70 POWER_SUPPLY_PROP_PRESENT,
71 POWER_SUPPLY_PROP_ONLINE,
72 POWER_SUPPLY_PROP_SCOPE,
73};
74
75static void wacom_scramble(__u8 *image)
76{
77 __u16 mask;
78 __u16 s1;
79 __u16 s2;
80 __u16 r1 ;
81 __u16 r2 ;
82 __u16 r;
83 __u8 buf[256];
84 int i, w, x, y, z;
85
86 for (x = 0; x < 32; x++) {
87 for (y = 0; y < 8; y++)
88 buf[(8 * x) + (7 - y)] = image[(8 * x) + y];
89 }
90
91 /* Change 76543210 into GECA6420 as required by Intuos4 WL
92 * HGFEDCBA HFDB7531
93 */
94 for (x = 0; x < 4; x++) {
95 for (y = 0; y < 4; y++) {
96 for (z = 0; z < 8; z++) {
97 mask = 0x0001;
98 r1 = 0;
99 r2 = 0;
100 i = (x << 6) + (y << 4) + z;
101 s1 = buf[i];
102 s2 = buf[i+8];
103 for (w = 0; w < 8; w++) {
104 r1 |= (s1 & mask);
105 r2 |= (s2 & mask);
106 s1 <<= 1;
107 s2 <<= 1;
108 mask <<= 2;
109 }
110 r = r1 | (r2 << 1);
111 i = (x << 6) + (y << 4) + (z << 1);
112 image[i] = 0xFF & r;
113 image[i+1] = (0xFF00 & r) >> 8;
114 }
115 }
116 }
117}
118
119static void wacom_set_image(struct hid_device *hdev, const char *image,
120 __u8 icon_no)
121{
122 __u8 rep_data[68];
123 __u8 p[256];
124 int ret, i, j;
125
126 for (i = 0; i < 256; i++)
127 p[i] = image[i];
128
129 rep_data[0] = WAC_CMD_ICON_START_STOP;
130 rep_data[1] = 0;
131 ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
132 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
133 if (ret < 0)
134 goto err;
135
136 rep_data[0] = WAC_CMD_ICON_TRANSFER;
137 rep_data[1] = icon_no & 0x07;
138
139 wacom_scramble(p);
140
141 for (i = 0; i < 4; i++) {
142 for (j = 0; j < 64; j++)
143 rep_data[j + 3] = p[(i << 6) + j];
144
145 rep_data[2] = i;
146 ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 67,
147 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
148 }
149
150 rep_data[0] = WAC_CMD_ICON_START_STOP;
151 rep_data[1] = 0;
152
153 ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
154 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
155
156err:
157 return;
158}
159
160static void wacom_leds_set_brightness(struct led_classdev *led_dev,
161 enum led_brightness value)
162{
163 struct device *dev = led_dev->dev->parent;
164 struct hid_device *hdev;
165 struct wacom_data *wdata;
166 unsigned char *buf;
167 __u8 led = 0;
168 int i;
169
170 hdev = container_of(dev, struct hid_device, dev);
171 wdata = hid_get_drvdata(hdev);
172 for (i = 0; i < 4; ++i) {
173 if (wdata->leds[i] == led_dev)
174 wdata->led_selector = i;
175 }
176
177 led = wdata->led_selector | 0x04;
178 buf = kzalloc(9, GFP_KERNEL);
179 if (buf) {
180 buf[0] = WAC_CMD_LED_CONTROL;
181 buf[1] = led;
182 buf[2] = value >> 2;
183 buf[3] = value;
184 /* use fixed brightness for OLEDs */
185 buf[4] = 0x08;
186 hid_hw_raw_request(hdev, buf[0], buf, 9, HID_FEATURE_REPORT,
187 HID_REQ_SET_REPORT);
188 kfree(buf);
189 }
190
191 return;
192}
193
194static enum led_brightness wacom_leds_get_brightness(struct led_classdev *led_dev)
195{
196 struct wacom_data *wdata;
197 struct device *dev = led_dev->dev->parent;
198 int value = 0;
199 int i;
200
201 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
202
203 for (i = 0; i < 4; ++i) {
204 if (wdata->leds[i] == led_dev) {
205 value = wdata->leds[i]->brightness;
206 break;
207 }
208 }
209
210 return value;
211}
212
213
214static int wacom_initialize_leds(struct hid_device *hdev)
215{
216 struct wacom_data *wdata = hid_get_drvdata(hdev);
217 struct led_classdev *led;
218 struct device *dev = &hdev->dev;
219 size_t namesz = strlen(dev_name(dev)) + 12;
220 char *name;
221 int i, ret;
222
223 wdata->led_selector = 0;
224
225 for (i = 0; i < 4; i++) {
226 led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
227 if (!led) {
228 hid_warn(hdev,
229 "can't allocate memory for LED selector\n");
230 ret = -ENOMEM;
231 goto err;
232 }
233
234 name = (void *)&led[1];
235 snprintf(name, namesz, "%s:selector:%d", dev_name(dev), i);
236 led->name = name;
237 led->brightness = 0;
238 led->max_brightness = 127;
239 led->brightness_get = wacom_leds_get_brightness;
240 led->brightness_set = wacom_leds_set_brightness;
241
242 wdata->leds[i] = led;
243
244 ret = led_classdev_register(dev, wdata->leds[i]);
245
246 if (ret) {
247 wdata->leds[i] = NULL;
248 kfree(led);
249 hid_warn(hdev, "can't register LED\n");
250 goto err;
251 }
252 }
253
254err:
255 return ret;
256}
257
258static void wacom_destroy_leds(struct hid_device *hdev)
259{
260 struct wacom_data *wdata = hid_get_drvdata(hdev);
261 struct led_classdev *led;
262 int i;
263
264 for (i = 0; i < 4; ++i) {
265 if (wdata->leds[i]) {
266 led = wdata->leds[i];
267 wdata->leds[i] = NULL;
268 led_classdev_unregister(led);
269 kfree(led);
270 }
271 }
272
273}
274
275static int wacom_battery_get_property(struct power_supply *psy,
276 enum power_supply_property psp,
277 union power_supply_propval *val)
278{
279 struct wacom_data *wdata = container_of(psy,
280 struct wacom_data, battery);
281 int ret = 0;
282
283 switch (psp) {
284 case POWER_SUPPLY_PROP_PRESENT:
285 val->intval = 1;
286 break;
287 case POWER_SUPPLY_PROP_SCOPE:
288 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
289 break;
290 case POWER_SUPPLY_PROP_CAPACITY:
291 val->intval = wdata->battery_capacity;
292 break;
293 case POWER_SUPPLY_PROP_STATUS:
294 if (wdata->bat_charging)
295 val->intval = POWER_SUPPLY_STATUS_CHARGING;
296 else
297 if (wdata->battery_capacity == 100 && wdata->ps_connected)
298 val->intval = POWER_SUPPLY_STATUS_FULL;
299 else
300 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
301 break;
302 default:
303 ret = -EINVAL;
304 break;
305 }
306 return ret;
307}
308
309static int wacom_ac_get_property(struct power_supply *psy,
310 enum power_supply_property psp,
311 union power_supply_propval *val)
312{
313 struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
314 int ret = 0;
315
316 switch (psp) {
317 case POWER_SUPPLY_PROP_PRESENT:
318 /* fall through */
319 case POWER_SUPPLY_PROP_ONLINE:
320 val->intval = wdata->ps_connected;
321 break;
322 case POWER_SUPPLY_PROP_SCOPE:
323 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
324 break;
325 default:
326 ret = -EINVAL;
327 break;
328 }
329 return ret;
330}
331
332static void wacom_set_features(struct hid_device *hdev, u8 speed)
333{
334 struct wacom_data *wdata = hid_get_drvdata(hdev);
335 int limit, ret;
336 __u8 rep_data[2];
337
338 switch (hdev->product) {
339 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
340 rep_data[0] = 0x03 ; rep_data[1] = 0x00;
341 limit = 3;
342 do {
343 ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
344 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
345 } while (ret < 0 && limit-- > 0);
346
347 if (ret >= 0) {
348 if (speed == 0)
349 rep_data[0] = 0x05;
350 else
351 rep_data[0] = 0x06;
352
353 rep_data[1] = 0x00;
354 limit = 3;
355 do {
356 ret = hid_hw_raw_request(hdev, rep_data[0],
357 rep_data, 2, HID_FEATURE_REPORT,
358 HID_REQ_SET_REPORT);
359 } while (ret < 0 && limit-- > 0);
360
361 if (ret >= 0) {
362 wdata->high_speed = speed;
363 return;
364 }
365 }
366
367 /*
368 * Note that if the raw queries fail, it's not a hard failure
369 * and it is safe to continue
370 */
371 hid_warn(hdev, "failed to poke device, command %d, err %d\n",
372 rep_data[0], ret);
373 break;
374 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
375 if (speed == 1)
376 wdata->features &= ~0x20;
377 else
378 wdata->features |= 0x20;
379
380 rep_data[0] = 0x03;
381 rep_data[1] = wdata->features;
382
383 ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
384 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
385 if (ret >= 0)
386 wdata->high_speed = speed;
387 break;
388 }
389
390 return;
391}
392
393static ssize_t wacom_show_speed(struct device *dev,
394 struct device_attribute
395 *attr, char *buf)
396{
397 struct wacom_data *wdata = dev_get_drvdata(dev);
398
399 return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
400}
401
402static ssize_t wacom_store_speed(struct device *dev,
403 struct device_attribute *attr,
404 const char *buf, size_t count)
405{
406 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
407 int new_speed;
408
409 if (sscanf(buf, "%1d", &new_speed ) != 1)
410 return -EINVAL;
411
412 if (new_speed == 0 || new_speed == 1) {
413 wacom_set_features(hdev, new_speed);
414 return strnlen(buf, PAGE_SIZE);
415 } else
416 return -EINVAL;
417}
418
419static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
420 wacom_show_speed, wacom_store_speed);
421
422#define WACOM_STORE(OLED_ID) \
423static ssize_t wacom_oled##OLED_ID##_store(struct device *dev, \
424 struct device_attribute *attr, \
425 const char *buf, size_t count) \
426{ \
427 struct hid_device *hdev = container_of(dev, struct hid_device, \
428 dev); \
429 \
430 if (count != 256) \
431 return -EINVAL; \
432 \
433 wacom_set_image(hdev, buf, OLED_ID); \
434 \
435 return count; \
436} \
437 \
438static DEVICE_ATTR(oled##OLED_ID##_img, S_IWUSR | S_IWGRP, NULL, \
439 wacom_oled##OLED_ID##_store)
440
441WACOM_STORE(0);
442WACOM_STORE(1);
443WACOM_STORE(2);
444WACOM_STORE(3);
445WACOM_STORE(4);
446WACOM_STORE(5);
447WACOM_STORE(6);
448WACOM_STORE(7);
449
450static int wacom_gr_parse_report(struct hid_device *hdev,
451 struct wacom_data *wdata,
452 struct input_dev *input, unsigned char *data)
453{
454 int tool, x, y, rw;
455
456 tool = 0;
457 /* Get X & Y positions */
458 x = le16_to_cpu(*(__le16 *) &data[2]);
459 y = le16_to_cpu(*(__le16 *) &data[4]);
460
461 /* Get current tool identifier */
462 if (data[1] & 0x90) { /* If pen is in the in/active area */
463 switch ((data[1] >> 5) & 3) {
464 case 0: /* Pen */
465 tool = BTN_TOOL_PEN;
466 break;
467
468 case 1: /* Rubber */
469 tool = BTN_TOOL_RUBBER;
470 break;
471
472 case 2: /* Mouse with wheel */
473 case 3: /* Mouse without wheel */
474 tool = BTN_TOOL_MOUSE;
475 break;
476 }
477
478 /* Reset tool if out of active tablet area */
479 if (!(data[1] & 0x10))
480 tool = 0;
481 }
482
483 /* If tool changed, notify input subsystem */
484 if (wdata->tool != tool) {
485 if (wdata->tool) {
486 /* Completely reset old tool state */
487 if (wdata->tool == BTN_TOOL_MOUSE) {
488 input_report_key(input, BTN_LEFT, 0);
489 input_report_key(input, BTN_RIGHT, 0);
490 input_report_key(input, BTN_MIDDLE, 0);
491 input_report_abs(input, ABS_DISTANCE,
492 input_abs_get_max(input, ABS_DISTANCE));
493 } else {
494 input_report_key(input, BTN_TOUCH, 0);
495 input_report_key(input, BTN_STYLUS, 0);
496 input_report_key(input, BTN_STYLUS2, 0);
497 input_report_abs(input, ABS_PRESSURE, 0);
498 }
499 input_report_key(input, wdata->tool, 0);
500 input_sync(input);
501 }
502 wdata->tool = tool;
503 if (tool)
504 input_report_key(input, tool, 1);
505 }
506
507 if (tool) {
508 input_report_abs(input, ABS_X, x);
509 input_report_abs(input, ABS_Y, y);
510
511 switch ((data[1] >> 5) & 3) {
512 case 2: /* Mouse with wheel */
513 input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
514 rw = (data[6] & 0x01) ? -1 :
515 (data[6] & 0x02) ? 1 : 0;
516 input_report_rel(input, REL_WHEEL, rw);
517 /* fall through */
518
519 case 3: /* Mouse without wheel */
520 input_report_key(input, BTN_LEFT, data[1] & 0x01);
521 input_report_key(input, BTN_RIGHT, data[1] & 0x02);
522 /* Compute distance between mouse and tablet */
523 rw = 44 - (data[6] >> 2);
524 if (rw < 0)
525 rw = 0;
526 else if (rw > 31)
527 rw = 31;
528 input_report_abs(input, ABS_DISTANCE, rw);
529 break;
530
531 default:
532 input_report_abs(input, ABS_PRESSURE,
533 data[6] | (((__u16) (data[1] & 0x08)) << 5));
534 input_report_key(input, BTN_TOUCH, data[1] & 0x01);
535 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
536 input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
537 break;
538 }
539
540 input_sync(input);
541 }
542
543 /* Report the state of the two buttons at the top of the tablet
544 * as two extra fingerpad keys (buttons 4 & 5). */
545 rw = data[7] & 0x03;
546 if (rw != wdata->butstate) {
547 wdata->butstate = rw;
548 input_report_key(input, BTN_0, rw & 0x02);
549 input_report_key(input, BTN_1, rw & 0x01);
550 input_report_key(input, BTN_TOOL_FINGER, 0xf0);
551 input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
552 input_sync(input);
553 }
554
555 /* Store current battery capacity and power supply state*/
556 rw = (data[7] >> 2 & 0x07);
557 if (rw != wdata->power_raw) {
558 wdata->power_raw = rw;
559 wdata->battery_capacity = batcap_gr[rw];
560 if (rw == 7)
561 wdata->ps_connected = 1;
562 else
563 wdata->ps_connected = 0;
564 }
565 return 1;
566}
567
568static void wacom_i4_parse_button_report(struct wacom_data *wdata,
569 struct input_dev *input, unsigned char *data)
570{
571 __u16 new_butstate;
572 __u8 new_whlstate;
573 __u8 sync = 0;
574
575 new_whlstate = data[1];
576 if (new_whlstate != wdata->whlstate) {
577 wdata->whlstate = new_whlstate;
578 if (new_whlstate & 0x80) {
579 input_report_key(input, BTN_TOUCH, 1);
580 input_report_abs(input, ABS_WHEEL, (new_whlstate & 0x7f));
581 input_report_key(input, BTN_TOOL_FINGER, 1);
582 } else {
583 input_report_key(input, BTN_TOUCH, 0);
584 input_report_abs(input, ABS_WHEEL, 0);
585 input_report_key(input, BTN_TOOL_FINGER, 0);
586 }
587 sync = 1;
588 }
589
590 new_butstate = (data[3] << 1) | (data[2] & 0x01);
591 if (new_butstate != wdata->butstate) {
592 wdata->butstate = new_butstate;
593 input_report_key(input, BTN_0, new_butstate & 0x001);
594 input_report_key(input, BTN_1, new_butstate & 0x002);
595 input_report_key(input, BTN_2, new_butstate & 0x004);
596 input_report_key(input, BTN_3, new_butstate & 0x008);
597 input_report_key(input, BTN_4, new_butstate & 0x010);
598 input_report_key(input, BTN_5, new_butstate & 0x020);
599 input_report_key(input, BTN_6, new_butstate & 0x040);
600 input_report_key(input, BTN_7, new_butstate & 0x080);
601 input_report_key(input, BTN_8, new_butstate & 0x100);
602 input_report_key(input, BTN_TOOL_FINGER, 1);
603 sync = 1;
604 }
605
606 if (sync) {
607 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
608 input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
609 input_sync(input);
610 }
611}
612
613static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
614 struct input_dev *input, unsigned char *data)
615{
616 __u16 x, y, pressure;
617 __u8 distance;
618 __u8 tilt_x, tilt_y;
619
620 switch (data[1]) {
621 case 0x80: /* Out of proximity report */
622 input_report_key(input, BTN_TOUCH, 0);
623 input_report_abs(input, ABS_PRESSURE, 0);
624 input_report_key(input, BTN_STYLUS, 0);
625 input_report_key(input, BTN_STYLUS2, 0);
626 input_report_key(input, wdata->tool, 0);
627 input_report_abs(input, ABS_MISC, 0);
628 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
629 wdata->tool = 0;
630 input_sync(input);
631 break;
632 case 0xC2: /* Tool report */
633 wdata->id = ((data[2] << 4) | (data[3] >> 4) |
634 ((data[7] & 0x0f) << 20) |
635 ((data[8] & 0xf0) << 12));
636 wdata->serial = ((data[3] & 0x0f) << 28) +
637 (data[4] << 20) + (data[5] << 12) +
638 (data[6] << 4) + (data[7] >> 4);
639
640 switch (wdata->id) {
641 case 0x100802:
642 wdata->tool = BTN_TOOL_PEN;
643 break;
644 case 0x10080A:
645 wdata->tool = BTN_TOOL_RUBBER;
646 break;
647 }
648 break;
649 default: /* Position/pressure report */
650 x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1);
651 y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
652 pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
653 | (data[1] & 0x01);
654 distance = (data[9] >> 2) & 0x3f;
655 tilt_x = ((data[7] << 1) & 0x7e) | (data[8] >> 7);
656 tilt_y = data[8] & 0x7f;
657
658 input_report_key(input, BTN_TOUCH, pressure > 1);
659
660 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
661 input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
662 input_report_key(input, wdata->tool, 1);
663 input_report_abs(input, ABS_X, x);
664 input_report_abs(input, ABS_Y, y);
665 input_report_abs(input, ABS_PRESSURE, pressure);
666 input_report_abs(input, ABS_DISTANCE, distance);
667 input_report_abs(input, ABS_TILT_X, tilt_x);
668 input_report_abs(input, ABS_TILT_Y, tilt_y);
669 input_report_abs(input, ABS_MISC, wdata->id);
670 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
671 input_report_key(input, wdata->tool, 1);
672 input_sync(input);
673 break;
674 }
675
676 return;
677}
678
679static void wacom_i4_parse_report(struct hid_device *hdev,
680 struct wacom_data *wdata,
681 struct input_dev *input, unsigned char *data)
682{
683 switch (data[0]) {
684 case 0x00: /* Empty report */
685 break;
686 case 0x02: /* Pen report */
687 wacom_i4_parse_pen_report(wdata, input, data);
688 break;
689 case 0x03: /* Features Report */
690 wdata->features = data[2];
691 break;
692 case 0x0C: /* Button report */
693 wacom_i4_parse_button_report(wdata, input, data);
694 break;
695 default:
696 hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]);
697 break;
698 }
699}
700
701static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
702 u8 *raw_data, int size)
703{
704 struct wacom_data *wdata = hid_get_drvdata(hdev);
705 struct hid_input *hidinput;
706 struct input_dev *input;
707 unsigned char *data = (unsigned char *) raw_data;
708 int i;
709 __u8 power_raw;
710
711 if (!(hdev->claimed & HID_CLAIMED_INPUT))
712 return 0;
713
714 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
715 input = hidinput->input;
716
717 switch (hdev->product) {
718 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
719 if (data[0] == 0x03) {
720 return wacom_gr_parse_report(hdev, wdata, input, data);
721 } else {
722 hid_err(hdev, "Unknown report: %d,%d size:%d\n",
723 data[0], data[1], size);
724 return 0;
725 }
726 break;
727 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
728 i = 1;
729
730 switch (data[0]) {
731 case 0x04:
732 wacom_i4_parse_report(hdev, wdata, input, data + i);
733 i += 10;
734 /* fall through */
735 case 0x03:
736 wacom_i4_parse_report(hdev, wdata, input, data + i);
737 i += 10;
738 wacom_i4_parse_report(hdev, wdata, input, data + i);
739 power_raw = data[i+10];
740 if (power_raw != wdata->power_raw) {
741 wdata->power_raw = power_raw;
742 wdata->battery_capacity = batcap_i4[power_raw & 0x07];
743 wdata->bat_charging = (power_raw & 0x08) ? 1 : 0;
744 wdata->ps_connected = (power_raw & 0x10) ? 1 : 0;
745 }
746
747 break;
748 default:
749 hid_err(hdev, "Unknown report: %d,%d size:%d\n",
750 data[0], data[1], size);
751 return 0;
752 }
753 }
754 return 1;
755}
756
757static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
758 struct hid_field *field, struct hid_usage *usage, unsigned long **bit,
759 int *max)
760{
761 struct input_dev *input = hi->input;
762
763 __set_bit(INPUT_PROP_POINTER, input->propbit);
764
765 /* Basics */
766 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
767
768 __set_bit(REL_WHEEL, input->relbit);
769
770 __set_bit(BTN_TOOL_PEN, input->keybit);
771 __set_bit(BTN_TOUCH, input->keybit);
772 __set_bit(BTN_STYLUS, input->keybit);
773 __set_bit(BTN_STYLUS2, input->keybit);
774 __set_bit(BTN_LEFT, input->keybit);
775 __set_bit(BTN_RIGHT, input->keybit);
776 __set_bit(BTN_MIDDLE, input->keybit);
777
778 /* Pad */
779 input_set_capability(input, EV_MSC, MSC_SERIAL);
780
781 __set_bit(BTN_0, input->keybit);
782 __set_bit(BTN_1, input->keybit);
783 __set_bit(BTN_TOOL_FINGER, input->keybit);
784
785 /* Distance, rubber and mouse */
786 __set_bit(BTN_TOOL_RUBBER, input->keybit);
787 __set_bit(BTN_TOOL_MOUSE, input->keybit);
788
789 switch (hdev->product) {
790 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
791 input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
792 input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
793 input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
794 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
795 break;
796 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
797 __set_bit(ABS_WHEEL, input->absbit);
798 __set_bit(ABS_MISC, input->absbit);
799 __set_bit(BTN_2, input->keybit);
800 __set_bit(BTN_3, input->keybit);
801 __set_bit(BTN_4, input->keybit);
802 __set_bit(BTN_5, input->keybit);
803 __set_bit(BTN_6, input->keybit);
804 __set_bit(BTN_7, input->keybit);
805 __set_bit(BTN_8, input->keybit);
806 input_set_abs_params(input, ABS_WHEEL, 0, 71, 0, 0);
807 input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
808 input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
809 input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
810 input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0);
811 input_set_abs_params(input, ABS_TILT_X, 0, 127, 0, 0);
812 input_set_abs_params(input, ABS_TILT_Y, 0, 127, 0, 0);
813 break;
814 }
815
816 return 0;
817}
818
819static int wacom_probe(struct hid_device *hdev,
820 const struct hid_device_id *id)
821{
822 struct wacom_data *wdata;
823 int ret;
824
825 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
826 if (wdata == NULL) {
827 hid_err(hdev, "can't alloc wacom descriptor\n");
828 return -ENOMEM;
829 }
830
831 hid_set_drvdata(hdev, wdata);
832
833 /* Parse the HID report now */
834 ret = hid_parse(hdev);
835 if (ret) {
836 hid_err(hdev, "parse failed\n");
837 goto err_free;
838 }
839
840 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
841 if (ret) {
842 hid_err(hdev, "hw start failed\n");
843 goto err_free;
844 }
845
846 ret = device_create_file(&hdev->dev, &dev_attr_speed);
847 if (ret)
848 hid_warn(hdev,
849 "can't create sysfs speed attribute err: %d\n", ret);
850
851#define OLED_INIT(OLED_ID) \
852 do { \
853 ret = device_create_file(&hdev->dev, \
854 &dev_attr_oled##OLED_ID##_img); \
855 if (ret) \
856 hid_warn(hdev, \
857 "can't create sysfs oled attribute, err: %d\n", ret);\
858 } while (0)
859
860OLED_INIT(0);
861OLED_INIT(1);
862OLED_INIT(2);
863OLED_INIT(3);
864OLED_INIT(4);
865OLED_INIT(5);
866OLED_INIT(6);
867OLED_INIT(7);
868
869 wdata->features = 0;
870 wacom_set_features(hdev, 1);
871
872 if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) {
873 sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
874 ret = wacom_initialize_leds(hdev);
875 if (ret)
876 hid_warn(hdev,
877 "can't create led attribute, err: %d\n", ret);
878 }
879
880 wdata->battery.properties = wacom_battery_props;
881 wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
882 wdata->battery.get_property = wacom_battery_get_property;
883 wdata->battery.name = "wacom_battery";
884 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
885 wdata->battery.use_for_apm = 0;
886
887
888 ret = power_supply_register(&hdev->dev, &wdata->battery);
889 if (ret) {
890 hid_err(hdev, "can't create sysfs battery attribute, err: %d\n",
891 ret);
892 goto err_battery;
893 }
894
895 power_supply_powers(&wdata->battery, &hdev->dev);
896
897 wdata->ac.properties = wacom_ac_props;
898 wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
899 wdata->ac.get_property = wacom_ac_get_property;
900 wdata->ac.name = "wacom_ac";
901 wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
902 wdata->ac.use_for_apm = 0;
903
904 ret = power_supply_register(&hdev->dev, &wdata->ac);
905 if (ret) {
906 hid_err(hdev,
907 "can't create ac battery attribute, err: %d\n", ret);
908 goto err_ac;
909 }
910
911 power_supply_powers(&wdata->ac, &hdev->dev);
912 return 0;
913
914err_ac:
915 power_supply_unregister(&wdata->battery);
916err_battery:
917 wacom_destroy_leds(hdev);
918 device_remove_file(&hdev->dev, &dev_attr_oled0_img);
919 device_remove_file(&hdev->dev, &dev_attr_oled1_img);
920 device_remove_file(&hdev->dev, &dev_attr_oled2_img);
921 device_remove_file(&hdev->dev, &dev_attr_oled3_img);
922 device_remove_file(&hdev->dev, &dev_attr_oled4_img);
923 device_remove_file(&hdev->dev, &dev_attr_oled5_img);
924 device_remove_file(&hdev->dev, &dev_attr_oled6_img);
925 device_remove_file(&hdev->dev, &dev_attr_oled7_img);
926 device_remove_file(&hdev->dev, &dev_attr_speed);
927 hid_hw_stop(hdev);
928err_free:
929 kfree(wdata);
930 return ret;
931}
932
933static void wacom_remove(struct hid_device *hdev)
934{
935 struct wacom_data *wdata = hid_get_drvdata(hdev);
936
937 wacom_destroy_leds(hdev);
938 device_remove_file(&hdev->dev, &dev_attr_oled0_img);
939 device_remove_file(&hdev->dev, &dev_attr_oled1_img);
940 device_remove_file(&hdev->dev, &dev_attr_oled2_img);
941 device_remove_file(&hdev->dev, &dev_attr_oled3_img);
942 device_remove_file(&hdev->dev, &dev_attr_oled4_img);
943 device_remove_file(&hdev->dev, &dev_attr_oled5_img);
944 device_remove_file(&hdev->dev, &dev_attr_oled6_img);
945 device_remove_file(&hdev->dev, &dev_attr_oled7_img);
946 device_remove_file(&hdev->dev, &dev_attr_speed);
947 hid_hw_stop(hdev);
948
949 power_supply_unregister(&wdata->battery);
950 power_supply_unregister(&wdata->ac);
951 kfree(hid_get_drvdata(hdev));
952}
953
954static const struct hid_device_id wacom_devices[] = {
955 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
956 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
957
958 { }
959};
960MODULE_DEVICE_TABLE(hid, wacom_devices);
961
962static struct hid_driver wacom_driver = {
963 .name = "wacom",
964 .id_table = wacom_devices,
965 .probe = wacom_probe,
966 .remove = wacom_remove,
967 .raw_event = wacom_raw_event,
968 .input_mapped = wacom_input_mapped,
969};
970module_hid_driver(wacom_driver);
971
972MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
973MODULE_LICENSE("GPL");
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
new file mode 100644
index 000000000000..64bc1b296d91
--- /dev/null
+++ b/drivers/hid/wacom.h
@@ -0,0 +1,146 @@
1/*
2 * drivers/input/tablet/wacom.h
3 *
4 * USB Wacom tablet support
5 *
6 * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
7 * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
8 * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
9 * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
10 * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
11 * Copyright (c) 2000 Daniel Egger <egger@suse.de>
12 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
13 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
14 * Copyright (c) 2002-2011 Ping Cheng <pingc@wacom.com>
15 * Copyright (c) 2014 Benjamin Tissoires <benjamin.tissoires@redhat.com>
16 *
17 * ChangeLog:
18 * v0.1 (vp) - Initial release
19 * v0.2 (aba) - Support for all buttons / combinations
20 * v0.3 (vp) - Support for Intuos added
21 * v0.4 (sm) - Support for more Intuos models, menustrip
22 * relative mode, proximity.
23 * v0.5 (vp) - Big cleanup, nifty features removed,
24 * they belong in userspace
25 * v1.8 (vp) - Submit URB only when operating, moved to CVS,
26 * use input_report_key instead of report_btn and
27 * other cleanups
28 * v1.11 (vp) - Add URB ->dev setting for new kernels
29 * v1.11 (jb) - Add support for the 4D Mouse & Lens
30 * v1.12 (de) - Add support for two more inking pen IDs
31 * v1.14 (vp) - Use new USB device id probing scheme.
32 * Fix Wacom Graphire mouse wheel
33 * v1.18 (vp) - Fix mouse wheel direction
34 * Make mouse relative
35 * v1.20 (fl) - Report tool id for Intuos devices
36 * - Multi tools support
37 * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...)
38 * - Add PL models support
39 * - Fix Wacom Graphire mouse wheel again
40 * v1.21 (vp) - Removed protocol descriptions
41 * - Added MISC_SERIAL for tool serial numbers
42 * (gb) - Identify version on module load.
43 * v1.21.1 (fl) - added Graphire2 support
44 * v1.21.2 (fl) - added Intuos2 support
45 * - added all the PL ids
46 * v1.21.3 (fl) - added another eraser id from Neil Okamoto
47 * - added smooth filter for Graphire from Peri Hankey
48 * - added PenPartner support from Olaf van Es
49 * - new tool ids from Ole Martin Bjoerndalen
50 * v1.29 (pc) - Add support for more tablets
51 * - Fix pressure reporting
52 * v1.30 (vp) - Merge 2.4 and 2.5 drivers
53 * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
54 * - Cleanups here and there
55 * v1.30.1 (pi) - Added Graphire3 support
56 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
57 * v1.43 (pc) - Added support for Cintiq 21UX
58 * - Fixed a Graphire bug
59 * - Merged wacom_intuos3_irq into wacom_intuos_irq
60 * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
61 * - Report Device IDs
62 * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19
63 * - Minor data report fix
64 * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
65 * - where wacom_sys.c deals with system specific code,
66 * - and wacom_wac.c deals with Wacom specific code
67 * - Support Intuos3 4x6
68 * v1.47 (pc) - Added support for Bamboo
69 * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
70 * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A)
71 * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28
72 * v1.51 (pc) - Added support for Intuos4
73 * v1.52 (pc) - Query Wacom data upon system resume
74 * - add defines for features->type
75 * - add new devices (0x9F, 0xE2, and 0XE3)
76 * v2.00 (bt) - conversion to a HID driver
77 * - integration of the Bluetooth devices
78 */
79
80/*
81 * This program is free software; you can redistribute it and/or modify
82 * it under the terms of the GNU General Public License as published by
83 * the Free Software Foundation; either version 2 of the License, or
84 * (at your option) any later version.
85 */
86#ifndef WACOM_H
87#define WACOM_H
88#include <linux/kernel.h>
89#include <linux/slab.h>
90#include <linux/module.h>
91#include <linux/mod_devicetable.h>
92#include <linux/usb/input.h>
93#include <linux/power_supply.h>
94#include <asm/unaligned.h>
95
96/*
97 * Version Information
98 */
99#define DRIVER_VERSION "v2.00"
100#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
101#define DRIVER_DESC "USB Wacom tablet driver"
102#define DRIVER_LICENSE "GPL"
103
104#define USB_VENDOR_ID_WACOM 0x056a
105#define USB_VENDOR_ID_LENOVO 0x17ef
106
107struct wacom {
108 struct usb_device *usbdev;
109 struct usb_interface *intf;
110 struct wacom_wac wacom_wac;
111 struct hid_device *hdev;
112 struct mutex lock;
113 struct work_struct work;
114 struct wacom_led {
115 u8 select[2]; /* status led selector (0..3) */
116 u8 llv; /* status led brightness no button (1..127) */
117 u8 hlv; /* status led brightness button pressed (1..127) */
118 u8 img_lum; /* OLED matrix display brightness */
119 } led;
120 bool led_initialized;
121 struct power_supply battery;
122 struct power_supply ac;
123};
124
125static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
126{
127 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
128 schedule_work(&wacom->work);
129}
130
131static inline void wacom_notify_battery(struct wacom_wac *wacom_wac)
132{
133 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
134
135 power_supply_changed(&wacom->battery);
136}
137
138extern const struct hid_device_id wacom_ids[];
139
140void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
141void wacom_setup_device_quirks(struct wacom_features *features);
142int wacom_setup_input_capabilities(struct input_dev *input_dev,
143 struct wacom_wac *wacom_wac);
144int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
145 struct wacom_wac *wacom_wac);
146#endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
new file mode 100644
index 000000000000..3e388ec31da8
--- /dev/null
+++ b/drivers/hid/wacom_sys.c
@@ -0,0 +1,1456 @@
1/*
2 * drivers/input/tablet/wacom_sys.c
3 *
4 * USB Wacom tablet support - system specific code
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include "wacom_wac.h"
15#include "wacom.h"
16#include <linux/hid.h>
17
18#define WAC_MSG_RETRIES 5
19
20#define WAC_CMD_LED_CONTROL 0x20
21#define WAC_CMD_ICON_START 0x21
22#define WAC_CMD_ICON_XFER 0x23
23#define WAC_CMD_ICON_BT_XFER 0x26
24#define WAC_CMD_RETRIES 10
25
26static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id,
27 void *buf, size_t size, unsigned int retries)
28{
29 int retval;
30
31 do {
32 retval = hid_hw_raw_request(hdev, id, buf, size, type,
33 HID_REQ_GET_REPORT);
34 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
35
36 return retval;
37}
38
39static int wacom_set_report(struct hid_device *hdev, u8 type, u8 *buf,
40 size_t size, unsigned int retries)
41{
42 int retval;
43
44 do {
45 retval = hid_hw_raw_request(hdev, buf[0], buf, size, type,
46 HID_REQ_SET_REPORT);
47 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
48
49 return retval;
50}
51
52static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
53 u8 *raw_data, int size)
54{
55 struct wacom *wacom = hid_get_drvdata(hdev);
56
57 if (size > WACOM_PKGLEN_MAX)
58 return 1;
59
60 memcpy(wacom->wacom_wac.data, raw_data, size);
61
62 wacom_wac_irq(&wacom->wacom_wac, size);
63
64 return 0;
65}
66
67static int wacom_open(struct input_dev *dev)
68{
69 struct wacom *wacom = input_get_drvdata(dev);
70 int retval;
71
72 mutex_lock(&wacom->lock);
73 retval = hid_hw_open(wacom->hdev);
74 mutex_unlock(&wacom->lock);
75
76 return retval;
77}
78
79static void wacom_close(struct input_dev *dev)
80{
81 struct wacom *wacom = input_get_drvdata(dev);
82
83 mutex_lock(&wacom->lock);
84 hid_hw_close(wacom->hdev);
85 mutex_unlock(&wacom->lock);
86}
87
88/*
89 * Calculate the resolution of the X or Y axis using hidinput_calc_abs_res.
90 */
91static int wacom_calc_hid_res(int logical_extents, int physical_extents,
92 unsigned unit, int exponent)
93{
94 struct hid_field field = {
95 .logical_maximum = logical_extents,
96 .physical_maximum = physical_extents,
97 .unit = unit,
98 .unit_exponent = exponent,
99 };
100
101 return hidinput_calc_abs_res(&field, ABS_X);
102}
103
104static void wacom_feature_mapping(struct hid_device *hdev,
105 struct hid_field *field, struct hid_usage *usage)
106{
107 struct wacom *wacom = hid_get_drvdata(hdev);
108 struct wacom_features *features = &wacom->wacom_wac.features;
109
110 switch (usage->hid) {
111 case HID_DG_CONTACTMAX:
112 /* leave touch_max as is if predefined */
113 if (!features->touch_max)
114 features->touch_max = field->value[0];
115 break;
116 }
117}
118
119/*
120 * Interface Descriptor of wacom devices can be incomplete and
121 * inconsistent so wacom_features table is used to store stylus
122 * device's packet lengths, various maximum values, and tablet
123 * resolution based on product ID's.
124 *
125 * For devices that contain 2 interfaces, wacom_features table is
126 * inaccurate for the touch interface. Since the Interface Descriptor
127 * for touch interfaces has pretty complete data, this function exists
128 * to query tablet for this missing information instead of hard coding in
129 * an additional table.
130 *
131 * A typical Interface Descriptor for a stylus will contain a
132 * boot mouse application collection that is not of interest and this
133 * function will ignore it.
134 *
135 * It also contains a digitizer application collection that also is not
136 * of interest since any information it contains would be duplicate
137 * of what is in wacom_features. Usually it defines a report of an array
138 * of bytes that could be used as max length of the stylus packet returned.
139 * If it happens to define a Digitizer-Stylus Physical Collection then
140 * the X and Y logical values contain valid data but it is ignored.
141 *
142 * A typical Interface Descriptor for a touch interface will contain a
143 * Digitizer-Finger Physical Collection which will define both logical
144 * X/Y maximum as well as the physical size of tablet. Since touch
145 * interfaces haven't supported pressure or distance, this is enough
146 * information to override invalid values in the wacom_features table.
147 *
148 * Intuos5 touch interface and 3rd gen Bamboo Touch do not contain useful
149 * data. We deal with them after returning from this function.
150 */
151static void wacom_usage_mapping(struct hid_device *hdev,
152 struct hid_field *field, struct hid_usage *usage)
153{
154 struct wacom *wacom = hid_get_drvdata(hdev);
155 struct wacom_features *features = &wacom->wacom_wac.features;
156 bool finger = (field->logical == HID_DG_FINGER) ||
157 (field->physical == HID_DG_FINGER);
158 bool pen = (field->logical == HID_DG_STYLUS) ||
159 (field->physical == HID_DG_STYLUS);
160
161 /*
162 * Requiring Stylus Usage will ignore boot mouse
163 * X/Y values and some cases of invalid Digitizer X/Y
164 * values commonly reported.
165 */
166 if (!pen && !finger)
167 return;
168
169 if (finger && !features->touch_max)
170 /* touch device at least supports one touch point */
171 features->touch_max = 1;
172
173 switch (usage->hid) {
174 case HID_GD_X:
175 features->x_max = field->logical_maximum;
176 if (finger) {
177 features->device_type = BTN_TOOL_FINGER;
178 features->x_phy = field->physical_maximum;
179 if (features->type != BAMBOO_PT) {
180 features->unit = field->unit;
181 features->unitExpo = field->unit_exponent;
182 }
183 } else {
184 features->device_type = BTN_TOOL_PEN;
185 }
186 break;
187 case HID_GD_Y:
188 features->y_max = field->logical_maximum;
189 if (finger) {
190 features->y_phy = field->physical_maximum;
191 if (features->type != BAMBOO_PT) {
192 features->unit = field->unit;
193 features->unitExpo = field->unit_exponent;
194 }
195 }
196 break;
197 case HID_DG_TIPPRESSURE:
198 if (pen)
199 features->pressure_max = field->logical_maximum;
200 break;
201 }
202}
203
204static void wacom_parse_hid(struct hid_device *hdev,
205 struct wacom_features *features)
206{
207 struct hid_report_enum *rep_enum;
208 struct hid_report *hreport;
209 int i, j;
210
211 /* check features first */
212 rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
213 list_for_each_entry(hreport, &rep_enum->report_list, list) {
214 for (i = 0; i < hreport->maxfield; i++) {
215 /* Ignore if report count is out of bounds. */
216 if (hreport->field[i]->report_count < 1)
217 continue;
218
219 for (j = 0; j < hreport->field[i]->maxusage; j++) {
220 wacom_feature_mapping(hdev, hreport->field[i],
221 hreport->field[i]->usage + j);
222 }
223 }
224 }
225
226 /* now check the input usages */
227 rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
228 list_for_each_entry(hreport, &rep_enum->report_list, list) {
229
230 if (!hreport->maxfield)
231 continue;
232
233 for (i = 0; i < hreport->maxfield; i++)
234 for (j = 0; j < hreport->field[i]->maxusage; j++)
235 wacom_usage_mapping(hdev, hreport->field[i],
236 hreport->field[i]->usage + j);
237 }
238}
239
240static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
241 int length, int mode)
242{
243 unsigned char *rep_data;
244 int error = -ENOMEM, limit = 0;
245
246 rep_data = kzalloc(length, GFP_KERNEL);
247 if (!rep_data)
248 return error;
249
250 do {
251 rep_data[0] = report_id;
252 rep_data[1] = mode;
253
254 error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data,
255 length, 1);
256 if (error >= 0)
257 error = wacom_get_report(hdev, HID_FEATURE_REPORT,
258 report_id, rep_data, length, 1);
259 } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
260
261 kfree(rep_data);
262
263 return error < 0 ? error : 0;
264}
265
266static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
267 struct wacom_features *features)
268{
269 struct wacom *wacom = hid_get_drvdata(hdev);
270 int ret;
271 u8 rep_data[2];
272
273 switch (features->type) {
274 case GRAPHIRE_BT:
275 rep_data[0] = 0x03;
276 rep_data[1] = 0x00;
277 ret = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data, 2,
278 3);
279
280 if (ret >= 0) {
281 rep_data[0] = speed == 0 ? 0x05 : 0x06;
282 rep_data[1] = 0x00;
283
284 ret = wacom_set_report(hdev, HID_FEATURE_REPORT,
285 rep_data, 2, 3);
286
287 if (ret >= 0) {
288 wacom->wacom_wac.bt_high_speed = speed;
289 return 0;
290 }
291 }
292
293 /*
294 * Note that if the raw queries fail, it's not a hard failure
295 * and it is safe to continue
296 */
297 hid_warn(hdev, "failed to poke device, command %d, err %d\n",
298 rep_data[0], ret);
299 break;
300 case INTUOS4WL:
301 if (speed == 1)
302 wacom->wacom_wac.bt_features &= ~0x20;
303 else
304 wacom->wacom_wac.bt_features |= 0x20;
305
306 rep_data[0] = 0x03;
307 rep_data[1] = wacom->wacom_wac.bt_features;
308
309 ret = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data, 2,
310 1);
311 if (ret >= 0)
312 wacom->wacom_wac.bt_high_speed = speed;
313 break;
314 }
315
316 return 0;
317}
318
319/*
320 * Switch the tablet into its most-capable mode. Wacom tablets are
321 * typically configured to power-up in a mode which sends mouse-like
322 * reports to the OS. To get absolute position, pressure data, etc.
323 * from the tablet, it is necessary to switch the tablet out of this
324 * mode and into one which sends the full range of tablet data.
325 */
326static int wacom_query_tablet_data(struct hid_device *hdev,
327 struct wacom_features *features)
328{
329 if (hdev->bus == BUS_BLUETOOTH)
330 return wacom_bt_query_tablet_data(hdev, 1, features);
331
332 if (features->device_type == BTN_TOOL_FINGER) {
333 if (features->type > TABLETPC) {
334 /* MT Tablet PC touch */
335 return wacom_set_device_mode(hdev, 3, 4, 4);
336 }
337 else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
338 return wacom_set_device_mode(hdev, 18, 3, 2);
339 }
340 } else if (features->device_type == BTN_TOOL_PEN) {
341 if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
342 return wacom_set_device_mode(hdev, 2, 2, 2);
343 }
344 }
345
346 return 0;
347}
348
349static void wacom_retrieve_hid_descriptor(struct hid_device *hdev,
350 struct wacom_features *features)
351{
352 struct wacom *wacom = hid_get_drvdata(hdev);
353 struct usb_interface *intf = wacom->intf;
354
355 /* default features */
356 features->device_type = BTN_TOOL_PEN;
357 features->x_fuzz = 4;
358 features->y_fuzz = 4;
359 features->pressure_fuzz = 0;
360 features->distance_fuzz = 0;
361
362 /*
363 * The wireless device HID is basic and layout conflicts with
364 * other tablets (monitor and touch interface can look like pen).
365 * Skip the query for this type and modify defaults based on
366 * interface number.
367 */
368 if (features->type == WIRELESS) {
369 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
370 features->device_type = 0;
371 } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) {
372 features->device_type = BTN_TOOL_FINGER;
373 features->pktlen = WACOM_PKGLEN_BBTOUCH3;
374 }
375 }
376
377 /* only devices that support touch need to retrieve the info */
378 if (features->type < BAMBOO_PT)
379 return;
380
381 wacom_parse_hid(hdev, features);
382}
383
384struct wacom_hdev_data {
385 struct list_head list;
386 struct kref kref;
387 struct hid_device *dev;
388 struct wacom_shared shared;
389};
390
391static LIST_HEAD(wacom_udev_list);
392static DEFINE_MUTEX(wacom_udev_list_lock);
393
394static bool wacom_are_sibling(struct hid_device *hdev,
395 struct hid_device *sibling)
396{
397 struct wacom *wacom = hid_get_drvdata(hdev);
398 struct wacom_features *features = &wacom->wacom_wac.features;
399 int vid = features->oVid;
400 int pid = features->oPid;
401 int n1,n2;
402
403 if (vid == 0 && pid == 0) {
404 vid = hdev->vendor;
405 pid = hdev->product;
406 }
407
408 if (vid != sibling->vendor || pid != sibling->product)
409 return false;
410
411 /* Compare the physical path. */
412 n1 = strrchr(hdev->phys, '.') - hdev->phys;
413 n2 = strrchr(sibling->phys, '.') - sibling->phys;
414 if (n1 != n2 || n1 <= 0 || n2 <= 0)
415 return false;
416
417 return !strncmp(hdev->phys, sibling->phys, n1);
418}
419
420static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev)
421{
422 struct wacom_hdev_data *data;
423
424 list_for_each_entry(data, &wacom_udev_list, list) {
425 if (wacom_are_sibling(hdev, data->dev)) {
426 kref_get(&data->kref);
427 return data;
428 }
429 }
430
431 return NULL;
432}
433
434static int wacom_add_shared_data(struct hid_device *hdev)
435{
436 struct wacom *wacom = hid_get_drvdata(hdev);
437 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
438 struct wacom_hdev_data *data;
439 int retval = 0;
440
441 mutex_lock(&wacom_udev_list_lock);
442
443 data = wacom_get_hdev_data(hdev);
444 if (!data) {
445 data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL);
446 if (!data) {
447 retval = -ENOMEM;
448 goto out;
449 }
450
451 kref_init(&data->kref);
452 data->dev = hdev;
453 list_add_tail(&data->list, &wacom_udev_list);
454 }
455
456 wacom_wac->shared = &data->shared;
457
458out:
459 mutex_unlock(&wacom_udev_list_lock);
460 return retval;
461}
462
463static void wacom_release_shared_data(struct kref *kref)
464{
465 struct wacom_hdev_data *data =
466 container_of(kref, struct wacom_hdev_data, kref);
467
468 mutex_lock(&wacom_udev_list_lock);
469 list_del(&data->list);
470 mutex_unlock(&wacom_udev_list_lock);
471
472 kfree(data);
473}
474
475static void wacom_remove_shared_data(struct wacom_wac *wacom)
476{
477 struct wacom_hdev_data *data;
478
479 if (wacom->shared) {
480 data = container_of(wacom->shared, struct wacom_hdev_data, shared);
481 kref_put(&data->kref, wacom_release_shared_data);
482 wacom->shared = NULL;
483 }
484}
485
486static int wacom_led_control(struct wacom *wacom)
487{
488 unsigned char *buf;
489 int retval;
490
491 buf = kzalloc(9, GFP_KERNEL);
492 if (!buf)
493 return -ENOMEM;
494
495 if (wacom->wacom_wac.features.type >= INTUOS5S &&
496 wacom->wacom_wac.features.type <= INTUOSPL) {
497 /*
498 * Touch Ring and crop mark LED luminance may take on
499 * one of four values:
500 * 0 = Low; 1 = Medium; 2 = High; 3 = Off
501 */
502 int ring_led = wacom->led.select[0] & 0x03;
503 int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03;
504 int crop_lum = 0;
505
506 buf[0] = WAC_CMD_LED_CONTROL;
507 buf[1] = (crop_lum << 4) | (ring_lum << 2) | (ring_led);
508 }
509 else {
510 int led = wacom->led.select[0] | 0x4;
511
512 if (wacom->wacom_wac.features.type == WACOM_21UX2 ||
513 wacom->wacom_wac.features.type == WACOM_24HD)
514 led |= (wacom->led.select[1] << 4) | 0x40;
515
516 buf[0] = WAC_CMD_LED_CONTROL;
517 buf[1] = led;
518 buf[2] = wacom->led.llv;
519 buf[3] = wacom->led.hlv;
520 buf[4] = wacom->led.img_lum;
521 }
522
523 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 9,
524 WAC_CMD_RETRIES);
525 kfree(buf);
526
527 return retval;
528}
529
530static int wacom_led_putimage(struct wacom *wacom, int button_id, u8 xfer_id,
531 const unsigned len, const void *img)
532{
533 unsigned char *buf;
534 int i, retval;
535 const unsigned chunk_len = len / 4; /* 4 chunks are needed to be sent */
536
537 buf = kzalloc(chunk_len + 3 , GFP_KERNEL);
538 if (!buf)
539 return -ENOMEM;
540
541 /* Send 'start' command */
542 buf[0] = WAC_CMD_ICON_START;
543 buf[1] = 1;
544 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2,
545 WAC_CMD_RETRIES);
546 if (retval < 0)
547 goto out;
548
549 buf[0] = xfer_id;
550 buf[1] = button_id & 0x07;
551 for (i = 0; i < 4; i++) {
552 buf[2] = i;
553 memcpy(buf + 3, img + i * chunk_len, chunk_len);
554
555 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
556 buf, chunk_len + 3, WAC_CMD_RETRIES);
557 if (retval < 0)
558 break;
559 }
560
561 /* Send 'stop' */
562 buf[0] = WAC_CMD_ICON_START;
563 buf[1] = 0;
564 wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2,
565 WAC_CMD_RETRIES);
566
567out:
568 kfree(buf);
569 return retval;
570}
571
572static ssize_t wacom_led_select_store(struct device *dev, int set_id,
573 const char *buf, size_t count)
574{
575 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
576 struct wacom *wacom = hid_get_drvdata(hdev);
577 unsigned int id;
578 int err;
579
580 err = kstrtouint(buf, 10, &id);
581 if (err)
582 return err;
583
584 mutex_lock(&wacom->lock);
585
586 wacom->led.select[set_id] = id & 0x3;
587 err = wacom_led_control(wacom);
588
589 mutex_unlock(&wacom->lock);
590
591 return err < 0 ? err : count;
592}
593
594#define DEVICE_LED_SELECT_ATTR(SET_ID) \
595static ssize_t wacom_led##SET_ID##_select_store(struct device *dev, \
596 struct device_attribute *attr, const char *buf, size_t count) \
597{ \
598 return wacom_led_select_store(dev, SET_ID, buf, count); \
599} \
600static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \
601 struct device_attribute *attr, char *buf) \
602{ \
603 struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
604 struct wacom *wacom = hid_get_drvdata(hdev); \
605 return snprintf(buf, 2, "%d\n", wacom->led.select[SET_ID]); \
606} \
607static DEVICE_ATTR(status_led##SET_ID##_select, S_IWUSR | S_IRUSR, \
608 wacom_led##SET_ID##_select_show, \
609 wacom_led##SET_ID##_select_store)
610
611DEVICE_LED_SELECT_ATTR(0);
612DEVICE_LED_SELECT_ATTR(1);
613
614static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest,
615 const char *buf, size_t count)
616{
617 unsigned int value;
618 int err;
619
620 err = kstrtouint(buf, 10, &value);
621 if (err)
622 return err;
623
624 mutex_lock(&wacom->lock);
625
626 *dest = value & 0x7f;
627 err = wacom_led_control(wacom);
628
629 mutex_unlock(&wacom->lock);
630
631 return err < 0 ? err : count;
632}
633
634#define DEVICE_LUMINANCE_ATTR(name, field) \
635static ssize_t wacom_##name##_luminance_store(struct device *dev, \
636 struct device_attribute *attr, const char *buf, size_t count) \
637{ \
638 struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
639 struct wacom *wacom = hid_get_drvdata(hdev); \
640 \
641 return wacom_luminance_store(wacom, &wacom->led.field, \
642 buf, count); \
643} \
644static DEVICE_ATTR(name##_luminance, S_IWUSR, \
645 NULL, wacom_##name##_luminance_store)
646
647DEVICE_LUMINANCE_ATTR(status0, llv);
648DEVICE_LUMINANCE_ATTR(status1, hlv);
649DEVICE_LUMINANCE_ATTR(buttons, img_lum);
650
651static ssize_t wacom_button_image_store(struct device *dev, int button_id,
652 const char *buf, size_t count)
653{
654 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
655 struct wacom *wacom = hid_get_drvdata(hdev);
656 int err;
657 unsigned len;
658 u8 xfer_id;
659
660 if (hdev->bus == BUS_BLUETOOTH) {
661 len = 256;
662 xfer_id = WAC_CMD_ICON_BT_XFER;
663 } else {
664 len = 1024;
665 xfer_id = WAC_CMD_ICON_XFER;
666 }
667
668 if (count != len)
669 return -EINVAL;
670
671 mutex_lock(&wacom->lock);
672
673 err = wacom_led_putimage(wacom, button_id, xfer_id, len, buf);
674
675 mutex_unlock(&wacom->lock);
676
677 return err < 0 ? err : count;
678}
679
680#define DEVICE_BTNIMG_ATTR(BUTTON_ID) \
681static ssize_t wacom_btnimg##BUTTON_ID##_store(struct device *dev, \
682 struct device_attribute *attr, const char *buf, size_t count) \
683{ \
684 return wacom_button_image_store(dev, BUTTON_ID, buf, count); \
685} \
686static DEVICE_ATTR(button##BUTTON_ID##_rawimg, S_IWUSR, \
687 NULL, wacom_btnimg##BUTTON_ID##_store)
688
689DEVICE_BTNIMG_ATTR(0);
690DEVICE_BTNIMG_ATTR(1);
691DEVICE_BTNIMG_ATTR(2);
692DEVICE_BTNIMG_ATTR(3);
693DEVICE_BTNIMG_ATTR(4);
694DEVICE_BTNIMG_ATTR(5);
695DEVICE_BTNIMG_ATTR(6);
696DEVICE_BTNIMG_ATTR(7);
697
698static struct attribute *cintiq_led_attrs[] = {
699 &dev_attr_status_led0_select.attr,
700 &dev_attr_status_led1_select.attr,
701 NULL
702};
703
704static struct attribute_group cintiq_led_attr_group = {
705 .name = "wacom_led",
706 .attrs = cintiq_led_attrs,
707};
708
709static struct attribute *intuos4_led_attrs[] = {
710 &dev_attr_status0_luminance.attr,
711 &dev_attr_status1_luminance.attr,
712 &dev_attr_status_led0_select.attr,
713 &dev_attr_buttons_luminance.attr,
714 &dev_attr_button0_rawimg.attr,
715 &dev_attr_button1_rawimg.attr,
716 &dev_attr_button2_rawimg.attr,
717 &dev_attr_button3_rawimg.attr,
718 &dev_attr_button4_rawimg.attr,
719 &dev_attr_button5_rawimg.attr,
720 &dev_attr_button6_rawimg.attr,
721 &dev_attr_button7_rawimg.attr,
722 NULL
723};
724
725static struct attribute_group intuos4_led_attr_group = {
726 .name = "wacom_led",
727 .attrs = intuos4_led_attrs,
728};
729
730static struct attribute *intuos5_led_attrs[] = {
731 &dev_attr_status0_luminance.attr,
732 &dev_attr_status_led0_select.attr,
733 NULL
734};
735
736static struct attribute_group intuos5_led_attr_group = {
737 .name = "wacom_led",
738 .attrs = intuos5_led_attrs,
739};
740
741static int wacom_initialize_leds(struct wacom *wacom)
742{
743 int error;
744
745 /* Initialize default values */
746 switch (wacom->wacom_wac.features.type) {
747 case INTUOS4S:
748 case INTUOS4:
749 case INTUOS4WL:
750 case INTUOS4L:
751 wacom->led.select[0] = 0;
752 wacom->led.select[1] = 0;
753 wacom->led.llv = 10;
754 wacom->led.hlv = 20;
755 wacom->led.img_lum = 10;
756 error = sysfs_create_group(&wacom->hdev->dev.kobj,
757 &intuos4_led_attr_group);
758 break;
759
760 case WACOM_24HD:
761 case WACOM_21UX2:
762 wacom->led.select[0] = 0;
763 wacom->led.select[1] = 0;
764 wacom->led.llv = 0;
765 wacom->led.hlv = 0;
766 wacom->led.img_lum = 0;
767
768 error = sysfs_create_group(&wacom->hdev->dev.kobj,
769 &cintiq_led_attr_group);
770 break;
771
772 case INTUOS5S:
773 case INTUOS5:
774 case INTUOS5L:
775 case INTUOSPS:
776 case INTUOSPM:
777 case INTUOSPL:
778 if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN) {
779 wacom->led.select[0] = 0;
780 wacom->led.select[1] = 0;
781 wacom->led.llv = 32;
782 wacom->led.hlv = 0;
783 wacom->led.img_lum = 0;
784
785 error = sysfs_create_group(&wacom->hdev->dev.kobj,
786 &intuos5_led_attr_group);
787 } else
788 return 0;
789 break;
790
791 default:
792 return 0;
793 }
794
795 if (error) {
796 hid_err(wacom->hdev,
797 "cannot create sysfs group err: %d\n", error);
798 return error;
799 }
800 wacom_led_control(wacom);
801 wacom->led_initialized = true;
802
803 return 0;
804}
805
806static void wacom_destroy_leds(struct wacom *wacom)
807{
808 if (!wacom->led_initialized)
809 return;
810
811 wacom->led_initialized = false;
812
813 switch (wacom->wacom_wac.features.type) {
814 case INTUOS4S:
815 case INTUOS4:
816 case INTUOS4WL:
817 case INTUOS4L:
818 sysfs_remove_group(&wacom->hdev->dev.kobj,
819 &intuos4_led_attr_group);
820 break;
821
822 case WACOM_24HD:
823 case WACOM_21UX2:
824 sysfs_remove_group(&wacom->hdev->dev.kobj,
825 &cintiq_led_attr_group);
826 break;
827
828 case INTUOS5S:
829 case INTUOS5:
830 case INTUOS5L:
831 case INTUOSPS:
832 case INTUOSPM:
833 case INTUOSPL:
834 if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN)
835 sysfs_remove_group(&wacom->hdev->dev.kobj,
836 &intuos5_led_attr_group);
837 break;
838 }
839}
840
841static enum power_supply_property wacom_battery_props[] = {
842 POWER_SUPPLY_PROP_STATUS,
843 POWER_SUPPLY_PROP_SCOPE,
844 POWER_SUPPLY_PROP_CAPACITY
845};
846
847static enum power_supply_property wacom_ac_props[] = {
848 POWER_SUPPLY_PROP_PRESENT,
849 POWER_SUPPLY_PROP_ONLINE,
850 POWER_SUPPLY_PROP_SCOPE,
851};
852
853static int wacom_battery_get_property(struct power_supply *psy,
854 enum power_supply_property psp,
855 union power_supply_propval *val)
856{
857 struct wacom *wacom = container_of(psy, struct wacom, battery);
858 int ret = 0;
859
860 switch (psp) {
861 case POWER_SUPPLY_PROP_SCOPE:
862 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
863 break;
864 case POWER_SUPPLY_PROP_CAPACITY:
865 val->intval =
866 wacom->wacom_wac.battery_capacity;
867 break;
868 case POWER_SUPPLY_PROP_STATUS:
869 if (wacom->wacom_wac.bat_charging)
870 val->intval = POWER_SUPPLY_STATUS_CHARGING;
871 else if (wacom->wacom_wac.battery_capacity == 100 &&
872 wacom->wacom_wac.ps_connected)
873 val->intval = POWER_SUPPLY_STATUS_FULL;
874 else
875 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
876 break;
877 default:
878 ret = -EINVAL;
879 break;
880 }
881
882 return ret;
883}
884
885static int wacom_ac_get_property(struct power_supply *psy,
886 enum power_supply_property psp,
887 union power_supply_propval *val)
888{
889 struct wacom *wacom = container_of(psy, struct wacom, ac);
890 int ret = 0;
891
892 switch (psp) {
893 case POWER_SUPPLY_PROP_PRESENT:
894 /* fall through */
895 case POWER_SUPPLY_PROP_ONLINE:
896 val->intval = wacom->wacom_wac.ps_connected;
897 break;
898 case POWER_SUPPLY_PROP_SCOPE:
899 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
900 break;
901 default:
902 ret = -EINVAL;
903 break;
904 }
905 return ret;
906}
907
908static int wacom_initialize_battery(struct wacom *wacom)
909{
910 static atomic_t battery_no = ATOMIC_INIT(0);
911 int error;
912 unsigned long n;
913
914 if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
915 n = atomic_inc_return(&battery_no) - 1;
916
917 wacom->battery.properties = wacom_battery_props;
918 wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
919 wacom->battery.get_property = wacom_battery_get_property;
920 sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n);
921 wacom->battery.name = wacom->wacom_wac.bat_name;
922 wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
923 wacom->battery.use_for_apm = 0;
924
925 wacom->ac.properties = wacom_ac_props;
926 wacom->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
927 wacom->ac.get_property = wacom_ac_get_property;
928 sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n);
929 wacom->ac.name = wacom->wacom_wac.ac_name;
930 wacom->ac.type = POWER_SUPPLY_TYPE_MAINS;
931 wacom->ac.use_for_apm = 0;
932
933 error = power_supply_register(&wacom->hdev->dev,
934 &wacom->battery);
935 if (error)
936 return error;
937
938 power_supply_powers(&wacom->battery, &wacom->hdev->dev);
939
940 error = power_supply_register(&wacom->hdev->dev, &wacom->ac);
941 if (error) {
942 power_supply_unregister(&wacom->battery);
943 return error;
944 }
945
946 power_supply_powers(&wacom->ac, &wacom->hdev->dev);
947 }
948
949 return 0;
950}
951
952static void wacom_destroy_battery(struct wacom *wacom)
953{
954 if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
955 wacom->battery.dev) {
956 power_supply_unregister(&wacom->battery);
957 wacom->battery.dev = NULL;
958 power_supply_unregister(&wacom->ac);
959 wacom->ac.dev = NULL;
960 }
961}
962
963static ssize_t wacom_show_speed(struct device *dev,
964 struct device_attribute
965 *attr, char *buf)
966{
967 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
968 struct wacom *wacom = hid_get_drvdata(hdev);
969
970 return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
971}
972
973static ssize_t wacom_store_speed(struct device *dev,
974 struct device_attribute *attr,
975 const char *buf, size_t count)
976{
977 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
978 struct wacom *wacom = hid_get_drvdata(hdev);
979 u8 new_speed;
980
981 if (kstrtou8(buf, 0, &new_speed))
982 return -EINVAL;
983
984 if (new_speed != 0 && new_speed != 1)
985 return -EINVAL;
986
987 wacom_bt_query_tablet_data(hdev, new_speed, &wacom->wacom_wac.features);
988
989 return count;
990}
991
992static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
993 wacom_show_speed, wacom_store_speed);
994
995static struct input_dev *wacom_allocate_input(struct wacom *wacom)
996{
997 struct input_dev *input_dev;
998 struct hid_device *hdev = wacom->hdev;
999 struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1000
1001 input_dev = input_allocate_device();
1002 if (!input_dev)
1003 return NULL;
1004
1005 input_dev->name = wacom_wac->name;
1006 input_dev->phys = hdev->phys;
1007 input_dev->dev.parent = &hdev->dev;
1008 input_dev->open = wacom_open;
1009 input_dev->close = wacom_close;
1010 input_dev->uniq = hdev->uniq;
1011 input_dev->id.bustype = hdev->bus;
1012 input_dev->id.vendor = hdev->vendor;
1013 input_dev->id.product = hdev->product;
1014 input_dev->id.version = hdev->version;
1015 input_set_drvdata(input_dev, wacom);
1016
1017 return input_dev;
1018}
1019
1020static void wacom_unregister_inputs(struct wacom *wacom)
1021{
1022 if (wacom->wacom_wac.input)
1023 input_unregister_device(wacom->wacom_wac.input);
1024 if (wacom->wacom_wac.pad_input)
1025 input_unregister_device(wacom->wacom_wac.pad_input);
1026 wacom->wacom_wac.input = NULL;
1027 wacom->wacom_wac.pad_input = NULL;
1028}
1029
1030static int wacom_register_inputs(struct wacom *wacom)
1031{
1032 struct input_dev *input_dev, *pad_input_dev;
1033 struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1034 int error;
1035
1036 input_dev = wacom_allocate_input(wacom);
1037 pad_input_dev = wacom_allocate_input(wacom);
1038 if (!input_dev || !pad_input_dev) {
1039 error = -ENOMEM;
1040 goto fail1;
1041 }
1042
1043 wacom_wac->input = input_dev;
1044 wacom_wac->pad_input = pad_input_dev;
1045 wacom_wac->pad_input->name = wacom_wac->pad_name;
1046
1047 error = wacom_setup_input_capabilities(input_dev, wacom_wac);
1048 if (error)
1049 goto fail2;
1050
1051 error = input_register_device(input_dev);
1052 if (error)
1053 goto fail2;
1054
1055 error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
1056 if (error) {
1057 /* no pad in use on this interface */
1058 input_free_device(pad_input_dev);
1059 wacom_wac->pad_input = NULL;
1060 pad_input_dev = NULL;
1061 } else {
1062 error = input_register_device(pad_input_dev);
1063 if (error)
1064 goto fail3;
1065 }
1066
1067 return 0;
1068
1069fail3:
1070 input_unregister_device(input_dev);
1071 input_dev = NULL;
1072fail2:
1073 wacom_wac->input = NULL;
1074 wacom_wac->pad_input = NULL;
1075fail1:
1076 if (input_dev)
1077 input_free_device(input_dev);
1078 if (pad_input_dev)
1079 input_free_device(pad_input_dev);
1080 return error;
1081}
1082
1083static void wacom_wireless_work(struct work_struct *work)
1084{
1085 struct wacom *wacom = container_of(work, struct wacom, work);
1086 struct usb_device *usbdev = wacom->usbdev;
1087 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1088 struct hid_device *hdev1, *hdev2;
1089 struct wacom *wacom1, *wacom2;
1090 struct wacom_wac *wacom_wac1, *wacom_wac2;
1091 int error;
1092
1093 /*
1094 * Regardless if this is a disconnect or a new tablet,
1095 * remove any existing input and battery devices.
1096 */
1097
1098 wacom_destroy_battery(wacom);
1099
1100 /* Stylus interface */
1101 hdev1 = usb_get_intfdata(usbdev->config->interface[1]);
1102 wacom1 = hid_get_drvdata(hdev1);
1103 wacom_wac1 = &(wacom1->wacom_wac);
1104 wacom_unregister_inputs(wacom1);
1105
1106 /* Touch interface */
1107 hdev2 = usb_get_intfdata(usbdev->config->interface[2]);
1108 wacom2 = hid_get_drvdata(hdev2);
1109 wacom_wac2 = &(wacom2->wacom_wac);
1110 wacom_unregister_inputs(wacom2);
1111
1112 if (wacom_wac->pid == 0) {
1113 hid_info(wacom->hdev, "wireless tablet disconnected\n");
1114 wacom_wac1->shared->type = 0;
1115 } else {
1116 const struct hid_device_id *id = wacom_ids;
1117
1118 hid_info(wacom->hdev, "wireless tablet connected with PID %x\n",
1119 wacom_wac->pid);
1120
1121 while (id->bus) {
1122 if (id->vendor == USB_VENDOR_ID_WACOM &&
1123 id->product == wacom_wac->pid)
1124 break;
1125 id++;
1126 }
1127
1128 if (!id->bus) {
1129 hid_info(wacom->hdev, "ignoring unknown PID.\n");
1130 return;
1131 }
1132
1133 /* Stylus interface */
1134 wacom_wac1->features =
1135 *((struct wacom_features *)id->driver_data);
1136 wacom_wac1->features.device_type = BTN_TOOL_PEN;
1137 snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen",
1138 wacom_wac1->features.name);
1139 snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
1140 wacom_wac1->features.name);
1141 wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max;
1142 wacom_wac1->shared->type = wacom_wac1->features.type;
1143 error = wacom_register_inputs(wacom1);
1144 if (error)
1145 goto fail;
1146
1147 /* Touch interface */
1148 if (wacom_wac1->features.touch_max ||
1149 wacom_wac1->features.type == INTUOSHT) {
1150 wacom_wac2->features =
1151 *((struct wacom_features *)id->driver_data);
1152 wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
1153 wacom_wac2->features.device_type = BTN_TOOL_FINGER;
1154 wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
1155 if (wacom_wac2->features.touch_max)
1156 snprintf(wacom_wac2->name, WACOM_NAME_MAX,
1157 "%s (WL) Finger",wacom_wac2->features.name);
1158 else
1159 snprintf(wacom_wac2->name, WACOM_NAME_MAX,
1160 "%s (WL) Pad",wacom_wac2->features.name);
1161 snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
1162 "%s (WL) Pad", wacom_wac2->features.name);
1163 error = wacom_register_inputs(wacom2);
1164 if (error)
1165 goto fail;
1166
1167 if (wacom_wac1->features.type == INTUOSHT &&
1168 wacom_wac1->features.touch_max)
1169 wacom_wac->shared->touch_input = wacom_wac2->input;
1170 }
1171
1172 error = wacom_initialize_battery(wacom);
1173 if (error)
1174 goto fail;
1175 }
1176
1177 return;
1178
1179fail:
1180 wacom_unregister_inputs(wacom1);
1181 wacom_unregister_inputs(wacom2);
1182 return;
1183}
1184
1185/*
1186 * Not all devices report physical dimensions from HID.
1187 * Compute the default from hardcoded logical dimension
1188 * and resolution before driver overwrites them.
1189 */
1190static void wacom_set_default_phy(struct wacom_features *features)
1191{
1192 if (features->x_resolution) {
1193 features->x_phy = (features->x_max * 100) /
1194 features->x_resolution;
1195 features->y_phy = (features->y_max * 100) /
1196 features->y_resolution;
1197 }
1198}
1199
1200static void wacom_calculate_res(struct wacom_features *features)
1201{
1202 features->x_resolution = wacom_calc_hid_res(features->x_max,
1203 features->x_phy,
1204 features->unit,
1205 features->unitExpo);
1206 features->y_resolution = wacom_calc_hid_res(features->y_max,
1207 features->y_phy,
1208 features->unit,
1209 features->unitExpo);
1210}
1211
1212static int wacom_hid_report_len(struct hid_report *report)
1213{
1214 /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
1215 return ((report->size - 1) >> 3) + 1 + (report->id > 0);
1216}
1217
1218static size_t wacom_compute_pktlen(struct hid_device *hdev)
1219{
1220 struct hid_report_enum *report_enum;
1221 struct hid_report *report;
1222 size_t size = 0;
1223
1224 report_enum = hdev->report_enum + HID_INPUT_REPORT;
1225
1226 list_for_each_entry(report, &report_enum->report_list, list) {
1227 size_t report_size = wacom_hid_report_len(report);
1228 if (report_size > size)
1229 size = report_size;
1230 }
1231
1232 return size;
1233}
1234
1235static int wacom_probe(struct hid_device *hdev,
1236 const struct hid_device_id *id)
1237{
1238 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
1239 struct usb_device *dev = interface_to_usbdev(intf);
1240 struct wacom *wacom;
1241 struct wacom_wac *wacom_wac;
1242 struct wacom_features *features;
1243 int error;
1244
1245 if (!id->driver_data)
1246 return -EINVAL;
1247
1248 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
1249 if (!wacom)
1250 return -ENOMEM;
1251
1252 hid_set_drvdata(hdev, wacom);
1253 wacom->hdev = hdev;
1254
1255 /* ask for the report descriptor to be loaded by HID */
1256 error = hid_parse(hdev);
1257 if (error) {
1258 hid_err(hdev, "parse failed\n");
1259 goto fail1;
1260 }
1261
1262 wacom_wac = &wacom->wacom_wac;
1263 wacom_wac->features = *((struct wacom_features *)id->driver_data);
1264 features = &wacom_wac->features;
1265 features->pktlen = wacom_compute_pktlen(hdev);
1266 if (features->pktlen > WACOM_PKGLEN_MAX) {
1267 error = -EINVAL;
1268 goto fail1;
1269 }
1270
1271 if (features->check_for_hid_type && features->hid_type != hdev->type) {
1272 error = -ENODEV;
1273 goto fail1;
1274 }
1275
1276 wacom->usbdev = dev;
1277 wacom->intf = intf;
1278 mutex_init(&wacom->lock);
1279 INIT_WORK(&wacom->work, wacom_wireless_work);
1280
1281 /* set the default size in case we do not get them from hid */
1282 wacom_set_default_phy(features);
1283
1284 /* Retrieve the physical and logical size for touch devices */
1285 wacom_retrieve_hid_descriptor(hdev, features);
1286
1287 /*
1288 * Intuos5 has no useful data about its touch interface in its
1289 * HID descriptor. If this is the touch interface (PacketSize
1290 * of WACOM_PKGLEN_BBTOUCH3), override the table values.
1291 */
1292 if (features->type >= INTUOS5S && features->type <= INTUOSHT) {
1293 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
1294 features->device_type = BTN_TOOL_FINGER;
1295
1296 features->x_max = 4096;
1297 features->y_max = 4096;
1298 } else {
1299 features->device_type = BTN_TOOL_PEN;
1300 }
1301 }
1302
1303 /*
1304 * Same thing for Bamboo 3rd gen.
1305 */
1306 if ((features->type == BAMBOO_PT) &&
1307 (features->pktlen == WACOM_PKGLEN_BBTOUCH3) &&
1308 (features->device_type == BTN_TOOL_PEN)) {
1309 features->device_type = BTN_TOOL_FINGER;
1310
1311 features->x_max = 4096;
1312 features->y_max = 4096;
1313 }
1314
1315 if (hdev->bus == BUS_BLUETOOTH)
1316 features->quirks |= WACOM_QUIRK_BATTERY;
1317
1318 wacom_setup_device_quirks(features);
1319
1320 /* set unit to "100th of a mm" for devices not reported by HID */
1321 if (!features->unit) {
1322 features->unit = 0x11;
1323 features->unitExpo = -3;
1324 }
1325 wacom_calculate_res(features);
1326
1327 strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
1328 snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name),
1329 "%s Pad", features->name);
1330
1331 if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
1332 /* Append the device type to the name */
1333 if (features->device_type != BTN_TOOL_FINGER)
1334 strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX);
1335 else if (features->touch_max)
1336 strlcat(wacom_wac->name, " Finger", WACOM_NAME_MAX);
1337 else
1338 strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX);
1339
1340 error = wacom_add_shared_data(hdev);
1341 if (error)
1342 goto fail1;
1343 }
1344
1345 error = wacom_initialize_leds(wacom);
1346 if (error)
1347 goto fail2;
1348
1349 if (!(features->quirks & WACOM_QUIRK_MONITOR) &&
1350 (features->quirks & WACOM_QUIRK_BATTERY)) {
1351 error = wacom_initialize_battery(wacom);
1352 if (error)
1353 goto fail3;
1354 }
1355
1356 if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
1357 error = wacom_register_inputs(wacom);
1358 if (error)
1359 goto fail4;
1360 }
1361
1362 if (hdev->bus == BUS_BLUETOOTH) {
1363 error = device_create_file(&hdev->dev, &dev_attr_speed);
1364 if (error)
1365 hid_warn(hdev,
1366 "can't create sysfs speed attribute err: %d\n",
1367 error);
1368 }
1369
1370 /* Note that if query fails it is not a hard failure */
1371 wacom_query_tablet_data(hdev, features);
1372
1373 /* Regular HID work starts now */
1374 error = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
1375 if (error) {
1376 hid_err(hdev, "hw start failed\n");
1377 goto fail5;
1378 }
1379
1380 if (features->quirks & WACOM_QUIRK_MONITOR)
1381 error = hid_hw_open(hdev);
1382
1383 if (wacom_wac->features.type == INTUOSHT && wacom_wac->features.touch_max) {
1384 if (wacom_wac->features.device_type == BTN_TOOL_FINGER)
1385 wacom_wac->shared->touch_input = wacom_wac->input;
1386 }
1387
1388 return 0;
1389
1390 fail5: if (hdev->bus == BUS_BLUETOOTH)
1391 device_remove_file(&hdev->dev, &dev_attr_speed);
1392 wacom_unregister_inputs(wacom);
1393 fail4: wacom_destroy_battery(wacom);
1394 fail3: wacom_destroy_leds(wacom);
1395 fail2: wacom_remove_shared_data(wacom_wac);
1396 fail1: kfree(wacom);
1397 hid_set_drvdata(hdev, NULL);
1398 return error;
1399}
1400
1401static void wacom_remove(struct hid_device *hdev)
1402{
1403 struct wacom *wacom = hid_get_drvdata(hdev);
1404
1405 hid_hw_stop(hdev);
1406
1407 cancel_work_sync(&wacom->work);
1408 wacom_unregister_inputs(wacom);
1409 if (hdev->bus == BUS_BLUETOOTH)
1410 device_remove_file(&hdev->dev, &dev_attr_speed);
1411 wacom_destroy_battery(wacom);
1412 wacom_destroy_leds(wacom);
1413 wacom_remove_shared_data(&wacom->wacom_wac);
1414
1415 hid_set_drvdata(hdev, NULL);
1416 kfree(wacom);
1417}
1418
1419static int wacom_resume(struct hid_device *hdev)
1420{
1421 struct wacom *wacom = hid_get_drvdata(hdev);
1422 struct wacom_features *features = &wacom->wacom_wac.features;
1423
1424 mutex_lock(&wacom->lock);
1425
1426 /* switch to wacom mode first */
1427 wacom_query_tablet_data(hdev, features);
1428 wacom_led_control(wacom);
1429
1430 mutex_unlock(&wacom->lock);
1431
1432 return 0;
1433}
1434
1435static int wacom_reset_resume(struct hid_device *hdev)
1436{
1437 return wacom_resume(hdev);
1438}
1439
1440static struct hid_driver wacom_driver = {
1441 .name = "wacom",
1442 .id_table = wacom_ids,
1443 .probe = wacom_probe,
1444 .remove = wacom_remove,
1445#ifdef CONFIG_PM
1446 .resume = wacom_resume,
1447 .reset_resume = wacom_reset_resume,
1448#endif
1449 .raw_event = wacom_raw_event,
1450};
1451module_hid_driver(wacom_driver);
1452
1453MODULE_VERSION(DRIVER_VERSION);
1454MODULE_AUTHOR(DRIVER_AUTHOR);
1455MODULE_DESCRIPTION(DRIVER_DESC);
1456MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
new file mode 100644
index 000000000000..aa6a08eb7ad6
--- /dev/null
+++ b/drivers/hid/wacom_wac.c
@@ -0,0 +1,2721 @@
1/*
2 * drivers/input/tablet/wacom_wac.c
3 *
4 * USB Wacom tablet support - Wacom specific code
5 *
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include "wacom_wac.h"
16#include "wacom.h"
17#include <linux/input/mt.h>
18#include <linux/hid.h>
19
20/* resolution for penabled devices */
21#define WACOM_PL_RES 20
22#define WACOM_PENPRTN_RES 40
23#define WACOM_VOLITO_RES 50
24#define WACOM_GRAPHIRE_RES 80
25#define WACOM_INTUOS_RES 100
26#define WACOM_INTUOS3_RES 200
27
28/*
29 * Scale factor relating reported contact size to logical contact area.
30 * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo
31 */
32#define WACOM_CONTACT_AREA_SCALE 2607
33
34/*
35 * Percent of battery capacity for Graphire.
36 * 8th value means AC online and show 100% capacity.
37 */
38static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
39
40/*
41 * Percent of battery capacity for Intuos4 WL, AC has a separate bit.
42 */
43static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
44
45static int wacom_penpartner_irq(struct wacom_wac *wacom)
46{
47 unsigned char *data = wacom->data;
48 struct input_dev *input = wacom->input;
49
50 switch (data[0]) {
51 case 1:
52 if (data[5] & 0x80) {
53 wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
54 wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
55 input_report_key(input, wacom->tool[0], 1);
56 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
57 input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
58 input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
59 input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
60 input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127));
61 input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
62 } else {
63 input_report_key(input, wacom->tool[0], 0);
64 input_report_abs(input, ABS_MISC, 0); /* report tool id */
65 input_report_abs(input, ABS_PRESSURE, -1);
66 input_report_key(input, BTN_TOUCH, 0);
67 }
68 break;
69
70 case 2:
71 input_report_key(input, BTN_TOOL_PEN, 1);
72 input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
73 input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
74 input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
75 input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
76 input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
77 input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
78 break;
79
80 default:
81 dev_dbg(input->dev.parent,
82 "%s: received unknown report #%d\n", __func__, data[0]);
83 return 0;
84 }
85
86 return 1;
87}
88
89static int wacom_pl_irq(struct wacom_wac *wacom)
90{
91 struct wacom_features *features = &wacom->features;
92 unsigned char *data = wacom->data;
93 struct input_dev *input = wacom->input;
94 int prox, pressure;
95
96 if (data[0] != WACOM_REPORT_PENABLED) {
97 dev_dbg(input->dev.parent,
98 "%s: received unknown report #%d\n", __func__, data[0]);
99 return 0;
100 }
101
102 prox = data[1] & 0x40;
103
104 if (prox) {
105 wacom->id[0] = ERASER_DEVICE_ID;
106 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
107 if (features->pressure_max > 255)
108 pressure = (pressure << 1) | ((data[4] >> 6) & 1);
109 pressure += (features->pressure_max + 1) / 2;
110
111 /*
112 * if going from out of proximity into proximity select between the eraser
113 * and the pen based on the state of the stylus2 button, choose eraser if
114 * pressed else choose pen. if not a proximity change from out to in, send
115 * an out of proximity for previous tool then a in for new tool.
116 */
117 if (!wacom->tool[0]) {
118 /* Eraser bit set for DTF */
119 if (data[1] & 0x10)
120 wacom->tool[1] = BTN_TOOL_RUBBER;
121 else
122 /* Going into proximity select tool */
123 wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
124 } else {
125 /* was entered with stylus2 pressed */
126 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
127 /* report out proximity for previous tool */
128 input_report_key(input, wacom->tool[1], 0);
129 input_sync(input);
130 wacom->tool[1] = BTN_TOOL_PEN;
131 return 0;
132 }
133 }
134 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
135 /* Unknown tool selected default to pen tool */
136 wacom->tool[1] = BTN_TOOL_PEN;
137 wacom->id[0] = STYLUS_DEVICE_ID;
138 }
139 input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */
140 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
141 input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
142 input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
143 input_report_abs(input, ABS_PRESSURE, pressure);
144
145 input_report_key(input, BTN_TOUCH, data[4] & 0x08);
146 input_report_key(input, BTN_STYLUS, data[4] & 0x10);
147 /* Only allow the stylus2 button to be reported for the pen tool. */
148 input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
149 } else {
150 /* report proximity-out of a (valid) tool */
151 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
152 /* Unknown tool selected default to pen tool */
153 wacom->tool[1] = BTN_TOOL_PEN;
154 }
155 input_report_key(input, wacom->tool[1], prox);
156 }
157
158 wacom->tool[0] = prox; /* Save proximity state */
159 return 1;
160}
161
162static int wacom_ptu_irq(struct wacom_wac *wacom)
163{
164 unsigned char *data = wacom->data;
165 struct input_dev *input = wacom->input;
166
167 if (data[0] != WACOM_REPORT_PENABLED) {
168 dev_dbg(input->dev.parent,
169 "%s: received unknown report #%d\n", __func__, data[0]);
170 return 0;
171 }
172
173 if (data[1] & 0x04) {
174 input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20);
175 input_report_key(input, BTN_TOUCH, data[1] & 0x08);
176 wacom->id[0] = ERASER_DEVICE_ID;
177 } else {
178 input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20);
179 input_report_key(input, BTN_TOUCH, data[1] & 0x01);
180 wacom->id[0] = STYLUS_DEVICE_ID;
181 }
182 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
183 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
184 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
185 input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6]));
186 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
187 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
188 return 1;
189}
190
191static int wacom_dtu_irq(struct wacom_wac *wacom)
192{
193 unsigned char *data = wacom->data;
194 struct input_dev *input = wacom->input;
195 int prox = data[1] & 0x20;
196
197 dev_dbg(input->dev.parent,
198 "%s: received report #%d", __func__, data[0]);
199
200 if (prox) {
201 /* Going into proximity select tool */
202 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
203 if (wacom->tool[0] == BTN_TOOL_PEN)
204 wacom->id[0] = STYLUS_DEVICE_ID;
205 else
206 wacom->id[0] = ERASER_DEVICE_ID;
207 }
208 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
209 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
210 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
211 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
212 input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]);
213 input_report_key(input, BTN_TOUCH, data[1] & 0x05);
214 if (!prox) /* out-prox */
215 wacom->id[0] = 0;
216 input_report_key(input, wacom->tool[0], prox);
217 input_report_abs(input, ABS_MISC, wacom->id[0]);
218 return 1;
219}
220
221static int wacom_dtus_irq(struct wacom_wac *wacom)
222{
223 char *data = wacom->data;
224 struct input_dev *input = wacom->input;
225 unsigned short prox, pressure = 0;
226
227 if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
228 dev_dbg(input->dev.parent,
229 "%s: received unknown report #%d", __func__, data[0]);
230 return 0;
231 } else if (data[0] == WACOM_REPORT_DTUSPAD) {
232 input = wacom->pad_input;
233 input_report_key(input, BTN_0, (data[1] & 0x01));
234 input_report_key(input, BTN_1, (data[1] & 0x02));
235 input_report_key(input, BTN_2, (data[1] & 0x04));
236 input_report_key(input, BTN_3, (data[1] & 0x08));
237 input_report_abs(input, ABS_MISC,
238 data[1] & 0x0f ? PAD_DEVICE_ID : 0);
239 return 1;
240 } else {
241 prox = data[1] & 0x80;
242 if (prox) {
243 switch ((data[1] >> 3) & 3) {
244 case 1: /* Rubber */
245 wacom->tool[0] = BTN_TOOL_RUBBER;
246 wacom->id[0] = ERASER_DEVICE_ID;
247 break;
248
249 case 2: /* Pen */
250 wacom->tool[0] = BTN_TOOL_PEN;
251 wacom->id[0] = STYLUS_DEVICE_ID;
252 break;
253 }
254 }
255
256 input_report_key(input, BTN_STYLUS, data[1] & 0x20);
257 input_report_key(input, BTN_STYLUS2, data[1] & 0x40);
258 input_report_abs(input, ABS_X, get_unaligned_be16(&data[3]));
259 input_report_abs(input, ABS_Y, get_unaligned_be16(&data[5]));
260 pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff);
261 input_report_abs(input, ABS_PRESSURE, pressure);
262 input_report_key(input, BTN_TOUCH, pressure > 10);
263
264 if (!prox) /* out-prox */
265 wacom->id[0] = 0;
266 input_report_key(input, wacom->tool[0], prox);
267 input_report_abs(input, ABS_MISC, wacom->id[0]);
268 return 1;
269 }
270}
271
272static int wacom_graphire_irq(struct wacom_wac *wacom)
273{
274 struct wacom_features *features = &wacom->features;
275 unsigned char *data = wacom->data;
276 struct input_dev *input = wacom->input;
277 struct input_dev *pad_input = wacom->pad_input;
278 int battery_capacity, ps_connected;
279 int prox;
280 int rw = 0;
281 int retval = 0;
282
283 if (features->type == GRAPHIRE_BT) {
284 if (data[0] != WACOM_REPORT_PENABLED_BT) {
285 dev_dbg(input->dev.parent,
286 "%s: received unknown report #%d\n", __func__,
287 data[0]);
288 goto exit;
289 }
290 } else if (data[0] != WACOM_REPORT_PENABLED) {
291 dev_dbg(input->dev.parent,
292 "%s: received unknown report #%d\n", __func__, data[0]);
293 goto exit;
294 }
295
296 prox = data[1] & 0x80;
297 if (prox || wacom->id[0]) {
298 if (prox) {
299 switch ((data[1] >> 5) & 3) {
300
301 case 0: /* Pen */
302 wacom->tool[0] = BTN_TOOL_PEN;
303 wacom->id[0] = STYLUS_DEVICE_ID;
304 break;
305
306 case 1: /* Rubber */
307 wacom->tool[0] = BTN_TOOL_RUBBER;
308 wacom->id[0] = ERASER_DEVICE_ID;
309 break;
310
311 case 2: /* Mouse with wheel */
312 input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
313 /* fall through */
314
315 case 3: /* Mouse without wheel */
316 wacom->tool[0] = BTN_TOOL_MOUSE;
317 wacom->id[0] = CURSOR_DEVICE_ID;
318 break;
319 }
320 }
321 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
322 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
323 if (wacom->tool[0] != BTN_TOOL_MOUSE) {
324 if (features->type == GRAPHIRE_BT)
325 input_report_abs(input, ABS_PRESSURE, data[6] |
326 (((__u16) (data[1] & 0x08)) << 5));
327 else
328 input_report_abs(input, ABS_PRESSURE, data[6] |
329 ((data[7] & 0x03) << 8));
330 input_report_key(input, BTN_TOUCH, data[1] & 0x01);
331 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
332 input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
333 } else {
334 input_report_key(input, BTN_LEFT, data[1] & 0x01);
335 input_report_key(input, BTN_RIGHT, data[1] & 0x02);
336 if (features->type == WACOM_G4 ||
337 features->type == WACOM_MO) {
338 input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);
339 rw = (data[7] & 0x04) - (data[7] & 0x03);
340 } else if (features->type == GRAPHIRE_BT) {
341 /* Compute distance between mouse and tablet */
342 rw = 44 - (data[6] >> 2);
343 rw = clamp_val(rw, 0, 31);
344 input_report_abs(input, ABS_DISTANCE, rw);
345 if (((data[1] >> 5) & 3) == 2) {
346 /* Mouse with wheel */
347 input_report_key(input, BTN_MIDDLE,
348 data[1] & 0x04);
349 rw = (data[6] & 0x01) ? -1 :
350 (data[6] & 0x02) ? 1 : 0;
351 } else {
352 rw = 0;
353 }
354 } else {
355 input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);
356 rw = -(signed char)data[6];
357 }
358 input_report_rel(input, REL_WHEEL, rw);
359 }
360
361 if (!prox)
362 wacom->id[0] = 0;
363 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
364 input_report_key(input, wacom->tool[0], prox);
365 input_sync(input); /* sync last event */
366 }
367
368 /* send pad data */
369 switch (features->type) {
370 case WACOM_G4:
371 prox = data[7] & 0xf8;
372 if (prox || wacom->id[1]) {
373 wacom->id[1] = PAD_DEVICE_ID;
374 input_report_key(pad_input, BTN_BACK, (data[7] & 0x40));
375 input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80));
376 rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
377 input_report_rel(pad_input, REL_WHEEL, rw);
378 if (!prox)
379 wacom->id[1] = 0;
380 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
381 retval = 1;
382 }
383 break;
384
385 case WACOM_MO:
386 prox = (data[7] & 0xf8) || data[8];
387 if (prox || wacom->id[1]) {
388 wacom->id[1] = PAD_DEVICE_ID;
389 input_report_key(pad_input, BTN_BACK, (data[7] & 0x08));
390 input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20));
391 input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x10));
392 input_report_key(pad_input, BTN_RIGHT, (data[7] & 0x40));
393 input_report_abs(pad_input, ABS_WHEEL, (data[8] & 0x7f));
394 if (!prox)
395 wacom->id[1] = 0;
396 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
397 retval = 1;
398 }
399 break;
400 case GRAPHIRE_BT:
401 prox = data[7] & 0x03;
402 if (prox || wacom->id[1]) {
403 wacom->id[1] = PAD_DEVICE_ID;
404 input_report_key(pad_input, BTN_0, (data[7] & 0x02));
405 input_report_key(pad_input, BTN_1, (data[7] & 0x01));
406 if (!prox)
407 wacom->id[1] = 0;
408 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
409 retval = 1;
410 }
411 break;
412 }
413
414 /* Store current battery capacity and power supply state */
415 if (features->type == GRAPHIRE_BT) {
416 rw = (data[7] >> 2 & 0x07);
417 battery_capacity = batcap_gr[rw];
418 ps_connected = rw == 7;
419 if ((wacom->battery_capacity != battery_capacity) ||
420 (wacom->ps_connected != ps_connected)) {
421 wacom->battery_capacity = battery_capacity;
422 wacom->ps_connected = ps_connected;
423 wacom_notify_battery(wacom);
424 }
425 }
426exit:
427 return retval;
428}
429
430static int wacom_intuos_inout(struct wacom_wac *wacom)
431{
432 struct wacom_features *features = &wacom->features;
433 unsigned char *data = wacom->data;
434 struct input_dev *input = wacom->input;
435 int idx = 0;
436
437 /* tool number */
438 if (features->type == INTUOS)
439 idx = data[1] & 0x01;
440
441 /* Enter report */
442 if ((data[1] & 0xfc) == 0xc0) {
443 if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
444 wacom->shared->stylus_in_proximity = true;
445
446 /* serial number of the tool */
447 wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
448 (data[4] << 20) + (data[5] << 12) +
449 (data[6] << 4) + (data[7] >> 4);
450
451 wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |
452 ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12);
453
454 switch (wacom->id[idx]) {
455 case 0x812: /* Inking pen */
456 case 0x801: /* Intuos3 Inking pen */
457 case 0x120802: /* Intuos4/5 Inking Pen */
458 case 0x012:
459 wacom->tool[idx] = BTN_TOOL_PENCIL;
460 break;
461
462 case 0x822: /* Pen */
463 case 0x842:
464 case 0x852:
465 case 0x823: /* Intuos3 Grip Pen */
466 case 0x813: /* Intuos3 Classic Pen */
467 case 0x885: /* Intuos3 Marker Pen */
468 case 0x802: /* Intuos4/5 13HD/24HD General Pen */
469 case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
470 case 0x022:
471 case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
472 case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */
473 case 0x160802: /* Cintiq 13HD Pro Pen */
474 case 0x180802: /* DTH2242 Pen */
475 case 0x100802: /* Intuos4/5 13HD/24HD General Pen */
476 wacom->tool[idx] = BTN_TOOL_PEN;
477 break;
478
479 case 0x832: /* Stroke pen */
480 case 0x032:
481 wacom->tool[idx] = BTN_TOOL_BRUSH;
482 break;
483
484 case 0x007: /* Mouse 4D and 2D */
485 case 0x09c:
486 case 0x094:
487 case 0x017: /* Intuos3 2D Mouse */
488 case 0x806: /* Intuos4 Mouse */
489 wacom->tool[idx] = BTN_TOOL_MOUSE;
490 break;
491
492 case 0x096: /* Lens cursor */
493 case 0x097: /* Intuos3 Lens cursor */
494 case 0x006: /* Intuos4 Lens cursor */
495 wacom->tool[idx] = BTN_TOOL_LENS;
496 break;
497
498 case 0x82a: /* Eraser */
499 case 0x85a:
500 case 0x91a:
501 case 0xd1a:
502 case 0x0fa:
503 case 0x82b: /* Intuos3 Grip Pen Eraser */
504 case 0x81b: /* Intuos3 Classic Pen Eraser */
505 case 0x91b: /* Intuos3 Airbrush Eraser */
506 case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */
507 case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */
508 case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
509 case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */
510 case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
511 case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
512 case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */
513 case 0x18080a: /* DTH2242 Eraser */
514 case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */
515 wacom->tool[idx] = BTN_TOOL_RUBBER;
516 break;
517
518 case 0xd12:
519 case 0x912:
520 case 0x112:
521 case 0x913: /* Intuos3 Airbrush */
522 case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
523 case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
524 wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
525 break;
526
527 default: /* Unknown tool */
528 wacom->tool[idx] = BTN_TOOL_PEN;
529 break;
530 }
531 return 1;
532 }
533
534 /* older I4 styli don't work with new Cintiqs */
535 if (!((wacom->id[idx] >> 20) & 0x01) &&
536 (features->type == WACOM_21UX2))
537 return 1;
538
539 /* Range Report */
540 if ((data[1] & 0xfe) == 0x20) {
541 input_report_key(input, BTN_TOUCH, 0);
542 input_report_abs(input, ABS_PRESSURE, 0);
543 input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);
544 if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
545 wacom->shared->stylus_in_proximity = true;
546 }
547
548 /* Exit report */
549 if ((data[1] & 0xfe) == 0x80) {
550 if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
551 wacom->shared->stylus_in_proximity = false;
552
553 /*
554 * Reset all states otherwise we lose the initial states
555 * when in-prox next time
556 */
557 input_report_abs(input, ABS_X, 0);
558 input_report_abs(input, ABS_Y, 0);
559 input_report_abs(input, ABS_DISTANCE, 0);
560 input_report_abs(input, ABS_TILT_X, 0);
561 input_report_abs(input, ABS_TILT_Y, 0);
562 if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
563 input_report_key(input, BTN_LEFT, 0);
564 input_report_key(input, BTN_MIDDLE, 0);
565 input_report_key(input, BTN_RIGHT, 0);
566 input_report_key(input, BTN_SIDE, 0);
567 input_report_key(input, BTN_EXTRA, 0);
568 input_report_abs(input, ABS_THROTTLE, 0);
569 input_report_abs(input, ABS_RZ, 0);
570 } else {
571 input_report_abs(input, ABS_PRESSURE, 0);
572 input_report_key(input, BTN_STYLUS, 0);
573 input_report_key(input, BTN_STYLUS2, 0);
574 input_report_key(input, BTN_TOUCH, 0);
575 input_report_abs(input, ABS_WHEEL, 0);
576 if (features->type >= INTUOS3S)
577 input_report_abs(input, ABS_Z, 0);
578 }
579 input_report_key(input, wacom->tool[idx], 0);
580 input_report_abs(input, ABS_MISC, 0); /* reset tool id */
581 input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
582 wacom->id[idx] = 0;
583 return 2;
584 }
585 return 0;
586}
587
588static void wacom_intuos_general(struct wacom_wac *wacom)
589{
590 struct wacom_features *features = &wacom->features;
591 unsigned char *data = wacom->data;
592 struct input_dev *input = wacom->input;
593 unsigned int t;
594
595 /* general pen packet */
596 if ((data[1] & 0xb8) == 0xa0) {
597 t = (data[6] << 2) | ((data[7] >> 6) & 3);
598 if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) {
599 t = (t << 1) | (data[1] & 1);
600 }
601 input_report_abs(input, ABS_PRESSURE, t);
602 input_report_abs(input, ABS_TILT_X,
603 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
604 input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
605 input_report_key(input, BTN_STYLUS, data[1] & 2);
606 input_report_key(input, BTN_STYLUS2, data[1] & 4);
607 input_report_key(input, BTN_TOUCH, t > 10);
608 }
609
610 /* airbrush second packet */
611 if ((data[1] & 0xbc) == 0xb4) {
612 input_report_abs(input, ABS_WHEEL,
613 (data[6] << 2) | ((data[7] >> 6) & 3));
614 input_report_abs(input, ABS_TILT_X,
615 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
616 input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
617 }
618}
619
620static int wacom_intuos_irq(struct wacom_wac *wacom)
621{
622 struct wacom_features *features = &wacom->features;
623 unsigned char *data = wacom->data;
624 struct input_dev *input = wacom->input;
625 unsigned int t;
626 int idx = 0, result;
627
628 if (data[0] != WACOM_REPORT_PENABLED &&
629 data[0] != WACOM_REPORT_INTUOSREAD &&
630 data[0] != WACOM_REPORT_INTUOSWRITE &&
631 data[0] != WACOM_REPORT_INTUOSPAD &&
632 data[0] != WACOM_REPORT_INTUOS5PAD) {
633 dev_dbg(input->dev.parent,
634 "%s: received unknown report #%d\n", __func__, data[0]);
635 return 0;
636 }
637
638 /* tool number */
639 if (features->type == INTUOS)
640 idx = data[1] & 0x01;
641
642 /* pad packets. Works as a second tool and is always in prox */
643 if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) {
644 input = wacom->pad_input;
645 if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
646 input_report_key(input, BTN_0, (data[2] & 0x01));
647 input_report_key(input, BTN_1, (data[3] & 0x01));
648 input_report_key(input, BTN_2, (data[3] & 0x02));
649 input_report_key(input, BTN_3, (data[3] & 0x04));
650 input_report_key(input, BTN_4, (data[3] & 0x08));
651 input_report_key(input, BTN_5, (data[3] & 0x10));
652 input_report_key(input, BTN_6, (data[3] & 0x20));
653 if (data[1] & 0x80) {
654 input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
655 } else {
656 /* Out of proximity, clear wheel value. */
657 input_report_abs(input, ABS_WHEEL, 0);
658 }
659 if (features->type != INTUOS4S) {
660 input_report_key(input, BTN_7, (data[3] & 0x40));
661 input_report_key(input, BTN_8, (data[3] & 0x80));
662 }
663 if (data[1] | (data[2] & 0x01) | data[3]) {
664 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
665 } else {
666 input_report_abs(input, ABS_MISC, 0);
667 }
668 } else if (features->type == DTK) {
669 input_report_key(input, BTN_0, (data[6] & 0x01));
670 input_report_key(input, BTN_1, (data[6] & 0x02));
671 input_report_key(input, BTN_2, (data[6] & 0x04));
672 input_report_key(input, BTN_3, (data[6] & 0x08));
673 input_report_key(input, BTN_4, (data[6] & 0x10));
674 input_report_key(input, BTN_5, (data[6] & 0x20));
675 if (data[6] & 0x3f) {
676 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
677 } else {
678 input_report_abs(input, ABS_MISC, 0);
679 }
680 } else if (features->type == WACOM_13HD) {
681 input_report_key(input, BTN_0, (data[3] & 0x01));
682 input_report_key(input, BTN_1, (data[4] & 0x01));
683 input_report_key(input, BTN_2, (data[4] & 0x02));
684 input_report_key(input, BTN_3, (data[4] & 0x04));
685 input_report_key(input, BTN_4, (data[4] & 0x08));
686 input_report_key(input, BTN_5, (data[4] & 0x10));
687 input_report_key(input, BTN_6, (data[4] & 0x20));
688 input_report_key(input, BTN_7, (data[4] & 0x40));
689 input_report_key(input, BTN_8, (data[4] & 0x80));
690 if ((data[3] & 0x01) | data[4]) {
691 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
692 } else {
693 input_report_abs(input, ABS_MISC, 0);
694 }
695 } else if (features->type == WACOM_24HD) {
696 input_report_key(input, BTN_0, (data[6] & 0x01));
697 input_report_key(input, BTN_1, (data[6] & 0x02));
698 input_report_key(input, BTN_2, (data[6] & 0x04));
699 input_report_key(input, BTN_3, (data[6] & 0x08));
700 input_report_key(input, BTN_4, (data[6] & 0x10));
701 input_report_key(input, BTN_5, (data[6] & 0x20));
702 input_report_key(input, BTN_6, (data[6] & 0x40));
703 input_report_key(input, BTN_7, (data[6] & 0x80));
704 input_report_key(input, BTN_8, (data[8] & 0x01));
705 input_report_key(input, BTN_9, (data[8] & 0x02));
706 input_report_key(input, BTN_A, (data[8] & 0x04));
707 input_report_key(input, BTN_B, (data[8] & 0x08));
708 input_report_key(input, BTN_C, (data[8] & 0x10));
709 input_report_key(input, BTN_X, (data[8] & 0x20));
710 input_report_key(input, BTN_Y, (data[8] & 0x40));
711 input_report_key(input, BTN_Z, (data[8] & 0x80));
712
713 /*
714 * Three "buttons" are available on the 24HD which are
715 * physically implemented as a touchstrip. Each button
716 * is approximately 3 bits wide with a 2 bit spacing.
717 * The raw touchstrip bits are stored at:
718 * ((data[3] & 0x1f) << 8) | data[4])
719 */
720 input_report_key(input, KEY_PROG1, data[4] & 0x07);
721 input_report_key(input, KEY_PROG2, data[4] & 0xE0);
722 input_report_key(input, KEY_PROG3, data[3] & 0x1C);
723
724 if (data[1] & 0x80) {
725 input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
726 } else {
727 /* Out of proximity, clear wheel value. */
728 input_report_abs(input, ABS_WHEEL, 0);
729 }
730
731 if (data[2] & 0x80) {
732 input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f));
733 } else {
734 /* Out of proximity, clear second wheel value. */
735 input_report_abs(input, ABS_THROTTLE, 0);
736 }
737
738 if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) {
739 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
740 } else {
741 input_report_abs(input, ABS_MISC, 0);
742 }
743 } else if (features->type == CINTIQ_HYBRID) {
744 /*
745 * Do not send hardware buttons under Android. They
746 * are already sent to the system through GPIO (and
747 * have different meaning).
748 */
749 input_report_key(input, BTN_1, (data[4] & 0x01));
750 input_report_key(input, BTN_2, (data[4] & 0x02));
751 input_report_key(input, BTN_3, (data[4] & 0x04));
752 input_report_key(input, BTN_4, (data[4] & 0x08));
753
754 input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */
755 input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */
756 input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */
757 input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */
758 input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */
759 } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
760 int i;
761
762 /* Touch ring mode switch has no capacitive sensor */
763 input_report_key(input, BTN_0, (data[3] & 0x01));
764
765 /*
766 * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
767 * addition to the mechanical switch. Switch data is
768 * stored in data[4], capacitive data in data[5].
769 */
770 for (i = 0; i < 8; i++)
771 input_report_key(input, BTN_1 + i, data[4] & (1 << i));
772
773 if (data[2] & 0x80) {
774 input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f));
775 } else {
776 /* Out of proximity, clear wheel value. */
777 input_report_abs(input, ABS_WHEEL, 0);
778 }
779
780 if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
781 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
782 } else {
783 input_report_abs(input, ABS_MISC, 0);
784 }
785 } else {
786 if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
787 input_report_key(input, BTN_0, (data[5] & 0x01));
788 input_report_key(input, BTN_1, (data[6] & 0x01));
789 input_report_key(input, BTN_2, (data[6] & 0x02));
790 input_report_key(input, BTN_3, (data[6] & 0x04));
791 input_report_key(input, BTN_4, (data[6] & 0x08));
792 input_report_key(input, BTN_5, (data[6] & 0x10));
793 input_report_key(input, BTN_6, (data[6] & 0x20));
794 input_report_key(input, BTN_7, (data[6] & 0x40));
795 input_report_key(input, BTN_8, (data[6] & 0x80));
796 input_report_key(input, BTN_9, (data[7] & 0x01));
797 input_report_key(input, BTN_A, (data[8] & 0x01));
798 input_report_key(input, BTN_B, (data[8] & 0x02));
799 input_report_key(input, BTN_C, (data[8] & 0x04));
800 input_report_key(input, BTN_X, (data[8] & 0x08));
801 input_report_key(input, BTN_Y, (data[8] & 0x10));
802 input_report_key(input, BTN_Z, (data[8] & 0x20));
803 input_report_key(input, BTN_BASE, (data[8] & 0x40));
804 input_report_key(input, BTN_BASE2, (data[8] & 0x80));
805
806 if (features->type == WACOM_22HD) {
807 input_report_key(input, KEY_PROG1, data[9] & 0x01);
808 input_report_key(input, KEY_PROG2, data[9] & 0x02);
809 input_report_key(input, KEY_PROG3, data[9] & 0x04);
810 }
811 } else {
812 input_report_key(input, BTN_0, (data[5] & 0x01));
813 input_report_key(input, BTN_1, (data[5] & 0x02));
814 input_report_key(input, BTN_2, (data[5] & 0x04));
815 input_report_key(input, BTN_3, (data[5] & 0x08));
816 input_report_key(input, BTN_4, (data[6] & 0x01));
817 input_report_key(input, BTN_5, (data[6] & 0x02));
818 input_report_key(input, BTN_6, (data[6] & 0x04));
819 input_report_key(input, BTN_7, (data[6] & 0x08));
820 input_report_key(input, BTN_8, (data[5] & 0x10));
821 input_report_key(input, BTN_9, (data[6] & 0x10));
822 }
823 input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
824 input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
825
826 if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
827 data[2] | (data[3] & 0x1f) | data[4] | data[8] |
828 (data[7] & 0x01)) {
829 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
830 } else {
831 input_report_abs(input, ABS_MISC, 0);
832 }
833 }
834 return 1;
835 }
836
837 /* process in/out prox events */
838 result = wacom_intuos_inout(wacom);
839 if (result)
840 return result - 1;
841
842 /* don't proceed if we don't know the ID */
843 if (!wacom->id[idx])
844 return 0;
845
846 /* Only large Intuos support Lense Cursor */
847 if (wacom->tool[idx] == BTN_TOOL_LENS &&
848 (features->type == INTUOS3 ||
849 features->type == INTUOS3S ||
850 features->type == INTUOS4 ||
851 features->type == INTUOS4S ||
852 features->type == INTUOS5 ||
853 features->type == INTUOS5S ||
854 features->type == INTUOSPM ||
855 features->type == INTUOSPS)) {
856
857 return 0;
858 }
859
860 /* Cintiq doesn't send data when RDY bit isn't set */
861 if (features->type == CINTIQ && !(data[1] & 0x40))
862 return 0;
863
864 if (features->type >= INTUOS3S) {
865 input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
866 input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
867 input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
868 } else {
869 input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2]));
870 input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4]));
871 input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
872 }
873
874 /* process general packets */
875 wacom_intuos_general(wacom);
876
877 /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */
878 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) {
879
880 if (data[1] & 0x02) {
881 /* Rotation packet */
882 if (features->type >= INTUOS3S) {
883 /* I3 marker pen rotation */
884 t = (data[6] << 3) | ((data[7] >> 5) & 7);
885 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
886 ((t-1) / 2 + 450)) : (450 - t / 2) ;
887 input_report_abs(input, ABS_Z, t);
888 } else {
889 /* 4D mouse rotation packet */
890 t = (data[6] << 3) | ((data[7] >> 5) & 7);
891 input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
892 ((t - 1) / 2) : -t / 2);
893 }
894
895 } else if (!(data[1] & 0x10) && features->type < INTUOS3S) {
896 /* 4D mouse packet */
897 input_report_key(input, BTN_LEFT, data[8] & 0x01);
898 input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
899 input_report_key(input, BTN_RIGHT, data[8] & 0x04);
900
901 input_report_key(input, BTN_SIDE, data[8] & 0x20);
902 input_report_key(input, BTN_EXTRA, data[8] & 0x10);
903 t = (data[6] << 2) | ((data[7] >> 6) & 3);
904 input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
905
906 } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
907 /* I4 mouse */
908 if (features->type >= INTUOS4S && features->type <= INTUOSPL) {
909 input_report_key(input, BTN_LEFT, data[6] & 0x01);
910 input_report_key(input, BTN_MIDDLE, data[6] & 0x02);
911 input_report_key(input, BTN_RIGHT, data[6] & 0x04);
912 input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)
913 - ((data[7] & 0x40) >> 6));
914 input_report_key(input, BTN_SIDE, data[6] & 0x08);
915 input_report_key(input, BTN_EXTRA, data[6] & 0x10);
916
917 input_report_abs(input, ABS_TILT_X,
918 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
919 input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
920 } else {
921 /* 2D mouse packet */
922 input_report_key(input, BTN_LEFT, data[8] & 0x04);
923 input_report_key(input, BTN_MIDDLE, data[8] & 0x08);
924 input_report_key(input, BTN_RIGHT, data[8] & 0x10);
925 input_report_rel(input, REL_WHEEL, (data[8] & 0x01)
926 - ((data[8] & 0x02) >> 1));
927
928 /* I3 2D mouse side buttons */
929 if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
930 input_report_key(input, BTN_SIDE, data[8] & 0x40);
931 input_report_key(input, BTN_EXTRA, data[8] & 0x20);
932 }
933 }
934 } else if ((features->type < INTUOS3S || features->type == INTUOS3L ||
935 features->type == INTUOS4L || features->type == INTUOS5L ||
936 features->type == INTUOSPL) &&
937 wacom->tool[idx] == BTN_TOOL_LENS) {
938 /* Lens cursor packets */
939 input_report_key(input, BTN_LEFT, data[8] & 0x01);
940 input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
941 input_report_key(input, BTN_RIGHT, data[8] & 0x04);
942 input_report_key(input, BTN_SIDE, data[8] & 0x10);
943 input_report_key(input, BTN_EXTRA, data[8] & 0x08);
944 }
945 }
946
947 input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
948 input_report_key(input, wacom->tool[idx], 1);
949 input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
950 return 1;
951}
952
953static int int_dist(int x1, int y1, int x2, int y2)
954{
955 int x = x2 - x1;
956 int y = y2 - y1;
957
958 return int_sqrt(x*x + y*y);
959}
960
961static void wacom_intuos_bt_process_data(struct wacom_wac *wacom,
962 unsigned char *data)
963{
964 memcpy(wacom->data, data, 10);
965 wacom_intuos_irq(wacom);
966
967 input_sync(wacom->input);
968 if (wacom->pad_input)
969 input_sync(wacom->pad_input);
970}
971
972static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
973{
974 unsigned char data[WACOM_PKGLEN_MAX];
975 int i = 1;
976 unsigned power_raw, battery_capacity, bat_charging, ps_connected;
977
978 memcpy(data, wacom->data, len);
979
980 switch (data[0]) {
981 case 0x04:
982 wacom_intuos_bt_process_data(wacom, data + i);
983 i += 10;
984 /* fall through */
985 case 0x03:
986 wacom_intuos_bt_process_data(wacom, data + i);
987 i += 10;
988 wacom_intuos_bt_process_data(wacom, data + i);
989 i += 10;
990 power_raw = data[i];
991 bat_charging = (power_raw & 0x08) ? 1 : 0;
992 ps_connected = (power_raw & 0x10) ? 1 : 0;
993 battery_capacity = batcap_i4[power_raw & 0x07];
994 if ((wacom->battery_capacity != battery_capacity) ||
995 (wacom->bat_charging != bat_charging) ||
996 (wacom->ps_connected != ps_connected)) {
997 wacom->battery_capacity = battery_capacity;
998 wacom->bat_charging = bat_charging;
999 wacom->ps_connected = ps_connected;
1000 wacom_notify_battery(wacom);
1001 }
1002
1003 break;
1004 default:
1005 dev_dbg(wacom->input->dev.parent,
1006 "Unknown report: %d,%d size:%zu\n",
1007 data[0], data[1], len);
1008 return 0;
1009 }
1010 return 0;
1011}
1012
1013static int wacom_24hdt_irq(struct wacom_wac *wacom)
1014{
1015 struct input_dev *input = wacom->input;
1016 unsigned char *data = wacom->data;
1017 int i;
1018 int current_num_contacts = data[61];
1019 int contacts_to_send = 0;
1020
1021 /*
1022 * First packet resets the counter since only the first
1023 * packet in series will have non-zero current_num_contacts.
1024 */
1025 if (current_num_contacts)
1026 wacom->num_contacts_left = current_num_contacts;
1027
1028 /* There are at most 4 contacts per packet */
1029 contacts_to_send = min(4, wacom->num_contacts_left);
1030
1031 for (i = 0; i < contacts_to_send; i++) {
1032 int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
1033 bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
1034 int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
1035
1036 if (slot < 0)
1037 continue;
1038 input_mt_slot(input, slot);
1039 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1040
1041 if (touch) {
1042 int t_x = get_unaligned_le16(&data[offset + 2]);
1043 int c_x = get_unaligned_le16(&data[offset + 4]);
1044 int t_y = get_unaligned_le16(&data[offset + 6]);
1045 int c_y = get_unaligned_le16(&data[offset + 8]);
1046 int w = get_unaligned_le16(&data[offset + 10]);
1047 int h = get_unaligned_le16(&data[offset + 12]);
1048
1049 input_report_abs(input, ABS_MT_POSITION_X, t_x);
1050 input_report_abs(input, ABS_MT_POSITION_Y, t_y);
1051 input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
1052 input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
1053 input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
1054 input_report_abs(input, ABS_MT_ORIENTATION, w > h);
1055 }
1056 }
1057 input_mt_report_pointer_emulation(input, true);
1058
1059 wacom->num_contacts_left -= contacts_to_send;
1060 if (wacom->num_contacts_left <= 0)
1061 wacom->num_contacts_left = 0;
1062
1063 return 1;
1064}
1065
1066static int wacom_mt_touch(struct wacom_wac *wacom)
1067{
1068 struct input_dev *input = wacom->input;
1069 unsigned char *data = wacom->data;
1070 int i;
1071 int current_num_contacts = data[2];
1072 int contacts_to_send = 0;
1073 int x_offset = 0;
1074
1075 /* MTTPC does not support Height and Width */
1076 if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
1077 x_offset = -4;
1078
1079 /*
1080 * First packet resets the counter since only the first
1081 * packet in series will have non-zero current_num_contacts.
1082 */
1083 if (current_num_contacts)
1084 wacom->num_contacts_left = current_num_contacts;
1085
1086 /* There are at most 5 contacts per packet */
1087 contacts_to_send = min(5, wacom->num_contacts_left);
1088
1089 for (i = 0; i < contacts_to_send; i++) {
1090 int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
1091 bool touch = data[offset] & 0x1;
1092 int id = get_unaligned_le16(&data[offset + 1]);
1093 int slot = input_mt_get_slot_by_key(input, id);
1094
1095 if (slot < 0)
1096 continue;
1097
1098 input_mt_slot(input, slot);
1099 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1100 if (touch) {
1101 int x = get_unaligned_le16(&data[offset + x_offset + 7]);
1102 int y = get_unaligned_le16(&data[offset + x_offset + 9]);
1103 input_report_abs(input, ABS_MT_POSITION_X, x);
1104 input_report_abs(input, ABS_MT_POSITION_Y, y);
1105 }
1106 }
1107 input_mt_report_pointer_emulation(input, true);
1108
1109 wacom->num_contacts_left -= contacts_to_send;
1110 if (wacom->num_contacts_left < 0)
1111 wacom->num_contacts_left = 0;
1112
1113 return 1;
1114}
1115
1116static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
1117{
1118 struct input_dev *input = wacom->input;
1119 unsigned char *data = wacom->data;
1120 int contact_with_no_pen_down_count = 0;
1121 int i;
1122
1123 for (i = 0; i < 2; i++) {
1124 int p = data[1] & (1 << i);
1125 bool touch = p && !wacom->shared->stylus_in_proximity;
1126
1127 input_mt_slot(input, i);
1128 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1129 if (touch) {
1130 int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff;
1131 int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff;
1132
1133 input_report_abs(input, ABS_MT_POSITION_X, x);
1134 input_report_abs(input, ABS_MT_POSITION_Y, y);
1135 contact_with_no_pen_down_count++;
1136 }
1137 }
1138 input_mt_report_pointer_emulation(input, true);
1139
1140 /* keep touch state for pen event */
1141 wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
1142
1143 return 1;
1144}
1145
1146static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
1147{
1148 unsigned char *data = wacom->data;
1149 struct input_dev *input = wacom->input;
1150 bool prox;
1151 int x = 0, y = 0;
1152
1153 if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
1154 return 0;
1155
1156 if (!wacom->shared->stylus_in_proximity) {
1157 if (len == WACOM_PKGLEN_TPC1FG) {
1158 prox = data[0] & 0x01;
1159 x = get_unaligned_le16(&data[1]);
1160 y = get_unaligned_le16(&data[3]);
1161 } else if (len == WACOM_PKGLEN_TPC1FG_B) {
1162 prox = data[2] & 0x01;
1163 x = get_unaligned_le16(&data[3]);
1164 y = get_unaligned_le16(&data[5]);
1165 } else {
1166 prox = data[1] & 0x01;
1167 x = le16_to_cpup((__le16 *)&data[2]);
1168 y = le16_to_cpup((__le16 *)&data[4]);
1169 }
1170 } else
1171 /* force touch out when pen is in prox */
1172 prox = 0;
1173
1174 if (prox) {
1175 input_report_abs(input, ABS_X, x);
1176 input_report_abs(input, ABS_Y, y);
1177 }
1178 input_report_key(input, BTN_TOUCH, prox);
1179
1180 /* keep touch state for pen events */
1181 wacom->shared->touch_down = prox;
1182
1183 return 1;
1184}
1185
1186static int wacom_tpc_pen(struct wacom_wac *wacom)
1187{
1188 unsigned char *data = wacom->data;
1189 struct input_dev *input = wacom->input;
1190 bool prox = data[1] & 0x20;
1191
1192 if (!wacom->shared->stylus_in_proximity) /* first in prox */
1193 /* Going into proximity select tool */
1194 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
1195
1196 /* keep pen state for touch events */
1197 wacom->shared->stylus_in_proximity = prox;
1198
1199 /* send pen events only when touch is up or forced out */
1200 if (!wacom->shared->touch_down) {
1201 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
1202 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
1203 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
1204 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
1205 input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x07) << 8) | data[6]);
1206 input_report_key(input, BTN_TOUCH, data[1] & 0x05);
1207 input_report_key(input, wacom->tool[0], prox);
1208 return 1;
1209 }
1210
1211 return 0;
1212}
1213
1214static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
1215{
1216 unsigned char *data = wacom->data;
1217
1218 dev_dbg(wacom->input->dev.parent,
1219 "%s: received report #%d\n", __func__, data[0]);
1220
1221 switch (len) {
1222 case WACOM_PKGLEN_TPC1FG:
1223 return wacom_tpc_single_touch(wacom, len);
1224
1225 case WACOM_PKGLEN_TPC2FG:
1226 return wacom_tpc_mt_touch(wacom);
1227
1228 case WACOM_PKGLEN_PENABLED:
1229 return wacom_tpc_pen(wacom);
1230
1231 default:
1232 switch (data[0]) {
1233 case WACOM_REPORT_TPC1FG:
1234 case WACOM_REPORT_TPCHID:
1235 case WACOM_REPORT_TPCST:
1236 case WACOM_REPORT_TPC1FGE:
1237 return wacom_tpc_single_touch(wacom, len);
1238
1239 case WACOM_REPORT_TPCMT:
1240 case WACOM_REPORT_TPCMT2:
1241 return wacom_mt_touch(wacom);
1242
1243 case WACOM_REPORT_PENABLED:
1244 return wacom_tpc_pen(wacom);
1245 }
1246 }
1247
1248 return 0;
1249}
1250
1251static int wacom_bpt_touch(struct wacom_wac *wacom)
1252{
1253 struct wacom_features *features = &wacom->features;
1254 struct input_dev *input = wacom->input;
1255 struct input_dev *pad_input = wacom->pad_input;
1256 unsigned char *data = wacom->data;
1257 int i;
1258
1259 if (data[0] != 0x02)
1260 return 0;
1261
1262 for (i = 0; i < 2; i++) {
1263 int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
1264 bool touch = data[offset + 3] & 0x80;
1265
1266 /*
1267 * Touch events need to be disabled while stylus is
1268 * in proximity because user's hand is resting on touchpad
1269 * and sending unwanted events. User expects tablet buttons
1270 * to continue working though.
1271 */
1272 touch = touch && !wacom->shared->stylus_in_proximity;
1273
1274 input_mt_slot(input, i);
1275 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1276 if (touch) {
1277 int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
1278 int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
1279 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
1280 x <<= 5;
1281 y <<= 5;
1282 }
1283 input_report_abs(input, ABS_MT_POSITION_X, x);
1284 input_report_abs(input, ABS_MT_POSITION_Y, y);
1285 }
1286 }
1287
1288 input_mt_report_pointer_emulation(input, true);
1289
1290 input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
1291 input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
1292 input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
1293 input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
1294
1295 return 1;
1296}
1297
1298static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
1299{
1300 struct wacom_features *features = &wacom->features;
1301 struct input_dev *input = wacom->input;
1302 bool touch = data[1] & 0x80;
1303 int slot = input_mt_get_slot_by_key(input, data[0]);
1304
1305 if (slot < 0)
1306 return;
1307
1308 touch = touch && !wacom->shared->stylus_in_proximity;
1309
1310 input_mt_slot(input, slot);
1311 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1312
1313 if (touch) {
1314 int x = (data[2] << 4) | (data[4] >> 4);
1315 int y = (data[3] << 4) | (data[4] & 0x0f);
1316 int width, height;
1317
1318 if (features->type >= INTUOSPS && features->type <= INTUOSPL) {
1319 width = data[5] * 100;
1320 height = data[6] * 100;
1321 } else {
1322 /*
1323 * "a" is a scaled-down area which we assume is
1324 * roughly circular and which can be described as:
1325 * a=(pi*r^2)/C.
1326 */
1327 int a = data[5];
1328 int x_res = input_abs_get_res(input, ABS_MT_POSITION_X);
1329 int y_res = input_abs_get_res(input, ABS_MT_POSITION_Y);
1330 width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
1331 height = width * y_res / x_res;
1332 }
1333
1334 input_report_abs(input, ABS_MT_POSITION_X, x);
1335 input_report_abs(input, ABS_MT_POSITION_Y, y);
1336 input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
1337 input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
1338 }
1339}
1340
1341static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
1342{
1343 struct input_dev *input = wacom->pad_input;
1344 struct wacom_features *features = &wacom->features;
1345
1346 if (features->type == INTUOSHT) {
1347 input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
1348 input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
1349 } else {
1350 input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
1351 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
1352 }
1353 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
1354 input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
1355}
1356
1357static int wacom_bpt3_touch(struct wacom_wac *wacom)
1358{
1359 struct input_dev *input = wacom->input;
1360 unsigned char *data = wacom->data;
1361 int count = data[1] & 0x07;
1362 int i;
1363
1364 if (data[0] != 0x02)
1365 return 0;
1366
1367 /* data has up to 7 fixed sized 8-byte messages starting at data[2] */
1368 for (i = 0; i < count; i++) {
1369 int offset = (8 * i) + 2;
1370 int msg_id = data[offset];
1371
1372 if (msg_id >= 2 && msg_id <= 17)
1373 wacom_bpt3_touch_msg(wacom, data + offset);
1374 else if (msg_id == 128)
1375 wacom_bpt3_button_msg(wacom, data + offset);
1376
1377 }
1378 input_mt_report_pointer_emulation(input, true);
1379
1380 return 1;
1381}
1382
1383static int wacom_bpt_pen(struct wacom_wac *wacom)
1384{
1385 struct wacom_features *features = &wacom->features;
1386 struct input_dev *input = wacom->input;
1387 unsigned char *data = wacom->data;
1388 int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
1389
1390 if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB)
1391 return 0;
1392
1393 if (data[0] == WACOM_REPORT_USB) {
1394 if (features->type == INTUOSHT && features->touch_max) {
1395 input_report_switch(wacom->shared->touch_input,
1396 SW_MUTE_DEVICE, data[8] & 0x40);
1397 input_sync(wacom->shared->touch_input);
1398 }
1399 return 0;
1400 }
1401
1402 prox = (data[1] & 0x20) == 0x20;
1403
1404 /*
1405 * All reports shared between PEN and RUBBER tool must be
1406 * forced to a known starting value (zero) when transitioning to
1407 * out-of-prox.
1408 *
1409 * If not reset then, to userspace, it will look like lost events
1410 * if new tool comes in-prox with same values as previous tool sent.
1411 *
1412 * Hardware does report zero in most out-of-prox cases but not all.
1413 */
1414 if (prox) {
1415 if (!wacom->shared->stylus_in_proximity) {
1416 if (data[1] & 0x08) {
1417 wacom->tool[0] = BTN_TOOL_RUBBER;
1418 wacom->id[0] = ERASER_DEVICE_ID;
1419 } else {
1420 wacom->tool[0] = BTN_TOOL_PEN;
1421 wacom->id[0] = STYLUS_DEVICE_ID;
1422 }
1423 wacom->shared->stylus_in_proximity = true;
1424 }
1425 x = le16_to_cpup((__le16 *)&data[2]);
1426 y = le16_to_cpup((__le16 *)&data[4]);
1427 p = le16_to_cpup((__le16 *)&data[6]);
1428 /*
1429 * Convert distance from out prox to distance from tablet.
1430 * distance will be greater than distance_max once
1431 * touching and applying pressure; do not report negative
1432 * distance.
1433 */
1434 if (data[8] <= features->distance_max)
1435 d = features->distance_max - data[8];
1436
1437 pen = data[1] & 0x01;
1438 btn1 = data[1] & 0x02;
1439 btn2 = data[1] & 0x04;
1440 }
1441
1442 input_report_key(input, BTN_TOUCH, pen);
1443 input_report_key(input, BTN_STYLUS, btn1);
1444 input_report_key(input, BTN_STYLUS2, btn2);
1445
1446 input_report_abs(input, ABS_X, x);
1447 input_report_abs(input, ABS_Y, y);
1448 input_report_abs(input, ABS_PRESSURE, p);
1449 input_report_abs(input, ABS_DISTANCE, d);
1450
1451 if (!prox) {
1452 wacom->id[0] = 0;
1453 wacom->shared->stylus_in_proximity = false;
1454 }
1455
1456 input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
1457 input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
1458
1459 return 1;
1460}
1461
1462static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
1463{
1464 if (len == WACOM_PKGLEN_BBTOUCH)
1465 return wacom_bpt_touch(wacom);
1466 else if (len == WACOM_PKGLEN_BBTOUCH3)
1467 return wacom_bpt3_touch(wacom);
1468 else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN)
1469 return wacom_bpt_pen(wacom);
1470
1471 return 0;
1472}
1473
1474static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
1475{
1476 unsigned char *data = wacom->data;
1477 int connected;
1478
1479 if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
1480 return 0;
1481
1482 connected = data[1] & 0x01;
1483 if (connected) {
1484 int pid, battery, ps_connected;
1485
1486 if ((wacom->shared->type == INTUOSHT) &&
1487 wacom->shared->touch_max) {
1488 input_report_switch(wacom->shared->touch_input,
1489 SW_MUTE_DEVICE, data[5] & 0x40);
1490 input_sync(wacom->shared->touch_input);
1491 }
1492
1493 pid = get_unaligned_be16(&data[6]);
1494 battery = (data[5] & 0x3f) * 100 / 31;
1495 ps_connected = !!(data[5] & 0x80);
1496 if (wacom->pid != pid) {
1497 wacom->pid = pid;
1498 wacom_schedule_work(wacom);
1499 }
1500
1501 if (wacom->shared->type &&
1502 (battery != wacom->battery_capacity ||
1503 ps_connected != wacom->ps_connected)) {
1504 wacom->battery_capacity = battery;
1505 wacom->ps_connected = ps_connected;
1506 wacom->bat_charging = ps_connected &&
1507 wacom->battery_capacity < 100;
1508 wacom_notify_battery(wacom);
1509 }
1510 } else if (wacom->pid != 0) {
1511 /* disconnected while previously connected */
1512 wacom->pid = 0;
1513 wacom_schedule_work(wacom);
1514 wacom->battery_capacity = 0;
1515 wacom->bat_charging = 0;
1516 wacom->ps_connected = 0;
1517 }
1518
1519 return 0;
1520}
1521
1522void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
1523{
1524 bool sync;
1525
1526 switch (wacom_wac->features.type) {
1527 case PENPARTNER:
1528 sync = wacom_penpartner_irq(wacom_wac);
1529 break;
1530
1531 case PL:
1532 sync = wacom_pl_irq(wacom_wac);
1533 break;
1534
1535 case WACOM_G4:
1536 case GRAPHIRE:
1537 case GRAPHIRE_BT:
1538 case WACOM_MO:
1539 sync = wacom_graphire_irq(wacom_wac);
1540 break;
1541
1542 case PTU:
1543 sync = wacom_ptu_irq(wacom_wac);
1544 break;
1545
1546 case DTU:
1547 sync = wacom_dtu_irq(wacom_wac);
1548 break;
1549
1550 case DTUS:
1551 sync = wacom_dtus_irq(wacom_wac);
1552 break;
1553
1554 case INTUOS:
1555 case INTUOS3S:
1556 case INTUOS3:
1557 case INTUOS3L:
1558 case INTUOS4S:
1559 case INTUOS4:
1560 case INTUOS4L:
1561 case CINTIQ:
1562 case WACOM_BEE:
1563 case WACOM_13HD:
1564 case WACOM_21UX2:
1565 case WACOM_22HD:
1566 case WACOM_24HD:
1567 case DTK:
1568 case CINTIQ_HYBRID:
1569 sync = wacom_intuos_irq(wacom_wac);
1570 break;
1571
1572 case INTUOS4WL:
1573 sync = wacom_intuos_bt_irq(wacom_wac, len);
1574 break;
1575
1576 case WACOM_24HDT:
1577 sync = wacom_24hdt_irq(wacom_wac);
1578 break;
1579
1580 case INTUOS5S:
1581 case INTUOS5:
1582 case INTUOS5L:
1583 case INTUOSPS:
1584 case INTUOSPM:
1585 case INTUOSPL:
1586 if (len == WACOM_PKGLEN_BBTOUCH3)
1587 sync = wacom_bpt3_touch(wacom_wac);
1588 else
1589 sync = wacom_intuos_irq(wacom_wac);
1590 break;
1591
1592 case TABLETPC:
1593 case TABLETPCE:
1594 case TABLETPC2FG:
1595 case MTSCREEN:
1596 case MTTPC:
1597 case MTTPC_B:
1598 sync = wacom_tpc_irq(wacom_wac, len);
1599 break;
1600
1601 case BAMBOO_PT:
1602 case INTUOSHT:
1603 sync = wacom_bpt_irq(wacom_wac, len);
1604 break;
1605
1606 case WIRELESS:
1607 sync = wacom_wireless_irq(wacom_wac, len);
1608 break;
1609
1610 default:
1611 sync = false;
1612 break;
1613 }
1614
1615 if (sync) {
1616 input_sync(wacom_wac->input);
1617 if (wacom_wac->pad_input)
1618 input_sync(wacom_wac->pad_input);
1619 }
1620}
1621
1622static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
1623{
1624 struct input_dev *input_dev = wacom_wac->input;
1625
1626 input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
1627
1628 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1629 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1630 __set_bit(BTN_TOOL_BRUSH, input_dev->keybit);
1631 __set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
1632 __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
1633 __set_bit(BTN_STYLUS, input_dev->keybit);
1634 __set_bit(BTN_STYLUS2, input_dev->keybit);
1635
1636 input_set_abs_params(input_dev, ABS_DISTANCE,
1637 0, wacom_wac->features.distance_max, 0, 0);
1638 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
1639 input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
1640 input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
1641}
1642
1643static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
1644{
1645 struct input_dev *input_dev = wacom_wac->input;
1646
1647 input_set_capability(input_dev, EV_REL, REL_WHEEL);
1648
1649 wacom_setup_cintiq(wacom_wac);
1650
1651 __set_bit(BTN_LEFT, input_dev->keybit);
1652 __set_bit(BTN_RIGHT, input_dev->keybit);
1653 __set_bit(BTN_MIDDLE, input_dev->keybit);
1654 __set_bit(BTN_SIDE, input_dev->keybit);
1655 __set_bit(BTN_EXTRA, input_dev->keybit);
1656 __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
1657 __set_bit(BTN_TOOL_LENS, input_dev->keybit);
1658
1659 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
1660 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
1661}
1662
1663void wacom_setup_device_quirks(struct wacom_features *features)
1664{
1665
1666 /* touch device found but size is not defined. use default */
1667 if (features->device_type == BTN_TOOL_FINGER && !features->x_max) {
1668 features->x_max = 1023;
1669 features->y_max = 1023;
1670 }
1671
1672 /* these device have multiple inputs */
1673 if (features->type >= WIRELESS ||
1674 (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
1675 (features->oVid && features->oPid))
1676 features->quirks |= WACOM_QUIRK_MULTI_INPUT;
1677
1678 /* quirk for bamboo touch with 2 low res touches */
1679 if (features->type == BAMBOO_PT &&
1680 features->pktlen == WACOM_PKGLEN_BBTOUCH) {
1681 features->x_max <<= 5;
1682 features->y_max <<= 5;
1683 features->x_fuzz <<= 5;
1684 features->y_fuzz <<= 5;
1685 features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
1686 }
1687
1688 if (features->type == WIRELESS) {
1689
1690 /* monitor never has input and pen/touch have delayed create */
1691 features->quirks |= WACOM_QUIRK_NO_INPUT;
1692
1693 /* must be monitor interface if no device_type set */
1694 if (!features->device_type) {
1695 features->quirks |= WACOM_QUIRK_MONITOR;
1696 features->quirks |= WACOM_QUIRK_BATTERY;
1697 }
1698 }
1699}
1700
1701static void wacom_abs_set_axis(struct input_dev *input_dev,
1702 struct wacom_wac *wacom_wac)
1703{
1704 struct wacom_features *features = &wacom_wac->features;
1705
1706 if (features->device_type == BTN_TOOL_PEN) {
1707 input_set_abs_params(input_dev, ABS_X, features->x_min,
1708 features->x_max, features->x_fuzz, 0);
1709 input_set_abs_params(input_dev, ABS_Y, features->y_min,
1710 features->y_max, features->y_fuzz, 0);
1711 input_set_abs_params(input_dev, ABS_PRESSURE, 0,
1712 features->pressure_max, features->pressure_fuzz, 0);
1713
1714 /* penabled devices have fixed resolution for each model */
1715 input_abs_set_res(input_dev, ABS_X, features->x_resolution);
1716 input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
1717 } else {
1718 if (features->touch_max == 1) {
1719 input_set_abs_params(input_dev, ABS_X, 0,
1720 features->x_max, features->x_fuzz, 0);
1721 input_set_abs_params(input_dev, ABS_Y, 0,
1722 features->y_max, features->y_fuzz, 0);
1723 input_abs_set_res(input_dev, ABS_X,
1724 features->x_resolution);
1725 input_abs_set_res(input_dev, ABS_Y,
1726 features->y_resolution);
1727 }
1728
1729 if (features->touch_max > 1) {
1730 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
1731 features->x_max, features->x_fuzz, 0);
1732 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
1733 features->y_max, features->y_fuzz, 0);
1734 input_abs_set_res(input_dev, ABS_MT_POSITION_X,
1735 features->x_resolution);
1736 input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
1737 features->y_resolution);
1738 }
1739 }
1740}
1741
1742int wacom_setup_input_capabilities(struct input_dev *input_dev,
1743 struct wacom_wac *wacom_wac)
1744{
1745 struct wacom_features *features = &wacom_wac->features;
1746
1747 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1748
1749 __set_bit(BTN_TOUCH, input_dev->keybit);
1750 __set_bit(ABS_MISC, input_dev->absbit);
1751
1752 wacom_abs_set_axis(input_dev, wacom_wac);
1753
1754 switch (features->type) {
1755 case WACOM_MO:
1756 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
1757 /* fall through */
1758
1759 case WACOM_G4:
1760 /* fall through */
1761
1762 case GRAPHIRE:
1763 input_set_capability(input_dev, EV_REL, REL_WHEEL);
1764
1765 __set_bit(BTN_LEFT, input_dev->keybit);
1766 __set_bit(BTN_RIGHT, input_dev->keybit);
1767 __set_bit(BTN_MIDDLE, input_dev->keybit);
1768
1769 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1770 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1771 __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
1772 __set_bit(BTN_STYLUS, input_dev->keybit);
1773 __set_bit(BTN_STYLUS2, input_dev->keybit);
1774
1775 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1776 break;
1777
1778 case GRAPHIRE_BT:
1779 __clear_bit(ABS_MISC, input_dev->absbit);
1780 input_set_abs_params(input_dev, ABS_DISTANCE, 0,
1781 features->distance_max,
1782 0, 0);
1783
1784 input_set_capability(input_dev, EV_REL, REL_WHEEL);
1785
1786 __set_bit(BTN_LEFT, input_dev->keybit);
1787 __set_bit(BTN_RIGHT, input_dev->keybit);
1788 __set_bit(BTN_MIDDLE, input_dev->keybit);
1789
1790 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1791 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1792 __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
1793 __set_bit(BTN_STYLUS, input_dev->keybit);
1794 __set_bit(BTN_STYLUS2, input_dev->keybit);
1795
1796 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1797 break;
1798
1799 case WACOM_24HD:
1800 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1801 input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
1802 /* fall through */
1803
1804 case DTK:
1805 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1806
1807 wacom_setup_cintiq(wacom_wac);
1808 break;
1809
1810 case WACOM_22HD:
1811 case WACOM_21UX2:
1812 case WACOM_BEE:
1813 case CINTIQ:
1814 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1815
1816 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1817
1818 wacom_setup_cintiq(wacom_wac);
1819 break;
1820
1821 case WACOM_13HD:
1822 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1823 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1824 wacom_setup_cintiq(wacom_wac);
1825 break;
1826
1827 case INTUOS3:
1828 case INTUOS3L:
1829 case INTUOS3S:
1830 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1831 /* fall through */
1832
1833 case INTUOS:
1834 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1835
1836 wacom_setup_intuos(wacom_wac);
1837 break;
1838
1839 case INTUOS5:
1840 case INTUOS5L:
1841 case INTUOSPM:
1842 case INTUOSPL:
1843 case INTUOS5S:
1844 case INTUOSPS:
1845 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1846
1847 if (features->device_type == BTN_TOOL_PEN) {
1848 input_set_abs_params(input_dev, ABS_DISTANCE, 0,
1849 features->distance_max,
1850 0, 0);
1851
1852 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1853
1854 wacom_setup_intuos(wacom_wac);
1855 } else if (features->device_type == BTN_TOOL_FINGER) {
1856 __clear_bit(ABS_MISC, input_dev->absbit);
1857
1858 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
1859 0, features->x_max, 0, 0);
1860 input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
1861 0, features->y_max, 0, 0);
1862 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
1863 }
1864 break;
1865
1866 case INTUOS4:
1867 case INTUOS4WL:
1868 case INTUOS4L:
1869 case INTUOS4S:
1870 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1871 wacom_setup_intuos(wacom_wac);
1872
1873 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1874 break;
1875
1876 case WACOM_24HDT:
1877 if (features->device_type == BTN_TOOL_FINGER) {
1878 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
1879 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
1880 input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
1881 input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
1882 }
1883 /* fall through */
1884
1885 case MTSCREEN:
1886 case MTTPC:
1887 case MTTPC_B:
1888 case TABLETPC2FG:
1889 if (features->device_type == BTN_TOOL_FINGER && features->touch_max > 1)
1890 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT);
1891 /* fall through */
1892
1893 case TABLETPC:
1894 case TABLETPCE:
1895 __clear_bit(ABS_MISC, input_dev->absbit);
1896
1897 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1898
1899 if (features->device_type != BTN_TOOL_PEN)
1900 break; /* no need to process stylus stuff */
1901
1902 /* fall through */
1903
1904 case DTUS:
1905 case PL:
1906 case DTU:
1907 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1908 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1909 __set_bit(BTN_STYLUS, input_dev->keybit);
1910 __set_bit(BTN_STYLUS2, input_dev->keybit);
1911
1912 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1913 break;
1914
1915 case PTU:
1916 __set_bit(BTN_STYLUS2, input_dev->keybit);
1917 /* fall through */
1918
1919 case PENPARTNER:
1920 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1921 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1922 __set_bit(BTN_STYLUS, input_dev->keybit);
1923
1924 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1925 break;
1926
1927 case INTUOSHT:
1928 if (features->touch_max &&
1929 features->device_type == BTN_TOOL_FINGER) {
1930 input_dev->evbit[0] |= BIT_MASK(EV_SW);
1931 __set_bit(SW_MUTE_DEVICE, input_dev->swbit);
1932 }
1933 /* fall through */
1934
1935 case BAMBOO_PT:
1936 __clear_bit(ABS_MISC, input_dev->absbit);
1937
1938 if (features->device_type == BTN_TOOL_FINGER) {
1939
1940 if (features->touch_max) {
1941 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
1942 input_set_abs_params(input_dev,
1943 ABS_MT_TOUCH_MAJOR,
1944 0, features->x_max, 0, 0);
1945 input_set_abs_params(input_dev,
1946 ABS_MT_TOUCH_MINOR,
1947 0, features->y_max, 0, 0);
1948 }
1949 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
1950 } else {
1951 /* buttons/keys only interface */
1952 __clear_bit(ABS_X, input_dev->absbit);
1953 __clear_bit(ABS_Y, input_dev->absbit);
1954 __clear_bit(BTN_TOUCH, input_dev->keybit);
1955 }
1956 } else if (features->device_type == BTN_TOOL_PEN) {
1957 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1958 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1959 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1960 __set_bit(BTN_STYLUS, input_dev->keybit);
1961 __set_bit(BTN_STYLUS2, input_dev->keybit);
1962 input_set_abs_params(input_dev, ABS_DISTANCE, 0,
1963 features->distance_max,
1964 0, 0);
1965 }
1966 break;
1967
1968 case CINTIQ_HYBRID:
1969 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1970 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1971
1972 wacom_setup_cintiq(wacom_wac);
1973 break;
1974 }
1975 return 0;
1976}
1977
1978int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
1979 struct wacom_wac *wacom_wac)
1980{
1981 struct wacom_features *features = &wacom_wac->features;
1982 int i;
1983
1984 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1985
1986 /* kept for making legacy xf86-input-wacom working with the wheels */
1987 __set_bit(ABS_MISC, input_dev->absbit);
1988
1989 /* kept for making legacy xf86-input-wacom accepting the pad */
1990 input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);
1991 input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);
1992
1993 switch (features->type) {
1994 case GRAPHIRE_BT:
1995 __set_bit(BTN_0, input_dev->keybit);
1996 __set_bit(BTN_1, input_dev->keybit);
1997 break;
1998
1999 case WACOM_MO:
2000 __set_bit(BTN_BACK, input_dev->keybit);
2001 __set_bit(BTN_LEFT, input_dev->keybit);
2002 __set_bit(BTN_FORWARD, input_dev->keybit);
2003 __set_bit(BTN_RIGHT, input_dev->keybit);
2004 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
2005 break;
2006
2007 case WACOM_G4:
2008 __set_bit(BTN_BACK, input_dev->keybit);
2009 __set_bit(BTN_LEFT, input_dev->keybit);
2010 __set_bit(BTN_FORWARD, input_dev->keybit);
2011 __set_bit(BTN_RIGHT, input_dev->keybit);
2012 input_set_capability(input_dev, EV_REL, REL_WHEEL);
2013 break;
2014
2015 case WACOM_24HD:
2016 __set_bit(BTN_A, input_dev->keybit);
2017 __set_bit(BTN_B, input_dev->keybit);
2018 __set_bit(BTN_C, input_dev->keybit);
2019 __set_bit(BTN_X, input_dev->keybit);
2020 __set_bit(BTN_Y, input_dev->keybit);
2021 __set_bit(BTN_Z, input_dev->keybit);
2022
2023 for (i = 0; i < 10; i++)
2024 __set_bit(BTN_0 + i, input_dev->keybit);
2025
2026 __set_bit(KEY_PROG1, input_dev->keybit);
2027 __set_bit(KEY_PROG2, input_dev->keybit);
2028 __set_bit(KEY_PROG3, input_dev->keybit);
2029
2030 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
2031 input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
2032 break;
2033
2034 case DTK:
2035 for (i = 0; i < 6; i++)
2036 __set_bit(BTN_0 + i, input_dev->keybit);
2037
2038 break;
2039
2040 case WACOM_22HD:
2041 __set_bit(KEY_PROG1, input_dev->keybit);
2042 __set_bit(KEY_PROG2, input_dev->keybit);
2043 __set_bit(KEY_PROG3, input_dev->keybit);
2044 /* fall through */
2045
2046 case WACOM_21UX2:
2047 __set_bit(BTN_A, input_dev->keybit);
2048 __set_bit(BTN_B, input_dev->keybit);
2049 __set_bit(BTN_C, input_dev->keybit);
2050 __set_bit(BTN_X, input_dev->keybit);
2051 __set_bit(BTN_Y, input_dev->keybit);
2052 __set_bit(BTN_Z, input_dev->keybit);
2053 __set_bit(BTN_BASE, input_dev->keybit);
2054 __set_bit(BTN_BASE2, input_dev->keybit);
2055 /* fall through */
2056
2057 case WACOM_BEE:
2058 __set_bit(BTN_8, input_dev->keybit);
2059 __set_bit(BTN_9, input_dev->keybit);
2060 /* fall through */
2061
2062 case CINTIQ:
2063 for (i = 0; i < 8; i++)
2064 __set_bit(BTN_0 + i, input_dev->keybit);
2065
2066 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
2067 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
2068 break;
2069
2070 case WACOM_13HD:
2071 for (i = 0; i < 9; i++)
2072 __set_bit(BTN_0 + i, input_dev->keybit);
2073
2074 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
2075 break;
2076
2077 case INTUOS3:
2078 case INTUOS3L:
2079 __set_bit(BTN_4, input_dev->keybit);
2080 __set_bit(BTN_5, input_dev->keybit);
2081 __set_bit(BTN_6, input_dev->keybit);
2082 __set_bit(BTN_7, input_dev->keybit);
2083
2084 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
2085 /* fall through */
2086
2087 case INTUOS3S:
2088 __set_bit(BTN_0, input_dev->keybit);
2089 __set_bit(BTN_1, input_dev->keybit);
2090 __set_bit(BTN_2, input_dev->keybit);
2091 __set_bit(BTN_3, input_dev->keybit);
2092
2093 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
2094 break;
2095
2096 case INTUOS5:
2097 case INTUOS5L:
2098 case INTUOSPM:
2099 case INTUOSPL:
2100 __set_bit(BTN_7, input_dev->keybit);
2101 __set_bit(BTN_8, input_dev->keybit);
2102 /* fall through */
2103
2104 case INTUOS5S:
2105 case INTUOSPS:
2106 /* touch interface does not have the pad device */
2107 if (features->device_type != BTN_TOOL_PEN)
2108 return 1;
2109
2110 for (i = 0; i < 7; i++)
2111 __set_bit(BTN_0 + i, input_dev->keybit);
2112
2113 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
2114 break;
2115
2116 case INTUOS4WL:
2117 /*
2118 * For Bluetooth devices, the udev rule does not work correctly
2119 * for pads unless we add a stylus capability, which forces
2120 * ID_INPUT_TABLET to be set.
2121 */
2122 __set_bit(BTN_STYLUS, input_dev->keybit);
2123 /* fall through */
2124
2125 case INTUOS4:
2126 case INTUOS4L:
2127 __set_bit(BTN_7, input_dev->keybit);
2128 __set_bit(BTN_8, input_dev->keybit);
2129 /* fall through */
2130
2131 case INTUOS4S:
2132 for (i = 0; i < 7; i++)
2133 __set_bit(BTN_0 + i, input_dev->keybit);
2134
2135 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
2136 break;
2137
2138 case CINTIQ_HYBRID:
2139 for (i = 0; i < 9; i++)
2140 __set_bit(BTN_0 + i, input_dev->keybit);
2141
2142 break;
2143
2144 case DTUS:
2145 for (i = 0; i < 4; i++)
2146 __set_bit(BTN_0 + i, input_dev->keybit);
2147 break;
2148
2149 case INTUOSHT:
2150 case BAMBOO_PT:
2151 /* pad device is on the touch interface */
2152 if (features->device_type != BTN_TOOL_FINGER)
2153 return 1;
2154
2155 __clear_bit(ABS_MISC, input_dev->absbit);
2156
2157 __set_bit(BTN_LEFT, input_dev->keybit);
2158 __set_bit(BTN_FORWARD, input_dev->keybit);
2159 __set_bit(BTN_BACK, input_dev->keybit);
2160 __set_bit(BTN_RIGHT, input_dev->keybit);
2161
2162 break;
2163
2164 default:
2165 /* no pad supported */
2166 return 1;
2167 }
2168 return 0;
2169}
2170
2171static const struct wacom_features wacom_features_0x00 =
2172 { "Wacom Penpartner", 5040, 3780, 255, 0,
2173 PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
2174static const struct wacom_features wacom_features_0x10 =
2175 { "Wacom Graphire", 10206, 7422, 511, 63,
2176 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2177static const struct wacom_features wacom_features_0x81 =
2178 { "Wacom Graphire BT", 16704, 12064, 511, 32,
2179 GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2180static const struct wacom_features wacom_features_0x11 =
2181 { "Wacom Graphire2 4x5", 10206, 7422, 511, 63,
2182 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2183static const struct wacom_features wacom_features_0x12 =
2184 { "Wacom Graphire2 5x7", 13918, 10206, 511, 63,
2185 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2186static const struct wacom_features wacom_features_0x13 =
2187 { "Wacom Graphire3", 10208, 7424, 511, 63,
2188 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2189static const struct wacom_features wacom_features_0x14 =
2190 { "Wacom Graphire3 6x8", 16704, 12064, 511, 63,
2191 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2192static const struct wacom_features wacom_features_0x15 =
2193 { "Wacom Graphire4 4x5", 10208, 7424, 511, 63,
2194 WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2195static const struct wacom_features wacom_features_0x16 =
2196 { "Wacom Graphire4 6x8", 16704, 12064, 511, 63,
2197 WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2198static const struct wacom_features wacom_features_0x17 =
2199 { "Wacom BambooFun 4x5", 14760, 9225, 511, 63,
2200 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2201static const struct wacom_features wacom_features_0x18 =
2202 { "Wacom BambooFun 6x8", 21648, 13530, 511, 63,
2203 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2204static const struct wacom_features wacom_features_0x19 =
2205 { "Wacom Bamboo1 Medium", 16704, 12064, 511, 63,
2206 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
2207static const struct wacom_features wacom_features_0x60 =
2208 { "Wacom Volito", 5104, 3712, 511, 63,
2209 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
2210static const struct wacom_features wacom_features_0x61 =
2211 { "Wacom PenStation2", 3250, 2320, 255, 63,
2212 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
2213static const struct wacom_features wacom_features_0x62 =
2214 { "Wacom Volito2 4x5", 5104, 3712, 511, 63,
2215 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
2216static const struct wacom_features wacom_features_0x63 =
2217 { "Wacom Volito2 2x3", 3248, 2320, 511, 63,
2218 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
2219static const struct wacom_features wacom_features_0x64 =
2220 { "Wacom PenPartner2", 3250, 2320, 511, 63,
2221 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
2222static const struct wacom_features wacom_features_0x65 =
2223 { "Wacom Bamboo", 14760, 9225, 511, 63,
2224 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2225static const struct wacom_features wacom_features_0x69 =
2226 { "Wacom Bamboo1", 5104, 3712, 511, 63,
2227 GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
2228static const struct wacom_features wacom_features_0x6A =
2229 { "Wacom Bamboo1 4x6", 14760, 9225, 1023, 63,
2230 GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2231static const struct wacom_features wacom_features_0x6B =
2232 { "Wacom Bamboo1 5x8", 21648, 13530, 1023, 63,
2233 GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2234static const struct wacom_features wacom_features_0x20 =
2235 { "Wacom Intuos 4x5", 12700, 10600, 1023, 31,
2236 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2237static const struct wacom_features wacom_features_0x21 =
2238 { "Wacom Intuos 6x8", 20320, 16240, 1023, 31,
2239 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2240static const struct wacom_features wacom_features_0x22 =
2241 { "Wacom Intuos 9x12", 30480, 24060, 1023, 31,
2242 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2243static const struct wacom_features wacom_features_0x23 =
2244 { "Wacom Intuos 12x12", 30480, 31680, 1023, 31,
2245 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2246static const struct wacom_features wacom_features_0x24 =
2247 { "Wacom Intuos 12x18", 45720, 31680, 1023, 31,
2248 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2249static const struct wacom_features wacom_features_0x30 =
2250 { "Wacom PL400", 5408, 4056, 255, 0,
2251 PL, WACOM_PL_RES, WACOM_PL_RES };
2252static const struct wacom_features wacom_features_0x31 =
2253 { "Wacom PL500", 6144, 4608, 255, 0,
2254 PL, WACOM_PL_RES, WACOM_PL_RES };
2255static const struct wacom_features wacom_features_0x32 =
2256 { "Wacom PL600", 6126, 4604, 255, 0,
2257 PL, WACOM_PL_RES, WACOM_PL_RES };
2258static const struct wacom_features wacom_features_0x33 =
2259 { "Wacom PL600SX", 6260, 5016, 255, 0,
2260 PL, WACOM_PL_RES, WACOM_PL_RES };
2261static const struct wacom_features wacom_features_0x34 =
2262 { "Wacom PL550", 6144, 4608, 511, 0,
2263 PL, WACOM_PL_RES, WACOM_PL_RES };
2264static const struct wacom_features wacom_features_0x35 =
2265 { "Wacom PL800", 7220, 5780, 511, 0,
2266 PL, WACOM_PL_RES, WACOM_PL_RES };
2267static const struct wacom_features wacom_features_0x37 =
2268 { "Wacom PL700", 6758, 5406, 511, 0,
2269 PL, WACOM_PL_RES, WACOM_PL_RES };
2270static const struct wacom_features wacom_features_0x38 =
2271 { "Wacom PL510", 6282, 4762, 511, 0,
2272 PL, WACOM_PL_RES, WACOM_PL_RES };
2273static const struct wacom_features wacom_features_0x39 =
2274 { "Wacom DTU710", 34080, 27660, 511, 0,
2275 PL, WACOM_PL_RES, WACOM_PL_RES };
2276static const struct wacom_features wacom_features_0xC4 =
2277 { "Wacom DTF521", 6282, 4762, 511, 0,
2278 PL, WACOM_PL_RES, WACOM_PL_RES };
2279static const struct wacom_features wacom_features_0xC0 =
2280 { "Wacom DTF720", 6858, 5506, 511, 0,
2281 PL, WACOM_PL_RES, WACOM_PL_RES };
2282static const struct wacom_features wacom_features_0xC2 =
2283 { "Wacom DTF720a", 6858, 5506, 511, 0,
2284 PL, WACOM_PL_RES, WACOM_PL_RES };
2285static const struct wacom_features wacom_features_0x03 =
2286 { "Wacom Cintiq Partner", 20480, 15360, 511, 0,
2287 PTU, WACOM_PL_RES, WACOM_PL_RES };
2288static const struct wacom_features wacom_features_0x41 =
2289 { "Wacom Intuos2 4x5", 12700, 10600, 1023, 31,
2290 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2291static const struct wacom_features wacom_features_0x42 =
2292 { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,
2293 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2294static const struct wacom_features wacom_features_0x43 =
2295 { "Wacom Intuos2 9x12", 30480, 24060, 1023, 31,
2296 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2297static const struct wacom_features wacom_features_0x44 =
2298 { "Wacom Intuos2 12x12", 30480, 31680, 1023, 31,
2299 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2300static const struct wacom_features wacom_features_0x45 =
2301 { "Wacom Intuos2 12x18", 45720, 31680, 1023, 31,
2302 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2303static const struct wacom_features wacom_features_0xB0 =
2304 { "Wacom Intuos3 4x5", 25400, 20320, 1023, 63,
2305 INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2306static const struct wacom_features wacom_features_0xB1 =
2307 { "Wacom Intuos3 6x8", 40640, 30480, 1023, 63,
2308 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2309static const struct wacom_features wacom_features_0xB2 =
2310 { "Wacom Intuos3 9x12", 60960, 45720, 1023, 63,
2311 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2312static const struct wacom_features wacom_features_0xB3 =
2313 { "Wacom Intuos3 12x12", 60960, 60960, 1023, 63,
2314 INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2315static const struct wacom_features wacom_features_0xB4 =
2316 { "Wacom Intuos3 12x19", 97536, 60960, 1023, 63,
2317 INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2318static const struct wacom_features wacom_features_0xB5 =
2319 { "Wacom Intuos3 6x11", 54204, 31750, 1023, 63,
2320 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2321static const struct wacom_features wacom_features_0xB7 =
2322 { "Wacom Intuos3 4x6", 31496, 19685, 1023, 63,
2323 INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2324static const struct wacom_features wacom_features_0xB8 =
2325 { "Wacom Intuos4 4x6", 31496, 19685, 2047, 63,
2326 INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2327static const struct wacom_features wacom_features_0xB9 =
2328 { "Wacom Intuos4 6x9", 44704, 27940, 2047, 63,
2329 INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2330static const struct wacom_features wacom_features_0xBA =
2331 { "Wacom Intuos4 8x13", 65024, 40640, 2047, 63,
2332 INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2333static const struct wacom_features wacom_features_0xBB =
2334 { "Wacom Intuos4 12x19", 97536, 60960, 2047, 63,
2335 INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2336static const struct wacom_features wacom_features_0xBC =
2337 { "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
2338 INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2339static const struct wacom_features wacom_features_0xBD =
2340 { "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
2341 INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2342static const struct wacom_features wacom_features_0x26 =
2343 { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63,
2344 INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 };
2345static const struct wacom_features wacom_features_0x27 =
2346 { "Wacom Intuos5 touch M", 44704, 27940, 2047, 63,
2347 INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 };
2348static const struct wacom_features wacom_features_0x28 =
2349 { "Wacom Intuos5 touch L", 65024, 40640, 2047, 63,
2350 INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 };
2351static const struct wacom_features wacom_features_0x29 =
2352 { "Wacom Intuos5 S", 31496, 19685, 2047, 63,
2353 INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2354static const struct wacom_features wacom_features_0x2A =
2355 { "Wacom Intuos5 M", 44704, 27940, 2047, 63,
2356 INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2357static const struct wacom_features wacom_features_0x314 =
2358 { "Wacom Intuos Pro S", 31496, 19685, 2047, 63,
2359 INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16,
2360 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2361static const struct wacom_features wacom_features_0x315 =
2362 { "Wacom Intuos Pro M", 44704, 27940, 2047, 63,
2363 INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16,
2364 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2365static const struct wacom_features wacom_features_0x317 =
2366 { "Wacom Intuos Pro L", 65024, 40640, 2047, 63,
2367 INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16,
2368 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2369static const struct wacom_features wacom_features_0xF4 =
2370 { "Wacom Cintiq 24HD", 104280, 65400, 2047, 63,
2371 WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
2372static const struct wacom_features wacom_features_0xF8 =
2373 { "Wacom Cintiq 24HD touch", 104280, 65400, 2047, 63, /* Pen */
2374 WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
2375 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
2376static const struct wacom_features wacom_features_0xF6 =
2377 { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
2378 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
2379 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2380static const struct wacom_features wacom_features_0x3F =
2381 { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
2382 CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2383static const struct wacom_features wacom_features_0xC5 =
2384 { "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63,
2385 WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2386static const struct wacom_features wacom_features_0xC6 =
2387 { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,
2388 WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2389static const struct wacom_features wacom_features_0x304 =
2390 { "Wacom Cintiq 13HD", 59352, 33648, 1023, 63,
2391 WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
2392static const struct wacom_features wacom_features_0xC7 =
2393 { "Wacom DTU1931", 37832, 30305, 511, 0,
2394 PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2395static const struct wacom_features wacom_features_0xCE =
2396 { "Wacom DTU2231", 47864, 27011, 511, 0,
2397 DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
2398 .check_for_hid_type = true, .hid_type = HID_TYPE_USBMOUSE };
2399static const struct wacom_features wacom_features_0xF0 =
2400 { "Wacom DTU1631", 34623, 19553, 511, 0,
2401 DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2402static const struct wacom_features wacom_features_0xFB =
2403 { "Wacom DTU1031", 22096, 13960, 511, 0,
2404 DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2405static const struct wacom_features wacom_features_0x57 =
2406 { "Wacom DTK2241", 95640, 54060, 2047, 63,
2407 DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
2408static const struct wacom_features wacom_features_0x59 = /* Pen */
2409 { "Wacom DTH2242", 95640, 54060, 2047, 63,
2410 DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
2411 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };
2412static const struct wacom_features wacom_features_0x5D = /* Touch */
2413 { "Wacom DTH2242", .type = WACOM_24HDT,
2414 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10,
2415 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2416static const struct wacom_features wacom_features_0xCC =
2417 { "Wacom Cintiq 21UX2", 87000, 65400, 2047, 63,
2418 WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
2419static const struct wacom_features wacom_features_0xFA =
2420 { "Wacom Cintiq 22HD", 95640, 54060, 2047, 63,
2421 WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
2422static const struct wacom_features wacom_features_0x5B =
2423 { "Wacom Cintiq 22HDT", 95640, 54060, 2047, 63,
2424 WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
2425 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
2426static const struct wacom_features wacom_features_0x5E =
2427 { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
2428 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10,
2429 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2430static const struct wacom_features wacom_features_0x90 =
2431 { "Wacom ISDv4 90", 26202, 16325, 255, 0,
2432 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2433static const struct wacom_features wacom_features_0x93 =
2434 { "Wacom ISDv4 93", 26202, 16325, 255, 0,
2435 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2436static const struct wacom_features wacom_features_0x97 =
2437 { "Wacom ISDv4 97", 26202, 16325, 511, 0,
2438 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2439static const struct wacom_features wacom_features_0x9A =
2440 { "Wacom ISDv4 9A", 26202, 16325, 255, 0,
2441 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2442static const struct wacom_features wacom_features_0x9F =
2443 { "Wacom ISDv4 9F", 26202, 16325, 255, 0,
2444 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2445static const struct wacom_features wacom_features_0xE2 =
2446 { "Wacom ISDv4 E2", 26202, 16325, 255, 0,
2447 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2448static const struct wacom_features wacom_features_0xE3 =
2449 { "Wacom ISDv4 E3", 26202, 16325, 255, 0,
2450 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2451static const struct wacom_features wacom_features_0xE5 =
2452 { "Wacom ISDv4 E5", 26202, 16325, 255, 0,
2453 MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2454static const struct wacom_features wacom_features_0xE6 =
2455 { "Wacom ISDv4 E6", 27760, 15694, 255, 0,
2456 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2457static const struct wacom_features wacom_features_0xEC =
2458 { "Wacom ISDv4 EC", 25710, 14500, 255, 0,
2459 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2460static const struct wacom_features wacom_features_0xED =
2461 { "Wacom ISDv4 ED", 26202, 16325, 255, 0,
2462 TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2463static const struct wacom_features wacom_features_0xEF =
2464 { "Wacom ISDv4 EF", 26202, 16325, 255, 0,
2465 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2466static const struct wacom_features wacom_features_0x100 =
2467 { "Wacom ISDv4 100", 26202, 16325, 255, 0,
2468 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2469static const struct wacom_features wacom_features_0x101 =
2470 { "Wacom ISDv4 101", 26202, 16325, 255, 0,
2471 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2472static const struct wacom_features wacom_features_0x10D =
2473 { "Wacom ISDv4 10D", 26202, 16325, 255, 0,
2474 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2475static const struct wacom_features wacom_features_0x10E =
2476 { "Wacom ISDv4 10E", 27760, 15694, 255, 0,
2477 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2478static const struct wacom_features wacom_features_0x10F =
2479 { "Wacom ISDv4 10F", 27760, 15694, 255, 0,
2480 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2481static const struct wacom_features wacom_features_0x116 =
2482 { "Wacom ISDv4 116", 26202, 16325, 255, 0,
2483 TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2484static const struct wacom_features wacom_features_0x12C =
2485 { "Wacom ISDv4 12C", 27848, 15752, 2047, 0,
2486 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2487static const struct wacom_features wacom_features_0x4001 =
2488 { "Wacom ISDv4 4001", 26202, 16325, 255, 0,
2489 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2490static const struct wacom_features wacom_features_0x4004 =
2491 { "Wacom ISDv4 4004", 11060, 6220, 255, 0,
2492 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2493static const struct wacom_features wacom_features_0x5000 =
2494 { "Wacom ISDv4 5000", 27848, 15752, 1023, 0,
2495 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2496static const struct wacom_features wacom_features_0x5002 =
2497 { "Wacom ISDv4 5002", 29576, 16724, 1023, 0,
2498 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2499static const struct wacom_features wacom_features_0x47 =
2500 { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,
2501 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2502static const struct wacom_features wacom_features_0x84 =
2503 { "Wacom Wireless Receiver", 0, 0, 0, 0,
2504 WIRELESS, 0, 0, .touch_max = 16 };
2505static const struct wacom_features wacom_features_0xD0 =
2506 { "Wacom Bamboo 2FG", 14720, 9200, 1023, 31,
2507 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2508static const struct wacom_features wacom_features_0xD1 =
2509 { "Wacom Bamboo 2FG 4x5", 14720, 9200, 1023, 31,
2510 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2511static const struct wacom_features wacom_features_0xD2 =
2512 { "Wacom Bamboo Craft", 14720, 9200, 1023, 31,
2513 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2514static const struct wacom_features wacom_features_0xD3 =
2515 { "Wacom Bamboo 2FG 6x8", 21648, 13700, 1023, 31,
2516 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2517static const struct wacom_features wacom_features_0xD4 =
2518 { "Wacom Bamboo Pen", 14720, 9200, 1023, 31,
2519 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2520static const struct wacom_features wacom_features_0xD5 =
2521 { "Wacom Bamboo Pen 6x8", 21648, 13700, 1023, 31,
2522 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2523static const struct wacom_features wacom_features_0xD6 =
2524 { "Wacom BambooPT 2FG 4x5", 14720, 9200, 1023, 31,
2525 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2526static const struct wacom_features wacom_features_0xD7 =
2527 { "Wacom BambooPT 2FG Small", 14720, 9200, 1023, 31,
2528 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2529static const struct wacom_features wacom_features_0xD8 =
2530 { "Wacom Bamboo Comic 2FG", 21648, 13700, 1023, 31,
2531 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2532static const struct wacom_features wacom_features_0xDA =
2533 { "Wacom Bamboo 2FG 4x5 SE", 14720, 9200, 1023, 31,
2534 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2535static const struct wacom_features wacom_features_0xDB =
2536 { "Wacom Bamboo 2FG 6x8 SE", 21648, 13700, 1023, 31,
2537 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
2538static const struct wacom_features wacom_features_0xDD =
2539 { "Wacom Bamboo Connect", 14720, 9200, 1023, 31,
2540 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2541static const struct wacom_features wacom_features_0xDE =
2542 { "Wacom Bamboo 16FG 4x5", 14720, 9200, 1023, 31,
2543 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };
2544static const struct wacom_features wacom_features_0xDF =
2545 { "Wacom Bamboo 16FG 6x8", 21648, 13700, 1023, 31,
2546 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };
2547static const struct wacom_features wacom_features_0x300 =
2548 { "Wacom Bamboo One S", 14720, 9225, 1023, 31,
2549 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2550static const struct wacom_features wacom_features_0x301 =
2551 { "Wacom Bamboo One M", 21648, 13530, 1023, 31,
2552 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2553static const struct wacom_features wacom_features_0x302 =
2554 { "Wacom Intuos PT S", 15200, 9500, 1023, 31,
2555 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
2556 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2557static const struct wacom_features wacom_features_0x303 =
2558 { "Wacom Intuos PT M", 21600, 13500, 1023, 31,
2559 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
2560 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2561static const struct wacom_features wacom_features_0x30E =
2562 { "Wacom Intuos S", 15200, 9500, 1023, 31,
2563 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
2564 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2565static const struct wacom_features wacom_features_0x6004 =
2566 { "ISD-V4", 12800, 8000, 255, 0,
2567 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2568static const struct wacom_features wacom_features_0x307 =
2569 { "Wacom ISDv5 307", 59352, 33648, 2047, 63,
2570 CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
2571 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
2572static const struct wacom_features wacom_features_0x309 =
2573 { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
2574 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,
2575 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2576
2577#define USB_DEVICE_WACOM(prod) \
2578 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
2579 .driver_data = (kernel_ulong_t)&wacom_features_##prod
2580
2581#define BT_DEVICE_WACOM(prod) \
2582 HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
2583 .driver_data = (kernel_ulong_t)&wacom_features_##prod
2584
2585#define USB_DEVICE_LENOVO(prod) \
2586 HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
2587 .driver_data = (kernel_ulong_t)&wacom_features_##prod
2588
2589const struct hid_device_id wacom_ids[] = {
2590 { USB_DEVICE_WACOM(0x00) },
2591 { USB_DEVICE_WACOM(0x03) },
2592 { USB_DEVICE_WACOM(0x10) },
2593 { USB_DEVICE_WACOM(0x11) },
2594 { USB_DEVICE_WACOM(0x12) },
2595 { USB_DEVICE_WACOM(0x13) },
2596 { USB_DEVICE_WACOM(0x14) },
2597 { USB_DEVICE_WACOM(0x15) },
2598 { USB_DEVICE_WACOM(0x16) },
2599 { USB_DEVICE_WACOM(0x17) },
2600 { USB_DEVICE_WACOM(0x18) },
2601 { USB_DEVICE_WACOM(0x19) },
2602 { USB_DEVICE_WACOM(0x20) },
2603 { USB_DEVICE_WACOM(0x21) },
2604 { USB_DEVICE_WACOM(0x22) },
2605 { USB_DEVICE_WACOM(0x23) },
2606 { USB_DEVICE_WACOM(0x24) },
2607 { USB_DEVICE_WACOM(0x26) },
2608 { USB_DEVICE_WACOM(0x27) },
2609 { USB_DEVICE_WACOM(0x28) },
2610 { USB_DEVICE_WACOM(0x29) },
2611 { USB_DEVICE_WACOM(0x2A) },
2612 { USB_DEVICE_WACOM(0x30) },
2613 { USB_DEVICE_WACOM(0x31) },
2614 { USB_DEVICE_WACOM(0x32) },
2615 { USB_DEVICE_WACOM(0x33) },
2616 { USB_DEVICE_WACOM(0x34) },
2617 { USB_DEVICE_WACOM(0x35) },
2618 { USB_DEVICE_WACOM(0x37) },
2619 { USB_DEVICE_WACOM(0x38) },
2620 { USB_DEVICE_WACOM(0x39) },
2621 { USB_DEVICE_WACOM(0x3F) },
2622 { USB_DEVICE_WACOM(0x41) },
2623 { USB_DEVICE_WACOM(0x42) },
2624 { USB_DEVICE_WACOM(0x43) },
2625 { USB_DEVICE_WACOM(0x44) },
2626 { USB_DEVICE_WACOM(0x45) },
2627 { USB_DEVICE_WACOM(0x47) },
2628 { USB_DEVICE_WACOM(0x57) },
2629 { USB_DEVICE_WACOM(0x59) },
2630 { USB_DEVICE_WACOM(0x5B) },
2631 { USB_DEVICE_WACOM(0x5D) },
2632 { USB_DEVICE_WACOM(0x5E) },
2633 { USB_DEVICE_WACOM(0x60) },
2634 { USB_DEVICE_WACOM(0x61) },
2635 { USB_DEVICE_WACOM(0x62) },
2636 { USB_DEVICE_WACOM(0x63) },
2637 { USB_DEVICE_WACOM(0x64) },
2638 { USB_DEVICE_WACOM(0x65) },
2639 { USB_DEVICE_WACOM(0x69) },
2640 { USB_DEVICE_WACOM(0x6A) },
2641 { USB_DEVICE_WACOM(0x6B) },
2642 { BT_DEVICE_WACOM(0x81) },
2643 { USB_DEVICE_WACOM(0x84) },
2644 { USB_DEVICE_WACOM(0x90) },
2645 { USB_DEVICE_WACOM(0x93) },
2646 { USB_DEVICE_WACOM(0x97) },
2647 { USB_DEVICE_WACOM(0x9A) },
2648 { USB_DEVICE_WACOM(0x9F) },
2649 { USB_DEVICE_WACOM(0xB0) },
2650 { USB_DEVICE_WACOM(0xB1) },
2651 { USB_DEVICE_WACOM(0xB2) },
2652 { USB_DEVICE_WACOM(0xB3) },
2653 { USB_DEVICE_WACOM(0xB4) },
2654 { USB_DEVICE_WACOM(0xB5) },
2655 { USB_DEVICE_WACOM(0xB7) },
2656 { USB_DEVICE_WACOM(0xB8) },
2657 { USB_DEVICE_WACOM(0xB9) },
2658 { USB_DEVICE_WACOM(0xBA) },
2659 { USB_DEVICE_WACOM(0xBB) },
2660 { USB_DEVICE_WACOM(0xBC) },
2661 { BT_DEVICE_WACOM(0xBD) },
2662 { USB_DEVICE_WACOM(0xC0) },
2663 { USB_DEVICE_WACOM(0xC2) },
2664 { USB_DEVICE_WACOM(0xC4) },
2665 { USB_DEVICE_WACOM(0xC5) },
2666 { USB_DEVICE_WACOM(0xC6) },
2667 { USB_DEVICE_WACOM(0xC7) },
2668 { USB_DEVICE_WACOM(0xCC) },
2669 { USB_DEVICE_WACOM(0xCE) },
2670 { USB_DEVICE_WACOM(0xD0) },
2671 { USB_DEVICE_WACOM(0xD1) },
2672 { USB_DEVICE_WACOM(0xD2) },
2673 { USB_DEVICE_WACOM(0xD3) },
2674 { USB_DEVICE_WACOM(0xD4) },
2675 { USB_DEVICE_WACOM(0xD5) },
2676 { USB_DEVICE_WACOM(0xD6) },
2677 { USB_DEVICE_WACOM(0xD7) },
2678 { USB_DEVICE_WACOM(0xD8) },
2679 { USB_DEVICE_WACOM(0xDA) },
2680 { USB_DEVICE_WACOM(0xDB) },
2681 { USB_DEVICE_WACOM(0xDD) },
2682 { USB_DEVICE_WACOM(0xDE) },
2683 { USB_DEVICE_WACOM(0xDF) },
2684 { USB_DEVICE_WACOM(0xE2) },
2685 { USB_DEVICE_WACOM(0xE3) },
2686 { USB_DEVICE_WACOM(0xE5) },
2687 { USB_DEVICE_WACOM(0xE6) },
2688 { USB_DEVICE_WACOM(0xEC) },
2689 { USB_DEVICE_WACOM(0xED) },
2690 { USB_DEVICE_WACOM(0xEF) },
2691 { USB_DEVICE_WACOM(0xF0) },
2692 { USB_DEVICE_WACOM(0xF4) },
2693 { USB_DEVICE_WACOM(0xF6) },
2694 { USB_DEVICE_WACOM(0xF8) },
2695 { USB_DEVICE_WACOM(0xFA) },
2696 { USB_DEVICE_WACOM(0xFB) },
2697 { USB_DEVICE_WACOM(0x100) },
2698 { USB_DEVICE_WACOM(0x101) },
2699 { USB_DEVICE_WACOM(0x10D) },
2700 { USB_DEVICE_WACOM(0x10E) },
2701 { USB_DEVICE_WACOM(0x10F) },
2702 { USB_DEVICE_WACOM(0x116) },
2703 { USB_DEVICE_WACOM(0x12C) },
2704 { USB_DEVICE_WACOM(0x300) },
2705 { USB_DEVICE_WACOM(0x301) },
2706 { USB_DEVICE_WACOM(0x302) },
2707 { USB_DEVICE_WACOM(0x303) },
2708 { USB_DEVICE_WACOM(0x304) },
2709 { USB_DEVICE_WACOM(0x307) },
2710 { USB_DEVICE_WACOM(0x309) },
2711 { USB_DEVICE_WACOM(0x30E) },
2712 { USB_DEVICE_WACOM(0x314) },
2713 { USB_DEVICE_WACOM(0x315) },
2714 { USB_DEVICE_WACOM(0x317) },
2715 { USB_DEVICE_WACOM(0x4001) },
2716 { USB_DEVICE_WACOM(0x4004) },
2717 { USB_DEVICE_WACOM(0x5000) },
2718 { USB_DEVICE_WACOM(0x5002) },
2719 { }
2720};
2721MODULE_DEVICE_TABLE(hid, wacom_ids);
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
new file mode 100644
index 000000000000..339ab5d81a2d
--- /dev/null
+++ b/drivers/hid/wacom_wac.h
@@ -0,0 +1,179 @@
1/*
2 * drivers/input/tablet/wacom_wac.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef WACOM_WAC_H
10#define WACOM_WAC_H
11
12#include <linux/types.h>
13
14/* maximum packet length for USB devices */
15#define WACOM_PKGLEN_MAX 68
16
17#define WACOM_NAME_MAX 64
18
19/* packet length for individual models */
20#define WACOM_PKGLEN_PENPRTN 7
21#define WACOM_PKGLEN_GRAPHIRE 8
22#define WACOM_PKGLEN_BBFUN 9
23#define WACOM_PKGLEN_INTUOS 10
24#define WACOM_PKGLEN_TPC1FG 5
25#define WACOM_PKGLEN_TPC1FG_B 10
26#define WACOM_PKGLEN_TPC2FG 14
27#define WACOM_PKGLEN_BBTOUCH 20
28#define WACOM_PKGLEN_BBTOUCH3 64
29#define WACOM_PKGLEN_BBPEN 10
30#define WACOM_PKGLEN_WIRELESS 32
31#define WACOM_PKGLEN_MTOUCH 62
32#define WACOM_PKGLEN_MTTPC 40
33#define WACOM_PKGLEN_DTUS 68
34#define WACOM_PKGLEN_PENABLED 8
35
36/* wacom data size per MT contact */
37#define WACOM_BYTES_PER_MT_PACKET 11
38#define WACOM_BYTES_PER_24HDT_PACKET 14
39
40/* device IDs */
41#define STYLUS_DEVICE_ID 0x02
42#define TOUCH_DEVICE_ID 0x03
43#define CURSOR_DEVICE_ID 0x06
44#define ERASER_DEVICE_ID 0x0A
45#define PAD_DEVICE_ID 0x0F
46
47/* wacom data packet report IDs */
48#define WACOM_REPORT_PENABLED 2
49#define WACOM_REPORT_PENABLED_BT 3
50#define WACOM_REPORT_INTUOSREAD 5
51#define WACOM_REPORT_INTUOSWRITE 6
52#define WACOM_REPORT_INTUOSPAD 12
53#define WACOM_REPORT_INTUOS5PAD 3
54#define WACOM_REPORT_DTUSPAD 21
55#define WACOM_REPORT_TPC1FG 6
56#define WACOM_REPORT_TPC2FG 13
57#define WACOM_REPORT_TPCMT 13
58#define WACOM_REPORT_TPCMT2 3
59#define WACOM_REPORT_TPCHID 15
60#define WACOM_REPORT_TPCST 16
61#define WACOM_REPORT_DTUS 17
62#define WACOM_REPORT_TPC1FGE 18
63#define WACOM_REPORT_24HDT 1
64#define WACOM_REPORT_WL 128
65#define WACOM_REPORT_USB 192
66
67/* device quirks */
68#define WACOM_QUIRK_MULTI_INPUT 0x0001
69#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
70#define WACOM_QUIRK_NO_INPUT 0x0004
71#define WACOM_QUIRK_MONITOR 0x0008
72#define WACOM_QUIRK_BATTERY 0x0010
73
74enum {
75 PENPARTNER = 0,
76 GRAPHIRE,
77 GRAPHIRE_BT,
78 WACOM_G4,
79 PTU,
80 PL,
81 DTU,
82 DTUS,
83 INTUOS,
84 INTUOS3S,
85 INTUOS3,
86 INTUOS3L,
87 INTUOS4S,
88 INTUOS4,
89 INTUOS4WL,
90 INTUOS4L,
91 INTUOS5S,
92 INTUOS5,
93 INTUOS5L,
94 INTUOSPS,
95 INTUOSPM,
96 INTUOSPL,
97 INTUOSHT,
98 WACOM_21UX2,
99 WACOM_22HD,
100 DTK,
101 WACOM_24HD,
102 CINTIQ_HYBRID,
103 CINTIQ,
104 WACOM_BEE,
105 WACOM_13HD,
106 WACOM_MO,
107 WIRELESS,
108 BAMBOO_PT,
109 WACOM_24HDT,
110 TABLETPC, /* add new TPC below */
111 TABLETPCE,
112 TABLETPC2FG,
113 MTSCREEN,
114 MTTPC,
115 MTTPC_B,
116 MAX_TYPE
117};
118
119struct wacom_features {
120 const char *name;
121 int x_max;
122 int y_max;
123 int pressure_max;
124 int distance_max;
125 int type;
126 int x_resolution;
127 int y_resolution;
128 int x_min;
129 int y_min;
130 int device_type;
131 int x_phy;
132 int y_phy;
133 unsigned unit;
134 int unitExpo;
135 int x_fuzz;
136 int y_fuzz;
137 int pressure_fuzz;
138 int distance_fuzz;
139 unsigned quirks;
140 unsigned touch_max;
141 int oVid;
142 int oPid;
143 int pktlen;
144 bool check_for_hid_type;
145 int hid_type;
146};
147
148struct wacom_shared {
149 bool stylus_in_proximity;
150 bool touch_down;
151 /* for wireless device to access USB interfaces */
152 unsigned touch_max;
153 int type;
154 struct input_dev *touch_input;
155};
156
157struct wacom_wac {
158 char name[WACOM_NAME_MAX];
159 char pad_name[WACOM_NAME_MAX];
160 char bat_name[WACOM_NAME_MAX];
161 char ac_name[WACOM_NAME_MAX];
162 unsigned char data[WACOM_PKGLEN_MAX];
163 int tool[2];
164 int id[2];
165 __u32 serial[2];
166 struct wacom_features features;
167 struct wacom_shared *shared;
168 struct input_dev *input;
169 struct input_dev *pad_input;
170 int pid;
171 int battery_capacity;
172 int num_contacts_left;
173 int bat_charging;
174 int ps_connected;
175 u8 bt_features;
176 u8 bt_high_speed;
177};
178
179#endif