diff --git a/.travis.yml b/.travis.yml index 69b7dd55..93dbe619 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,3 +36,14 @@ install: script: - ./autogen.sh --with-kernel=${KERNELDIR}/${KERNEL} && make EXTRA_CFLAGS="-Werror -Wno-type-limits -Wno-unused-function -isystem ${KERNELDIR}/${KERNEL}/arch/x86/include -isystem ${KERNELDIR}/${KERNEL}/arch/x86/include/uapi -isystem ${KERNELDIR}/${KERNEL}/include/linux" + +jobs: + include: + stage: checkpatch + before_script: + - sed -i '/duplicate signatures/,/^$/ s/if (/if (0 and /' ${KERNELDIR}/${KERNEL}/scripts/checkpatch.pl + - git remote add upstream https://github.com/linuxwacom/input-wacom.git + - git fetch upstream master + - git format-patch FETCH_HEAD + script: + - if ls *.patch 2>/dev/null; then ${KERNELDIR}/${KERNEL}/scripts/checkpatch.pl --max-line-length=90 --ignore OPEN_BRACE --ignore EMAIL_SUBJECT *.patch; fi diff --git a/2.6.32/wacom.h b/2.6.32/wacom.h old mode 100755 new mode 100644 index e9f9b076..3f58e9d6 --- a/2.6.32/wacom.h +++ b/2.6.32/wacom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom.h * @@ -75,10 +76,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_H #define WACOM_H diff --git a/2.6.32/wacom_sys.c b/2.6.32/wacom_sys.c index 84f9d0d0..48d34135 100644 --- a/2.6.32/wacom_sys.c +++ b/2.6.32/wacom_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_sys.c * @@ -5,10 +6,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -223,7 +220,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi switch (data) { case HID_USAGE_WT_X: features->device_type = BTN_TOOL_TRIPLETAP; - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->pktlen = WACOM_PKGLEN_INTUOSP2T; features->unit = report[i+4]; features->unitExpo = report[i+6]; @@ -233,7 +231,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi break; case HID_USAGE_WT_Y: - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->y_phy = get_unaligned_le16(&report[i + 4]); features->y_max = get_unaligned_le16(&report[i + 7]); } diff --git a/2.6.32/wacom_w8001.c b/2.6.32/wacom_w8001.c old mode 100755 new mode 100644 index 7594a3e2..83cbe78c --- a/2.6.32/wacom_w8001.c +++ b/2.6.32/wacom_w8001.c @@ -27,6 +27,8 @@ MODULE_AUTHOR("Jaya Kumar "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +#define W8001_MAX_PHYS 42 + #define W8001_MAX_LENGTH 13 #define W8001_LEAD_MASK 0x80 #define W8001_LEAD_BYTE 0x80 @@ -87,7 +89,7 @@ struct w8001 { unsigned char response_type; unsigned char response[W8001_MAX_LENGTH]; unsigned char data[W8001_MAX_LENGTH]; - char phys[32]; + char phys[W8001_MAX_PHYS]; int type; unsigned int pktlen; int max_touch_x; diff --git a/2.6.32/wacom_wac.c b/2.6.32/wacom_wac.c index 3aa3940e..78bbf45a 100644 --- a/2.6.32/wacom_wac.c +++ b/2.6.32/wacom_wac.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_wac.c * * USB Wacom tablet support - Wacom specific code - * */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -464,6 +460,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 || @@ -493,9 +491,29 @@ 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; + + 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); + } } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { /* * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in @@ -514,6 +532,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) | @@ -525,7 +546,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3] & 0x1f) << 8) | data[4]; } - prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2; wacom_report_numbered_buttons(input, nbuttons, buttons); @@ -533,6 +554,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); @@ -780,6 +813,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) y >>= 1; distance >>= 1; } + if (features->type == INTUOSHT2) + distance = features->distance_max - distance; input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_DISTANCE, distance); @@ -1011,6 +1046,12 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 1; break; case WACOM_27QHDT: + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return 0; + } + current_num_contacts = data[63]; contacts_per_packet = 10; bytes_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; @@ -1025,6 +1066,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 3; break; case INTUOSP2: + case INTUOSP2S: current_num_contacts = data[1]; contacts_per_packet = 5; bytes_per_packet = WACOM_BYTES_PER_INTUOSP2_PACKET; @@ -1071,6 +1113,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) break; case INTUOSP2: + case INTUOSP2S: contact_id = data[offset]; prox = data[offset + 1] & 0x01; x = get_unaligned_le16(&data[offset + 2]); @@ -1700,6 +1743,11 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = le16_to_cpup((__le16 *)&data[4]); keys = 0; break; + case 7: + buttons = (data[1]) | (data[3] << 6); + ring = le16_to_cpup((__le16 *)&data[4]); + keys = 0; + break; case 0: buttons = 0; ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ @@ -1724,8 +1772,8 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ringvalue += 3*72/16; if (ringvalue > 71) ringvalue -= 72; - } - else if (input->id.product == 0x34d || input->id.product == 0x34e) { + } else if (input->id.product == 0x34d || input->id.product == 0x34e || + input->id.product == 0x398 || input->id.product == 0x399) { /* MobileStudio Pro */ ringvalue = 35 - (ring & 0x7F); ringvalue += 36/2; @@ -1937,6 +1985,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_MSPRO: case INTUOSP2: + case INTUOSP2S: case CINTIQ_16: if (len == WACOM_PKGLEN_INTUOSP2T && wacom_wac->data[0] == WACOM_REPORT_VENDOR_DEF_TOUCH) @@ -2256,6 +2305,12 @@ void wacom_setup_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_THROTTLE, 0, 71, 0, 0); /* fall through */ @@ -2271,6 +2326,13 @@ void wacom_setup_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_Z, -900, 899, 0, 0); wacom_setup_cintiq(wacom_wac); @@ -2280,6 +2342,9 @@ void wacom_setup_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: @@ -2291,6 +2356,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + wacom_setup_cintiq(wacom_wac); + break; + case INTUOS3: case INTUOS3L: input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); @@ -2306,6 +2374,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, break; case INTUOSP2: + case INTUOSP2S: if (features->device_type == BTN_TOOL_TRIPLETAP) { for (i = 0; i < 10; i++) wacom_wac->slots[i] = -1; @@ -2321,6 +2390,8 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; } + /* fall through */ + case INTUOS5: case INTUOS5L: case INTUOSPM: @@ -2373,6 +2444,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, for (i = 0; i < 10; i++) wacom_wac->slots[i] = -1; } + if (wacom_wac->shared->touch_input->id.product == 0x32C || + wacom_wac->shared->touch_input->id.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 TABLETPC2FG: @@ -2405,6 +2482,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, case DTUS2: case DTK2451: input_set_capability(input_dev, EV_MSC, MSC_SERIAL); + /* fall through */ case DTUSX: case PL: @@ -3070,8 +3148,40 @@ static const struct wacom_features wacom_features_0x390 = { "Wacom Cintiq 16", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x391 = + { "Wacom Cintiq 22", WACOM_PKGLEN_MSPRO, 96012, 54358, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x392 = + { "Wacom Intuos Pro S", WACOM_PKGLEN_INTUOSP2, 31920, 19950, 8191, 63, + INTUOSP2S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 10 }; +static const struct wacom_features wacom_features_0x396 = + { "Wacom DTK-1660E", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x398 = + { "Wacom MobileStudio Pro 13", WACOM_PKGLEN_MSPRO, 59552, 33848, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39A }; +static const struct wacom_features wacom_features_0x399 = + { "Wacom MobileStudio Pro 16", WACOM_PKGLEN_MSPRO, 69920, 39680, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 13, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, - .oVid = USB_VENDOR_ID_WACOM }; + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39B }; +static const struct wacom_features wacom_features_0x39A = + { "Wacom MobileStudio Pro 13 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x398 }; +static const struct wacom_features wacom_features_0x39B = + { "Wacom MobileStudio Pro 16 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x399 }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -3258,6 +3368,13 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x37E) }, { USB_DEVICE_WACOM(0x382) }, { USB_DEVICE_DETAILED(0x390, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x391, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x392, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x396, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0x398) }, + { USB_DEVICE_WACOM(0x399) }, + { USB_DEVICE_WACOM(0x39A) }, + { USB_DEVICE_WACOM(0x39B) }, #ifndef RHEL6_RELEASE { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, diff --git a/2.6.32/wacom_wac.h b/2.6.32/wacom_wac.h old mode 100755 new mode 100644 index 45e865bb..c2e19ee1 --- a/2.6.32/wacom_wac.h +++ b/2.6.32/wacom_wac.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_WAC_H #define WACOM_WAC_H @@ -129,6 +125,7 @@ enum { WACOM_MSPROT, DTH1152T, INTUOSP2, + INTUOSP2S, INTUOSHT3, TABLETPC, /* add new TPC below */ TABLETPCE, diff --git a/2.6.38/wacom.h b/2.6.38/wacom.h index c1db6616..8812566c 100644 --- a/2.6.38/wacom.h +++ b/2.6.38/wacom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom.h * @@ -75,10 +76,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_H #define WACOM_H diff --git a/2.6.38/wacom_sys.c b/2.6.38/wacom_sys.c index 496f4075..52fa8734 100644 --- a/2.6.38/wacom_sys.c +++ b/2.6.38/wacom_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_sys.c * @@ -5,10 +6,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include @@ -359,7 +356,8 @@ static int wacom_parse_hid(struct usb_interface *intf, case HID_USAGE_WT_X: if (finger) features->device_type = BTN_TOOL_FINGER; - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->touch_max = 10; features->pktlen = WACOM_PKGLEN_INTUOSP2T; features->unit = report[i+4]; @@ -370,7 +368,8 @@ static int wacom_parse_hid(struct usb_interface *intf, break; case HID_USAGE_WT_Y: - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->y_phy = get_unaligned_le16(&report[i + 4]); features->y_max = get_unaligned_le16(&report[i + 7]); } diff --git a/2.6.38/wacom_w8001.c b/2.6.38/wacom_w8001.c index f15afb2a..0dc6e959 100644 --- a/2.6.38/wacom_w8001.c +++ b/2.6.38/wacom_w8001.c @@ -27,6 +27,8 @@ MODULE_AUTHOR("Jaya Kumar "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +#define W8001_MAX_PHYS 42 + #define W8001_MAX_LENGTH 13 #define W8001_LEAD_MASK 0x80 #define W8001_LEAD_BYTE 0x80 @@ -89,7 +91,7 @@ struct w8001 { unsigned char response_type; unsigned char response[W8001_MAX_LENGTH]; unsigned char data[W8001_MAX_LENGTH]; - char phys[32]; + char phys[W8001_MAX_PHYS]; int type; unsigned int pktlen; u16 max_touch_x; diff --git a/2.6.38/wacom_wac.c b/2.6.38/wacom_wac.c index 032e0701..3cf693a7 100644 --- a/2.6.38/wacom_wac.c +++ b/2.6.38/wacom_wac.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_wac.c * * USB Wacom tablet support - Wacom specific code - * */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -496,6 +492,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 || @@ -525,9 +523,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); + } } else if (features->type == CINTIQ_HYBRID) { /* * Do not send hardware buttons under Android. They @@ -542,14 +563,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) */ buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == CINTIQ_COMPANION_2) { - /* d-pad right -> data[4] & 0x10 - * d-pad up -> data[4] & 0x20 - * d-pad left -> data[4] & 0x40 - * d-pad down -> data[4] & 0x80 - * d-pad center -> data[3] & 0x01 + /* d-pad right -> data[2] & 0x10 + * d-pad up -> data[2] & 0x20 + * d-pad left -> data[2] & 0x40 + * d-pad down -> data[2] & 0x80 + * d-pad center -> data[1] & 0x01 */ buttons = ((data[2] >> 4) << 7) | - ((data[1] & 0x04) << 6) | + ((data[1] & 0x04) << 4) | ((data[2] & 0x0F) << 2) | (data[1] & 0x03); } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { @@ -570,6 +591,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) | @@ -581,7 +605,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3] & 0x1f) << 8) | data[4]; } - prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2; wacom_report_numbered_buttons(input, nbuttons, buttons); @@ -589,6 +613,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); @@ -842,6 +878,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) y >>= 1; distance >>= 1; } + if (features->type == INTUOSHT2) + distance = features->distance_max - distance; input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_DISTANCE, distance); @@ -1055,7 +1093,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) input_report_key(input, BTN_BASE2, (data[11] & 0x02)); if (data[12] & 0x80) - input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); + input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f) - 1); else input_report_abs(input, ABS_WHEEL, 0); @@ -1236,6 +1274,12 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 1; break; case WACOM_27QHDT: + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return 0; + } + current_num_contacts = data[63]; contacts_per_packet = 10; bytes_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; @@ -1250,6 +1294,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 3; break; case INTUOSP2: + case INTUOSP2S: current_num_contacts = data[1]; contacts_per_packet = 5; bytes_per_packet = WACOM_BYTES_PER_INTUOSP2_PACKET; @@ -1306,6 +1351,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) break; case INTUOSP2: + case INTUOSP2S: contact_id = data[offset]; prox = data[offset + 1] & 0x01; x = get_unaligned_le16(&data[offset + 2]); @@ -1904,6 +1950,11 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = le16_to_cpup((__le16 *)&data[4]); keys = 0; break; + case 7: + buttons = (data[1]) | (data[3] << 6); + ring = le16_to_cpup((__le16 *)&data[4]); + keys = 0; + break; case 0: buttons = 0; ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ @@ -1928,8 +1979,8 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ringvalue += 3*72/16; if (ringvalue > 71) ringvalue -= 72; - } - else if (input->id.product == 0x34d || input->id.product == 0x34e) { + } else if (input->id.product == 0x34d || input->id.product == 0x34e || + input->id.product == 0x398 || input->id.product == 0x399) { /* MobileStudio Pro */ ringvalue = 35 - (ring & 0x7F); ringvalue += 36/2; @@ -2141,6 +2192,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_MSPRO: case INTUOSP2: + case INTUOSP2S: case CINTIQ_16: if (len == WACOM_PKGLEN_INTUOSP2T && wacom_wac->data[0] == WACOM_REPORT_VENDOR_DEF_TOUCH) @@ -2504,6 +2556,12 @@ int wacom_setup_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_THROTTLE, 0, 71, 0, 0); /* fall through */ @@ -2523,6 +2581,13 @@ int wacom_setup_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); + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); @@ -2533,6 +2598,9 @@ int wacom_setup_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: @@ -2563,6 +2631,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, break; case INTUOSP2: + case INTUOSP2S: if (features->device_type == BTN_TOOL_PEN) { __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; @@ -2648,6 +2717,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, /* fall through */ case WACOM_27QHDT: + if (wacom_wac->shared->touch_input->id.product == 0x32C || + wacom_wac->shared->touch_input->id.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: @@ -2691,6 +2768,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case DTUS2: case DTK2451: input_set_capability(input_dev, EV_MSC, MSC_SERIAL); + /* fall through */ case DTUSX: case PL: @@ -3419,8 +3497,40 @@ static const struct wacom_features wacom_features_0x390 = { "Wacom Cintiq 16", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x391 = + { "Wacom Cintiq 22", WACOM_PKGLEN_MSPRO, 96012, 54358, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x392 = + { "Wacom Intuos Pro S", WACOM_PKGLEN_INTUOSP2, 31920, 19950, 8191, 63, + INTUOSP2S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 10 }; +static const struct wacom_features wacom_features_0x396 = + { "Wacom DTK-1660E", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x398 = + { "Wacom MobileStudio Pro 13", WACOM_PKGLEN_MSPRO, 59552, 33848, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39A }; +static const struct wacom_features wacom_features_0x399 = + { "Wacom MobileStudio Pro 16", WACOM_PKGLEN_MSPRO, 69920, 39680, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 13, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, - .oVid = USB_VENDOR_ID_WACOM }; + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39B }; +static const struct wacom_features wacom_features_0x39A = + { "Wacom MobileStudio Pro 13 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x398 }; +static const struct wacom_features wacom_features_0x39B = + { "Wacom MobileStudio Pro 16 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x399 }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -3611,6 +3721,13 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x37E) }, { USB_DEVICE_WACOM(0x382) }, { USB_DEVICE_DETAILED(0x390, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x391, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x392, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x396, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0x398) }, + { USB_DEVICE_WACOM(0x399) }, + { USB_DEVICE_WACOM(0x39A) }, + { USB_DEVICE_WACOM(0x39B) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, diff --git a/2.6.38/wacom_wac.h b/2.6.38/wacom_wac.h index c2e337d4..499c8e7d 100644 --- a/2.6.38/wacom_wac.h +++ b/2.6.38/wacom_wac.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_WAC_H #define WACOM_WAC_H @@ -143,6 +139,7 @@ enum { WACOM_MSPROT, DTH1152T, INTUOSP2, + INTUOSP2S, INTUOSHT3, WIRELESS, REMOTE, diff --git a/3.17/wacom.h b/3.17/wacom.h index b74b048f..dabc23ca 100644 --- a/3.17/wacom.h +++ b/3.17/wacom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom.h * @@ -78,10 +79,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_H #define WACOM_H diff --git a/3.17/wacom_sys.c b/3.17/wacom_sys.c index a2574c74..8aaaa7e6 100644 --- a/3.17/wacom_sys.c +++ b/3.17/wacom_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_sys.c * @@ -5,10 +6,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -139,7 +136,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, } static int wacom_wac_pen_serial_enforce(struct hid_device *hdev, - struct hid_report *report, u8 *raw_data, int size) + struct hid_report *report, u8 *raw_data, int report_size) { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; @@ -200,7 +197,8 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev, if (flush) wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo); else if (insert) - wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, raw_data, size); + wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, + raw_data, report_size); return insert && !flush; } @@ -355,18 +353,23 @@ static void wacom_feature_mapping(struct hid_device *hdev, wacom_hid_usage_quirk(hdev, field, usage); switch (equivalent_usage) { + case WACOM_HID_WD_TOUCH_RING_SETTING: + wacom->generic_has_leds = true; + break; case HID_DG_CONTACTMAX: /* leave touch_max as is if predefined */ if (!features->touch_max) { /* read manually */ - data = kzalloc(2, GFP_KERNEL); + n = wacom_hid_report_len(field->report); + data = hid_alloc_report_buf(field->report, GFP_KERNEL); if (!data) break; data[0] = field->report->id; ret = wacom_get_report(hdev, HID_FEATURE_REPORT, - data, 2, WAC_CMD_RETRIES); - if (ret == 2) { - features->touch_max = data[1]; + data, n, WAC_CMD_RETRIES); + if (ret == n) { + ret = hid_report_raw_event(hdev, + HID_FEATURE_REPORT, data, n, 0); } else { features->touch_max = 16; hid_warn(hdev, "wacom_feature_mapping: " @@ -2053,7 +2056,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct wacom_features *features = &wacom_wac->features; - char name[WACOM_NAME_MAX]; + char name[WACOM_NAME_MAX - 20]; /* Leave some room for suffixes */ /* Generic devices name unspecified */ if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { diff --git a/3.17/wacom_w8001.c b/3.17/wacom_w8001.c index 3715d1ea..691285ac 100644 --- a/3.17/wacom_w8001.c +++ b/3.17/wacom_w8001.c @@ -27,6 +27,8 @@ MODULE_AUTHOR("Jaya Kumar "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +#define W8001_MAX_PHYS 42 + #define W8001_MAX_LENGTH 13 #define W8001_LEAD_MASK 0x80 #define W8001_LEAD_BYTE 0x80 @@ -89,7 +91,7 @@ struct w8001 { unsigned char response_type; unsigned char response[W8001_MAX_LENGTH]; unsigned char data[W8001_MAX_LENGTH]; - char phys[32]; + char phys[W8001_MAX_PHYS]; int type; unsigned int pktlen; u16 max_touch_x; diff --git a/3.17/wacom_wac.c b/3.17/wacom_wac.c index f12bd972..9d39b0cb 100644 --- a/3.17/wacom_wac.c +++ b/3.17/wacom_wac.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_wac.c * * USB Wacom tablet support - Wacom specific code - * */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -269,7 +265,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) static int wacom_dtus_irq(struct wacom_wac *wacom) { - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; unsigned short prox, pressure = 0; @@ -503,6 +499,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 || @@ -532,10 +530,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])); @@ -553,14 +573,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) */ buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == CINTIQ_COMPANION_2) { - /* d-pad right -> data[4] & 0x10 - * d-pad up -> data[4] & 0x20 - * d-pad left -> data[4] & 0x40 - * d-pad down -> data[4] & 0x80 - * d-pad center -> data[3] & 0x01 + /* d-pad right -> data[2] & 0x10 + * d-pad up -> data[2] & 0x20 + * d-pad left -> data[2] & 0x40 + * d-pad down -> data[2] & 0x80 + * d-pad center -> data[1] & 0x01 */ buttons = ((data[2] >> 4) << 7) | - ((data[1] & 0x04) << 6) | + ((data[1] & 0x04) << 4) | ((data[2] & 0x0F) << 2) | (data[1] & 0x03); } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { @@ -581,6 +601,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) | @@ -592,7 +615,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3] & 0x1f) << 8) | data[4]; } - prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2; wacom_report_numbered_buttons(input, nbuttons, buttons); @@ -600,6 +623,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); @@ -866,6 +901,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) y >>= 1; distance >>= 1; } + if (features->type == INTUOSHT2) + distance = features->distance_max - distance; input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_DISTANCE, distance); @@ -1079,7 +1116,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) input_report_key(input, BTN_BASE2, (data[11] & 0x02)); if (data[12] & 0x80) - input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); + input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f) - 1); else input_report_abs(input, ABS_WHEEL, 0); @@ -1236,7 +1273,8 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) unsigned char *data = wacom->data; int i; - if (wacom->features.type == INTUOSP2_BT) { + if (wacom->features.type == INTUOSP2_BT || + wacom->features.type == INTUOSP2S_BT) { wacom->serial[0] = get_unaligned_le64(&data[99]); wacom->id[0] = get_unaligned_le16(&data[107]); pen_frame_len = 14; @@ -1288,7 +1326,8 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); - if (wacom->features.type == INTUOSP2_BT) { + if (wacom->features.type == INTUOSP2_BT || + wacom->features.type == INTUOSP2S_BT) { /* Fix rotation alignment: userspace expects zero at left */ int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); @@ -1309,7 +1348,8 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) if (wacom->tool[0]) { input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); - if (wacom->features.type == INTUOSP2_BT) { + if (wacom->features.type == INTUOSP2_BT || + wacom->features.type == INTUOSP2S_BT) { input_report_abs(pen_input, ABS_DISTANCE, range ? frame[13] : wacom->features.distance_max); } else { @@ -1476,7 +1516,8 @@ static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len) } wacom_intuos_pro2_bt_pen(wacom); - if (wacom->features.type == INTUOSP2_BT) { + if (wacom->features.type == INTUOSP2_BT || + wacom->features.type == INTUOSP2S_BT) { wacom_intuos_pro2_bt_touch(wacom); wacom_intuos_pro2_bt_pad(wacom); wacom_intuos_pro2_bt_battery(wacom); @@ -1498,6 +1539,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; @@ -1788,6 +1835,9 @@ int wacom_equivalent_usage(int usage) int subpage = (usage & 0xFF00) << 8; int subusage = (usage & 0xFF); + if (usage == WACOM_HID_WT_REPORT_VALID) + return usage; + if (subpage == HID_UP_UNDEFINED) subpage = WACOM_HID_SP_DIGITIZER; @@ -1947,8 +1997,6 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_BUTTONCENTER: - wacom->generic_has_leds = true; - /* fall through */ case WACOM_HID_WD_BUTTONHOME: case WACOM_HID_WD_BUTTONUP: case WACOM_HID_WD_BUTTONDOWN: @@ -2062,12 +2110,16 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field */ if (hdev->vendor == 0x56a && (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ - hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ + hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ + hdev->product == 0x392 || /* Intuos Pro 2 */ + hdev->product == 0x398 || hdev->product == 0x399)) { /* MobileStudio Pro */ value = (field->logical_maximum - value); - if (hdev->product == 0x357 || hdev->product == 0x358) + if (hdev->product == 0x357 || hdev->product == 0x358 || + hdev->product == 0x392) value = wacom_offset_rotation(input, usage, value, 3, 16); - else if (hdev->product == 0x34d || hdev->product == 0x34e) + else if (hdev->product == 0x34d || hdev->product == 0x34e || + hdev->product == 0x398 || hdev->product == 0x399) value = wacom_offset_rotation(input, usage, value, 1, 2); } else { @@ -2139,14 +2191,12 @@ static void wacom_wac_pad_report(struct hid_device *hdev, bool active = wacom_wac->hid_data.inrange_state != 0; /* report prox for expresskey events */ - if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) && - wacom_wac->hid_data.pad_input_event_flag) { + if (wacom_wac->hid_data.pad_input_event_flag) { input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); input_sync(input); if (!active) wacom_wac->hid_data.pad_input_event_flag = false; } - } static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, @@ -2532,6 +2582,10 @@ static void wacom_wac_finger_event(struct hid_device *hdev, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); + struct wacom_features *features = &wacom->wacom_wac.features; + + if (wacom_wac->is_invalid_bt_frame) + return; switch (equivalent_usage) { case HID_GD_X: @@ -2552,9 +2606,14 @@ static void wacom_wac_finger_event(struct hid_device *hdev, case HID_DG_TIPSWITCH: wacom_wac->hid_data.tipswitch = value; break; + case WACOM_HID_WT_REPORT_VALID: + wacom_wac->is_invalid_bt_frame = !value; + return; + case HID_DG_CONTACTMAX: + features->touch_max = value; + return; } - if (usage->usage_index + 1 == field->report_count) { if (equivalent_usage == wacom_wac->hid_data.last_slot_field) wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); @@ -2569,6 +2628,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, struct hid_data* hid_data = &wacom_wac->hid_data; int i; + wacom_wac->is_invalid_bt_frame = false; + for (i = 0; i < report->maxfield; i++) { struct hid_field *field = report->field[i]; int j; @@ -2589,25 +2650,9 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, case HID_DG_TIPSWITCH: hid_data->last_slot_field = equivalent_usage; break; - case HID_DG_CONTACTCOUNT: - hid_data->cc_report = report->id; - hid_data->cc_index = i; - hid_data->cc_value_index = j; - break; } } } - - 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) - 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, @@ -2617,6 +2662,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev, struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; + struct hid_data *hid_data = &wacom_wac->hid_data; /* If more packets of data are expected, give us a chance to * process them rather than immediately syncing a partial @@ -2630,6 +2676,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev, input_sync(input); wacom_wac->hid_data.num_received = 0; + hid_data->num_expected = 0; /* keep touch state for pen event */ wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); @@ -2704,12 +2751,73 @@ static void wacom_report_events(struct hid_device *hdev, } } +static void wacom_set_num_expected(struct hid_device *hdev, + struct hid_report *report, + int collection_index, + struct hid_field *field, + int field_index) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct hid_data *hid_data = &wacom_wac->hid_data; + unsigned int original_collection_level = + hdev->collection[collection_index].level; + bool end_collection = false; + int i; + + if (hid_data->num_expected) + return; + + // find the contact count value for this segment + for (i = field_index; i < report->maxfield && !end_collection; i++) { + struct hid_field *field = report->field[i]; + unsigned int field_level = + hdev->collection[field->usage[0].collection_index].level; + unsigned int j; + + if (field_level != original_collection_level) + continue; + + for (j = 0; j < field->maxusage; j++) { + struct hid_usage *usage = &field->usage[j]; + + if (usage->collection_index != collection_index) { + end_collection = true; + break; + } + if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) { + hid_data->cc_report = report->id; + hid_data->cc_index = i; + hid_data->cc_value_index = j; + + 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) + hid_data->num_expected = value; + } + } + } + } + + if (hid_data->cc_report == 0 || hid_data->cc_index < 0) + hid_data->num_expected = wacom_wac->features.touch_max; +} + static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, int collection_index, struct hid_field *field, int field_index) { struct wacom *wacom = hid_get_drvdata(hdev); + if (WACOM_FINGER_FIELD(field)) + wacom_set_num_expected(hdev, report, collection_index, field, + field_index); wacom_report_events(hdev, report, collection_index, field_index); /* @@ -2722,9 +2830,7 @@ static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *repo if (report->type != HID_INPUT_REPORT) return -1; - if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) - wacom_wac_pad_report(hdev, report, field); - else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) + if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_report(hdev, report); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_report(hdev, report); @@ -2738,7 +2844,7 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct hid_field *field; bool pad_in_hid_field = false, pen_in_hid_field = false, - finger_in_hid_field = false; + finger_in_hid_field = false, true_pad = false; int r; int prev_collection = -1; @@ -2754,6 +2860,8 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) pen_in_hid_field = true; if (WACOM_FINGER_FIELD(field)) finger_in_hid_field = true; + if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) + true_pad = true; } wacom_wac_battery_pre_report(hdev, report); @@ -2777,6 +2885,9 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) } wacom_wac_battery_report(hdev, report); + + if (true_pad && wacom->wacom_wac.pad_input) + wacom_wac_pad_report(hdev, report, field); } static int wacom_bpt_touch(struct wacom_wac *wacom) @@ -3245,6 +3356,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) break; case INTUOSP2_BT: + case INTUOSP2S_BT: case INTUOSHT3_BT: sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); break; @@ -3428,7 +3540,8 @@ void wacom_setup_device_quirks(struct wacom *wacom) if (features->type == REMOTE) features->device_type = WACOM_DEVICETYPE_PAD; - if (features->type == INTUOSP2_BT) { + if (features->type == INTUOSP2_BT || + features->type == INTUOSP2S_BT) { features->device_type |= WACOM_DEVICETYPE_PEN | WACOM_DEVICETYPE_PAD | WACOM_DEVICETYPE_TOUCH; @@ -3609,6 +3722,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, case INTUOS5S: case INTUOSPS: case INTUOSP2_BT: + case INTUOSP2S_BT: input_set_abs_params(input_dev, ABS_DISTANCE, 0, features->distance_max, features->distance_fuzz, 0); @@ -3723,6 +3837,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, switch (features->type) { case INTUOSP2_BT: + case INTUOSP2S_BT: input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); @@ -3738,8 +3853,14 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 5920, 4, 0); } + else if (wacom_wac->shared->touch->product == 0x393) { + input_set_abs_params(input_dev, ABS_MT_POSITION_X, + 0, 6400, 4, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, + 0, 4000, 4, 0); + } input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40); - input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40); + input_abs_set_res(input_dev, ABS_MT_POSITION_Y, 40); /* fall through */ @@ -3762,6 +3883,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: @@ -3900,6 +4029,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; @@ -3908,6 +4043,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); @@ -3921,6 +4062,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: @@ -3950,6 +4094,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOS5S: case INTUOSPS: case INTUOSP2_BT: + case INTUOSP2S_BT: input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); break; @@ -4527,6 +4672,10 @@ static const struct wacom_features wacom_features_0x37A = static const struct wacom_features wacom_features_0x37B = { "Wacom One by Wacom M", 21600, 13500, 2047, 63, BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0x393 = + { "Wacom Intuos Pro S", 31920, 19950, 8191, 63, + INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, + .touch_max = 10 }; static const struct wacom_features wacom_features_HID_ANY_ID = { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID }; @@ -4699,6 +4848,7 @@ const struct hid_device_id wacom_ids[] = { { BT_DEVICE_WACOM(0x379) }, { USB_DEVICE_WACOM(0x37A) }, { USB_DEVICE_WACOM(0x37B) }, + { BT_DEVICE_WACOM(0x393) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, diff --git a/3.17/wacom_wac.h b/3.17/wacom_wac.h index 2e0ab6fb..72addd37 100644 --- a/3.17/wacom_wac.h +++ b/3.17/wacom_wac.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_WAC_H #define WACOM_WAC_H @@ -165,6 +161,7 @@ #define WACOM_HID_WD_OFFSETBOTTOM (WACOM_HID_UP_WACOMDIGITIZER | 0x0d33) #define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002) #define WACOM_HID_WD_DIGITIZERINFO (WACOM_HID_UP_WACOMDIGITIZER | 0x1013) +#define WACOM_HID_WD_TOUCH_RING_SETTING (WACOM_HID_UP_WACOMDIGITIZER | 0x1032) #define WACOM_HID_UP_G9 0xff090000 #define WACOM_HID_G9_PEN (WACOM_HID_UP_G9 | 0x02) #define WACOM_HID_G9_TOUCHSCREEN (WACOM_HID_UP_G9 | 0x11) @@ -178,6 +175,7 @@ #define WACOM_HID_WT_SERIALNUMBER (WACOM_HID_UP_WACOMTOUCH | 0x5b) #define WACOM_HID_WT_X (WACOM_HID_UP_WACOMTOUCH | 0x130) #define WACOM_HID_WT_Y (WACOM_HID_UP_WACOMTOUCH | 0x131) +#define WACOM_HID_WT_REPORT_VALID (WACOM_HID_UP_WACOMTOUCH | 0x1d0) #define WACOM_BATTERY_USAGE(f) (((f)->hid == HID_DG_BATTERYSTRENGTH) || \ ((f)->hid == WACOM_HID_WD_BATTERY_CHARGING) || \ @@ -234,6 +232,7 @@ enum { INTUOSPM, INTUOSPL, INTUOSP2_BT, + INTUOSP2S_BT, INTUOSHT3_BT, WACOM_21UX2, WACOM_22HD, diff --git a/3.7/wacom.h b/3.7/wacom.h index 1ef3ee8e..e917521e 100644 --- a/3.7/wacom.h +++ b/3.7/wacom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom.h * @@ -75,10 +76,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_H #define WACOM_H diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c index 4e5288d1..0b1cbca7 100644 --- a/3.7/wacom_sys.c +++ b/3.7/wacom_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_sys.c * @@ -5,10 +6,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include @@ -359,7 +356,8 @@ static int wacom_parse_hid(struct usb_interface *intf, case HID_USAGE_WT_X: if (finger) features->device_type = BTN_TOOL_FINGER; - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->touch_max = 10; features->pktlen = WACOM_PKGLEN_INTUOSP2T; features->unit = report[i+4]; @@ -370,7 +368,8 @@ static int wacom_parse_hid(struct usb_interface *intf, break; case HID_USAGE_WT_Y: - if (features->type == INTUOSP2) { + if (features->type == INTUOSP2 || + features->type == INTUOSP2S) { features->y_phy = get_unaligned_le16(&report[i + 4]); features->y_max = get_unaligned_le16(&report[i + 7]); } diff --git a/3.7/wacom_w8001.c b/3.7/wacom_w8001.c index 3715d1ea..691285ac 100644 --- a/3.7/wacom_w8001.c +++ b/3.7/wacom_w8001.c @@ -27,6 +27,8 @@ MODULE_AUTHOR("Jaya Kumar "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +#define W8001_MAX_PHYS 42 + #define W8001_MAX_LENGTH 13 #define W8001_LEAD_MASK 0x80 #define W8001_LEAD_BYTE 0x80 @@ -89,7 +91,7 @@ struct w8001 { unsigned char response_type; unsigned char response[W8001_MAX_LENGTH]; unsigned char data[W8001_MAX_LENGTH]; - char phys[32]; + char phys[W8001_MAX_PHYS]; int type; unsigned int pktlen; u16 max_touch_x; diff --git a/3.7/wacom_wac.c b/3.7/wacom_wac.c index 3eacf483..51ed3e69 100644 --- a/3.7/wacom_wac.c +++ b/3.7/wacom_wac.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_wac.c * * USB Wacom tablet support - Wacom specific code - * */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -269,7 +265,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) static int wacom_dtus_irq(struct wacom_wac *wacom) { - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->input; struct wacom_features *features = &wacom->features; unsigned short prox, pressure = 0; @@ -496,6 +492,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 || @@ -525,9 +523,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); + } } else if (features->type == CINTIQ_HYBRID) { /* * Do not send hardware buttons under Android. They @@ -542,14 +563,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) */ buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == CINTIQ_COMPANION_2) { - /* d-pad right -> data[4] & 0x10 - * d-pad up -> data[4] & 0x20 - * d-pad left -> data[4] & 0x40 - * d-pad down -> data[4] & 0x80 - * d-pad center -> data[3] & 0x01 + /* d-pad right -> data[2] & 0x10 + * d-pad up -> data[2] & 0x20 + * d-pad left -> data[2] & 0x40 + * d-pad down -> data[2] & 0x80 + * d-pad center -> data[1] & 0x01 */ buttons = ((data[2] >> 4) << 7) | - ((data[1] & 0x04) << 6) | + ((data[1] & 0x04) << 4) | ((data[2] & 0x0F) << 2) | (data[1] & 0x03); } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { @@ -570,6 +591,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) | @@ -581,7 +605,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3] & 0x1f) << 8) | data[4]; } - prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2; wacom_report_numbered_buttons(input, nbuttons, buttons); @@ -589,6 +613,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); @@ -842,6 +878,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) y >>= 1; distance >>= 1; } + if (features->type == INTUOSHT2) + distance = features->distance_max - distance; input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_DISTANCE, distance); @@ -1055,7 +1093,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) input_report_key(input, BTN_BASE2, (data[11] & 0x02)); if (data[12] & 0x80) - input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); + input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f) - 1); else input_report_abs(input, ABS_WHEEL, 0); @@ -1216,6 +1254,12 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 1; break; case WACOM_27QHDT: + if (wacom->shared->has_mute_touch_switch && + !wacom->shared->is_touch_on) { + if (!wacom->shared->touch_down) + return 0; + } + current_num_contacts = data[63]; contacts_per_packet = 10; bytes_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; @@ -1230,6 +1274,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) bytes_header = 3; break; case INTUOSP2: + case INTUOSP2S: current_num_contacts = data[1]; contacts_per_packet = 5; bytes_per_packet = WACOM_BYTES_PER_INTUOSP2_PACKET; @@ -1286,6 +1331,7 @@ static int wacom_multitouch_generic(struct wacom_wac *wacom) break; case INTUOSP2: + case INTUOSP2S: contact_id = data[offset]; prox = data[offset + 1] & 0x01; x = get_unaligned_le16(&data[offset + 2]); @@ -1886,6 +1932,11 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ring = le16_to_cpup((__le16 *)&data[4]); keys = 0; break; + case 7: + buttons = (data[1]) | (data[3] << 6); + ring = le16_to_cpup((__le16 *)&data[4]); + keys = 0; + break; case 0: buttons = 0; ring = WACOM_INTUOSP2_RING_UNTOUCHED; /* No ring */ @@ -1910,8 +1961,8 @@ static int wacom_mspro_pad_irq(struct wacom_wac *wacom) ringvalue += 3*72/16; if (ringvalue > 71) ringvalue -= 72; - } - else if (input->id.product == 0x34d || input->id.product == 0x34e) { + } else if (input->id.product == 0x34d || input->id.product == 0x34e || + input->id.product == 0x398 || input->id.product == 0x399) { /* MobileStudio Pro */ ringvalue = 35 - (ring & 0x7F); ringvalue += 36/2; @@ -2123,6 +2174,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case WACOM_MSPRO: case INTUOSP2: + case INTUOSP2S: case CINTIQ_16: if (len == WACOM_PKGLEN_INTUOSP2T && wacom_wac->data[0] == WACOM_REPORT_VENDOR_DEF_TOUCH) @@ -2475,6 +2527,12 @@ int wacom_setup_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_THROTTLE, 0, 71, 0, 0); /* fall through */ @@ -2494,6 +2552,13 @@ int wacom_setup_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); + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); @@ -2504,6 +2569,9 @@ int wacom_setup_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: @@ -2534,6 +2602,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, break; case INTUOSP2: + case INTUOSP2S: if (features->device_type == BTN_TOOL_PEN) { __set_bit(BTN_STYLUS3, input_dev->keybit); wacom_wac->previous_ring = WACOM_INTUOSP2_RING_UNTOUCHED; @@ -2604,6 +2673,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, /* fall through */ case WACOM_27QHDT: + if (wacom_wac->shared->touch_input->id.product == 0x32C || + wacom_wac->shared->touch_input->id.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: @@ -2636,6 +2713,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case DTUS2: case DTK2451: input_set_capability(input_dev, EV_MSC, MSC_SERIAL); + /* fall through */ case DTUSX: case PL: @@ -3349,8 +3427,40 @@ static const struct wacom_features wacom_features_0x390 = { "Wacom Cintiq 16", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x391 = + { "Wacom Cintiq 22", WACOM_PKGLEN_MSPRO, 96012, 54358, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x392 = + { "Wacom Intuos Pro S", WACOM_PKGLEN_INTUOSP2, 31920, 19950, 8191, 63, + INTUOSP2S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 10 }; +static const struct wacom_features wacom_features_0x396 = + { "Wacom DTK-1660E", WACOM_PKGLEN_MSPRO, 69632, 39518, 8191, 63, + CINTIQ_16, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; +static const struct wacom_features wacom_features_0x398 = + { "Wacom MobileStudio Pro 13", WACOM_PKGLEN_MSPRO, 59552, 33848, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39A }; +static const struct wacom_features wacom_features_0x399 = + { "Wacom MobileStudio Pro 16", WACOM_PKGLEN_MSPRO, 69920, 39680, 8191, 63, + WACOM_MSPRO, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 13, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, - .oVid = USB_VENDOR_ID_WACOM }; + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x39B }; +static const struct wacom_features wacom_features_0x39A = + { "Wacom MobileStudio Pro 13 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x398 }; +static const struct wacom_features wacom_features_0x39B = + { "Wacom MobileStudio Pro 16 Touch", WACOM_PKGLEN_MSPROT, /* Touch */ + .type = WACOM_MSPROT, .touch_max = 10, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x399 }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -3541,6 +3651,13 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x37E) }, { USB_DEVICE_WACOM(0x382) }, { USB_DEVICE_DETAILED(0x390, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x391, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x392, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x396, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0x398) }, + { USB_DEVICE_WACOM(0x399) }, + { USB_DEVICE_WACOM(0x39A) }, + { USB_DEVICE_WACOM(0x39B) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, diff --git a/3.7/wacom_wac.h b/3.7/wacom_wac.h index da7387a3..fb68cb6f 100644 --- a/3.7/wacom_wac.h +++ b/3.7/wacom_wac.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_WAC_H #define WACOM_WAC_H @@ -143,6 +139,7 @@ enum { WACOM_MSPROT, DTH1152T, INTUOSP2, + INTUOSP2S, INTUOSHT3, WIRELESS, REMOTE, diff --git a/4.5/wacom.h b/4.5/wacom.h index 160216af..c120c885 100644 --- a/4.5/wacom.h +++ b/4.5/wacom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom.h * @@ -78,10 +79,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_H #define WACOM_H diff --git a/4.5/wacom_sys.c b/4.5/wacom_sys.c index 1958426f..5b97b8cf 100644 --- a/4.5/wacom_sys.c +++ b/4.5/wacom_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_sys.c * @@ -5,10 +6,6 @@ */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" diff --git a/4.5/wacom_wac.c b/4.5/wacom_wac.c index e6624e82..49c5d744 100644 --- a/4.5/wacom_wac.c +++ b/4.5/wacom_wac.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/input/tablet/wacom_wac.c * * USB Wacom tablet support - Wacom specific code - * */ /* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include "wacom_wac.h" @@ -893,6 +889,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) y >>= 1; distance >>= 1; } + if (features->type == INTUOSHT2) + distance = features->distance_max - distance; input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_DISTANCE, distance); @@ -1106,7 +1104,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) input_report_key(input, BTN_BASE2, (data[11] & 0x02)); if (data[12] & 0x80) - input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); + input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f) - 1); else input_report_abs(input, ABS_WHEEL, 0); diff --git a/4.5/wacom_wac.h b/4.5/wacom_wac.h index 118af340..3d2bee73 100644 --- a/4.5/wacom_wac.h +++ b/4.5/wacom_wac.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef WACOM_WAC_H #define WACOM_WAC_H diff --git a/configure.ac b/configure.ac index c449f5a9..aa196792 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.60) AC_INIT([input-wacom], - [0.42.0]) + [0.43.0]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) diff --git a/release.sh b/release.sh index 883adfc4..be87484f 100755 --- a/release.sh +++ b/release.sh @@ -96,86 +96,6 @@ fi } -#------------------------------------------------------------------------------ -# Function: release_to_sourceforge -#------------------------------------------------------------------------------ -# -release_to_sourceforge () { - - # Some hostnames are also used as /srv subdirs - host_linuxwacom="shell.sourceforge.net" - - section_path=archive/individual/$section - srv_path="/srv/$host_current/$section_path" - - if [ x"$section" = xxf86-input-wacom ] || - [ x"$section" = xinput-wacom ] || - [ x"$section" = xlibwacom ]; then - # input-wacom files are in a subdirectory for whatever reason - if [ x"$section" = xinput-wacom ]; then - section="xf86-input-wacom/input-wacom" - fi - - hostname=$host_linuxwacom - host_current="sourceforge.net" - section_path="projects/linuxwacom/files/$section" - srv_path="/home/frs/project/linuxwacom/$section" - - echo "creating shell on sourceforge for $SF_USERNAME" - ssh ${SF_USERNAME%@},linuxwacom@$hostname create - #echo "Simply log out once you get to the prompt" - #ssh -t ${SF_USERNAME%@},linuxwacom@$hostname create - #echo "Sleeping for 30 seconds, because this sometimes helps against sourceforge's random authentication denials" - #sleep 30 - fi - - # Use personal web space on the host for unit testing (leave commented out) - # srv_path="~/public_html$srv_path" - - # Check that the server path actually does exist - ssh $SF_USERNAME$hostname ls $srv_path >/dev/null 2>&1 || - if [ $? -ne 0 ]; then - echo "Error: the path \"$srv_path\" on the web server does not exist." - cd $top_src - return 1 - fi - - # Check for already existing tarballs - for tarball in $targz $tarbz2 $tarxz; do - ssh $SF_USERNAME$hostname ls $srv_path/$tarball >/dev/null 2>&1 - if [ $? -eq 0 ]; then - if [ "x$FORCE" = "xyes" ]; then - echo "Warning: overwriting released tarballs due to --force option." - else - echo "Error: tarball $tar_name already exists. Use --force to overwrite." - cd $top_src - return 1 - fi - fi - done - - # Upload to host using the 'scp' remote file copy program - if [ x"$DRY_RUN" = x ]; then - echo "Info: uploading tarballs to web server:" - scp $targz $tarbz2 $tarxz $siggz $sigbz2 $sigxz $SF_USERNAME$hostname:$srv_path - if [ $? -ne 0 ]; then - echo "Error: the tarballs uploading failed." - cd $top_src - return 1 - fi - else - echo "Info: skipping tarballs uploading in dry-run mode." - echo " \"$srv_path\"." - fi - - host_current="sourceforge.net" - section_path="projects/linuxwacom/files/$section" - # DL_URL & PGP_URL will be overwritten by the Github download url if github was - # enabled on the command line - DL_URL="http://$host_current/$section_path/$tarbz2" - PGP_URL="http://$host_current/$section_path/$tarbz2.sig" -} - #------------------------------------------------------------------------------ # Function: check_json_message #------------------------------------------------------------------------------ @@ -204,7 +124,7 @@ release_to_github() { # example skomra:de0e4dc3efbf2d008053027708227b365b7f80bf GH_REPO="linuxwacom" - PROJECT="input-wacom" + PROJECT="$1" release_description="Temporary Empty Release Description" release_descr=$(jq -n --arg release_description "$release_description" '$release_description') @@ -253,8 +173,6 @@ generate_announce() cat </dev/null` @@ -732,7 +645,6 @@ Options: --moduleset The jhbuild moduleset full pathname to be updated --no-quit Do not quit after error; just print error message --github Release project to Github with username / token - --sourceforge @ Release project to Sourceforge with username Environment variables defined by the "make" program and used by release.sh: MAKE The name of the make command [make] @@ -824,12 +736,6 @@ do GH_USERNAME=$2 shift ;; - # Sourceforge username. Optional. - --sourceforge) - check_option_args $1 $2 - shift - SF_USERNAME=$1 - ;; --*) echo "" echo "Error: unknown option: $1" @@ -859,9 +765,9 @@ do shift done -if [[ x$GH_USERNAME = "x" ]] && [[ x$SF_USERNAME = "x" ]] ; then - echo "At least one of --github or --sourceforge option required"; - exit 1; +if [[ x$GH_USERNAME = "x" ]] ; then + GH_USERNAME=`whoami` + echo "--github missing, using local username as github username" fi # If no modules specified (blank cmd line) display help