From fed87e655a2c20468d628b37424af58287803afe Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 5 Sep 2010 12:25:11 -0700 Subject: Input: wacom - add fuzz parameters to features The signal-to-noise ratio varies between devices, but currently all devices are treated the same way. Add fuzz parameters to the feature struct, allowing for tailored treatment of devices. Signed-off-by: Henrik Rydberg Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 42ba3691d90..e510e4fb54f 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -333,8 +333,12 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, struct usb_host_interface *interface = intf->cur_altsetting; struct hid_descriptor *hid_desc; - /* default device to penabled */ + /* default features */ features->device_type = BTN_TOOL_PEN; + features->x_fuzz = 4; + features->y_fuzz = 4; + features->pressure_fuzz = 0; + features->distance_fuzz = 0; /* only Tablet PCs need to retrieve the info */ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) -- cgit v1.2.3-70-g09d2 From 4a88081e739a41d6d70bace7e0a027f9054ab540 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Sun, 5 Sep 2010 12:25:40 -0700 Subject: Input: wacom - parse the Bamboo device family The Bamboo devices have multiple interfaces which need to be setup separately. Use the HID parsing mechanism to achieve that. Signed-off-by: Ping Cheng Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 44 ++++++++++++++++++++++++++++++++-------- drivers/input/tablet/wacom_wac.h | 2 ++ 2 files changed, 37 insertions(+), 9 deletions(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index e510e4fb54f..98cba08bb96 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -195,17 +195,30 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->pktlen = WACOM_PKGLEN_TPC2FG; features->device_type = BTN_TOOL_TRIPLETAP; } - features->x_max = - get_unaligned_le16(&report[i + 3]); - features->x_phy = - get_unaligned_le16(&report[i + 6]); - features->unit = report[i + 9]; - features->unitExpo = report[i + 11]; - i += 12; + if (features->type == BAMBOO_PT) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_BBTOUCH; + features->device_type = BTN_TOOL_TRIPLETAP; + features->x_phy = + get_unaligned_le16(&report[i + 5]); + features->x_max = + get_unaligned_le16(&report[i + 8]); + i += 15; + } else { + features->x_max = + get_unaligned_le16(&report[i + 3]); + features->x_phy = + get_unaligned_le16(&report[i + 6]); + features->unit = report[i + 9]; + features->unitExpo = report[i + 11]; + i += 12; + } } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; + if (features->type == BAMBOO_PT) + features->pktlen = WACOM_PKGLEN_BBFUN; features->device_type = BTN_TOOL_PEN; features->x_max = get_unaligned_le16(&report[i + 3]); @@ -234,6 +247,15 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->y_phy = get_unaligned_le16(&report[i + 6]); i += 7; + } else if (features->type == BAMBOO_PT) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_BBTOUCH; + features->device_type = BTN_TOOL_TRIPLETAP; + features->y_phy = + get_unaligned_le16(&report[i + 3]); + features->y_max = + get_unaligned_le16(&report[i + 6]); + i += 12; } else { features->y_max = features->x_max; @@ -245,6 +267,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; + if (features->type == BAMBOO_PT) + features->pktlen = WACOM_PKGLEN_BBFUN; features->device_type = BTN_TOOL_PEN; features->y_max = get_unaligned_le16(&report[i + 3]); @@ -341,7 +365,8 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, features->distance_fuzz = 0; /* only Tablet PCs need to retrieve the info */ - if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) + if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && + (features->type != BAMBOO_PT)) goto out; if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { @@ -499,7 +524,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); - if (features->type == TABLETPC || features->type == TABLETPC2FG) { + if (features->type == TABLETPC || features->type == TABLETPC2FG || + features->type == BAMBOO_PT) { /* Append the device type to the name */ strlcat(wacom_wac->name, features->device_type == BTN_TOOL_PEN ? diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index d769e9aa6f1..fb30895d63e 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -21,6 +21,7 @@ #define WACOM_PKGLEN_INTUOS 10 #define WACOM_PKGLEN_TPC1FG 5 #define WACOM_PKGLEN_TPC2FG 14 +#define WACOM_PKGLEN_BBTOUCH 20 /* device IDs */ #define STYLUS_DEVICE_ID 0x02 @@ -44,6 +45,7 @@ enum { PTU, PL, DTU, + BAMBOO_PT, INTUOS, INTUOS3S, INTUOS3, -- cgit v1.2.3-70-g09d2 From bc73dd39e78dd6e5b34cd938b7f037a8bc041bdd Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 5 Sep 2010 12:26:16 -0700 Subject: Input: wacom - collect device quirks into single function Collect device-specific code into a single function, and use quirks to flag specific behavior instead. Signed-off-by: Henrik Rydberg Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom.h | 1 + drivers/input/tablet/wacom_sys.c | 11 +++-------- drivers/input/tablet/wacom_wac.c | 16 ++++++++++++++++ drivers/input/tablet/wacom_wac.h | 4 ++++ 4 files changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 284dfaab6b8..de5adb10903 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -118,6 +118,7 @@ struct wacom { extern const struct usb_device_id wacom_ids[]; void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); +void wacom_setup_device_quirks(struct wacom_features *features); void wacom_setup_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); #endif diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 98cba08bb96..fc6fd53c1af 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -381,12 +381,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, if (error) goto out; - /* touch device found but size is not defined. use default */ - if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { - features->x_max = 1023; - features->y_max = 1023; - } - out: return error; } @@ -522,10 +516,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail2; + wacom_setup_device_quirks(features); + strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); - if (features->type == TABLETPC || features->type == TABLETPC2FG || - features->type == BAMBOO_PT) { + if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { /* Append the device type to the name */ strlcat(wacom_wac->name, features->device_type == BTN_TOOL_PEN ? diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 6d7e1647715..44b4a59750d 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -941,6 +941,22 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); } + +void wacom_setup_device_quirks(struct wacom_features *features) +{ + + /* touch device found but size is not defined. use default */ + if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { + features->x_max = 1023; + features->y_max = 1023; + } + + /* these device have multiple inputs */ + if (features->type == TABLETPC || features->type == TABLETPC2FG || + features->type == BAMBOO_PT) + features->quirks |= WACOM_QUIRK_MULTI_INPUT; +} + void wacom_setup_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index fb30895d63e..6a1ff10b095 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -38,6 +38,9 @@ #define WACOM_REPORT_TPC1FG 6 #define WACOM_REPORT_TPC2FG 13 +/* device quirks */ +#define WACOM_QUIRK_MULTI_INPUT 0x0001 + enum { PENPARTNER = 0, GRAPHIRE, @@ -79,6 +82,7 @@ struct wacom_features { int y_fuzz; int pressure_fuzz; int distance_fuzz; + unsigned quirks; }; struct wacom_shared { -- cgit v1.2.3-70-g09d2 From 3dc9f40de4dddf9147b80cf15be633189a2b70f4 Mon Sep 17 00:00:00 2001 From: Chris Bagwell Date: Sun, 12 Sep 2010 00:08:40 -0700 Subject: Input: wacom - request tablet data for Bamboo Pens Bamboo P&T need to use second form of usb_set_report() to ask to report tablet data. With previous addition of Bamboo Touch, BTN_TOOL_TRIPLETAP is now used for both TABLETPC2FG and BAMBOO_PT types. So reduced check to match type=TABLETPC2FG. This change shows redundant check for !TABLETPC2FG in else statement. Signed-off-by: Chris Bagwell Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index fc6fd53c1af..1e3af299a1c 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -319,8 +319,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat if (!rep_data) return error; - /* ask to report tablet data if it is 2FGT or not a Tablet PC */ - if (features->device_type == BTN_TOOL_TRIPLETAP) { + /* ask to report tablet data if it is 2FGT Tablet PC or + * not a Tablet PC */ + if (features->type == TABLETPC2FG) { do { rep_data[0] = 3; rep_data[1] = 4; @@ -332,7 +333,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat WAC_HID_FEATURE_REPORT, report_id, rep_data, 3); } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); - } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { + } else if (features->type != TABLETPC) { do { rep_data[0] = 2; rep_data[1] = 2; @@ -364,7 +365,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, features->pressure_fuzz = 0; features->distance_fuzz = 0; - /* only Tablet PCs need to retrieve the info */ + /* only Tablet PCs and Bamboo P&T need to retrieve the info */ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && (features->type != BAMBOO_PT)) goto out; -- cgit v1.2.3-70-g09d2 From f6cd378372bff06093d72f978c0150eeed3ea201 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Oct 2010 21:46:11 -0700 Subject: Input: wacom - fix runtime PM related deadlock When runtime PM is enabled by default for input devices, X hangs in wacom open: [] mutex_lock+0x1a/0x40 [] wacom_resume+0x3b/0x90 [wacom] [] usb_resume_interface+0xd2/0x190 [] usb_resume_both+0x6d/0x110 [] usb_runtime_resume+0x24/0x40 [] __pm_runtime_resume+0x26f/0x450 [] __pm_runtime_resume+0x1da/0x450 [] pm_runtime_resume+0x2a/0x50 [] usb_autopm_get_interface+0x26/0x60 [] wacom_open+0x36/0x90 [wacom] wacom_open() takes wacom->lock and calls usb_autopm_get_interface(), which in turn calls wacom_resume() which tries to acquire the lock again. The fix is to call usb_autopm_get_interface() first, before we take the lock. Since we do not do usb_autopm_put_interface() until wacom_close() is called runtime PM is effectively disabled for the driver, however changing it now would risk regressions so the complete fix will have to wait till the next merge window. Reported-by: Jiri Slaby Acked-by: Oliver Neukum Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 42ba3691d90..b35876ee690 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb) static int wacom_open(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + int retval = 0; - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); + if (usb_autopm_get_interface(wacom->intf) < 0) return -EIO; - } + + mutex_lock(&wacom->lock); if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; + retval = -EIO; + goto out; } wacom->open = true; wacom->intf->needs_remote_wakeup = 1; +out: mutex_unlock(&wacom->lock); - return 0; + if (retval) + usb_autopm_put_interface(wacom->intf); + return retval; } static void wacom_close(struct input_dev *dev) @@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev) wacom->open = false; wacom->intf->needs_remote_wakeup = 0; mutex_unlock(&wacom->lock); + + usb_autopm_put_interface(wacom->intf); } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, -- cgit v1.2.3-70-g09d2 From 62ecae09a01df507ef52e1bc90fc233a1978c60a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 10 Oct 2010 14:24:16 -0700 Subject: Input: wacom - properly enable runtime PM We need to always call usb_autopm_put_interface() in wacom_open(), not only when initialization fails, otherwise the device will be marked as PM-busy and will never be put in suspended state. Based on patch by Oliver Neukum. Acked-by: Oliver Neukum Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/input/tablet/wacom_sys.c') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 02de6535723..fc381498b79 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -120,14 +120,16 @@ static int wacom_open(struct input_dev *dev) out: mutex_unlock(&wacom->lock); - if (retval) - usb_autopm_put_interface(wacom->intf); + usb_autopm_put_interface(wacom->intf); return retval; } static void wacom_close(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + int autopm_error; + + autopm_error = usb_autopm_get_interface(wacom->intf); mutex_lock(&wacom->lock); usb_kill_urb(wacom->irq); @@ -135,7 +137,8 @@ static void wacom_close(struct input_dev *dev) wacom->intf->needs_remote_wakeup = 0; mutex_unlock(&wacom->lock); - usb_autopm_put_interface(wacom->intf); + if (!autopm_error) + usb_autopm_put_interface(wacom->intf); } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, -- cgit v1.2.3-70-g09d2