Skip to content

Commit 500d416

Browse files
PinglinuxJiri Kosina
authored andcommitted
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 <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent a2f71c6 commit 500d416

File tree

4 files changed

+83
-15
lines changed

4 files changed

+83
-15
lines changed

drivers/hid/wacom_sys.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev,
403403
else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
404404
return wacom_set_device_mode(hdev, 18, 3, 2);
405405
}
406+
else if (features->type == WACOM_27QHDT) {
407+
return wacom_set_device_mode(hdev, 131, 3, 2);
408+
}
406409
} else if (features->device_type == BTN_TOOL_PEN) {
407410
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
408411
return wacom_set_device_mode(hdev, 2, 2, 2);

drivers/hid/wacom_wac.c

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
656656
data[0] != WACOM_REPORT_INTUOSREAD &&
657657
data[0] != WACOM_REPORT_INTUOSWRITE &&
658658
data[0] != WACOM_REPORT_INTUOSPAD &&
659+
data[0] != WACOM_REPORT_CINTIQ &&
660+
data[0] != WACOM_REPORT_CINTIQPAD &&
659661
data[0] != WACOM_REPORT_INTUOS5PAD) {
660662
dev_dbg(input->dev.parent,
661663
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -667,7 +669,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
667669
idx = data[1] & 0x01;
668670

669671
/* 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) {
671674
input = wacom->pad_input;
672675
if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
673676
input_report_key(input, BTN_0, (data[2] & 0x01));
@@ -767,6 +770,14 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
767770
} else {
768771
input_report_abs(input, ABS_MISC, 0);
769772
}
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]));
770781
} else if (features->type == CINTIQ_HYBRID) {
771782
/*
772783
* Do not send hardware buttons under Android. They
@@ -1027,8 +1038,20 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
10271038
struct input_dev *input = wacom->input;
10281039
unsigned char *data = wacom->data;
10291040
int i;
1030-
int current_num_contacts = data[61];
1041+
int current_num_contacts = 0;
10311042
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+
}
10321055

10331056
/*
10341057
* First packet resets the counter since only the first
@@ -1037,11 +1060,10 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
10371060
if (current_num_contacts)
10381061
wacom->num_contacts_left = current_num_contacts;
10391062

1040-
/* There are at most 4 contacts per packet */
1041-
contacts_to_send = min(4, wacom->num_contacts_left);
1063+
contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
10421064

10431065
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;
10451067
bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity;
10461068
int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
10471069

@@ -1052,18 +1074,23 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
10521074

10531075
if (touch) {
10541076
int t_x = get_unaligned_le16(&data[offset + 2]);
1055-
int c_x = get_unaligned_le16(&data[offset + 4]);
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]);
1077+
int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]);
10601078

10611079
input_report_abs(input, ABS_MT_POSITION_X, t_x);
10621080
input_report_abs(input, ABS_MT_POSITION_Y, t_y);
1063-
input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
1064-
input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
1065-
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
1066-
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
1081+
1082+
if (wacom->features.type != WACOM_27QHDT) {
1083+
int c_x = get_unaligned_le16(&data[offset + 4]);
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+
}
10671094
}
10681095
}
10691096
input_mt_report_pointer_emulation(input, true);
@@ -1894,6 +1921,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
18941921
case WACOM_21UX2:
18951922
case WACOM_22HD:
18961923
case WACOM_24HD:
1924+
case WACOM_27QHD:
18971925
case DTK:
18981926
case CINTIQ_HYBRID:
18991927
sync = wacom_intuos_irq(wacom_wac);
@@ -1904,6 +1932,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
19041932
break;
19051933

19061934
case WACOM_24HDT:
1935+
case WACOM_27QHDT:
19071936
sync = wacom_24hdt_irq(wacom_wac);
19081937
break;
19091938

@@ -2115,6 +2144,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
21152144
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
21162145
break;
21172146

2147+
case WACOM_27QHD:
21182148
case WACOM_24HD:
21192149
case DTK:
21202150
case WACOM_22HD:
@@ -2183,6 +2213,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
21832213
}
21842214
/* fall through */
21852215

2216+
case WACOM_27QHDT:
21862217
case MTSCREEN:
21872218
case MTTPC:
21882219
case MTTPC_B:
@@ -2330,6 +2361,19 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
23302361
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
23312362
break;
23322363

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+
23332377
case DTK:
23342378
for (i = 0; i < 6; i++)
23352379
__set_bit(BTN_0 + i, input_dev->keybit);
@@ -2680,6 +2724,18 @@ static const struct wacom_features wacom_features_0xF6 =
26802724
{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
26812725
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
26822726
.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 };
26832739
static const struct wacom_features wacom_features_0x3F =
26842740
{ "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
26852741
CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
@@ -3046,6 +3102,9 @@ const struct hid_device_id wacom_ids[] = {
30463102
{ USB_DEVICE_WACOM(0x315) },
30473103
{ USB_DEVICE_WACOM(0x317) },
30483104
{ USB_DEVICE_WACOM(0x323) },
3105+
{ USB_DEVICE_WACOM(0x32A) },
3106+
{ USB_DEVICE_WACOM(0x32B) },
3107+
{ USB_DEVICE_WACOM(0x32C) },
30493108
{ USB_DEVICE_WACOM(0x32F) },
30503109
{ USB_DEVICE_WACOM(0x4001) },
30513110
{ USB_DEVICE_WACOM(0x4004) },

drivers/hid/wacom_wac.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <linux/hid.h>
1414

1515
/* maximum packet length for USB devices */
16-
#define WACOM_PKGLEN_MAX 68
16+
#define WACOM_PKGLEN_MAX 192
1717

1818
#define WACOM_NAME_MAX 64
1919

@@ -37,6 +37,7 @@
3737
/* wacom data size per MT contact */
3838
#define WACOM_BYTES_PER_MT_PACKET 11
3939
#define WACOM_BYTES_PER_24HDT_PACKET 14
40+
#define WACOM_BYTES_PER_QHDTHID_PACKET 6
4041

4142
/* device IDs */
4243
#define STYLUS_DEVICE_ID 0x02
@@ -58,6 +59,8 @@
5859
#define WACOM_REPORT_TPCMT 13
5960
#define WACOM_REPORT_TPCMT2 3
6061
#define WACOM_REPORT_TPCHID 15
62+
#define WACOM_REPORT_CINTIQ 16
63+
#define WACOM_REPORT_CINTIQPAD 17
6164
#define WACOM_REPORT_TPCST 16
6265
#define WACOM_REPORT_DTUS 17
6366
#define WACOM_REPORT_TPC1FGE 18
@@ -109,6 +112,7 @@ enum {
109112
WACOM_22HD,
110113
DTK,
111114
WACOM_24HD,
115+
WACOM_27QHD,
112116
CINTIQ_HYBRID,
113117
CINTIQ,
114118
WACOM_BEE,
@@ -117,6 +121,7 @@ enum {
117121
WIRELESS,
118122
BAMBOO_PT,
119123
WACOM_24HDT,
124+
WACOM_27QHDT,
120125
TABLETPC, /* add new TPC below */
121126
TABLETPCE,
122127
TABLETPC2FG,

include/uapi/linux/input.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ struct input_keymap_entry {
166166
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
167167
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
168168
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
169+
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
169170

170171
#define INPUT_PROP_MAX 0x1f
171172
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)

0 commit comments

Comments
 (0)