Input: wacom - use hid communication instead of plain usb
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>
Thu, 24 Jul 2014 19:56:22 +0000 (12:56 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 26 Jul 2014 01:53:50 +0000 (18:53 -0700)
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>
drivers/input/tablet/wacom_sys.c

index 5ceeab6e95f16701b7aeca7213faedfd847e1eb2..120ab1b5df3c7709092788c67ef01b9888d59308 100644 (file)
@@ -34,11 +34,6 @@ struct wac_hid_descriptor {
        __le16   wDescriptorLength;
 } __attribute__ ((packed));
 
-/* defines to get/set USB message */
-#define USB_REQ_GET_REPORT     0x01
-#define USB_REQ_SET_REPORT     0x09
-
-#define WAC_HID_FEATURE_REPORT 0x03
 #define WAC_MSG_RETRIES                5
 
 #define WAC_CMD_LED_CONTROL    0x20
@@ -46,38 +41,27 @@ struct wac_hid_descriptor {
 #define WAC_CMD_ICON_XFER      0x23
 #define WAC_CMD_RETRIES                10
 
-static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id,
+static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id,
                            void *buf, size_t size, unsigned int retries)
 {
-       struct usb_device *dev = interface_to_usbdev(intf);
        int retval;
 
        do {
-               retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                               USB_REQ_GET_REPORT,
-                               USB_DIR_IN | USB_TYPE_CLASS |
-                               USB_RECIP_INTERFACE,
-                               (type << 8) + id,
-                               intf->altsetting[0].desc.bInterfaceNumber,
-                               buf, size, 100);
+               retval = hid_hw_raw_request(hdev, id, buf, size, type,
+                               HID_REQ_GET_REPORT);
        } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
 
        return retval;
 }
 
-static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id,
+static int wacom_set_report(struct hid_device *hdev, u8 type, u8 id,
                            void *buf, size_t size, unsigned int retries)
 {
-       struct usb_device *dev = interface_to_usbdev(intf);
        int retval;
 
        do {
-               retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                               USB_REQ_SET_REPORT,
-                               USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-                               (type << 8) + id,
-                               intf->altsetting[0].desc.bInterfaceNumber,
-                               buf, size, 1000);
+               retval = hid_hw_raw_request(hdev, id, buf, size, type,
+                               HID_REQ_SET_REPORT);
        } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
 
        return retval;
@@ -188,7 +172,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
        return length;
 }
 
-static void wacom_retrieve_report_data(struct usb_interface *intf,
+static void wacom_retrieve_report_data(struct hid_device *hdev,
                                       struct wacom_features *features)
 {
        int result = 0;
@@ -198,7 +182,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf,
        if (rep_data) {
 
                rep_data[0] = 12;
-               result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
+               result = wacom_get_report(hdev, HID_FEATURE_REPORT,
                                          rep_data[0], rep_data, 2,
                                          WAC_MSG_RETRIES);
 
@@ -245,10 +229,12 @@ static void wacom_retrieve_report_data(struct usb_interface *intf,
  * Intuos5 touch interface does not contain useful data. We deal with
  * this after returning from this function.
  */
-static int wacom_parse_hid(struct usb_interface *intf,
+static int wacom_parse_hid(struct hid_device *hdev,
                           struct wac_hid_descriptor *hid_desc,
                           struct wacom_features *features)
 {
+       struct wacom *wacom = hid_get_drvdata(hdev);
+       struct usb_interface *intf = wacom->intf;
        struct usb_device *dev = interface_to_usbdev(intf);
        char limit = 0;
        /* result has to be defined as int for some devices */
@@ -435,7 +421,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
                        case HID_DG_CONTACTMAX:
                                /* leave touch_max as is if predefined */
                                if (!features->touch_max)
-                                       wacom_retrieve_report_data(intf, features);
+                                       wacom_retrieve_report_data(hdev, features);
                                i++;
                                break;
 
@@ -474,7 +460,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
        return result;
 }
 
-static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int length, int mode)
+static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
+               int length, int mode)
 {
        unsigned char *rep_data;
        int error = -ENOMEM, limit = 0;
@@ -487,10 +474,10 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int
                rep_data[0] = report_id;
                rep_data[1] = mode;
 
-               error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
+               error = wacom_set_report(hdev, HID_FEATURE_REPORT,
                                         report_id, rep_data, length, 1);
                if (error >= 0)
-                       error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
+                       error = wacom_get_report(hdev, HID_FEATURE_REPORT,
                                                 report_id, rep_data, length, 1);
        } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
 
@@ -506,29 +493,32 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int
  * from the tablet, it is necessary to switch the tablet out of this
  * mode and into one which sends the full range of tablet data.
  */
-static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features)
+static int wacom_query_tablet_data(struct hid_device *hdev,
+               struct wacom_features *features)
 {
        if (features->device_type == BTN_TOOL_FINGER) {
                if (features->type > TABLETPC) {
                        /* MT Tablet PC touch */
-                       return wacom_set_device_mode(intf, 3, 4, 4);
+                       return wacom_set_device_mode(hdev, 3, 4, 4);
                }
                else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
-                       return wacom_set_device_mode(intf, 18, 3, 2);
+                       return wacom_set_device_mode(hdev, 18, 3, 2);
                }
        } else if (features->device_type == BTN_TOOL_PEN) {
                if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
-                       return wacom_set_device_mode(intf, 2, 2, 2);
+                       return wacom_set_device_mode(hdev, 2, 2, 2);
                }
        }
 
        return 0;
 }
 
