aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet/wacom_sys.c')
-rw-r--r--drivers/input/tablet/wacom_sys.c101
1 files changed, 91 insertions, 10 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 8f9cde3e0ec2..2a97b7e76db1 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -28,7 +28,9 @@
28#define HID_USAGE_Y_TILT 0x3e 28#define HID_USAGE_Y_TILT 0x3e
29#define HID_USAGE_FINGER 0x22 29#define HID_USAGE_FINGER 0x22
30#define HID_USAGE_STYLUS 0x20 30#define HID_USAGE_STYLUS 0x20
31#define HID_COLLECTION 0xc0 31#define HID_COLLECTION 0xa1
32#define HID_COLLECTION_LOGICAL 0x02
33#define HID_COLLECTION_END 0xc0
32 34
33enum { 35enum {
34 WCM_UNDEFINED = 0, 36 WCM_UNDEFINED = 0,
@@ -66,7 +68,8 @@ static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id,
66 do { 68 do {
67 retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 69 retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
68 USB_REQ_GET_REPORT, 70 USB_REQ_GET_REPORT,
69 USB_TYPE_CLASS | USB_RECIP_INTERFACE, 71 USB_DIR_IN | USB_TYPE_CLASS |
72 USB_RECIP_INTERFACE,
70 (type << 8) + id, 73 (type << 8) + id,
71 intf->altsetting[0].desc.bInterfaceNumber, 74 intf->altsetting[0].desc.bInterfaceNumber,
72 buf, size, 100); 75 buf, size, 100);
@@ -164,7 +167,70 @@ static void wacom_close(struct input_dev *dev)
164 usb_autopm_put_interface(wacom->intf); 167 usb_autopm_put_interface(wacom->intf);
165} 168}
166 169
167static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, 170static int wacom_parse_logical_collection(unsigned char *report,
171 struct wacom_features *features)
172{
173 int length = 0;
174
175 if (features->type == BAMBOO_PT) {
176
177 /* Logical collection is only used by 3rd gen Bamboo Touch */
178 features->pktlen = WACOM_PKGLEN_BBTOUCH3;
179 features->device_type = BTN_TOOL_DOUBLETAP;
180
181 /*
182 * Stylus and Touch have same active area
183 * so compute physical size based on stylus
184 * data before its overwritten.
185 */
186 features->x_phy =
187 (features->x_max * features->x_resolution) / 100;
188 features->y_phy =
189 (features->y_max * features->y_resolution) / 100;
190
191 features->x_max = features->y_max =
192 get_unaligned_le16(&report[10]);
193
194 length = 11;
195 }
196 return length;
197}
198
199/*
200 * Interface Descriptor of wacom devices can be incomplete and
201 * inconsistent so wacom_features table is used to store stylus
202 * device's packet lengths, various maximum values, and tablet
203 * resolution based on product ID's.
204 *
205 * For devices that contain 2 interfaces, wacom_features table is
206 * inaccurate for the touch interface. Since the Interface Descriptor
207 * for touch interfaces has pretty complete data, this function exists
208 * to query tablet for this missing information instead of hard coding in
209 * an additional table.
210 *
211 * A typical Interface Descriptor for a stylus will contain a
212 * boot mouse application collection that is not of interest and this
213 * function will ignore it.
214 *
215 * It also contains a digitizer application collection that also is not
216 * of interest since any information it contains would be duplicate
217 * of what is in wacom_features. Usually it defines a report of an array
218 * of bytes that could be used as max length of the stylus packet returned.
219 * If it happens to define a Digitizer-Stylus Physical Collection then
220 * the X and Y logical values contain valid data but it is ignored.
221 *
222 * A typical Interface Descriptor for a touch interface will contain a
223 * Digitizer-Finger Physical Collection which will define both logical
224 * X/Y maximum as well as the physical size of tablet. Since touch
225 * interfaces haven't supported pressure or distance, this is enough
226 * information to override invalid values in the wacom_features table.
227 *
228 * 3rd gen Bamboo Touch no longer define a Digitizer-Finger Pysical
229 * Collection. Instead they define a Logical Collection with a single
230 * Logical Maximum for both X and Y.
231 */
232static int wacom_parse_hid(struct usb_interface *intf,
233 struct hid_descriptor *hid_desc,
168 struct wacom_features *features) 234 struct wacom_features *features)
169{ 235{
170 struct usb_device *dev = interface_to_usbdev(intf); 236 struct usb_device *dev = interface_to_usbdev(intf);
@@ -244,8 +310,6 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
244 /* penabled only accepts exact bytes of data */ 310 /* penabled only accepts exact bytes of data */
245 if (features->type == TABLETPC2FG) 311 if (features->type == TABLETPC2FG)
246 features->pktlen = WACOM_PKGLEN_GRAPHIRE; 312 features->pktlen = WACOM_PKGLEN_GRAPHIRE;
247 if (features->type == BAMBOO_PT)
248 features->pktlen = WACOM_PKGLEN_BBFUN;
249 features->device_type = BTN_TOOL_PEN; 313 features->device_type = BTN_TOOL_PEN;
250 features->x_max = 314 features->x_max =
251 get_unaligned_le16(&report[i + 3]); 315 get_unaligned_le16(&report[i + 3]);
@@ -287,8 +351,6 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
287 /* penabled only accepts exact bytes of data */ 351 /* penabled only accepts exact bytes of data */
288 if (features->type == TABLETPC2FG) 352 if (features->type == TABLETPC2FG)
289 features->pktlen = WACOM_PKGLEN_GRAPHIRE; 353 features->pktlen = WACOM_PKGLEN_GRAPHIRE;
290 if (features->type == BAMBOO_PT)
291 features->pktlen = WACOM_PKGLEN_BBFUN;
292 features->device_type = BTN_TOOL_PEN; 354 features->device_type = BTN_TOOL_PEN;
293 features->y_max = 355 features->y_max =
294 get_unaligned_le16(&report[i + 3]); 356 get_unaligned_le16(&report[i + 3]);
@@ -302,6 +364,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
302 i++; 364 i++;
303 break; 365 break;
304 366
367 /*
368 * Requiring Stylus Usage will ignore boot mouse
369 * X/Y values and some cases of invalid Digitizer X/Y
370 * values commonly reported.
371 */
305 case HID_USAGE_STYLUS: 372 case HID_USAGE_STYLUS:
306 pen = 1; 373 pen = 1;
307 i++; 374 i++;
@@ -309,10 +376,20 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
309 } 376 }
310 break; 377 break;
311 378
312 case HID_COLLECTION: 379 case HID_COLLECTION_END:
313 /* reset UsagePage and Finger */ 380 /* reset UsagePage and Finger */
314 finger = usage = 0; 381 finger = usage = 0;
315 break; 382 break;
383
384 case HID_COLLECTION:
385 i++;
386 switch (report[i]) {
387 case HID_COLLECTION_LOGICAL:
388 i += wacom_parse_logical_collection(&report[i],
389 features);
390 break;
391 }
392 break;
316 } 393 }
317 } 394 }
318 395
@@ -348,7 +425,8 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
348 WAC_HID_FEATURE_REPORT, 425 WAC_HID_FEATURE_REPORT,
349 report_id, rep_data, 4, 1); 426 report_id, rep_data, 4, 1);
350 } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); 427 } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
351 } else if (features->type != TABLETPC) { 428 } else if (features->type != TABLETPC &&
429 features->device_type == BTN_TOOL_PEN) {
352 do { 430 do {
353 rep_data[0] = 2; 431 rep_data[0] = 2;
354 rep_data[1] = 2; 432 rep_data[1] = 2;
@@ -485,7 +563,8 @@ static int wacom_led_control(struct wacom *wacom)
485 if (!buf) 563 if (!buf)
486 return -ENOMEM; 564 return -ENOMEM;
487 565
488 if (wacom->wacom_wac.features.type == WACOM_21UX2) 566 if (wacom->wacom_wac.features.type == WACOM_21UX2 ||
567 wacom->wacom_wac.features.type == WACOM_24HD)
489 led = (wacom->led.select[1] << 4) | 0x40; 568 led = (wacom->led.select[1] << 4) | 0x40;
490 569
491 led |= wacom->led.select[0] | 0x4; 570 led |= wacom->led.select[0] | 0x4;
@@ -704,6 +783,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
704 &intuos4_led_attr_group); 783 &intuos4_led_attr_group);
705 break; 784 break;
706 785
786 case WACOM_24HD:
707 case WACOM_21UX2: 787 case WACOM_21UX2:
708 wacom->led.select[0] = 0; 788 wacom->led.select[0] = 0;
709 wacom->led.select[1] = 0; 789 wacom->led.select[1] = 0;
@@ -738,6 +818,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
738 &intuos4_led_attr_group); 818 &intuos4_led_attr_group);
739 break; 819 break;
740 820
821 case WACOM_24HD:
741 case WACOM_21UX2: 822 case WACOM_21UX2:
742 sysfs_remove_group(&wacom->intf->dev.kobj, 823 sysfs_remove_group(&wacom->intf->dev.kobj,
743 &cintiq_led_attr_group); 824 &cintiq_led_attr_group);