On Sun, Feb 5, 2012 at 8:46 PM, <chris@xxxxxxxxxxxxxx> wrote: > From: Chris Bagwell <chris@xxxxxxxxxxxxxx> > > The 3rd gen Bamboo Pen & Touch tablets support an optional > wireless module. When its receiver is plugged into USB it > presents 3 interfaces: 0) Monitor 1) Pen and 2) Touch. > > The exact capabilities of the Pen and Touch interfaces can > not be determined until a tablet connection is established > and reported over the Monitor interface. > > This patch detects this wireless receiver and enables interrupt > packets to be processed for the Monitor interface. Processing > the data in packets will be left to another patch. > > Since it doesn't make sense to create an input device for the > Monitor interface, it is not created. Creation of Pen and Touch > input device is also delayed until monitor packets can be processed. > > Signed-off-by: Chris Bagwell <chris@xxxxxxxxxxxxxx> > --- > drivers/input/tablet/wacom_sys.c | 35 ++++++++++++++++++++++++++++++----- > drivers/input/tablet/wacom_wac.c | 28 +++++++++++++++++++++++++++- > drivers/input/tablet/wacom_wac.h | 4 ++++ > 3 files changed, 61 insertions(+), 6 deletions(-) > > diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c > index 43e82e9..2827ef3 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 != BAMBOO_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 == BAMBOO_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,9 +944,16 @@ 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_MONITOR) { > + if (usb_submit_urb(wacom->irq, GFP_KERNEL)) > + 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); > @@ -953,7 +976,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 +1009,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 9283507..5b3c58f 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_bpt_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 BAMBOO_WIRELESS: > + sync = wacom_bpt_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 == BAMBOO_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 == BAMBOO_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, > @@ -1637,6 +1659,9 @@ static const struct wacom_features wacom_features_0xE6 = > 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, BAMBOO_WIRELESS, 0, 0 }; I just realized that the following patch will require a .touch_max = 64; here: [PATCH v2 1/2] input : wacom - retrieve maximum number of touch points In v2, I'll fix add that and add a note about dependency. Chris > 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 }; > @@ -1763,6 +1788,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 4f0ba21..fcee9c5 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, > + BAMBOO_WIRELESS, > INTUOS, > INTUOS3S, > INTUOS3, > -- > 1.7.7.6 > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html