-static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+static int wacom_retrieve_hid_descriptor(struct hid_device *hdev,
                                         struct wacom_features *features)
 {
        int error = 0;
+       struct wacom *wacom = hid_get_drvdata(hdev);
+       struct usb_interface *intf = wacom->intf;
        struct usb_host_interface *interface = intf->cur_altsetting;
        struct wac_hid_descriptor *hid_desc;
 
@@ -564,12 +554,12 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
                error = usb_get_extra_descriptor(&interface->endpoint[0],
                                                 HID_DEVICET_REPORT, &hid_desc);
                if (error) {
-                       dev_err(&intf->dev,
+                       hid_err(hdev,
                                "can not retrieve extra class descriptor\n");
                        goto out;
                }
        }
-       error = wacom_parse_hid(intf, hid_desc, features);
+       error = wacom_parse_hid(hdev, hid_desc, features);
 
  out:
        return error;
@@ -711,8 +701,8 @@ static int wacom_led_control(struct wacom *wacom)
                buf[4] = wacom->led.img_lum;
        }
 
-       retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL,
-                                 buf, 9, WAC_CMD_RETRIES);
+       retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
+                                 WAC_CMD_LED_CONTROL, buf, 9, WAC_CMD_RETRIES);
        kfree(buf);
 
        return retval;
@@ -730,8 +720,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
        /* Send 'start' command */
        buf[0] = WAC_CMD_ICON_START;
        buf[1] = 1;
-       retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START,
-                                 buf, 2, WAC_CMD_RETRIES);
+       retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
+                                 WAC_CMD_ICON_START, buf, 2, WAC_CMD_RETRIES);
        if (retval < 0)
                goto out;
 
@@ -741,7 +731,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
                buf[2] = i;
                memcpy(buf + 3, img + i * 256, 256);
 
-               retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_XFER,
+               retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
+                                         WAC_CMD_ICON_XFER,
                                          buf, 259, WAC_CMD_RETRIES);
                if (retval < 0)
                        break;
@@ -750,7 +741,7 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
        /* Send 'stop' */
        buf[0] = WAC_CMD_ICON_START;
        buf[1] = 0;
-       wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START,
+       wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, WAC_CMD_ICON_START,
                         buf, 2, WAC_CMD_RETRIES);
 
 out:
@@ -1331,7 +1322,7 @@ static int wacom_probe(struct hid_device *hdev,
        wacom_set_default_phy(features);
 
        /* Retrieve the physical and logical size for touch devices */
-       error = wacom_retrieve_hid_descriptor(intf, features);
+       error = wacom_retrieve_hid_descriptor(hdev, features);
        if (error)
                goto fail1;
 
@@ -1395,7 +1386,7 @@ static int wacom_probe(struct hid_device *hdev,
        }
 
        /* Note that if query fails it is not a hard failure */
-       wacom_query_tablet_data(intf, features);
+       wacom_query_tablet_data(hdev, features);
 
        /* Regular HID work starts now */
        error = hid_parse(hdev);
@@ -1452,7 +1443,7 @@ static int wacom_resume(struct hid_device *hdev)
        mutex_lock(&wacom->lock);
 
        /* switch to wacom mode first */
-       wacom_query_tablet_data(wacom->intf, features);
+       wacom_query_tablet_data(hdev, features);
        wacom_led_control(wacom);
 
        mutex_unlock(&wacom->lock);