[PATCH] HID: wacom: Use correct report to query pen ID from INTUOSHT2 devices
Unlike other tablets which are compatible with the wacom_intuos_irq handler, INTUOSHT2 devices provide pen ID with report ID 8 instead of 5. To ensure wacom_intuos_schedule_prox_event works as intended for these tablets, we must be sure it uses the correct report ID in this case. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 6 +- drivers/hid/wacom_wac.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f706604..3aeddc2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -439,11 +439,15 @@ exit: static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + struct wacom_features *features = _wac->features; struct hid_report *r; struct hid_report_enum *re; re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); - r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; + if (features->type == INTUOSHT2) + r = re->report_id_hash[WACOM_REPORT_INTUOSHT2_ID]; + else + r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; if (r) { hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 3f60192..25baa7f 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -70,6 +70,7 @@ #define WACOM_REPORT_DEVICE_LIST 16 #define WACOM_REPORT_INTUOS_PEN16 #define WACOM_REPORT_REMOTE17 +#define WACOM_REPORT_INTUOSHT2_ID 8 /* device quirks */ #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] HID: wacom: bitwise vs logical ORs
On Wed, Dec 16, 2015 at 6:57 AM, Jiri Kosina <ji...@kernel.org> wrote: > On Wed, 9 Dec 2015, Dan Carpenter wrote: > >> Smatch complains that these should probably be bitwise ORs instead of >> logical. It doesn't matter for "prox" but it makes a difference for >> "strip1" and "strip2". >> >> Fixes: c7f0522a1ad1 ('HID: wacom: Slim down wacom_intuos_pad processing') >> Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com> > > Jason, could you please provide your Ack for this one? > > It's obviously a Correct Thing To Do(TM), but I assume you've tested on > your devices with this patch, so some other changes might potentially be > needed to "compensate" for the fix ... > > Thanks, > > -- > Jiri Kosina > SUSE Labs > This patch looks fine to me (the 'prox' calculation /should/ be logical, but I suppose bitwise works too :D). Found two other bugs from c7f0522 while reviewing though -- I'll have patches for you shortly. Reviewed-by: Jason Gerecke <jason.gere...@wacom.com> Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three,/ So you look at the sixty-fours -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] HID: wacom: Limit touchstrip data to 13 bits
Commit c7f0522 uses sixteen bits of data in the construction of 'strip1' and 'strip2'. This can cause problems in some cases, however, since some tablets store flags in the MSB of data[2] and data[4] that should not be included in these values. This restores the 0x1f mask that used prior to c7f0522. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 22d3225..cf87810 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -545,8 +545,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) ((data[6] & 0x0F) << 4) | (data[5] & 0x0F); } - strip1 = (data[1] << 8) | data[2]; - strip2 = (data[3] << 8) | data[4]; + strip1 = ((data[1] & 0x1f) << 8) | data[2]; + strip2 = ((data[3] & 0x1f) << 8) | data[4]; } prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] HID: wacom: Fix touchring value reporting
Commit c7f0522 reports incorrect touchring values to userspace. This is due to its incorrect handling of the 'touched' bit present in the 'ring1' and 'ring2' variables. Instead of using this bit when determining if a value should be sent, the ABS_WHEEL and ABS_INPUT check (different?!) portions of the position bits. Furthermore, the full values of 'ring1' and 'ring2' are reported to userspace, despite the 'touched' flag needing to be trimmed beforehand. This commit addresses both issues. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 94dffde..23212af 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -560,8 +560,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) input_report_abs(input, ABS_RX, strip1); input_report_abs(input, ABS_RY, strip2); - input_report_abs(input, ABS_WHEEL,ring1 & 0x7f ? ring1 : 0); - input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); + input_report_abs(input, ABS_WHEEL,(ring1 & 0x80) ? (ring1 & 0x7f) : 0); + input_report_abs(input, ABS_THROTTLE, (ring2 & 0x80) ? (ring2 & 0x7f) : 0); input_report_key(input, wacom->tool[1], prox ? 1 : 0); input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] HID: wacom: Fix pad button range for CINTIQ_COMPANION_2
Commit c7f0522 incorrectly constructs the 'buttons' variable for the CINTIQ_COMPANION_2 case. The high nybble of data[2] is shifted four bits too far, leaving the bits associated with BTN_7 through BTN_A unset. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 23212af..f706604 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -516,7 +516,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) * d-pad down -> data[4] & 0x80 * d-pad center -> data[3] & 0x01 */ - buttons = ((data[2] & 0xF0) << 7) | + buttons = ((data[2] >> 4) << 7) | ((data[1] & 0x04) << 6) | ((data[2] & 0x0F) << 2) | (data[1] & 0x03); -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] HID: wacom: Report 'strip2' values in ABS_RY
Commit c7f0522 accidentally used ABS_RX for reporting both 'strip1' and 'strip2', when the latter should actually be reported through ABS_RY. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index cf87810..94dffde 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -558,7 +558,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) input_report_key(input, KEY_PROG1 + i, keys & (1 << i)); input_report_abs(input, ABS_RX, strip1); - input_report_abs(input, ABS_RX, strip2); + input_report_abs(input, ABS_RY, strip2); input_report_abs(input, ABS_WHEEL,ring1 & 0x7f ? ring1 : 0); input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Apply lowres quirk to BAMBOO_TOUCH devices
When splitting the touch-only "BAMBOO_TOUCH" type out of the existing "BAMBOO_PT" type in 3b164a00, the lowres quirk was not updated so that it would continue to apply to these devices (effectively only the 0xD0). The absence of this quirk does not significantly impact usability, but is a correctness issue nonetheless. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 3953416..bec2300 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2421,7 +2421,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) features->quirks |= WACOM_QUIRK_BATTERY; /* quirk for bamboo touch with 2 low res touches */ - if (features->type == BAMBOO_PT && + if ((features->type == BAMBOO_PT || features->type == BAMBOO_TOUCH) && features->pktlen == WACOM_PKGLEN_BBTOUCH) { features->x_max <<= 5; features->y_max <<= 5; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] HID: wacom: Move Intuos pad handling code into dedicated function
Begin slimming down the body of 'wacom_intuos_irq' by moving out its largest block of code to a dedicated 'wacom_intuos_pad' function. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 482 +--- 1 file changed, 247 insertions(+), 235 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 8b29949..c611ea5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -446,6 +446,249 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) } } +static int wacom_intuos_pad(struct wacom_wac *wacom) +{ + struct wacom_features *features = >features; + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pad_input; + + /* pad packets. Works as a second tool and is always in prox */ + if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || + data[0] == WACOM_REPORT_CINTIQPAD)) + return 0; + + if (features->type >= INTUOS4S && features->type <= INTUOS4L) { + input_report_key(input, BTN_0, (data[2] & 0x01)); + input_report_key(input, BTN_1, (data[3] & 0x01)); + input_report_key(input, BTN_2, (data[3] & 0x02)); + input_report_key(input, BTN_3, (data[3] & 0x04)); + input_report_key(input, BTN_4, (data[3] & 0x08)); + input_report_key(input, BTN_5, (data[3] & 0x10)); + input_report_key(input, BTN_6, (data[3] & 0x20)); + if (data[1] & 0x80) { + input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); + } else { + /* Out of proximity, clear wheel value. */ + input_report_abs(input, ABS_WHEEL, 0); + } + if (features->type != INTUOS4S) { + input_report_key(input, BTN_7, (data[3] & 0x40)); + input_report_key(input, BTN_8, (data[3] & 0x80)); + } + if (data[1] | (data[2] & 0x01) | data[3]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == DTK) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + if (data[6] & 0x3f) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_13HD) { + input_report_key(input, BTN_0, (data[3] & 0x01)); + input_report_key(input, BTN_1, (data[4] & 0x01)); + input_report_key(input, BTN_2, (data[4] & 0x02)); + input_report_key(input, BTN_3, (data[4] & 0x04)); + input_report_key(input, BTN_4, (data[4] & 0x08)); + input_report_key(input, BTN_5, (data[4] & 0x10)); + input_report_key(input, BTN_6, (data[4] & 0x20)); + input_report_key(input, BTN_7, (data[4] & 0x40)); + input_report_key(input, BTN_8, (data[4] & 0x80)); + if ((data[3] & 0x01) | data[4]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_24HD) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + input_report_key(input, BTN_6, (data[6] & 0x40)); + input_report_key(input, BTN_7, (data[6] & 0x80)); + input_report_key(input, BTN_8, (data[8] & 0x01)); + input_report_key(input, BTN_9, (data[8] & 0x02)); + input_report_key(input, BTN_A, (data[8] & 0x04)); + input_report_key(input, BTN_B, (data[8] & 0x08)); + input_report_key(input, BTN_C, (d
[PATCH 4/7] HID: wacom: Replace magic masks and comparisons with switch cases
Reasoning through the conditions under which a particular block of code in 'wacom_intuos_general' will be reached is not at all easy due to the sheer number of magic masks and comparisons. Remove these and replace them with a switch statement over the various 'types' of packets that will be encountered. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 79 ++--- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e395688..a426cb2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -886,6 +886,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom) unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; + unsigned char type = (data[1] >> 1) & 0x0F; unsigned int t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && @@ -902,8 +903,12 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); } - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { + switch (type) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + /* general pen packet */ t = (data[6] << 2) | ((data[7] >> 6) & 3); if (features->pressure_max == 2047) { t = (t << 1) | (data[1] & 1); @@ -917,36 +922,40 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS, data[1] & 2); input_report_key(input, BTN_STYLUS2, data[1] & 4); input_report_key(input, BTN_TOUCH, t > 10); - } + break; - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { + case 0x0a: + case 0x0b: + /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(input, ABS_TILT_X, (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } + break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(input, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } + case 0x05: + case 0x07: + /* Rotation packet */ + if (features->type >= INTUOS3S) { + /* I3 marker pen rotation */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : + ((t-1) / 2 + 450)) : (450 - t / 2) ; + input_report_abs(input, ABS_Z, t); + } else { + /* 4D mouse rotation packet */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? + ((t - 1) / 2) : -t / 2); + } + break; - } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { + /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ + case 0x04: + case 0x06: + case 0x08: + if (features->type < INTUOS3S && type != 0x08) { /* 4D mouse packet */ input_report_key(input, BTN_LEFT, data[8] & 0x01);
[PATCH 7/7] HID: wacom: Rename wacom ID report ID macros
"INTUOSREAD" and "INTUOSWRITE" are poorly named. These are report IDs for pen ID (proximity) packets. It should be noted that the latter is only used on Intuos/Intuos2 for a second stylus when DualTrack is in use. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 6 +++--- drivers/hid/wacom_wac.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0008650..3953416 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -443,7 +443,7 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) struct hid_report_enum *re; re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); - r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; + r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; if (r) { hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); } @@ -1027,8 +1027,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) int result; if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && + data[0] != WACOM_REPORT_INTUOS_ID1 && + data[0] != WACOM_REPORT_INTUOS_ID2 && data[0] != WACOM_REPORT_INTUOSPAD && data[0] != WACOM_REPORT_INTUOS_PEN && data[0] != WACOM_REPORT_CINTIQ && diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 877c24a..3f60192 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -47,8 +47,8 @@ /* wacom data packet report IDs */ #define WACOM_REPORT_PENABLED 2 #define WACOM_REPORT_PENABLED_BT 3 -#define WACOM_REPORT_INTUOSREAD5 -#define WACOM_REPORT_INTUOSWRITE 6 +#define WACOM_REPORT_INTUOS_ID15 +#define WACOM_REPORT_INTUOS_ID26 #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_INTUOS5PAD3 #define WACOM_REPORT_DTUSPAD 21 -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] HID: wacom: Slim down wacom_intuos_pad processing
Seperate the function into two halves: first gather data from the packet, next report all gathered data. The input subsystem should automatically mute any events that aren't actually declared for the tablet at hand. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 277 +++- 1 file changed, 86 insertions(+), 191 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c611ea5..ec1e13e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -34,6 +34,9 @@ */ #define WACOM_CONTACT_AREA_SCALE 2607 +static void wacom_report_numbered_buttons(struct input_dev *input_dev, + int button_count, int mask); + /* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity. @@ -451,6 +454,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) struct wacom_features *features = >features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pad_input; + int i; + int buttons = 0, nbuttons = features->numbered_buttons; + int keys = 0, nkeys = 0; + int ring1 = 0, ring2 = 0; + int strip1 = 0, strip2 = 0; + bool prox = false; /* pad packets. Works as a second tool and is always in prox */ if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || @@ -458,72 +467,16 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) return 0; if (features->type >= INTUOS4S && features->type <= INTUOS4L) { - input_report_key(input, BTN_0, (data[2] & 0x01)); - input_report_key(input, BTN_1, (data[3] & 0x01)); - input_report_key(input, BTN_2, (data[3] & 0x02)); - input_report_key(input, BTN_3, (data[3] & 0x04)); - input_report_key(input, BTN_4, (data[3] & 0x08)); - input_report_key(input, BTN_5, (data[3] & 0x10)); - input_report_key(input, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - if (features->type != INTUOS4S) { - input_report_key(input, BTN_7, (data[3] & 0x40)); - input_report_key(input, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[3] << 1) | (data[2] & 0x01); + ring1 = data[1]; } else if (features->type == DTK) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = data[6]; } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == WACOM_24HD) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] &a
[PATCH 6/7] HID: wacom: Clean up value reading
Make the logic for reading X, Y, distance, and pressure a bit more clear. An additional bit was stuffed into the packet format many models back, and /most/ devices in use will use it. If we happen to be dealing with a particularly old tablet, just shift it off the end to pretend we never read it. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ce3afab..0008650 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -887,21 +887,23 @@ static int wacom_intuos_general(struct wacom_wac *wacom) struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned char type = (data[1] >> 1) & 0x0F; - unsigned int t; + unsigned int x, y, distance, t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && data[0] != WACOM_REPORT_INTUOS_PEN) return 0; - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + x = (be16_to_cpup((__be16 *)[2]) << 1) | ((data[9] >> 1) & 1); + y = (be16_to_cpup((__be16 *)[4]) << 1) | (data[9] & 1); + distance = data[9] >> 2; + if (features->type < INTUOS3S) { + x >>= 1; + y >>= 1; + distance >>= 1; } + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_abs(input, ABS_DISTANCE, distance); switch (type) { case 0x00: @@ -909,10 +911,9 @@ static int wacom_intuos_general(struct wacom_wac *wacom) case 0x02: case 0x03: /* general pen packet */ - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->pressure_max == 2047) { - t = (t << 1) | (data[1] & 1); - } + t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1); + if (features->pressure_max < 2047) + t >>= 1; input_report_abs(input, ABS_PRESSURE, t); if (features->type != INTUOSHT2) { input_report_abs(input, ABS_TILT_X, -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] HID: wacom: Further clean up wacom_intuos_general packet decoder
Continue re-organizing and trimming cases to make it easier to wrap the brain around. A number of changes were made after consulting the protocol spec and so don't necessarily follow from the code itself. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 87 +++-- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a426cb2..ce3afab 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -925,7 +925,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x0a: - case 0x0b: /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); @@ -935,7 +934,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x05: - case 0x07: /* Rotation packet */ if (features->type >= INTUOS3S) { /* I3 marker pen rotation */ @@ -944,61 +942,56 @@ static int wacom_intuos_general(struct wacom_wac *wacom) ((t-1) / 2 + 450)) : (450 - t / 2) ; input_report_abs(input, ABS_Z, t); } else { - /* 4D mouse rotation packet */ + /* 4D mouse 2nd packet */ t = (data[6] << 3) | ((data[7] >> 5) & 7); input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2); } break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ case 0x04: + /* 4D mouse 1st packet */ + input_report_key(input, BTN_LEFT, data[8] & 0x01); + input_report_key(input, BTN_MIDDLE, data[8] & 0x02); + input_report_key(input, BTN_RIGHT, data[8] & 0x04); + + input_report_key(input, BTN_SIDE, data[8] & 0x20); + input_report_key(input, BTN_EXTRA, data[8] & 0x10); + t = (data[6] << 2) | ((data[7] >> 6) & 3); + input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); + break; + case 0x06: - case 0x08: - if (features->type < INTUOS3S && type != 0x08) { - /* 4D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x01); - input_report_key(input, BTN_MIDDLE, data[8] & 0x02); - input_report_key(input, BTN_RIGHT, data[8] & 0x04); + /* I4 mouse */ + input_report_key(input, BTN_LEFT, data[6] & 0x01); + input_report_key(input, BTN_MIDDLE, data[6] & 0x02); + input_report_key(input, BTN_RIGHT, data[6] & 0x04); + input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) +- ((data[7] & 0x40) >> 6)); + input_report_key(input, BTN_SIDE, data[6] & 0x08); + input_report_key(input, BTN_EXTRA, data[6] & 0x10); - input_report_key(input, BTN_SIDE, data[8] & 0x20); - input_report_key(input, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - } - else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (features->type >= INTUOS4S && features->type <= INTUOSPL) { - input_report_key(input, BTN_LEFT, data[6] & 0x01); - input_report_key(input, BTN_MIDDLE, data[6] & 0x02); - input_report_key(input, BTN_RIGHT, data[6] & 0x04); - input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) -- ((data[7] & 0x40) >> 6)); - input_report_key(input, BTN_SIDE, data[6] & 0x08); - input_report_key(input, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(input, ABS_TILT_X, - (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); - input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } else { - /* 2D mouse
[PATCH 3/7] HID: wacom: Centralize Intuos pen packet decoding
Continue to slim down 'wacom_intuos_irq' by moving all decoding and reporting of pen packet data into the 'wacom_intuos_general' function. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 105 +--- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ec1e13e..e395688 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -880,13 +880,28 @@ static int wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } -static void wacom_intuos_general(struct wacom_wac *wacom) +static int wacom_intuos_general(struct wacom_wac *wacom) { struct wacom_features *features = >features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; + int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned int t; + if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && + data[0] != WACOM_REPORT_INTUOS_PEN) + return 0; + + if (features->type >= INTUOS3S) { + input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); + input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); + } else { + input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); + input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + } + /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); @@ -912,55 +927,6 @@ static void wacom_intuos_general(struct wacom_wac *wacom) (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); } -} - -static int wacom_intuos_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = >features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->pen_input; - unsigned int t; - int idx = 0, result; - - if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && - data[0] != WACOM_REPORT_INTUOSPAD && - data[0] != WACOM_REPORT_INTUOS_PEN && - data[0] != WACOM_REPORT_CINTIQ && - data[0] != WACOM_REPORT_CINTIQPAD && - data[0] != WACOM_REPORT_INTUOS5PAD) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); -return 0; - } - - /* tool number */ - if (features->type == INTUOS) - idx = data[1] & 0x01; - - /* process pad events */ - result = wacom_intuos_pad(wacom); - if (result) - return result; - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom); - if (result) -return result - 1; - - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom); /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { @@ -1036,7 +1002,44 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, wacom->tool[idx], 1); input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); wacom->reporting_data = true; - return 1; + return 2; +} + +static int wacom_intuos_irq(struct wacom_wac *wacom) +{ + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pen_input; + int result; + + if (data[0] != WACOM_REPORT_PENABLED && + dat
[PATCH v2] HID: wacom: Call 'wacom_query_tablet_data' only after 'hid_hw_start'
When connecting the Cintiq Companion 2 as an external tablet (i.e., using it in "hybrid" mode) it has been seen to cause the kernel of the machine it is connected to to Oops. The cause has been traced to us attempting to switch the tablet's mode prior to actually starting HID device (resulting in the eventual dereference of the uninitialized control URB). Commit 3b164a0 moved the mode switch from occuring post-start to occurring pre-start. The change was not seen to cause issues largely due to the fact that most devices mode switch with 'hid_hw_raw_request' (which is safe to call prior to start) rather than 'hid_hw_request'. Moving the call back to its original location resolves the issue, but causes some touch-only Bamboo tablets (e.g. 056a:00d0) to stop working. The affected tablets require us to perform a mode switch on their vestigial pen interface prior ignoring with -ENODEV, meaning that the code which is responsible for doing the ignoring has to move as well. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- Jiri, Ping clued me in to the fact that 'wacom_query_tablet_data' hasn't always been in this problematic location. The offending commit mentioned in the revised commit summary is queued for 4.4, so this only needs to get into the next RC rather than be targeted for stable. Jason drivers/hid/wacom_sys.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index abb7fdf..e06af5b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1778,24 +1778,6 @@ static int wacom_probe(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PEN; } - /* Note that if query fails it is not a hard failure */ - wacom_query_tablet_data(hdev, features); - - /* touch only Bamboo doesn't support pen */ - if ((features->type == BAMBOO_TOUCH) && - (features->device_type & WACOM_DEVICETYPE_PEN)) { - error = -ENODEV; - goto fail_shared_data; - } - - /* pen only Bamboo neither support touch nor pad */ - if ((features->type == BAMBOO_PEN) && - ((features->device_type & WACOM_DEVICETYPE_TOUCH) || - (features->device_type & WACOM_DEVICETYPE_PAD))) { - error = -ENODEV; - goto fail_shared_data; - } - wacom_calculate_res(features); wacom_update_name(wacom); @@ -1833,6 +1815,24 @@ static int wacom_probe(struct hid_device *hdev, goto fail_hw_start; } + /* Note that if query fails it is not a hard failure */ + wacom_query_tablet_data(hdev, features); + + /* touch only Bamboo doesn't support pen */ + if ((features->type == BAMBOO_TOUCH) && + (features->device_type & WACOM_DEVICETYPE_PEN)) { + error = -ENODEV; + goto fail_hw_start; + } + + /* pen only Bamboo neither support touch nor pad */ + if ((features->type == BAMBOO_PEN) && + ((features->device_type & WACOM_DEVICETYPE_TOUCH) || + (features->device_type & WACOM_DEVICETYPE_PAD))) { + error = -ENODEV; + goto fail_hw_start; + } + if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) error = hid_hw_open(hdev); -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] HID: wacom: Remove useless conditions from 'wacom_query_tablet_data'
When support for the Cintiq Companion Hybrid and Cintiq Companion 2 was added (36d3c51 and f7acb55), the 'wacom_query_tablet_data' function was updated to include references to CINTIQ_HYBRID and CINTIQ_COMPANION_2 with the thought that they were necessary to switch the touch interface into the proper mode. This is unnecessary, however, since those types are only ever associated with the pen interface -- the touch interfaces are either CINTIQ_24HDT or HID_GENERIC. To avoid confusion in the future, we remove the unnecessary CINTIQ_HYBRID and CINTIQ_COMPANION_2 conditions. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 45656e8..69ff5b5 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -422,7 +422,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); } - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID || features->type == CINTIQ_COMPANION_2) { + else if (features->type == WACOM_24HDT) { return wacom_set_device_mode(hdev, 18, 3, 2); } else if (features->type == WACOM_27QHDT) { -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] HID: wacom: Call 'wacom_query_tablet_data' only after 'hid_hw_start'
When connecting the Cintiq Companion 2 as an external tablet (i.e., using it in "hybrid" mode) it has been seen to cause the kernel of the machine it is connected to to Oops. The cause has been traced to us attempting to switch the tablet's mode prior to actually starting HID device (resulting in the eventual dereference of the uninitialized control URB). This has not been an issue in the past since we've historically used 'hid_hw_raw_request' to perform the mode switch. HID_GENERIC devices, however use 'hid_hw_request' which assumes that 'hid_hw_start' has already been called. That we've not encountered problems beforehand seems to be entirely due to luck. Since the timing of the mode switch is not critical, we can simply move it to occur after the call to 'hid_hw_start'. Alternately, we could have potentially modified 'wacom_hid_set_device_mode' to use 'hid_hw_raw_reqest'. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- Jiri, Please mark this for stable since it possible other HID_GENERIC devices may trigger this Oops as well. Thanks, Jason drivers/hid/wacom_sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index b4de325..45656e8 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1778,9 +1778,6 @@ static int wacom_probe(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PEN; } - /* Note that if query fails it is not a hard failure */ - wacom_query_tablet_data(hdev, features); - /* touch only Bamboo doesn't support pen */ if ((features->type == BAMBOO_TOUCH) && (features->device_type & WACOM_DEVICETYPE_PEN)) { @@ -1833,6 +1830,9 @@ static int wacom_probe(struct hid_device *hdev, goto fail_hw_start; } + /* Note that if query fails it is not a hard failure */ + wacom_query_tablet_data(hdev, features); + if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) error = hid_hw_open(hdev); -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] HID: wacom: Fix ABS_MISC reporting for Cintiq Companion 2
The pad handling code introduced for the Cintiq Companion 2 (f7acb55) looks at the wrong bytes in the report when deciding whether ABS_MISC should be sent. This does not cause any issues with the X driver now that the pen and pad have been split to separate devices, but is incorrect and has caused issues when backporting to distros with pre- 3.17 kernels. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 453da6d..9db6a8b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -966,7 +966,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ - if (data[4] | (data[3] & 0x01)) { + if (data[2] | (data[1] & 0x07)) { input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { input_report_abs(input, ABS_MISC, 0); -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Report full pressure range for Intuos, Cintiq 13HD Touch
The new Intuos tablets added in eda01da and the Cintiq 13HD Touch added in b4bf212 are capable of reporting 2048 levels of pressure. Although the kernel reports the correct range to userspace, an oversight has resulted in the driver ingoring the 11th pressure bit and only sending pressures of 0 through 1023. We could fix this issue by expanding the type check to include these devices, but it makes much more sense to just have the driver look at the device's maximum pressure when determining if it should read the 11th bit. Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e0b9320..ddee08d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -765,7 +765,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= CINTIQ_COMPANION_2) { + if (features->pressure_max == 2047) { t = (t << 1) | (data[1] & 1); } input_report_abs(input, ABS_PRESSURE, t); -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] HID: wacom: Add support for Cintiq Companion 2
Adds support for the EMR (pen+pad) and touchscreen devices used by the Wacom Cintiq Companion 2. This applies both to using the device as a standalone system, as well as when operating in "Cintiq mode" (where the EMR/touchscreen are simply exposed as USB devices to the system its connected to). Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> Signed-off-by: Clifford Jolly <expiredpopsi...@gmail.com> --- Changes from v2: * The switch in wacom_setup_pen_input_capabilities now only contains the first CINTIQ_COMPANION_2 case. The second case has been moved to the switch in wacom_setup_pad_input_capabilities where it belongs. * The second CINTIQ_COMPANION_2 case mentioned above no longer explicitly sets up the pad buttons since wacom_setup_numbered_buttons is now (70ee06c) in charge of this initialization. drivers/hid/wacom_sys.c | 2 +- drivers/hid/wacom_wac.c | 36 +++- drivers/hid/wacom_wac.h | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5f6e48e..2e7a1c7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -420,7 +420,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); } - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { + else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID || features->type == CINTIQ_COMPANION_2) { return wacom_set_device_mode(hdev, 18, 3, 2); } else if (features->type == WACOM_27QHDT) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 46bd02b..e0b9320 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -765,7 +765,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { + if (features->type >= INTUOS4S && features->type <= CINTIQ_COMPANION_2) { t = (t << 1) | (data[1] & 1); } input_report_abs(input, ABS_PRESSURE, t); @@ -948,6 +948,27 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) } else { input_report_abs(input, ABS_MISC, 0); } + + } else if (features->type == CINTIQ_COMPANION_2) { + input_report_key(input, BTN_1, (data[1] & 0x02)); + input_report_key(input, BTN_2, (data[2] & 0x01)); + input_report_key(input, BTN_3, (data[2] & 0x02)); + input_report_key(input, BTN_4, (data[2] & 0x04)); + input_report_key(input, BTN_5, (data[2] & 0x08)); + input_report_key(input, BTN_6, (data[1] & 0x04)); + + input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ + input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ + input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ + input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ + input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ + + if (data[4] | (data[3] & 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { int i; @@ -2290,6 +2311,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_27QHD: case DTK: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: sync = wacom_intuos_irq(wacom_wac); break; @@ -2543,6 +2565,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, case CINTIQ: case WACOM_13HD: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); @@ -2775,6 +2798,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, switch (features->type) { case CINTIQ_HYBRI
Re: [PATCH v2] HID: wacom: Add support for Cintiq Companion 2
10/11/2015 4:02 PM, Jiri Kosina wrote: > On Thu, 8 Oct 2015, Jason Gerecke wrote: > >> Adds support for the EMR (pen+pad) and touchscreen devices used by the >> Wacom Cintiq Companion 2. This applies both to using the device as a >> standalone system, as well as when operating in "Cintiq mode" (where >> the EMR/touchscreen are simply exposed as USB devices to the system >> its connected to). >> >> Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> >> Signed-off-by: Clifford Jolly <expiredpopsi...@gmail.com> > [ ... snip ... ] >> @@ -2290,6 +2311,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t >> len) >> case WACOM_27QHD: >> case DTK: >> case CINTIQ_HYBRID: >> +case CINTIQ_COMPANION_2: >> sync = wacom_intuos_irq(wacom_wac); >> break; > > This doesn't make any sense. You break here out after handling > CINTIQ_COMPANION_2 in features->type switch ... > >> >> @@ -2543,6 +2565,7 @@ int wacom_setup_pen_input_capabilities(struct >> input_dev *input_dev, >> case CINTIQ: >> case WACOM_13HD: >> case CINTIQ_HYBRID: >> +case CINTIQ_COMPANION_2: >> input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); >> input_abs_set_res(input_dev, ABS_Z, 287); >> __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); > > ... here you break out of the switch case a few lines below again. > > >> @@ -2595,6 +2618,12 @@ int wacom_setup_pen_input_capabilities(struct >> input_dev *input_dev, >> __clear_bit(ABS_MISC, input_dev->absbit); >> /* fall through */ >> >> +case CINTIQ_COMPANION_2: >> +for (i = 0; i < 10; i++) > > Where do you define this 'i'? > >> +__set_bit(BTN_0 + i, input_dev->keybit); >> +__set_bit(BTN_A, input_dev->keybit); >> +break; >> + > > And here you break out of the same case again explicitly again. > Looks like something went awry when migrating my patch from my branch in our local "input-wacom" tree to your upstream branch. Based on what's wrong, it looks like `patch` may have been confused by Aaron's recent changes to 'wacom_setup_pad_input_capabilities' (70ee06c) that weren't integrated into my local branch. I'll submit a fixed version shortly. Apologies for the noise. Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] HID: wacom: Add support for Cintiq Companion 2
Adds support for the EMR (pen+pad) and touchscreen devices used by the Wacom Cintiq Companion 2. This applies both to using the device as a standalone system, as well as when operating in "Cintiq mode" (where the EMR/touchscreen are simply exposed as USB devices to the system its connected to). Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> Signed-off-by: Clifford Jolly <expiredpopsi...@gmail.com> --- drivers/hid/wacom_sys.c | 2 +- drivers/hid/wacom_wac.c | 41 - drivers/hid/wacom_wac.h | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5f6e48e..2e7a1c7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -420,7 +420,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); } - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { + else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID || features->type == CINTIQ_COMPANION_2) { return wacom_set_device_mode(hdev, 18, 3, 2); } else if (features->type == WACOM_27QHDT) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 46bd02b..44d4cc3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -765,7 +765,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { + if (features->type >= INTUOS4S && features->type <= CINTIQ_COMPANION_2) { t = (t << 1) | (data[1] & 1); } input_report_abs(input, ABS_PRESSURE, t); @@ -948,6 +948,27 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) } else { input_report_abs(input, ABS_MISC, 0); } + + } else if (features->type == CINTIQ_COMPANION_2) { + input_report_key(input, BTN_1, (data[1] & 0x02)); + input_report_key(input, BTN_2, (data[2] & 0x01)); + input_report_key(input, BTN_3, (data[2] & 0x02)); + input_report_key(input, BTN_4, (data[2] & 0x04)); + input_report_key(input, BTN_5, (data[2] & 0x08)); + input_report_key(input, BTN_6, (data[1] & 0x04)); + + input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ + input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ + input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ + input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ + input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ + + if (data[4] | (data[3] & 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { int i; @@ -2290,6 +2311,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_27QHD: case DTK: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: sync = wacom_intuos_irq(wacom_wac); break; @@ -2543,6 +2565,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, case CINTIQ: case WACOM_13HD: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); @@ -2595,6 +2618,12 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, __clear_bit(ABS_MISC, input_dev->absbit); /* fall through */ + case CINTIQ_COMPANION_2: + for (i = 0; i < 10; i++) + __set_bit(BTN_0 + i, input_dev->keybit); + __set_bit(BTN_A, input_dev->keybit); + break; + case DTUS: case DTUSX: case PL: @@ -3347,6 +3376,14 @@ static const struct wacom_features wacom_features_0x318 = static const str
[PATCH 2/2] HID: wacom: Expect 'touch_max' touches if HID_DG_CONTACTCOUNT not present
When introduced in commit 1b5d514, the check 'if (hid_data->cc_index >= 0)' in 'wacom_wac_finger_pre_report' was intended to switch where the driver got the expected number of contacts from: HID_DG_CONTACTCOUNT if the usage was present, or 'touch_max' otherwise. Unfortunately, an oversight worthy of a brown paper bag (specifically, that 'cc_index' could never be negative) meant that the latter 'else' clause would never be entered. The patch prior to this one introduced a way for 'cc_index' to be negative, but only if HID_DG_CONTACTCOUNT is present in some report _other_ than the one being processed. To ensure the 'else' clause is also entered for devices which don't have HID_DG_CONTACTCOUNT on _any_ report, we add the additional constraint that 'cc_report' be non-zero (which is true only if the usage is present in some report). Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- Jiri, Could you please queue this patch and the prior for 4.3? They fix issues with the implementation of my "Ignore contacts in excess of declared contact count" patch which was pulled in as part of the 4.3 merge window. Thanks :) drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 4140b1d..46bd02b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1740,8 +1740,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, } } } - - if (hid_data->cc_index >= 0) { + if (hid_data->cc_report != 0 && + hid_data->cc_index >= 0) { struct hid_field *field = report->field[hid_data->cc_index]; int value = field->value[hid_data->cc_value_index]; if (value) -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] HID: wacom: Tie cached HID_DG_CONTACTCOUNT indices to report ID
The cached indicies 'cc_index' and 'cc_value_index' introduced in 1b5d514 are only valid for a single report ID. If a touchscreen has multiple reports with a HID_DG_CONTACTCOUNT usage, its possible that the values will not be correct for the report we're handling, resulting in an incorrect value for 'num_expected'. This has been observed with the Cintiq Companion 2. To address this, we store the ID of the report those indicies are valid for in a new 'cc_report' variable. Before using them to get the expected contact count, we first check if the ID of the report we're processing matches 'cc_report'. If it doesn't, we update the indicies to point to the HID_DG_CONTACTCOUNT usage of the current report (if it has one). Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> --- Jiri, Could you please queue this patch and the next for 4.3? They fix issues with the implementation of my "Ignore contacts in excess of declared contact count" patch which was pulled in as part of the 4.3 merge window. Thanks :) drivers/hid/wacom_wac.c | 26 ++ drivers/hid/wacom_wac.h | 1 + 2 files changed, 27 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c40a6d1..4140b1d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1628,6 +1628,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); break; case HID_DG_CONTACTCOUNT: + wacom_wac->hid_data.cc_report = field->report->id; wacom_wac->hid_data.cc_index = field->index; wacom_wac->hid_data.cc_value_index = usage->usage_index; break; @@ -1715,6 +1716,31 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, struct wacom_wac *wacom_wac = >wacom_wac; struct hid_data* hid_data = _wac->hid_data; + if (hid_data->cc_report != 0 && + hid_data->cc_report != report->id) { + int i; + + hid_data->cc_report = report->id; + hid_data->cc_index = -1; + hid_data->cc_value_index = -1; + + for (i = 0; i < report->maxfield; i++) { + struct hid_field *field = report->field[i]; + int j; + + for (j = 0; j < field->maxusage; j++) { + if (field->usage[j].hid == HID_DG_CONTACTCOUNT) { + hid_data->cc_index = i; + hid_data->cc_value_index = j; + + /* break */ + i = report->maxfield; + j = field->maxusage; + } + } + } + } + if (hid_data->cc_index >= 0) { struct hid_field *field = report->field[hid_data->cc_index]; int value = field->value[hid_data->cc_value_index]; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 1e270d4..809c03e 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -198,6 +198,7 @@ struct hid_data { int width; int height; int id; + int cc_report; int cc_index; int cc_value_index; int num_expected; -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Add support for Cintiq Companion 2
Signed-off-by: Jason Gerecke <jason.gere...@wacom.com> Signed-off-by: Clifford Jolly <expiredpopsi...@gmail.com> --- drivers/hid/wacom_sys.c | 2 +- drivers/hid/wacom_wac.c | 41 - drivers/hid/wacom_wac.h | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5f6e48e..2e7a1c7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -420,7 +420,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); } - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { + else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID || features->type == CINTIQ_COMPANION_2) { return wacom_set_device_mode(hdev, 18, 3, 2); } else if (features->type == WACOM_27QHDT) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 46bd02b..44d4cc3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -765,7 +765,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { + if (features->type >= INTUOS4S && features->type <= CINTIQ_COMPANION_2) { t = (t << 1) | (data[1] & 1); } input_report_abs(input, ABS_PRESSURE, t); @@ -948,6 +948,27 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) } else { input_report_abs(input, ABS_MISC, 0); } + + } else if (features->type == CINTIQ_COMPANION_2) { + input_report_key(input, BTN_1, (data[1] & 0x02)); + input_report_key(input, BTN_2, (data[2] & 0x01)); + input_report_key(input, BTN_3, (data[2] & 0x02)); + input_report_key(input, BTN_4, (data[2] & 0x04)); + input_report_key(input, BTN_5, (data[2] & 0x08)); + input_report_key(input, BTN_6, (data[1] & 0x04)); + + input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ + input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ + input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ + input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ + input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ + + if (data[4] | (data[3] & 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { int i; @@ -2290,6 +2311,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_27QHD: case DTK: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: sync = wacom_intuos_irq(wacom_wac); break; @@ -2543,6 +2565,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, case CINTIQ: case WACOM_13HD: case CINTIQ_HYBRID: + case CINTIQ_COMPANION_2: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); @@ -2595,6 +2618,12 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, __clear_bit(ABS_MISC, input_dev->absbit); /* fall through */ + case CINTIQ_COMPANION_2: + for (i = 0; i < 10; i++) + __set_bit(BTN_0 + i, input_dev->keybit); + __set_bit(BTN_A, input_dev->keybit); + break; + case DTUS: case DTUSX: case PL: @@ -3347,6 +3376,14 @@ static const struct wacom_features wacom_features_0x318 = static const struct wacom_features wacom_features_0x319 = { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */ .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; +static const struct wacom_features wacom_features_0x325 = + { "Wacom ISDv5 325", 59552, 33848, 2047, 63, +
[PATCH] HID: wacom: Use tablet-provided touch height/width values for INTUOSHT
The current generation of Intuos tablets (i.e. INTUOSHT) report touch width and height data just like the Intuos Pro do. This commit changes the code to allow these tablets to use the appropriate codepath instead of the one intended for Intuos5/Bamboo. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index fe164df..3024a3c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1772,7 +1772,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) int y = (data[3] 4) | (data[4] 0x0f); int width, height; - if (features-type = INTUOSPS features-type = INTUOSPL) { + if (features-type = INTUOSPS features-type = INTUOSHT) { width = data[5] * 100; height = data[6] * 100; } else { -- 2.5.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: wacom: Report correct device resolution when using the wireless adapater
On 8/10/2015 1:45 AM, Jiri Kosina wrote: On Wed, 5 Aug 2015, Jason Gerecke wrote: The 'wacom_wireless_work' function does not recalculate the tablet's resolution, causing the value contained in the 'features' struct to always be reported to userspace. This value is valid only for the pen interface, meaning that the value will be incorrect for the touchpad (if present). This in particular causes problems for libinput which relies on the reported resolution being correct. This patch adds the necessary calls to recalculate the resolution for each interface. This requires a little bit of code shuffling since both the 'wacom_set_default_phy' and 'wacom_calculate_res' are declared below their new first point of use in 'wacom_wireless_work'. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Jiri: Would it be possible to target this patch for 4.2? Just want to understand the context here -- is this a regression? If yes, since what version/commit? Thanks. This bug was exposed by an update to libinput which makes it more reliant on accurate resolution values. It is a regression in our code, but one which has gone unnoticed for quite some time. I've tracked its introduction to somewhere between 3.11 and 3.13, and having looked at the commits in that range believe that 401d7d1 (merged in 3.12) is likely the culprit. That commit replaced a function which calculated the resolution as part of the input device registration process with one that calculates it as part of the probe process after the HID descriptor is read (which doesn't do us any good in the wireless case). Fixing this in 4.2 ensures that this bug doesn't tickle libinput any longer than necessary. It would also be nice to backport this patch to stable, but I'm not sure if it quite meets the necessary severity standards. Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours drivers/hid/wacom_sys.c | 70 ++--- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4c0ffca..7e064b0 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1282,6 +1282,39 @@ fail_register_pen_input: return error; } +/* + * Not all devices report physical dimensions from HID. + * Compute the default from hardcoded logical dimension + * and resolution before driver overwrites them. + */ +static void wacom_set_default_phy(struct wacom_features *features) +{ +if (features-x_resolution) { +features-x_phy = (features-x_max * 100) / +features-x_resolution; +features-y_phy = (features-y_max * 100) / +features-y_resolution; +} +} + +static void wacom_calculate_res(struct wacom_features *features) +{ +/* set unit to 100th of a mm for devices not reported by HID */ +if (!features-unit) { +features-unit = 0x11; +features-unitExpo = -3; +} + +features-x_resolution = wacom_calc_hid_res(features-x_max, +features-x_phy, +features-unit, +features-unitExpo); +features-y_resolution = wacom_calc_hid_res(features-y_max, +features-y_phy, +features-unit, +features-unitExpo); +} + static void wacom_wireless_work(struct work_struct *work) { struct wacom *wacom = container_of(work, struct wacom, work); @@ -1339,6 +1372,8 @@ static void wacom_wireless_work(struct work_struct *work) if (wacom_wac1-features.type != INTUOSHT wacom_wac1-features.type != BAMBOO_PT) wacom_wac1-features.device_type |= WACOM_DEVICETYPE_PAD; +wacom_set_default_phy(wacom_wac1-features); +wacom_calculate_res(wacom_wac1-features); snprintf(wacom_wac1-pen_name, WACOM_NAME_MAX, %s (WL) Pen, wacom_wac1-features.name); snprintf(wacom_wac1-pad_name, WACOM_NAME_MAX, %s (WL) Pad, @@ -1357,7 +1392,9 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac2-features = *((struct wacom_features *)id-driver_data); wacom_wac2-features.pktlen = WACOM_PKGLEN_BBTOUCH3; +wacom_set_default_phy(wacom_wac2-features); wacom_wac2-features.x_max = wacom_wac2-features.y_max = 4096; +wacom_calculate_res(wacom_wac2-features); snprintf(wacom_wac2
[PATCH] HID: wacom: Report correct device resolution when using the wireless adapater
The 'wacom_wireless_work' function does not recalculate the tablet's resolution, causing the value contained in the 'features' struct to always be reported to userspace. This value is valid only for the pen interface, meaning that the value will be incorrect for the touchpad (if present). This in particular causes problems for libinput which relies on the reported resolution being correct. This patch adds the necessary calls to recalculate the resolution for each interface. This requires a little bit of code shuffling since both the 'wacom_set_default_phy' and 'wacom_calculate_res' are declared below their new first point of use in 'wacom_wireless_work'. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Jiri: Would it be possible to target this patch for 4.2? drivers/hid/wacom_sys.c | 70 ++--- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4c0ffca..7e064b0 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1282,6 +1282,39 @@ fail_register_pen_input: return error; } +/* + * Not all devices report physical dimensions from HID. + * Compute the default from hardcoded logical dimension + * and resolution before driver overwrites them. + */ +static void wacom_set_default_phy(struct wacom_features *features) +{ + if (features-x_resolution) { + features-x_phy = (features-x_max * 100) / + features-x_resolution; + features-y_phy = (features-y_max * 100) / + features-y_resolution; + } +} + +static void wacom_calculate_res(struct wacom_features *features) +{ + /* set unit to 100th of a mm for devices not reported by HID */ + if (!features-unit) { + features-unit = 0x11; + features-unitExpo = -3; + } + + features-x_resolution = wacom_calc_hid_res(features-x_max, + features-x_phy, + features-unit, + features-unitExpo); + features-y_resolution = wacom_calc_hid_res(features-y_max, + features-y_phy, + features-unit, + features-unitExpo); +} + static void wacom_wireless_work(struct work_struct *work) { struct wacom *wacom = container_of(work, struct wacom, work); @@ -1339,6 +1372,8 @@ static void wacom_wireless_work(struct work_struct *work) if (wacom_wac1-features.type != INTUOSHT wacom_wac1-features.type != BAMBOO_PT) wacom_wac1-features.device_type |= WACOM_DEVICETYPE_PAD; + wacom_set_default_phy(wacom_wac1-features); + wacom_calculate_res(wacom_wac1-features); snprintf(wacom_wac1-pen_name, WACOM_NAME_MAX, %s (WL) Pen, wacom_wac1-features.name); snprintf(wacom_wac1-pad_name, WACOM_NAME_MAX, %s (WL) Pad, @@ -1357,7 +1392,9 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac2-features = *((struct wacom_features *)id-driver_data); wacom_wac2-features.pktlen = WACOM_PKGLEN_BBTOUCH3; + wacom_set_default_phy(wacom_wac2-features); wacom_wac2-features.x_max = wacom_wac2-features.y_max = 4096; + wacom_calculate_res(wacom_wac2-features); snprintf(wacom_wac2-touch_name, WACOM_NAME_MAX, %s (WL) Finger,wacom_wac2-features.name); snprintf(wacom_wac2-pad_name, WACOM_NAME_MAX, @@ -1405,39 +1442,6 @@ void wacom_battery_work(struct work_struct *work) } } -/* - * Not all devices report physical dimensions from HID. - * Compute the default from hardcoded logical dimension - * and resolution before driver overwrites them. - */ -static void wacom_set_default_phy(struct wacom_features *features) -{ - if (features-x_resolution) { - features-x_phy = (features-x_max * 100) / - features-x_resolution; - features-y_phy = (features-y_max * 100) / - features-y_resolution; - } -} - -static void wacom_calculate_res(struct wacom_features *features) -{ - /* set unit to 100th of a mm for devices not reported by HID */ - if (!features-unit) { - features-unit = 0x11; - features-unitExpo = -3; - } - - features-x_resolution = wacom_calc_hid_res(features-x_max, - features-x_phy
[PATCH] HID: wacom: Do not repeatedly attempt to set device mode on error
As an extension of aef3156d7, there is no sense in repeatedly calling the 'wacom_set_report' and 'wacom_get_report' functions if they return an error. Getting an error from them implies that the device is out to lunch: either a hard error code was returned or repeated attempts at recovering from a soft error all failed. In either case, doing even more retries is not likely to resolve whatever is wrong. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 20d15c5..6edb7d1 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -335,7 +335,7 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id, if (error = 0) error = wacom_get_report(hdev, HID_FEATURE_REPORT, rep_data, length, 1); - } while ((error 0 || rep_data[1] != mode) limit++ WAC_MSG_RETRIES); + } while (error = 0 rep_data[1] != mode limit++ WAC_MSG_RETRIES); kfree(rep_data); -- 2.5.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Simplify 'wacom_pl_irq'
Unlike other IRQ functions, 'wacom_pl_irq' uses the second element of the 'tool' array to store information about its single pen. This makes the function more difficult to understand (since it doesn't follow the general pattern of other IRQ functions) and prevents the possibility of refactoring how pen state is stored. This patch rewrites 'wacom_pl_irq' to follow the usual IRQ conventions, including storing tool type in 'tool[0]' and implicitly tracking prox with the 'id[0]' variable. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 84 + 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 4d11c78..fe164df 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -125,61 +125,47 @@ static int wacom_pl_irq(struct wacom_wac *wacom) prox = data[1] 0x40; - if (prox) { - wacom-id[0] = ERASER_DEVICE_ID; - pressure = (signed char)((data[7] 1) | ((data[4] 2) 1)); - if (features-pressure_max 255) - pressure = (pressure 1) | ((data[4] 6) 1); - pressure += (features-pressure_max + 1) / 2; - - /* -* if going from out of proximity into proximity select between the eraser -* and the pen based on the state of the stylus2 button, choose eraser if -* pressed else choose pen. if not a proximity change from out to in, send -* an out of proximity for previous tool then a in for new tool. -*/ - if (!wacom-tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] 0x10) - wacom-tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom-tool[1] = (data[4] 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } else { - /* was entered with stylus2 pressed */ - if (wacom-tool[1] == BTN_TOOL_RUBBER !(data[4] 0x20)) { - /* report out proximity for previous tool */ - input_report_key(input, wacom-tool[1], 0); - input_sync(input); - wacom-tool[1] = BTN_TOOL_PEN; - return 0; - } + if (!wacom-id[0]) { + if ((data[0] 0x10) || (data[4] 0x20)) { + wacom-tool[0] = BTN_TOOL_RUBBER; + wacom-id[0] = ERASER_DEVICE_ID; } - if (wacom-tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom-tool[1] = BTN_TOOL_PEN; + else { + wacom-tool[0] = BTN_TOOL_PEN; wacom-id[0] = STYLUS_DEVICE_ID; } - input_report_key(input, wacom-tool[1], prox); /* report in proximity for tool */ - input_report_abs(input, ABS_MISC, wacom-id[0]); /* report tool id */ - input_report_abs(input, ABS_X, data[3] | (data[2] 7) | ((data[1] 0x03) 14)); - input_report_abs(input, ABS_Y, data[6] | (data[5] 7) | ((data[4] 0x03) 14)); - input_report_abs(input, ABS_PRESSURE, pressure); + } - input_report_key(input, BTN_TOUCH, data[4] 0x08); - input_report_key(input, BTN_STYLUS, data[4] 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - input_report_key(input, BTN_STYLUS2, (wacom-tool[1] == BTN_TOOL_PEN) (data[4] 0x20)); - } else { - /* report proximity-out of a (valid) tool */ - if (wacom-tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom-tool[1] = BTN_TOOL_PEN; - } - input_report_key(input, wacom-tool[1], prox); + /* If the eraser is in prox, STYLUS2 is always set. If we +* mis-detected the type and notice that STYLUS2 isn't set +* then force the eraser out of prox and let the pen in. +*/ + if (wacom-tool[0] == BTN_TOOL_RUBBER !(data[4] 0x20)) { + input_report_key(input, BTN_TOOL_RUBBER, 0); + input_report_abs(input, ABS_MISC, 0); + input_sync(input); + wacom-tool[0] = BTN_TOOL_PEN; + wacom-id[0] = STYLUS_DEVICE_ID; } - wacom-tool[0] = prox; /* Save proximity state */ + pressure = (signed char)((data[7] 1) | ((data[4] 2) 1)); + if (features-pressure_max 255) + pressure = (pressure 1) | ((data[4] 6) 1
[PATCH 1/3] HID: wacom: Use calculated pkglen for wireless touch interface
Commit 01c846f introduced the 'wacom_compute_pktlen' function which automatically determines the correct value for an interface's pkglen by scanning the HID descriptor. This function returns the correct value for the wireless receiver's touch interface, removing the need for us to set it manually here. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index d932349..a334332 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -457,7 +457,6 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, features-device_type = WACOM_DEVICETYPE_NONE; } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { features-device_type |= WACOM_DEVICETYPE_TOUCH; - features-pktlen = WACOM_PKGLEN_BBTOUCH3; } } -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] HID: wacom: Replace WACOM_QUIRK_MONITOR with WACOM_DEVICETYPE_WL_MONITOR
The monitor interface on the wireless receiver is more logically expressed as a type of device instead of a quirk. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 6 +++--- drivers/hid/wacom_wac.c | 4 +--- drivers/hid/wacom_wac.h | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a334332..13834ba 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -454,7 +454,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, */ if (features-type == WIRELESS) { if (intf-cur_altsetting-desc.bInterfaceNumber == 0) { - features-device_type = WACOM_DEVICETYPE_NONE; + features-device_type = WACOM_DEVICETYPE_WL_MONITOR; } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { features-device_type |= WACOM_DEVICETYPE_TOUCH; } @@ -1581,7 +1581,7 @@ static int wacom_probe(struct hid_device *hdev, if (error) goto fail_shared_data; - if (!(features-quirks WACOM_QUIRK_MONITOR) + if (!(features-device_type WACOM_DEVICETYPE_WL_MONITOR) (features-quirks WACOM_QUIRK_BATTERY)) { error = wacom_initialize_battery(wacom); if (error) @@ -1615,7 +1615,7 @@ static int wacom_probe(struct hid_device *hdev, /* Note that if query fails it is not a hard failure */ wacom_query_tablet_data(hdev, features); - if (features-quirks WACOM_QUIRK_MONITOR) + if (features-device_type WACOM_DEVICETYPE_WL_MONITOR) error = hid_hw_open(hdev); if (wacom_wac-features.type == INTUOSHT diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 280deb2..82bb0d3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2330,9 +2330,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) /* 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 == WACOM_DEVICETYPE_NONE) { - features-quirks |= WACOM_QUIRK_MONITOR; + if (features-device_type == WACOM_DEVICETYPE_WL_MONITOR) { features-quirks |= WACOM_QUIRK_BATTERY; } } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index c245a66..87df674 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -69,7 +69,6 @@ /* device quirks */ #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 #define WACOM_QUIRK_NO_INPUT 0x0002 -#define WACOM_QUIRK_MONITOR0x0004 #define WACOM_QUIRK_BATTERY0x0008 /* device types */ @@ -77,6 +76,7 @@ #define WACOM_DEVICETYPE_PEN0x0001 #define WACOM_DEVICETYPE_TOUCH 0x0002 #define WACOM_DEVICETYPE_PAD0x0004 +#define WACOM_DEVICETYPE_WL_MONITOR 0x0008 #define WACOM_VENDORDEFINED_PEN0xff0d0001 -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] HID: wacom: Remove WACOM_QUIRK_NO_INPUT
WACOM_QUIRK_NO_INPUT is a signal to the driver that input devices should not be created for a particular device. This quirk was used by the wireless receiver to prevent any devices from being created during the initial probe (defering it instead until we got a tablet connection event in 'wacom_wireless_work'). This quirk is not necessary now that a device_type is associated with each device. Any input device allocated by 'wacom_allocate_inputs' which is not necessary for a particular device is freed in 'wacom_register_inputs'. In particular, none of the wireless receivers devices have the pen, pad, or touch device types set so the same effect is achieved without the need to be explicit. We now return early in wacom_retrieve_hid_descriptor for wireless devices (to prevent the device_type from being overridden) but since we ignore the HID descriptor for the wireless reciever anyway, this is not an issue. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 24 ++-- drivers/hid/wacom_wac.c | 4 drivers/hid/wacom_wac.h | 1 - 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 13834ba..20d15c5 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -453,11 +453,11 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, * interface number. */ if (features-type == WIRELESS) { - if (intf-cur_altsetting-desc.bInterfaceNumber == 0) { + if (intf-cur_altsetting-desc.bInterfaceNumber == 0) features-device_type = WACOM_DEVICETYPE_WL_MONITOR; - } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { - features-device_type |= WACOM_DEVICETYPE_TOUCH; - } + else + features-device_type = WACOM_DEVICETYPE_NONE; + return; } wacom_parse_hid(hdev, features); @@ -1531,11 +1531,9 @@ static int wacom_probe(struct hid_device *hdev, mutex_init(wacom-lock); INIT_WORK(wacom-work, wacom_wireless_work); - if (!(features-quirks WACOM_QUIRK_NO_INPUT)) { - error = wacom_allocate_inputs(wacom); - if (error) - goto fail_allocate_inputs; - } + error = wacom_allocate_inputs(wacom); + if (error) + goto fail_allocate_inputs; /* * Bamboo Pad has a generic hid handling for the Pen, and we switch it @@ -1588,11 +1586,9 @@ static int wacom_probe(struct hid_device *hdev, goto fail_battery; } - if (!(features-quirks WACOM_QUIRK_NO_INPUT)) { - error = wacom_register_inputs(wacom); - if (error) - goto fail_register_inputs; - } + error = wacom_register_inputs(wacom); + if (error) + goto fail_register_inputs; if (hdev-bus == BUS_BLUETOOTH) { error = device_create_file(hdev-dev, dev_attr_speed); diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 82bb0d3..4d11c78 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2326,10 +2326,6 @@ void wacom_setup_device_quirks(struct wacom *wacom) } if (features-type == WIRELESS) { - - /* monitor never has input and pen/touch have delayed create */ - features-quirks |= WACOM_QUIRK_NO_INPUT; - if (features-device_type == WACOM_DEVICETYPE_WL_MONITOR) { features-quirks |= WACOM_QUIRK_BATTERY; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 87df674..6233eea 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -68,7 +68,6 @@ /* device quirks */ #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 -#define WACOM_QUIRK_NO_INPUT 0x0002 #define WACOM_QUIRK_BATTERY0x0008 /* device types */ -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] HID: wacom: Ignore contacts in excess of declared contact count
The reports sent from some touch devices (e.g. the Cintiq 24HDT) contain junk data in the contact slots which follow the final valid contact. To avoid forwarding it to usrspace, we store the reported contact count during the pre-process phase and then only process that many contacts. If a device sends its contacts across multiple reports (what Microsoft refers to as hybrid mode) then the contact count will be zero for reports other than the first. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 30 +- drivers/hid/wacom_wac.h | 4 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1d9d5d1..09fe5d6 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1510,6 +1510,10 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, features-last_slot_field = usage-hid; wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); break; + case HID_DG_CONTACTCOUNT: + wacom_wac-hid_data.cc_index = field-index; + wacom_wac-hid_data.cc_value_index = usage-usage_index; + break; } } @@ -1521,6 +1525,10 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, bool prox = hid_data-tipswitch !wacom_wac-shared-stylus_in_proximity; + wacom_wac-hid_data.num_received++; + if (wacom_wac-hid_data.num_received wacom_wac-hid_data.num_expected) + return; + if (mt) { int slot; @@ -1573,7 +1581,19 @@ static int wacom_wac_finger_event(struct hid_device *hdev, static void wacom_wac_finger_pre_report(struct hid_device *hdev, struct hid_report *report) { - return; + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct hid_data* hid_data = wacom_wac-hid_data; + + if (hid_data-cc_index = 0) { + struct hid_field *field = report-field[hid_data-cc_index]; + int value = field-value[hid_data-cc_value_index]; + if (value) + hid_data-num_expected = value; + } + else { + hid_data-num_expected = wacom_wac-features.touch_max; + } } static void wacom_wac_finger_report(struct hid_device *hdev, @@ -1584,10 +1604,18 @@ static void wacom_wac_finger_report(struct hid_device *hdev, struct input_dev *input = wacom_wac-touch_input; unsigned touch_max = wacom_wac-features.touch_max; + /* If more packets of data are expected, give us a chance to +* process them rather than immediately syncing a partial +* update. +*/ + if (wacom_wac-hid_data.num_received wacom_wac-hid_data.num_expected) + return; + if (touch_max 1) input_mt_sync_frame(input); input_sync(input); + wacom_wac-hid_data.num_received = 0; /* keep touch state for pen event */ wacom_wac-shared-touch_down = wacom_wac_finger_count_touches(wacom_wac); diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 2978c30..c245a66 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -193,6 +193,10 @@ struct hid_data { int width; int height; int id; + int cc_index; + int cc_value_index; + int num_expected; + int num_received; }; struct wacom_wac { -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] HID: wacom: Report touch width/height/orientation for GENERIC devices
The HID_DG_WIDTH and HID_DG_HEIGHT usages report with width and height of contacts. From this information, a crude determination of orientation is also possible. This patch reports all three to userspace if a device reports this usage. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 09fe5d6..280deb2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1497,6 +1497,13 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_POSITION_Y, 4); break; + case HID_DG_WIDTH: + case HID_DG_HEIGHT: + features-last_slot_field = usage-hid; + wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MAJOR, 0); + wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MINOR, 0); + input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); + break; case HID_DG_CONTACTID: features-last_slot_field = usage-hid; break; @@ -1545,6 +1552,13 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, hid_data-x); input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, hid_data-y); + + if (test_bit(ABS_MT_TOUCH_MAJOR, input-absbit)) { + input_report_abs(input, ABS_MT_TOUCH_MAJOR, max(hid_data-width, hid_data-height)); + input_report_abs(input, ABS_MT_TOUCH_MINOR, min(hid_data-width, hid_data-height)); + if (hid_data-width != hid_data-height) + input_report_abs(input, ABS_MT_ORIENTATION, hid_data-width = hid_data-height ? 0 : 1); + } } } @@ -1561,6 +1575,12 @@ static int wacom_wac_finger_event(struct hid_device *hdev, case HID_GD_Y: wacom_wac-hid_data.y = value; break; + case HID_DG_WIDTH: + wacom_wac-hid_data.width = value; + break; + case HID_DG_HEIGHT: + wacom_wac-hid_data.height = value; + break; case HID_DG_CONTACTID: wacom_wac-hid_data.id = value; break; -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] HID: wacom: Perform all event processing as part of report processing
In some cases, we need access to information before it becomes available to the 'event' handler. In particular, for some devices we cannot properly process the finger data without first knowing the contact count at the very end of the report (e.g. the Cintiq 24HDT touch screen, when forced through the GENERIC codepath). Since the HID subsystem doesn't provide a way to take action before 'event' is called, we take a cue from hid-multitouch.c and add a pre-process step within the 'report' handler that performs the same function. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 1 - drivers/hid/wacom_wac.c | 39 +++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 2a22163..d932349 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1690,7 +1690,6 @@ static struct hid_driver wacom_driver = { .id_table = wacom_ids, .probe =wacom_probe, .remove = wacom_remove, - .event =wacom_wac_event, .report = wacom_wac_report, #ifdef CONFIG_PM .resume = wacom_resume, diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f5a0d3c..1d9d5d1 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1437,6 +1437,12 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, return 0; } +static void wacom_wac_pen_pre_report(struct hid_device *hdev, + struct hid_report *report) +{ + return; +} + static void wacom_wac_pen_report(struct hid_device *hdev, struct hid_report *report) { @@ -1564,6 +1570,12 @@ static int wacom_wac_finger_event(struct hid_device *hdev, return 0; } +static void wacom_wac_finger_pre_report(struct hid_device *hdev, + struct hid_report *report) +{ + return; +} + static void wacom_wac_finger_report(struct hid_device *hdev, struct hid_report *report) { @@ -1615,6 +1627,25 @@ int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, return 0; } +static void wacom_report_events(struct hid_device *hdev, struct hid_report *report) +{ + int r; + + for (r = 0; r report-maxfield; r++) { + struct hid_field *field; + unsigned count, n; + + field = report-field[r]; + count = field-report_count; + + if (!(HID_MAIN_ITEM_VARIABLE field-flags)) + continue; + + for (n = 0; n count; n++) + wacom_wac_event(hdev, field, field-usage[n], field-value[n]); + } +} + void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) { struct wacom *wacom = hid_get_drvdata(hdev); @@ -1625,6 +1656,14 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) return; if (WACOM_PEN_FIELD(field)) + wacom_wac_pen_pre_report(hdev, report); + + if (WACOM_FINGER_FIELD(field)) + wacom_wac_finger_pre_report(hdev, report); + + wacom_report_events(hdev, report); + + if (WACOM_PEN_FIELD(field)) return wacom_wac_pen_report(hdev, report); if (WACOM_FINGER_FIELD(field)) -- 2.4.6 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] HID: wacom: Properly free inputs if 'wacom_allocate_inputs' fails
The 'wacom_allocate_inputs' function tries to allocate three input devices: one each for the pen, touch, and pad. The pointers that are returned by the 'wacom_allocate_input' calls are temporarily stored to local variables where they are checked to ensure they're non-null before storing them in the 'wacom_wac' structure. If an allocation fails, the 'wacom_free_inputs' function is called to reclaim the memory. Unfortunately, 'wacom_free_inputs' is called prior to the pointers being copied, so it is not actually able to free anything. This patch has the calls to 'wacom_allocate_input' store the pointer directly in the 'wacom_wac' structure where they can be freed. Also, it replaces the call to 'wacom_free_inputs' with the (more general) 'wacom_clean_inputs' and removes the no-longer-used function. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Jiri, This patch should cleanly apply to either your 'for-4.3/wacom' or 'for-4.2/upstream-fixes' branch. It conflicts with 'for-4.3/upstream' where Markus' Delete unnecessary checks patch (67e123f) resides. I can provide a patch which applies cleanly to that branch instead if you would like. The conflict is due to his patch modifying the 'wacom_free_inputs' function; this patch removes the function entirely though so the conflict shouldn't be too difficult to resolve. Jason drivers/hid/wacom_sys.c | 55 - 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4c0ffca..3512d83 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1145,43 +1145,6 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) return input_dev; } -static void wacom_free_inputs(struct wacom *wacom) -{ - struct wacom_wac *wacom_wac = (wacom-wacom_wac); - - if (wacom_wac-pen_input) - input_free_device(wacom_wac-pen_input); - if (wacom_wac-touch_input) - input_free_device(wacom_wac-touch_input); - if (wacom_wac-pad_input) - input_free_device(wacom_wac-pad_input); - wacom_wac-pen_input = NULL; - wacom_wac-touch_input = NULL; - wacom_wac-pad_input = NULL; -} - -static int wacom_allocate_inputs(struct wacom *wacom) -{ - struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; - struct wacom_wac *wacom_wac = (wacom-wacom_wac); - - pen_input_dev = wacom_allocate_input(wacom); - touch_input_dev = wacom_allocate_input(wacom); - pad_input_dev = wacom_allocate_input(wacom); - if (!pen_input_dev || !touch_input_dev || !pad_input_dev) { - wacom_free_inputs(wacom); - return -ENOMEM; - } - - wacom_wac-pen_input = pen_input_dev; - wacom_wac-touch_input = touch_input_dev; - wacom_wac-touch_input-name = wacom_wac-touch_name; - wacom_wac-pad_input = pad_input_dev; - wacom_wac-pad_input-name = wacom_wac-pad_name; - - return 0; -} - static void wacom_clean_inputs(struct wacom *wacom) { if (wacom-wacom_wac.pen_input) { @@ -1208,6 +1171,24 @@ static void wacom_clean_inputs(struct wacom *wacom) wacom_destroy_leds(wacom); } +static int wacom_allocate_inputs(struct wacom *wacom) +{ + struct wacom_wac *wacom_wac = (wacom-wacom_wac); + + wacom_wac-pen_input = wacom_allocate_input(wacom); + wacom_wac-touch_input = wacom_allocate_input(wacom); + wacom_wac-pad_input = wacom_allocate_input(wacom); + if (!wacom_wac-pen_input || !wacom_wac-touch_input || !wacom_wac-pad_input) { + wacom_clean_inputs(wacom); + return -ENOMEM; + } + + wacom_wac-touch_input-name = wacom_wac-touch_name; + wacom_wac-pad_input-name = wacom_wac-pad_name; + + return 0; +} + static int wacom_register_inputs(struct wacom *wacom) { struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; -- 2.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] HID: wacom: Set default device name to value from wacom-features
Allocated input devices should not use the 'pen_name' by default since we do not know at that point in time if that is an appropriate choice of name. Instead, use the (tool-agnostic) name that is stored in the device's 'wacom_features' structure. This also has the nice side-effect of requring us to be explicit about the naming of the pen device, as we already are for touch and pad devices. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 3512d83..2a22163 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1130,7 +1130,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) if (!input_dev) return NULL; - input_dev-name = wacom_wac-pen_name; + input_dev-name = wacom_wac-features.name; input_dev-phys = hdev-phys; input_dev-dev.parent = hdev-dev; input_dev-open = wacom_open; @@ -1183,6 +1183,7 @@ static int wacom_allocate_inputs(struct wacom *wacom) return -ENOMEM; } + wacom_wac-pen_input-name = wacom_wac-pen_name; wacom_wac-touch_input-name = wacom_wac-touch_name; wacom_wac-pad_input-name = wacom_wac-pad_name; -- 2.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Enable pad device for older Bamboo Touch tablets
Commit 862cf55 neglected to set the WACOM_DEVICETYPE_PAD flag for older two-finger Bamboo Touch tablets. Not only does this result in the pad device not appearing when such a tablet is plugged in, but also causes a segfault when 'wacom_bpt_touch' tries to send pad events. This patch adds the flag to resolve these issues. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 232da89..0d24423 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2213,6 +2213,9 @@ void wacom_setup_device_quirks(struct wacom *wacom) features-x_max = 4096; features-y_max = 4096; } + else if (features-pktlen == WACOM_PKGLEN_BBTOUCH) { + features-device_type |= WACOM_DEVICETYPE_PAD; + } } /* -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] HID: wacom: NULL dereferences on error in probe()
On 6/24/2015 7:27 AM, Dan Carpenter wrote: We can't pass a NULL to input_unregister_device(). Fixes: 2a6cdbdd4cc0 ('HID: wacom: Introduce new 'touch_input' device') Signed-off-by: Dan Carpenter dan.carpen...@oracle.com Looks reasonable to me. Reviewed-by: Jason Gerecke jason.gere...@wacom.com -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4c0ffca..44958d7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1271,11 +1271,13 @@ fail_leds: pad_input_dev = NULL; wacom_wac-pad_registered = false; fail_register_pad_input: - input_unregister_device(touch_input_dev); + if (touch_input_dev) + input_unregister_device(touch_input_dev); wacom_wac-touch_input = NULL; wacom_wac-touch_registered = false; fail_register_touch_input: - input_unregister_device(pen_input_dev); + if (pen_input_dev) + input_unregister_device(pen_input_dev); wacom_wac-pen_input = NULL; wacom_wac-pen_registered = false; fail_register_pen_input: -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: wacom: remove the extra Pen interface for Wacom Bamboo PAD
On 6/18/2015 12:58 PM, Benjamin Tissoires wrote: As mentioned in the comment in the code, both the pen and touch data come from the interface tagged as BAMBOO_PAD. The driver re-routes the events for the Pen to the generic HID interface and keeps the ones for the touch through this current interface. Clearing the WACOM_DEVICETYPE_PEN bit removes the extra unused interface and makes the Bamboo PAD to behave like in 4.1. Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com --- Hi, well, the fix was definitively easy to restore the Bamboo PAD interface. Thanks Jason for the good cleanup and sorry for not having the time to review the previous series. Cheers, Benjamin drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 232da89..d260528 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2223,7 +2223,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) * so rewrite this one to be of type BTN_TOOL_FINGER. Nit: Looks like I forgot to update this comment to say WACOM_DEVICETYPE_TOUCH. Mind fixing that in this patch since you're here anyway? Otherwise, looks good :) Reviewed-by: Jason Gerecke jason.gere...@wacom.com -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours */ if (features-type == BAMBOO_PAD) - features-device_type |= WACOM_DEVICETYPE_TOUCH; + features-device_type = WACOM_DEVICETYPE_TOUCH; if (wacom-hdev-bus == BUS_BLUETOOTH) features-quirks |= WACOM_QUIRK_BATTERY; -- To unsubscribe from this list: send the line unsubscribe linux-input in
[PATCH v2 2/5] HID: wacom: Treat features-device_type values as flags
The USB devices that this driver has historically supported segregate the pen and touch portions of the tablet. Oftentimes the segregation would be done at the interface level, though on occasion (e.g. Cintiq 24HDT) the tablet would combine two totally independent USB devices behind an internal USB hub. Because pen and touch never shared the same interface, it made sense for the 'device_type' to store a single value: pen or touch. Recently, however, some I2C devices have been created which combine the two. A first step to accomodating this is to expand 'device_type' so that it can represent two (or potentially more) types simultaneously. To do this, we treat it as a bitfield and set/check individual bits rather than using the '=' and '==' operators. This should not result in any functional change since no supported devices (that I'm aware of, at least) have HID descriptors that indicate both pen and touch reports on a single interface. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- No changes from v1. drivers/hid/wacom_sys.c | 35 ++- drivers/hid/wacom_wac.c | 30 +++--- drivers/hid/wacom_wac.h | 5 + 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index bdf31c9..2b4cbd8 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -197,9 +197,9 @@ static void wacom_usage_mapping(struct hid_device *hdev, * values commonly reported. */ if (pen) - features-device_type = BTN_TOOL_PEN; + features-device_type |= WACOM_DEVICETYPE_PEN; else if (finger) - features-device_type = BTN_TOOL_FINGER; + features-device_type |= WACOM_DEVICETYPE_TOUCH; else return; @@ -411,7 +411,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, if (features-type == HID_GENERIC) return wacom_hid_set_device_mode(hdev); - if (features-device_type == BTN_TOOL_FINGER) { + if (features-device_type WACOM_DEVICETYPE_TOUCH) { if (features-type TABLETPC) { /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); @@ -425,7 +425,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, else if (features-type == BAMBOO_PAD) { return wacom_set_device_mode(hdev, 2, 2, 2); } - } else if (features-device_type == BTN_TOOL_PEN) { + } else if (features-device_type WACOM_DEVICETYPE_PEN) { if (features-type = BAMBOO_PT features-type != WIRELESS) { return wacom_set_device_mode(hdev, 2, 2, 2); } @@ -454,9 +454,9 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, */ if (features-type == WIRELESS) { if (intf-cur_altsetting-desc.bInterfaceNumber == 0) { - features-device_type = 0; + features-device_type = WACOM_DEVICETYPE_NONE; } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { - features-device_type = BTN_TOOL_FINGER; + features-device_type |= WACOM_DEVICETYPE_TOUCH; features-pktlen = WACOM_PKGLEN_BBTOUCH3; } } @@ -538,9 +538,9 @@ static int wacom_add_shared_data(struct hid_device *hdev) wacom_wac-shared = data-shared; - if (wacom_wac-features.device_type == BTN_TOOL_FINGER) + if (wacom_wac-features.device_type WACOM_DEVICETYPE_TOUCH) wacom_wac-shared-touch = hdev; - else if (wacom_wac-features.device_type == BTN_TOOL_PEN) + else if (wacom_wac-features.device_type WACOM_DEVICETYPE_PEN) wacom_wac-shared-pen = hdev; out: @@ -892,7 +892,7 @@ static int wacom_initialize_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) { + if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) { wacom-led.select[0] = 0; wacom-led.select[1] = 0; wacom-led.llv = 32; @@ -948,7 +948,7 @@ static void wacom_destroy_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) + if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) sysfs_remove_group(wacom-hdev-dev.kobj, intuos5_led_attr_group); break; @@ -1296,7 +1296,7 @@ static void wacom_wireless_work(struct work_struct *work) /* Stylus interface */ wacom_wac1-features
[PATCH v2 3/5] HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type
Historically, both the touch and pad tools would have shared the 'BTN_TOOL_FINGER' type. Any time you needed to distinguish the two, you had to use some other bit of knowledge (e.g. that the pad was on the same interface as the pen, and thus 'touch_max' would be zero). To make these checks more readable, we introduce WACOM_DEVICETYPE_PAD. Although we still have to rely on other bits of knowledge to set this bit on the right interface (since it cannot be detected from the HID descriptor), it can be done just once inside 'wacom_setup_device_quirks'. This patch introduces no functional changes. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Changes from v1: * Correct conditions under which 'wacom_wireless_work' sets the pad device type flag. Fixes issue with some pad devices not showing up and others crashing. * Set pad/touch flags for INTUOSHT and BAMBOO_PT inside the block of 'wacom_setup_device_quirks' which handles them. Ensures types are properly set on the devices before we get too far. drivers/hid/wacom_sys.c | 65 +++- drivers/hid/wacom_wac.c | 71 ++--- drivers/hid/wacom_wac.h | 1 + 3 files changed, 73 insertions(+), 64 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 2b4cbd8..aaa9c84 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -859,6 +859,9 @@ static int wacom_initialize_leds(struct wacom *wacom) { int error; + if (!(wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PAD)) + return 0; + /* Initialize default values */ switch (wacom-wacom_wac.features.type) { case INTUOS4S: @@ -892,17 +895,14 @@ static int wacom_initialize_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) { - wacom-led.select[0] = 0; - wacom-led.select[1] = 0; - wacom-led.llv = 32; - wacom-led.hlv = 0; - wacom-led.img_lum = 0; - - error = sysfs_create_group(wacom-hdev-dev.kobj, - intuos5_led_attr_group); - } else - return 0; + wacom-led.select[0] = 0; + wacom-led.select[1] = 0; + wacom-led.llv = 32; + wacom-led.hlv = 0; + wacom-led.img_lum = 0; + + error = sysfs_create_group(wacom-hdev-dev.kobj, + intuos5_led_attr_group); break; default: @@ -925,6 +925,9 @@ static void wacom_destroy_leds(struct wacom *wacom) if (!wacom-led_initialized) return; + if (!(wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PAD)) + return; + wacom-led_initialized = false; switch (wacom-wacom_wac.features.type) { @@ -948,9 +951,8 @@ static void wacom_destroy_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) - sysfs_remove_group(wacom-hdev-dev.kobj, - intuos5_led_attr_group); + sysfs_remove_group(wacom-hdev-dev.kobj, + intuos5_led_attr_group); break; } } @@ -1297,6 +1299,9 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac1-features = *((struct wacom_features *)id-driver_data); wacom_wac1-features.device_type |= WACOM_DEVICETYPE_PEN; + if (wacom_wac1-features.type != INTUOSHT + wacom_wac1-features.type != BAMBOO_PT) + wacom_wac1-features.device_type |= WACOM_DEVICETYPE_PAD; snprintf(wacom_wac1-name, WACOM_NAME_MAX, %s (WL) Pen, wacom_wac1-features.name); snprintf(wacom_wac1-pad_name, WACOM_NAME_MAX, %s (WL) Pad, @@ -1315,16 +1320,16 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac2-features = *((struct wacom_features *)id-driver_data); wacom_wac2-features.pktlen = WACOM_PKGLEN_BBTOUCH3; - wacom_wac2-features.device_type |= WACOM_DEVICETYPE_TOUCH; wacom_wac2-features.x_max = wacom_wac2-features.y_max = 4096; - if (wacom_wac2-features.touch_max) - snprintf(wacom_wac2-name, WACOM_NAME_MAX, -%s (WL) Finger,wacom_wac2-features.name); - else - snprintf
[PATCH v2 1/5] HID: wacom: Simplify 'wacom_update_name'
A little bit of cleanup work for 'wacom_update_name' to make it easier on the eyes. Creates a temporary 'name' variable on which we'll perform our edits. Once the name is in its final form, it will be copied (with appropriate suffix) to 'wacom_wac-name' and 'wacom_wac-pad_name'. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- No changes from v1. drivers/hid/wacom_sys.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index eea18a6..bdf31c9 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1417,6 +1417,7 @@ static void wacom_update_name(struct wacom *wacom) { struct wacom_wac *wacom_wac = wacom-wacom_wac; struct wacom_features *features = wacom_wac-features; + char name[WACOM_NAME_MAX]; /* Generic devices name unspecified */ if ((features-type == HID_GENERIC) !strcmp(Wacom HID, features-name)) { @@ -1424,41 +1425,43 @@ static void wacom_update_name(struct wacom *wacom) strstr(wacom-hdev-name, wacom) || strstr(wacom-hdev-name, WACOM)) { /* name is in HID descriptor, use it */ - strlcpy(wacom_wac-name, wacom-hdev-name, - sizeof(wacom_wac-name)); + strlcpy(name, wacom-hdev-name, sizeof(name)); /* strip out excess whitespaces */ while (1) { - char *gap = strstr(wacom_wac-name, ); + char *gap = strstr(name, ); if (gap == NULL) break; /* shift everything including the terminator */ memmove(gap, gap+1, strlen(gap)); } /* get rid of trailing whitespace */ - if (wacom_wac-name[strlen(wacom_wac-name)-1] == ' ') - wacom_wac-name[strlen(wacom_wac-name)-1] = '\0'; + if (name[strlen(name)-1] == ' ') + name[strlen(name)-1] = '\0'; } else { /* no meaningful name retrieved. use product ID */ - snprintf(wacom_wac-name, sizeof(wacom_wac-name), + snprintf(name, sizeof(name), %s %X, features-name, wacom-hdev-product); } } else { - strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); + strlcpy(name, features-name, sizeof(name)); } /* Append the device type to the name */ snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), - %s Pad, wacom_wac-name); + %s Pad, name); if (features-device_type == BTN_TOOL_PEN) { - strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Pen, name); } else if (features-device_type == BTN_TOOL_FINGER) { if (features-touch_max) - strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Finger, name); else - strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Pad, name); } } -- 2.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] HID: wacom: Introduce new 'touch_input' device
Instead of having a single 'input_dev' device that will take either pen or touch data depending on the type of the device, create seperate devices devices for each. By splitting things like this, we can support devices (e.g. the I2C AES sensors in some newer tablet PCs) that send both pen and touch reports from a single endpoint. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Changes from v1: * Fixed mis-named devices (Pad - Pen; Touch - Finger) * Do not update touch state in 'wacom_bpt3_touch' unless a touchpad is actually present. * In 'wacom_wireless_work' and 'wacom_probe', have 'wacom_wac-shared-touch_input' point to the touch input instead of the pen input. drivers/hid/wacom_sys.c | 116 +--- drivers/hid/wacom_wac.c | 115 +-- drivers/hid/wacom_wac.h | 9 ++-- 3 files changed, 139 insertions(+), 101 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index ca15c7f..4c0ffca 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -253,7 +253,7 @@ static void wacom_post_parse_hid(struct hid_device *hdev, if (features-type == HID_GENERIC) { /* Any last-minute generic device setup */ if (features-touch_max 1) { - input_mt_init_slots(wacom_wac-input, wacom_wac-features.touch_max, + input_mt_init_slots(wacom_wac-touch_input, wacom_wac-features.touch_max, INPUT_MT_DIRECT); } } @@ -1130,7 +1130,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) if (!input_dev) return NULL; - input_dev-name = wacom_wac-name; + input_dev-name = wacom_wac-pen_name; input_dev-phys = hdev-phys; input_dev-dev.parent = hdev-dev; input_dev-open = wacom_open; @@ -1149,27 +1149,33 @@ static void wacom_free_inputs(struct wacom *wacom) { struct wacom_wac *wacom_wac = (wacom-wacom_wac); - if (wacom_wac-input) - input_free_device(wacom_wac-input); + if (wacom_wac-pen_input) + input_free_device(wacom_wac-pen_input); + if (wacom_wac-touch_input) + input_free_device(wacom_wac-touch_input); if (wacom_wac-pad_input) input_free_device(wacom_wac-pad_input); - wacom_wac-input = NULL; + wacom_wac-pen_input = NULL; + wacom_wac-touch_input = NULL; wacom_wac-pad_input = NULL; } static int wacom_allocate_inputs(struct wacom *wacom) { - struct input_dev *input_dev, *pad_input_dev; + struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = (wacom-wacom_wac); - input_dev = wacom_allocate_input(wacom); + pen_input_dev = wacom_allocate_input(wacom); + touch_input_dev = wacom_allocate_input(wacom); pad_input_dev = wacom_allocate_input(wacom); - if (!input_dev || !pad_input_dev) { + if (!pen_input_dev || !touch_input_dev || !pad_input_dev) { wacom_free_inputs(wacom); return -ENOMEM; } - wacom_wac-input = input_dev; + wacom_wac-pen_input = pen_input_dev; + wacom_wac-touch_input = touch_input_dev; + wacom_wac-touch_input-name = wacom_wac-touch_name; wacom_wac-pad_input = pad_input_dev; wacom_wac-pad_input-name = wacom_wac-pad_name; @@ -1178,11 +1184,17 @@ static int wacom_allocate_inputs(struct wacom *wacom) static void wacom_clean_inputs(struct wacom *wacom) { - if (wacom-wacom_wac.input) { - if (wacom-wacom_wac.input_registered) - input_unregister_device(wacom-wacom_wac.input); + if (wacom-wacom_wac.pen_input) { + if (wacom-wacom_wac.pen_registered) + input_unregister_device(wacom-wacom_wac.pen_input); else - input_free_device(wacom-wacom_wac.input); + input_free_device(wacom-wacom_wac.pen_input); + } + if (wacom-wacom_wac.touch_input) { + if (wacom-wacom_wac.touch_registered) + input_unregister_device(wacom-wacom_wac.touch_input); + else + input_free_device(wacom-wacom_wac.touch_input); } if (wacom-wacom_wac.pad_input) { if (wacom-wacom_wac.pad_registered) @@ -1190,33 +1202,49 @@ static void wacom_clean_inputs(struct wacom *wacom) else input_free_device(wacom-wacom_wac.pad_input); } - wacom-wacom_wac.input = NULL; + wacom-wacom_wac.pen_input = NULL; + wacom-wacom_wac.touch_input = NULL; wacom-wacom_wac.pad_input = NULL; wacom_destroy_leds(wacom); } static int wacom_register_inputs(struct wacom *wacom) { - struct input_dev
Re: [PATCH 0/5] HID: wacom: Support tablets with pen and touch on same interface
On 6/8/2015 8:59 AM, Benjamin Tissoires wrote: Hi again, On Jun 03 2015 or thereabouts, Jason Gerecke wrote: I've recently got my hands on a device which has an I2C sensor that sends both pen and touch reports from a single interface. To userspace, it shows up as a single input device which blends both the report types (e.g. it has ABS_PRESSURE for the pen, and ABS_MT_POSITION_X for the touch). This patch set modifies the driver to be able to handle devices which place both pen and touch on a the same interface. It does this by treating the pen, touch, and pad (which was already special-cased) independently. If a device has the appropriate device_type, one or more of pen/touch/pad input devices will be created, initialized, and used to send data to userspace. Signed-off-by: Jason Gerecke jason.gere...@wacom.com So, besides the typo in 5/5, the series is: Reviewed-by: Bnejamin Tissoires benjamin.tissoi...@redhat.com I'll send a follow up patch to fix the Bamboo PAD extra interface once this will land in Jiri's tree. Cheers, Benjamin Just stumbled across a bug with wireless operation (missing pad device). Hopefully Jiri hasn't merged anything yet :) Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours Jason Gerecke (5): HID: wacom: Simplify 'wacom_update_name' HID: wacom: Treat features-device_type values as flags HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type HID: wacom: Split apart 'wacom_setup_pentouch_input_capabilites' HID: wacom: Introduce new 'touch_input' device drivers/hid/wacom.h | 4 +- drivers/hid/wacom_sys.c | 194 +++-- drivers/hid/wacom_wac.c | 379 ++-- drivers/hid/wacom_wac.h | 15 +- 4 files changed, 332 insertions(+), 260 deletions(-) -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] HID: wacom: Treat features-device_type values as flags
On 6/4/2015 11:59 AM, Benjamin Tissoires wrote: On Jun 03 2015 or thereabouts, Jason Gerecke wrote: The USB devices that this driver has historically supported segregate the pen and touch portions of the tablet. Oftentimes the segregation would be done at the interface level, though on occasion (e.g. Cintiq 24HDT) the tablet would combine two totally independent USB devices behind an internal USB hub. Because pen and touch never shared the same interface, it made sense for the 'device_type' to store a single value: pen or touch. Recently, however, some I2C devices have been created which combine the two. A first step to accomodating this is to expand 'device_type' so that it can represent two (or potentially more) types simultaneously. To do this, we treat it as a bitfield and set/check individual bits rather than using the '=' and '==' operators. This should not result in any functional change since no supported devices (that I'm aware of, at least) have HID descriptors that indicate both pen and touch reports on a single interface. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 35 ++- drivers/hid/wacom_wac.c | 30 +++--- drivers/hid/wacom_wac.h | 5 + 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index bdf31c9..2b4cbd8 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -197,9 +197,9 @@ static void wacom_usage_mapping(struct hid_device *hdev, * values commonly reported. */ if (pen) -features-device_type = BTN_TOOL_PEN; +features-device_type |= WACOM_DEVICETYPE_PEN; else if (finger) -features-device_type = BTN_TOOL_FINGER; +features-device_type |= WACOM_DEVICETYPE_TOUCH; else return; @@ -411,7 +411,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, if (features-type == HID_GENERIC) return wacom_hid_set_device_mode(hdev); -if (features-device_type == BTN_TOOL_FINGER) { +if (features-device_type WACOM_DEVICETYPE_TOUCH) { if (features-type TABLETPC) { /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); @@ -425,7 +425,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, else if (features-type == BAMBOO_PAD) { return wacom_set_device_mode(hdev, 2, 2, 2); } -} else if (features-device_type == BTN_TOOL_PEN) { +} else if (features-device_type WACOM_DEVICETYPE_PEN) { if (features-type = BAMBOO_PT features-type != WIRELESS) { return wacom_set_device_mode(hdev, 2, 2, 2); } @@ -454,9 +454,9 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, */ if (features-type == WIRELESS) { if (intf-cur_altsetting-desc.bInterfaceNumber == 0) { -features-device_type = 0; +features-device_type = WACOM_DEVICETYPE_NONE; } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { -features-device_type = BTN_TOOL_FINGER; +features-device_type |= WACOM_DEVICETYPE_TOUCH; features-pktlen = WACOM_PKGLEN_BBTOUCH3; } } @@ -538,9 +538,9 @@ static int wacom_add_shared_data(struct hid_device *hdev) wacom_wac-shared = data-shared; -if (wacom_wac-features.device_type == BTN_TOOL_FINGER) +if (wacom_wac-features.device_type WACOM_DEVICETYPE_TOUCH) wacom_wac-shared-touch = hdev; -else if (wacom_wac-features.device_type == BTN_TOOL_PEN) +else if (wacom_wac-features.device_type WACOM_DEVICETYPE_PEN) wacom_wac-shared-pen = hdev; out: @@ -892,7 +892,7 @@ static int wacom_initialize_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: -if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) { +if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) { wacom-led.select[0] = 0; wacom-led.select[1] = 0; wacom-led.llv = 32; @@ -948,7 +948,7 @@ static void wacom_destroy_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: -if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) +if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) sysfs_remove_group(wacom-hdev-dev.kobj, intuos5_led_attr_group); break; @@ -1296,7 +1296,7 @@ static void wacom_wireless_work(struct work_struct *work) /* Stylus interface */ wacom_wac1-features
Re: [PATCH 5/5] HID: wacom: Introduce new 'touch_input' device
On 6/4/2015 11:56 AM, Benjamin Tissoires wrote: Hi Jason, On Jun 03 2015 or thereabouts, Jason Gerecke wrote: Instead of having a single 'input_dev' device that will take either pen or touch data depending on the type of the device, create seperate devices devices for each. By splitting things like this, we can support devices (e.g. the I2C AES sensors in some newer tablet PCs) that send both pen and touch reports from a single endpoint. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Besides the Wacom PAD problem already mentioned in the 0/5 thread (I will test it tomorrow and come with a following patch if need), I have 2 nitpicks here: drivers/hid/wacom_sys.c | 118 +--- drivers/hid/wacom_wac.c | 108 drivers/hid/wacom_wac.h | 9 ++-- 3 files changed, 135 insertions(+), 100 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a213a8a..a928c1d 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -253,7 +253,7 @@ static void wacom_post_parse_hid(struct hid_device *hdev, if (features-type == HID_GENERIC) { /* Any last-minute generic device setup */ if (features-touch_max 1) { -input_mt_init_slots(wacom_wac-input, wacom_wac-features.touch_max, +input_mt_init_slots(wacom_wac-touch_input, wacom_wac-features.touch_max, INPUT_MT_DIRECT); } } @@ -1130,7 +1130,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) if (!input_dev) return NULL; -input_dev-name = wacom_wac-name; +input_dev-name = wacom_wac-pen_name; input_dev-phys = hdev-phys; input_dev-dev.parent = hdev-dev; input_dev-open = wacom_open; @@ -1149,27 +1149,33 @@ static void wacom_free_inputs(struct wacom *wacom) { struct wacom_wac *wacom_wac = (wacom-wacom_wac); -if (wacom_wac-input) -input_free_device(wacom_wac-input); +if (wacom_wac-pen_input) +input_free_device(wacom_wac-pen_input); +if (wacom_wac-touch_input) +input_free_device(wacom_wac-touch_input); if (wacom_wac-pad_input) input_free_device(wacom_wac-pad_input); -wacom_wac-input = NULL; +wacom_wac-pen_input = NULL; +wacom_wac-touch_input = NULL; wacom_wac-pad_input = NULL; } static int wacom_allocate_inputs(struct wacom *wacom) { -struct input_dev *input_dev, *pad_input_dev; +struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = (wacom-wacom_wac); -input_dev = wacom_allocate_input(wacom); +pen_input_dev = wacom_allocate_input(wacom); +touch_input_dev = wacom_allocate_input(wacom); pad_input_dev = wacom_allocate_input(wacom); I know you are not introducing anything new here, but that means that now, we reserve 3 input devices, while we might not even use one. I just wonder if we should not start having a smarter input allocation in wacom.ko where we would create the inputs only if they are needed. IIRC, I came to use this extra pad input node to have all the bits in place while parsing the report descriptor, but maybe we could be smarter. I've been considering this as well. I was thinking about creating some kind of structure to allow us to better separate the individual tools (e.g. a kind of tool-specific wacom_wac with name, input device, and features [addressing your concerns in patch 2]) but haven't come up with a good design yet. Its on my list of back-burner tasks, though we might be able to do something about the excess allocations themselves without quite as much work. -if (!input_dev || !pad_input_dev) { +if (!pen_input_dev || !touch_input_dev || !pad_input_dev) { wacom_free_inputs(wacom); return -ENOMEM; } -wacom_wac-input = input_dev; +wacom_wac-pen_input = pen_input_dev; +wacom_wac-touch_input = touch_input_dev; +wacom_wac-touch_input-name = wacom_wac-touch_name; wacom_wac-pad_input = pad_input_dev; wacom_wac-pad_input-name = wacom_wac-pad_name; @@ -1178,11 +1184,17 @@ static int wacom_allocate_inputs(struct wacom *wacom) static void wacom_clean_inputs(struct wacom *wacom) { -if (wacom-wacom_wac.input) { -if (wacom-wacom_wac.input_registered) -input_unregister_device(wacom-wacom_wac.input); +if (wacom-wacom_wac.pen_input) { +if (wacom-wacom_wac.pen_registered) +input_unregister_device(wacom-wacom_wac.pen_input); else -input_free_device(wacom-wacom_wac.input); +input_free_device(wacom-wacom_wac.pen_input); +} +if (wacom-wacom_wac.touch_input) { +if (wacom
Re: [PATCH 0/5] HID: wacom: Support tablets with pen and touch on same interface
On 6/4/2015 7:18 AM, Benjamin Tissoires wrote: Hi Jason, On Jun 03 2015 or thereabouts, Jason Gerecke wrote: I've recently got my hands on a device which has an I2C sensor that sends both pen and touch reports from a single interface. To userspace, it shows up as a single input device which blends both the report types (e.g. it has ABS_PRESSURE for the pen, and ABS_MT_POSITION_X for the touch). This patch set modifies the driver to be able to handle devices which place both pen and touch on a the same interface. It does this by treating the pen, touch, and pad (which was already special-cased) independently. If a device has the appropriate device_type, one or more of pen/touch/pad input devices will be created, initialized, and used to send data to userspace. Signed-off-by: Jason Gerecke jason.gere...@wacom.com This all seems sensible. I gave a quick look yesterday and could not found any obvious problem, but I'd like to review it more thoroughly before giving my rev-by (and do a little bit of testing too). I don't believe there will be any problems for the series, besides the Bamboo PAD. Have you tested on this? Cheers, Benjamin I don't have a Bamboo PAD to test with, but carefully looking at each interface's HID descriptor makes me think you may be right. The debug interface in particular uses a WACOM_VENDORDEFINED_PEN application collection and will be marked as WACOM_DEVICETYPE_PEN instead of WACOM_DEVICETYPE_TOUCH. The smallest fix that should do the trick would be to just swap the device_type in 'wacom_setup_device_quirks'. Alternatively, we could only allow the debug interface to be probed, set the touch device type flag (in addition to the automatically-set pen flag), and extend the IRQ function to explicitly handle pen events. The alternative is a bit more work (and we'd need somebody with a device to test it...) but I think might make the codepath for the Bamboo PAD a bit easier to follow. -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours Jason Gerecke (5): HID: wacom: Simplify 'wacom_update_name' HID: wacom: Treat features-device_type values as flags HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type HID: wacom: Split apart 'wacom_setup_pentouch_input_capabilites' HID: wacom: Introduce new 'touch_input' device drivers/hid/wacom.h | 4 +- drivers/hid/wacom_sys.c | 194 +++-- drivers/hid/wacom_wac.c | 379 ++-- drivers/hid/wacom_wac.h | 15 +- 4 files changed, 332 insertions(+), 260 deletions(-) -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/5] HID: wacom: Simplify 'wacom_update_name'
A little bit of cleanup work for 'wacom_update_name' to make it easier on the eyes. Creates a temporary 'name' variable on which we'll perform our edits. Once the name is in its final form, it will be copied (with appropriate suffix) to 'wacom_wac-name' and 'wacom_wac-pad_name'. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index eea18a6..bdf31c9 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1417,6 +1417,7 @@ static void wacom_update_name(struct wacom *wacom) { struct wacom_wac *wacom_wac = wacom-wacom_wac; struct wacom_features *features = wacom_wac-features; + char name[WACOM_NAME_MAX]; /* Generic devices name unspecified */ if ((features-type == HID_GENERIC) !strcmp(Wacom HID, features-name)) { @@ -1424,41 +1425,43 @@ static void wacom_update_name(struct wacom *wacom) strstr(wacom-hdev-name, wacom) || strstr(wacom-hdev-name, WACOM)) { /* name is in HID descriptor, use it */ - strlcpy(wacom_wac-name, wacom-hdev-name, - sizeof(wacom_wac-name)); + strlcpy(name, wacom-hdev-name, sizeof(name)); /* strip out excess whitespaces */ while (1) { - char *gap = strstr(wacom_wac-name, ); + char *gap = strstr(name, ); if (gap == NULL) break; /* shift everything including the terminator */ memmove(gap, gap+1, strlen(gap)); } /* get rid of trailing whitespace */ - if (wacom_wac-name[strlen(wacom_wac-name)-1] == ' ') - wacom_wac-name[strlen(wacom_wac-name)-1] = '\0'; + if (name[strlen(name)-1] == ' ') + name[strlen(name)-1] = '\0'; } else { /* no meaningful name retrieved. use product ID */ - snprintf(wacom_wac-name, sizeof(wacom_wac-name), + snprintf(name, sizeof(name), %s %X, features-name, wacom-hdev-product); } } else { - strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); + strlcpy(name, features-name, sizeof(name)); } /* Append the device type to the name */ snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), - %s Pad, wacom_wac-name); + %s Pad, name); if (features-device_type == BTN_TOOL_PEN) { - strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Pen, name); } else if (features-device_type == BTN_TOOL_FINGER) { if (features-touch_max) - strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Finger, name); else - strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s Pad, name); } } -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/5] HID: wacom: Introduce new 'touch_input' device
Instead of having a single 'input_dev' device that will take either pen or touch data depending on the type of the device, create seperate devices devices for each. By splitting things like this, we can support devices (e.g. the I2C AES sensors in some newer tablet PCs) that send both pen and touch reports from a single endpoint. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 118 +--- drivers/hid/wacom_wac.c | 108 drivers/hid/wacom_wac.h | 9 ++-- 3 files changed, 135 insertions(+), 100 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a213a8a..a928c1d 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -253,7 +253,7 @@ static void wacom_post_parse_hid(struct hid_device *hdev, if (features-type == HID_GENERIC) { /* Any last-minute generic device setup */ if (features-touch_max 1) { - input_mt_init_slots(wacom_wac-input, wacom_wac-features.touch_max, + input_mt_init_slots(wacom_wac-touch_input, wacom_wac-features.touch_max, INPUT_MT_DIRECT); } } @@ -1130,7 +1130,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) if (!input_dev) return NULL; - input_dev-name = wacom_wac-name; + input_dev-name = wacom_wac-pen_name; input_dev-phys = hdev-phys; input_dev-dev.parent = hdev-dev; input_dev-open = wacom_open; @@ -1149,27 +1149,33 @@ static void wacom_free_inputs(struct wacom *wacom) { struct wacom_wac *wacom_wac = (wacom-wacom_wac); - if (wacom_wac-input) - input_free_device(wacom_wac-input); + if (wacom_wac-pen_input) + input_free_device(wacom_wac-pen_input); + if (wacom_wac-touch_input) + input_free_device(wacom_wac-touch_input); if (wacom_wac-pad_input) input_free_device(wacom_wac-pad_input); - wacom_wac-input = NULL; + wacom_wac-pen_input = NULL; + wacom_wac-touch_input = NULL; wacom_wac-pad_input = NULL; } static int wacom_allocate_inputs(struct wacom *wacom) { - struct input_dev *input_dev, *pad_input_dev; + struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = (wacom-wacom_wac); - input_dev = wacom_allocate_input(wacom); + pen_input_dev = wacom_allocate_input(wacom); + touch_input_dev = wacom_allocate_input(wacom); pad_input_dev = wacom_allocate_input(wacom); - if (!input_dev || !pad_input_dev) { + if (!pen_input_dev || !touch_input_dev || !pad_input_dev) { wacom_free_inputs(wacom); return -ENOMEM; } - wacom_wac-input = input_dev; + wacom_wac-pen_input = pen_input_dev; + wacom_wac-touch_input = touch_input_dev; + wacom_wac-touch_input-name = wacom_wac-touch_name; wacom_wac-pad_input = pad_input_dev; wacom_wac-pad_input-name = wacom_wac-pad_name; @@ -1178,11 +1184,17 @@ static int wacom_allocate_inputs(struct wacom *wacom) static void wacom_clean_inputs(struct wacom *wacom) { - if (wacom-wacom_wac.input) { - if (wacom-wacom_wac.input_registered) - input_unregister_device(wacom-wacom_wac.input); + if (wacom-wacom_wac.pen_input) { + if (wacom-wacom_wac.pen_registered) + input_unregister_device(wacom-wacom_wac.pen_input); else - input_free_device(wacom-wacom_wac.input); + input_free_device(wacom-wacom_wac.pen_input); + } + if (wacom-wacom_wac.touch_input) { + if (wacom-wacom_wac.touch_registered) + input_unregister_device(wacom-wacom_wac.touch_input); + else + input_free_device(wacom-wacom_wac.touch_input); } if (wacom-wacom_wac.pad_input) { if (wacom-wacom_wac.pad_registered) @@ -1190,33 +1202,49 @@ static void wacom_clean_inputs(struct wacom *wacom) else input_free_device(wacom-wacom_wac.pad_input); } - wacom-wacom_wac.input = NULL; + wacom-wacom_wac.pen_input = NULL; + wacom-wacom_wac.touch_input = NULL; wacom-wacom_wac.pad_input = NULL; wacom_destroy_leds(wacom); } static int wacom_register_inputs(struct wacom *wacom) { - struct input_dev *input_dev, *pad_input_dev; + struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = (wacom-wacom_wac); - struct wacom_features *features = wacom_wac-features; int error = 0; - input_dev = wacom_wac-input; + pen_input_dev
[PATCH 0/5] HID: wacom: Support tablets with pen and touch on same interface
I've recently got my hands on a device which has an I2C sensor that sends both pen and touch reports from a single interface. To userspace, it shows up as a single input device which blends both the report types (e.g. it has ABS_PRESSURE for the pen, and ABS_MT_POSITION_X for the touch). This patch set modifies the driver to be able to handle devices which place both pen and touch on a the same interface. It does this by treating the pen, touch, and pad (which was already special-cased) independently. If a device has the appropriate device_type, one or more of pen/touch/pad input devices will be created, initialized, and used to send data to userspace. Signed-off-by: Jason Gerecke jason.gere...@wacom.com Jason Gerecke (5): HID: wacom: Simplify 'wacom_update_name' HID: wacom: Treat features-device_type values as flags HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type HID: wacom: Split apart 'wacom_setup_pentouch_input_capabilites' HID: wacom: Introduce new 'touch_input' device drivers/hid/wacom.h | 4 +- drivers/hid/wacom_sys.c | 194 +++-- drivers/hid/wacom_wac.c | 379 ++-- drivers/hid/wacom_wac.h | 15 +- 4 files changed, 332 insertions(+), 260 deletions(-) -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/5] HID: wacom: Treat features-device_type values as flags
The USB devices that this driver has historically supported segregate the pen and touch portions of the tablet. Oftentimes the segregation would be done at the interface level, though on occasion (e.g. Cintiq 24HDT) the tablet would combine two totally independent USB devices behind an internal USB hub. Because pen and touch never shared the same interface, it made sense for the 'device_type' to store a single value: pen or touch. Recently, however, some I2C devices have been created which combine the two. A first step to accomodating this is to expand 'device_type' so that it can represent two (or potentially more) types simultaneously. To do this, we treat it as a bitfield and set/check individual bits rather than using the '=' and '==' operators. This should not result in any functional change since no supported devices (that I'm aware of, at least) have HID descriptors that indicate both pen and touch reports on a single interface. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 35 ++- drivers/hid/wacom_wac.c | 30 +++--- drivers/hid/wacom_wac.h | 5 + 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index bdf31c9..2b4cbd8 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -197,9 +197,9 @@ static void wacom_usage_mapping(struct hid_device *hdev, * values commonly reported. */ if (pen) - features-device_type = BTN_TOOL_PEN; + features-device_type |= WACOM_DEVICETYPE_PEN; else if (finger) - features-device_type = BTN_TOOL_FINGER; + features-device_type |= WACOM_DEVICETYPE_TOUCH; else return; @@ -411,7 +411,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, if (features-type == HID_GENERIC) return wacom_hid_set_device_mode(hdev); - if (features-device_type == BTN_TOOL_FINGER) { + if (features-device_type WACOM_DEVICETYPE_TOUCH) { if (features-type TABLETPC) { /* MT Tablet PC touch */ return wacom_set_device_mode(hdev, 3, 4, 4); @@ -425,7 +425,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev, else if (features-type == BAMBOO_PAD) { return wacom_set_device_mode(hdev, 2, 2, 2); } - } else if (features-device_type == BTN_TOOL_PEN) { + } else if (features-device_type WACOM_DEVICETYPE_PEN) { if (features-type = BAMBOO_PT features-type != WIRELESS) { return wacom_set_device_mode(hdev, 2, 2, 2); } @@ -454,9 +454,9 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, */ if (features-type == WIRELESS) { if (intf-cur_altsetting-desc.bInterfaceNumber == 0) { - features-device_type = 0; + features-device_type = WACOM_DEVICETYPE_NONE; } else if (intf-cur_altsetting-desc.bInterfaceNumber == 2) { - features-device_type = BTN_TOOL_FINGER; + features-device_type |= WACOM_DEVICETYPE_TOUCH; features-pktlen = WACOM_PKGLEN_BBTOUCH3; } } @@ -538,9 +538,9 @@ static int wacom_add_shared_data(struct hid_device *hdev) wacom_wac-shared = data-shared; - if (wacom_wac-features.device_type == BTN_TOOL_FINGER) + if (wacom_wac-features.device_type WACOM_DEVICETYPE_TOUCH) wacom_wac-shared-touch = hdev; - else if (wacom_wac-features.device_type == BTN_TOOL_PEN) + else if (wacom_wac-features.device_type WACOM_DEVICETYPE_PEN) wacom_wac-shared-pen = hdev; out: @@ -892,7 +892,7 @@ static int wacom_initialize_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) { + if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) { wacom-led.select[0] = 0; wacom-led.select[1] = 0; wacom-led.llv = 32; @@ -948,7 +948,7 @@ static void wacom_destroy_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type == BTN_TOOL_PEN) + if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) sysfs_remove_group(wacom-hdev-dev.kobj, intuos5_led_attr_group); break; @@ -1296,7 +1296,7 @@ static void wacom_wireless_work(struct work_struct *work) /* Stylus interface */ wacom_wac1-features
[PATCH 4/5] HID: wacom: Split apart 'wacom_setup_pentouch_input_capabilites'
This splits the 'wacom_setup_pentouch_input_capabilites' function into pieces dedicated to doing setup for just the pen interface and just the touch interface. This makes it easier to focus on the relevant piece when making changes. This patch introduces no functional changes. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom.h | 4 +- drivers/hid/wacom_sys.c | 8 +- drivers/hid/wacom_wac.c | 234 +--- 3 files changed, 131 insertions(+), 115 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index c76e21f..a533787 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -135,7 +135,9 @@ extern const struct hid_device_id wacom_ids[]; void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); void wacom_setup_device_quirks(struct wacom *wacom); -int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, +int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, + struct wacom_wac *wacom_wac); +int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index daf8051..a213a8a 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1199,7 +1199,8 @@ static int wacom_register_inputs(struct wacom *wacom) { struct input_dev *input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = (wacom-wacom_wac); - int error; + struct wacom_features *features = wacom_wac-features; + int error = 0; input_dev = wacom_wac-input; pad_input_dev = wacom_wac-pad_input; @@ -1207,7 +1208,10 @@ static int wacom_register_inputs(struct wacom *wacom) if (!input_dev || !pad_input_dev) return -EINVAL; - error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac); + if (features-device_type WACOM_DEVICETYPE_PEN) + error = wacom_setup_pen_input_capabilities(input_dev, wacom_wac); + if (!error features-device_type WACOM_DEVICETYPE_TOUCH) + error = wacom_setup_touch_input_capabilities(input_dev, wacom_wac); if (!error) { error = input_register_device(input_dev); if (error) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1e23bd8..318d9d3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2241,54 +2241,16 @@ void wacom_setup_device_quirks(struct wacom *wacom) } } -static void wacom_abs_set_axis(struct input_dev *input_dev, - struct wacom_wac *wacom_wac) -{ - struct wacom_features *features = wacom_wac-features; - - if (features-device_type WACOM_DEVICETYPE_PEN) { - input_set_abs_params(input_dev, ABS_X, features-x_min, -features-x_max, features-x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, features-y_min, -features-y_max, features-y_fuzz, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, - features-pressure_max, features-pressure_fuzz, 0); - - /* penabled devices have fixed resolution for each model */ - input_abs_set_res(input_dev, ABS_X, features-x_resolution); - input_abs_set_res(input_dev, ABS_Y, features-y_resolution); - } else if (features-device_type WACOM_DEVICETYPE_TOUCH) { - if (features-touch_max == 1) { - input_set_abs_params(input_dev, ABS_X, 0, - features-x_max, features-x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, 0, - features-y_max, features-y_fuzz, 0); - input_abs_set_res(input_dev, ABS_X, - features-x_resolution); - input_abs_set_res(input_dev, ABS_Y, - features-y_resolution); - } - - if (features-touch_max 1) { - input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, - features-x_max, features-x_fuzz, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, - features-y_max, features-y_fuzz, 0); - input_abs_set_res(input_dev, ABS_MT_POSITION_X, - features-x_resolution); - input_abs_set_res(input_dev, ABS_MT_POSITION_Y, - features-y_resolution); - } - } -} - -int
[PATCH 3/5] HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type
Historically, both the touch and pad tools would have shared the 'BTN_TOOL_FINGER' type. Any time you needed to distinguish the two, you had to use some other bit of knowledge (e.g. that the pad was on the same interface as the pen, and thus 'touch_max' would be zero). To make these checks more readable, we introduce WACOM_DEVICETYPE_PAD. Although we still have to rely on other bits of knowledge to set this bit on the right interface (since it cannot be detected from the HID descriptor), it can be done just once inside 'wacom_setup_device_quirks'. This patch introduces no functional changes. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_sys.c | 54 +++- drivers/hid/wacom_wac.c | 73 +++-- drivers/hid/wacom_wac.h | 1 + 3 files changed, 70 insertions(+), 58 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 2b4cbd8..daf8051 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -859,6 +859,9 @@ static int wacom_initialize_leds(struct wacom *wacom) { int error; + if (!(wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PAD)) + return 0; + /* Initialize default values */ switch (wacom-wacom_wac.features.type) { case INTUOS4S: @@ -892,17 +895,14 @@ static int wacom_initialize_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) { - wacom-led.select[0] = 0; - wacom-led.select[1] = 0; - wacom-led.llv = 32; - wacom-led.hlv = 0; - wacom-led.img_lum = 0; - - error = sysfs_create_group(wacom-hdev-dev.kobj, - intuos5_led_attr_group); - } else - return 0; + wacom-led.select[0] = 0; + wacom-led.select[1] = 0; + wacom-led.llv = 32; + wacom-led.hlv = 0; + wacom-led.img_lum = 0; + + error = sysfs_create_group(wacom-hdev-dev.kobj, + intuos5_led_attr_group); break; default: @@ -925,6 +925,9 @@ static void wacom_destroy_leds(struct wacom *wacom) if (!wacom-led_initialized) return; + if (!(wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PAD)) + return; + wacom-led_initialized = false; switch (wacom-wacom_wac.features.type) { @@ -948,9 +951,8 @@ static void wacom_destroy_leds(struct wacom *wacom) case INTUOSPS: case INTUOSPM: case INTUOSPL: - if (wacom-wacom_wac.features.device_type WACOM_DEVICETYPE_PEN) - sysfs_remove_group(wacom-hdev-dev.kobj, - intuos5_led_attr_group); + sysfs_remove_group(wacom-hdev-dev.kobj, + intuos5_led_attr_group); break; } } @@ -1315,14 +1317,16 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac2-features = *((struct wacom_features *)id-driver_data); wacom_wac2-features.pktlen = WACOM_PKGLEN_BBTOUCH3; - wacom_wac2-features.device_type |= WACOM_DEVICETYPE_TOUCH; wacom_wac2-features.x_max = wacom_wac2-features.y_max = 4096; - if (wacom_wac2-features.touch_max) + if (wacom_wac2-features.touch_max) { + wacom_wac2-features.device_type |= WACOM_DEVICETYPE_TOUCH; snprintf(wacom_wac2-name, WACOM_NAME_MAX, %s (WL) Finger,wacom_wac2-features.name); - else + } else { + wacom_wac2-features.device_type |= WACOM_DEVICETYPE_PAD; snprintf(wacom_wac2-name, WACOM_NAME_MAX, %s (WL) Pad,wacom_wac2-features.name); + } snprintf(wacom_wac2-pad_name, WACOM_NAME_MAX, %s (WL) Pad, wacom_wac2-features.name); wacom_wac2-pid = wacom_wac-pid; @@ -1456,12 +1460,12 @@ static void wacom_update_name(struct wacom *wacom) %s Pen, name); } else if (features-device_type WACOM_DEVICETYPE_TOUCH) { - if (features-touch_max) - snprintf(wacom_wac-name, sizeof(wacom_wac-name), - %s Finger, name); - else - snprintf(wacom_wac-name
[PATCH v2 2/2] HID: wacom: Handle failing HID_DG_CONTACTMAX requests
Hardware may not respond to a request for the HID_DG_CONTACTMAX feature and we should be tolerant of such a failure. This is especially true when using hid-replay where the hardware doesn't exist, but also for devices attached to a flaky bus. This patch increases the number of allowable retries to match other calls to 'wacom_get_report' and also provides a fallback which forces 'touch_max = 16' (enough for any Wacom device seen so far). Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Changed in v2: - Fixed placement of 'else' - Use 'hid_warn' instead of 'dev_warn' drivers/hid/wacom_sys.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 109312f..eea18a6 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -125,9 +125,16 @@ static void wacom_feature_mapping(struct hid_device *hdev, break; data[0] = field-report-id; ret = wacom_get_report(hdev, HID_FEATURE_REPORT, - data, 2, 0); - if (ret == 2) + data, 2, WAC_CMD_RETRIES); + if (ret == 2) { features-touch_max = data[1]; + } else { + features-touch_max = 16; + hid_warn(hdev, wacom_feature_mapping: +could not get HID_DG_CONTACTMAX, +defaulting to %d\n, + features-touch_max); + } kfree(data); } break; -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/2] HID: wacom: Have wacom_{get,set}_report retry on -EAGAIN, not -EPIPE
Retrying on -EPIPE makes very little sense since this typically indicates a problem that will not just disappear on its own. For instance, the USB documentation states that it will be sent if the endpoint is stalled or the device has disconnected. Instead, we should retry if -EAGAIN is received since this indicates a temporary error condition such as a busy bus. In addition to adjusting the conditions we retry under, we also log an error on failure so that we can be aware of what's going on. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- Changed in v2: - Renamed from HID: wacom: Allow wacom_{get,set}_report to retry on -EAGAIN - Changed retry conditions so that we no longer retry on -EPIPE - Use 'hid_err' instead of 'dev_err' drivers/hid/wacom_sys.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 7abf52c..109312f 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -35,7 +35,11 @@ static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf, do { retval = hid_hw_raw_request(hdev, buf[0], buf, size, type, HID_REQ_GET_REPORT); - } while ((retval == -ETIMEDOUT || retval == -EPIPE) --retries); + } while ((retval == -ETIMEDOUT || retval == -EAGAIN) --retries); + + if (retval 0) + hid_err(hdev, wacom_get_report: ran out of retries + (last error = %d)\n, retval); return retval; } @@ -48,7 +52,11 @@ static int wacom_set_report(struct hid_device *hdev, u8 type, u8 *buf, do { retval = hid_hw_raw_request(hdev, buf[0], buf, size, type, HID_REQ_SET_REPORT); - } while ((retval == -ETIMEDOUT || retval == -EPIPE) --retries); + } while ((retval == -ETIMEDOUT || retval == -EAGAIN) --retries); + + if (retval 0) + hid_err(hdev, wacom_set_report: ran out of retries + (last error = %d)\n, retval); return retval; } -- 2.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] HID: wacom: retrieve name from HID descriptor for generic devices
On 4/20/2015 2:09 PM, Ping Cheng wrote: HID generic devices share the same default name, Wacom HID. This causes userland programs to show same device names for different devices, which would confuse end users with same device names for different devices too. This patch uses name retrieved from HID descriptor, if a meaningful name is reported. Otherwise, affix its product ID to Wacom HID. Signed-off-by: Ping Cheng pi...@wacom.com --- v2: updated with Jason's pid affix and extract whitespace suggestions. --- drivers/hid/wacom_sys.c | 53 +++-- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 1b00d8d..a857cd2 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1392,6 +1392,47 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev) return size; } +static void wacom_update_name(struct wacom *wacom) +{ + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct wacom_features *features = wacom_wac-features; + + /* Generic devices name unspecified */ + if ((features-type == HID_GENERIC) !strcmp(Wacom HID, features-name)) { + if (strstr(wacom-hdev-name, Wacom) || + strstr(wacom-hdev-name, wacom) || + strstr(wacom-hdev-name, WACOM)) { + /* name is in HID descriptor, use it */ + strlcpy(wacom_wac-name, wacom-hdev-name, + sizeof(wacom_wac-name)); + + /* strip out excess whitespaces */ + while (1) { + char *gap = strstr(wacom_wac-name, ); + if (gap == NULL) + break; + memmove(gap, gap+1, strlen(gap)); + } Alas, my snippet doesn't work as intended when placed here. It will remove extra internal whitespace without issue, but will leave a single trailing space at the end of the string if there were one or more spaces there originally. Because of this, a double space can be re-introduced once you append the e.g. Pen suffix below. I suggested the loop be placed at the bottom of the function because of this. Alternatively, you could put a call to 'strim' immediately before or after the loop to get rid of the extra trailing space (though I don't particularly like how it smells): memmove(wacom_wac-name, strim(wacom_wac-name), \ strlen(wacom_wac-name)+1); Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours + } else { + /* no meaningful name retrieved. use product ID */ + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s %x, features-name, wacom-hdev-product); + } + } else { + strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); + } + snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), + %s Pad, wacom_wac-name); + + /* Append the device type to the name */ + if (features-device_type != BTN_TOOL_FINGER) + strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); + else if (features-touch_max) + strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); + else + strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); +} + static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -1517,17 +1558,7 @@ static int wacom_probe(struct hid_device *hdev, } wacom_calculate_res(features); - strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); - snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), - %s Pad, features-name); - - /* Append the device type to the name */ - if (features-device_type != BTN_TOOL_FINGER) - strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); - else if (features-touch_max) - strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); - else - strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); + wacom_update_name(wacom); error = wacom_add_shared_data(hdev); if (error) -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] HID: wacom: move all quirks to wacom_setup_device_quirks
On 4/15/2015 4:53 PM, Ping Cheng wrote: It makes probe routine easy to follow. Signed-off-by: Ping Cheng pi...@wacom.com For patches 2-4, Reviewed-by: Jason Gerecke jason.gere...@wacom.com Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours --- drivers/hid/wacom.h | 2 +- drivers/hid/wacom_sys.c | 39 +-- drivers/hid/wacom_wac.c | 30 +- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index ad7318d..0f189c2 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -132,7 +132,7 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) extern const struct hid_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_device_quirks(struct wacom *wacom); int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 4c5d924..ca30eab 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1504,44 +1504,7 @@ static int wacom_probe(struct hid_device *hdev, /* Retrieve the physical and logical size for touch devices */ wacom_retrieve_hid_descriptor(hdev, features); - /* - * Intuos5 has no useful data about its touch interface in its - * HID descriptor. If this is the touch interface (PacketSize - * of WACOM_PKGLEN_BBTOUCH3), override the table values. - */ - if (features-type = INTUOS5S features-type = INTUOSHT) { - if (features-pktlen == WACOM_PKGLEN_BBTOUCH3) { - features-device_type = BTN_TOOL_FINGER; - - features-x_max = 4096; - features-y_max = 4096; - } else { - features-device_type = BTN_TOOL_PEN; - } - } - - /* - * Same thing for Bamboo 3rd gen. - */ - if ((features-type == BAMBOO_PT) - (features-pktlen == WACOM_PKGLEN_BBTOUCH3) - (features-device_type == BTN_TOOL_PEN)) { - features-device_type = BTN_TOOL_FINGER; - - features-x_max = 4096; - features-y_max = 4096; - } - - /* - * Same thing for Bamboo PAD - */ - if (features-type == BAMBOO_PAD) - features-device_type = BTN_TOOL_FINGER; - - if (hdev-bus == BUS_BLUETOOTH) - features-quirks |= WACOM_QUIRK_BATTERY; - - wacom_setup_device_quirks(features); + wacom_setup_device_quirks(wacom); /* set unit to 100th of a mm for devices not reported by HID */ if (!features-unit) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 69c7df7..952ed4c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2164,8 +2164,9 @@ 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) +void wacom_setup_device_quirks(struct wacom *wacom) { + struct wacom_features *features = wacom-wacom_wac.features; /* touch device found but size is not defined. use default */ if (features-device_type == BTN_TOOL_FINGER !features-x_max) { @@ -2173,6 +2174,33 @@ void wacom_setup_device_quirks(struct wacom_features *features) features-y_max = 1023; } + /* + * Intuos5/Pro and Bamboo 3rd gen have no useful data about its + * touch interface in its HID descriptor. If this is the touch + * interface (PacketSize of WACOM_PKGLEN_BBTOUCH3), override the + * tablet values. + */ + if ((features-type = INTUOS5S features-type = INTUOSHT) || + (features-type == BAMBOO_PT)) { + if (features-pktlen == WACOM_PKGLEN_BBTOUCH3) { + features-device_type = BTN_TOOL_FINGER; + + features-x_max = 4096; + features-y_max = 4096; + } else { + features-device_type = BTN_TOOL_PEN; + } + } + + /* + * Same thing for Bamboo PAD + */ + if (features-type == BAMBOO_PAD) + features-device_type = BTN_TOOL_FINGER; + + if (wacom-hdev-bus == BUS_BLUETOOTH) + features-quirks |= WACOM_QUIRK_BATTERY; + /* quirk for bamboo touch with 2 low res touches */ if (features-type == BAMBOO_PT features-pktlen == WACOM_PKGLEN_BBTOUCH
Re: [PATCH 1/4] HID: wacom: retrieve name from HID descriptor for generic devices
On 4/15/2015 4:52 PM, Ping Cheng wrote: HID generic devices share the same default name, Wacom HID. This causes userland programs to show same device names for different devices, which would confuse end users with same device names for different devices too. This patch uses name retrieved from HID descriptor, if a meaningful name is reported. Otherwise, affix its product ID to Wacom HID. Signed-off-by: Ping Cheng pi...@wacom.com --- drivers/hid/wacom_sys.c | 45 ++--- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 1b00d8d..4c5d924 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1392,6 +1392,39 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev) return size; } +static void wacom_update_name(struct wacom *wacom) +{ + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct wacom_features *features = wacom_wac-features; + + /* Generic devices name unspecified */ + if ((features-type == HID_GENERIC) !strcmp(Wacom HID, features-name)) { + if (strstr(wacom-hdev-name, Wacom) || + strstr(wacom-hdev-name, wacom) || + strstr(wacom-hdev-name, WACOM)) { + /* name is in HID descriptor, use it */ + strlcpy(wacom_wac-name, wacom-hdev-name, + sizeof(wacom_wac-name)); + } else { + /* no meaningful name retrieved. use product ID */ + snprintf(wacom_wac-name, sizeof(wacom_wac-name), + %s %x, features-name, wacom_wac-pid); 'wacom_wac-pid' doesn't seem to have been initialized at this point. 'wacom-hdev-product' works, however. + } + } else { + strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); + } + snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), + %s Pad, wacom_wac-name); + + /* Append the device type to the name */ + if (features-device_type != BTN_TOOL_FINGER) + strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); + else if (features-touch_max) + strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); + else + strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); Some of the ISDv4 names seem to be full of excess whitespace. For example, I see names like: Wacom Co.,Ltd. Pen and MultiTouch Sensor Pen Wacom Co.,Ltd. Pen and MultiTouch Sensor Touch I'd suggest adding an additional block similar to the following at this point in the code to fix it: /* strip out excess whitespace */ while (1) { char *gap = strstr(wacom-wac-name, ); if (gap == NULL) break; memmove(gap, gap+1, strlen(gap+1)+1); } -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours +} + static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -1517,17 +1550,7 @@ static int wacom_probe(struct hid_device *hdev, } wacom_calculate_res(features); - strlcpy(wacom_wac-name, features-name, sizeof(wacom_wac-name)); - snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), - %s Pad, features-name); - - /* Append the device type to the name */ - if (features-device_type != BTN_TOOL_FINGER) - strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); - else if (features-touch_max) - strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); - else - strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); + wacom_update_name(wacom); error = wacom_add_shared_data(hdev); if (error) -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Simplify check for presence of single-finger touch
To determine if a touch is present in the single-touch case, we can simply check if the BTN_TOUCH key is active or not. This will work for both HID_GENERIC and other device types. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/wacom_wac.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 69c7df7..2292d85 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1072,9 +1072,8 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) int count = 0; int i; - /* non-HID_GENERIC single touch input doesn't call this routine */ - if ((touch_max == 1) (wacom-features.type == HID_GENERIC)) - return wacom-hid_data.tipswitch + if (touch_max == 1) + return test_bit(BTN_TOUCH, input-key) !wacom-shared-stylus_in_proximity; for (i = 0; i input-mt-num_slots; i++) { -- 2.3.5 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] HID: wacom: remove hardcoded WACOM_QUIRK_MULTI_INPUT
On 3/20/2015 2:57 PM, Ping Cheng wrote: The quirk was added for devices that support both pen and touch. It decides if a device supports multiple inputs by hardcoded feature type. However, for some devices, we do not know if they support both before accessing their HID descriptors. This patch relies on dynamically assigned device_type to make the decision. Also, we make it certain that wacom_wac-shared is always created. That is, the driver will not be loaded if it fails to create wacom_wac-shared. Signed-off-by: Ping Cheng pi...@wacom.com Reviewed-by: Jason Gerecke jason.gere...@wacom.com --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours --- drivers/hid/wacom_sys.c | 24 +++- drivers/hid/wacom_wac.c | 18 -- drivers/hid/wacom_wac.h | 9 - 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index f0568a7..a99e66f 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1462,19 +1462,17 @@ static int wacom_probe(struct hid_device *hdev, snprintf(wacom_wac-pad_name, sizeof(wacom_wac-pad_name), %s Pad, features-name); - if (features-quirks WACOM_QUIRK_MULTI_INPUT) { - /* Append the device type to the name */ - if (features-device_type != BTN_TOOL_FINGER) - strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); - else if (features-touch_max) - strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); - else - strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); - - error = wacom_add_shared_data(hdev); - if (error) - goto fail_shared_data; - } + /* Append the device type to the name */ + if (features-device_type != BTN_TOOL_FINGER) + strlcat(wacom_wac-name, Pen, WACOM_NAME_MAX); + else if (features-touch_max) + strlcat(wacom_wac-name, Finger, WACOM_NAME_MAX); + else + strlcat(wacom_wac-name, Pad, WACOM_NAME_MAX); + + error = wacom_add_shared_data(hdev); + if (error) + goto fail_shared_data; if (!(features-quirks WACOM_QUIRK_MONITOR) (features-quirks WACOM_QUIRK_BATTERY)) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bbe32d6..3b01dc9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -551,12 +551,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) (features-type == CINTIQ !(data[1] 0x40))) return 1; - if (wacom-shared) { - wacom-shared-stylus_in_proximity = true; - - if (wacom-shared-touch_down) - return 1; - } + wacom-shared-stylus_in_proximity = true; + if (wacom-shared-touch_down) + return 1; /* in Range while exiting */ if (((data[1] 0xfe) == 0x20) wacom-reporting_data) { @@ -568,8 +565,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) /* Exit report */ if ((data[1] 0xfe) == 0x80) { - if (features-quirks WACOM_QUIRK_MULTI_INPUT) - wacom-shared-stylus_in_proximity = false; + wacom-shared-stylus_in_proximity = false; wacom-reporting_data = false; /* don't report exit if we don't know the ID */ @@ -2054,12 +2050,6 @@ void wacom_setup_device_quirks(struct wacom_features *features) features-y_max = 1023; } - /* these device have multiple inputs */ - if (features-type = WIRELESS || - (features-type = INTUOS5S features-type = INTUOSHT) || - (features-oVid features-oPid)) - features-quirks |= WACOM_QUIRK_MULTI_INPUT; - /* quirk for bamboo touch with 2 low res touches */ if (features-type == BAMBOO_PT features-pktlen == WACOM_PKGLEN_BBTOUCH) { diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 021ee1c..309f219 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -69,11 +69,10 @@ #define WACOM_REPORT_USB 192 /* device quirks */ -#define WACOM_QUIRK_MULTI_INPUT0x0001 -#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 -#define WACOM_QUIRK_NO_INPUT 0x0004 -#define WACOM_QUIRK_MONITOR0x0008 -#define WACOM_QUIRK_BATTERY0x0010 +#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 +#define WACOM_QUIRK_NO_INPUT 0x0002 +#define WACOM_QUIRK_MONITOR0x0004 +#define WACOM_QUIRK_BATTERY0x0008 #define WACOM_PEN_FIELD(f)(((f)-logical == HID_DG_STYLUS) || \ ((f)-physical == HID_DG_STYLUS
Re: [PATCH v2] HID: wacom: ask for a in-prox report when it was missed
On 3/16/2015 12:27 PM, Benjamin Tissoires wrote: On Mar 16 2015 or thereabouts, Jason Gerecke wrote: On 3/16/2015 7:50 AM, Jiri Kosina wrote: On Thu, 5 Mar 2015, Benjamin Tissoires wrote: If noone listens to the input device when a tool comes in proximity, the tablet does not send the in-prox event when a client becomes available. That means that no events will be sent until the tool is taken out of proximity. In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will read the corresponding feature and generate an in-prox event. To make some generation of hardware working, we need to unset the quirk NO_GET set by hid-core because the interfaces are seen as boot mouse. We don't schedule this read in a worker while we are in an IO interrupt. We know that usbhid will do it asynchronously. If this is triggered by uhid, then this is obviously a client side bug :) Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com Ping, Jason, I'd like to get your Ack on this before pushing this through if possible. Thanks. This update seems to have solved the issue I was having earlier. I do still see some weird behavior with the Intuos3 though. For whatever reason, if a tool is in prox and no client is connected, the device will repeatedly connect and disconnect from the bus. For example, while sitting at a VT after connecting the device: [ 209.890431] usb 2-1.5.4: new full-speed USB device number 10 using ehci-pci [ 209.992189] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input26 [ 209.992475] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input27 [ 209.992846] wacom 0003:056A:00B1.0009: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 213.022545] usb 2-1.5.4: USB disconnect, device number 10 [ 213.344055] usb 2-1.5.4: new full-speed USB device number 11 using ehci-pci [ 213.445779] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input28 [ 213.446185] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input29 [ 213.446703] wacom 0003:056A:00B1.000A: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 214.815925] usb 2-1.5.4: USB disconnect, device number 11 [ 215.246142] usb 2-1.5.4: new full-speed USB device number 12 using ehci-pci [ ... and so on ...] It makes using the device from a VT difficult (e.g. for debugging), but in the typical case where X is started shortly after boot and hotplugs devices as soon as they're available it shouldn't pose a problem. If Benjamin has any ideas I'd like to hear them, but in the meantime I'm comfortable seeing this go upstream: HID_QUIRK_ALWAYS_POLL :) Some usb devices do not like to not be polled and keep disconnecting/reconnecting. Looks like the Intuos 3 is one of them. The only cons are that the device won't save power when no one is reading the inputs. Not sure if that is a requirement for Wacom tablets though. Note that HID_QUIRK_ALWAYS_POLL should make this patch useless in these cases, the kernel will keep track of the current device because it will receive the events. Acked-by: Jason Gerecke killert...@gmail.com Thanks! Cheers, Benjamin That does indeed seem to solve the Intuos3 weirdness :) Saving power is a big deal for ISDv4/5 sensors where it has a direct impact on runtime. If setting HID_QURIK_ALWAYS_POLL e.g. disables USB selective suspend then that'd be an issue. However, if it simply causes the kernel to respond to events even if nobody is listening then it'd probably be similar to the situation when we were under drivers/input. I'm inclined to say we should target that quirk at only those devices that need it since I know tablet PC manufacturers go to quite some lengths to minimize every mA of unnecessary current draw from the batteries. -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] HID: wacom: ask for a in-prox report when it was missed
On 3/16/2015 2:04 PM, Benjamin Tissoires wrote: On Mar 16 2015 or thereabouts, Jason Gerecke wrote: On 3/16/2015 12:27 PM, Benjamin Tissoires wrote: On Mar 16 2015 or thereabouts, Jason Gerecke wrote: On 3/16/2015 7:50 AM, Jiri Kosina wrote: On Thu, 5 Mar 2015, Benjamin Tissoires wrote: If noone listens to the input device when a tool comes in proximity, the tablet does not send the in-prox event when a client becomes available. That means that no events will be sent until the tool is taken out of proximity. In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will read the corresponding feature and generate an in-prox event. To make some generation of hardware working, we need to unset the quirk NO_GET set by hid-core because the interfaces are seen as boot mouse. We don't schedule this read in a worker while we are in an IO interrupt. We know that usbhid will do it asynchronously. If this is triggered by uhid, then this is obviously a client side bug :) Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com Ping, Jason, I'd like to get your Ack on this before pushing this through if possible. Thanks. This update seems to have solved the issue I was having earlier. I do still see some weird behavior with the Intuos3 though. For whatever reason, if a tool is in prox and no client is connected, the device will repeatedly connect and disconnect from the bus. For example, while sitting at a VT after connecting the device: [ 209.890431] usb 2-1.5.4: new full-speed USB device number 10 using ehci-pci [ 209.992189] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input26 [ 209.992475] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input27 [ 209.992846] wacom 0003:056A:00B1.0009: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 213.022545] usb 2-1.5.4: USB disconnect, device number 10 [ 213.344055] usb 2-1.5.4: new full-speed USB device number 11 using ehci-pci [ 213.445779] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input28 [ 213.446185] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input29 [ 213.446703] wacom 0003:056A:00B1.000A: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 214.815925] usb 2-1.5.4: USB disconnect, device number 11 [ 215.246142] usb 2-1.5.4: new full-speed USB device number 12 using ehci-pci [ ... and so on ...] It makes using the device from a VT difficult (e.g. for debugging), but in the typical case where X is started shortly after boot and hotplugs devices as soon as they're available it shouldn't pose a problem. If Benjamin has any ideas I'd like to hear them, but in the meantime I'm comfortable seeing this go upstream: HID_QUIRK_ALWAYS_POLL :) Some usb devices do not like to not be polled and keep disconnecting/reconnecting. Looks like the Intuos 3 is one of them. The only cons are that the device won't save power when no one is reading the inputs. Not sure if that is a requirement for Wacom tablets though. Note that HID_QUIRK_ALWAYS_POLL should make this patch useless in these cases, the kernel will keep track of the current device because it will receive the events. Acked-by: Jason Gerecke killert...@gmail.com Thanks! Cheers, Benjamin That does indeed seem to solve the Intuos3 weirdness :) Saving power is a big deal for ISDv4/5 sensors where it has a direct impact on runtime. If setting HID_QURIK_ALWAYS_POLL e.g. disables USB selective suspend then that'd be an issue. However, if it simply causes the kernel to respond to events even if nobody is listening then it'd probably be similar to the situation when we were under drivers/input. I'm inclined to say we should target that quirk at only those devices that need it since I know tablet PC manufacturers go to quite some lengths to minimize every mA of unnecessary current draw from the batteries. Just a thought, but it looks like the problematic generation have the QUIRK_NO_GET set by hid-core (boot interface). If you are on it, could I ask you to test to set HID_QUIRK_ALWAYS_POLL and unset HID_QUIRK_NO_GET only if HID_QUIRK_NO_GET was set? IIRC, there was no problems on the Intuos 4+ with the USB suspend, so maybe that trick would be enough. Cheers, Benjamin I'm not sure that'll be enough. Most of our devices use a boot mouse interface, even some that work fine using the default quirks (e.g. Cintiq 24HDT). On the tablet PC side of the world, it looks like its a crapshoot whether the sensor will have a boot mouse collection or something else (though I haven't yet checked to see how they react to having a pen in prox without a client). -- Jason --- Now instead of four in the eights
Re: [PATCH v2] HID: wacom: ask for a in-prox report when it was missed
On 3/16/2015 2:04 PM, Benjamin Tissoires wrote: On Mar 16 2015 or thereabouts, Jason Gerecke wrote: On 3/16/2015 12:27 PM, Benjamin Tissoires wrote: On Mar 16 2015 or thereabouts, Jason Gerecke wrote: On 3/16/2015 7:50 AM, Jiri Kosina wrote: On Thu, 5 Mar 2015, Benjamin Tissoires wrote: If noone listens to the input device when a tool comes in proximity, the tablet does not send the in-prox event when a client becomes available. That means that no events will be sent until the tool is taken out of proximity. In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will read the corresponding feature and generate an in-prox event. To make some generation of hardware working, we need to unset the quirk NO_GET set by hid-core because the interfaces are seen as boot mouse. We don't schedule this read in a worker while we are in an IO interrupt. We know that usbhid will do it asynchronously. If this is triggered by uhid, then this is obviously a client side bug :) Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com Ping, Jason, I'd like to get your Ack on this before pushing this through if possible. Thanks. This update seems to have solved the issue I was having earlier. I do still see some weird behavior with the Intuos3 though. For whatever reason, if a tool is in prox and no client is connected, the device will repeatedly connect and disconnect from the bus. For example, while sitting at a VT after connecting the device: [ 209.890431] usb 2-1.5.4: new full-speed USB device number 10 using ehci-pci [ 209.992189] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input26 [ 209.992475] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input27 [ 209.992846] wacom 0003:056A:00B1.0009: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 213.022545] usb 2-1.5.4: USB disconnect, device number 10 [ 213.344055] usb 2-1.5.4: new full-speed USB device number 11 using ehci-pci [ 213.445779] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input28 [ 213.446185] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input29 [ 213.446703] wacom 0003:056A:00B1.000A: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 214.815925] usb 2-1.5.4: USB disconnect, device number 11 [ 215.246142] usb 2-1.5.4: new full-speed USB device number 12 using ehci-pci [ ... and so on ...] It makes using the device from a VT difficult (e.g. for debugging), but in the typical case where X is started shortly after boot and hotplugs devices as soon as they're available it shouldn't pose a problem. If Benjamin has any ideas I'd like to hear them, but in the meantime I'm comfortable seeing this go upstream: HID_QUIRK_ALWAYS_POLL :) Some usb devices do not like to not be polled and keep disconnecting/reconnecting. Looks like the Intuos 3 is one of them. The only cons are that the device won't save power when no one is reading the inputs. Not sure if that is a requirement for Wacom tablets though. Note that HID_QUIRK_ALWAYS_POLL should make this patch useless in these cases, the kernel will keep track of the current device because it will receive the events. Acked-by: Jason Gerecke killert...@gmail.com Thanks! Cheers, Benjamin That does indeed seem to solve the Intuos3 weirdness :) Saving power is a big deal for ISDv4/5 sensors where it has a direct impact on runtime. If setting HID_QURIK_ALWAYS_POLL e.g. disables USB selective suspend then that'd be an issue. However, if it simply causes the kernel to respond to events even if nobody is listening then it'd probably be similar to the situation when we were under drivers/input. I'm inclined to say we should target that quirk at only those devices that need it since I know tablet PC manufacturers go to quite some lengths to minimize every mA of unnecessary current draw from the batteries. Just a thought, but it looks like the problematic generation have the QUIRK_NO_GET set by hid-core (boot interface). If you are on it, could I ask you to test to set HID_QUIRK_ALWAYS_POLL and unset HID_QUIRK_NO_GET only if HID_QUIRK_NO_GET was set? IIRC, there was no problems on the Intuos 4+ with the USB suspend, so maybe that trick would be enough. Cheers, Benjamin I'm not sure that'll be enough. Most of our devices use a boot mouse interface, even some that work fine using the default quirks (e.g. Cintiq 24HDT). On the tablet PC side of the world, it looks like its a crapshoot whether the sensor will have a boot mouse collection or something else (though I haven't yet checked to see how they react to having a pen in prox without a client). -- Jason --- Now instead of four in the eights
Re: [PATCH v2] HID: wacom: ask for a in-prox report when it was missed
On 3/16/2015 7:50 AM, Jiri Kosina wrote: On Thu, 5 Mar 2015, Benjamin Tissoires wrote: If noone listens to the input device when a tool comes in proximity, the tablet does not send the in-prox event when a client becomes available. That means that no events will be sent until the tool is taken out of proximity. In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will read the corresponding feature and generate an in-prox event. To make some generation of hardware working, we need to unset the quirk NO_GET set by hid-core because the interfaces are seen as boot mouse. We don't schedule this read in a worker while we are in an IO interrupt. We know that usbhid will do it asynchronously. If this is triggered by uhid, then this is obviously a client side bug :) Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com Ping, Jason, I'd like to get your Ack on this before pushing this through if possible. Thanks. This update seems to have solved the issue I was having earlier. I do still see some weird behavior with the Intuos3 though. For whatever reason, if a tool is in prox and no client is connected, the device will repeatedly connect and disconnect from the bus. For example, while sitting at a VT after connecting the device: [ 209.890431] usb 2-1.5.4: new full-speed USB device number 10 using ehci-pci [ 209.992189] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input26 [ 209.992475] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.0009/input/input27 [ 209.992846] wacom 0003:056A:00B1.0009: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 213.022545] usb 2-1.5.4: USB disconnect, device number 10 [ 213.344055] usb 2-1.5.4: new full-speed USB device number 11 using ehci-pci [ 213.445779] input: Wacom Intuos3 6x8 as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input28 [ 213.446185] input: Wacom Intuos3 6x8 Pad as /devices/pci:00/:00:1d.0/usb2/2-1/2-1.5/2-1.5.4/2-1.5.4:1.0/0003:056A:00B1.000A/input/input29 [ 213.446703] wacom 0003:056A:00B1.000A: hidraw4: USB HID v1.00 Mouse [Tablet PTZ-630] on usb-:00:1d.0-1.5.4/input0 [ 214.815925] usb 2-1.5.4: USB disconnect, device number 11 [ 215.246142] usb 2-1.5.4: new full-speed USB device number 12 using ehci-pci [ ... and so on ...] It makes using the device from a VT difficult (e.g. for debugging), but in the typical case where X is started shortly after boot and hotplugs devices as soon as they're available it shouldn't pose a problem. If Benjamin has any ideas I'd like to hear them, but in the meantime I'm comfortable seeing this go upstream: Acked-by: Jason Gerecke killert...@gmail.com -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/7] HID: wacom: Move handling of Intuos status packets to seperate function
On 3/9/2015 6:31 PM, Ping Cheng wrote: On Fri, Mar 6, 2015 at 11:47 AM, Jason Gerecke killert...@gmail.com wrote: In addition to the touchswitch state for Intuos, these packets are also sent by the Intuos Pro, Intuos5, and last-generation Bamboo tablets when using a wired connection. They contain, among other things, information about the optional wireless module and battery charge state (to be supported in subsuquent patches). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 36 +++- drivers/hid/wacom_wac.h | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bbf72f9..cb308c5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1740,20 +1740,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) unsigned char *data = wacom-data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; - if (data[0] != WACOM_REPORT_PENABLED data[0] != WACOM_REPORT_USB) + if (data[0] != WACOM_REPORT_PENABLED) return 0; - if (data[0] == WACOM_REPORT_USB) { - if (features-type == INTUOSHT - wacom-shared-touch_input - features-touch_max) { - input_report_switch(wacom-shared-touch_input, - SW_MUTE_DEVICE, data[8] 0x40); - input_sync(wacom-shared-touch_input); - } - return 0; - } - prox = (data[1] 0x20) == 0x20; /* @@ -1960,6 +1949,24 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) +{ + struct wacom_features *features = wacom_wac-features; + unsigned char *data = wacom_wac-data; + + if (data[0] != WACOM_REPORT_USB) + return 0; + + if (features-type == INTUOSHT + wacom_wac-shared-touch_input + features-touch_max) { + input_report_switch(wacom_wac-shared-touch_input, + SW_MUTE_DEVICE, data[8] 0x40); + input_sync(wacom_wac-shared-touch_input); + } + return 0; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -2044,7 +2051,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case BAMBOO_PT: case INTUOSHT: - sync = wacom_bpt_irq(wacom_wac, len); + if (wacom_wac-data[0] == WACOM_REPORT_USB) + sync = wacom_status_irq(wacom_wac, len); + else + sync = wacom_bpt_irq(wacom_wac, len); break; case BAMBOO_PAD: diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index a3d0828..ee6a545 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -71,6 +71,7 @@ #define WACOM_REPORT_USB 192 #define WACOM_REPORT_BPAD_PEN 3 #define WACOM_REPORT_BPAD_TOUCH16 +#define WACOM_PKGLEN_STATUS10 I don't see anywhere else WACOM_PKGLEN_STATUS is used. Do I miss something? Good catch. That's leftover cruft from an earlier revision which is not necessary anymore. I'll resubmit this patch with the hunk removed. Except that, the patchset looks good. Acked-by: Ping Cheng pin...@wacom.com Ping Speaking of small mistakes... s/pinbgc/pingc/ :) -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT0x0001 -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 7/7] HID: wacom: Add battery presence indicator to wireless tablets
Declares the POWER_SUPPLY_PROP_PRESENT property to provide userspace with a way to determine if the battery on a wireless tablet is plugged in. Although current wireless tablets do not explicitly report this information, it can be inferred from other state information. In particular, a battery is assumed to be present if any of the following are true: a non-zero battery level reported, the battery is reported as charging, or the tablet is operating wirelessly. Note: The last condition above may not strictly hold for the Graphire Wireless (it charges from a DC barrel jack instead of a USB port), but I do not know what is reported in the no-battery condition. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_sys.c | 4 drivers/hid/wacom_wac.c | 16 ++-- drivers/hid/wacom_wac.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 955ce7c..ab7bf84 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -945,6 +945,7 @@ static void wacom_destroy_leds(struct wacom *wacom) } static enum power_supply_property wacom_battery_props[] = { + POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_CAPACITY @@ -964,6 +965,9 @@ static int wacom_battery_get_property(struct power_supply *psy, int ret = 0; switch (psp) { + case POWER_SUPPLY_PROP_PRESENT: + val-intval = wacom-wacom_wac.bat_connected; + break; case POWER_SUPPLY_PROP_SCOPE: val-intval = POWER_SUPPLY_SCOPE_DEVICE; break; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 57faf5b..9262622 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -46,16 +46,19 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; static void wacom_notify_battery(struct wacom_wac *wacom_wac, - int bat_capacity, bool bat_charging, bool ps_connected) + int bat_capacity, bool bat_charging, bool bat_connected, + bool ps_connected) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); bool changed = wacom_wac-battery_capacity != bat_capacity || wacom_wac-bat_charging != bat_charging || + wacom_wac-bat_connected!= bat_connected || wacom_wac-ps_connected != ps_connected; if (changed) { wacom_wac-battery_capacity = bat_capacity; wacom_wac-bat_charging = bat_charging; + wacom_wac-bat_connected = bat_connected; wacom_wac-ps_connected = ps_connected; if (wacom-battery.dev) @@ -438,7 +441,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; wacom_notify_battery(wacom, battery_capacity, ps_connected, -ps_connected); +1, ps_connected); } exit: return retval; @@ -1029,6 +1032,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) ps_connected = (power_raw 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw 0x07]; wacom_notify_battery(wacom, battery_capacity, bat_charging, +battery_capacity || bat_charging, ps_connected); break; default: @@ -1936,13 +1940,13 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) } if (wacom-shared-type) - wacom_notify_battery(wacom, battery, charging, 0); + wacom_notify_battery(wacom, battery, charging, 1, 0); } else if (wacom-pid != 0) { /* disconnected while previously connected */ wacom-pid = 0; wacom_schedule_work(wacom); - wacom_notify_battery(wacom, 0, 0, 0); + wacom_notify_battery(wacom, 0, 0, 0, 0); } return 0; @@ -1970,7 +1974,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) bool charging = !!(data[8] 0x80); wacom_notify_battery(wacom_wac, battery, charging, -1); +battery || charging, 1); if (!wacom-battery.dev !(features-quirks WACOM_QUIRK_BATTERY)) { @@ -1984,7 +1988,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) features-quirks = ~WACOM_QUIRK_BATTERY; INIT_WORK(wacom-work
[PATCH 7/7] HID: wacom: Add battery presence indicator to wireless tablets
Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_sys.c | 4 drivers/hid/wacom_wac.c | 16 ++-- drivers/hid/wacom_wac.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 955ce7c..ab7bf84 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -945,6 +945,7 @@ static void wacom_destroy_leds(struct wacom *wacom) } static enum power_supply_property wacom_battery_props[] = { + POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_CAPACITY @@ -964,6 +965,9 @@ static int wacom_battery_get_property(struct power_supply *psy, int ret = 0; switch (psp) { + case POWER_SUPPLY_PROP_PRESENT: + val-intval = wacom-wacom_wac.bat_connected; + break; case POWER_SUPPLY_PROP_SCOPE: val-intval = POWER_SUPPLY_SCOPE_DEVICE; break; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 57faf5b..9262622 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -46,16 +46,19 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; static void wacom_notify_battery(struct wacom_wac *wacom_wac, - int bat_capacity, bool bat_charging, bool ps_connected) + int bat_capacity, bool bat_charging, bool bat_connected, + bool ps_connected) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); bool changed = wacom_wac-battery_capacity != bat_capacity || wacom_wac-bat_charging != bat_charging || + wacom_wac-bat_connected!= bat_connected || wacom_wac-ps_connected != ps_connected; if (changed) { wacom_wac-battery_capacity = bat_capacity; wacom_wac-bat_charging = bat_charging; + wacom_wac-bat_connected = bat_connected; wacom_wac-ps_connected = ps_connected; if (wacom-battery.dev) @@ -438,7 +441,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; wacom_notify_battery(wacom, battery_capacity, ps_connected, -ps_connected); +1, ps_connected); } exit: return retval; @@ -1029,6 +1032,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) ps_connected = (power_raw 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw 0x07]; wacom_notify_battery(wacom, battery_capacity, bat_charging, +battery_capacity || bat_charging, ps_connected); break; default: @@ -1936,13 +1940,13 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) } if (wacom-shared-type) - wacom_notify_battery(wacom, battery, charging, 0); + wacom_notify_battery(wacom, battery, charging, 1, 0); } else if (wacom-pid != 0) { /* disconnected while previously connected */ wacom-pid = 0; wacom_schedule_work(wacom); - wacom_notify_battery(wacom, 0, 0, 0); + wacom_notify_battery(wacom, 0, 0, 0, 0); } return 0; @@ -1970,7 +1974,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) bool charging = !!(data[8] 0x80); wacom_notify_battery(wacom_wac, battery, charging, -1); +battery || charging, 1); if (!wacom-battery.dev !(features-quirks WACOM_QUIRK_BATTERY)) { @@ -1984,7 +1988,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) features-quirks = ~WACOM_QUIRK_BATTERY; INIT_WORK(wacom-work, wacom_battery_work); wacom_schedule_work(wacom_wac); - wacom_notify_battery(wacom_wac, 0, 0, 0); + wacom_notify_battery(wacom_wac, 0, 0, 0, 0); } return 0; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index ee6a545..f3daf7b 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -213,6 +213,7 @@ struct wacom_wac { int battery_capacity; int num_contacts_left; int bat_charging; + int bat_connected; int ps_connected; u8 bt_features; u8 bt_high_speed; -- 2.3.0 -- To unsubscribe from this list: send the line
[PATCH 4/7] HID: wacom: Provide battery charge state to system over USB if available
If a wireless adapter (which contains the charging circuitry) is detected as being attached to the tablet then create a new battery interface and update its status as data is reported. Also destroy the battery if the adapter goes away. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 5d57fec..f1e53f1 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1952,6 +1952,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) { + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); struct wacom_features *features = wacom_wac-features; unsigned char *data = wacom_wac-data; @@ -1965,6 +1966,30 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) SW_MUTE_DEVICE, data[8] 0x40); input_sync(wacom_wac-shared-touch_input); } + + if (data[9] 0x02) { /* wireless module is attached */ + int battery = (data[8] 0x3f) * 100 / 31; + bool ps_connected = !!(data[8] 0x80); + bool charging = ps_connected + wacom_wac-battery_capacity 100; + + wacom_notify_battery(wacom_wac, battery, charging, +ps_connected); + + if (!wacom-battery.dev + !(features-quirks WACOM_QUIRK_BATTERY)) { + features-quirks |= WACOM_QUIRK_BATTERY; + INIT_WORK(wacom-work, wacom_battery_work); + wacom_schedule_work(wacom_wac); + } + } + else if ((features-quirks WACOM_QUIRK_BATTERY) +wacom-battery.dev) { + features-quirks = ~WACOM_QUIRK_BATTERY; + INIT_WORK(wacom-work, wacom_battery_work); + wacom_schedule_work(wacom_wac); + wacom_notify_battery(wacom_wac, 0, 0, 0); + } return 0; } -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] HID: wacom: Centralize updating of wacom_wac battery status
Has the 'wacom_notify_battery' function take on the job of detecting if updating the power supply is necessary to remove multiple nearly-identical 'if' blocks. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom.h | 7 -- drivers/hid/wacom_wac.c | 57 + 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 7db4328..b8344b1 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -129,13 +129,6 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) schedule_work(wacom-work); } -static inline void wacom_notify_battery(struct wacom_wac *wacom_wac) -{ - struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); - - power_supply_changed(wacom-battery); -} - extern const struct hid_device_id wacom_ids[]; void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index cb308c5..5d57fec 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -45,6 +45,24 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; */ static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; +static void wacom_notify_battery(struct wacom_wac *wacom_wac, + int bat_capacity, bool bat_charging, bool ps_connected) +{ + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + bool changed = wacom_wac-battery_capacity != bat_capacity || + wacom_wac-bat_charging != bat_charging || + wacom_wac-ps_connected != ps_connected; + + if (changed) { + wacom_wac-battery_capacity = bat_capacity; + wacom_wac-bat_charging = bat_charging; + wacom_wac-ps_connected = ps_connected; + + if (wacom-battery.dev) + power_supply_changed(wacom-battery); + } +} + static int wacom_penpartner_irq(struct wacom_wac *wacom) { unsigned char *data = wacom-data; @@ -419,12 +437,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) rw = (data[7] 2 0x07); battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; - if ((wacom-battery_capacity != battery_capacity) || - (wacom-ps_connected != ps_connected)) { - wacom-battery_capacity = battery_capacity; - wacom-ps_connected = ps_connected; - wacom_notify_battery(wacom); - } + wacom_notify_battery(wacom, battery_capacity, ps_connected, +ps_connected); } exit: return retval; @@ -1014,15 +1028,8 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) bat_charging = (power_raw 0x08) ? 1 : 0; ps_connected = (power_raw 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw 0x07]; - if ((wacom-battery_capacity != battery_capacity) || - (wacom-bat_charging != bat_charging) || - (wacom-ps_connected != ps_connected)) { - wacom-battery_capacity = battery_capacity; - wacom-bat_charging = bat_charging; - wacom-ps_connected = ps_connected; - wacom_notify_battery(wacom); - } - + wacom_notify_battery(wacom, battery_capacity, bat_charging, +ps_connected); break; default: dev_dbg(wacom-input-dev.parent, @@ -1910,7 +1917,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) connected = data[1] 0x01; if (connected) { - int pid, battery, ps_connected; + int pid, battery, ps_connected, charging; if ((wacom-shared-type == INTUOSHT) wacom-shared-touch_input @@ -1923,27 +1930,21 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) pid = get_unaligned_be16(data[6]); battery = (data[5] 0x3f) * 100 / 31; ps_connected = !!(data[5] 0x80); + charging = ps_connected wacom-battery_capacity 100; if (wacom-pid != pid) { wacom-pid = pid; wacom_schedule_work(wacom); } - if (wacom-shared-type - (battery != wacom-battery_capacity || -ps_connected != wacom-ps_connected)) { - wacom-battery_capacity = battery; - wacom-ps_connected = ps_connected; - wacom-bat_charging = ps_connected - wacom-battery_capacity 100
[PATCH 5/7] HID: wacom: Report battery status for Intuos Pro and Intuos5
Calls the wacom_status_irq function to report battery status for the Intuos Pro and Intuos5 (in addition to the already-reporting Intuos and last-generation Bamboo). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f1e53f1..726fedb 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2062,6 +2062,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case INTUOSPL: if (len == WACOM_PKGLEN_BBTOUCH3) sync = wacom_bpt3_touch(wacom_wac); + else if (wacom_wac-data[0] == WACOM_REPORT_USB) + sync = wacom_status_irq(wacom_wac, len); else sync = wacom_intuos_irq(wacom_wac); break; -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] HID: wacom: Report battery status for Intuos Pro and Intuos5
Calls the wacom_status_irq function to report battery status for the Intuos Pro and Intuos5 (in addition to the already-reporting Intuos and last-generation Bamboo). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f1e53f1..726fedb 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2062,6 +2062,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case INTUOSPL: if (len == WACOM_PKGLEN_BBTOUCH3) sync = wacom_bpt3_touch(wacom_wac); + else if (wacom_wac-data[0] == WACOM_REPORT_USB) + sync = wacom_status_irq(wacom_wac, len); else sync = wacom_intuos_irq(wacom_wac); break; -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] HID: wacom: Add battery presence indicator to wireless tablets
Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_sys.c | 4 drivers/hid/wacom_wac.c | 16 ++-- drivers/hid/wacom_wac.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 955ce7c..ab7bf84 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -945,6 +945,7 @@ static void wacom_destroy_leds(struct wacom *wacom) } static enum power_supply_property wacom_battery_props[] = { + POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_CAPACITY @@ -964,6 +965,9 @@ static int wacom_battery_get_property(struct power_supply *psy, int ret = 0; switch (psp) { + case POWER_SUPPLY_PROP_PRESENT: + val-intval = wacom-wacom_wac.bat_connected; + break; case POWER_SUPPLY_PROP_SCOPE: val-intval = POWER_SUPPLY_SCOPE_DEVICE; break; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 57faf5b..9262622 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -46,16 +46,19 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; static void wacom_notify_battery(struct wacom_wac *wacom_wac, - int bat_capacity, bool bat_charging, bool ps_connected) + int bat_capacity, bool bat_charging, bool bat_connected, + bool ps_connected) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); bool changed = wacom_wac-battery_capacity != bat_capacity || wacom_wac-bat_charging != bat_charging || + wacom_wac-bat_connected!= bat_connected || wacom_wac-ps_connected != ps_connected; if (changed) { wacom_wac-battery_capacity = bat_capacity; wacom_wac-bat_charging = bat_charging; + wacom_wac-bat_connected = bat_connected; wacom_wac-ps_connected = ps_connected; if (wacom-battery.dev) @@ -438,7 +441,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; wacom_notify_battery(wacom, battery_capacity, ps_connected, -ps_connected); +1, ps_connected); } exit: return retval; @@ -1029,6 +1032,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) ps_connected = (power_raw 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw 0x07]; wacom_notify_battery(wacom, battery_capacity, bat_charging, +battery_capacity || bat_charging, ps_connected); break; default: @@ -1936,13 +1940,13 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) } if (wacom-shared-type) - wacom_notify_battery(wacom, battery, charging, 0); + wacom_notify_battery(wacom, battery, charging, 1, 0); } else if (wacom-pid != 0) { /* disconnected while previously connected */ wacom-pid = 0; wacom_schedule_work(wacom); - wacom_notify_battery(wacom, 0, 0, 0); + wacom_notify_battery(wacom, 0, 0, 0, 0); } return 0; @@ -1970,7 +1974,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) bool charging = !!(data[8] 0x80); wacom_notify_battery(wacom_wac, battery, charging, -1); +battery || charging, 1); if (!wacom-battery.dev !(features-quirks WACOM_QUIRK_BATTERY)) { @@ -1984,7 +1988,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) features-quirks = ~WACOM_QUIRK_BATTERY; INIT_WORK(wacom-work, wacom_battery_work); wacom_schedule_work(wacom_wac); - wacom_notify_battery(wacom_wac, 0, 0, 0); + wacom_notify_battery(wacom_wac, 0, 0, 0, 0); } return 0; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index ee6a545..f3daf7b 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -213,6 +213,7 @@ struct wacom_wac { int battery_capacity; int num_contacts_left; int bat_charging; + int bat_connected; int ps_connected; u8 bt_features; u8 bt_high_speed; -- 2.3.0 -- To unsubscribe from this list: send the line
[PATCH 6/7] HID: wacom: Status packet provides 'charging', not 'powered' bit
The status packet for tablets which can use a wireless module contains a bit that is set if the battery is charging. This bit will be 0 if either a battery is not present or if the battery has reached full charge. Note that the charging circuit may continue to charge the battery for a short time after reaching 100%. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_sys.c | 2 ++ drivers/hid/wacom_wac.c | 14 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index dfa4be7..955ce7c 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -977,6 +977,8 @@ static int wacom_battery_get_property(struct power_supply *psy, else if (wacom-wacom_wac.battery_capacity == 100 wacom-wacom_wac.ps_connected) val-intval = POWER_SUPPLY_STATUS_FULL; + else if (wacom-wacom_wac.ps_connected) + val-intval = POWER_SUPPLY_STATUS_NOT_CHARGING; else val-intval = POWER_SUPPLY_STATUS_DISCHARGING; break; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 726fedb..57faf5b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1917,7 +1917,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) connected = data[1] 0x01; if (connected) { - int pid, battery, ps_connected, charging; + int pid, battery, charging; if ((wacom-shared-type == INTUOSHT) wacom-shared-touch_input @@ -1929,16 +1929,14 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) pid = get_unaligned_be16(data[6]); battery = (data[5] 0x3f) * 100 / 31; - ps_connected = !!(data[5] 0x80); - charging = ps_connected wacom-battery_capacity 100; + charging = !!(data[5] 0x80); if (wacom-pid != pid) { wacom-pid = pid; wacom_schedule_work(wacom); } if (wacom-shared-type) - wacom_notify_battery(wacom, battery, charging, -ps_connected); + wacom_notify_battery(wacom, battery, charging, 0); } else if (wacom-pid != 0) { /* disconnected while previously connected */ @@ -1969,12 +1967,10 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) if (data[9] 0x02) { /* wireless module is attached */ int battery = (data[8] 0x3f) * 100 / 31; - bool ps_connected = !!(data[8] 0x80); - bool charging = ps_connected - wacom_wac-battery_capacity 100; + bool charging = !!(data[8] 0x80); wacom_notify_battery(wacom_wac, battery, charging, -ps_connected); +1); if (!wacom-battery.dev !(features-quirks WACOM_QUIRK_BATTERY)) { -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] HID: wacom: Move handling of Intuos status packets to seperate function
In addition to the touchswitch state for Intuos, these packets are also sent by the Intuos Pro, Intuos5, and last-generation Bamboo tablets when using a wired connection. They contain, among other things, information about the optional wireless module and battery charge state (to be supported in subsuquent patches). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 36 +++- drivers/hid/wacom_wac.h | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bbf72f9..cb308c5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1740,20 +1740,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) unsigned char *data = wacom-data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; - if (data[0] != WACOM_REPORT_PENABLED data[0] != WACOM_REPORT_USB) + if (data[0] != WACOM_REPORT_PENABLED) return 0; - if (data[0] == WACOM_REPORT_USB) { - if (features-type == INTUOSHT - wacom-shared-touch_input - features-touch_max) { - input_report_switch(wacom-shared-touch_input, - SW_MUTE_DEVICE, data[8] 0x40); - input_sync(wacom-shared-touch_input); - } - return 0; - } - prox = (data[1] 0x20) == 0x20; /* @@ -1960,6 +1949,24 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) +{ + struct wacom_features *features = wacom_wac-features; + unsigned char *data = wacom_wac-data; + + if (data[0] != WACOM_REPORT_USB) + return 0; + + if (features-type == INTUOSHT + wacom_wac-shared-touch_input + features-touch_max) { + input_report_switch(wacom_wac-shared-touch_input, + SW_MUTE_DEVICE, data[8] 0x40); + input_sync(wacom_wac-shared-touch_input); + } + return 0; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -2044,7 +2051,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case BAMBOO_PT: case INTUOSHT: - sync = wacom_bpt_irq(wacom_wac, len); + if (wacom_wac-data[0] == WACOM_REPORT_USB) + sync = wacom_status_irq(wacom_wac, len); + else + sync = wacom_bpt_irq(wacom_wac, len); break; case BAMBOO_PAD: diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index a3d0828..ee6a545 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -71,6 +71,7 @@ #define WACOM_REPORT_USB 192 #define WACOM_REPORT_BPAD_PEN 3 #define WACOM_REPORT_BPAD_TOUCH16 +#define WACOM_PKGLEN_STATUS10 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT0x0001 -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] HID: wacom: Provide battery charge state to system over USB if available
If a wireless adapter (which contains the charging circuitry) is detected as being attached to the tablet then create a new battery interface and update its status as data is reported. Also destroy the battery if the adapter goes away. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 5d57fec..f1e53f1 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1952,6 +1952,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) { + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); struct wacom_features *features = wacom_wac-features; unsigned char *data = wacom_wac-data; @@ -1965,6 +1966,30 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) SW_MUTE_DEVICE, data[8] 0x40); input_sync(wacom_wac-shared-touch_input); } + + if (data[9] 0x02) { /* wireless module is attached */ + int battery = (data[8] 0x3f) * 100 / 31; + bool ps_connected = !!(data[8] 0x80); + bool charging = ps_connected + wacom_wac-battery_capacity 100; + + wacom_notify_battery(wacom_wac, battery, charging, +ps_connected); + + if (!wacom-battery.dev + !(features-quirks WACOM_QUIRK_BATTERY)) { + features-quirks |= WACOM_QUIRK_BATTERY; + INIT_WORK(wacom-work, wacom_battery_work); + wacom_schedule_work(wacom_wac); + } + } + else if ((features-quirks WACOM_QUIRK_BATTERY) +wacom-battery.dev) { + features-quirks = ~WACOM_QUIRK_BATTERY; + INIT_WORK(wacom-work, wacom_battery_work); + wacom_schedule_work(wacom_wac); + wacom_notify_battery(wacom_wac, 0, 0, 0); + } return 0; } -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] HID: wacom: Allow dynamic battery creation/destruction
Tablets like the Intuos, Intuos Pro, and Bamboo have a connector for an optional wireless module that can be connected on the fly. The presence (or absence) of this module is indicated in a status report recieved from the tablet. This patch adds a workqueue function that will create or destroy a power_supply object at runtime to match the current state of the WACOM_QUIRK_BATTERY flag. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom.h | 1 + drivers/hid/wacom_sys.c | 17 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index b8344b1..ad7318d 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -142,4 +142,5 @@ void wacom_wac_usage_mapping(struct hid_device *hdev, int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value); void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); +void wacom_battery_work(struct work_struct *work); #endif diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 957699f..dfa4be7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1057,8 +1057,7 @@ static int wacom_initialize_battery(struct wacom *wacom) static void wacom_destroy_battery(struct wacom *wacom) { - if ((wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) -wacom-battery.dev) { + if (wacom-battery.dev) { power_supply_unregister(wacom-battery); wacom-battery.dev = NULL; power_supply_unregister(wacom-ac); @@ -1329,6 +1328,20 @@ fail: return; } +void wacom_battery_work(struct work_struct *work) +{ + struct wacom *wacom = container_of(work, struct wacom, work); + + if ((wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) +!wacom-battery.dev) { + wacom_initialize_battery(wacom); + } + else if (!(wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) +wacom-battery.dev) { + wacom_destroy_battery(wacom); + } +} + /* * Not all devices report physical dimensions from HID. * Compute the default from hardcoded logical dimension -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] HID: wacom: Move handling of Intuos status packets to seperate function
In addition to the touchswitch state for Intuos, these packets are also sent by the Intuos Pro, Intuos5, and last-generation Bamboo tablets when using a wired connection. They contain, among other things, information about the optional wireless module and battery charge state (to be supported in subsuquent patches). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 36 +++- drivers/hid/wacom_wac.h | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bbf72f9..cb308c5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1740,20 +1740,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) unsigned char *data = wacom-data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; - if (data[0] != WACOM_REPORT_PENABLED data[0] != WACOM_REPORT_USB) + if (data[0] != WACOM_REPORT_PENABLED) return 0; - if (data[0] == WACOM_REPORT_USB) { - if (features-type == INTUOSHT - wacom-shared-touch_input - features-touch_max) { - input_report_switch(wacom-shared-touch_input, - SW_MUTE_DEVICE, data[8] 0x40); - input_sync(wacom-shared-touch_input); - } - return 0; - } - prox = (data[1] 0x20) == 0x20; /* @@ -1960,6 +1949,24 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) +{ + struct wacom_features *features = wacom_wac-features; + unsigned char *data = wacom_wac-data; + + if (data[0] != WACOM_REPORT_USB) + return 0; + + if (features-type == INTUOSHT + wacom_wac-shared-touch_input + features-touch_max) { + input_report_switch(wacom_wac-shared-touch_input, + SW_MUTE_DEVICE, data[8] 0x40); + input_sync(wacom_wac-shared-touch_input); + } + return 0; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -2044,7 +2051,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case BAMBOO_PT: case INTUOSHT: - sync = wacom_bpt_irq(wacom_wac, len); + if (wacom_wac-data[0] == WACOM_REPORT_USB) + sync = wacom_status_irq(wacom_wac, len); + else + sync = wacom_bpt_irq(wacom_wac, len); break; case BAMBOO_PAD: diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index a3d0828..ee6a545 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -71,6 +71,7 @@ #define WACOM_REPORT_USB 192 #define WACOM_REPORT_BPAD_PEN 3 #define WACOM_REPORT_BPAD_TOUCH16 +#define WACOM_PKGLEN_STATUS10 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT0x0001 -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] HID: wacom: Status packet provides 'charging', not 'powered' bit
The status packet for tablets which can use a wireless module contains a bit that is set if the battery is charging. This bit will be 0 if either a battery is not present or if the battery has reached full charge. Note that the charging circuit may continue to charge the battery for a short time after reaching 100%. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_sys.c | 2 ++ drivers/hid/wacom_wac.c | 14 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index dfa4be7..955ce7c 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -977,6 +977,8 @@ static int wacom_battery_get_property(struct power_supply *psy, else if (wacom-wacom_wac.battery_capacity == 100 wacom-wacom_wac.ps_connected) val-intval = POWER_SUPPLY_STATUS_FULL; + else if (wacom-wacom_wac.ps_connected) + val-intval = POWER_SUPPLY_STATUS_NOT_CHARGING; else val-intval = POWER_SUPPLY_STATUS_DISCHARGING; break; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 726fedb..57faf5b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1917,7 +1917,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) connected = data[1] 0x01; if (connected) { - int pid, battery, ps_connected, charging; + int pid, battery, charging; if ((wacom-shared-type == INTUOSHT) wacom-shared-touch_input @@ -1929,16 +1929,14 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) pid = get_unaligned_be16(data[6]); battery = (data[5] 0x3f) * 100 / 31; - ps_connected = !!(data[5] 0x80); - charging = ps_connected wacom-battery_capacity 100; + charging = !!(data[5] 0x80); if (wacom-pid != pid) { wacom-pid = pid; wacom_schedule_work(wacom); } if (wacom-shared-type) - wacom_notify_battery(wacom, battery, charging, -ps_connected); + wacom_notify_battery(wacom, battery, charging, 0); } else if (wacom-pid != 0) { /* disconnected while previously connected */ @@ -1969,12 +1967,10 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) if (data[9] 0x02) { /* wireless module is attached */ int battery = (data[8] 0x3f) * 100 / 31; - bool ps_connected = !!(data[8] 0x80); - bool charging = ps_connected - wacom_wac-battery_capacity 100; + bool charging = !!(data[8] 0x80); wacom_notify_battery(wacom_wac, battery, charging, -ps_connected); +1); if (!wacom-battery.dev !(features-quirks WACOM_QUIRK_BATTERY)) { -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] HID: wacom: Centralize updating of wacom_wac battery status
Has the 'wacom_notify_battery' function take on the job of detecting if updating the power supply is necessary to remove multiple nearly-identical 'if' blocks. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom.h | 7 -- drivers/hid/wacom_wac.c | 57 + 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 7db4328..b8344b1 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -129,13 +129,6 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) schedule_work(wacom-work); } -static inline void wacom_notify_battery(struct wacom_wac *wacom_wac) -{ - struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); - - power_supply_changed(wacom-battery); -} - extern const struct hid_device_id wacom_ids[]; void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index cb308c5..5d57fec 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -45,6 +45,24 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; */ static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; +static void wacom_notify_battery(struct wacom_wac *wacom_wac, + int bat_capacity, bool bat_charging, bool ps_connected) +{ + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + bool changed = wacom_wac-battery_capacity != bat_capacity || + wacom_wac-bat_charging != bat_charging || + wacom_wac-ps_connected != ps_connected; + + if (changed) { + wacom_wac-battery_capacity = bat_capacity; + wacom_wac-bat_charging = bat_charging; + wacom_wac-ps_connected = ps_connected; + + if (wacom-battery.dev) + power_supply_changed(wacom-battery); + } +} + static int wacom_penpartner_irq(struct wacom_wac *wacom) { unsigned char *data = wacom-data; @@ -419,12 +437,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) rw = (data[7] 2 0x07); battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; - if ((wacom-battery_capacity != battery_capacity) || - (wacom-ps_connected != ps_connected)) { - wacom-battery_capacity = battery_capacity; - wacom-ps_connected = ps_connected; - wacom_notify_battery(wacom); - } + wacom_notify_battery(wacom, battery_capacity, ps_connected, +ps_connected); } exit: return retval; @@ -1014,15 +1028,8 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) bat_charging = (power_raw 0x08) ? 1 : 0; ps_connected = (power_raw 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw 0x07]; - if ((wacom-battery_capacity != battery_capacity) || - (wacom-bat_charging != bat_charging) || - (wacom-ps_connected != ps_connected)) { - wacom-battery_capacity = battery_capacity; - wacom-bat_charging = bat_charging; - wacom-ps_connected = ps_connected; - wacom_notify_battery(wacom); - } - + wacom_notify_battery(wacom, battery_capacity, bat_charging, +ps_connected); break; default: dev_dbg(wacom-input-dev.parent, @@ -1910,7 +1917,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) connected = data[1] 0x01; if (connected) { - int pid, battery, ps_connected; + int pid, battery, ps_connected, charging; if ((wacom-shared-type == INTUOSHT) wacom-shared-touch_input @@ -1923,27 +1930,21 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) pid = get_unaligned_be16(data[6]); battery = (data[5] 0x3f) * 100 / 31; ps_connected = !!(data[5] 0x80); + charging = ps_connected wacom-battery_capacity 100; if (wacom-pid != pid) { wacom-pid = pid; wacom_schedule_work(wacom); } - if (wacom-shared-type - (battery != wacom-battery_capacity || -ps_connected != wacom-ps_connected)) { - wacom-battery_capacity = battery; - wacom-ps_connected = ps_connected; - wacom-bat_charging = ps_connected - wacom-battery_capacity 100
[PATCH 3/7] HID: wacom: Allow dynamic battery creation/destruction
Tablets like the Intuos, Intuos Pro, and Bamboo have a connector for an optional wireless module that can be connected on the fly. The presence (or absence) of this module is indicated in a status report recieved from the tablet. This patch adds a workqueue function that will create or destroy a power_supply object at runtime to match the current state of the WACOM_QUIRK_BATTERY flag. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom.h | 1 + drivers/hid/wacom_sys.c | 17 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index b8344b1..ad7318d 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -142,4 +142,5 @@ void wacom_wac_usage_mapping(struct hid_device *hdev, int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value); void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); +void wacom_battery_work(struct work_struct *work); #endif diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 957699f..dfa4be7 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1057,8 +1057,7 @@ static int wacom_initialize_battery(struct wacom *wacom) static void wacom_destroy_battery(struct wacom *wacom) { - if ((wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) -wacom-battery.dev) { + if (wacom-battery.dev) { power_supply_unregister(wacom-battery); wacom-battery.dev = NULL; power_supply_unregister(wacom-ac); @@ -1329,6 +1328,20 @@ fail: return; } +void wacom_battery_work(struct work_struct *work) +{ + struct wacom *wacom = container_of(work, struct wacom, work); + + if ((wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) +!wacom-battery.dev) { + wacom_initialize_battery(wacom); + } + else if (!(wacom-wacom_wac.features.quirks WACOM_QUIRK_BATTERY) +wacom-battery.dev) { + wacom_destroy_battery(wacom); + } +} + /* * Not all devices report physical dimensions from HID. * Compute the default from hardcoded logical dimension -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] HID: wacom: rely on actual touch down count to decide touch_down
On 2/20/2015 2:27 PM, Ping Cheng wrote: touch_down is a flag to indicate if there are touches on tablet or not. Since one set of touch events may be posted over more than one data packet/touch frame, and pen may come in proximity while touch events are partially sent, counting all touch events for the set reflects the actual status of touch_down. Signed-off-by: Ping Cheng pi...@wacom.com Its a little ugly, but does the job. It seems like you could update touch_down once at the end of wacom_wac_irq by inspecting the slots, but I need to toy around with adapting wacom_wac_finger_count_touches some more... Acked-by: Jason Gerecke killert...@gmail.com -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours --- drivers/hid/wacom_wac.c | 75 - 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 69827c9..cf76741 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1046,27 +1046,28 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) struct input_dev *input = wacom-input; unsigned char *data = wacom-data; int i; - int current_num_contacts = 0; + int current_num_contacts = data[61]; int contacts_to_send = 0; int num_contacts_left = 4; /* maximum contacts per packet */ int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; int y_offset = 2; + static int contact_with_no_pen_down_count = 0; if (wacom-features.type == WACOM_27QHDT) { current_num_contacts = data[63]; num_contacts_left = 10; byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; y_offset = 0; - } else { - current_num_contacts = data[61]; } /* * First packet resets the counter since only the first * packet in series will have non-zero current_num_contacts. */ - if (current_num_contacts) + if (current_num_contacts) { wacom-num_contacts_left = current_num_contacts; + contact_with_no_pen_down_count = 0; + } contacts_to_send = min(num_contacts_left, wacom-num_contacts_left); @@ -1099,15 +1100,16 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); input_report_abs(input, ABS_MT_ORIENTATION, w h); } + contact_with_no_pen_down_count++; } } input_mt_report_pointer_emulation(input, true); wacom-num_contacts_left -= contacts_to_send; - if (wacom-num_contacts_left = 0) + if (wacom-num_contacts_left = 0) { wacom-num_contacts_left = 0; - - wacom-shared-touch_down = (wacom-num_contacts_left 0); + wacom-shared-touch_down = (contact_with_no_pen_down_count 0); + } return 1; } @@ -1119,6 +1121,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) int current_num_contacts = data[2]; int contacts_to_send = 0; int x_offset = 0; + static int contact_with_no_pen_down_count = 0; /* MTTPC does not support Height and Width */ if (wacom-features.type == MTTPC || wacom-features.type == MTTPC_B) @@ -1128,8 +1131,10 @@ static int wacom_mt_touch(struct wacom_wac *wacom) * First packet resets the counter since only the first * packet in series will have non-zero current_num_contacts. */ - if (current_num_contacts) + if (current_num_contacts) { wacom-num_contacts_left = current_num_contacts; + contact_with_no_pen_down_count = 0; + } /* There are at most 5 contacts per packet */ contacts_to_send = min(5, wacom-num_contacts_left); @@ -1150,15 +1155,16 @@ static int wacom_mt_touch(struct wacom_wac *wacom) int y = get_unaligned_le16(data[offset + x_offset + 9]); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); + contact_with_no_pen_down_count++; } } input_mt_report_pointer_emulation(input, true); wacom-num_contacts_left -= contacts_to_send; - if (wacom-num_contacts_left 0) + if (wacom-num_contacts_left = 0) { wacom-num_contacts_left = 0; - - wacom-shared-touch_down = (wacom-num_contacts_left 0); + wacom-shared-touch_down = (contact_with_no_pen_down_count 0); + } return 1; } @@ -1196,29 +1202,25 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len
Re: [PATCH 1/2] HID: wacom: do not send pen events before touch is up/forced out
On 2/20/2015 2:25 PM, Ping Cheng wrote: If pen comes in proximity while touch is down, we force touch up before sending pen events. Otherwise, there can be unfinished touch events compete with pen events. This idea has been fully implemented for Tablet PCs. But other tablets that support both pen and touch are not fully considered. Signed-off-by: Ping Cheng pi...@wacom.com Acked-by: Jason Gerecke killert...@gmail.com -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours --- drivers/hid/wacom_wac.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 046351c..69827c9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -554,6 +554,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) if (features-quirks WACOM_QUIRK_MULTI_INPUT) wacom-shared-stylus_in_proximity = true; + if (wacom-shared-touch_down) + return 1; + /* in Range while exiting */ if (((data[1] 0xfe) == 0x20) wacom-reporting_data) { input_report_key(input, BTN_TOUCH, 0); @@ -1759,6 +1762,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) return 0; } + if (wacom-shared-touch_down) + return 0; + prox = (data[1] 0x20) == 0x20; /* -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: wacom: ask for a in-prox report when it was missed
On 3/3/2015 9:20 AM, Benjamin Tissoires wrote: If noone listens to the input device when a tool comes in proximity, the tablet does not send the in-prox event when a client becomes available. That means that no events will be sent until the tool is taken out of proximity. In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will read the corresponding feature and generate an in-prox event. We don't schedule this read while we are in an IO interrupt because we know that usbhid will do it asynchronously. If this is triggered by uhid then this is obviously a client side bug :) Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com Ping and I were both a little confused by this patch. Our first impression was that this wouldn't accomplish anything since the driver would see events from the tablet regardless of if a client were connected or not. Testing proved us wrong though, with the events clearly going to that great /dev/null in the sky. Is this behavior different from the USB and HID subsystems? IIRC, the prox code didn't use to behave like this... Under the assumption that USB events are indeed being dropped until a client is connected, then this patch looks fairly reasonable. It doesn't, however, seem to work reliably across tablets. An Intuos Pro reacted as I'd expect (with the patch in place, already-in-prox tools actually send events once e.g. evemu-record is run) but didn't seem to do anything for an Intuos5 or Intuos3 (nothing comes through evemu-record until I removed the tool from prox and then put it back in). -- Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three, / So you look at the sixty-fours --- drivers/hid/wacom_wac.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 9ec4545..ff9a7ab 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -430,6 +430,19 @@ exit: return retval; } +static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) +{ + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + struct hid_report *r; + struct hid_report_enum *re; + + re = (wacom-hdev-report_enum[HID_FEATURE_REPORT]); + r = re-report_id_hash[WACOM_REPORT_INTUOSREAD]; + if (r) { + hid_hw_request(wacom-hdev, r, HID_REQ_GET_REPORT); + } +} + static int wacom_intuos_inout(struct wacom_wac *wacom) { struct wacom_features *features = wacom-features; @@ -609,8 +622,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) } /* don't report other events if we don't know the ID */ - if (!wacom-id[idx]) + if (!wacom-id[idx]) { + /* but reschedule a read of the current tool */ + wacom_intuos_schedule_prox_event(wacom); return 1; + } return 0; } -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: wacom: Report ABS_MISC event for Cintiq Companion Hybrid
It appears that the Cintiq Companion Hybrid does not send an ABS_MISC event to userspace when any of its ExpressKeys are pressed. This is not strictly necessary now that the pad exists on its own device, but should be fixed for consistency's sake. Traditionally both the stylus and pad shared the same device node, and xf86-input-wacom would use ABS_MISC for disambiguation. Not sending this causes the Hybrid to behave incorrectly with xf86-input-wacom beginning with its 8f44f3 commit. Signed-off-by: Jason Gerecke killert...@gmail.com --- Question: I'd like to write a version of this patch which targets stable releases where the stylus and pad share the device node. How would I go about submitting one, since CCing this patch to stable won't quite do the trick (the patches would have to be against our old home under drivers/input/tablet...) drivers/hid/wacom_wac.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a4ba8ca..f886149 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -783,6 +783,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_7, (data[4] 0x40)); /* Left */ input_report_key(input, BTN_8, (data[4] 0x80)); /* Down */ input_report_key(input, BTN_0, (data[3] 0x01)); /* Center */ + + if (data[4] | (data[3] 0x01)) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } } else if (features-type = INTUOS5S features-type = INTUOSPL) { int i; -- 2.2.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] HID: wacom: add support of the Pen of the Bamboo Pad
On Mon, Jan 5, 2015 at 1:32 PM, Benjamin Tissoires benjamin.tissoi...@redhat.com wrote: Bamboo Pads are using the generic processing but their report descriptors differ from the ISDv* line. The pen fields are marked with the .physical as Digitizer_Pen, which makes also sense. Add this field to the checks and enable for free Bamboo Pads. Reported-by: Josep Sanchez Ferreres josep.sanchez.ferre...@est.fib.upc.edu Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com --- Hi Jason, I still did not managed to put in shape the regression tests for the Wacom recordings we have. I do not think this will impact the current supported devices (none that I have present the HID_DG_PEN application/logical/physical tag). It would be good still if you could have a look and validate the patch series. Cheers, Benjamin None of the units I've collected descriptors for appear to have a HD_DG_PEN physical collection, so I also don't see any potential for regression. For both patches: Reviewed-by: Jason Gerecke killert...@gmail.com Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three,/ So you look at the sixty-fours drivers/hid/wacom_wac.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 7436f2b..7afd929 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -74,6 +74,7 @@ #define WACOM_PEN_FIELD(f) (((f)-logical == HID_DG_STYLUS) || \ ((f)-physical == HID_DG_STYLUS) || \ +((f)-physical == HID_DG_PEN) || \ ((f)-application == HID_DG_PEN)) #define WACOM_FINGER_FIELD(f) (((f)-logical == HID_DG_FINGER) || \ ((f)-physical == HID_DG_FINGER) || \ -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] HID: wacom: Report input events for each finger on generic devices
On Wed, Dec 10, 2014 at 12:25 PM, Benjamin Tissoires benjamin.tissoi...@gmail.com wrote: On Fri, Dec 5, 2014 at 4:37 PM, Jason Gerecke killert...@gmail.com wrote: The existing generic touch code only reports events after reading an entire HID report, which practically means that only data about the last contact in a report will ever be provided to userspace. This patch uses a trick from hid-multitouch.c to discover what type of field is at the end of each contact; when such a field is encountered all the stored contact data will be reported. Signed-off-by: Jason Gerecke killert...@gmail.com --- Thanks for the v2 Jason. I think we are closes to it. I have some comments on the style, but now that I have read it more carefully, I have a better idea of it, and the patch is not so scary. Jiri. If you reviewed it and took it, that's fine. If not, then I think there is still room for improvements. I'm really hoping to get this in for 3.19 if its possible, so I'm going to try to get this turned-around today... Cheers, Benjamin Changes from v1: * Patch renamed from HID: wacom: Report input events immediately upon receipt * Instead of reporting on-reciept, events are bundled and sent at the end of each contact * Adds code to discover 'last_slot_field' based on hid-multitouch.c implementation drivers/hid/wacom_wac.c | 94 - drivers/hid/wacom_wac.h | 1 + 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c33f889..75fc16e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1381,35 +1381,68 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; - unsigned touch_max = wacom_wac-features.touch_max; not sure we really need to remove the temporary variable touch_max here. + struct wacom_features *features = wacom_wac-features; switch (usage-hid) { case HID_GD_X: - if (touch_max == 1) + features-last_slot_field = usage-hid; + if (features-touch_max == 1) these changes (touchmax = features-touch_max) hinder a little bit the actual change, that is worrisome :) ACK. wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); else wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_X, 4); break; case HID_GD_Y: - if (touch_max == 1) + features-last_slot_field = usage-hid; + if (features-touch_max == 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); else wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_Y, 4); break; case HID_DG_CONTACTID: + features-last_slot_field = usage-hid; break; case HID_DG_INRANGE: + features-last_slot_field = usage-hid; break; case HID_DG_INVERT: + features-last_slot_field = usage-hid; break; case HID_DG_TIPSWITCH: + features-last_slot_field = usage-hid; wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); break; } } +static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + struct input_dev *input) +{ + struct hid_data *hid_data = wacom_wac-hid_data; + bool mt = wacom_wac-features.touch_max 1; + bool prox = hid_data-tipswitch + !wacom_wac-shared-stylus_in_proximity; + + if (mt) { Personal taste. I don't like the if (mt) approach in this patch. I preferred the old approach: if (mt) wacom_wac_finger_mt_slot() else wacom_wac_finger_touch() i.e. one function per case. I don't really like the idea of breaking this into two functions. The differences between how a each MT contact is reported and how the sole ST contact is reported are trivial, and I feel that breaking them apart leads to unnecessary duplication. I'll split it out if you feel that is warranted though. + int slot; + + slot = input_mt_get_slot_by_key(input, hid_data-id); + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); + } + else { + input_report_key(input, BTN_TOUCH, prox); + } + + if (prox) { + input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X, +hid_data-x); + input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y
[PATCH v3 3/3] HID: wacom: Report input events for each finger on generic devices
The existing generic touch code only reports events after reading an entire HID report, which practically means that only data about the last contact in a report will ever be provided to userspace. This patch uses a trick from hid-multitouch.c to discover what type of field is at the end of each contact; when such a field is encountered all the stored contact data will be reported. Signed-off-by: Jason Gerecke killert...@gmail.com --- Changes from v2: * No longer removing 'touch_max' variables to make changes clearer * Renamed 'wacom_wac_finger_touches' to 'wacom_wac_finger_count_touches' * Removed call to 'wacom_wac_finger_slot' in 'wacom_wac_finger_report' since it is already called for the single-touch case within 'wacom_wac_finger_event'. drivers/hid/wacom_wac.c | 86 + drivers/hid/wacom_wac.h | 1 + 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 064fd6c..26f27bd 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1381,10 +1381,12 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct wacom_features *features = wacom_wac-features; unsigned touch_max = wacom_wac-features.touch_max; switch (usage-hid) { case HID_GD_X: + features-last_slot_field = usage-hid; if (touch_max == 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); else @@ -1392,6 +1394,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, ABS_MT_POSITION_X, 4); break; case HID_GD_Y: + features-last_slot_field = usage-hid; if (touch_max == 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); else @@ -1399,17 +1402,48 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, ABS_MT_POSITION_Y, 4); break; case HID_DG_CONTACTID: + features-last_slot_field = usage-hid; break; case HID_DG_INRANGE: + features-last_slot_field = usage-hid; break; case HID_DG_INVERT: + features-last_slot_field = usage-hid; break; case HID_DG_TIPSWITCH: + features-last_slot_field = usage-hid; wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); break; } } +static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + struct input_dev *input) +{ + struct hid_data *hid_data = wacom_wac-hid_data; + bool mt = wacom_wac-features.touch_max 1; + bool prox = hid_data-tipswitch + !wacom_wac-shared-stylus_in_proximity; + + if (mt) { + int slot; + + slot = input_mt_get_slot_by_key(input, hid_data-id); + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); + } + else { + input_report_key(input, BTN_TOUCH, prox); + } + + if (prox) { + input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X, +hid_data-x); + input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, +hid_data-y); + } +} + static int wacom_wac_finger_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -1432,36 +1466,35 @@ static int wacom_wac_finger_event(struct hid_device *hdev, } + if (usage-usage_index + 1 == field-report_count) { + if (usage-hid == wacom_wac-features.last_slot_field) + wacom_wac_finger_slot(wacom_wac, wacom_wac-input); + } + return 0; } -static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, - struct input_dev *input, bool touch) +static int wacom_wac_finger_count_touches(struct hid_device *hdev) { - int slot; - struct hid_data *hid_data = wacom_wac-hid_data; + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct input_dev *input = wacom_wac-input; + unsigned touch_max = wacom_wac-features.touch_max; + int count = 0; + int i; - slot = input_mt_get_slot_by_key(input, hid_data-id); + if (touch_max == 1) + return wacom_wac-hid_data.tipswitch + !wacom_wac-shared-stylus_in_proximity; - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch
[PATCH v2 2/3] HID: wacom: Initialize MT slots for generic devices at post_parse_hid
If a HID descriptor places HID_DG_CONTACTID before HID_DG_X and HID_DG_Y then the ABS_X and ABS_Y will not be automatically initialized by the call to input_mt_init_slots. To ensure that this is not a problem, we relocate that call to occur after HID parsing has been completed and we've initalized all the multitouch axes. Signed-off-by: Jason Gerecke killert...@gmail.com --- Changes from v1: * Patch renamed from HID: wacom: Manually declare ABS_{X,Y} for pointer emulation * Patch moves call to input_mt_init_slots rather than manually declare ABS_{X,Y} drivers/hid/wacom_sys.c | 18 ++ drivers/hid/wacom_wac.c | 3 --- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index eb55316..872aa0b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -13,6 +13,7 @@ #include wacom_wac.h #include wacom.h +#include linux/input/mt.h #define WAC_MSG_RETRIES5 @@ -236,6 +237,21 @@ static void wacom_usage_mapping(struct hid_device *hdev, wacom_wac_usage_mapping(hdev, field, usage); } +static void wacom_post_parse_hid(struct hid_device *hdev, +struct wacom_features *features) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = wacom-wacom_wac; + + if (features-type == HID_GENERIC) { + /* Any last-minute generic device setup */ + if (features-touch_max 1) { + input_mt_init_slots(wacom_wac-input, wacom_wac-features.touch_max, + INPUT_MT_DIRECT); + } + } +} + static void wacom_parse_hid(struct hid_device *hdev, struct wacom_features *features) { @@ -270,6 +286,8 @@ static void wacom_parse_hid(struct hid_device *hdev, wacom_usage_mapping(hdev, hreport-field[i], hreport-field[i]-usage + j); } + + wacom_post_parse_hid(hdev, features); } static int wacom_hid_set_device_mode(struct hid_device *hdev) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a8a19a5..c33f889 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1381,7 +1381,6 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; - struct input_dev *input = wacom_wac-input; unsigned touch_max = wacom_wac-features.touch_max; switch (usage-hid) { @@ -1400,8 +1399,6 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, ABS_MT_POSITION_Y, 4); break; case HID_DG_CONTACTID: - input_mt_init_slots(input, wacom_wac-features.touch_max, - INPUT_MT_DIRECT); break; case HID_DG_INRANGE: break; -- 2.1.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] HID: wacom: Report input events for each finger on generic devices
The existing generic touch code only reports events after reading an entire HID report, which practically means that only data about the last contact in a report will ever be provided to userspace. This patch uses a trick from hid-multitouch.c to discover what type of field is at the end of each contact; when such a field is encountered all the stored contact data will be reported. Signed-off-by: Jason Gerecke killert...@gmail.com --- Changes from v1: * Patch renamed from HID: wacom: Report input events immediately upon receipt * Instead of reporting on-reciept, events are bundled and sent at the end of each contact * Adds code to discover 'last_slot_field' based on hid-multitouch.c implementation drivers/hid/wacom_wac.c | 94 - drivers/hid/wacom_wac.h | 1 + 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c33f889..75fc16e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1381,35 +1381,68 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; - unsigned touch_max = wacom_wac-features.touch_max; + struct wacom_features *features = wacom_wac-features; switch (usage-hid) { case HID_GD_X: - if (touch_max == 1) + features-last_slot_field = usage-hid; + if (features-touch_max == 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); else wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_X, 4); break; case HID_GD_Y: - if (touch_max == 1) + features-last_slot_field = usage-hid; + if (features-touch_max == 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); else wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_Y, 4); break; case HID_DG_CONTACTID: + features-last_slot_field = usage-hid; break; case HID_DG_INRANGE: + features-last_slot_field = usage-hid; break; case HID_DG_INVERT: + features-last_slot_field = usage-hid; break; case HID_DG_TIPSWITCH: + features-last_slot_field = usage-hid; wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); break; } } +static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + struct input_dev *input) +{ + struct hid_data *hid_data = wacom_wac-hid_data; + bool mt = wacom_wac-features.touch_max 1; + bool prox = hid_data-tipswitch + !wacom_wac-shared-stylus_in_proximity; + + if (mt) { + int slot; + + slot = input_mt_get_slot_by_key(input, hid_data-id); + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); + } + else { + input_report_key(input, BTN_TOUCH, prox); + } + + if (prox) { + input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X, +hid_data-x); + input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, +hid_data-y); + } +} + static int wacom_wac_finger_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -1432,36 +1465,35 @@ static int wacom_wac_finger_event(struct hid_device *hdev, } + if (usage-usage_index + 1 == field-report_count) { + if (usage-hid == wacom_wac-features.last_slot_field) + wacom_wac_finger_slot(wacom_wac, wacom_wac-input); + } + return 0; } -static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, - struct input_dev *input, bool touch) +static int wacom_wac_finger_touches(struct hid_device *hdev) { - int slot; - struct hid_data *hid_data = wacom_wac-hid_data; + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct input_dev *input = wacom_wac-input; + unsigned touch_max = wacom_wac-features.touch_max; + int count = 0; + int i; - slot = input_mt_get_slot_by_key(input, hid_data-id); + if (touch_max == 1) + return wacom_wac-hid_data.tipswitch + !wacom_wac-shared-stylus_in_proximity; - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch
[PATCH 3/3] HID: wacom: Report input events immediately upon receipt
Multitouch tablets cannot work properly if wacom_wac_finger_event simply stores the event details, since details about former fingers will be overwritten by later ones (causing wacom_wac_finger_report to effectively only report the state of the *last* finger in the packet). This patch modifies the logic so that events are generated as soon as possible in response to events. We do temporarily store HID_DG_TIPSWITCH value since the value of HID_DG_CONTACTID is (at least in for the tablets I've tested) not known until shortly afterwards. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 77 - 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a55e0ed..3eaa98a 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1412,19 +1412,40 @@ static int wacom_wac_finger_event(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct hid_data *data = wacom_wac-hid_data; + unsigned mt = wacom_wac-features.touch_max 1; + struct input_dev *input = wacom_wac-input; + bool prox = data-tipswitch !wacom_wac-shared-stylus_in_proximity; + int slot; switch (usage-hid) { case HID_GD_X: - wacom_wac-hid_data.x = value; + if (prox) { + input_report_abs(input, +mt ? ABS_MT_POSITION_X : ABS_X, +value); + } break; case HID_GD_Y: - wacom_wac-hid_data.y = value; + if (prox) { + input_report_abs(input, +mt ? ABS_MT_POSITION_Y : ABS_Y, +value); + } break; case HID_DG_CONTACTID: - wacom_wac-hid_data.id = value; + slot = input_mt_get_slot_by_key(input, value); + + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); break; case HID_DG_TIPSWITCH: - wacom_wac-hid_data.tipswitch = value; + data-tipswitch = value; + if (!mt) { + prox = data-tipswitch + !wacom_wac-shared-stylus_in_proximity; + input_report_key(input, BTN_TOUCH, prox); + } break; } @@ -1432,33 +1453,26 @@ static int wacom_wac_finger_event(struct hid_device *hdev, return 0; } -static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, - struct input_dev *input, bool touch) +static int wacom_wac_finger_touches(struct hid_device *hdev) { - int slot; - struct hid_data *hid_data = wacom_wac-hid_data; - - slot = input_mt_get_slot_by_key(input, hid_data-id); - - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch) { - input_report_abs(input, ABS_MT_POSITION_X, hid_data-x); - input_report_abs(input, ABS_MT_POSITION_Y, hid_data-y); - } - input_mt_sync_frame(input); -} + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = wacom-wacom_wac; + struct input_dev *input = wacom_wac-input; + unsigned touch_max = wacom_wac-features.touch_max; + int count = 0; + int i; -static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac, - struct input_dev *input, bool touch) -{ - struct hid_data *hid_data = wacom_wac-hid_data; + if (touch_max == 1) + return (wacom_wac-hid_data.tipswitch + !wacom_wac-shared-stylus_in_proximity); - if (touch) { - input_report_abs(input, ABS_X, hid_data-x); - input_report_abs(input, ABS_Y, hid_data-y); + for (i = 0; i input-mt-num_slots; i++) { + struct input_mt_slot *ps = input-mt-slots[i]; + int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); + if (id = 0) + count++; } - input_report_key(input, BTN_TOUCH, touch); + return count; } static void wacom_wac_finger_report(struct hid_device *hdev, @@ -1467,18 +1481,15 @@ static void wacom_wac_finger_report(struct hid_device *hdev, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = wacom-wacom_wac; struct input_dev *input = wacom_wac-input; - bool touch = wacom_wac-hid_data.tipswitch -!wacom_wac-shared-stylus_in_proximity; unsigned touch_max = wacom_wac-features.touch_max; if (touch_max 1
[PATCH 0/3] HID: wacom: Fix generic multitouch device handling
This set of patches addresses the problems that I had getting Benjamin's HID generic handling patches. Each of the patches addresses a seprate issue I encountered: * Patch 1/3: The devices that I'm using have some usages outside of a logical or physical collection container which prevents the reports from being sent. I'm not sure if keying on the application collection is ideal, but it does do the job. * Patch 2/3: The devices that I'm using put their X and Y usages after the finger count, which prevents the (compatibility) ABS_X and ABS_Y axes from being initialized. This patch just guarantees that they'll be initialized. * Patch 3/3: Benjamin's original code seemed to only report data about the last finger in a multitouch report since information about earlier fingers would be overwritten. This patch changes the logic so that we immediately report field values whenever we can (there are some cases that we can't -- the tip/range bits appear before the contact identifier, so we have to store their state for a short time). -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] HID: wacom: Consult the application usage when determining field type
It is not necessarily sufficient to look only at the physical and logical usages when determining if a field is for the pen or touch. Some fields are not contained in a sub-collection and thus only have an application usage. Not checking the application usage in such cases causes us to ignore the field entirely, which may lead to incorrect behavior. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 9565d31..1468f00 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1484,9 +1484,11 @@ static void wacom_wac_finger_report(struct hid_device *hdev, } #define WACOM_PEN_FIELD(f) (((f)-logical == HID_DG_STYLUS) || \ -((f)-physical == HID_DG_STYLUS)) +((f)-physical == HID_DG_STYLUS) || \ +((f)-application == HID_DG_PEN)) #define WACOM_FINGER_FIELD(f) (((f)-logical == HID_DG_FINGER) || \ -((f)-physical == HID_DG_FINGER)) +((f)-physical == HID_DG_FINGER) || \ +((f)-application == HID_DG_TOUCHSCREEN)) void wacom_wac_usage_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) -- 2.1.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] HID: wacom: Manually declare ABS_{X,Y} for pointer emulation
If a HID descriptor places HID_DG_CONTACTID before HID_DG_X and HID_DG_Y then the ABS_X and ABS_Y will not be automatically initialized by the call to input_mt_init_slots. Here we move the setup of those axes outside of the 'if' statement so that they're always present if the associated HID field is. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1468f00..a55e0ed 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1382,16 +1382,14 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, switch (usage-hid) { case HID_GD_X: - if (touch_max == 1) - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); - else + wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); + if (touch_max 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_X, 4); break; case HID_GD_Y: - if (touch_max == 1) - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); - else + wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); + if (touch_max 1) wacom_map_usage(wacom, usage, field, EV_ABS, ABS_MT_POSITION_Y, 4); break; -- 2.1.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] HID: wacom: Report ABS_TILT_{X,Y} as signed values
Centers the ABS_TILT_{X,Y} axes so that a value of zero is reported when the pen is vertical. Combined with resolution information in the next patch, this makes it possible for userspace to calculate the pen angle without needing hardware-specific knowledge. The xf86-input-wacom driver was updated to support signed tilt values in late-2012 (2f2acec). Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 8a83da9..525b648 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -600,8 +600,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) } input_report_abs(input, ABS_PRESSURE, t); input_report_abs(input, ABS_TILT_X, - ((data[7] 1) 0x7e) | (data[8] 7)); - input_report_abs(input, ABS_TILT_Y, data[8] 0x7f); +(((data[7] 1) 0x7e) | (data[8] 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] 0x7f) - 64); input_report_key(input, BTN_STYLUS, data[1] 2); input_report_key(input, BTN_STYLUS2, data[1] 4); input_report_key(input, BTN_TOUCH, t 10); @@ -612,8 +612,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) input_report_abs(input, ABS_WHEEL, (data[6] 2) | ((data[7] 6) 3)); input_report_abs(input, ABS_TILT_X, - ((data[7] 1) 0x7e) | (data[8] 7)); - input_report_abs(input, ABS_TILT_Y, data[8] 0x7f); +(((data[7] 1) 0x7e) | (data[8] 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] 0x7f) - 64); } } @@ -915,8 +915,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_EXTRA, data[6] 0x10); input_report_abs(input, ABS_TILT_X, - ((data[7] 1) 0x7e) | (data[8] 7)); - input_report_abs(input, ABS_TILT_Y, data[8] 0x7f); + (((data[7] 1) 0x7e) | (data[8] 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] 0x7f) - 64); } else { /* 2D mouse packet */ input_report_key(input, BTN_LEFT, data[8] 0x04); @@ -1926,8 +1926,8 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac-features.distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); } static void wacom_setup_intuos(struct wacom_wac *wacom_wac) -- 2.1.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] HID: wacom: Add angular resolution data to some ABS axes
Provide the resolution of several angular axes (tilt, pen rotation, puck rotation) to userspace. Because these values are natively degree-based, we need to convert them to into units/radian as required by the input_absinfo struct. To ensure wraparound behaves properly for the rotation axes, the converted value was rounded up rather than rounded nearest. Notably, the touchring axes (ABS_WHEEL and ABS_THROTTLE) are left without a a declared resolution because the their low resolution cannot be accurately represented (the worst-case rounding-induced error would be ~16 degrees). Pre-scaling the values and range by at least 10x would reduce the error in the resolution to acceptable levels, but the xf86-input-wacom driver is not able to use pre-scaled values for these axes at this time. Signed-off-by: Jason Gerecke killert...@gmail.com --- drivers/hid/wacom_wac.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 525b648..5833731 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1927,7 +1927,9 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) 0, wacom_wac-features.distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); + input_abs_set_res(input_dev, ABS_TILT_X, 57); input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); + input_abs_set_res(input_dev, ABS_TILT_Y, 57); } static void wacom_setup_intuos(struct wacom_wac *wacom_wac) @@ -1947,6 +1949,7 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) __set_bit(BTN_TOOL_LENS, input_dev-keybit); input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_RZ, 287); input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); } @@ -2092,6 +2095,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case WACOM_24HD: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); /* fall through */ @@ -2106,6 +2110,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case WACOM_BEE: case CINTIQ: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev-propbit); @@ -2114,6 +2119,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case WACOM_13HD: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev-propbit); wacom_setup_cintiq(wacom_wac); break; @@ -2122,6 +2128,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case INTUOS3L: case INTUOS3S: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); /* fall through */ case INTUOS: @@ -2144,6 +2151,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, 0, 0); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); wacom_setup_intuos(wacom_wac); } else if (features-device_type == BTN_TOOL_FINGER) { @@ -2162,6 +2170,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case INTUOS4L: case INTUOS4S: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); wacom_setup_intuos(wacom_wac); __set_bit(INPUT_PROP_POINTER, input_dev-propbit); @@ -2261,6 +2270,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case CINTIQ_HYBRID: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev-propbit); wacom_setup_cintiq(wacom_wac); -- 2.1.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: input: Fix TransducerSerialNumber implementation
On Tue, Sep 23, 2014 at 11:09 AM, Jason Gerecke killert...@gmail.com wrote: The commit which introduced TransducerSerialNumber (368c966) is missing two crucial implementation details. Firstly, the commit does not set the type/code/bit/max fields as expected later down the code which can cause the driver to crash when a tablet with this usage is connected. Secondly, the call to 'set_bit' causes MSC_PULSELED to be sent instead of the expected MSC_SERIAL. This commit addreses both issues. Signed-off-by: Jason Gerecke jason.gere...@wacom.com --- drivers/hid/hid-input.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2619f7f..cb1b3fa 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -689,7 +689,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; case 0x5b: /* TransducerSerialNumber */ - set_bit(MSC_SERIAL, input-mscbit); + usage-type = EV_MSC; + usage-code = MSC_SERIAL; + bit = input-mscbit; + max = MSC_MAX; break; default: goto unknown; -- 2.1.0 This patch still seems to be in limbo. Anyone (Ping? Benjamin?) care to provide an ACK or review? Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three,/ So you look at the sixty-fours -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] HID: wacom: Prevent potential null dereference after disconnect
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g. wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away. Signed-off-by: Jason Gerecke killert...@gmail.com --- Changes in v2: * Added in missing escape character drivers/hid/wacom_sys.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 8593047..265429b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id, unsigned int id; int err; + if (!wacom) + return -ENODEV; + err = kstrtouint(buf, 10, id); if (err) return err; @@ -666,6 +669,8 @@ static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ struct wacom *wacom = hid_get_drvdata(hdev);\ + if (!wacom) \ + return -ENODEV; \ return scnprintf(buf, PAGE_SIZE, %d\n,\ wacom-led.select[SET_ID]);\ } \ @@ -702,7 +707,8 @@ static ssize_t wacom_##name##_luminance_store(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ struct wacom *wacom = hid_get_drvdata(hdev);\ - \ + if (!wacom) \ + return -ENODEV; \ return wacom_luminance_store(wacom, wacom-led.field, \ buf, count); \ } \ @@ -710,6 +716,8 @@ static ssize_t wacom_##name##_luminance_show(struct device *dev,\ struct device_attribute *attr, char *buf) \ { \ struct wacom *wacom = dev_get_drvdata(dev); \ + if (!wacom) \ + return -ENODEV; \ return scnprintf(buf, PAGE_SIZE, %d\n, wacom-led.field); \ } \ static DEVICE_ATTR(name##_luminance, DEV_ATTR_RW_PERM, \ @@ -729,6 +737,9 @@ static ssize_t wacom_button_image_store(struct device *dev, int button_id, unsigned len; u8 xfer_id; + if (!wacom) + return -ENODEV; + if (hdev-bus == BUS_BLUETOOTH) { len = 256; xfer_id = WAC_CMD_ICON_BT_XFER; -- 2.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] HID: wacom: Prevent potential null dereference after disconnect
On Wed, Oct 8, 2014 at 2:40 PM, Dmitry Torokhov dmitry.torok...@gmail.com wrote: On Wed, Oct 08, 2014 at 11:25:42AM -0700, Jason Gerecke wrote: Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g. wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away. Signed-off-by: Jason Gerecke killert...@gmail.com --- Changes in v2: * Added in missing escape character drivers/hid/wacom_sys.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 8593047..265429b 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id, unsigned int id; int err; + if (!wacom) + return -ENODEV; + Strong NAK. If device could disappear before this check it could as well disappear after your check. This patch does not solve anything. I assume I'll want to either disable interrupts or take a lock depending on if `wacom_remove` is called from within the interrupt context, but I haven't had to deal with concurrency in the kernel before so I'm not entirely sure which option (or which primitive if locking) would be appropriate... Jason --- Now instead of four in the eights place / you’ve got three, ‘Cause you added one / (That is to say, eight) to the two, / But you can’t take seven from three,/ So you look at the sixty-fours err = kstrtouint(buf, 10, id); if (err) return err; Thanks. -- Dmitry -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html