| .. | .. |
|---|
| 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) }, |
|---|