diff options
author | Ping Cheng <pinglinux@gmail.com> | 2015-01-27 16:30:03 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-01-29 08:05:05 -0500 |
commit | 500d4160abe9a2e88b12e319c13ae3ebd1e18108 (patch) | |
tree | b592fb9443e6621d2d51ab4dec42139481f614c1 /drivers/hid/wacom_wac.c | |
parent | a2f71c6c878e664cce4591fc1de36dce2bf44d8d (diff) |
HID: wacom: add support for Cintiq 27QHD and 27QHD touch
These devices have accelerometers. To report accelerometer coordinates, a new
property, INPUT_PROP_ACCELEROMETER, is added.
Signed-off-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/wacom_wac.c')
-rw-r--r-- | drivers/hid/wacom_wac.c | 87 |
1 files changed, 73 insertions, 14 deletions
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) }, |