.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/input/tablet/wacom_wac.c |
---|
3 | 4 | * |
---|
4 | 5 | * USB Wacom tablet support - Wacom specific code |
---|
5 | | - * |
---|
6 | 6 | */ |
---|
7 | 7 | |
---|
8 | 8 | /* |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License as published by |
---|
11 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
12 | | - * (at your option) any later version. |
---|
13 | 9 | */ |
---|
14 | 10 | |
---|
15 | 11 | #include "wacom_wac.h" |
---|
.. | .. |
---|
345 | 341 | |
---|
346 | 342 | case 2: /* Mouse with wheel */ |
---|
347 | 343 | input_report_key(input, BTN_MIDDLE, data[1] & 0x04); |
---|
348 | | - /* fall through */ |
---|
| 344 | + fallthrough; |
---|
349 | 345 | |
---|
350 | 346 | case 3: /* Mouse without wheel */ |
---|
351 | 347 | wacom->tool[0] = BTN_TOOL_MOUSE; |
---|
.. | .. |
---|
487 | 483 | int ring1 = 0, ring2 = 0; |
---|
488 | 484 | int strip1 = 0, strip2 = 0; |
---|
489 | 485 | bool prox = false; |
---|
| 486 | + bool wrench = false, keyboard = false, mute_touch = false, menu = false, |
---|
| 487 | + info = false; |
---|
490 | 488 | |
---|
491 | 489 | /* pad packets. Works as a second tool and is always in prox */ |
---|
492 | 490 | if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || |
---|
.. | .. |
---|
516 | 514 | keys = ((data[3] & 0x1C) ? 1<<2 : 0) | |
---|
517 | 515 | ((data[4] & 0xE0) ? 1<<1 : 0) | |
---|
518 | 516 | ((data[4] & 0x07) ? 1<<0 : 0); |
---|
| 517 | + keyboard = !!(data[4] & 0xE0); |
---|
| 518 | + info = !!(data[3] & 0x1C); |
---|
| 519 | + |
---|
| 520 | + if (features->oPid) { |
---|
| 521 | + mute_touch = !!(data[4] & 0x07); |
---|
| 522 | + if (mute_touch) |
---|
| 523 | + wacom->shared->is_touch_on = |
---|
| 524 | + !wacom->shared->is_touch_on; |
---|
| 525 | + } else { |
---|
| 526 | + wrench = !!(data[4] & 0x07); |
---|
| 527 | + } |
---|
519 | 528 | } else if (features->type == WACOM_27QHD) { |
---|
520 | 529 | nkeys = 3; |
---|
521 | 530 | keys = data[2] & 0x07; |
---|
522 | 531 | |
---|
| 532 | + wrench = !!(data[2] & 0x01); |
---|
| 533 | + keyboard = !!(data[2] & 0x02); |
---|
| 534 | + |
---|
| 535 | + if (features->oPid) { |
---|
| 536 | + mute_touch = !!(data[2] & 0x04); |
---|
| 537 | + if (mute_touch) |
---|
| 538 | + wacom->shared->is_touch_on = |
---|
| 539 | + !wacom->shared->is_touch_on; |
---|
| 540 | + } else { |
---|
| 541 | + menu = !!(data[2] & 0x04); |
---|
| 542 | + } |
---|
523 | 543 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); |
---|
524 | 544 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); |
---|
525 | 545 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); |
---|
.. | .. |
---|
565 | 585 | if (features->type == WACOM_22HD) { |
---|
566 | 586 | nkeys = 3; |
---|
567 | 587 | keys = data[9] & 0x07; |
---|
| 588 | + |
---|
| 589 | + info = !!(data[9] & 0x01); |
---|
| 590 | + wrench = !!(data[9] & 0x02); |
---|
568 | 591 | } |
---|
569 | 592 | } else { |
---|
570 | 593 | buttons = ((data[6] & 0x10) << 5) | |
---|
.. | .. |
---|
583 | 606 | |
---|
584 | 607 | for (i = 0; i < nkeys; i++) |
---|
585 | 608 | input_report_key(input, KEY_PROG1 + i, keys & (1 << i)); |
---|
| 609 | + |
---|
| 610 | + input_report_key(input, KEY_BUTTONCONFIG, wrench); |
---|
| 611 | + input_report_key(input, KEY_ONSCREEN_KEYBOARD, keyboard); |
---|
| 612 | + input_report_key(input, KEY_CONTROLPANEL, menu); |
---|
| 613 | + input_report_key(input, KEY_INFO, info); |
---|
| 614 | + |
---|
| 615 | + if (wacom->shared && wacom->shared->touch_input) { |
---|
| 616 | + input_report_switch(wacom->shared->touch_input, |
---|
| 617 | + SW_MUTE_DEVICE, |
---|
| 618 | + !wacom->shared->is_touch_on); |
---|
| 619 | + input_sync(wacom->shared->touch_input); |
---|
| 620 | + } |
---|
586 | 621 | |
---|
587 | 622 | input_report_abs(input, ABS_RX, strip1); |
---|
588 | 623 | input_report_abs(input, ABS_RY, strip2); |
---|
.. | .. |
---|
603 | 638 | return (tool_id & ~0xFFF) << 4 | (tool_id & 0xFFF); |
---|
604 | 639 | } |
---|
605 | 640 | |
---|
| 641 | +static bool wacom_is_art_pen(int tool_id) |
---|
| 642 | +{ |
---|
| 643 | + bool is_art_pen = false; |
---|
| 644 | + |
---|
| 645 | + switch (tool_id) { |
---|
| 646 | + case 0x885: /* Intuos3 Marker Pen */ |
---|
| 647 | + case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ |
---|
| 648 | + case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */ |
---|
| 649 | + is_art_pen = true; |
---|
| 650 | + break; |
---|
| 651 | + } |
---|
| 652 | + return is_art_pen; |
---|
| 653 | +} |
---|
| 654 | + |
---|
606 | 655 | static int wacom_intuos_get_tool_type(int tool_id) |
---|
607 | 656 | { |
---|
608 | | - int tool_type; |
---|
| 657 | + int tool_type = BTN_TOOL_PEN; |
---|
| 658 | + |
---|
| 659 | + if (wacom_is_art_pen(tool_id)) |
---|
| 660 | + return tool_type; |
---|
609 | 661 | |
---|
610 | 662 | switch (tool_id) { |
---|
611 | 663 | case 0x812: /* Inking pen */ |
---|
.. | .. |
---|
620 | 672 | case 0x852: |
---|
621 | 673 | case 0x823: /* Intuos3 Grip Pen */ |
---|
622 | 674 | case 0x813: /* Intuos3 Classic Pen */ |
---|
623 | | - case 0x885: /* Intuos3 Marker Pen */ |
---|
624 | 675 | case 0x802: /* Intuos4/5 13HD/24HD General Pen */ |
---|
625 | | - case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ |
---|
626 | 676 | case 0x8e2: /* IntuosHT2 pen */ |
---|
627 | 677 | case 0x022: |
---|
628 | | - case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */ |
---|
| 678 | + case 0x10842: /* MobileStudio Pro Pro Pen slim */ |
---|
629 | 679 | case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */ |
---|
630 | 680 | case 0x16802: /* Cintiq 13HD Pro Pen */ |
---|
631 | 681 | case 0x18802: /* DTH2242 Pen */ |
---|
.. | .. |
---|
667 | 717 | case 0x1480a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */ |
---|
668 | 718 | case 0x1090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ |
---|
669 | 719 | case 0x1080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ |
---|
| 720 | + case 0x1084a: /* MobileStudio Pro Pro Pen slim Eraser */ |
---|
670 | 721 | case 0x1680a: /* Cintiq 13HD Pro Pen Eraser */ |
---|
671 | 722 | case 0x1880a: /* DTH2242 Eraser */ |
---|
672 | 723 | case 0x1080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ |
---|
.. | .. |
---|
680 | 731 | case 0x902: /* Intuos4/5 13HD/24HD Airbrush */ |
---|
681 | 732 | case 0x10902: /* Intuos4/5 13HD/24HD Airbrush */ |
---|
682 | 733 | tool_type = BTN_TOOL_AIRBRUSH; |
---|
683 | | - break; |
---|
684 | | - |
---|
685 | | - default: /* Unknown tool */ |
---|
686 | | - tool_type = BTN_TOOL_PEN; |
---|
687 | 734 | break; |
---|
688 | 735 | } |
---|
689 | 736 | return tool_type; |
---|
.. | .. |
---|
1164 | 1211 | case 0x04: |
---|
1165 | 1212 | wacom_intuos_bt_process_data(wacom, data + i); |
---|
1166 | 1213 | i += 10; |
---|
1167 | | - /* fall through */ |
---|
| 1214 | + fallthrough; |
---|
1168 | 1215 | case 0x03: |
---|
1169 | 1216 | wacom_intuos_bt_process_data(wacom, data + i); |
---|
1170 | 1217 | i += 10; |
---|
.. | .. |
---|
1220 | 1267 | unsigned char *data = wacom->data; |
---|
1221 | 1268 | int i; |
---|
1222 | 1269 | |
---|
1223 | | - if (wacom->features.type == INTUOSP2_BT) { |
---|
| 1270 | + if (wacom->features.type == INTUOSP2_BT || |
---|
| 1271 | + wacom->features.type == INTUOSP2S_BT) { |
---|
1224 | 1272 | wacom->serial[0] = get_unaligned_le64(&data[99]); |
---|
1225 | 1273 | wacom->id[0] = get_unaligned_le16(&data[107]); |
---|
1226 | 1274 | pen_frame_len = 14; |
---|
.. | .. |
---|
1272 | 1320 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); |
---|
1273 | 1321 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); |
---|
1274 | 1322 | |
---|
1275 | | - if (wacom->features.type == INTUOSP2_BT) { |
---|
| 1323 | + if (wacom->features.type == INTUOSP2_BT || |
---|
| 1324 | + wacom->features.type == INTUOSP2S_BT) { |
---|
1276 | 1325 | /* Fix rotation alignment: userspace expects zero at left */ |
---|
1277 | 1326 | int16_t rotation = |
---|
1278 | 1327 | (int16_t)get_unaligned_le16(&frame[9]); |
---|
.. | .. |
---|
1290 | 1339 | get_unaligned_le16(&frame[11])); |
---|
1291 | 1340 | } |
---|
1292 | 1341 | } |
---|
1293 | | - |
---|
1294 | 1342 | if (wacom->tool[0]) { |
---|
1295 | 1343 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); |
---|
1296 | | - if (wacom->features.type == INTUOSP2_BT) { |
---|
| 1344 | + if (wacom->features.type == INTUOSP2_BT || |
---|
| 1345 | + wacom->features.type == INTUOSP2S_BT) { |
---|
1297 | 1346 | input_report_abs(pen_input, ABS_DISTANCE, |
---|
1298 | 1347 | range ? frame[13] : wacom->features.distance_max); |
---|
1299 | 1348 | } else { |
---|
.. | .. |
---|
1388 | 1437 | { |
---|
1389 | 1438 | struct input_dev *pad_input = wacom->pad_input; |
---|
1390 | 1439 | unsigned char *data = wacom->data; |
---|
| 1440 | + int nbuttons = wacom->features.numbered_buttons; |
---|
1391 | 1441 | |
---|
1392 | | - int buttons = data[282] | ((data[281] & 0x40) << 2); |
---|
| 1442 | + int expresskeys = data[282]; |
---|
| 1443 | + int center = (data[281] & 0x40) >> 6; |
---|
1393 | 1444 | int ring = data[285] & 0x7F; |
---|
1394 | 1445 | bool ringstatus = data[285] & 0x80; |
---|
1395 | | - bool prox = buttons || ringstatus; |
---|
| 1446 | + bool prox = expresskeys || center || ringstatus; |
---|
1396 | 1447 | |
---|
1397 | 1448 | /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ |
---|
1398 | 1449 | ring = 71 - ring; |
---|
.. | .. |
---|
1400 | 1451 | if (ring > 71) |
---|
1401 | 1452 | ring -= 72; |
---|
1402 | 1453 | |
---|
1403 | | - wacom_report_numbered_buttons(pad_input, 9, buttons); |
---|
| 1454 | + wacom_report_numbered_buttons(pad_input, nbuttons, |
---|
| 1455 | + expresskeys | (center << (nbuttons - 1))); |
---|
1404 | 1456 | |
---|
1405 | 1457 | input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); |
---|
1406 | 1458 | |
---|
.. | .. |
---|
1460 | 1512 | } |
---|
1461 | 1513 | |
---|
1462 | 1514 | wacom_intuos_pro2_bt_pen(wacom); |
---|
1463 | | - if (wacom->features.type == INTUOSP2_BT) { |
---|
| 1515 | + if (wacom->features.type == INTUOSP2_BT || |
---|
| 1516 | + wacom->features.type == INTUOSP2S_BT) { |
---|
1464 | 1517 | wacom_intuos_pro2_bt_touch(wacom); |
---|
1465 | 1518 | wacom_intuos_pro2_bt_pad(wacom); |
---|
1466 | 1519 | wacom_intuos_pro2_bt_battery(wacom); |
---|
.. | .. |
---|
1481 | 1534 | int num_contacts_left = 4; /* maximum contacts per packet */ |
---|
1482 | 1535 | int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; |
---|
1483 | 1536 | int y_offset = 2; |
---|
| 1537 | + |
---|
| 1538 | + if (wacom->shared->has_mute_touch_switch && |
---|
| 1539 | + !wacom->shared->is_touch_on) { |
---|
| 1540 | + if (!wacom->shared->touch_down) |
---|
| 1541 | + return 0; |
---|
| 1542 | + } |
---|
1484 | 1543 | |
---|
1485 | 1544 | if (wacom->features.type == WACOM_27QHDT) { |
---|
1486 | 1545 | current_num_contacts = data[63]; |
---|
.. | .. |
---|
1772 | 1831 | int subpage = (usage & 0xFF00) << 8; |
---|
1773 | 1832 | int subusage = (usage & 0xFF); |
---|
1774 | 1833 | |
---|
| 1834 | + if (usage == WACOM_HID_WT_REPORT_VALID) |
---|
| 1835 | + return usage; |
---|
| 1836 | + |
---|
1775 | 1837 | if (subpage == HID_UP_UNDEFINED) |
---|
1776 | 1838 | subpage = WACOM_HID_SP_DIGITIZER; |
---|
1777 | 1839 | |
---|
.. | .. |
---|
1954 | 2016 | wacom_wac->has_mute_touch_switch = true; |
---|
1955 | 2017 | usage->type = EV_SW; |
---|
1956 | 2018 | usage->code = SW_MUTE_DEVICE; |
---|
1957 | | - features->device_type |= WACOM_DEVICETYPE_PAD; |
---|
1958 | 2019 | break; |
---|
1959 | 2020 | case WACOM_HID_WD_TOUCHSTRIP: |
---|
1960 | 2021 | wacom_map_usage(input, usage, field, EV_ABS, ABS_RX, 0); |
---|
.. | .. |
---|
2034 | 2095 | wacom_wac->hid_data.inrange_state |= value; |
---|
2035 | 2096 | } |
---|
2036 | 2097 | |
---|
2037 | | - switch (equivalent_usage) { |
---|
2038 | | - case WACOM_HID_WD_TOUCHRING: |
---|
2039 | | - /* |
---|
2040 | | - * Userspace expects touchrings to increase in value with |
---|
2041 | | - * clockwise gestures and have their zero point at the |
---|
2042 | | - * tablet's left. HID events "should" be clockwise- |
---|
2043 | | - * increasing and zero at top, though the MobileStudio |
---|
2044 | | - * Pro and 2nd-gen Intuos Pro don't do this... |
---|
2045 | | - */ |
---|
2046 | | - if (hdev->vendor == 0x56a && |
---|
2047 | | - (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ |
---|
2048 | | - hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ |
---|
2049 | | - value = (field->logical_maximum - value); |
---|
2050 | | - |
---|
2051 | | - if (hdev->product == 0x357 || hdev->product == 0x358) |
---|
2052 | | - value = wacom_offset_rotation(input, usage, value, 3, 16); |
---|
2053 | | - else if (hdev->product == 0x34d || hdev->product == 0x34e) |
---|
2054 | | - value = wacom_offset_rotation(input, usage, value, 1, 2); |
---|
2055 | | - } |
---|
2056 | | - else { |
---|
2057 | | - value = wacom_offset_rotation(input, usage, value, 1, 4); |
---|
2058 | | - } |
---|
2059 | | - do_report = true; |
---|
2060 | | - break; |
---|
2061 | | - case WACOM_HID_WD_TOUCHRINGSTATUS: |
---|
2062 | | - if (!value) |
---|
2063 | | - input_event(input, usage->type, usage->code, 0); |
---|
2064 | | - break; |
---|
2065 | | - |
---|
2066 | | - case WACOM_HID_WD_MUTE_DEVICE: |
---|
2067 | | - case WACOM_HID_WD_TOUCHONOFF: |
---|
| 2098 | + /* Process touch switch state first since it is reported through touch interface, |
---|
| 2099 | + * which is indepentent of pad interface. In the case when there are no other pad |
---|
| 2100 | + * events, the pad interface will not even be created. |
---|
| 2101 | + */ |
---|
| 2102 | + if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) || |
---|
| 2103 | + (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) { |
---|
2068 | 2104 | if (wacom_wac->shared->touch_input) { |
---|
2069 | 2105 | bool *is_touch_on = &wacom_wac->shared->is_touch_on; |
---|
2070 | 2106 | |
---|
.. | .. |
---|
2077 | 2113 | SW_MUTE_DEVICE, !(*is_touch_on)); |
---|
2078 | 2114 | input_sync(wacom_wac->shared->touch_input); |
---|
2079 | 2115 | } |
---|
| 2116 | + return; |
---|
| 2117 | + } |
---|
| 2118 | + |
---|
| 2119 | + if (!input) |
---|
| 2120 | + return; |
---|
| 2121 | + |
---|
| 2122 | + switch (equivalent_usage) { |
---|
| 2123 | + case WACOM_HID_WD_TOUCHRING: |
---|
| 2124 | + /* |
---|
| 2125 | + * Userspace expects touchrings to increase in value with |
---|
| 2126 | + * clockwise gestures and have their zero point at the |
---|
| 2127 | + * tablet's left. HID events "should" be clockwise- |
---|
| 2128 | + * increasing and zero at top, though the MobileStudio |
---|
| 2129 | + * Pro and 2nd-gen Intuos Pro don't do this... |
---|
| 2130 | + */ |
---|
| 2131 | + if (hdev->vendor == 0x56a && |
---|
| 2132 | + (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ |
---|
| 2133 | + hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ |
---|
| 2134 | + hdev->product == 0x392 || /* Intuos Pro 2 */ |
---|
| 2135 | + hdev->product == 0x398 || hdev->product == 0x399 || /* MobileStudio Pro */ |
---|
| 2136 | + hdev->product == 0x3AA)) { /* MobileStudio Pro */ |
---|
| 2137 | + value = (field->logical_maximum - value); |
---|
| 2138 | + |
---|
| 2139 | + if (hdev->product == 0x357 || hdev->product == 0x358 || |
---|
| 2140 | + hdev->product == 0x392) |
---|
| 2141 | + value = wacom_offset_rotation(input, usage, value, 3, 16); |
---|
| 2142 | + else if (hdev->product == 0x34d || hdev->product == 0x34e || |
---|
| 2143 | + hdev->product == 0x398 || hdev->product == 0x399 || |
---|
| 2144 | + hdev->product == 0x3AA) |
---|
| 2145 | + value = wacom_offset_rotation(input, usage, value, 1, 2); |
---|
| 2146 | + } |
---|
| 2147 | + else { |
---|
| 2148 | + value = wacom_offset_rotation(input, usage, value, 1, 4); |
---|
| 2149 | + } |
---|
| 2150 | + do_report = true; |
---|
| 2151 | + break; |
---|
| 2152 | + case WACOM_HID_WD_TOUCHRINGSTATUS: |
---|
| 2153 | + if (!value) |
---|
| 2154 | + input_event(input, usage->type, usage->code, 0); |
---|
2080 | 2155 | break; |
---|
2081 | 2156 | |
---|
2082 | 2157 | case WACOM_HID_WD_MODE_CHANGE: |
---|
.. | .. |
---|
2090 | 2165 | for (i = 0; i < wacom->led.count; i++) |
---|
2091 | 2166 | wacom_update_led(wacom, features->numbered_buttons, |
---|
2092 | 2167 | value, i); |
---|
2093 | | - /* fall through*/ |
---|
| 2168 | + fallthrough; |
---|
2094 | 2169 | default: |
---|
2095 | 2170 | do_report = true; |
---|
2096 | 2171 | break; |
---|
.. | .. |
---|
2181 | 2256 | case HID_DG_TOOLSERIALNUMBER: |
---|
2182 | 2257 | features->quirks |= WACOM_QUIRK_TOOLSERIAL; |
---|
2183 | 2258 | wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0); |
---|
2184 | | - |
---|
2185 | | - /* Adjust AES usages to match modern convention */ |
---|
2186 | | - if (usage->hid == WACOM_HID_WT_SERIALNUMBER && field->report_size == 16) { |
---|
2187 | | - if (field->index + 2 < field->report->maxfield) { |
---|
2188 | | - struct hid_field *a = field->report->field[field->index + 1]; |
---|
2189 | | - struct hid_field *b = field->report->field[field->index + 2]; |
---|
2190 | | - |
---|
2191 | | - if (a->maxusage > 0 && a->usage[0].hid == HID_DG_TOOLSERIALNUMBER && a->report_size == 32 && |
---|
2192 | | - b->maxusage > 0 && b->usage[0].hid == 0xFF000000 && b->report_size == 8) { |
---|
2193 | | - features->quirks |= WACOM_QUIRK_AESPEN; |
---|
2194 | | - usage->hid = WACOM_HID_WD_TOOLTYPE; |
---|
2195 | | - field->logical_minimum = S16_MIN; |
---|
2196 | | - field->logical_maximum = S16_MAX; |
---|
2197 | | - a->logical_minimum = S32_MIN; |
---|
2198 | | - a->logical_maximum = S32_MAX; |
---|
2199 | | - b->usage[0].hid = WACOM_HID_WD_SERIALHI; |
---|
2200 | | - b->logical_minimum = 0; |
---|
2201 | | - b->logical_maximum = U8_MAX; |
---|
2202 | | - } |
---|
2203 | | - } |
---|
2204 | | - } |
---|
2205 | 2259 | break; |
---|
2206 | 2260 | case WACOM_HID_WD_SENSE: |
---|
2207 | 2261 | features->quirks |= WACOM_QUIRK_SENSE; |
---|
.. | .. |
---|
2275 | 2329 | } |
---|
2276 | 2330 | return; |
---|
2277 | 2331 | case HID_DG_TWIST: |
---|
| 2332 | + /* don't modify the value if the pen doesn't support the feature */ |
---|
| 2333 | + if (!wacom_is_art_pen(wacom_wac->id[0])) return; |
---|
| 2334 | + |
---|
2278 | 2335 | /* |
---|
2279 | 2336 | * Userspace expects pen twist to have its zero point when |
---|
2280 | 2337 | * the buttons/finger is on the tablet's left. HID values |
---|
.. | .. |
---|
2555 | 2612 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
---|
2556 | 2613 | struct wacom_features *features = &wacom->wacom_wac.features; |
---|
2557 | 2614 | |
---|
| 2615 | + if (wacom_wac->is_invalid_bt_frame) |
---|
| 2616 | + return; |
---|
| 2617 | + |
---|
2558 | 2618 | switch (equivalent_usage) { |
---|
2559 | 2619 | case HID_DG_CONFIDENCE: |
---|
2560 | 2620 | wacom_wac->hid_data.confidence = value; |
---|
.. | .. |
---|
2577 | 2637 | case HID_DG_TIPSWITCH: |
---|
2578 | 2638 | wacom_wac->hid_data.tipswitch = value; |
---|
2579 | 2639 | break; |
---|
| 2640 | + case WACOM_HID_WT_REPORT_VALID: |
---|
| 2641 | + wacom_wac->is_invalid_bt_frame = !value; |
---|
| 2642 | + return; |
---|
2580 | 2643 | case HID_DG_CONTACTMAX: |
---|
2581 | 2644 | if (!features->touch_max) { |
---|
2582 | 2645 | features->touch_max = value; |
---|
.. | .. |
---|
2586 | 2649 | } |
---|
2587 | 2650 | return; |
---|
2588 | 2651 | } |
---|
2589 | | - |
---|
2590 | 2652 | |
---|
2591 | 2653 | if (usage->usage_index + 1 == field->report_count) { |
---|
2592 | 2654 | if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { |
---|
.. | .. |
---|
2607 | 2669 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
---|
2608 | 2670 | struct hid_data* hid_data = &wacom_wac->hid_data; |
---|
2609 | 2671 | int i; |
---|
| 2672 | + |
---|
| 2673 | + wacom_wac->is_invalid_bt_frame = false; |
---|
2610 | 2674 | |
---|
2611 | 2675 | hid_data->confidence = true; |
---|
2612 | 2676 | |
---|
.. | .. |
---|
2719 | 2783 | /* usage tests must precede field tests */ |
---|
2720 | 2784 | if (WACOM_BATTERY_USAGE(usage)) |
---|
2721 | 2785 | wacom_wac_battery_event(hdev, field, usage, value); |
---|
2722 | | - else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) |
---|
| 2786 | + else if (WACOM_PAD_FIELD(field)) |
---|
2723 | 2787 | wacom_wac_pad_event(hdev, field, usage, value); |
---|
2724 | 2788 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) |
---|
2725 | 2789 | wacom_wac_pen_event(hdev, field, usage, value); |
---|
.. | .. |
---|
3299 | 3363 | break; |
---|
3300 | 3364 | |
---|
3301 | 3365 | case INTUOSP2_BT: |
---|
| 3366 | + case INTUOSP2S_BT: |
---|
3302 | 3367 | case INTUOSHT3_BT: |
---|
3303 | 3368 | sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); |
---|
3304 | 3369 | break; |
---|
.. | .. |
---|
3479 | 3544 | if (features->type == REMOTE) |
---|
3480 | 3545 | features->device_type = WACOM_DEVICETYPE_PAD; |
---|
3481 | 3546 | |
---|
3482 | | - if (features->type == INTUOSP2_BT) { |
---|
| 3547 | + if (features->type == INTUOSP2_BT || |
---|
| 3548 | + features->type == INTUOSP2S_BT) { |
---|
3483 | 3549 | features->device_type |= WACOM_DEVICETYPE_PEN | |
---|
3484 | 3550 | WACOM_DEVICETYPE_PAD | |
---|
3485 | 3551 | WACOM_DEVICETYPE_TOUCH; |
---|
.. | .. |
---|
3599 | 3665 | switch (features->type) { |
---|
3600 | 3666 | case GRAPHIRE_BT: |
---|
3601 | 3667 | __clear_bit(ABS_MISC, input_dev->absbit); |
---|
| 3668 | + fallthrough; |
---|
3602 | 3669 | |
---|
3603 | 3670 | case WACOM_MO: |
---|
3604 | 3671 | case WACOM_G4: |
---|
3605 | 3672 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, |
---|
3606 | 3673 | features->distance_max, |
---|
3607 | 3674 | features->distance_fuzz, 0); |
---|
3608 | | - /* fall through */ |
---|
| 3675 | + fallthrough; |
---|
3609 | 3676 | |
---|
3610 | 3677 | case GRAPHIRE: |
---|
3611 | 3678 | input_set_capability(input_dev, EV_REL, REL_WHEEL); |
---|
.. | .. |
---|
3645 | 3712 | case INTUOS4S: |
---|
3646 | 3713 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
---|
3647 | 3714 | input_abs_set_res(input_dev, ABS_Z, 287); |
---|
3648 | | - /* fall through */ |
---|
| 3715 | + fallthrough; |
---|
3649 | 3716 | |
---|
3650 | 3717 | case INTUOS: |
---|
3651 | 3718 | wacom_setup_intuos(wacom_wac); |
---|
.. | .. |
---|
3658 | 3725 | case INTUOS5S: |
---|
3659 | 3726 | case INTUOSPS: |
---|
3660 | 3727 | case INTUOSP2_BT: |
---|
| 3728 | + case INTUOSP2S_BT: |
---|
3661 | 3729 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, |
---|
3662 | 3730 | features->distance_max, |
---|
3663 | 3731 | features->distance_fuzz, 0); |
---|
.. | .. |
---|
3677 | 3745 | case TABLETPC: |
---|
3678 | 3746 | case TABLETPCE: |
---|
3679 | 3747 | __clear_bit(ABS_MISC, input_dev->absbit); |
---|
3680 | | - /* fall through */ |
---|
| 3748 | + fallthrough; |
---|
3681 | 3749 | |
---|
3682 | 3750 | case DTUS: |
---|
3683 | 3751 | case DTUSX: |
---|
.. | .. |
---|
3691 | 3759 | |
---|
3692 | 3760 | case PTU: |
---|
3693 | 3761 | __set_bit(BTN_STYLUS2, input_dev->keybit); |
---|
3694 | | - /* fall through */ |
---|
| 3762 | + fallthrough; |
---|
3695 | 3763 | |
---|
3696 | 3764 | case PENPARTNER: |
---|
3697 | 3765 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
---|
.. | .. |
---|
3768 | 3836 | |
---|
3769 | 3837 | switch (features->type) { |
---|
3770 | 3838 | case INTUOSP2_BT: |
---|
| 3839 | + case INTUOSP2S_BT: |
---|
3771 | 3840 | input_dev->evbit[0] |= BIT_MASK(EV_SW); |
---|
3772 | 3841 | __set_bit(SW_MUTE_DEVICE, input_dev->swbit); |
---|
3773 | 3842 | |
---|
.. | .. |
---|
3783 | 3852 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, |
---|
3784 | 3853 | 0, 5920, 4, 0); |
---|
3785 | 3854 | } |
---|
| 3855 | + else if (wacom_wac->shared->touch->product == 0x393) { |
---|
| 3856 | + input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
---|
| 3857 | + 0, 6400, 4, 0); |
---|
| 3858 | + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, |
---|
| 3859 | + 0, 4000, 4, 0); |
---|
| 3860 | + } |
---|
3786 | 3861 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40); |
---|
3787 | 3862 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, 40); |
---|
3788 | 3863 | |
---|
3789 | | - /* fall through */ |
---|
| 3864 | + fallthrough; |
---|
3790 | 3865 | |
---|
3791 | 3866 | case INTUOS5: |
---|
3792 | 3867 | case INTUOS5L: |
---|
.. | .. |
---|
3804 | 3879 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); |
---|
3805 | 3880 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); |
---|
3806 | 3881 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); |
---|
3807 | | - /* fall through */ |
---|
| 3882 | + fallthrough; |
---|
3808 | 3883 | |
---|
3809 | 3884 | case WACOM_27QHDT: |
---|
| 3885 | + if (wacom_wac->shared->touch->product == 0x32C || |
---|
| 3886 | + wacom_wac->shared->touch->product == 0xF6) { |
---|
| 3887 | + input_dev->evbit[0] |= BIT_MASK(EV_SW); |
---|
| 3888 | + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); |
---|
| 3889 | + wacom_wac->has_mute_touch_switch = true; |
---|
| 3890 | + } |
---|
| 3891 | + fallthrough; |
---|
| 3892 | + |
---|
3810 | 3893 | case MTSCREEN: |
---|
3811 | 3894 | case MTTPC: |
---|
3812 | 3895 | case MTTPC_B: |
---|
3813 | 3896 | case TABLETPC2FG: |
---|
3814 | 3897 | input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT); |
---|
3815 | | - /*fall through */ |
---|
| 3898 | + fallthrough; |
---|
3816 | 3899 | |
---|
3817 | 3900 | case TABLETPC: |
---|
3818 | 3901 | case TABLETPCE: |
---|
.. | .. |
---|
3822 | 3905 | case INTUOSHT2: |
---|
3823 | 3906 | input_dev->evbit[0] |= BIT_MASK(EV_SW); |
---|
3824 | 3907 | __set_bit(SW_MUTE_DEVICE, input_dev->swbit); |
---|
3825 | | - /* fall through */ |
---|
| 3908 | + fallthrough; |
---|
3826 | 3909 | |
---|
3827 | 3910 | case BAMBOO_PT: |
---|
3828 | 3911 | case BAMBOO_TOUCH: |
---|
.. | .. |
---|
4042 | 4125 | __set_bit(KEY_PROG2, input_dev->keybit); |
---|
4043 | 4126 | __set_bit(KEY_PROG3, input_dev->keybit); |
---|
4044 | 4127 | |
---|
| 4128 | + __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit); |
---|
| 4129 | + __set_bit(KEY_INFO, input_dev->keybit); |
---|
| 4130 | + |
---|
| 4131 | + if (!features->oPid) |
---|
| 4132 | + __set_bit(KEY_BUTTONCONFIG, input_dev->keybit); |
---|
| 4133 | + |
---|
4045 | 4134 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
---|
4046 | 4135 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
---|
4047 | 4136 | break; |
---|
.. | .. |
---|
4050 | 4139 | __set_bit(KEY_PROG1, input_dev->keybit); |
---|
4051 | 4140 | __set_bit(KEY_PROG2, input_dev->keybit); |
---|
4052 | 4141 | __set_bit(KEY_PROG3, input_dev->keybit); |
---|
| 4142 | + |
---|
| 4143 | + __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit); |
---|
| 4144 | + __set_bit(KEY_BUTTONCONFIG, input_dev->keybit); |
---|
| 4145 | + |
---|
| 4146 | + if (!features->oPid) |
---|
| 4147 | + __set_bit(KEY_CONTROLPANEL, input_dev->keybit); |
---|
4053 | 4148 | input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0); |
---|
4054 | 4149 | input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */ |
---|
4055 | 4150 | input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0); |
---|
.. | .. |
---|
4063 | 4158 | __set_bit(KEY_PROG1, input_dev->keybit); |
---|
4064 | 4159 | __set_bit(KEY_PROG2, input_dev->keybit); |
---|
4065 | 4160 | __set_bit(KEY_PROG3, input_dev->keybit); |
---|
4066 | | - /* fall through */ |
---|
| 4161 | + |
---|
| 4162 | + __set_bit(KEY_BUTTONCONFIG, input_dev->keybit); |
---|
| 4163 | + __set_bit(KEY_INFO, input_dev->keybit); |
---|
| 4164 | + fallthrough; |
---|
4067 | 4165 | |
---|
4068 | 4166 | case WACOM_21UX2: |
---|
4069 | 4167 | case WACOM_BEE: |
---|
.. | .. |
---|
4079 | 4177 | case INTUOS3: |
---|
4080 | 4178 | case INTUOS3L: |
---|
4081 | 4179 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
---|
4082 | | - /* fall through */ |
---|
| 4180 | + fallthrough; |
---|
4083 | 4181 | |
---|
4084 | 4182 | case INTUOS3S: |
---|
4085 | 4183 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
---|
.. | .. |
---|
4092 | 4190 | case INTUOS5S: |
---|
4093 | 4191 | case INTUOSPS: |
---|
4094 | 4192 | case INTUOSP2_BT: |
---|
| 4193 | + case INTUOSP2S_BT: |
---|
4095 | 4194 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
---|
4096 | 4195 | break; |
---|
4097 | 4196 | |
---|
.. | .. |
---|
4102 | 4201 | * ID_INPUT_TABLET to be set. |
---|
4103 | 4202 | */ |
---|
4104 | 4203 | __set_bit(BTN_STYLUS, input_dev->keybit); |
---|
4105 | | - /* fall through */ |
---|
| 4204 | + fallthrough; |
---|
4106 | 4205 | |
---|
4107 | 4206 | case INTUOS4: |
---|
4108 | 4207 | case INTUOS4L: |
---|
.. | .. |
---|
4669 | 4768 | static const struct wacom_features wacom_features_0x37B = |
---|
4670 | 4769 | { "Wacom One by Wacom M", 21600, 13500, 2047, 63, |
---|
4671 | 4770 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
---|
| 4771 | +static const struct wacom_features wacom_features_0x393 = |
---|
| 4772 | + { "Wacom Intuos Pro S", 31920, 19950, 8191, 63, |
---|
| 4773 | + INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, |
---|
| 4774 | + .touch_max = 10 }; |
---|
| 4775 | +static const struct wacom_features wacom_features_0x3c6 = |
---|
| 4776 | + { "Wacom Intuos BT S", 15200, 9500, 4095, 63, |
---|
| 4777 | + INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; |
---|
| 4778 | +static const struct wacom_features wacom_features_0x3c8 = |
---|
| 4779 | + { "Wacom Intuos BT M", 21600, 13500, 4095, 63, |
---|
| 4780 | + INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; |
---|
4672 | 4781 | |
---|
4673 | 4782 | static const struct wacom_features wacom_features_HID_ANY_ID = |
---|
4674 | 4783 | { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID }; |
---|
.. | .. |
---|
4841 | 4950 | { BT_DEVICE_WACOM(0x379) }, |
---|
4842 | 4951 | { USB_DEVICE_WACOM(0x37A) }, |
---|
4843 | 4952 | { USB_DEVICE_WACOM(0x37B) }, |
---|
| 4953 | + { BT_DEVICE_WACOM(0x393) }, |
---|
| 4954 | + { BT_DEVICE_WACOM(0x3c6) }, |
---|
| 4955 | + { BT_DEVICE_WACOM(0x3c8) }, |
---|
4844 | 4956 | { USB_DEVICE_WACOM(0x4001) }, |
---|
4845 | 4957 | { USB_DEVICE_WACOM(0x4004) }, |
---|
4846 | 4958 | { USB_DEVICE_WACOM(0x5000) }, |
---|