diff options
Diffstat (limited to 'drivers/input/tablet/wacom_wac.c')
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c3468c8dbd89..0a67031ffc13 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) return -1; } +static int int_dist(int x1, int y1, int x2, int y2) +{ + int x = x2 - x1; + int y = y2 - y1; + + return int_sqrt(x*x + y*y); +} + +static int wacom_24hdt_irq(struct wacom_wac *wacom) +{ + struct input_dev *input = wacom->input; + char *data = wacom->data; + int i; + int current_num_contacts = data[61]; + int contacts_to_send = 0; + + /* + * First packet resets the counter since only the first + * packet in series will have non-zero current_num_contacts. + */ + if (current_num_contacts) + wacom->num_contacts_left = current_num_contacts; + + /* There are at most 4 contacts per packet */ + contacts_to_send = min(4, wacom->num_contacts_left); + + for (i = 0; i < contacts_to_send; i++) { + int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; + bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; + int id = data[offset + 1]; + int slot = find_slot_from_contactid(wacom, id); + + if (slot < 0) + continue; + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); + + if (touch) { + int t_x = le16_to_cpup((__le16 *)&data[offset + 2]); + int c_x = le16_to_cpup((__le16 *)&data[offset + 4]); + int t_y = le16_to_cpup((__le16 *)&data[offset + 6]); + int c_y = le16_to_cpup((__le16 *)&data[offset + 8]); + int w = le16_to_cpup((__le16 *)&data[offset + 10]); + int h = le16_to_cpup((__le16 *)&data[offset + 12]); + + input_report_abs(input, ABS_MT_POSITION_X, t_x); + input_report_abs(input, ABS_MT_POSITION_Y, t_y); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); + input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); + input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); + input_report_abs(input, ABS_MT_ORIENTATION, w > h); + } + wacom->slots[slot] = touch ? id : -1; + } + + input_mt_report_pointer_emulation(input, true); + + wacom->num_contacts_left -= contacts_to_send; + if (wacom->num_contacts_left <= 0) + wacom->num_contacts_left = 0; + + return 1; +} + static int wacom_mt_touch(struct wacom_wac *wacom) { struct input_dev *input = wacom->input; @@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_intuos_irq(wacom_wac); break; + case WACOM_24HDT: + sync = wacom_24hdt_irq(wacom_wac); + break; + case INTUOS5S: case INTUOS5: case INTUOS5L: @@ -1340,7 +1408,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) /* these device have multiple inputs */ if (features->type >= WIRELESS || - (features->type >= INTUOS5S && features->type <= INTUOS5L)) + (features->type >= INTUOS5S && features->type <= INTUOS5L) || + (features->oVid && features->oPid)) features->quirks |= WACOM_QUIRK_MULTI_INPUT; /* quirk for bamboo touch with 2 low res touches */ @@ -1449,6 +1518,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); + + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + wacom_setup_cintiq(wacom_wac); break; @@ -1575,6 +1647,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); break; + case WACOM_24HDT: + if (features->device_type == BTN_TOOL_FINGER) { + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); + } + /* fall through */ + case MTSCREEN: if (features->device_type == BTN_TOOL_FINGER) { wacom_wac->slots = kmalloc(features->touch_max * @@ -1869,8 +1950,11 @@ static const struct wacom_features wacom_features_0xF4 = { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xF8 = - { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, - 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; + { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ + 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; +static const struct wacom_features wacom_features_0xF6 = + { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 }; static const struct wacom_features wacom_features_0x3F = { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; @@ -2113,6 +2197,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, { USB_DEVICE_WACOM(0xF8) }, + { USB_DEVICE_WACOM(0xF6) }, { USB_DEVICE_WACOM(0xFA) }, { USB_DEVICE_LENOVO(0x6004) }, { } |