diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index f6da2f8a9c18a08f5de28aa04d97805a08251fd3..d8cc9ce165ff2b3829a498aca8a4b44c3ec2db53 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -422,6 +422,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat report_id, rep_data, 4, 1); } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); } else if (features->type != TABLETPC && + features->type != WIRELESS && features->device_type == BTN_TOOL_PEN) { do { rep_data[0] = 2; @@ -454,6 +455,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, features->pressure_fuzz = 0; features->distance_fuzz = 0; + /* + * The wireless device HID is basic and layout conflicts with + * other tablets (monitor and touch interface can look like pen). + * Skip the query for this type and modify defaults based on + * interface number. + */ + if (features->type == WIRELESS) { + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { + features->device_type = 0; + } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) { + features->device_type = BTN_TOOL_DOUBLETAP; + features->pktlen = WACOM_PKGLEN_BBTOUCH3; + } + } + /* only Tablet PCs and Bamboo P&T need to retrieve the info */ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && (features->type != BAMBOO_PT)) @@ -928,14 +944,22 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail4; - error = wacom_register_input(wacom); - if (error) - goto fail5; + if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { + error = wacom_register_input(wacom); + if (error) + goto fail5; + } /* Note that if query fails it is not a hard failure */ wacom_query_tablet_data(intf, features); usb_set_intfdata(intf, wacom); + + if (features->quirks & WACOM_QUIRK_MONITOR) { + if (usb_submit_urb(wacom->irq, GFP_KERNEL)) + goto fail5; + } + return 0; fail5: wacom_destroy_leds(wacom); @@ -953,7 +977,8 @@ static void wacom_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); usb_kill_urb(wacom->irq); - input_unregister_device(wacom->wacom_wac.input); + if (wacom->wacom_wac.input) + input_unregister_device(wacom->wacom_wac.input); wacom_destroy_leds(wacom); usb_free_urb(wacom->irq); usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, @@ -985,7 +1010,8 @@ static int wacom_resume(struct usb_interface *intf) wacom_query_tablet_data(intf, features); wacom_led_control(wacom); - if (wacom->open && usb_submit_urb(wacom->irq, GFP_NOIO) < 0) + if ((wacom->open || features->quirks & WACOM_QUIRK_MONITOR) + && usb_submit_urb(wacom->irq, GFP_NOIO) < 0) rv = -EIO; mutex_unlock(&wacom->lock); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 07a1f218b5c1b6943512e0e7ea1148f61ed1fac2..6264e6a8d513744209b4d9caf16bcf01b1c60d35 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1044,6 +1044,14 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) +{ + if (len != WACOM_PKGLEN_WIRELESS) + return 0; + + return 0; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -1094,6 +1102,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_bpt_irq(wacom_wac, len); break; + case WIRELESS: + sync = wacom_wireless_irq(wacom_wac, len); + break; + default: sync = false; break; @@ -1155,7 +1167,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) /* these device have multiple inputs */ if (features->type == TABLETPC || features->type == TABLETPC2FG || - features->type == BAMBOO_PT) + features->type == BAMBOO_PT || features->type == WIRELESS) features->quirks |= WACOM_QUIRK_MULTI_INPUT; /* quirk for bamboo touch with 2 low res touches */ @@ -1167,6 +1179,16 @@ void wacom_setup_device_quirks(struct wacom_features *features) features->y_fuzz <<= 5; features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; } + + if (features->type == WIRELESS) { + + /* monitor never has input and pen/touch have delayed create */ + features->quirks |= WACOM_QUIRK_NO_INPUT; + + /* must be monitor interface if no device_type set */ + if (!features->device_type) + features->quirks |= WACOM_QUIRK_MONITOR; + } } static unsigned int wacom_calculate_touch_res(unsigned int logical_max, @@ -1640,6 +1662,9 @@ static const struct wacom_features wacom_features_0xEC = static const struct wacom_features wacom_features_0x47 = { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0x84 = + { "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0, + 0, WIRELESS, 0, 0 }; static const struct wacom_features wacom_features_0xD0 = { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -1766,6 +1791,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_MOUSE) }, + { USB_DEVICE_WACOM(0x84) }, { USB_DEVICE_WACOM(0xD0) }, { USB_DEVICE_WACOM(0xD1) }, { USB_DEVICE_WACOM(0xD2) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 4f0ba21b01962c4b2556535468c96f7355e17d1c..2c04b6248a568e1847d81c801ac7070dbaf66774 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -24,6 +24,7 @@ #define WACOM_PKGLEN_BBTOUCH 20 #define WACOM_PKGLEN_BBTOUCH3 64 #define WACOM_PKGLEN_BBPEN 10 +#define WACOM_PKGLEN_WIRELESS 32 /* device IDs */ #define STYLUS_DEVICE_ID 0x02 @@ -45,6 +46,8 @@ /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 +#define WACOM_QUIRK_NO_INPUT 0x0004 +#define WACOM_QUIRK_MONITOR 0x0008 enum { PENPARTNER = 0, @@ -54,6 +57,7 @@ enum { PL, DTU, BAMBOO_PT, + WIRELESS, INTUOS, INTUOS3S, INTUOS3,