[PATCH] HID: wacom: Use correct report to query pen ID from INTUOSHT2 devices

2016-01-06 Thread Jason Gerecke
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

2015-12-16 Thread Jason Gerecke
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

2015-12-16 Thread Jason Gerecke
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

2015-12-16 Thread Jason Gerecke
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

2015-12-16 Thread Jason Gerecke
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

2015-12-16 Thread Jason Gerecke
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

2015-12-04 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
"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

2015-11-30 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
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

2015-11-30 Thread Jason Gerecke
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'

2015-11-03 Thread Jason Gerecke
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'

2015-11-02 Thread Jason Gerecke
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'

2015-11-02 Thread Jason Gerecke
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

2015-11-02 Thread Jason Gerecke
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

2015-10-15 Thread Jason Gerecke
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

2015-10-13 Thread Jason Gerecke
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

2015-10-12 Thread Jason Gerecke
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

2015-10-08 Thread Jason Gerecke
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

2015-10-07 Thread Jason Gerecke
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

2015-10-07 Thread Jason Gerecke
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

2015-10-07 Thread Jason Gerecke
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

2015-08-17 Thread Jason Gerecke
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

2015-08-10 Thread Jason Gerecke
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

2015-08-05 Thread Jason Gerecke
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

2015-08-05 Thread Jason Gerecke
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'

2015-08-03 Thread Jason Gerecke
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

2015-08-03 Thread Jason Gerecke
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

2015-08-03 Thread Jason Gerecke
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

2015-08-03 Thread Jason Gerecke
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

2015-07-21 Thread Jason Gerecke
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

2015-07-21 Thread Jason Gerecke
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

2015-07-21 Thread Jason Gerecke
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

2015-07-13 Thread Jason Gerecke
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

2015-07-13 Thread Jason Gerecke
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

2015-07-01 Thread Jason Gerecke
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()

2015-06-25 Thread Jason Gerecke
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

2015-06-19 Thread Jason Gerecke
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

2015-06-15 Thread Jason Gerecke
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

2015-06-15 Thread Jason Gerecke
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'

2015-06-15 Thread Jason Gerecke
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

2015-06-15 Thread Jason Gerecke
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

2015-06-08 Thread Jason Gerecke
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

2015-06-04 Thread Jason Gerecke
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

2015-06-04 Thread Jason Gerecke
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

2015-06-04 Thread Jason Gerecke
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'

2015-06-03 Thread Jason Gerecke
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

2015-06-03 Thread Jason Gerecke
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

2015-06-03 Thread Jason Gerecke
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

2015-06-03 Thread Jason Gerecke
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'

2015-06-03 Thread Jason Gerecke
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

2015-06-03 Thread Jason Gerecke
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

2015-05-21 Thread Jason Gerecke
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

2015-05-21 Thread Jason Gerecke
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

2015-04-20 Thread Jason Gerecke
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

2015-04-16 Thread Jason Gerecke
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

2015-04-16 Thread Jason Gerecke
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

2015-04-15 Thread Jason Gerecke
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

2015-04-01 Thread Jason Gerecke

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

2015-03-16 Thread Jason Gerecke

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

2015-03-16 Thread Jason Gerecke

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

2015-03-16 Thread Jason Gerecke

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

2015-03-16 Thread Jason Gerecke
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

2015-03-12 Thread Jason Gerecke

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

2015-03-11 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-06 Thread Jason Gerecke
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

2015-03-04 Thread Jason Gerecke

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

2015-03-04 Thread Jason Gerecke

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

2015-03-03 Thread Jason Gerecke

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

2015-01-22 Thread Jason Gerecke
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

2015-01-05 Thread Jason Gerecke
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

2014-12-10 Thread Jason Gerecke
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

2014-12-10 Thread Jason Gerecke
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

2014-12-05 Thread Jason Gerecke
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

2014-12-05 Thread Jason Gerecke
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

2014-11-24 Thread Jason Gerecke
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

2014-11-24 Thread Jason Gerecke
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

2014-11-24 Thread Jason Gerecke
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

2014-11-24 Thread Jason Gerecke
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

2014-11-18 Thread Jason Gerecke
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

2014-11-18 Thread Jason Gerecke
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

2014-10-28 Thread Jason Gerecke
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

2014-10-08 Thread Jason Gerecke
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

2014-10-08 Thread Jason Gerecke
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


  1   2   >