aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-07-24 15:56:22 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-25 21:53:50 -0400
commit27b20a9dec0cb1a4cc0517b94302875800191e34 (patch)
treea656870538b89d58b6f4d13d061c07adecf55db5 /drivers/input/tablet
parent29b4739134c73a2873adec93346f09bb76d6a794 (diff)
Input: wacom - use hid communication instead of plain usb
Wacom.ko was a plain USB driver for a HID device. The communications from/to the devices can actually be replaced with the HID API. At the USB level, the reports are exactly the same. This will allow to use uhid virtual devices instead of true USB devices. This step is necessary to implement regression tests. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Reviewed-by: Jason Gerecke <killertofu@gmail.com> Tested-by: Jason Gerecke <killertofu@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r--drivers/input/tablet/wacom_sys.c81
1 files changed, 36 insertions, 45 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 5ceeab6e95f1..120ab1b5df3c 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -34,11 +34,6 @@ struct wac_hid_descriptor {
34 __le16 wDescriptorLength; 34 __le16 wDescriptorLength;
35} __attribute__ ((packed)); 35} __attribute__ ((packed));
36 36
37/* defines to get/set USB message */
38#define USB_REQ_GET_REPORT 0x01
39#define USB_REQ_SET_REPORT 0x09
40
41#define WAC_HID_FEATURE_REPORT 0x03
42#define WAC_MSG_RETRIES 5 37#define WAC_MSG_RETRIES 5
43 38
44#define WAC_CMD_LED_CONTROL 0x20 39#define WAC_CMD_LED_CONTROL 0x20
@@ -46,38 +41,27 @@ struct wac_hid_descriptor {
46#define WAC_CMD_ICON_XFER 0x23 41#define WAC_CMD_ICON_XFER 0x23
47#define WAC_CMD_RETRIES 10 42#define WAC_CMD_RETRIES 10
48 43
49static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id, 44static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id,
50 void *buf, size_t size, unsigned int retries) 45 void *buf, size_t size, unsigned int retries)
51{ 46{
52 struct usb_device *dev = interface_to_usbdev(intf);
53 int retval; 47 int retval;
54 48
55 do { 49 do {
56 retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 50 retval = hid_hw_raw_request(hdev, id, buf, size, type,
57 USB_REQ_GET_REPORT, 51 HID_REQ_GET_REPORT);
58 USB_DIR_IN | USB_TYPE_CLASS |
59 USB_RECIP_INTERFACE,
60 (type << 8) + id,
61 intf->altsetting[0].desc.bInterfaceNumber,
62 buf, size, 100);
63 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); 52 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
64 53
65 return retval; 54 return retval;
66} 55}
67 56
68static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id, 57static int wacom_set_report(struct hid_device *hdev, u8 type, u8 id,
69 void *buf, size_t size, unsigned int retries) 58 void *buf, size_t size, unsigned int retries)
70{ 59{
71 struct usb_device *dev = interface_to_usbdev(intf);
72 int retval; 60 int retval;
73 61
74 do { 62 do {
75 retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 63 retval = hid_hw_raw_request(hdev, id, buf, size, type,
76 USB_REQ_SET_REPORT, 64 HID_REQ_SET_REPORT);
77 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
78 (type << 8) + id,
79 intf->altsetting[0].desc.bInterfaceNumber,
80 buf, size, 1000);
81 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); 65 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
82 66
83 return retval; 67 return retval;
@@ -188,7 +172,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
188 return length; 172 return length;
189} 173}
190 174
191static void wacom_retrieve_report_data(struct usb_interface *intf, 175static void wacom_retrieve_report_data(struct hid_device *hdev,
192 struct wacom_features *features) 176 struct wacom_features *features)
193{ 177{
194 int result = 0; 178 int result = 0;
@@ -198,7 +182,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf,
198 if (rep_data) { 182 if (rep_data) {
199 183
200 rep_data[0] = 12; 184 rep_data[0] = 12;
201 result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, 185 result = wacom_get_report(hdev, HID_FEATURE_REPORT,
202 rep_data[0], rep_data, 2, 186 rep_data[0], rep_data, 2,
203 WAC_MSG_RETRIES); 187 WAC_MSG_RETRIES);
204 188
@@ -245,10 +229,12 @@ static void wacom_retrieve_report_data(struct usb_interface *intf,
245 * Intuos5 touch interface does not contain useful data. We deal with 229 * Intuos5 touch interface does not contain useful data. We deal with
246 * this after returning from this function. 230 * this after returning from this function.
247 */ 231 */
248static int wacom_parse_hid(struct usb_interface *intf, 232static int wacom_parse_hid(struct hid_device *hdev,
249 struct wac_hid_descriptor *hid_desc, 233 struct wac_hid_descriptor *hid_desc,
250 struct wacom_features *features) 234 struct wacom_features *features)
251{ 235{
236 struct wacom *wacom = hid_get_drvdata(hdev);
237 struct usb_interface *intf = wacom->intf;
252 struct usb_device *dev = interface_to_usbdev(intf); 238 struct usb_device *dev = interface_to_usbdev(intf);
253 char limit = 0; 239 char limit = 0;
254 /* result has to be defined as int for some devices */ 240 /* result has to be defined as int for some devices */
@@ -435,7 +421,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
435 case HID_DG_CONTACTMAX: 421 case HID_DG_CONTACTMAX:
436 /* leave touch_max as is if predefined */ 422 /* leave touch_max as is if predefined */
437 if (!features->touch_max) 423 if (!features->touch_max)
438 wacom_retrieve_report_data(intf, features); 424 wacom_retrieve_report_data(hdev, features);
439 i++; 425 i++;
440 break; 426 break;
441 427
@@ -474,7 +460,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
474 return result; 460 return result;
475} 461}
476 462
477static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int length, int mode) 463static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
464 int length, int mode)
478{ 465{
479 unsigned char *rep_data; 466 unsigned char *rep_data;
480 int error = -ENOMEM, limit = 0; 467 int error = -ENOMEM, limit = 0;
@@ -487,10 +474,10 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int
487 rep_data[0] = report_id; 474 rep_data[0] = report_id;
488 rep_data[1] = mode; 475 rep_data[1] = mode;
489 476
490 error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, 477 error = wacom_set_report(hdev, HID_FEATURE_REPORT,
491 report_id, rep_data, length, 1); 478 report_id, rep_data, length, 1);
492 if (error >= 0) 479 if (error >= 0)
493 error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, 480 error = wacom_get_report(hdev, HID_FEATURE_REPORT,
494 report_id, rep_data, length, 1); 481 report_id, rep_data, length, 1);
495 } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); 482 } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
496 483
@@ -506,29 +493,32 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int
506 * from the tablet, it is necessary to switch the tablet out of this 493 * from the tablet, it is necessary to switch the tablet out of this
507 * mode and into one which sends the full range of tablet data. 494 * mode and into one which sends the full range of tablet data.
508 */ 495 */
509static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) 496static int wacom_query_tablet_data(struct hid_device *hdev,
497 struct wacom_features *features)
510{ 498{
511 if (features->device_type == BTN_TOOL_FINGER) { 499 if (features->device_type == BTN_TOOL_FINGER) {
512 if (features->type > TABLETPC) { 500 if (features->type > TABLETPC) {
513 /* MT Tablet PC touch */ 501 /* MT Tablet PC touch */
514 return wacom_set_device_mode(intf, 3, 4, 4); 502 return wacom_set_device_mode(hdev, 3, 4, 4);
515 } 503 }
516 else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { 504 else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
517 return wacom_set_device_mode(intf, 18, 3, 2); 505 return wacom_set_device_mode(hdev, 18, 3, 2);
518 } 506 }
519 } else if (features->device_type == BTN_TOOL_PEN) { 507 } else if (features->device_type == BTN_TOOL_PEN) {
520 if (features->type <= BAMBOO_PT && features->type != WIRELESS) { 508 if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
521 return wacom_set_device_mode(intf, 2, 2, 2); 509 return wacom_set_device_mode(hdev, 2, 2, 2);
522 } 510 }
523 } 511 }
524 512
525 return 0; 513 return 0;
526} 514}
527 515
528static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, 516static int wacom_retrieve_hid_descriptor(struct hid_device *hdev,
529 struct wacom_features *features) 517 struct wacom_features *features)
530{ 518{
531 int error = 0; 519 int error = 0;
520 struct wacom *wacom = hid_get_drvdata(hdev);
521 struct usb_interface *intf = wacom->intf;
532 struct usb_host_interface *interface = intf->cur_altsetting; 522 struct usb_host_interface *interface = intf->cur_altsetting;
533 struct wac_hid_descriptor *hid_desc; 523 struct wac_hid_descriptor *hid_desc;
534 524
@@ -564,12 +554,12 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
564 error = usb_get_extra_descriptor(&interface->endpoint[0], 554 error = usb_get_extra_descriptor(&interface->endpoint[0],
565 HID_DEVICET_REPORT, &hid_desc); 555 HID_DEVICET_REPORT, &hid_desc);
566 if (error) { 556 if (error) {
567 dev_err(&intf->dev, 557 hid_err(hdev,
568 "can not retrieve extra class descriptor\n"); 558 "can not retrieve extra class descriptor\n");
569 goto out; 559 goto out;
570 } 560 }
571 } 561 }
572 error = wacom_parse_hid(intf, hid_desc, features); 562 error = wacom_parse_hid(hdev, hid_desc, features);
573 563
574 out: 564 out:
575 return error; 565 return error;
@@ -711,8 +701,8 @@ static int wacom_led_control(struct wacom *wacom)
711 buf[4] = wacom->led.img_lum; 701 buf[4] = wacom->led.img_lum;
712 } 702 }
713 703
714 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, 704 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
715 buf, 9, WAC_CMD_RETRIES); 705 WAC_CMD_LED_CONTROL, buf, 9, WAC_CMD_RETRIES);
716 kfree(buf); 706 kfree(buf);
717 707
718 return retval; 708 return retval;
@@ -730,8 +720,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
730 /* Send 'start' command */ 720 /* Send 'start' command */
731 buf[0] = WAC_CMD_ICON_START; 721 buf[0] = WAC_CMD_ICON_START;
732 buf[1] = 1; 722 buf[1] = 1;
733 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, 723 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
734 buf, 2, WAC_CMD_RETRIES); 724 WAC_CMD_ICON_START, buf, 2, WAC_CMD_RETRIES);
735 if (retval < 0) 725 if (retval < 0)
736 goto out; 726 goto out;
737 727
@@ -741,7 +731,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
741 buf[2] = i; 731 buf[2] = i;
742 memcpy(buf + 3, img + i * 256, 256); 732 memcpy(buf + 3, img + i * 256, 256);
743 733
744 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_XFER, 734 retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
735 WAC_CMD_ICON_XFER,
745 buf, 259, WAC_CMD_RETRIES); 736 buf, 259, WAC_CMD_RETRIES);
746 if (retval < 0) 737 if (retval < 0)
747 break; 738 break;
@@ -750,7 +741,7 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
750 /* Send 'stop' */ 741 /* Send 'stop' */
751 buf[0] = WAC_CMD_ICON_START; 742 buf[0] = WAC_CMD_ICON_START;
752 buf[1] = 0; 743 buf[1] = 0;
753 wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, 744 wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, WAC_CMD_ICON_START,
754 buf, 2, WAC_CMD_RETRIES); 745 buf, 2, WAC_CMD_RETRIES);
755 746
756out: 747out:
@@ -1331,7 +1322,7 @@ static int wacom_probe(struct hid_device *hdev,
1331 wacom_set_default_phy(features); 1322 wacom_set_default_phy(features);
1332 1323
1333 /* Retrieve the physical and logical size for touch devices */ 1324 /* Retrieve the physical and logical size for touch devices */
1334 error = wacom_retrieve_hid_descriptor(intf, features); 1325 error = wacom_retrieve_hid_descriptor(hdev, features);
1335 if (error) 1326 if (error)
1336 goto fail1; 1327 goto fail1;
1337 1328
@@ -1395,7 +1386,7 @@ static int wacom_probe(struct hid_device *hdev,
1395 } 1386 }
1396 1387
1397 /* Note that if query fails it is not a hard failure */ 1388 /* Note that if query fails it is not a hard failure */
1398 wacom_query_tablet_data(intf, features); 1389 wacom_query_tablet_data(hdev, features);
1399 1390
1400 /* Regular HID work starts now */ 1391 /* Regular HID work starts now */
1401 error = hid_parse(hdev); 1392 error = hid_parse(hdev);
@@ -1452,7 +1443,7 @@ static int wacom_resume(struct hid_device *hdev)
1452 mutex_lock(&wacom->lock); 1443 mutex_lock(&wacom->lock);
1453 1444
1454 /* switch to wacom mode first */ 1445 /* switch to wacom mode first */
1455 wacom_query_tablet_data(wacom->intf, features); 1446 wacom_query_tablet_data(hdev, features);
1456 wacom_led_control(wacom); 1447 wacom_led_control(wacom);
1457 1448
1458 mutex_unlock(&wacom->lock); 1449 mutex_unlock(&wacom->lock);