diff options
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r-- | drivers/input/tablet/Kconfig | 11 | ||||
-rw-r--r-- | drivers/input/tablet/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/tablet/acecad.c | 3 | ||||
-rw-r--r-- | drivers/input/tablet/aiptek.c | 28 | ||||
-rw-r--r-- | drivers/input/tablet/hanwang.c | 446 | ||||
-rw-r--r-- | drivers/input/tablet/wacom.h | 2 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 87 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 741 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 19 |
9 files changed, 1060 insertions, 278 deletions
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index effb49ea24aa..58a87755b936 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -49,6 +49,17 @@ config TABLET_USB_GTCO | |||
49 | To compile this driver as a module, choose M here: the | 49 | To compile this driver as a module, choose M here: the |
50 | module will be called gtco. | 50 | module will be called gtco. |
51 | 51 | ||
52 | config TABLET_USB_HANWANG | ||
53 | tristate "Hanwang Art Master III tablet support (USB)" | ||
54 | depends on USB_ARCH_HAS_HCD | ||
55 | select USB | ||
56 | help | ||
57 | Say Y here if you want to use the USB version of the Hanwang Art | ||
58 | Master III tablet. | ||
59 | |||
60 | To compile this driver as a module, choose M here: the | ||
61 | module will be called hanwang. | ||
62 | |||
52 | config TABLET_USB_KBTAB | 63 | config TABLET_USB_KBTAB |
53 | tristate "KB Gear JamStudio tablet support (USB)" | 64 | tristate "KB Gear JamStudio tablet support (USB)" |
54 | depends on USB_ARCH_HAS_HCD | 65 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile index ce8b9a9cfa40..3f6c25220638 100644 --- a/drivers/input/tablet/Makefile +++ b/drivers/input/tablet/Makefile | |||
@@ -8,5 +8,6 @@ wacom-objs := wacom_wac.o wacom_sys.o | |||
8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o | 8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o |
9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o | 9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o |
10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o | 10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o |
11 | obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o | ||
11 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o | 12 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o |
12 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o | 13 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o |
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index aea9a9399a36..d94f7e9aa997 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c | |||
@@ -229,12 +229,13 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
229 | 229 | ||
230 | err = input_register_device(acecad->input); | 230 | err = input_register_device(acecad->input); |
231 | if (err) | 231 | if (err) |
232 | goto fail2; | 232 | goto fail3; |
233 | 233 | ||
234 | usb_set_intfdata(intf, acecad); | 234 | usb_set_intfdata(intf, acecad); |
235 | 235 | ||
236 | return 0; | 236 | return 0; |
237 | 237 | ||
238 | fail3: usb_free_urb(acecad->irq); | ||
238 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); | 239 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); |
239 | fail1: input_free_device(input_dev); | 240 | fail1: input_free_device(input_dev); |
240 | kfree(acecad); | 241 | kfree(acecad); |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 57b25b84d1fc..0a619c558bfb 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const | |||
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | static DEVICE_ATTR(pointer_mode, | 1099 | static DEVICE_ATTR(pointer_mode, |
1100 | S_IRUGO | S_IWUGO, | 1100 | S_IRUGO | S_IWUSR, |
1101 | show_tabletPointerMode, store_tabletPointerMode); | 1101 | show_tabletPointerMode, store_tabletPointerMode); |
1102 | 1102 | ||
1103 | /*********************************************************************** | 1103 | /*********************************************************************** |
@@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co | |||
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static DEVICE_ATTR(coordinate_mode, | 1136 | static DEVICE_ATTR(coordinate_mode, |
1137 | S_IRUGO | S_IWUGO, | 1137 | S_IRUGO | S_IWUSR, |
1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); | 1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); |
1139 | 1139 | ||
1140 | /*********************************************************************** | 1140 | /*********************************************************************** |
@@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch | |||
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | static DEVICE_ATTR(tool_mode, | 1178 | static DEVICE_ATTR(tool_mode, |
1179 | S_IRUGO | S_IWUGO, | 1179 | S_IRUGO | S_IWUSR, |
1180 | show_tabletToolMode, store_tabletToolMode); | 1180 | show_tabletToolMode, store_tabletToolMode); |
1181 | 1181 | ||
1182 | /*********************************************************************** | 1182 | /*********************************************************************** |
@@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char | |||
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | static DEVICE_ATTR(xtilt, | 1221 | static DEVICE_ATTR(xtilt, |
1222 | S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt); | 1222 | S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt); |
1223 | 1223 | ||
1224 | /*********************************************************************** | 1224 | /*********************************************************************** |
1225 | * support routines for the 'ytilt' file. Note that this file | 1225 | * support routines for the 'ytilt' file. Note that this file |
@@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char | |||
1261 | } | 1261 | } |
1262 | 1262 | ||
1263 | static DEVICE_ATTR(ytilt, | 1263 | static DEVICE_ATTR(ytilt, |
1264 | S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt); | 1264 | S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt); |
1265 | 1265 | ||
1266 | /*********************************************************************** | 1266 | /*********************************************************************** |
1267 | * support routines for the 'jitter' file. Note that this file | 1267 | * support routines for the 'jitter' file. Note that this file |
@@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const | |||
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | static DEVICE_ATTR(jitter, | 1290 | static DEVICE_ATTR(jitter, |
1291 | S_IRUGO | S_IWUGO, | 1291 | S_IRUGO | S_IWUSR, |
1292 | show_tabletJitterDelay, store_tabletJitterDelay); | 1292 | show_tabletJitterDelay, store_tabletJitterDelay); |
1293 | 1293 | ||
1294 | /*********************************************************************** | 1294 | /*********************************************************************** |
@@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, | |||
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | static DEVICE_ATTR(delay, | 1319 | static DEVICE_ATTR(delay, |
1320 | S_IRUGO | S_IWUGO, | 1320 | S_IRUGO | S_IWUSR, |
1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); | 1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); |
1322 | 1322 | ||
1323 | /*********************************************************************** | 1323 | /*********************************************************************** |
@@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const | |||
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | static DEVICE_ATTR(stylus_upper, | 1408 | static DEVICE_ATTR(stylus_upper, |
1409 | S_IRUGO | S_IWUGO, | 1409 | S_IRUGO | S_IWUSR, |
1410 | show_tabletStylusUpper, store_tabletStylusUpper); | 1410 | show_tabletStylusUpper, store_tabletStylusUpper); |
1411 | 1411 | ||
1412 | /*********************************************************************** | 1412 | /*********************************************************************** |
@@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | static DEVICE_ATTR(stylus_lower, | 1439 | static DEVICE_ATTR(stylus_lower, |
1440 | S_IRUGO | S_IWUGO, | 1440 | S_IRUGO | S_IWUSR, |
1441 | show_tabletStylusLower, store_tabletStylusLower); | 1441 | show_tabletStylusLower, store_tabletStylusLower); |
1442 | 1442 | ||
1443 | /*********************************************************************** | 1443 | /*********************************************************************** |
@@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c | |||
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | static DEVICE_ATTR(mouse_left, | 1477 | static DEVICE_ATTR(mouse_left, |
1478 | S_IRUGO | S_IWUGO, | 1478 | S_IRUGO | S_IWUSR, |
1479 | show_tabletMouseLeft, store_tabletMouseLeft); | 1479 | show_tabletMouseLeft, store_tabletMouseLeft); |
1480 | 1480 | ||
1481 | /*********************************************************************** | 1481 | /*********************************************************************** |
@@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const | |||
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | static DEVICE_ATTR(mouse_middle, | 1507 | static DEVICE_ATTR(mouse_middle, |
1508 | S_IRUGO | S_IWUGO, | 1508 | S_IRUGO | S_IWUSR, |
1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); | 1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); |
1510 | 1510 | ||
1511 | /*********************************************************************** | 1511 | /*********************************************************************** |
@@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const | |||
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | static DEVICE_ATTR(mouse_right, | 1537 | static DEVICE_ATTR(mouse_right, |
1538 | S_IRUGO | S_IWUGO, | 1538 | S_IRUGO | S_IWUSR, |
1539 | show_tabletMouseRight, store_tabletMouseRight); | 1539 | show_tabletMouseRight, store_tabletMouseRight); |
1540 | 1540 | ||
1541 | /*********************************************************************** | 1541 | /*********************************************************************** |
@@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char | |||
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | static DEVICE_ATTR(wheel, | 1569 | static DEVICE_ATTR(wheel, |
1570 | S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel); | 1570 | S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel); |
1571 | 1571 | ||
1572 | /*********************************************************************** | 1572 | /*********************************************************************** |
1573 | * support routines for the 'execute' file. Note that this file | 1573 | * support routines for the 'execute' file. Note that this file |
@@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha | |||
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | static DEVICE_ATTR(execute, | 1602 | static DEVICE_ATTR(execute, |
1603 | S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute); | 1603 | S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute); |
1604 | 1604 | ||
1605 | /*********************************************************************** | 1605 | /*********************************************************************** |
1606 | * support routines for the 'odm_code' file. Note that this file | 1606 | * support routines for the 'odm_code' file. Note that this file |
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c new file mode 100644 index 000000000000..6504b627b234 --- /dev/null +++ b/drivers/input/tablet/hanwang.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | * USB Hanwang tablet support | ||
3 | * | ||
4 | * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn> | ||
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 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/usb/input.h> | ||
31 | |||
32 | #define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>" | ||
33 | #define DRIVER_DESC "USB Hanwang tablet driver" | ||
34 | #define DRIVER_LICENSE "GPL" | ||
35 | |||
36 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
37 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
38 | MODULE_LICENSE(DRIVER_LICENSE); | ||
39 | |||
40 | #define USB_VENDOR_ID_HANWANG 0x0b57 | ||
41 | #define HANWANG_TABLET_INT_CLASS 0x0003 | ||
42 | #define HANWANG_TABLET_INT_SUB_CLASS 0x0001 | ||
43 | #define HANWANG_TABLET_INT_PROTOCOL 0x0002 | ||
44 | |||
45 | #define ART_MASTER_PKGLEN_MAX 10 | ||
46 | |||
47 | /* device IDs */ | ||
48 | #define STYLUS_DEVICE_ID 0x02 | ||
49 | #define TOUCH_DEVICE_ID 0x03 | ||
50 | #define CURSOR_DEVICE_ID 0x06 | ||
51 | #define ERASER_DEVICE_ID 0x0A | ||
52 | #define PAD_DEVICE_ID 0x0F | ||
53 | |||
54 | /* match vendor and interface info */ | ||
55 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ | ||
56 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ | ||
57 | | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
58 | .idVendor = (vend), \ | ||
59 | .bInterfaceClass = (cl), \ | ||
60 | .bInterfaceSubClass = (sc), \ | ||
61 | .bInterfaceProtocol = (pr) | ||
62 | |||
63 | enum hanwang_tablet_type { | ||
64 | HANWANG_ART_MASTER_III, | ||
65 | HANWANG_ART_MASTER_HD, | ||
66 | }; | ||
67 | |||
68 | struct hanwang { | ||
69 | unsigned char *data; | ||
70 | dma_addr_t data_dma; | ||
71 | struct input_dev *dev; | ||
72 | struct usb_device *usbdev; | ||
73 | struct urb *irq; | ||
74 | const struct hanwang_features *features; | ||
75 | unsigned int current_tool; | ||
76 | unsigned int current_id; | ||
77 | char name[64]; | ||
78 | char phys[32]; | ||
79 | }; | ||
80 | |||
81 | struct hanwang_features { | ||
82 | unsigned short pid; | ||
83 | char *name; | ||
84 | enum hanwang_tablet_type type; | ||
85 | int pkg_len; | ||
86 | int max_x; | ||
87 | int max_y; | ||
88 | int max_tilt_x; | ||
89 | int max_tilt_y; | ||
90 | int max_pressure; | ||
91 | }; | ||
92 | |||
93 | static const struct hanwang_features features_array[] = { | ||
94 | { 0x8528, "Hanwang Art Master III 0906", HANWANG_ART_MASTER_III, | ||
95 | ART_MASTER_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 }, | ||
96 | { 0x8529, "Hanwang Art Master III 0604", HANWANG_ART_MASTER_III, | ||
97 | ART_MASTER_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 }, | ||
98 | { 0x852a, "Hanwang Art Master III 1308", HANWANG_ART_MASTER_III, | ||
99 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, | ||
100 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, | ||
101 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, | ||
102 | }; | ||
103 | |||
104 | static const int hw_eventtypes[] = { | ||
105 | EV_KEY, EV_ABS, EV_MSC, | ||
106 | }; | ||
107 | |||
108 | static const int hw_absevents[] = { | ||
109 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, | ||
110 | ABS_RX, ABS_RY, ABS_PRESSURE, ABS_MISC, | ||
111 | }; | ||
112 | |||
113 | static const int hw_btnevents[] = { | ||
114 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, | ||
115 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, | ||
116 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, | ||
117 | }; | ||
118 | |||
119 | static const int hw_mscevents[] = { | ||
120 | MSC_SERIAL, | ||
121 | }; | ||
122 | |||
123 | static void hanwang_parse_packet(struct hanwang *hanwang) | ||
124 | { | ||
125 | unsigned char *data = hanwang->data; | ||
126 | struct input_dev *input_dev = hanwang->dev; | ||
127 | struct usb_device *dev = hanwang->usbdev; | ||
128 | enum hanwang_tablet_type type = hanwang->features->type; | ||
129 | int i; | ||
130 | u16 x, y, p; | ||
131 | |||
132 | switch (data[0]) { | ||
133 | case 0x02: /* data packet */ | ||
134 | switch (data[1]) { | ||
135 | case 0x80: /* tool prox out */ | ||
136 | hanwang->current_id = 0; | ||
137 | input_report_key(input_dev, hanwang->current_tool, 0); | ||
138 | break; | ||
139 | |||
140 | case 0xc2: /* first time tool prox in */ | ||
141 | switch (data[3] & 0xf0) { | ||
142 | case 0x20: /* art_master III */ | ||
143 | case 0x30: /* art_master_HD */ | ||
144 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
145 | hanwang->current_tool = BTN_TOOL_PEN; | ||
146 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | ||
147 | break; | ||
148 | case 0xa0: /* art_master III */ | ||
149 | case 0xb0: /* art_master_HD */ | ||
150 | hanwang->current_id = ERASER_DEVICE_ID; | ||
151 | hanwang->current_tool = BTN_TOOL_RUBBER; | ||
152 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); | ||
153 | break; | ||
154 | default: | ||
155 | hanwang->current_id = 0; | ||
156 | dev_dbg(&dev->dev, | ||
157 | "unknown tablet tool %02x ", data[0]); | ||
158 | break; | ||
159 | } | ||
160 | break; | ||
161 | |||
162 | default: /* tool data packet */ | ||
163 | x = (data[2] << 8) | data[3]; | ||
164 | y = (data[4] << 8) | data[5]; | ||
165 | |||
166 | switch (type) { | ||
167 | case HANWANG_ART_MASTER_III: | ||
168 | p = (data[6] << 3) | | ||
169 | ((data[7] & 0xc0) >> 5) | | ||
170 | (data[1] & 0x01); | ||
171 | break; | ||
172 | |||
173 | case HANWANG_ART_MASTER_HD: | ||
174 | p = (data[7] >> 6) | (data[6] << 2); | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | p = 0; | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | input_report_abs(input_dev, ABS_X, | ||
183 | le16_to_cpup((__le16 *)&x)); | ||
184 | input_report_abs(input_dev, ABS_Y, | ||
185 | le16_to_cpup((__le16 *)&y)); | ||
186 | input_report_abs(input_dev, ABS_PRESSURE, | ||
187 | le16_to_cpup((__le16 *)&p)); | ||
188 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); | ||
189 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); | ||
190 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); | ||
191 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | ||
192 | break; | ||
193 | } | ||
194 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
195 | input_event(input_dev, EV_MSC, MSC_SERIAL, | ||
196 | hanwang->features->pid); | ||
197 | break; | ||
198 | |||
199 | case 0x0c: | ||
200 | /* roll wheel */ | ||
201 | hanwang->current_id = PAD_DEVICE_ID; | ||
202 | |||
203 | switch (type) { | ||
204 | case HANWANG_ART_MASTER_III: | ||
205 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
206 | data[2] || data[3]); | ||
207 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | ||
208 | input_report_key(input_dev, BTN_0, data[2]); | ||
209 | for (i = 0; i < 8; i++) | ||
210 | input_report_key(input_dev, | ||
211 | BTN_1 + i, data[3] & (1 << i)); | ||
212 | break; | ||
213 | |||
214 | case HANWANG_ART_MASTER_HD: | ||
215 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
216 | data[2] || data[3] || data[4] || | ||
217 | data[5] || data[6]); | ||
218 | input_report_abs(input_dev, ABS_RX, | ||
219 | ((data[1] & 0x1f) << 8) | data[2]); | ||
220 | input_report_abs(input_dev, ABS_RY, | ||
221 | ((data[3] & 0x1f) << 8) | data[4]); | ||
222 | input_report_key(input_dev, BTN_0, data[5] & 0x01); | ||
223 | for (i = 0; i < 4; i++) { | ||
224 | input_report_key(input_dev, | ||
225 | BTN_1 + i, data[5] & (1 << i)); | ||
226 | input_report_key(input_dev, | ||
227 | BTN_5 + i, data[6] & (1 << i)); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
233 | input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | dev_dbg(&dev->dev, "error packet %02x ", data[0]); | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | input_sync(input_dev); | ||
242 | } | ||
243 | |||
244 | static void hanwang_irq(struct urb *urb) | ||
245 | { | ||
246 | struct hanwang *hanwang = urb->context; | ||
247 | struct usb_device *dev = hanwang->usbdev; | ||
248 | int retval; | ||
249 | |||
250 | switch (urb->status) { | ||
251 | case 0: | ||
252 | /* success */; | ||
253 | hanwang_parse_packet(hanwang); | ||
254 | break; | ||
255 | case -ECONNRESET: | ||
256 | case -ENOENT: | ||
257 | case -ESHUTDOWN: | ||
258 | /* this urb is terminated, clean up */ | ||
259 | dev_err(&dev->dev, "%s - urb shutting down with status: %d", | ||
260 | __func__, urb->status); | ||
261 | return; | ||
262 | default: | ||
263 | dev_err(&dev->dev, "%s - nonzero urb status received: %d", | ||
264 | __func__, urb->status); | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
269 | if (retval) | ||
270 | dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d", | ||
271 | __func__, retval); | ||
272 | } | ||
273 | |||
274 | static int hanwang_open(struct input_dev *dev) | ||
275 | { | ||
276 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
277 | |||
278 | hanwang->irq->dev = hanwang->usbdev; | ||
279 | if (usb_submit_urb(hanwang->irq, GFP_KERNEL)) | ||
280 | return -EIO; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void hanwang_close(struct input_dev *dev) | ||
286 | { | ||
287 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
288 | |||
289 | usb_kill_urb(hanwang->irq); | ||
290 | } | ||
291 | |||
292 | static bool get_features(struct usb_device *dev, struct hanwang *hanwang) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(features_array); i++) { | ||
297 | if (le16_to_cpu(dev->descriptor.idProduct) == | ||
298 | features_array[i].pid) { | ||
299 | hanwang->features = &features_array[i]; | ||
300 | return true; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return false; | ||
305 | } | ||
306 | |||
307 | |||
308 | static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
309 | { | ||
310 | struct usb_device *dev = interface_to_usbdev(intf); | ||
311 | struct usb_endpoint_descriptor *endpoint; | ||
312 | struct hanwang *hanwang; | ||
313 | struct input_dev *input_dev; | ||
314 | int error; | ||
315 | int i; | ||
316 | |||
317 | hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); | ||
318 | input_dev = input_allocate_device(); | ||
319 | if (!hanwang || !input_dev) { | ||
320 | error = -ENOMEM; | ||
321 | goto fail1; | ||
322 | } | ||
323 | |||
324 | if (!get_features(dev, hanwang)) { | ||
325 | error = -ENXIO; | ||
326 | goto fail1; | ||
327 | } | ||
328 | |||
329 | hanwang->data = usb_alloc_coherent(dev, hanwang->features->pkg_len, | ||
330 | GFP_KERNEL, &hanwang->data_dma); | ||
331 | if (!hanwang->data) { | ||
332 | error = -ENOMEM; | ||
333 | goto fail1; | ||
334 | } | ||
335 | |||
336 | hanwang->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
337 | if (!hanwang->irq) { | ||
338 | error = -ENOMEM; | ||
339 | goto fail2; | ||
340 | } | ||
341 | |||
342 | hanwang->usbdev = dev; | ||
343 | hanwang->dev = input_dev; | ||
344 | |||
345 | usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys)); | ||
346 | strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys)); | ||
347 | |||
348 | strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); | ||
349 | input_dev->name = hanwang->name; | ||
350 | input_dev->phys = hanwang->phys; | ||
351 | usb_to_input_id(dev, &input_dev->id); | ||
352 | input_dev->dev.parent = &intf->dev; | ||
353 | |||
354 | input_set_drvdata(input_dev, hanwang); | ||
355 | |||
356 | input_dev->open = hanwang_open; | ||
357 | input_dev->close = hanwang_close; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i) | ||
360 | __set_bit(hw_eventtypes[i], input_dev->evbit); | ||
361 | |||
362 | for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i) | ||
363 | __set_bit(hw_absevents[i], input_dev->absbit); | ||
364 | |||
365 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) | ||
366 | __set_bit(hw_btnevents[i], input_dev->keybit); | ||
367 | |||
368 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) | ||
369 | __set_bit(hw_mscevents[i], input_dev->mscbit); | ||
370 | |||
371 | input_set_abs_params(input_dev, ABS_X, | ||
372 | 0, hanwang->features->max_x, 4, 0); | ||
373 | input_set_abs_params(input_dev, ABS_Y, | ||
374 | 0, hanwang->features->max_y, 4, 0); | ||
375 | input_set_abs_params(input_dev, ABS_TILT_X, | ||
376 | 0, hanwang->features->max_tilt_x, 0, 0); | ||
377 | input_set_abs_params(input_dev, ABS_TILT_Y, | ||
378 | 0, hanwang->features->max_tilt_y, 0, 0); | ||
379 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
380 | 0, hanwang->features->max_pressure, 0, 0); | ||
381 | |||
382 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
383 | usb_fill_int_urb(hanwang->irq, dev, | ||
384 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
385 | hanwang->data, hanwang->features->pkg_len, | ||
386 | hanwang_irq, hanwang, endpoint->bInterval); | ||
387 | hanwang->irq->transfer_dma = hanwang->data_dma; | ||
388 | hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
389 | |||
390 | error = input_register_device(hanwang->dev); | ||
391 | if (error) | ||
392 | goto fail3; | ||
393 | |||
394 | usb_set_intfdata(intf, hanwang); | ||
395 | |||
396 | return 0; | ||
397 | |||
398 | fail3: usb_free_urb(hanwang->irq); | ||
399 | fail2: usb_free_coherent(dev, hanwang->features->pkg_len, | ||
400 | hanwang->data, hanwang->data_dma); | ||
401 | fail1: input_free_device(input_dev); | ||
402 | kfree(hanwang); | ||
403 | return error; | ||
404 | |||
405 | } | ||
406 | |||
407 | static void hanwang_disconnect(struct usb_interface *intf) | ||
408 | { | ||
409 | struct hanwang *hanwang = usb_get_intfdata(intf); | ||
410 | |||
411 | input_unregister_device(hanwang->dev); | ||
412 | usb_free_urb(hanwang->irq); | ||
413 | usb_free_coherent(interface_to_usbdev(intf), | ||
414 | hanwang->features->pkg_len, hanwang->data, | ||
415 | hanwang->data_dma); | ||
416 | kfree(hanwang); | ||
417 | usb_set_intfdata(intf, NULL); | ||
418 | } | ||
419 | |||
420 | static const struct usb_device_id hanwang_ids[] = { | ||
421 | { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS, | ||
422 | HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) }, | ||
423 | {} | ||
424 | }; | ||
425 | |||
426 | MODULE_DEVICE_TABLE(usb, hanwang_ids); | ||
427 | |||
428 | static struct usb_driver hanwang_driver = { | ||
429 | .name = "hanwang", | ||
430 | .probe = hanwang_probe, | ||
431 | .disconnect = hanwang_disconnect, | ||
432 | .id_table = hanwang_ids, | ||
433 | }; | ||
434 | |||
435 | static int __init hanwang_init(void) | ||
436 | { | ||
437 | return usb_register(&hanwang_driver); | ||
438 | } | ||
439 | |||
440 | static void __exit hanwang_exit(void) | ||
441 | { | ||
442 | usb_deregister(&hanwang_driver); | ||
443 | } | ||
444 | |||
445 | module_init(hanwang_init); | ||
446 | module_exit(hanwang_exit); | ||
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 284dfaab6b8c..23317bd09c82 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -103,6 +103,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
103 | MODULE_LICENSE(DRIVER_LICENSE); | 103 | MODULE_LICENSE(DRIVER_LICENSE); |
104 | 104 | ||
105 | #define USB_VENDOR_ID_WACOM 0x056a | 105 | #define USB_VENDOR_ID_WACOM 0x056a |
106 | #define USB_VENDOR_ID_LENOVO 0x17ef | ||
106 | 107 | ||
107 | struct wacom { | 108 | struct wacom { |
108 | dma_addr_t data_dma; | 109 | dma_addr_t data_dma; |
@@ -118,6 +119,7 @@ struct wacom { | |||
118 | extern const struct usb_device_id wacom_ids[]; | 119 | extern const struct usb_device_id wacom_ids[]; |
119 | 120 | ||
120 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 121 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
122 | void wacom_setup_device_quirks(struct wacom_features *features); | ||
121 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 123 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
122 | struct wacom_wac *wacom_wac); | 124 | struct wacom_wac *wacom_wac); |
123 | #endif | 125 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b35876ee6908..449c0a46dbac 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -120,14 +120,16 @@ static int wacom_open(struct input_dev *dev) | |||
120 | 120 | ||
121 | out: | 121 | out: |
122 | mutex_unlock(&wacom->lock); | 122 | mutex_unlock(&wacom->lock); |
123 | if (retval) | 123 | usb_autopm_put_interface(wacom->intf); |
124 | usb_autopm_put_interface(wacom->intf); | ||
125 | return retval; | 124 | return retval; |
126 | } | 125 | } |
127 | 126 | ||
128 | static void wacom_close(struct input_dev *dev) | 127 | static void wacom_close(struct input_dev *dev) |
129 | { | 128 | { |
130 | struct wacom *wacom = input_get_drvdata(dev); | 129 | struct wacom *wacom = input_get_drvdata(dev); |
130 | int autopm_error; | ||
131 | |||
132 | autopm_error = usb_autopm_get_interface(wacom->intf); | ||
131 | 133 | ||
132 | mutex_lock(&wacom->lock); | 134 | mutex_lock(&wacom->lock); |
133 | usb_kill_urb(wacom->irq); | 135 | usb_kill_urb(wacom->irq); |
@@ -135,7 +137,8 @@ static void wacom_close(struct input_dev *dev) | |||
135 | wacom->intf->needs_remote_wakeup = 0; | 137 | wacom->intf->needs_remote_wakeup = 0; |
136 | mutex_unlock(&wacom->lock); | 138 | mutex_unlock(&wacom->lock); |
137 | 139 | ||
138 | usb_autopm_put_interface(wacom->intf); | 140 | if (!autopm_error) |
141 | usb_autopm_put_interface(wacom->intf); | ||
139 | } | 142 | } |
140 | 143 | ||
141 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 144 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
@@ -190,23 +193,36 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
190 | case HID_USAGE_X: | 193 | case HID_USAGE_X: |
191 | if (usage == WCM_DESKTOP) { | 194 | if (usage == WCM_DESKTOP) { |
192 | if (finger) { | 195 | if (finger) { |
193 | features->device_type = BTN_TOOL_DOUBLETAP; | 196 | features->device_type = BTN_TOOL_FINGER; |
194 | if (features->type == TABLETPC2FG) { | 197 | if (features->type == TABLETPC2FG) { |
195 | /* need to reset back */ | 198 | /* need to reset back */ |
196 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 199 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
197 | features->device_type = BTN_TOOL_TRIPLETAP; | 200 | features->device_type = BTN_TOOL_DOUBLETAP; |
201 | } | ||
202 | if (features->type == BAMBOO_PT) { | ||
203 | /* need to reset back */ | ||
204 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
205 | features->device_type = BTN_TOOL_DOUBLETAP; | ||
206 | features->x_phy = | ||
207 | get_unaligned_le16(&report[i + 5]); | ||
208 | features->x_max = | ||
209 | get_unaligned_le16(&report[i + 8]); | ||
210 | i += 15; | ||
211 | } else { | ||
212 | features->x_max = | ||
213 | get_unaligned_le16(&report[i + 3]); | ||
214 | features->x_phy = | ||
215 | get_unaligned_le16(&report[i + 6]); | ||
216 | features->unit = report[i + 9]; | ||
217 | features->unitExpo = report[i + 11]; | ||
218 | i += 12; | ||
198 | } | 219 | } |
199 | features->x_max = | ||
200 | get_unaligned_le16(&report[i + 3]); | ||
201 | features->x_phy = | ||
202 | get_unaligned_le16(&report[i + 6]); | ||
203 | features->unit = report[i + 9]; | ||
204 | features->unitExpo = report[i + 11]; | ||
205 | i += 12; | ||
206 | } else if (pen) { | 220 | } else if (pen) { |
207 | /* penabled only accepts exact bytes of data */ | 221 | /* penabled only accepts exact bytes of data */ |
208 | if (features->type == TABLETPC2FG) | 222 | if (features->type == TABLETPC2FG) |
209 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 223 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
224 | if (features->type == BAMBOO_PT) | ||
225 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
210 | features->device_type = BTN_TOOL_PEN; | 226 | features->device_type = BTN_TOOL_PEN; |
211 | features->x_max = | 227 | features->x_max = |
212 | get_unaligned_le16(&report[i + 3]); | 228 | get_unaligned_le16(&report[i + 3]); |
@@ -225,16 +241,25 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
225 | case HID_USAGE_Y: | 241 | case HID_USAGE_Y: |
226 | if (usage == WCM_DESKTOP) { | 242 | if (usage == WCM_DESKTOP) { |
227 | if (finger) { | 243 | if (finger) { |
228 | features->device_type = BTN_TOOL_DOUBLETAP; | 244 | features->device_type = BTN_TOOL_FINGER; |
229 | if (features->type == TABLETPC2FG) { | 245 | if (features->type == TABLETPC2FG) { |
230 | /* need to reset back */ | 246 | /* need to reset back */ |
231 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 247 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
232 | features->device_type = BTN_TOOL_TRIPLETAP; | 248 | features->device_type = BTN_TOOL_DOUBLETAP; |
233 | features->y_max = | 249 | features->y_max = |
234 | get_unaligned_le16(&report[i + 3]); | 250 | get_unaligned_le16(&report[i + 3]); |
235 | features->y_phy = | 251 | features->y_phy = |
236 | get_unaligned_le16(&report[i + 6]); | 252 | get_unaligned_le16(&report[i + 6]); |
237 | i += 7; | 253 | i += 7; |
254 | } else if (features->type == BAMBOO_PT) { | ||
255 | /* need to reset back */ | ||
256 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
257 | features->device_type = BTN_TOOL_DOUBLETAP; | ||
258 | features->y_phy = | ||
259 | get_unaligned_le16(&report[i + 3]); | ||
260 | features->y_max = | ||
261 | get_unaligned_le16(&report[i + 6]); | ||
262 | i += 12; | ||
238 | } else { | 263 | } else { |
239 | features->y_max = | 264 | features->y_max = |
240 | features->x_max; | 265 | features->x_max; |
@@ -246,6 +271,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
246 | /* penabled only accepts exact bytes of data */ | 271 | /* penabled only accepts exact bytes of data */ |
247 | if (features->type == TABLETPC2FG) | 272 | if (features->type == TABLETPC2FG) |
248 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 273 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
274 | if (features->type == BAMBOO_PT) | ||
275 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
249 | features->device_type = BTN_TOOL_PEN; | 276 | features->device_type = BTN_TOOL_PEN; |
250 | features->y_max = | 277 | features->y_max = |
251 | get_unaligned_le16(&report[i + 3]); | 278 | get_unaligned_le16(&report[i + 3]); |
@@ -296,8 +323,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
296 | if (!rep_data) | 323 | if (!rep_data) |
297 | return error; | 324 | return error; |
298 | 325 | ||
299 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ | 326 | /* ask to report tablet data if it is 2FGT Tablet PC or |
300 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 327 | * not a Tablet PC */ |
328 | if (features->type == TABLETPC2FG) { | ||
301 | do { | 329 | do { |
302 | rep_data[0] = 3; | 330 | rep_data[0] = 3; |
303 | rep_data[1] = 4; | 331 | rep_data[1] = 4; |
@@ -309,7 +337,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
309 | WAC_HID_FEATURE_REPORT, report_id, | 337 | WAC_HID_FEATURE_REPORT, report_id, |
310 | rep_data, 3); | 338 | rep_data, 3); |
311 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | 339 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); |
312 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | 340 | } else if (features->type != TABLETPC) { |
313 | do { | 341 | do { |
314 | rep_data[0] = 2; | 342 | rep_data[0] = 2; |
315 | rep_data[1] = 2; | 343 | rep_data[1] = 2; |
@@ -334,11 +362,16 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
334 | struct usb_host_interface *interface = intf->cur_altsetting; | 362 | struct usb_host_interface *interface = intf->cur_altsetting; |
335 | struct hid_descriptor *hid_desc; | 363 | struct hid_descriptor *hid_desc; |
336 | 364 | ||
337 | /* default device to penabled */ | 365 | /* default features */ |
338 | features->device_type = BTN_TOOL_PEN; | 366 | features->device_type = BTN_TOOL_PEN; |
339 | 367 | features->x_fuzz = 4; | |
340 | /* only Tablet PCs need to retrieve the info */ | 368 | features->y_fuzz = 4; |
341 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | 369 | features->pressure_fuzz = 0; |
370 | features->distance_fuzz = 0; | ||
371 | |||
372 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | ||
373 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | ||
374 | (features->type != BAMBOO_PT)) | ||
342 | goto out; | 375 | goto out; |
343 | 376 | ||
344 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 377 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { |
@@ -353,12 +386,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
353 | if (error) | 386 | if (error) |
354 | goto out; | 387 | goto out; |
355 | 388 | ||
356 | /* touch device found but size is not defined. use default */ | ||
357 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
358 | features->x_max = 1023; | ||
359 | features->y_max = 1023; | ||
360 | } | ||
361 | |||
362 | out: | 389 | out: |
363 | return error; | 390 | return error; |
364 | } | 391 | } |
@@ -492,11 +519,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
492 | /* Retrieve the physical and logical size for OEM devices */ | 519 | /* Retrieve the physical and logical size for OEM devices */ |
493 | error = wacom_retrieve_hid_descriptor(intf, features); | 520 | error = wacom_retrieve_hid_descriptor(intf, features); |
494 | if (error) | 521 | if (error) |
495 | goto fail2; | 522 | goto fail3; |
523 | |||
524 | wacom_setup_device_quirks(features); | ||
496 | 525 | ||
497 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 526 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
498 | 527 | ||
499 | if (features->type == TABLETPC || features->type == TABLETPC2FG) { | 528 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
500 | /* Append the device type to the name */ | 529 | /* Append the device type to the name */ |
501 | strlcat(wacom_wac->name, | 530 | strlcat(wacom_wac->name, |
502 | features->device_type == BTN_TOOL_PEN ? | 531 | features->device_type == BTN_TOOL_PEN ? |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 47fd7a041c52..08ba5ad9c9be 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -14,6 +14,15 @@ | |||
14 | 14 | ||
15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
16 | #include "wacom.h" | 16 | #include "wacom.h" |
17 | #include <linux/input/mt.h> | ||
18 | |||
19 | /* resolution for penabled devices */ | ||
20 | #define WACOM_PL_RES 20 | ||
21 | #define WACOM_PENPRTN_RES 40 | ||
22 | #define WACOM_VOLITO_RES 50 | ||
23 | #define WACOM_GRAPHIRE_RES 80 | ||
24 | #define WACOM_INTUOS_RES 100 | ||
25 | #define WACOM_INTUOS3_RES 200 | ||
17 | 26 | ||
18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 27 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
19 | { | 28 | { |
@@ -674,187 +683,234 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
674 | return 1; | 683 | return 1; |
675 | } | 684 | } |
676 | 685 | ||
677 | 686 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |
678 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) | ||
679 | { | 687 | { |
680 | struct input_dev *input = wacom->input; | 688 | struct input_dev *input = wacom->input; |
681 | int finger = idx + 1; | 689 | unsigned char *data = wacom->data; |
682 | int x = le16_to_cpup((__le16 *)&data[finger * 2]) & 0x7fff; | 690 | int contact_with_no_pen_down_count = 0; |
683 | int y = le16_to_cpup((__le16 *)&data[4 + finger * 2]) & 0x7fff; | 691 | int i; |
684 | 692 | ||
685 | /* | 693 | for (i = 0; i < 2; i++) { |
686 | * Work around input core suppressing "duplicate" events since | 694 | int p = data[1] & (1 << i); |
687 | * we are abusing ABS_X/ABS_Y to transmit multi-finger data. | 695 | bool touch = p && !wacom->shared->stylus_in_proximity; |
688 | * This should go away once we switch to true multitouch | ||
689 | * protocol. | ||
690 | */ | ||
691 | if (wacom->last_finger != finger) { | ||
692 | if (x == input_abs_get_val(input, ABS_X)) | ||
693 | x++; | ||
694 | 696 | ||
695 | if (y == input_abs_get_val(input, ABS_Y)) | 697 | input_mt_slot(input, i); |
696 | y++; | 698 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
699 | if (touch) { | ||
700 | int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff; | ||
701 | int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff; | ||
702 | |||
703 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
704 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
705 | contact_with_no_pen_down_count++; | ||
706 | } | ||
697 | } | 707 | } |
698 | 708 | ||
699 | input_report_abs(input, ABS_X, x); | 709 | /* keep touch state for pen event */ |
700 | input_report_abs(input, ABS_Y, y); | 710 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
701 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
702 | input_report_key(input, wacom->tool[finger], 1); | ||
703 | if (!idx) | ||
704 | input_report_key(input, BTN_TOUCH, 1); | ||
705 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
706 | input_sync(input); | ||
707 | 711 | ||
708 | wacom->last_finger = finger; | 712 | input_mt_report_pointer_emulation(input, true); |
709 | } | ||
710 | 713 | ||
711 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, int idx) | 714 | return 1; |
712 | { | ||
713 | struct input_dev *input = wacom->input; | ||
714 | int finger = idx + 1; | ||
715 | |||
716 | input_report_abs(input, ABS_X, 0); | ||
717 | input_report_abs(input, ABS_Y, 0); | ||
718 | input_report_abs(input, ABS_MISC, 0); | ||
719 | input_report_key(input, wacom->tool[finger], 0); | ||
720 | if (!idx) | ||
721 | input_report_key(input, BTN_TOUCH, 0); | ||
722 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
723 | input_sync(input); | ||
724 | } | 715 | } |
725 | 716 | ||
726 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, size_t len) | 717 | static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) |
727 | { | 718 | { |
728 | char *data = wacom->data; | 719 | char *data = wacom->data; |
729 | struct input_dev *input = wacom->input; | 720 | struct input_dev *input = wacom->input; |
721 | bool prox; | ||
722 | int x = 0, y = 0; | ||
730 | 723 | ||
731 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 724 | if (!wacom->shared->stylus_in_proximity) { |
732 | wacom->id[0] = TOUCH_DEVICE_ID; | 725 | if (len == WACOM_PKGLEN_TPC1FG) { |
733 | wacom->tool[2] = BTN_TOOL_TRIPLETAP; | 726 | prox = data[0] & 0x01; |
727 | x = get_unaligned_le16(&data[1]); | ||
728 | y = get_unaligned_le16(&data[3]); | ||
729 | } else { /* with capacity */ | ||
730 | prox = data[1] & 0x01; | ||
731 | x = le16_to_cpup((__le16 *)&data[2]); | ||
732 | y = le16_to_cpup((__le16 *)&data[4]); | ||
733 | } | ||
734 | } else | ||
735 | /* force touch out when pen is in prox */ | ||
736 | prox = 0; | ||
734 | 737 | ||
735 | if (len != WACOM_PKGLEN_TPC1FG) { | 738 | if (prox) { |
739 | input_report_abs(input, ABS_X, x); | ||
740 | input_report_abs(input, ABS_Y, y); | ||
741 | } | ||
742 | input_report_key(input, BTN_TOUCH, prox); | ||
736 | 743 | ||
737 | switch (data[0]) { | 744 | /* keep touch state for pen events */ |
745 | wacom->shared->touch_down = prox; | ||
738 | 746 | ||
739 | case WACOM_REPORT_TPC1FG: | 747 | return 1; |
740 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 748 | } |
741 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | ||
742 | input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); | ||
743 | input_report_key(input, BTN_TOUCH, le16_to_cpup((__le16 *)&data[6])); | ||
744 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
745 | input_report_key(input, wacom->tool[1], 1); | ||
746 | input_sync(input); | ||
747 | break; | ||
748 | 749 | ||
749 | case WACOM_REPORT_TPC2FG: | 750 | static int wacom_tpc_pen(struct wacom_wac *wacom) |
750 | if (data[1] & 0x01) | 751 | { |
751 | wacom_tpc_finger_in(wacom, data, 0); | 752 | struct wacom_features *features = &wacom->features; |
752 | else if (wacom->id[1] & 0x01) | 753 | char *data = wacom->data; |
753 | wacom_tpc_touch_out(wacom, 0); | 754 | struct input_dev *input = wacom->input; |
755 | int pressure; | ||
756 | bool prox = data[1] & 0x20; | ||
754 | 757 | ||
755 | if (data[1] & 0x02) | 758 | if (!wacom->shared->stylus_in_proximity) /* first in prox */ |
756 | wacom_tpc_finger_in(wacom, data, 1); | 759 | /* Going into proximity select tool */ |
757 | else if (wacom->id[1] & 0x02) | 760 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
758 | wacom_tpc_touch_out(wacom, 1); | 761 | |
759 | break; | 762 | /* keep pen state for touch events */ |
760 | } | 763 | wacom->shared->stylus_in_proximity = prox; |
761 | } else { | 764 | |
762 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); | 765 | /* send pen events only when touch is up or forced out */ |
763 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); | 766 | if (!wacom->shared->touch_down) { |
764 | input_report_key(input, BTN_TOUCH, 1); | 767 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
765 | input_report_abs(input, ABS_MISC, wacom->id[1]); | 768 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
766 | input_report_key(input, wacom->tool[1], 1); | 769 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
767 | input_sync(input); | 770 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
771 | pressure = ((data[7] & 0x01) << 8) | data[6]; | ||
772 | if (pressure < 0) | ||
773 | pressure = features->pressure_max + pressure + 1; | ||
774 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
775 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
776 | input_report_key(input, wacom->tool[0], prox); | ||
777 | return 1; | ||
768 | } | 778 | } |
779 | |||
780 | return 0; | ||
769 | } | 781 | } |
770 | 782 | ||
771 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | 783 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) |
772 | { | 784 | { |
773 | struct wacom_features *features = &wacom->features; | ||
774 | char *data = wacom->data; | 785 | char *data = wacom->data; |
775 | struct input_dev *input = wacom->input; | ||
776 | int prox = 0, pressure; | ||
777 | int retval = 0; | ||
778 | 786 | ||
779 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 787 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
780 | 788 | ||
781 | if (len == WACOM_PKGLEN_TPC1FG || /* single touch */ | 789 | if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG) |
782 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ | 790 | return wacom_tpc_single_touch(wacom, len); |
783 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ | 791 | else if (data[0] == WACOM_REPORT_TPC2FG) |
792 | return wacom_tpc_mt_touch(wacom); | ||
793 | else if (data[0] == WACOM_REPORT_PENABLED) | ||
794 | return wacom_tpc_pen(wacom); | ||
784 | 795 | ||
785 | if (wacom->shared->stylus_in_proximity) { | 796 | return 0; |
786 | if (wacom->id[1] & 0x01) | 797 | } |
787 | wacom_tpc_touch_out(wacom, 0); | ||
788 | 798 | ||
789 | if (wacom->id[1] & 0x02) | 799 | static int wacom_bpt_touch(struct wacom_wac *wacom) |
790 | wacom_tpc_touch_out(wacom, 1); | 800 | { |
801 | struct wacom_features *features = &wacom->features; | ||
802 | struct input_dev *input = wacom->input; | ||
803 | unsigned char *data = wacom->data; | ||
804 | int i; | ||
791 | 805 | ||
792 | wacom->id[1] = 0; | 806 | for (i = 0; i < 2; i++) { |
793 | return 0; | 807 | int p = data[9 * i + 2]; |
794 | } | 808 | bool touch = p && !wacom->shared->stylus_in_proximity; |
795 | 809 | ||
796 | if (len == WACOM_PKGLEN_TPC1FG) { /* with touch */ | 810 | input_mt_slot(input, i); |
797 | prox = data[0] & 0x01; | 811 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
798 | } else { /* with capacity */ | 812 | /* |
799 | if (data[0] == WACOM_REPORT_TPC1FG) | 813 | * Touch events need to be disabled while stylus is |
800 | /* single touch */ | 814 | * in proximity because user's hand is resting on touchpad |
801 | prox = data[1] & 0x01; | 815 | * and sending unwanted events. User expects tablet buttons |
802 | else | 816 | * to continue working though. |
803 | /* 2FG touch data */ | 817 | */ |
804 | prox = data[1] & 0x03; | 818 | if (touch) { |
819 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | ||
820 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | ||
821 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | ||
822 | x <<= 5; | ||
823 | y <<= 5; | ||
824 | } | ||
825 | input_report_abs(input, ABS_MT_PRESSURE, p); | ||
826 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
827 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
805 | } | 828 | } |
829 | } | ||
806 | 830 | ||
807 | if (prox) { | 831 | input_mt_report_pointer_emulation(input, true); |
808 | if (!wacom->id[1]) | ||
809 | wacom->last_finger = 1; | ||
810 | wacom_tpc_touch_in(wacom, len); | ||
811 | } else { | ||
812 | if (data[0] == WACOM_REPORT_TPC2FG) { | ||
813 | /* 2FGT out-prox */ | ||
814 | if (wacom->id[1] & 0x01) | ||
815 | wacom_tpc_touch_out(wacom, 0); | ||
816 | 832 | ||
817 | if (wacom->id[1] & 0x02) | 833 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); |
818 | wacom_tpc_touch_out(wacom, 1); | 834 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); |
819 | } else | 835 | input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); |
820 | /* one finger touch */ | 836 | input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); |
821 | wacom_tpc_touch_out(wacom, 0); | ||
822 | 837 | ||
823 | wacom->id[0] = 0; | 838 | input_sync(input); |
824 | } | 839 | |
825 | /* keep prox bit to send proper out-prox event */ | 840 | return 0; |
826 | wacom->id[1] = prox; | 841 | } |
827 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ | 842 | |
828 | prox = data[1] & 0x20; | 843 | static int wacom_bpt_pen(struct wacom_wac *wacom) |
829 | 844 | { | |
830 | if (!wacom->shared->stylus_in_proximity) { /* first in prox */ | 845 | struct input_dev *input = wacom->input; |
831 | /* Going into proximity select tool */ | 846 | unsigned char *data = wacom->data; |
832 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 847 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; |
833 | if (wacom->tool[0] == BTN_TOOL_PEN) | ||
834 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
835 | else | ||
836 | wacom->id[0] = ERASER_DEVICE_ID; | ||
837 | 848 | ||
849 | /* | ||
850 | * Similar to Graphire protocol, data[1] & 0x20 is proximity and | ||
851 | * data[1] & 0x18 is tool ID. 0x30 is safety check to ignore | ||
852 | * 2 unused tool ID's. | ||
853 | */ | ||
854 | prox = (data[1] & 0x30) == 0x30; | ||
855 | |||
856 | /* | ||
857 | * All reports shared between PEN and RUBBER tool must be | ||
858 | * forced to a known starting value (zero) when transitioning to | ||
859 | * out-of-prox. | ||
860 | * | ||
861 | * If not reset then, to userspace, it will look like lost events | ||
862 | * if new tool comes in-prox with same values as previous tool sent. | ||
863 | * | ||
864 | * Hardware does report zero in most out-of-prox cases but not all. | ||
865 | */ | ||
866 | if (prox) { | ||
867 | if (!wacom->shared->stylus_in_proximity) { | ||
868 | if (data[1] & 0x08) { | ||
869 | wacom->tool[0] = BTN_TOOL_RUBBER; | ||
870 | wacom->id[0] = ERASER_DEVICE_ID; | ||
871 | } else { | ||
872 | wacom->tool[0] = BTN_TOOL_PEN; | ||
873 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
874 | } | ||
838 | wacom->shared->stylus_in_proximity = true; | 875 | wacom->shared->stylus_in_proximity = true; |
839 | } | 876 | } |
840 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | 877 | x = le16_to_cpup((__le16 *)&data[2]); |
841 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); | 878 | y = le16_to_cpup((__le16 *)&data[4]); |
842 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 879 | p = le16_to_cpup((__le16 *)&data[6]); |
843 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | 880 | d = data[8]; |
844 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 881 | pen = data[1] & 0x01; |
845 | if (pressure < 0) | 882 | btn1 = data[1] & 0x02; |
846 | pressure = features->pressure_max + pressure + 1; | 883 | btn2 = data[1] & 0x04; |
847 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
848 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
849 | if (!prox) { /* out-prox */ | ||
850 | wacom->id[0] = 0; | ||
851 | wacom->shared->stylus_in_proximity = false; | ||
852 | } | ||
853 | input_report_key(input, wacom->tool[0], prox); | ||
854 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
855 | retval = 1; | ||
856 | } | 884 | } |
857 | return retval; | 885 | |
886 | input_report_key(input, BTN_TOUCH, pen); | ||
887 | input_report_key(input, BTN_STYLUS, btn1); | ||
888 | input_report_key(input, BTN_STYLUS2, btn2); | ||
889 | |||
890 | input_report_abs(input, ABS_X, x); | ||
891 | input_report_abs(input, ABS_Y, y); | ||
892 | input_report_abs(input, ABS_PRESSURE, p); | ||
893 | input_report_abs(input, ABS_DISTANCE, d); | ||
894 | |||
895 | if (!prox) { | ||
896 | wacom->id[0] = 0; | ||
897 | wacom->shared->stylus_in_proximity = false; | ||
898 | } | ||
899 | |||
900 | input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ | ||
901 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ | ||
902 | |||
903 | return 1; | ||
904 | } | ||
905 | |||
906 | static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | ||
907 | { | ||
908 | if (len == WACOM_PKGLEN_BBTOUCH) | ||
909 | return wacom_bpt_touch(wacom); | ||
910 | else if (len == WACOM_PKGLEN_BBFUN) | ||
911 | return wacom_bpt_pen(wacom); | ||
912 | |||
913 | return 0; | ||
858 | } | 914 | } |
859 | 915 | ||
860 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | 916 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) |
@@ -902,6 +958,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
902 | sync = wacom_tpc_irq(wacom_wac, len); | 958 | sync = wacom_tpc_irq(wacom_wac, len); |
903 | break; | 959 | break; |
904 | 960 | ||
961 | case BAMBOO_PT: | ||
962 | sync = wacom_bpt_irq(wacom_wac, len); | ||
963 | break; | ||
964 | |||
905 | default: | 965 | default: |
906 | sync = false; | 966 | sync = false; |
907 | break; | 967 | break; |
@@ -911,26 +971,17 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
911 | input_sync(wacom_wac->input); | 971 | input_sync(wacom_wac->input); |
912 | } | 972 | } |
913 | 973 | ||
914 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | 974 | static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) |
915 | { | 975 | { |
916 | struct input_dev *input_dev = wacom_wac->input; | 976 | struct input_dev *input_dev = wacom_wac->input; |
917 | 977 | ||
918 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 978 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); |
919 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
920 | |||
921 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
922 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
923 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
924 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
925 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
926 | 979 | ||
927 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 980 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
928 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 981 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
929 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
930 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); | 982 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); |
931 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); | 983 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); |
932 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); | 984 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); |
933 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
934 | __set_bit(BTN_STYLUS, input_dev->keybit); | 985 | __set_bit(BTN_STYLUS, input_dev->keybit); |
935 | __set_bit(BTN_STYLUS2, input_dev->keybit); | 986 | __set_bit(BTN_STYLUS2, input_dev->keybit); |
936 | 987 | ||
@@ -939,10 +990,62 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | |||
939 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | 990 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
940 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | 991 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); |
941 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | 992 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); |
993 | } | ||
994 | |||
995 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | ||
996 | { | ||
997 | struct input_dev *input_dev = wacom_wac->input; | ||
998 | |||
999 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
1000 | |||
1001 | wacom_setup_cintiq(wacom_wac); | ||
1002 | |||
1003 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1004 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1005 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
1006 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
1007 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
1008 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
1009 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
1010 | |||
942 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | 1011 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); |
943 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | 1012 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); |
944 | } | 1013 | } |
945 | 1014 | ||
1015 | void wacom_setup_device_quirks(struct wacom_features *features) | ||
1016 | { | ||
1017 | |||
1018 | /* touch device found but size is not defined. use default */ | ||
1019 | if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { | ||
1020 | features->x_max = 1023; | ||
1021 | features->y_max = 1023; | ||
1022 | } | ||
1023 | |||
1024 | /* these device have multiple inputs */ | ||
1025 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | ||
1026 | features->type == BAMBOO_PT) | ||
1027 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | ||
1028 | |||
1029 | /* quirks for bamboo touch */ | ||
1030 | if (features->type == BAMBOO_PT && | ||
1031 | features->device_type == BTN_TOOL_DOUBLETAP) { | ||
1032 | features->x_max <<= 5; | ||
1033 | features->y_max <<= 5; | ||
1034 | features->x_fuzz <<= 5; | ||
1035 | features->y_fuzz <<= 5; | ||
1036 | features->pressure_max = 256; | ||
1037 | features->pressure_fuzz = 16; | ||
1038 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | ||
1043 | unsigned int physical_max) | ||
1044 | { | ||
1045 | /* Touch physical dimensions are in 100th of mm */ | ||
1046 | return (logical_max * 100) / physical_max; | ||
1047 | } | ||
1048 | |||
946 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1049 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
947 | struct wacom_wac *wacom_wac) | 1050 | struct wacom_wac *wacom_wac) |
948 | { | 1051 | { |
@@ -953,9 +1056,25 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
953 | 1056 | ||
954 | __set_bit(BTN_TOUCH, input_dev->keybit); | 1057 | __set_bit(BTN_TOUCH, input_dev->keybit); |
955 | 1058 | ||
956 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 1059 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, |
957 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 1060 | features->x_fuzz, 0); |
958 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 1061 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, |
1062 | features->y_fuzz, 0); | ||
1063 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, | ||
1064 | features->pressure_fuzz, 0); | ||
1065 | |||
1066 | if (features->device_type == BTN_TOOL_PEN) { | ||
1067 | /* penabled devices have fixed resolution for each model */ | ||
1068 | input_abs_set_res(input_dev, ABS_X, features->x_resolution); | ||
1069 | input_abs_set_res(input_dev, ABS_Y, features->y_resolution); | ||
1070 | } else { | ||
1071 | input_abs_set_res(input_dev, ABS_X, | ||
1072 | wacom_calculate_touch_res(features->x_max, | ||
1073 | features->x_phy)); | ||
1074 | input_abs_set_res(input_dev, ABS_Y, | ||
1075 | wacom_calculate_touch_res(features->y_max, | ||
1076 | features->y_phy)); | ||
1077 | } | ||
959 | 1078 | ||
960 | __set_bit(ABS_MISC, input_dev->absbit); | 1079 | __set_bit(ABS_MISC, input_dev->absbit); |
961 | 1080 | ||
@@ -1005,9 +1124,19 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1005 | __set_bit(BTN_9, input_dev->keybit); | 1124 | __set_bit(BTN_9, input_dev->keybit); |
1006 | /* fall through */ | 1125 | /* fall through */ |
1007 | 1126 | ||
1127 | case CINTIQ: | ||
1128 | for (i = 0; i < 8; i++) | ||
1129 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1130 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1131 | |||
1132 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
1133 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
1134 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1135 | wacom_setup_cintiq(wacom_wac); | ||
1136 | break; | ||
1137 | |||
1008 | case INTUOS3: | 1138 | case INTUOS3: |
1009 | case INTUOS3L: | 1139 | case INTUOS3L: |
1010 | case CINTIQ: | ||
1011 | __set_bit(BTN_4, input_dev->keybit); | 1140 | __set_bit(BTN_4, input_dev->keybit); |
1012 | __set_bit(BTN_5, input_dev->keybit); | 1141 | __set_bit(BTN_5, input_dev->keybit); |
1013 | __set_bit(BTN_6, input_dev->keybit); | 1142 | __set_bit(BTN_6, input_dev->keybit); |
@@ -1048,19 +1177,20 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1048 | break; | 1177 | break; |
1049 | 1178 | ||
1050 | case TABLETPC2FG: | 1179 | case TABLETPC2FG: |
1051 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 1180 | if (features->device_type == BTN_TOOL_DOUBLETAP) { |
1052 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 1181 | |
1053 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 1182 | input_mt_init_slots(input_dev, 2); |
1183 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | ||
1184 | 0, MT_TOOL_MAX, 0, 0); | ||
1185 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1186 | 0, features->x_max, 0, 0); | ||
1187 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1188 | 0, features->y_max, 0, 0); | ||
1054 | } | 1189 | } |
1055 | /* fall through */ | 1190 | /* fall through */ |
1056 | 1191 | ||
1057 | case TABLETPC: | 1192 | case TABLETPC: |
1058 | if (features->device_type == BTN_TOOL_DOUBLETAP || | 1193 | __clear_bit(ABS_MISC, input_dev->absbit); |
1059 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1060 | input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); | ||
1061 | input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); | ||
1062 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1063 | } | ||
1064 | 1194 | ||
1065 | if (features->device_type != BTN_TOOL_PEN) | 1195 | if (features->device_type != BTN_TOOL_PEN) |
1066 | break; /* no need to process stylus stuff */ | 1196 | break; /* no need to process stylus stuff */ |
@@ -1078,148 +1208,285 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1078 | case PENPARTNER: | 1208 | case PENPARTNER: |
1079 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1209 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1080 | break; | 1210 | break; |
1211 | |||
1212 | case BAMBOO_PT: | ||
1213 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
1214 | |||
1215 | if (features->device_type == BTN_TOOL_DOUBLETAP) { | ||
1216 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1217 | __set_bit(BTN_FORWARD, input_dev->keybit); | ||
1218 | __set_bit(BTN_BACK, input_dev->keybit); | ||
1219 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1220 | |||
1221 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1222 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1223 | |||
1224 | input_mt_init_slots(input_dev, 2); | ||
1225 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1226 | 0, features->x_max, | ||
1227 | features->x_fuzz, 0); | ||
1228 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1229 | 0, features->y_max, | ||
1230 | features->y_fuzz, 0); | ||
1231 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1232 | 0, features->pressure_max, | ||
1233 | features->pressure_fuzz, 0); | ||
1234 | } else if (features->device_type == BTN_TOOL_PEN) { | ||
1235 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1236 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1237 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1238 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1239 | } | ||
1240 | break; | ||
1081 | } | 1241 | } |
1082 | } | 1242 | } |
1083 | 1243 | ||
1084 | static const struct wacom_features wacom_features_0x00 = | 1244 | static const struct wacom_features wacom_features_0x00 = |
1085 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; | 1245 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, |
1246 | 0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; | ||
1086 | static const struct wacom_features wacom_features_0x10 = | 1247 | static const struct wacom_features wacom_features_0x10 = |
1087 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | 1248 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, |
1249 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1088 | static const struct wacom_features wacom_features_0x11 = | 1250 | static const struct wacom_features wacom_features_0x11 = |
1089 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | 1251 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, |
1252 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1090 | static const struct wacom_features wacom_features_0x12 = | 1253 | static const struct wacom_features wacom_features_0x12 = |
1091 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; | 1254 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, |
1255 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1092 | static const struct wacom_features wacom_features_0x13 = | 1256 | static const struct wacom_features wacom_features_0x13 = |
1093 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; | 1257 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, |
1258 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1094 | static const struct wacom_features wacom_features_0x14 = | 1259 | static const struct wacom_features wacom_features_0x14 = |
1095 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | 1260 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1261 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1096 | static const struct wacom_features wacom_features_0x15 = | 1262 | static const struct wacom_features wacom_features_0x15 = |
1097 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; | 1263 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, |
1264 | 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1098 | static const struct wacom_features wacom_features_0x16 = | 1265 | static const struct wacom_features wacom_features_0x16 = |
1099 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; | 1266 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1267 | 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1100 | static const struct wacom_features wacom_features_0x17 = | 1268 | static const struct wacom_features wacom_features_0x17 = |
1101 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | 1269 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, |
1270 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1102 | static const struct wacom_features wacom_features_0x18 = | 1271 | static const struct wacom_features wacom_features_0x18 = |
1103 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; | 1272 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, |
1273 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1104 | static const struct wacom_features wacom_features_0x19 = | 1274 | static const struct wacom_features wacom_features_0x19 = |
1105 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | 1275 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1276 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1106 | static const struct wacom_features wacom_features_0x60 = | 1277 | static const struct wacom_features wacom_features_0x60 = |
1107 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1278 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1279 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1108 | static const struct wacom_features wacom_features_0x61 = | 1280 | static const struct wacom_features wacom_features_0x61 = |
1109 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; | 1281 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, |
1282 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1110 | static const struct wacom_features wacom_features_0x62 = | 1283 | static const struct wacom_features wacom_features_0x62 = |
1111 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1284 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1285 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1112 | static const struct wacom_features wacom_features_0x63 = | 1286 | static const struct wacom_features wacom_features_0x63 = |
1113 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; | 1287 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, |
1288 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1114 | static const struct wacom_features wacom_features_0x64 = | 1289 | static const struct wacom_features wacom_features_0x64 = |
1115 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; | 1290 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, |
1291 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1116 | static const struct wacom_features wacom_features_0x65 = | 1292 | static const struct wacom_features wacom_features_0x65 = |
1117 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | 1293 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, |
1294 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1118 | static const struct wacom_features wacom_features_0x69 = | 1295 | static const struct wacom_features wacom_features_0x69 = |
1119 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1296 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1297 | 63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; | ||
1120 | static const struct wacom_features wacom_features_0x20 = | 1298 | static const struct wacom_features wacom_features_0x20 = |
1121 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | 1299 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, |
1300 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1122 | static const struct wacom_features wacom_features_0x21 = | 1301 | static const struct wacom_features wacom_features_0x21 = |
1123 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1302 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1303 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1124 | static const struct wacom_features wacom_features_0x22 = | 1304 | static const struct wacom_features wacom_features_0x22 = |
1125 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | 1305 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, |
1306 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1126 | static const struct wacom_features wacom_features_0x23 = | 1307 | static const struct wacom_features wacom_features_0x23 = |
1127 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | 1308 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, |
1309 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1128 | static const struct wacom_features wacom_features_0x24 = | 1310 | static const struct wacom_features wacom_features_0x24 = |
1129 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | 1311 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, |
1312 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1130 | static const struct wacom_features wacom_features_0x30 = | 1313 | static const struct wacom_features wacom_features_0x30 = |
1131 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; | 1314 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, |
1315 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1132 | static const struct wacom_features wacom_features_0x31 = | 1316 | static const struct wacom_features wacom_features_0x31 = |
1133 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; | 1317 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, |
1318 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1134 | static const struct wacom_features wacom_features_0x32 = | 1319 | static const struct wacom_features wacom_features_0x32 = |
1135 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; | 1320 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, |
1321 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1136 | static const struct wacom_features wacom_features_0x33 = | 1322 | static const struct wacom_features wacom_features_0x33 = |
1137 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; | 1323 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, |
1324 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1138 | static const struct wacom_features wacom_features_0x34 = | 1325 | static const struct wacom_features wacom_features_0x34 = |
1139 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; | 1326 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, |
1327 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1140 | static const struct wacom_features wacom_features_0x35 = | 1328 | static const struct wacom_features wacom_features_0x35 = |
1141 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; | 1329 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, |
1330 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1142 | static const struct wacom_features wacom_features_0x37 = | 1331 | static const struct wacom_features wacom_features_0x37 = |
1143 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; | 1332 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, |
1333 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1144 | static const struct wacom_features wacom_features_0x38 = | 1334 | static const struct wacom_features wacom_features_0x38 = |
1145 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | 1335 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, |
1336 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1146 | static const struct wacom_features wacom_features_0x39 = | 1337 | static const struct wacom_features wacom_features_0x39 = |
1147 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; | 1338 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, |
1339 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1148 | static const struct wacom_features wacom_features_0xC4 = | 1340 | static const struct wacom_features wacom_features_0xC4 = |
1149 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | 1341 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, |
1342 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1150 | static const struct wacom_features wacom_features_0xC0 = | 1343 | static const struct wacom_features wacom_features_0xC0 = |
1151 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | 1344 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, |
1345 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1152 | static const struct wacom_features wacom_features_0xC2 = | 1346 | static const struct wacom_features wacom_features_0xC2 = |
1153 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | 1347 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, |
1348 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1154 | static const struct wacom_features wacom_features_0x03 = | 1349 | static const struct wacom_features wacom_features_0x03 = |
1155 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; | 1350 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, |
1351 | 0, PTU, WACOM_PL_RES, WACOM_PL_RES }; | ||
1156 | static const struct wacom_features wacom_features_0x41 = | 1352 | static const struct wacom_features wacom_features_0x41 = |
1157 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | 1353 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, |
1354 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1158 | static const struct wacom_features wacom_features_0x42 = | 1355 | static const struct wacom_features wacom_features_0x42 = |
1159 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1356 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1357 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1160 | static const struct wacom_features wacom_features_0x43 = | 1358 | static const struct wacom_features wacom_features_0x43 = |
1161 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | 1359 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, |
1360 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1162 | static const struct wacom_features wacom_features_0x44 = | 1361 | static const struct wacom_features wacom_features_0x44 = |
1163 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | 1362 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, |
1363 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1164 | static const struct wacom_features wacom_features_0x45 = | 1364 | static const struct wacom_features wacom_features_0x45 = |
1165 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | 1365 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, |
1366 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1166 | static const struct wacom_features wacom_features_0xB0 = | 1367 | static const struct wacom_features wacom_features_0xB0 = |
1167 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; | 1368 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, |
1369 | 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1168 | static const struct wacom_features wacom_features_0xB1 = | 1370 | static const struct wacom_features wacom_features_0xB1 = |
1169 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; | 1371 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, |
1372 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1170 | static const struct wacom_features wacom_features_0xB2 = | 1373 | static const struct wacom_features wacom_features_0xB2 = |
1171 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; | 1374 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, |
1375 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1172 | static const struct wacom_features wacom_features_0xB3 = | 1376 | static const struct wacom_features wacom_features_0xB3 = |
1173 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; | 1377 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, |
1378 | 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1174 | static const struct wacom_features wacom_features_0xB4 = | 1379 | static const struct wacom_features wacom_features_0xB4 = |
1175 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; | 1380 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, |
1381 | 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1176 | static const struct wacom_features wacom_features_0xB5 = | 1382 | static const struct wacom_features wacom_features_0xB5 = |
1177 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; | 1383 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, |
1384 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1178 | static const struct wacom_features wacom_features_0xB7 = | 1385 | static const struct wacom_features wacom_features_0xB7 = |
1179 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; | 1386 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, |
1387 | 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1180 | static const struct wacom_features wacom_features_0xB8 = | 1388 | static const struct wacom_features wacom_features_0xB8 = |
1181 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; | 1389 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, |
1390 | 63, INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1182 | static const struct wacom_features wacom_features_0xB9 = | 1391 | static const struct wacom_features wacom_features_0xB9 = |
1183 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; | 1392 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
1393 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1184 | static const struct wacom_features wacom_features_0xBA = | 1394 | static const struct wacom_features wacom_features_0xBA = |
1185 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; | 1395 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, |
1396 | 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1186 | static const struct wacom_features wacom_features_0xBB = | 1397 | static const struct wacom_features wacom_features_0xBB = |
1187 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; | 1398 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, |
1399 | 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1188 | static const struct wacom_features wacom_features_0xBC = | 1400 | static const struct wacom_features wacom_features_0xBC = |
1189 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 }; | 1401 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, |
1402 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1190 | static const struct wacom_features wacom_features_0x3F = | 1403 | static const struct wacom_features wacom_features_0x3F = |
1191 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; | 1404 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
1405 | 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1192 | static const struct wacom_features wacom_features_0xC5 = | 1406 | static const struct wacom_features wacom_features_0xC5 = |
1193 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; | 1407 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, |
1408 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1194 | static const struct wacom_features wacom_features_0xC6 = | 1409 | static const struct wacom_features wacom_features_0xC6 = |
1195 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; | 1410 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, |
1411 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1196 | static const struct wacom_features wacom_features_0xC7 = | 1412 | static const struct wacom_features wacom_features_0xC7 = |
1197 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; | 1413 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, |
1414 | 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1198 | static const struct wacom_features wacom_features_0xCE = | 1415 | static const struct wacom_features wacom_features_0xCE = |
1199 | { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, 0, DTU }; | 1416 | { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, |
1417 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1200 | static const struct wacom_features wacom_features_0xF0 = | 1418 | static const struct wacom_features wacom_features_0xF0 = |
1201 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU }; | 1419 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, |
1420 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1202 | static const struct wacom_features wacom_features_0xCC = | 1421 | static const struct wacom_features wacom_features_0xCC = |
1203 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; | 1422 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, |
1423 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1204 | static const struct wacom_features wacom_features_0x90 = | 1424 | static const struct wacom_features wacom_features_0x90 = |
1205 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1425 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1426 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1206 | static const struct wacom_features wacom_features_0x93 = | 1427 | static const struct wacom_features wacom_features_0x93 = |
1207 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1428 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1429 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1208 | static const struct wacom_features wacom_features_0x9A = | 1430 | static const struct wacom_features wacom_features_0x9A = |
1209 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1431 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1432 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1210 | static const struct wacom_features wacom_features_0x9F = | 1433 | static const struct wacom_features wacom_features_0x9F = |
1211 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1434 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1435 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1212 | static const struct wacom_features wacom_features_0xE2 = | 1436 | static const struct wacom_features wacom_features_0xE2 = |
1213 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 1437 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1438 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1214 | static const struct wacom_features wacom_features_0xE3 = | 1439 | static const struct wacom_features wacom_features_0xE3 = |
1215 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 1440 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1441 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1442 | static const struct wacom_features wacom_features_0xE6 = | ||
1443 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, | ||
1444 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1216 | static const struct wacom_features wacom_features_0x47 = | 1445 | static const struct wacom_features wacom_features_0x47 = |
1217 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1446 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1447 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1448 | static const struct wacom_features wacom_features_0xD0 = | ||
1449 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1450 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1451 | static const struct wacom_features wacom_features_0xD1 = | ||
1452 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1453 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1454 | static const struct wacom_features wacom_features_0xD2 = | ||
1455 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1456 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1457 | static const struct wacom_features wacom_features_0xD3 = | ||
1458 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1459 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1460 | static const struct wacom_features wacom_features_0xD4 = | ||
1461 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, | ||
1462 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1463 | static const struct wacom_features wacom_features_0xD6 = | ||
1464 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1465 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1466 | static const struct wacom_features wacom_features_0xD7 = | ||
1467 | { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1468 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1469 | static const struct wacom_features wacom_features_0xD8 = | ||
1470 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1471 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1472 | static const struct wacom_features wacom_features_0xDA = | ||
1473 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1474 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1475 | static struct wacom_features wacom_features_0xDB = | ||
1476 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1477 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1478 | static const struct wacom_features wacom_features_0x6004 = | ||
1479 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | ||
1480 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1218 | 1481 | ||
1219 | #define USB_DEVICE_WACOM(prod) \ | 1482 | #define USB_DEVICE_WACOM(prod) \ |
1220 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1483 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
1221 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1484 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
1222 | 1485 | ||
1486 | #define USB_DEVICE_LENOVO(prod) \ | ||
1487 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | ||
1488 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1489 | |||
1223 | const struct usb_device_id wacom_ids[] = { | 1490 | const struct usb_device_id wacom_ids[] = { |
1224 | { USB_DEVICE_WACOM(0x00) }, | 1491 | { USB_DEVICE_WACOM(0x00) }, |
1225 | { USB_DEVICE_WACOM(0x10) }, | 1492 | { USB_DEVICE_WACOM(0x10) }, |
@@ -1279,6 +1546,16 @@ const struct usb_device_id wacom_ids[] = { | |||
1279 | { USB_DEVICE_WACOM(0xC6) }, | 1546 | { USB_DEVICE_WACOM(0xC6) }, |
1280 | { USB_DEVICE_WACOM(0xC7) }, | 1547 | { USB_DEVICE_WACOM(0xC7) }, |
1281 | { USB_DEVICE_WACOM(0xCE) }, | 1548 | { USB_DEVICE_WACOM(0xCE) }, |
1549 | { USB_DEVICE_WACOM(0xD0) }, | ||
1550 | { USB_DEVICE_WACOM(0xD1) }, | ||
1551 | { USB_DEVICE_WACOM(0xD2) }, | ||
1552 | { USB_DEVICE_WACOM(0xD3) }, | ||
1553 | { USB_DEVICE_WACOM(0xD4) }, | ||
1554 | { USB_DEVICE_WACOM(0xD6) }, | ||
1555 | { USB_DEVICE_WACOM(0xD7) }, | ||
1556 | { USB_DEVICE_WACOM(0xD8) }, | ||
1557 | { USB_DEVICE_WACOM(0xDA) }, | ||
1558 | { USB_DEVICE_WACOM(0xDB) }, | ||
1282 | { USB_DEVICE_WACOM(0xF0) }, | 1559 | { USB_DEVICE_WACOM(0xF0) }, |
1283 | { USB_DEVICE_WACOM(0xCC) }, | 1560 | { USB_DEVICE_WACOM(0xCC) }, |
1284 | { USB_DEVICE_WACOM(0x90) }, | 1561 | { USB_DEVICE_WACOM(0x90) }, |
@@ -1287,7 +1564,9 @@ const struct usb_device_id wacom_ids[] = { | |||
1287 | { USB_DEVICE_WACOM(0x9F) }, | 1564 | { USB_DEVICE_WACOM(0x9F) }, |
1288 | { USB_DEVICE_WACOM(0xE2) }, | 1565 | { USB_DEVICE_WACOM(0xE2) }, |
1289 | { USB_DEVICE_WACOM(0xE3) }, | 1566 | { USB_DEVICE_WACOM(0xE3) }, |
1567 | { USB_DEVICE_WACOM(0xE6) }, | ||
1290 | { USB_DEVICE_WACOM(0x47) }, | 1568 | { USB_DEVICE_WACOM(0x47) }, |
1569 | { USB_DEVICE_LENOVO(0x6004) }, | ||
1291 | { } | 1570 | { } |
1292 | }; | 1571 | }; |
1293 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1572 | MODULE_DEVICE_TABLE(usb, wacom_ids); |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 99e1a54cd305..53eb71b68330 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define WACOM_PKGLEN_INTUOS 10 | 21 | #define WACOM_PKGLEN_INTUOS 10 |
22 | #define WACOM_PKGLEN_TPC1FG 5 | 22 | #define WACOM_PKGLEN_TPC1FG 5 |
23 | #define WACOM_PKGLEN_TPC2FG 14 | 23 | #define WACOM_PKGLEN_TPC2FG 14 |
24 | #define WACOM_PKGLEN_BBTOUCH 20 | ||
24 | 25 | ||
25 | /* device IDs */ | 26 | /* device IDs */ |
26 | #define STYLUS_DEVICE_ID 0x02 | 27 | #define STYLUS_DEVICE_ID 0x02 |
@@ -37,6 +38,10 @@ | |||
37 | #define WACOM_REPORT_TPC1FG 6 | 38 | #define WACOM_REPORT_TPC1FG 6 |
38 | #define WACOM_REPORT_TPC2FG 13 | 39 | #define WACOM_REPORT_TPC2FG 13 |
39 | 40 | ||
41 | /* device quirks */ | ||
42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | ||
43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | ||
44 | |||
40 | enum { | 45 | enum { |
41 | PENPARTNER = 0, | 46 | PENPARTNER = 0, |
42 | GRAPHIRE, | 47 | GRAPHIRE, |
@@ -44,6 +49,7 @@ enum { | |||
44 | PTU, | 49 | PTU, |
45 | PL, | 50 | PL, |
46 | DTU, | 51 | DTU, |
52 | BAMBOO_PT, | ||
47 | INTUOS, | 53 | INTUOS, |
48 | INTUOS3S, | 54 | INTUOS3S, |
49 | INTUOS3, | 55 | INTUOS3, |
@@ -68,24 +74,31 @@ struct wacom_features { | |||
68 | int pressure_max; | 74 | int pressure_max; |
69 | int distance_max; | 75 | int distance_max; |
70 | int type; | 76 | int type; |
77 | int x_resolution; | ||
78 | int y_resolution; | ||
71 | int device_type; | 79 | int device_type; |
72 | int x_phy; | 80 | int x_phy; |
73 | int y_phy; | 81 | int y_phy; |
74 | unsigned char unit; | 82 | unsigned char unit; |
75 | unsigned char unitExpo; | 83 | unsigned char unitExpo; |
84 | int x_fuzz; | ||
85 | int y_fuzz; | ||
86 | int pressure_fuzz; | ||
87 | int distance_fuzz; | ||
88 | unsigned quirks; | ||
76 | }; | 89 | }; |
77 | 90 | ||
78 | struct wacom_shared { | 91 | struct wacom_shared { |
79 | bool stylus_in_proximity; | 92 | bool stylus_in_proximity; |
93 | bool touch_down; | ||
80 | }; | 94 | }; |
81 | 95 | ||
82 | struct wacom_wac { | 96 | struct wacom_wac { |
83 | char name[64]; | 97 | char name[64]; |
84 | unsigned char *data; | 98 | unsigned char *data; |
85 | int tool[3]; | 99 | int tool[2]; |
86 | int id[3]; | 100 | int id[2]; |
87 | __u32 serial[2]; | 101 | __u32 serial[2]; |
88 | int last_finger; | ||
89 | struct wacom_features features; | 102 | struct wacom_features features; |
90 | struct wacom_shared *shared; | 103 | struct wacom_shared *shared; |
91 | struct input_dev *input; | 104 | struct input_dev *input; |