Input: wacom - add touch sensor support for Cintiq 24HD touch
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>
This commit is contained in:
parent
aea2bf6a57
commit
b1e4279e4e
3 changed files with 104 additions and 3 deletions
|
@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
features->pktlen = WACOM_PKGLEN_TPC2FG;
|
features->pktlen = WACOM_PKGLEN_TPC2FG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features->type == MTSCREEN)
|
if (features->type == MTSCREEN || WACOM_24HDT)
|
||||||
features->pktlen = WACOM_PKGLEN_MTOUCH;
|
features->pktlen = WACOM_PKGLEN_MTOUCH;
|
||||||
|
|
||||||
if (features->type == BAMBOO_PT) {
|
if (features->type == BAMBOO_PT) {
|
||||||
|
@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
features->x_max =
|
features->x_max =
|
||||||
get_unaligned_le16(&report[i + 8]);
|
get_unaligned_le16(&report[i + 8]);
|
||||||
i += 15;
|
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 {
|
} else {
|
||||||
features->x_max =
|
features->x_max =
|
||||||
get_unaligned_le16(&report[i + 3]);
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
features->y_phy =
|
features->y_phy =
|
||||||
get_unaligned_le16(&report[i + 6]);
|
get_unaligned_le16(&report[i + 6]);
|
||||||
i += 7;
|
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) {
|
} else if (type == BAMBOO_PT) {
|
||||||
features->y_phy =
|
features->y_phy =
|
||||||
get_unaligned_le16(&report[i + 3]);
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
|
||||||
/* MT Tablet PC touch */
|
/* MT Tablet PC touch */
|
||||||
return wacom_set_device_mode(intf, 3, 4, 4);
|
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) {
|
} else if (features->device_type == BTN_TOOL_PEN) {
|
||||||
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
|
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
|
||||||
return wacom_set_device_mode(intf, 2, 2, 2);
|
return wacom_set_device_mode(intf, 2, 2, 2);
|
||||||
|
|
|
@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
|
||||||
return -1;
|
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)
|
static int wacom_mt_touch(struct wacom_wac *wacom)
|
||||||
{
|
{
|
||||||
struct input_dev *input = wacom->input;
|
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);
|
sync = wacom_intuos_irq(wacom_wac);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WACOM_24HDT:
|
||||||
|
sync = wacom_24hdt_irq(wacom_wac);
|
||||||
|
break;
|
||||||
|
|
||||||
case INTUOS5S:
|
case INTUOS5S:
|
||||||
case INTUOS5:
|
case INTUOS5:
|
||||||
case INTUOS5L:
|
case INTUOS5L:
|
||||||
|
@ -1576,6 +1644,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
|
||||||
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
||||||
break;
|
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:
|
case MTSCREEN:
|
||||||
if (features->device_type == BTN_TOOL_FINGER) {
|
if (features->device_type == BTN_TOOL_FINGER) {
|
||||||
wacom_wac->slots = kmalloc(features->touch_max *
|
wacom_wac->slots = kmalloc(features->touch_max *
|
||||||
|
@ -1870,8 +1947,11 @@ static const struct wacom_features wacom_features_0xF4 =
|
||||||
{ "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
|
{ "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
|
||||||
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
||||||
static const struct wacom_features wacom_features_0xF8 =
|
static const struct wacom_features wacom_features_0xF8 =
|
||||||
{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
|
{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */
|
||||||
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
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 =
|
static const struct wacom_features wacom_features_0x3F =
|
||||||
{ "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023,
|
{ "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023,
|
||||||
63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
||||||
|
@ -2114,6 +2194,7 @@ const struct usb_device_id wacom_ids[] = {
|
||||||
{ USB_DEVICE_WACOM(0x47) },
|
{ USB_DEVICE_WACOM(0x47) },
|
||||||
{ USB_DEVICE_WACOM(0xF4) },
|
{ USB_DEVICE_WACOM(0xF4) },
|
||||||
{ USB_DEVICE_WACOM(0xF8) },
|
{ USB_DEVICE_WACOM(0xF8) },
|
||||||
|
{ USB_DEVICE_WACOM(0xF6) },
|
||||||
{ USB_DEVICE_WACOM(0xFA) },
|
{ USB_DEVICE_WACOM(0xFA) },
|
||||||
{ USB_DEVICE_LENOVO(0x6004) },
|
{ USB_DEVICE_LENOVO(0x6004) },
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
/* wacom data size per MT contact */
|
/* wacom data size per MT contact */
|
||||||
#define WACOM_BYTES_PER_MT_PACKET 11
|
#define WACOM_BYTES_PER_MT_PACKET 11
|
||||||
|
#define WACOM_BYTES_PER_24HDT_PACKET 14
|
||||||
|
|
||||||
/* device IDs */
|
/* device IDs */
|
||||||
#define STYLUS_DEVICE_ID 0x02
|
#define STYLUS_DEVICE_ID 0x02
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#define WACOM_REPORT_TPCHID 15
|
#define WACOM_REPORT_TPCHID 15
|
||||||
#define WACOM_REPORT_TPCST 16
|
#define WACOM_REPORT_TPCST 16
|
||||||
#define WACOM_REPORT_TPC1FGE 18
|
#define WACOM_REPORT_TPC1FGE 18
|
||||||
|
#define WACOM_REPORT_24HDT 1
|
||||||
|
|
||||||
/* device quirks */
|
/* device quirks */
|
||||||
#define WACOM_QUIRK_MULTI_INPUT 0x0001
|
#define WACOM_QUIRK_MULTI_INPUT 0x0001
|
||||||
|
@ -81,6 +83,7 @@ enum {
|
||||||
WACOM_MO,
|
WACOM_MO,
|
||||||
WIRELESS,
|
WIRELESS,
|
||||||
BAMBOO_PT,
|
BAMBOO_PT,
|
||||||
|
WACOM_24HDT,
|
||||||
TABLETPC, /* add new TPC below */
|
TABLETPC, /* add new TPC below */
|
||||||
TABLETPCE,
|
TABLETPCE,
|
||||||
TABLETPC2FG,
|
TABLETPC2FG,
|
||||||
|
|
Loading…
Reference in a new issue