summaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorAaron Armstrong Skomra <skomra@gmail.com>2019-08-16 12:02:50 -0700
committerJiri Kosina <jkosina@suse.cz>2019-08-20 16:59:05 +0200
commit670e90924bfe9cf80536eab66a31704e07b5fd00 (patch)
tree392d2ac2d52460ded23371dbdde92866bf300bc4 /drivers/hid
parent073b50bccbbf99a3b79a1913604c656d0e1a56c9 (diff)
downloadlinux-670e90924bfe9cf80536eab66a31704e07b5fd00.tar.gz
linux-670e90924bfe9cf80536eab66a31704e07b5fd00.tar.bz2
linux-670e90924bfe9cf80536eab66a31704e07b5fd00.zip
HID: wacom: support named keys on older devices
Some Wacom devices have keys with predefined meanings. However, when support was originally added for these devices, the codes for these keys were not available yet. These keys were thus reported with the numbered KEY_PROG* range. Some missing key codes were added with commit 4eb220cb35a9 ("HID: wacom: generic: add 3 tablet touch keys") and we are now able to report the proper key codes. We continue to report the original KEY_PROG codes so as not to break any unknown applications that may depend on them. Also, to support the touch key, track its state in the pad report. Signed-off-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com> Link: https://gitlab.freedesktop.org/libinput/libinput/merge_requests/155 Link: https://github.com/linuxwacom/xf86-input-wacom/pull/46 Reviewed-by: Ping Cheng <ping.cheng@wacom.com> Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/wacom_wac.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 125b4ed7afc6..6b739c1bda99 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -483,6 +483,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
int ring1 = 0, ring2 = 0;
int strip1 = 0, strip2 = 0;
bool prox = false;
+ bool wrench = false, keyboard = false, mute_touch = false, menu = false,
+ info = false;
/* pad packets. Works as a second tool and is always in prox */
if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
@@ -512,10 +514,32 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
keys = ((data[3] & 0x1C) ? 1<<2 : 0) |
((data[4] & 0xE0) ? 1<<1 : 0) |
((data[4] & 0x07) ? 1<<0 : 0);
+ keyboard = !!(data[4] & 0xE0);
+ info = !!(data[3] & 0x1C);
+
+ if (features->oPid) {
+ mute_touch = !!(data[4] & 0x07);
+ if (mute_touch)
+ wacom->shared->is_touch_on =
+ !wacom->shared->is_touch_on;
+ } else {
+ wrench = !!(data[4] & 0x07);
+ }
} else if (features->type == WACOM_27QHD) {
nkeys = 3;
keys = data[2] & 0x07;
+ wrench = !!(data[2] & 0x01);
+ keyboard = !!(data[2] & 0x02);
+
+ if (features->oPid) {
+ mute_touch = !!(data[2] & 0x04);
+ if (mute_touch)
+ wacom->shared->is_touch_on =
+ !wacom->shared->is_touch_on;
+ } else {
+ menu = !!(data[2] & 0x04);
+ }
input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
@@ -561,6 +585,9 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
if (features->type == WACOM_22HD) {
nkeys = 3;
keys = data[9] & 0x07;
+
+ info = !!(data[9] & 0x01);
+ wrench = !!(data[9] & 0x02);
}
} else {
buttons = ((data[6] & 0x10) << 5) |
@@ -580,6 +607,18 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
for (i = 0; i < nkeys; i++)
input_report_key(input, KEY_PROG1 + i, keys & (1 << i));
+ input_report_key(input, KEY_BUTTONCONFIG, wrench);
+ input_report_key(input, KEY_ONSCREEN_KEYBOARD, keyboard);
+ input_report_key(input, KEY_CONTROLPANEL, menu);
+ input_report_key(input, KEY_INFO, info);
+
+ if (wacom->shared && wacom->shared->touch_input) {
+ input_report_switch(wacom->shared->touch_input,
+ SW_MUTE_DEVICE,
+ !wacom->shared->is_touch_on);
+ input_sync(wacom->shared->touch_input);
+ }
+
input_report_abs(input, ABS_RX, strip1);
input_report_abs(input, ABS_RY, strip2);
@@ -1480,6 +1519,12 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
int y_offset = 2;
+ if (wacom->shared->has_mute_touch_switch &&
+ !wacom->shared->is_touch_on) {
+ if (!wacom->shared->touch_down)
+ return 0;
+ }
+
if (wacom->features.type == WACOM_27QHDT) {
current_num_contacts = data[63];
num_contacts_left = 10;
@@ -3812,6 +3857,14 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
/* fall through */
case WACOM_27QHDT:
+ if (wacom_wac->shared->touch->product == 0x32C ||
+ wacom_wac->shared->touch->product == 0xF6) {
+ input_dev->evbit[0] |= BIT_MASK(EV_SW);
+ __set_bit(SW_MUTE_DEVICE, input_dev->swbit);
+ wacom_wac->shared->has_mute_touch_switch = true;
+ }
+ /* fall through */
+
case MTSCREEN:
case MTTPC:
case MTTPC_B:
@@ -4047,6 +4100,12 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
__set_bit(KEY_PROG2, input_dev->keybit);
__set_bit(KEY_PROG3, input_dev->keybit);
+ __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit);
+ __set_bit(KEY_INFO, input_dev->keybit);
+
+ if (!features->oPid)
+ __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);
+
input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
break;
@@ -4055,6 +4114,12 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
__set_bit(KEY_PROG1, input_dev->keybit);
__set_bit(KEY_PROG2, input_dev->keybit);
__set_bit(KEY_PROG3, input_dev->keybit);
+
+ __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit);
+ __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);
+
+ if (!features->oPid)
+ __set_bit(KEY_CONTROLPANEL, input_dev->keybit);
input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0);
input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */
input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0);
@@ -4068,6 +4133,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
__set_bit(KEY_PROG1, input_dev->keybit);
__set_bit(KEY_PROG2, input_dev->keybit);
__set_bit(KEY_PROG3, input_dev->keybit);
+
+ __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);
+ __set_bit(KEY_INFO, input_dev->keybit);
/* fall through */
case WACOM_21UX2: