diff options
| -rw-r--r-- | drivers/hid/wacom_sys.c | 3 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.c | 87 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 7 | ||||
| -rw-r--r-- | include/uapi/linux/input.h | 1 |
4 files changed, 83 insertions, 15 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index f01ab3a0c5f5..f0568a7e6de9 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -403,6 +403,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev, | |||
| 403 | else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { | 403 | else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { |
| 404 | return wacom_set_device_mode(hdev, 18, 3, 2); | 404 | return wacom_set_device_mode(hdev, 18, 3, 2); |
| 405 | } | 405 | } |
| 406 | else if (features->type == WACOM_27QHDT) { | ||
| 407 | return wacom_set_device_mode(hdev, 131, 3, 2); | ||
| 408 | } | ||
| 406 | } else if (features->device_type == BTN_TOOL_PEN) { | 409 | } else if (features->device_type == BTN_TOOL_PEN) { |
| 407 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { | 410 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
| 408 | return wacom_set_device_mode(hdev, 2, 2, 2); | 411 | return wacom_set_device_mode(hdev, 2, 2, 2); |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index d239d82a1f90..1a6507999a65 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -656,6 +656,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 656 | data[0] != WACOM_REPORT_INTUOSREAD && | 656 | data[0] != WACOM_REPORT_INTUOSREAD && |
| 657 | data[0] != WACOM_REPORT_INTUOSWRITE && | 657 | data[0] != WACOM_REPORT_INTUOSWRITE && |
| 658 | data[0] != WACOM_REPORT_INTUOSPAD && | 658 | data[0] != WACOM_REPORT_INTUOSPAD && |
| 659 | data[0] != WACOM_REPORT_CINTIQ && | ||
| 660 | data[0] != WACOM_REPORT_CINTIQPAD && | ||
| 659 | data[0] != WACOM_REPORT_INTUOS5PAD) { | 661 | data[0] != WACOM_REPORT_INTUOS5PAD) { |
| 660 | dev_dbg(input->dev.parent, | 662 | dev_dbg(input->dev.parent, |
| 661 | "%s: received unknown report #%d\n", __func__, data[0]); | 663 | "%s: received unknown report #%d\n", __func__, data[0]); |
| @@ -667,7 +669,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 667 | idx = data[1] & 0x01; | 669 | idx = data[1] & 0x01; |
| 668 | 670 | ||
| 669 | /* pad packets. Works as a second tool and is always in prox */ | 671 | /* pad packets. Works as a second tool and is always in prox */ |
| 670 | if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) { | 672 | if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || |
| 673 | data[0] == WACOM_REPORT_CINTIQPAD) { | ||
| 671 | input = wacom->pad_input; | 674 | input = wacom->pad_input; |
| 672 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 675 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
| 673 | input_report_key(input, BTN_0, (data[2] & 0x01)); | 676 | input_report_key(input, BTN_0, (data[2] & 0x01)); |
| @@ -767,6 +770,14 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 767 | } else { | 770 | } else { |
| 768 | input_report_abs(input, ABS_MISC, 0); | 771 | input_report_abs(input, ABS_MISC, 0); |
| 769 | } | 772 | } |
| 773 | } else if (features->type == WACOM_27QHD) { | ||
| 774 | input_report_key(input, KEY_PROG1, data[2] & 0x01); | ||
| 775 | input_report_key(input, KEY_PROG2, data[2] & 0x02); | ||
| 776 | input_report_key(input, KEY_PROG3, data[2] & 0x04); | ||
| 777 | |||
| 778 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); | ||
| 779 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); | ||
| 780 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); | ||
| 770 | } else if (features->type == CINTIQ_HYBRID) { | 781 | } else if (features->type == CINTIQ_HYBRID) { |
| 771 | /* | 782 | /* |
| 772 | * Do not send hardware buttons under Android. They | 783 | * Do not send hardware buttons under Android. They |
| @@ -1027,8 +1038,20 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1027 | struct input_dev *input = wacom->input; | 1038 | struct input_dev *input = wacom->input; |
| 1028 | unsigned char *data = wacom->data; | 1039 | unsigned char *data = wacom->data; |
| 1029 | int i; | 1040 | int i; |
| 1030 | int current_num_contacts = data[61]; | 1041 | int current_num_contacts = 0; |
| 1031 | int contacts_to_send = 0; | 1042 | int contacts_to_send = 0; |
| 1043 | int num_contacts_left = 4; /* maximum contacts per packet */ | ||
| 1044 | int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; | ||
| 1045 | int y_offset = 2; | ||
| 1046 | |||
| 1047 | if (wacom->features.type == WACOM_27QHDT) { | ||
| 1048 | current_num_contacts = data[63]; | ||
| 1049 | num_contacts_left = 10; | ||
| 1050 | byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; | ||
| 1051 | y_offset = 0; | ||
| 1052 | } else { | ||
| 1053 | current_num_contacts = data[61]; | ||
| 1054 | } | ||
| 1032 | 1055 | ||
| 1033 | /* | 1056 | /* |
| 1034 | * First packet resets the counter since only the first | 1057 | * First packet resets the counter since only the first |
| @@ -1037,11 +1060,10 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1037 | if (current_num_contacts) | 1060 | if (current_num_contacts) |
| 1038 | wacom->num_contacts_left = current_num_contacts; | 1061 | wacom->num_contacts_left = current_num_contacts; |
| 1039 | 1062 | ||
| 1040 | /* There are at most 4 contacts per packet */ | 1063 | contacts_to_send = min(num_contacts_left, wacom->num_contacts_left); |
| 1041 | contacts_to_send = min(4, wacom->num_contacts_left); | ||
| 1042 | 1064 | ||
| 1043 | for (i = 0; i < contacts_to_send; i++) { | 1065 | for (i = 0; i < contacts_to_send; i++) { |
| 1044 | int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; | 1066 | int offset = (byte_per_packet * i) + 1; |
| 1045 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; | 1067 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; |
| 1046 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); | 1068 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); |
| 1047 | 1069 | ||
| @@ -1052,18 +1074,23 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1052 | 1074 | ||
| 1053 | if (touch) { | 1075 | if (touch) { |
| 1054 | int t_x = get_unaligned_le16(&data[offset + 2]); | 1076 | int t_x = get_unaligned_le16(&data[offset + 2]); |
| 1055 | int c_x = get_unaligned_le16(&data[offset + 4]); | 1077 | int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]); |
| 1056 | int t_y = get_unaligned_le16(&data[offset + 6]); | ||
| 1057 | int c_y = get_unaligned_le16(&data[offset + 8]); | ||
| 1058 | int w = get_unaligned_le16(&data[offset + 10]); | ||
| 1059 | int h = get_unaligned_le16(&data[offset + 12]); | ||
| 1060 | 1078 | ||
| 1061 | input_report_abs(input, ABS_MT_POSITION_X, t_x); | 1079 | input_report_abs(input, ABS_MT_POSITION_X, t_x); |
| 1062 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); | 1080 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); |
| 1063 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | 1081 | |
| 1064 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | 1082 | if (wacom->features.type != WACOM_27QHDT) { |
| 1065 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | 1083 | int c_x = get_unaligned_le16(&data[offset + 4]); |
| 1066 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | 1084 | int c_y = get_unaligned_le16(&data[offset + 8]); |
| 1085 | int w = get_unaligned_le16(&data[offset + 10]); | ||
| 1086 | int h = get_unaligned_le16(&data[offset + 12]); | ||
| 1087 | |||
| 1088 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | ||
| 1089 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | ||
| 1090 | min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | ||
| 1091 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | ||
| 1092 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | ||
| 1093 | } | ||
| 1067 | } | 1094 | } |
| 1068 | } | 1095 | } |
| 1069 | input_mt_report_pointer_emulation(input, true); | 1096 | input_mt_report_pointer_emulation(input, true); |
| @@ -1894,6 +1921,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 1894 | case WACOM_21UX2: | 1921 | case WACOM_21UX2: |
| 1895 | case WACOM_22HD: | 1922 | case WACOM_22HD: |
| 1896 | case WACOM_24HD: | 1923 | case WACOM_24HD: |
| 1924 | case WACOM_27QHD: | ||
| 1897 | case DTK: | 1925 | case DTK: |
| 1898 | case CINTIQ_HYBRID: | 1926 | case CINTIQ_HYBRID: |
| 1899 | sync = wacom_intuos_irq(wacom_wac); | 1927 | sync = wacom_intuos_irq(wacom_wac); |
| @@ -1904,6 +1932,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 1904 | break; | 1932 | break; |
| 1905 | 1933 | ||
| 1906 | case WACOM_24HDT: | 1934 | case WACOM_24HDT: |
| 1935 | case WACOM_27QHDT: | ||
| 1907 | sync = wacom_24hdt_irq(wacom_wac); | 1936 | sync = wacom_24hdt_irq(wacom_wac); |
| 1908 | break; | 1937 | break; |
| 1909 | 1938 | ||
| @@ -2115,6 +2144,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2115 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 2144 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
| 2116 | break; | 2145 | break; |
| 2117 | 2146 | ||
| 2147 | case WACOM_27QHD: | ||
| 2118 | case WACOM_24HD: | 2148 | case WACOM_24HD: |
| 2119 | case DTK: | 2149 | case DTK: |
| 2120 | case WACOM_22HD: | 2150 | case WACOM_22HD: |
| @@ -2183,6 +2213,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2183 | } | 2213 | } |
| 2184 | /* fall through */ | 2214 | /* fall through */ |
| 2185 | 2215 | ||
| 2216 | case WACOM_27QHDT: | ||
| 2186 | case MTSCREEN: | 2217 | case MTSCREEN: |
| 2187 | case MTTPC: | 2218 | case MTTPC: |
| 2188 | case MTTPC_B: | 2219 | case MTTPC_B: |
| @@ -2330,6 +2361,19 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
| 2330 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | 2361 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
| 2331 | break; | 2362 | break; |
| 2332 | 2363 | ||
| 2364 | case WACOM_27QHD: | ||
| 2365 | __set_bit(KEY_PROG1, input_dev->keybit); | ||
| 2366 | __set_bit(KEY_PROG2, input_dev->keybit); | ||
| 2367 | __set_bit(KEY_PROG3, input_dev->keybit); | ||
| 2368 | input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0); | ||
| 2369 | input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */ | ||
| 2370 | input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0); | ||
| 2371 | input_abs_set_res(input_dev, ABS_Y, 1024); | ||
| 2372 | input_set_abs_params(input_dev, ABS_Z, -2048, 2048, 0, 0); | ||
| 2373 | input_abs_set_res(input_dev, ABS_Z, 1024); | ||
| 2374 | __set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit); | ||
| 2375 | break; | ||
| 2376 | |||
| 2333 | case DTK: | 2377 | case DTK: |
| 2334 | for (i = 0; i < 6; i++) | 2378 | for (i = 0; i < 6; i++) |
| 2335 | __set_bit(BTN_0 + i, input_dev->keybit); | 2379 | __set_bit(BTN_0 + i, input_dev->keybit); |
| @@ -2680,6 +2724,18 @@ static const struct wacom_features wacom_features_0xF6 = | |||
| 2680 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | 2724 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ |
| 2681 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, | 2725 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, |
| 2682 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2726 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
| 2727 | static const struct wacom_features wacom_features_0x32A = | ||
| 2728 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, | ||
| 2729 | 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
| 2730 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
| 2731 | static const struct wacom_features wacom_features_0x32B = | ||
| 2732 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, | ||
| 2733 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
| 2734 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
| 2735 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C }; | ||
| 2736 | static const struct wacom_features wacom_features_0x32C = | ||
| 2737 | { "Wacom Cintiq 27QHD touch", .type = WACOM_27QHDT, | ||
| 2738 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 }; | ||
| 2683 | static const struct wacom_features wacom_features_0x3F = | 2739 | static const struct wacom_features wacom_features_0x3F = |
| 2684 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, | 2740 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, |
| 2685 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2741 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| @@ -3046,6 +3102,9 @@ const struct hid_device_id wacom_ids[] = { | |||
| 3046 | { USB_DEVICE_WACOM(0x315) }, | 3102 | { USB_DEVICE_WACOM(0x315) }, |
| 3047 | { USB_DEVICE_WACOM(0x317) }, | 3103 | { USB_DEVICE_WACOM(0x317) }, |
| 3048 | { USB_DEVICE_WACOM(0x323) }, | 3104 | { USB_DEVICE_WACOM(0x323) }, |
| 3105 | { USB_DEVICE_WACOM(0x32A) }, | ||
| 3106 | { USB_DEVICE_WACOM(0x32B) }, | ||
| 3107 | { USB_DEVICE_WACOM(0x32C) }, | ||
| 3049 | { USB_DEVICE_WACOM(0x32F) }, | 3108 | { USB_DEVICE_WACOM(0x32F) }, |
| 3050 | { USB_DEVICE_WACOM(0x4001) }, | 3109 | { USB_DEVICE_WACOM(0x4001) }, |
| 3051 | { USB_DEVICE_WACOM(0x4004) }, | 3110 | { USB_DEVICE_WACOM(0x4004) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 72e78cc18933..021ee1c1980a 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <linux/hid.h> | 13 | #include <linux/hid.h> |
| 14 | 14 | ||
| 15 | /* maximum packet length for USB devices */ | 15 | /* maximum packet length for USB devices */ |
| 16 | #define WACOM_PKGLEN_MAX 68 | 16 | #define WACOM_PKGLEN_MAX 192 |
| 17 | 17 | ||
| 18 | #define WACOM_NAME_MAX 64 | 18 | #define WACOM_NAME_MAX 64 |
| 19 | 19 | ||
| @@ -37,6 +37,7 @@ | |||
| 37 | /* wacom data size per MT contact */ | 37 | /* wacom data size per MT contact */ |
| 38 | #define WACOM_BYTES_PER_MT_PACKET 11 | 38 | #define WACOM_BYTES_PER_MT_PACKET 11 |
| 39 | #define WACOM_BYTES_PER_24HDT_PACKET 14 | 39 | #define WACOM_BYTES_PER_24HDT_PACKET 14 |
| 40 | #define WACOM_BYTES_PER_QHDTHID_PACKET 6 | ||
| 40 | 41 | ||
| 41 | /* device IDs */ | 42 | /* device IDs */ |
| 42 | #define STYLUS_DEVICE_ID 0x02 | 43 | #define STYLUS_DEVICE_ID 0x02 |
| @@ -58,6 +59,8 @@ | |||
| 58 | #define WACOM_REPORT_TPCMT 13 | 59 | #define WACOM_REPORT_TPCMT 13 |
| 59 | #define WACOM_REPORT_TPCMT2 3 | 60 | #define WACOM_REPORT_TPCMT2 3 |
| 60 | #define WACOM_REPORT_TPCHID 15 | 61 | #define WACOM_REPORT_TPCHID 15 |
| 62 | #define WACOM_REPORT_CINTIQ 16 | ||
| 63 | #define WACOM_REPORT_CINTIQPAD 17 | ||
| 61 | #define WACOM_REPORT_TPCST 16 | 64 | #define WACOM_REPORT_TPCST 16 |
| 62 | #define WACOM_REPORT_DTUS 17 | 65 | #define WACOM_REPORT_DTUS 17 |
| 63 | #define WACOM_REPORT_TPC1FGE 18 | 66 | #define WACOM_REPORT_TPC1FGE 18 |
| @@ -109,6 +112,7 @@ enum { | |||
| 109 | WACOM_22HD, | 112 | WACOM_22HD, |
| 110 | DTK, | 113 | DTK, |
| 111 | WACOM_24HD, | 114 | WACOM_24HD, |
| 115 | WACOM_27QHD, | ||
| 112 | CINTIQ_HYBRID, | 116 | CINTIQ_HYBRID, |
| 113 | CINTIQ, | 117 | CINTIQ, |
| 114 | WACOM_BEE, | 118 | WACOM_BEE, |
| @@ -117,6 +121,7 @@ enum { | |||
| 117 | WIRELESS, | 121 | WIRELESS, |
| 118 | BAMBOO_PT, | 122 | BAMBOO_PT, |
| 119 | WACOM_24HDT, | 123 | WACOM_24HDT, |
| 124 | WACOM_27QHDT, | ||
| 120 | TABLETPC, /* add new TPC below */ | 125 | TABLETPC, /* add new TPC below */ |
| 121 | TABLETPCE, | 126 | TABLETPCE, |
| 122 | TABLETPC2FG, | 127 | TABLETPC2FG, |
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index a1d7e931ab72..b0a813079852 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h | |||
| @@ -166,6 +166,7 @@ struct input_keymap_entry { | |||
| 166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ | 166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ |
| 167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ | 167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ |
| 168 | #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ | 168 | #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ |
| 169 | #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ | ||
| 169 | 170 | ||
| 170 | #define INPUT_PROP_MAX 0x1f | 171 | #define INPUT_PROP_MAX 0x1f |
| 171 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) | 172 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) |
