diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a205055a4c517d..6fd6226ca854ea 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -28,6 +28,7 @@ #define HID_USAGE_Y_TILT 0x3e #define HID_USAGE_FINGER 0x22 #define HID_USAGE_STYLUS 0x20 +#define HID_USAGE_CREATE 0x80 #define HID_COLLECTION 0xc0 enum { @@ -246,6 +247,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->pktlen = WACOM_PKGLEN_GRAPHIRE; if (features->type == BAMBOO_PT) features->pktlen = WACOM_PKGLEN_BBFUN; + if (features->type == BAMBOO_PTC) + features->pktlen = WACOM_PKGLEN_INTUOS; features->device_type = BTN_TOOL_PEN; features->x_max = get_unaligned_le16(&report[i + 3]); @@ -296,6 +299,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->pktlen = WACOM_PKGLEN_GRAPHIRE; if (features->type == BAMBOO_PT) features->pktlen = WACOM_PKGLEN_BBFUN; + if (features->type == BAMBOO_PTC) + features->pktlen = WACOM_PKGLEN_INTUOS; features->device_type = BTN_TOOL_PEN; features->y_max = get_unaligned_le16(&report[i + 3]); @@ -304,6 +309,17 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi } break; + case HID_USAGE_CREATE: + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_BBCREATE; + features->device_type = BTN_TOOL_DOUBLETAP; + features->x_max = 255; + features->y_max = 255; + features->x_phy = features->x_max * 100; + features->y_phy = features->y_max * 100; + i += 15; + break; + case HID_USAGE_FINGER: finger = 1; i++; @@ -396,7 +412,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, /* only Tablet PCs and Bamboo P&T need to retrieve the info */ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && - (features->type != BAMBOO_PT)) + (features->type != BAMBOO_PT) && (features->type != BAMBOO_PTC)) goto out; if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c1c2f7b28d89ba..daa22dbb44e8bf 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -909,6 +909,81 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_bptc_touch(struct wacom_wac *wacom) +{ + struct input_dev *input = wacom->input; + unsigned char *data = wacom->data; + bool touch = (data[2] & 0x80) == 0; + + input_mt_report_pointer_emulation(input, true); + + input_mt_slot(input, 0); + if (wacom->shared->stylus_in_proximity) + { + input_mt_report_slot_state(input, MT_TOOL_FINGER, 0); + } + else + { + if (touch) { + int x = data[4]; + int y = data[5]; + input_mt_report_slot_state(input, MT_TOOL_FINGER, + data[3] & 0x80); + input_report_abs(input, ABS_MT_POSITION_X, x); + input_report_abs(input, ABS_MT_POSITION_Y, y); + } + } + + if ((data[2] | 0x80) == 0x80) + { + input_report_key(input, BTN_BACK, (data[3] & 0x08) != 0); + input_report_key(input, BTN_FORWARD, (data[3] & 0x04) != 0); + input_report_key(input, BTN_RIGHT, (data[3] & 0x02) != 0); + input_report_key(input, BTN_LEFT, (data[3] & 0x01) != 0); + } + + return 1; +} + +static int wacom_bptc_pen(struct wacom_wac *wacom) +{ + char *data = wacom->data; + struct input_dev *input = wacom->input; + int pressure; + bool prox = data[1] & 0x20; + + if (!wacom->shared->stylus_in_proximity) /* first in prox */ + /* Going into proximity select tool */ + wacom->tool[0] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; + + /* keep pen state for touch events */ + wacom->shared->stylus_in_proximity = prox; + + /* send pen events only when touch is up or forced out */ + if (!wacom->shared->touch_down) { + input_report_key(input, BTN_STYLUS, data[1] & 0x02); + input_report_key(input, BTN_STYLUS2, data[1] & 0x04); + input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); + input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); + input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); + input_report_key(input, BTN_TOUCH, data[1] & 0x01); + input_report_key(input, wacom->tool[0], prox); + return 1; + } + + return 0; +} + +static int wacom_bptc_irq(struct wacom_wac *wacom, size_t len) +{ + if (len == WACOM_PKGLEN_BBCREATE) + return wacom_bptc_touch(wacom); + else if (len == WACOM_PKGLEN_INTUOS) + return wacom_bptc_pen(wacom); + + return 0; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -958,6 +1033,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_bpt_irq(wacom_wac, len); break; + case BAMBOO_PTC: + sync = wacom_bptc_irq(wacom_wac, len); + break; + default: sync = false; break; @@ -1019,7 +1098,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) /* these device have multiple inputs */ if (features->type == TABLETPC || features->type == TABLETPC2FG || - features->type == BAMBOO_PT) + features->type == BAMBOO_PT || features->type == BAMBOO_PTC) features->quirks |= WACOM_QUIRK_MULTI_INPUT; /* quirks for bamboo touch */ @@ -1201,6 +1280,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, break; case BAMBOO_PT: + case BAMBOO_PTC: __clear_bit(ABS_MISC, input_dev->absbit); if (features->device_type == BTN_TOOL_DOUBLETAP) { @@ -1478,6 +1558,9 @@ static const struct wacom_features wacom_features_0xDA = static struct wacom_features wacom_features_0xDB = { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xDF = + { "Wacom Bamboo Create", WACOM_PKGLEN_INTUOS, 21648, 13530, 1023, + 63, BAMBOO_PTC, WACOM_INTUOS_RES, WACOM_INTUOS_RES, }; static const struct wacom_features wacom_features_0x6004 = { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -1573,6 +1656,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xD8) }, { USB_DEVICE_WACOM(0xDA) }, { USB_DEVICE_WACOM(0xDB) }, + { USB_DEVICE_WACOM(0xDF) }, { USB_DEVICE_WACOM(0xF0) }, { USB_DEVICE_WACOM(0xCC) }, { USB_DEVICE_WACOM(0x90) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 53eb71b6833099..3253572fa80ebb 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -22,6 +22,7 @@ #define WACOM_PKGLEN_TPC1FG 5 #define WACOM_PKGLEN_TPC2FG 14 #define WACOM_PKGLEN_BBTOUCH 20 +#define WACOM_PKGLEN_BBCREATE 64 /* device IDs */ #define STYLUS_DEVICE_ID 0x02 @@ -50,6 +51,7 @@ enum { PL, DTU, BAMBOO_PT, + BAMBOO_PTC, INTUOS, INTUOS3S, INTUOS3,