* [PATCH 2/2] HID: wacom: rely on actual touch down count to decide touch_down
@ 2015-02-20 22:27 Ping Cheng
2015-03-05 0:28 ` Jason Gerecke
0 siblings, 1 reply; 2+ messages in thread
From: Ping Cheng @ 2015-02-20 22:27 UTC (permalink / raw)
To: jkosina; +Cc: linux-input, Ping Cheng
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 <pingc@wacom.com>
---
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)
{
unsigned char *data = wacom->data;
struct input_dev *input = wacom->input;
- bool prox;
+ bool prox = !wacom->shared->stylus_in_proximity;
int x = 0, y = 0;
if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
return 0;
- if (!wacom->shared->stylus_in_proximity) {
- if (len == WACOM_PKGLEN_TPC1FG) {
- prox = data[0] & 0x01;
- x = get_unaligned_le16(&data[1]);
- y = get_unaligned_le16(&data[3]);
- } else if (len == WACOM_PKGLEN_TPC1FG_B) {
- prox = data[2] & 0x01;
- x = get_unaligned_le16(&data[3]);
- y = get_unaligned_le16(&data[5]);
- } else {
- prox = data[1] & 0x01;
- x = le16_to_cpup((__le16 *)&data[2]);
- y = le16_to_cpup((__le16 *)&data[4]);
- }
- } else
- /* force touch out when pen is in prox */
- prox = 0;
+ if (len == WACOM_PKGLEN_TPC1FG) {
+ prox = prox && (data[0] & 0x01);
+ x = get_unaligned_le16(&data[1]);
+ y = get_unaligned_le16(&data[3]);
+ } else if (len == WACOM_PKGLEN_TPC1FG_B) {
+ prox = prox && (data[2] & 0x01);
+ x = get_unaligned_le16(&data[3]);
+ y = get_unaligned_le16(&data[5]);
+ } else {
+ prox = prox && (data[1] & 0x01);
+ x = le16_to_cpup((__le16 *)&data[2]);
+ y = le16_to_cpup((__le16 *)&data[4]);
+ }
if (prox) {
input_report_abs(input, ABS_X, x);
@@ -1616,6 +1618,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
struct input_dev *pad_input = wacom->pad_input;
unsigned char *data = wacom->data;
int i;
+ int contact_with_no_pen_down_count = 0;
if (data[0] != 0x02)
return 0;
@@ -1643,6 +1646,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
}
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
+ contact_with_no_pen_down_count++;
}
}
@@ -1652,11 +1656,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
return 1;
}
-static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
+static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count)
{
struct wacom_features *features = &wacom->features;
struct input_dev *input = wacom->input;
@@ -1664,7 +1669,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
int slot = input_mt_get_slot_by_key(input, data[0]);
if (slot < 0)
- return;
+ return 0;
touch = touch && !wacom->shared->stylus_in_proximity;
@@ -1696,7 +1701,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
input_report_abs(input, ABS_MT_POSITION_Y, y);
input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
+ last_touch_count++;
}
+ return last_touch_count;
}
static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
@@ -1721,6 +1728,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
int count = data[1] & 0x07;
int i;
+ int contact_with_no_pen_down_count = 0;
if (data[0] != 0x02)
return 0;
@@ -1731,12 +1739,15 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
int msg_id = data[offset];
if (msg_id >= 2 && msg_id <= 17)
- wacom_bpt3_touch_msg(wacom, data + offset);
+ contact_with_no_pen_down_count =
+ wacom_bpt3_touch_msg(wacom, data + offset,
+ contact_with_no_pen_down_count);
else if (msg_id == 128)
wacom_bpt3_button_msg(wacom, data + offset);
}
input_mt_report_pointer_emulation(input, true);
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
return 1;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 2/2] HID: wacom: rely on actual touch down count to decide touch_down
2015-02-20 22:27 [PATCH 2/2] HID: wacom: rely on actual touch down count to decide touch_down Ping Cheng
@ 2015-03-05 0:28 ` Jason Gerecke
0 siblings, 0 replies; 2+ messages in thread
From: Jason Gerecke @ 2015-03-05 0:28 UTC (permalink / raw)
To: Ping Cheng, jkosina; +Cc: linux-input, Ping Cheng
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 <pingc@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 <killertofu@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)
> {
> unsigned char *data = wacom->data;
> struct input_dev *input = wacom->input;
> - bool prox;
> + bool prox = !wacom->shared->stylus_in_proximity;
> int x = 0, y = 0;
>
> if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
> return 0;
>
> - if (!wacom->shared->stylus_in_proximity) {
> - if (len == WACOM_PKGLEN_TPC1FG) {
> - prox = data[0] & 0x01;
> - x = get_unaligned_le16(&data[1]);
> - y = get_unaligned_le16(&data[3]);
> - } else if (len == WACOM_PKGLEN_TPC1FG_B) {
> - prox = data[2] & 0x01;
> - x = get_unaligned_le16(&data[3]);
> - y = get_unaligned_le16(&data[5]);
> - } else {
> - prox = data[1] & 0x01;
> - x = le16_to_cpup((__le16 *)&data[2]);
> - y = le16_to_cpup((__le16 *)&data[4]);
> - }
> - } else
> - /* force touch out when pen is in prox */
> - prox = 0;
> + if (len == WACOM_PKGLEN_TPC1FG) {
> + prox = prox && (data[0] & 0x01);
> + x = get_unaligned_le16(&data[1]);
> + y = get_unaligned_le16(&data[3]);
> + } else if (len == WACOM_PKGLEN_TPC1FG_B) {
> + prox = prox && (data[2] & 0x01);
> + x = get_unaligned_le16(&data[3]);
> + y = get_unaligned_le16(&data[5]);
> + } else {
> + prox = prox && (data[1] & 0x01);
> + x = le16_to_cpup((__le16 *)&data[2]);
> + y = le16_to_cpup((__le16 *)&data[4]);
> + }
>
> if (prox) {
> input_report_abs(input, ABS_X, x);
> @@ -1616,6 +1618,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
> struct input_dev *pad_input = wacom->pad_input;
> unsigned char *data = wacom->data;
> int i;
> + int contact_with_no_pen_down_count = 0;
>
> if (data[0] != 0x02)
> return 0;
> @@ -1643,6 +1646,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
> }
> input_report_abs(input, ABS_MT_POSITION_X, x);
> input_report_abs(input, ABS_MT_POSITION_Y, y);
> + contact_with_no_pen_down_count++;
> }
> }
>
> @@ -1652,11 +1656,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
> input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
> input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
> input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
> + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
>
> return 1;
> }
>
> -static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
> +static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count)
> {
> struct wacom_features *features = &wacom->features;
> struct input_dev *input = wacom->input;
> @@ -1664,7 +1669,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
> int slot = input_mt_get_slot_by_key(input, data[0]);
>
> if (slot < 0)
> - return;
> + return 0;
>
> touch = touch && !wacom->shared->stylus_in_proximity;
>
> @@ -1696,7 +1701,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
> input_report_abs(input, ABS_MT_POSITION_Y, y);
> input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
> input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
> + last_touch_count++;
> }
> + return last_touch_count;
> }
>
> static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
> @@ -1721,6 +1728,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
> unsigned char *data = wacom->data;
> int count = data[1] & 0x07;
> int i;
> + int contact_with_no_pen_down_count = 0;
>
> if (data[0] != 0x02)
> return 0;
> @@ -1731,12 +1739,15 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
> int msg_id = data[offset];
>
> if (msg_id >= 2 && msg_id <= 17)
> - wacom_bpt3_touch_msg(wacom, data + offset);
> + contact_with_no_pen_down_count =
> + wacom_bpt3_touch_msg(wacom, data + offset,
> + contact_with_no_pen_down_count);
> else if (msg_id == 128)
> wacom_bpt3_button_msg(wacom, data + offset);
>
> }
> input_mt_report_pointer_emulation(input, true);
> + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
>
> return 1;
> }
>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-03-05 0:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-20 22:27 [PATCH 2/2] HID: wacom: rely on actual touch down count to decide touch_down Ping Cheng
2015-03-05 0:28 ` Jason Gerecke
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.