diff options
author | Jiri Kosina <jkosina@suse.cz> | 2018-06-08 10:28:24 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-06-08 10:28:24 +0200 |
commit | 06d8b9067c9bb9d65c7479506e682b211735fa1a (patch) | |
tree | fc0a998e703c7ed98c42dd0268f04b074932e288 /drivers/hid | |
parent | 43e7b1494161bd56dc2bd9bf7c995abc3894089a (diff) | |
parent | 8947b0cfdcc111722b2293f26debdab8697f4c68 (diff) |
Merge branch 'for-4.18/wacom' into for-linus
Support for "In Range" flag for Wacom Intuos/Bamboo devices from Jason Gerecke
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/wacom_wac.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 5f947ec20dcb..0bb44d0088ed 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2894,24 +2894,31 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) struct wacom_features *features = &wacom->features; struct input_dev *input = wacom->pen_input; unsigned char *data = wacom->data; - int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; + int x = 0, y = 0, p = 0, d = 0; + bool pen = false, btn1 = false, btn2 = false; + bool range, prox, rdy; if (data[0] != WACOM_REPORT_PENABLED) return 0; - prox = (data[1] & 0x20) == 0x20; + range = (data[1] & 0x80) == 0x80; + prox = (data[1] & 0x40) == 0x40; + rdy = (data[1] & 0x20) == 0x20; + + wacom->shared->stylus_in_proximity = range; + if (delay_pen_events(wacom)) + return 0; + + if (rdy) { + p = le16_to_cpup((__le16 *)&data[6]); + pen = data[1] & 0x01; + btn1 = data[1] & 0x02; + btn2 = data[1] & 0x04; + } + if (prox) { + x = le16_to_cpup((__le16 *)&data[2]); + y = le16_to_cpup((__le16 *)&data[4]); - /* - * All reports shared between PEN and RUBBER tool must be - * forced to a known starting value (zero) when transitioning to - * out-of-prox. - * - * If not reset then, to userspace, it will look like lost events - * if new tool comes in-prox with same values as previous tool sent. - * - * Hardware does report zero in most out-of-prox cases but not all. - */ - if (!wacom->shared->stylus_in_proximity) { if (data[1] & 0x08) { wacom->tool[0] = BTN_TOOL_RUBBER; wacom->id[0] = ERASER_DEVICE_ID; @@ -2919,16 +2926,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) wacom->tool[0] = BTN_TOOL_PEN; wacom->id[0] = STYLUS_DEVICE_ID; } + wacom->reporting_data = true; } - - wacom->shared->stylus_in_proximity = prox; - if (delay_pen_events(wacom)) - return 0; - - if (prox) { - x = le16_to_cpup((__le16 *)&data[2]); - y = le16_to_cpup((__le16 *)&data[4]); - p = le16_to_cpup((__le16 *)&data[6]); + if (range) { /* * Convert distance from out prox to distance from tablet. * distance will be greater than distance_max once @@ -2937,25 +2937,29 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) */ if (data[8] <= features->distance_max) d = features->distance_max - data[8]; - - pen = data[1] & 0x01; - btn1 = data[1] & 0x02; - btn2 = data[1] & 0x04; } else { wacom->id[0] = 0; } - input_report_key(input, BTN_TOUCH, pen); - input_report_key(input, BTN_STYLUS, btn1); - input_report_key(input, BTN_STYLUS2, btn2); + if (wacom->reporting_data) { + input_report_key(input, BTN_TOUCH, pen); + input_report_key(input, BTN_STYLUS, btn1); + input_report_key(input, BTN_STYLUS2, btn2); - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - input_report_abs(input, ABS_PRESSURE, p); - input_report_abs(input, ABS_DISTANCE, d); + if (prox || !range) { + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + } + input_report_abs(input, ABS_PRESSURE, p); + input_report_abs(input, ABS_DISTANCE, d); - input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ - input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ + input_report_key(input, wacom->tool[0], range); /* PEN or RUBBER */ + input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ + } + + if (!range) { + wacom->reporting_data = false; + } return 1; } |