Commit eda01dab authored by Ping Cheng's avatar Ping Cheng Committed by Jiri Kosina

HID: wacom: Add four new Intuos devices

This series of devices supports both pen and touch. It reports
touch data in Bamboo3 format and pen data in Intuos pro format.
Signed-off-by: default avatarPing Cheng <pingc@wacom.com>
Tested-By: default avatarAaron Skomra <aaron.skomra@wacom.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 3b164a00
...@@ -1569,7 +1569,8 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -1569,7 +1569,8 @@ static void wacom_wireless_work(struct work_struct *work)
/* Touch interface */ /* Touch interface */
if (wacom_wac1->features.touch_max || if (wacom_wac1->features.touch_max ||
wacom_wac1->features.type == INTUOSHT) { (wacom_wac1->features.type >= INTUOSHT &&
wacom_wac1->features.type <= BAMBOO_PT)) {
wacom_wac2->features = wacom_wac2->features =
*((struct wacom_features *)id->driver_data); *((struct wacom_features *)id->driver_data);
wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
...@@ -1592,7 +1593,8 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -1592,7 +1593,8 @@ static void wacom_wireless_work(struct work_struct *work)
if (error) if (error)
goto fail; goto fail;
if (wacom_wac1->features.type == INTUOSHT && if ((wacom_wac1->features.type == INTUOSHT ||
wacom_wac1->features.type == INTUOSHT2) &&
wacom_wac1->features.touch_max) wacom_wac1->features.touch_max)
wacom_wac->shared->touch_input = wacom_wac2->touch_input; wacom_wac->shared->touch_input = wacom_wac2->touch_input;
} }
...@@ -1834,8 +1836,9 @@ static int wacom_probe(struct hid_device *hdev, ...@@ -1834,8 +1836,9 @@ static int wacom_probe(struct hid_device *hdev,
if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
error = hid_hw_open(hdev); error = hid_hw_open(hdev);
if (wacom_wac->features.type == INTUOSHT && if ((wacom_wac->features.type == INTUOSHT ||
wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { wacom_wac->features.type == INTUOSHT2) &&
(wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)) {
wacom_wac->shared->touch_input = wacom_wac->touch_input; wacom_wac->shared->touch_input = wacom_wac->touch_input;
} }
......
...@@ -769,9 +769,11 @@ static void wacom_intuos_general(struct wacom_wac *wacom) ...@@ -769,9 +769,11 @@ static void wacom_intuos_general(struct wacom_wac *wacom)
t = (t << 1) | (data[1] & 1); t = (t << 1) | (data[1] & 1);
} }
input_report_abs(input, ABS_PRESSURE, t); input_report_abs(input, ABS_PRESSURE, t);
input_report_abs(input, ABS_TILT_X, if (features->type != INTUOSHT2) {
input_report_abs(input, ABS_TILT_X,
(((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
}
input_report_key(input, BTN_STYLUS, data[1] & 2); input_report_key(input, BTN_STYLUS, data[1] & 2);
input_report_key(input, BTN_STYLUS2, data[1] & 4); input_report_key(input, BTN_STYLUS2, data[1] & 4);
input_report_key(input, BTN_TOUCH, t > 10); input_report_key(input, BTN_TOUCH, t > 10);
...@@ -799,6 +801,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) ...@@ -799,6 +801,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
data[0] != WACOM_REPORT_INTUOSREAD && data[0] != WACOM_REPORT_INTUOSREAD &&
data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSWRITE &&
data[0] != WACOM_REPORT_INTUOSPAD && data[0] != WACOM_REPORT_INTUOSPAD &&
data[0] != WACOM_REPORT_INTUOS_PEN &&
data[0] != WACOM_REPORT_CINTIQ && data[0] != WACOM_REPORT_CINTIQ &&
data[0] != WACOM_REPORT_CINTIQPAD && data[0] != WACOM_REPORT_CINTIQPAD &&
data[0] != WACOM_REPORT_INTUOS5PAD) { data[0] != WACOM_REPORT_INTUOS5PAD) {
...@@ -1896,7 +1899,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) ...@@ -1896,7 +1899,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
int y = (data[3] << 4) | (data[4] & 0x0f); int y = (data[3] << 4) | (data[4] & 0x0f);
int width, height; int width, height;
if (features->type >= INTUOSPS && features->type <= INTUOSHT) { if (features->type >= INTUOSPS && features->type <= INTUOSHT2) {
width = data[5] * 100; width = data[5] * 100;
height = data[6] * 100; height = data[6] * 100;
} else { } else {
...@@ -1924,7 +1927,7 @@ static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) ...@@ -1924,7 +1927,7 @@ static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
struct input_dev *input = wacom->pad_input; struct input_dev *input = wacom->pad_input;
struct wacom_features *features = &wacom->features; struct wacom_features *features = &wacom->features;
if (features->type == INTUOSHT) { if (features->type == INTUOSHT || features->type == INTUOSHT2) {
input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0); input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0); input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
} else { } else {
...@@ -1939,7 +1942,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) ...@@ -1939,7 +1942,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
{ {
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
int count = data[1] & 0x07; int count = data[1] & 0x07;
int i; int touch_changed = 0, i;
if (data[0] != 0x02) if (data[0] != 0x02)
return 0; return 0;
...@@ -1949,15 +1952,16 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) ...@@ -1949,15 +1952,16 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
int offset = (8 * i) + 2; int offset = (8 * i) + 2;
int msg_id = data[offset]; int msg_id = data[offset];
if (msg_id >= 2 && msg_id <= 17) if (msg_id >= 2 && msg_id <= 17) {
wacom_bpt3_touch_msg(wacom, data + offset); wacom_bpt3_touch_msg(wacom, data + offset);
else if (msg_id == 128) touch_changed++;
} else if (msg_id == 128)
wacom_bpt3_button_msg(wacom, data + offset); wacom_bpt3_button_msg(wacom, data + offset);
} }
/* only update the touch if we actually have a touchpad */ /* only update touch if we actually have a touchpad and touch data changed */
if (wacom->touch_registered) { if (wacom->touch_registered && touch_changed) {
input_mt_sync_frame(wacom->touch_input); input_mt_sync_frame(wacom->touch_input);
wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
} }
...@@ -2038,7 +2042,13 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) ...@@ -2038,7 +2042,13 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
{ {
if (len == WACOM_PKGLEN_BBTOUCH) struct wacom_features *features = &wacom->features;
if ((features->type == INTUOSHT2) &&
(wacom->data[0] == WACOM_REPORT_INTUOS_PEN) &&
(features->device_type & WACOM_DEVICETYPE_PEN))
return wacom_intuos_irq(wacom);
else if (len == WACOM_PKGLEN_BBTOUCH)
return wacom_bpt_touch(wacom); return wacom_bpt_touch(wacom);
else if (len == WACOM_PKGLEN_BBTOUCH3) else if (len == WACOM_PKGLEN_BBTOUCH3)
return wacom_bpt3_touch(wacom); return wacom_bpt3_touch(wacom);
...@@ -2145,7 +2155,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) ...@@ -2145,7 +2155,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
if (connected) { if (connected) {
int pid, battery, charging; int pid, battery, charging;
if ((wacom->shared->type == INTUOSHT) && if ((wacom->shared->type == INTUOSHT ||
wacom->shared->type == INTUOSHT2) &&
wacom->shared->touch_input && wacom->shared->touch_input &&
wacom->shared->touch_max) { wacom->shared->touch_max) {
input_report_switch(wacom->shared->touch_input, input_report_switch(wacom->shared->touch_input,
...@@ -2183,7 +2194,8 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -2183,7 +2194,8 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
if (data[0] != WACOM_REPORT_USB) if (data[0] != WACOM_REPORT_USB)
return 0; return 0;
if (features->type == INTUOSHT && if ((features->type == INTUOSHT ||
features->type == INTUOSHT2) &&
wacom_wac->shared->touch_input && wacom_wac->shared->touch_input &&
features->touch_max) { features->touch_max) {
input_report_switch(wacom_wac->shared->touch_input, input_report_switch(wacom_wac->shared->touch_input,
...@@ -2303,6 +2315,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -2303,6 +2315,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case BAMBOO_PEN: case BAMBOO_PEN:
case BAMBOO_TOUCH: case BAMBOO_TOUCH:
case INTUOSHT: case INTUOSHT:
case INTUOSHT2:
if (wacom_wac->data[0] == WACOM_REPORT_USB) if (wacom_wac->data[0] == WACOM_REPORT_USB)
sync = wacom_status_irq(wacom_wac, len); sync = wacom_status_irq(wacom_wac, len);
else else
...@@ -2339,22 +2352,31 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -2339,22 +2352,31 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
} }
} }
static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) static void wacom_setup_basic_pro_pen(struct wacom_wac *wacom_wac)
{ {
struct input_dev *input_dev = wacom_wac->pen_input; struct input_dev *input_dev = wacom_wac->pen_input;
input_set_capability(input_dev, EV_MSC, MSC_SERIAL); input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit);
__set_bit(BTN_TOOL_BRUSH, input_dev->keybit);
__set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
__set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
__set_bit(BTN_STYLUS, input_dev->keybit); __set_bit(BTN_STYLUS, input_dev->keybit);
__set_bit(BTN_STYLUS2, input_dev->keybit); __set_bit(BTN_STYLUS2, input_dev->keybit);
input_set_abs_params(input_dev, ABS_DISTANCE, input_set_abs_params(input_dev, ABS_DISTANCE,
0, wacom_wac->features.distance_max, 0, 0); 0, wacom_wac->features.distance_max, 0, 0);
}
static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
{
struct input_dev *input_dev = wacom_wac->pen_input;
wacom_setup_basic_pro_pen(wacom_wac);
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_BRUSH, input_dev->keybit);
__set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
__set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0);
input_abs_set_res(input_dev, ABS_TILT_X, 57); input_abs_set_res(input_dev, ABS_TILT_X, 57);
...@@ -2600,16 +2622,21 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, ...@@ -2600,16 +2622,21 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
case INTUOSHT: case INTUOSHT:
case BAMBOO_PT: case BAMBOO_PT:
case BAMBOO_PEN: case BAMBOO_PEN:
__clear_bit(ABS_MISC, input_dev->absbit); case INTUOSHT2:
__set_bit(INPUT_PROP_POINTER, input_dev->propbit); __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit); if (features->type == INTUOSHT2) {
__set_bit(BTN_STYLUS, input_dev->keybit); wacom_setup_basic_pro_pen(wacom_wac);
__set_bit(BTN_STYLUS2, input_dev->keybit); } else {
input_set_abs_params(input_dev, ABS_DISTANCE, 0, __clear_bit(ABS_MISC, input_dev->absbit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_STYLUS, input_dev->keybit);
__set_bit(BTN_STYLUS2, input_dev->keybit);
input_set_abs_params(input_dev, ABS_DISTANCE, 0,
features->distance_max, features->distance_max,
0, 0); 0, 0);
}
break; break;
case BAMBOO_PAD: case BAMBOO_PAD:
__clear_bit(ABS_MISC, input_dev->absbit); __clear_bit(ABS_MISC, input_dev->absbit);
...@@ -2690,6 +2717,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, ...@@ -2690,6 +2717,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
break; break;
case INTUOSHT: case INTUOSHT:
case INTUOSHT2:
input_dev->evbit[0] |= BIT_MASK(EV_SW); input_dev->evbit[0] |= BIT_MASK(EV_SW);
__set_bit(SW_MUTE_DEVICE, input_dev->swbit); __set_bit(SW_MUTE_DEVICE, input_dev->swbit);
/* fall through */ /* fall through */
...@@ -2849,6 +2877,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, ...@@ -2849,6 +2877,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
case INTUOSHT: case INTUOSHT:
case BAMBOO_PT: case BAMBOO_PT:
case BAMBOO_TOUCH: case BAMBOO_TOUCH:
case INTUOSHT2:
__clear_bit(ABS_MISC, input_dev->absbit); __clear_bit(ABS_MISC, input_dev->absbit);
__set_bit(BTN_LEFT, input_dev->keybit); __set_bit(BTN_LEFT, input_dev->keybit);
...@@ -3335,6 +3364,22 @@ static const struct wacom_features wacom_features_0x331 = ...@@ -3335,6 +3364,22 @@ static const struct wacom_features wacom_features_0x331 =
{ "Wacom Express Key Remote", .type = REMOTE, { "Wacom Express Key Remote", .type = REMOTE,
.numbered_buttons = 18, .check_for_hid_type = true, .numbered_buttons = 18, .check_for_hid_type = true,
.hid_type = HID_TYPE_USBNONE }; .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x33B =
{ "Wacom Intuos S 2", 15200, 9500, 2047, 63,
INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x33C =
{ "Wacom Intuos PT S 2", 15200, 9500, 2047, 63,
INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x33D =
{ "Wacom Intuos P M 2", 21600, 13500, 2047, 63,
INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x33E =
{ "Wacom Intuos PT M 2", 21600, 13500, 2047, 63,
INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_HID_ANY_ID = static const struct wacom_features wacom_features_HID_ANY_ID =
{ "Wacom HID", .type = HID_GENERIC }; { "Wacom HID", .type = HID_GENERIC };
...@@ -3494,6 +3539,10 @@ const struct hid_device_id wacom_ids[] = { ...@@ -3494,6 +3539,10 @@ const struct hid_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x333) }, { USB_DEVICE_WACOM(0x333) },
{ USB_DEVICE_WACOM(0x335) }, { USB_DEVICE_WACOM(0x335) },
{ USB_DEVICE_WACOM(0x336) }, { USB_DEVICE_WACOM(0x336) },
{ USB_DEVICE_WACOM(0x33B) },
{ USB_DEVICE_WACOM(0x33C) },
{ USB_DEVICE_WACOM(0x33D) },
{ USB_DEVICE_WACOM(0x33E) },
{ USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4001) },
{ USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x4004) },
{ USB_DEVICE_WACOM(0x5000) }, { USB_DEVICE_WACOM(0x5000) },
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
#define WACOM_REPORT_BPAD_PEN 3 #define WACOM_REPORT_BPAD_PEN 3
#define WACOM_REPORT_BPAD_TOUCH 16 #define WACOM_REPORT_BPAD_TOUCH 16
#define WACOM_REPORT_DEVICE_LIST 16 #define WACOM_REPORT_DEVICE_LIST 16
#define WACOM_REPORT_INTUOS_PEN 16
#define WACOM_REPORT_REMOTE 17 #define WACOM_REPORT_REMOTE 17
/* device quirks */ /* device quirks */
...@@ -130,6 +131,7 @@ enum { ...@@ -130,6 +131,7 @@ enum {
WIRELESS, WIRELESS,
BAMBOO_PEN, BAMBOO_PEN,
INTUOSHT, INTUOSHT,
INTUOSHT2,
BAMBOO_TOUCH, BAMBOO_TOUCH,
BAMBOO_PT, BAMBOO_PT,
WACOM_24HDT, WACOM_24HDT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment