aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_wac.c
diff options
context:
space:
mode:
authorPing Cheng <pinglinux@gmail.com>2015-01-27 16:30:03 -0500
committerJiri Kosina <jkosina@suse.cz>2015-01-29 08:05:05 -0500
commit500d4160abe9a2e88b12e319c13ae3ebd1e18108 (patch)
treeb592fb9443e6621d2d51ab4dec42139481f614c1 /drivers/hid/wacom_wac.c
parenta2f71c6c878e664cce4591fc1de36dce2bf44d8d (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.c87
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 };
2727static 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 };
2731static 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 };
2736static 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 };
2683static const struct wacom_features wacom_features_0x3F = 2739static 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) },