Skip to content

Commit

Permalink
Input: wacom - add touch sensor support for Cintiq 24HD touch
Browse files Browse the repository at this point in the history
Decode multitouch reports from the touch sensor of the Cintiq 24HD
touch.

Signed-off-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Jason Gerecke authored and Linus Torvalds committed Oct 25, 2012
1 parent aea2bf6 commit b1e4279
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
19 changes: 18 additions & 1 deletion drivers/input/tablet/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->pktlen = WACOM_PKGLEN_TPC2FG;
}

if (features->type == MTSCREEN)
if (features->type == MTSCREEN || WACOM_24HDT)
features->pktlen = WACOM_PKGLEN_MTOUCH;

if (features->type == BAMBOO_PT) {
Expand All @@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->x_max =
get_unaligned_le16(&report[i + 8]);
i += 15;
} else if (features->type == WACOM_24HDT) {
features->x_max =
get_unaligned_le16(&report[i + 3]);
features->x_phy =
get_unaligned_le16(&report[i + 8]);
features->unit = report[i - 1];
features->unitExpo = report[i - 3];
i += 12;
} else {
features->x_max =
get_unaligned_le16(&report[i + 3]);
Expand Down Expand Up @@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
} else if (type == WACOM_24HDT) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i - 2]);
i += 7;
} else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
Expand Down Expand Up @@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
/* MT Tablet PC touch */
return wacom_set_device_mode(intf, 3, 4, 4);
}
else if (features->type == WACOM_24HDT) {
return wacom_set_device_mode(intf, 18, 3, 2);
}
} else if (features->device_type == BTN_TOOL_PEN) {
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
return wacom_set_device_mode(intf, 2, 2, 2);
Expand Down
85 changes: 83 additions & 2 deletions drivers/input/tablet/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -1576,6 +1644,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 *
Expand Down Expand Up @@ -1870,8 +1947,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 };
Expand Down Expand Up @@ -2114,6 +2194,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) },
{ }
Expand Down
3 changes: 3 additions & 0 deletions drivers/input/tablet/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

/* wacom data size per MT contact */
#define WACOM_BYTES_PER_MT_PACKET 11
#define WACOM_BYTES_PER_24HDT_PACKET 14

/* device IDs */
#define STYLUS_DEVICE_ID 0x02
Expand All @@ -49,6 +50,7 @@
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
#define WACOM_REPORT_TPC1FGE 18
#define WACOM_REPORT_24HDT 1

/* device quirks */
#define WACOM_QUIRK_MULTI_INPUT 0x0001
Expand Down Expand Up @@ -81,6 +83,7 @@ enum {
WACOM_MO,
WIRELESS,
BAMBOO_PT,
WACOM_24HDT,
TABLETPC, /* add new TPC below */
TABLETPCE,
TABLETPC2FG,
Expand Down

0 comments on commit b1e4279

Please sign in to comment.