* [PATCH 1/2] input : wacom - retrieve maximum number of touch points
@ 2012-02-01 4:03 chris
2012-02-01 4:03 ` [PATCH 2/2] input: wacom - add 0xE5 (MT device) support chris
2012-02-01 11:53 ` [PATCH 1/2] input : wacom - retrieve maximum number of touch points Maurus Cuelenaere
0 siblings, 2 replies; 7+ messages in thread
From: chris @ 2012-02-01 4:03 UTC (permalink / raw)
To: dmitry.torokhov, linux-input; +Cc: Ping Cheng, Chris Bagwell, Ping Cheng
From: Ping Cheng <pinglinux@gmail.com>
>From the HID usage table when it is supported.
Tested-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
These two patches were originally in a set of 4 from Ping.
2 of those 4 have already been committed to next branch.
The change between this version and Ping's last version is
making use of features to set the new touch_max value.
The 2nd patch is unmodified.
drivers/input/tablet/wacom_sys.c | 26 +++++++++++++++++-
drivers/input/tablet/wacom_wac.c | 55 +++++++++++++++++++++++--------------
drivers/input/tablet/wacom_wac.h | 1 +
3 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index c9588ee..5004a75 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_CONTACTMAX 0x55
#define HID_COLLECTION 0xa1
#define HID_COLLECTION_LOGICAL 0x02
#define HID_COLLECTION_END 0xc0
@@ -196,6 +197,24 @@ static int wacom_parse_logical_collection(unsigned char *report,
return length;
}
+static void wacom_retrieve_report_data(struct usb_interface *intf,
+ struct wacom_features *features)
+{
+ int result = 0;
+ unsigned char *rep_data;
+
+ rep_data = kmalloc(2, GFP_KERNEL);
+ if (!rep_data)
+ return;
+
+ rep_data[0] = 12;
+ result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
+ rep_data[0], rep_data, 2, WAC_MSG_RETRIES);
+
+ if ((result >= 0) && (rep_data[1] > 2))
+ features->touch_max = rep_data[1];
+}
+
/*
* Interface Descriptor of wacom devices can be incomplete and
* inconsistent so wacom_features table is used to store stylus
@@ -369,6 +388,11 @@ static int wacom_parse_hid(struct usb_interface *intf,
pen = 1;
i++;
break;
+
+ case HID_USAGE_CONTACTMAX:
+ wacom_retrieve_report_data(intf, features);
+ i++;
+ break;
}
break;
@@ -873,7 +897,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- /* Retrieve the physical and logical size for OEM devices */
+ /* Retrieve the physical and logical size for touch devices */
error = wacom_retrieve_hid_descriptor(intf, features);
if (error)
goto fail3;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 9283507..c56d577 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -830,7 +830,8 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
{
char *data = wacom->data;
- dbg("wacom_tpc_irq: received report #%d", data[0]);
+ dbg("wacom_tpc_irq: received report #%d with %d contacts",
+ data[0], wacom->features.touch_max);
switch (len) {
case WACOM_PKGLEN_TPC1FG:
@@ -1331,7 +1332,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
case TABLETPC2FG:
if (features->device_type == BTN_TOOL_FINGER) {
- input_mt_init_slots(input_dev, 2);
+ input_mt_init_slots(input_dev, features->touch_max);
input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
0, MT_TOOL_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
@@ -1386,6 +1387,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ input_mt_init_slots(input_dev, features->touch_max);
if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
__set_bit(BTN_TOOL_TRIPLETAP,
@@ -1393,13 +1395,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_QUADTAP,
input_dev->keybit);
- input_mt_init_slots(input_dev, 16);
-
input_set_abs_params(input_dev,
ABS_MT_TOUCH_MAJOR,
0, 255, 0, 0);
- } else {
- input_mt_init_slots(input_dev, 2);
}
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
@@ -1615,40 +1613,48 @@ static const struct wacom_features wacom_features_0x90 =
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x93 =
{ "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
- 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 1 };
static const struct wacom_features wacom_features_0x97 =
{ "Wacom ISDv4 97", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 511,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x9A =
{ "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
- 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 1 };
static const struct wacom_features wacom_features_0x9F =
{ "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE2 =
{ "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0x47 =
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023,
31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD0 =
{ "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD1 =
{ "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD2 =
{ "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD3 =
{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD4 =
{ "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1657,28 +1663,35 @@ static const struct wacom_features wacom_features_0xD5 =
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD6 =
{ "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD7 =
{ "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD8 =
{ "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xDA =
{ "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static struct wacom_features wacom_features_0xDB =
{ "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xDD =
{ "Wacom Bamboo Connect", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xDE =
{ "Wacom Bamboo 16FG 4x5", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 16 };
static const struct wacom_features wacom_features_0xDF =
{ "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 16 };
static const struct wacom_features wacom_features_0x6004 =
{ "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 4f0ba21..1c9dc3e 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -91,6 +91,7 @@ struct wacom_features {
int pressure_fuzz;
int distance_fuzz;
unsigned quirks;
+ unsigned touch_max;
};
struct wacom_shared {
--
1.7.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] input: wacom - add 0xE5 (MT device) support
2012-02-01 4:03 [PATCH 1/2] input : wacom - retrieve maximum number of touch points chris
@ 2012-02-01 4:03 ` chris
2012-02-01 11:53 ` [PATCH 1/2] input : wacom - retrieve maximum number of touch points Maurus Cuelenaere
1 sibling, 0 replies; 7+ messages in thread
From: chris @ 2012-02-01 4:03 UTC (permalink / raw)
To: dmitry.torokhov, linux-input; +Cc: Ping Cheng, Ping Cheng
From: Ping Cheng <pinglinux@gmail.com>
And getting rid of duplicate code since X/Y will always be present.
Tested-by: Chris Bagwell <chris@cnpbagwell.com>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom_sys.c | 57 ++++++++++++------------
drivers/input/tablet/wacom_wac.c | 88 ++++++++++++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.h | 8 +++
3 files changed, 122 insertions(+), 31 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 5004a75..dc00386 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -306,6 +306,10 @@ static int wacom_parse_hid(struct usb_interface *intf,
/* need to reset back */
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
+
+ if (features->type == MTSCREEN)
+ features->pktlen = WACOM_PKGLEN_MTOUCH;
+
if (features->type == BAMBOO_PT) {
/* need to reset back */
features->pktlen = WACOM_PKGLEN_BBTOUCH;
@@ -338,18 +342,15 @@ static int wacom_parse_hid(struct usb_interface *intf,
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->device_type = BTN_TOOL_FINGER;
- if (features->type == TABLETPC2FG) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_TPC2FG;
+ int type = features->type;
+
+ if (type == TABLETPC2FG || type == MTSCREEN) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
- } else if (features->type == BAMBOO_PT) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ } else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
features->y_max =
@@ -363,10 +364,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
i += 4;
}
} else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- features->device_type = BTN_TOOL_PEN;
features->y_max =
get_unaligned_le16(&report[i + 3]);
i += 4;
@@ -429,24 +426,28 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
if (!rep_data)
return error;
- /* ask to report tablet data if it is MT Tablet PC or
- * not a Tablet PC */
- if (features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- rep_data[2] = 0;
- rep_data[3] = 0;
- report_id = 3;
- error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
+ /* ask to report Wacom data */
+ if (features->device_type == BTN_TOOL_FINGER) {
+ /* if it is an MT Tablet PC touch */
+ if ((features->type == TABLETPC2FG) ||
+ (features->type == MTSCREEN)) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ rep_data[2] = 0;
+ rep_data[3] = 0;
+ report_id = 3;
+ error = wacom_set_report(intf,
+ WAC_HID_FEATURE_REPORT,
report_id, rep_data, 4, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
+ if (error >= 0)
+ error = wacom_get_report(intf,
WAC_HID_FEATURE_REPORT,
report_id, rep_data, 4, 1);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
- } else if (features->type != TABLETPC &&
- features->device_type == BTN_TOOL_PEN) {
+ } while ((error < 0 || rep_data[1] != 4) &&
+ limit++ < WAC_MSG_RETRIES);
+ }
+ } else if (features->type != TABLETPC) { /* or not a Tablet PC pen */
do {
rep_data[0] = 2;
rep_data[1] = 2;
@@ -478,9 +479,9 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
features->pressure_fuzz = 0;
features->distance_fuzz = 0;
- /* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ /* only devices that support touch need to retrieve the info */
if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
- (features->type != BAMBOO_PT))
+ (features->type != BAMBOO_PT) && (features->type != MTSCREEN))
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 c56d577..a7d37de 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -729,6 +729,75 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
return 1;
}
+static int wacom_mt_touch(struct wacom_wac *wacom)
+{
+ struct wacom_features *features = &wacom->features;
+ struct input_dev *input = wacom->input;
+ char *data = wacom->data;
+ struct input_mt_slot *mt;
+ int i, id = -1, j = 0, k = 4;
+ int x = 0, y = 0;
+ int current_num_contacts = data[2];
+ int contacts_to_send = 0;
+ bool touch = false;
+
+ /* reset the counter by the first packet since only the first
+ * packet in series will have non-zero current_num_contacts
+ */
+ if (current_num_contacts) {
+ features->num_contacts = current_num_contacts;
+ features->num_contacts_left = current_num_contacts;
+ }
+
+ /* There are at most 5 contacts per packet */
+ contacts_to_send = min(5, (int)features->num_contacts_left);
+
+ for (i = 0; i < contacts_to_send; i++) {
+ id = le16_to_cpup((__le16 *)&data[k]);
+
+ /* is there an existing slot for this contact? */
+ for (j = 0; j < features->touch_max; j++) {
+ mt = &input->mt[j];
+ if (input_mt_get_value(mt, ABS_MT_TRACKING_ID) == id )
+ break;
+ }
+
+ /* no. then find an unused slot to fill */
+ if (j >= features->touch_max) {
+ for (j = 0; j < features->touch_max; j++) {
+ mt = &input->mt[j];
+ if (input_mt_get_value(mt, ABS_MT_TRACKING_ID) == -1 )
+ break;
+ }
+ }
+
+ touch = data[k - 1] & 0x1;
+ input_mt_slot(input, j);
+ if (touch) {
+ x = le16_to_cpup((__le16 *)&data[k + 6]);
+ y = le16_to_cpup((__le16 *)&data[k + 8]);
+
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ } else
+ id = -1;
+
+ /* keep the id from firmware since we need
+ * it to process future events
+ */
+ input_report_abs(input, ABS_MT_TRACKING_ID, id);
+
+ k += WACOM_BYTES_PER_MT_PACKET;
+ }
+
+ input_mt_report_pointer_emulation(input, true);
+
+ features->num_contacts_left -= contacts_to_send;
+ if (features->num_contacts_left < 0)
+ features->num_contacts_left = 0;
+ return 1;
+}
+
static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -767,6 +836,10 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
bool prox;
int x = 0, y = 0;
+ if ((wacom->features.touch_max > 1) ||
+ (len > WACOM_PKGLEN_TPC2FG))
+ return 0;
+
if (!wacom->shared->stylus_in_proximity) {
if (len == WACOM_PKGLEN_TPC1FG) {
prox = data[0] & 0x01;
@@ -835,10 +908,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
switch (len) {
case WACOM_PKGLEN_TPC1FG:
- return wacom_tpc_single_touch(wacom, len);
+ return wacom_tpc_single_touch(wacom, len);
case WACOM_PKGLEN_TPC2FG:
- return wacom_tpc_mt_touch(wacom);
+ return wacom_tpc_mt_touch(wacom);
default:
switch (data[0]) {
@@ -847,6 +920,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
case WACOM_REPORT_TPCST:
return wacom_tpc_single_touch(wacom, len);
+ case WACOM_REPORT_TPCMT:
+ return wacom_mt_touch(wacom);
+
case WACOM_REPORT_PENABLED:
return wacom_tpc_pen(wacom);
}
@@ -1088,6 +1164,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case TABLETPC:
case TABLETPC2FG:
+ case MTSCREEN:
sync = wacom_tpc_irq(wacom_wac, len);
break;
@@ -1156,7 +1233,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 == MTSCREEN)
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1330,6 +1407,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
break;
case TABLETPC2FG:
+ case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
input_mt_init_slots(input_dev, features->touch_max);
@@ -1633,6 +1711,9 @@ static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.touch_max = 2 };
+static const struct wacom_features wacom_features_0xE5 =
+ { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255,
+ 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
@@ -1799,6 +1880,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x9F) },
{ USB_DEVICE_WACOM(0xE2) },
{ USB_DEVICE_WACOM(0xE3) },
+ { USB_DEVICE_WACOM(0xE5) },
{ USB_DEVICE_WACOM(0xE6) },
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 1c9dc3e..265b09f 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -24,6 +24,10 @@
#define WACOM_PKGLEN_BBTOUCH 20
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
+#define WACOM_PKGLEN_MTOUCH 62
+
+/* wacom data size per MT contact */
+#define WACOM_BYTES_PER_MT_PACKET 11
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -39,6 +43,7 @@
#define WACOM_REPORT_INTUOSPAD 12
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
+#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
@@ -68,6 +73,7 @@ enum {
WACOM_MO,
TABLETPC,
TABLETPC2FG,
+ MTSCREEN,
MAX_TYPE
};
@@ -92,6 +98,8 @@ struct wacom_features {
int distance_fuzz;
unsigned quirks;
unsigned touch_max;
+ unsigned num_contacts;
+ unsigned num_contacts_left;
};
struct wacom_shared {
--
1.7.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] input : wacom - retrieve maximum number of touch points
2012-02-01 4:03 [PATCH 1/2] input : wacom - retrieve maximum number of touch points chris
2012-02-01 4:03 ` [PATCH 2/2] input: wacom - add 0xE5 (MT device) support chris
@ 2012-02-01 11:53 ` Maurus Cuelenaere
2012-02-01 16:16 ` Chris Bagwell
1 sibling, 1 reply; 7+ messages in thread
From: Maurus Cuelenaere @ 2012-02-01 11:53 UTC (permalink / raw)
To: chris; +Cc: dmitry.torokhov, linux-input, Ping Cheng, Ping Cheng
Op 01-02-12 05:03, chris@cnpbagwell.com schreef:
> From: Ping Cheng<pinglinux@gmail.com>
>
> From the HID usage table when it is supported.
>
> Tested-by: Chris Bagwell<chris@cnpbagwell.com>
> Signed-off-by: Chris Bagwell<chris@cnpbagwell.com>
> Signed-off-by: Ping Cheng<pingc@wacom.com>
> ---
>
> These two patches were originally in a set of 4 from Ping.
> 2 of those 4 have already been committed to next branch.
>
> The change between this version and Ping's last version is
> making use of features to set the new touch_max value.
> The 2nd patch is unmodified.
>
> drivers/input/tablet/wacom_sys.c | 26 +++++++++++++++++-
> drivers/input/tablet/wacom_wac.c | 55 +++++++++++++++++++++++--------------
> drivers/input/tablet/wacom_wac.h | 1 +
> 3 files changed, 60 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
> index c9588ee..5004a75 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_CONTACTMAX 0x55
> #define HID_COLLECTION 0xa1
> #define HID_COLLECTION_LOGICAL 0x02
> #define HID_COLLECTION_END 0xc0
> @@ -196,6 +197,24 @@ static int wacom_parse_logical_collection(unsigned char *report,
> return length;
> }
>
> +static void wacom_retrieve_report_data(struct usb_interface *intf,
> + struct wacom_features *features)
> +{
> + int result = 0;
> + unsigned char *rep_data;
> +
> + rep_data = kmalloc(2, GFP_KERNEL);
> + if (!rep_data)
> + return;
Why not allocate this on the stack?
This also can't leak memory (like you currently do).
> +
> + rep_data[0] = 12;
> + result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
> + rep_data[0], rep_data, 2, WAC_MSG_RETRIES);
> +
> + if ((result>= 0)&& (rep_data[1]> 2))
> + features->touch_max = rep_data[1];
> +}
> +
--
Maurus Cuelenaere
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] input : wacom - retrieve maximum number of touch points
2012-02-01 11:53 ` [PATCH 1/2] input : wacom - retrieve maximum number of touch points Maurus Cuelenaere
@ 2012-02-01 16:16 ` Chris Bagwell
0 siblings, 0 replies; 7+ messages in thread
From: Chris Bagwell @ 2012-02-01 16:16 UTC (permalink / raw)
To: Maurus Cuelenaere; +Cc: dmitry.torokhov, linux-input, Ping Cheng, Ping Cheng
On Wed, Feb 1, 2012 at 5:53 AM, Maurus Cuelenaere <mcuelenaere@gmail.com> wrote:
> Op 01-02-12 05:03, chris@cnpbagwell.com schreef:
>
>> From: Ping Cheng<pinglinux@gmail.com>
>>
>> From the HID usage table when it is supported.
>>
>> Tested-by: Chris Bagwell<chris@cnpbagwell.com>
>> Signed-off-by: Chris Bagwell<chris@cnpbagwell.com>
>> Signed-off-by: Ping Cheng<pingc@wacom.com>
>> ---
>>
>> These two patches were originally in a set of 4 from Ping.
>> 2 of those 4 have already been committed to next branch.
>>
>> The change between this version and Ping's last version is
>> making use of features to set the new touch_max value.
>> The 2nd patch is unmodified.
>>
>> drivers/input/tablet/wacom_sys.c | 26 +++++++++++++++++-
>> drivers/input/tablet/wacom_wac.c | 55
>> +++++++++++++++++++++++--------------
>> drivers/input/tablet/wacom_wac.h | 1 +
>> 3 files changed, 60 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/input/tablet/wacom_sys.c
>> b/drivers/input/tablet/wacom_sys.c
>> index c9588ee..5004a75 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_CONTACTMAX 0x55
>> #define HID_COLLECTION 0xa1
>> #define HID_COLLECTION_LOGICAL 0x02
>> #define HID_COLLECTION_END 0xc0
>> @@ -196,6 +197,24 @@ static int wacom_parse_logical_collection(unsigned
>> char *report,
>> return length;
>> }
>>
>> +static void wacom_retrieve_report_data(struct usb_interface *intf,
>> + struct wacom_features *features)
>> +{
>> + int result = 0;
>> + unsigned char *rep_data;
>> +
>> + rep_data = kmalloc(2, GFP_KERNEL);
>> + if (!rep_data)
>> + return;
>
>
> Why not allocate this on the stack?
> This also can't leak memory (like you currently do).
Ah, thank you. That leak got introduced in v2 and I missed it.
Agree with using stack. I think we can spare the 2 bytes. :)
In v1, this function was inlined in another function that was doing
malloc()'s for large message and it felt balanced there.
Chris
>
>> +
>> + rep_data[0] = 12;
>> + result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
>> + rep_data[0], rep_data, 2, WAC_MSG_RETRIES);
>> +
>> + if ((result>= 0)&& (rep_data[1]> 2))
>>
>> + features->touch_max = rep_data[1];
>> +}
>> +
>
>
> --
> Maurus Cuelenaere
>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] input: wacom - add 0xE5 (MT device) support
2012-04-26 1:14 Ping Cheng
@ 2012-04-30 4:10 ` Dmitry Torokhov
0 siblings, 0 replies; 7+ messages in thread
From: Dmitry Torokhov @ 2012-04-30 4:10 UTC (permalink / raw)
To: Ping Cheng; +Cc: linux-input, Chris Bagwell, Ping Cheng
On Wed, Apr 25, 2012 at 06:14:16PM -0700, Ping Cheng wrote:
> Main part of patch is adding support for a new Wacom MT touch
> packet and labels these devices using MTSCREEN type.
>
> Other items of interest:
>
> Delete some duplicate code in HID parsing for Y info since
> its already done in X path.
>
> In wacom_query_tablet_data(), only invoke the set report
> that requests tablets to send Wacom Touch packets for
> Finger interfaces. Mostly, this is to make code intent clear.
Applied, but:
> +
> + wacom->num_contacts_left -= contacts_to_send;
> + if (wacom->num_contacts_left < 0)
> + wacom->num_contacts_left = 0;
num_contacts_left is unsigned so this condition woudl never fire.
Changed num_contacts_left to be signed before applying.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] input: wacom - add 0xE5 (MT device) support
@ 2012-04-26 1:14 Ping Cheng
2012-04-30 4:10 ` Dmitry Torokhov
0 siblings, 1 reply; 7+ messages in thread
From: Ping Cheng @ 2012-04-26 1:14 UTC (permalink / raw)
To: linux-input; +Cc: dmitry.torokhov, Ping Cheng, Chris Bagwell, Ping Cheng
Main part of patch is adding support for a new Wacom MT touch
packet and labels these devices using MTSCREEN type.
Other items of interest:
Delete some duplicate code in HID parsing for Y info since
its already done in X path.
In wacom_query_tablet_data(), only invoke the set report
that requests tablets to send Wacom Touch packets for
Finger interfaces. Mostly, this is to make code intent clear.
Tested-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom.h | 4 +-
drivers/input/tablet/wacom_sys.c | 86 +++++++++++++++++++---------------
drivers/input/tablet/wacom_wac.c | 96 ++++++++++++++++++++++++++++++++++++--
drivers/input/tablet/wacom_wac.h | 8 +++
4 files changed, 149 insertions(+), 45 deletions(-)
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index b4842d0..b79d451 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -135,6 +135,6 @@ extern const struct usb_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
void wacom_setup_device_quirks(struct wacom_features *features);
-void wacom_setup_input_capabilities(struct input_dev *input_dev,
- struct wacom_wac *wacom_wac);
+int wacom_setup_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac);
#endif
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 347026b..a941d6e 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -317,6 +317,10 @@ static int wacom_parse_hid(struct usb_interface *intf,
/* need to reset back */
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
+
+ if (features->type == MTSCREEN)
+ features->pktlen = WACOM_PKGLEN_MTOUCH;
+
if (features->type == BAMBOO_PT) {
/* need to reset back */
features->pktlen = WACOM_PKGLEN_BBTOUCH;
@@ -349,18 +353,15 @@ static int wacom_parse_hid(struct usb_interface *intf,
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->device_type = BTN_TOOL_FINGER;
- if (features->type == TABLETPC2FG) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_TPC2FG;
+ int type = features->type;
+
+ if (type == TABLETPC2FG || type == MTSCREEN) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
- } else if (features->type == BAMBOO_PT) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ } else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
features->y_max =
@@ -374,10 +375,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
i += 4;
}
} else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- features->device_type = BTN_TOOL_PEN;
features->y_max =
get_unaligned_le16(&report[i + 3]);
i += 4;
@@ -440,22 +437,27 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
if (!rep_data)
return error;
- /* ask to report tablet data if it is MT Tablet PC or
- * not a Tablet PC */
- if (features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- rep_data[2] = 0;
- rep_data[3] = 0;
- report_id = 3;
- error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 4, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 4, 1);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
+ /* ask to report Wacom data */
+ if (features->device_type == BTN_TOOL_FINGER) {
+ /* if it is an MT Tablet PC touch */
+ if ((features->type == TABLETPC2FG) ||
+ (features->type == MTSCREEN)) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ rep_data[2] = 0;
+ rep_data[3] = 0;
+ report_id = 3;
+ error = wacom_set_report(intf,
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 4, 1);
+ if (error >= 0)
+ error = wacom_get_report(intf,
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 4, 1);
+ } while ((error < 0 || rep_data[1] != 4) &&
+ limit++ < WAC_MSG_RETRIES);
+ }
} else if (features->type != TABLETPC &&
features->type != WIRELESS &&
features->device_type == BTN_TOOL_PEN) {
@@ -466,8 +468,8 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
report_id, rep_data, 2, 1);
if (error >= 0)
error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2, 1);
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2, 1);
} while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
}
@@ -505,9 +507,9 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
}
}
- /* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ /* only devices that support touch need to retrieve the info */
if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
- (features->type != BAMBOO_PT))
+ (features->type != BAMBOO_PT) && (features->type != MTSCREEN))
goto out;
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -978,8 +980,10 @@ static int wacom_register_input(struct wacom *wacom)
int error;
input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
+ if (!input_dev) {
+ error = -ENOMEM;
+ goto fail1;
+ }
input_dev->name = wacom_wac->name;
input_dev->dev.parent = &intf->dev;
@@ -989,14 +993,20 @@ static int wacom_register_input(struct wacom *wacom)
input_set_drvdata(input_dev, wacom);
wacom_wac->input = input_dev;
- wacom_setup_input_capabilities(input_dev, wacom_wac);
+ error = wacom_setup_input_capabilities(input_dev, wacom_wac);
+ if (error)
+ goto fail1;
error = input_register_device(input_dev);
- if (error) {
- input_free_device(input_dev);
- wacom_wac->input = NULL;
- }
+ if (error)
+ goto fail2;
+
+ return 0;
+fail2:
+ input_free_device(input_dev);
+ wacom_wac->input = NULL;
+fail1:
return error;
}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index e5cd0e5..3afd3bc 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -768,6 +768,70 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
return 1;
}
+static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
+{
+ int touch_max = wacom->features.touch_max;
+ int i;
+
+ if (!wacom->slots)
+ return -1;
+
+ for (i = 0; i < touch_max; ++i) {
+ if (wacom->slots[i] == contactid)
+ return i;
+ }
+ for (i = 0; i < touch_max; ++i) {
+ if (wacom->slots[i] == -1)
+ return i;
+ }
+ return -1;
+}
+
+static int wacom_mt_touch(struct wacom_wac *wacom)
+{
+ struct input_dev *input = wacom->input;
+ char *data = wacom->data;
+ int i;
+ int current_num_contacts = data[2];
+ int contacts_to_send = 0;
+
+ /* reset the counter by the first packet 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 5 contacts per packet */
+ contacts_to_send = min(5, (int)wacom->num_contacts_left);
+
+ for (i = 0; i < contacts_to_send; i++) {
+ int offset = (WACOM_BYTES_PER_MT_PACKET * i) + 3;
+ bool touch = data[offset] & 0x1;
+ int id = le16_to_cpup((__le16 *)&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 x = le16_to_cpup((__le16 *)&data[offset + 7]);
+ int y = le16_to_cpup((__le16 *)&data[offset + 9]);
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ }
+ 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_tpc_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -806,6 +870,10 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
bool prox;
int x = 0, y = 0;
+ if ((wacom->features.touch_max > 1) ||
+ (len > WACOM_PKGLEN_TPC2FG))
+ return 0;
+
if (!wacom->shared->stylus_in_proximity) {
if (len == WACOM_PKGLEN_TPC1FG) {
prox = data[0] & 0x01;
@@ -873,10 +941,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
switch (len) {
case WACOM_PKGLEN_TPC1FG:
- return wacom_tpc_single_touch(wacom, len);
+ return wacom_tpc_single_touch(wacom, len);
case WACOM_PKGLEN_TPC2FG:
- return wacom_tpc_mt_touch(wacom);
+ return wacom_tpc_mt_touch(wacom);
default:
switch (data[0]) {
@@ -885,6 +953,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
case WACOM_REPORT_TPCST:
return wacom_tpc_single_touch(wacom, len);
+ case WACOM_REPORT_TPCMT:
+ return wacom_mt_touch(wacom);
+
case WACOM_REPORT_PENABLED:
return wacom_tpc_pen(wacom);
}
@@ -1164,6 +1235,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case TABLETPC:
case TABLETPC2FG:
+ case MTSCREEN:
sync = wacom_tpc_irq(wacom_wac, len);
break;
@@ -1237,7 +1309,8 @@ 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 == WIRELESS ||
- (features->type >= INTUOS5S && features->type <= INTUOS5L))
+ (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
+ features->type == MTSCREEN)
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1268,8 +1341,8 @@ static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
return (logical_max * 100) / physical_max;
}
-void wacom_setup_input_capabilities(struct input_dev *input_dev,
- struct wacom_wac *wacom_wac)
+int wacom_setup_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac)
{
struct wacom_features *features = &wacom_wac->features;
int i;
@@ -1465,8 +1538,16 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
break;
case TABLETPC2FG:
+ case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
+ wacom_wac->slots = kmalloc(features->touch_max *
+ sizeof(int), GFP_KERNEL);
+ if (!wacom_wac->slots)
+ return -ENOMEM;
+ for (i = 0; i < features->touch_max; i++)
+ wacom_wac->slots[i] = -1;
+
input_mt_init_slots(input_dev, features->touch_max);
input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
0, MT_TOOL_MAX, 0, 0);
@@ -1552,6 +1633,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
}
break;
}
+ return 0;
}
static const struct wacom_features wacom_features_0x00 =
@@ -1784,6 +1866,9 @@ static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.touch_max = 2 };
+static const struct wacom_features wacom_features_0xE5 =
+ { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255,
+ 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
@@ -1962,6 +2047,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x9F) },
{ USB_DEVICE_WACOM(0xE2) },
{ USB_DEVICE_WACOM(0xE3) },
+ { USB_DEVICE_WACOM(0xE5) },
{ USB_DEVICE_WACOM(0xE6) },
{ USB_DEVICE_WACOM(0xEC) },
{ USB_DEVICE_WACOM(0x47) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 321269c..3dde639 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,10 @@
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
#define WACOM_PKGLEN_WIRELESS 32
+#define WACOM_PKGLEN_MTOUCH 62
+
+/* wacom data size per MT contact */
+#define WACOM_BYTES_PER_MT_PACKET 11
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -41,6 +45,7 @@
#define WACOM_REPORT_INTUOS5PAD 3
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
+#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
@@ -76,6 +81,7 @@ enum {
WACOM_MO,
TABLETPC,
TABLETPC2FG,
+ MTSCREEN,
MAX_TYPE
};
@@ -118,6 +124,8 @@ struct wacom_wac {
struct input_dev *input;
int pid;
int battery_capacity;
+ unsigned num_contacts_left;
+ int *slots;
};
#endif
--
1.7.5.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] input: wacom - add 0xE5 (MT device) support
2012-04-15 22:50 [PATCH 0/2] Add E5 support chris
@ 2012-04-15 22:50 ` chris
0 siblings, 0 replies; 7+ messages in thread
From: chris @ 2012-04-15 22:50 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, pinglinux; +Cc: Chris Bagwell, Ping Cheng
From: Ping Cheng <pinglinux@gmail.com>
Main part of patch is adding support for a new Wacom MT touch
packet and labels these devices using MTSCREEN type.
Other items of interest:
Delete some duplicate code in HID parsing for Y info since
its already done in X path.
In wacom_query_tablet_data(), only invoke the set report
that requests tablets to send Wacom Touch packets for
Finger interfaces. Mostly, this is to make code intent clear.
Tested-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom.h | 4 +-
drivers/input/tablet/wacom_sys.c | 86 +++++++++++++++++++---------------
drivers/input/tablet/wacom_wac.c | 96 ++++++++++++++++++++++++++++++++++++--
drivers/input/tablet/wacom_wac.h | 8 +++
4 files changed, 149 insertions(+), 45 deletions(-)
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index b4842d0..b79d451 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -135,6 +135,6 @@ extern const struct usb_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
void wacom_setup_device_quirks(struct wacom_features *features);
-void wacom_setup_input_capabilities(struct input_dev *input_dev,
- struct wacom_wac *wacom_wac);
+int wacom_setup_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac);
#endif
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 469f6ce..822ab06 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -310,6 +310,10 @@ static int wacom_parse_hid(struct usb_interface *intf,
/* need to reset back */
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
+
+ if (features->type == MTSCREEN)
+ features->pktlen = WACOM_PKGLEN_MTOUCH;
+
if (features->type == BAMBOO_PT) {
/* need to reset back */
features->pktlen = WACOM_PKGLEN_BBTOUCH;
@@ -342,18 +346,15 @@ static int wacom_parse_hid(struct usb_interface *intf,
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->device_type = BTN_TOOL_FINGER;
- if (features->type == TABLETPC2FG) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_TPC2FG;
+ int type = features->type;
+
+ if (type == TABLETPC2FG || type == MTSCREEN) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
- } else if (features->type == BAMBOO_PT) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ } else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
features->y_max =
@@ -367,10 +368,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
i += 4;
}
} else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- features->device_type = BTN_TOOL_PEN;
features->y_max =
get_unaligned_le16(&report[i + 3]);
i += 4;
@@ -433,22 +430,27 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
if (!rep_data)
return error;
- /* ask to report tablet data if it is MT Tablet PC or
- * not a Tablet PC */
- if (features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- rep_data[2] = 0;
- rep_data[3] = 0;
- report_id = 3;
- error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 4, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 4, 1);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
+ /* ask to report Wacom data */
+ if (features->device_type == BTN_TOOL_FINGER) {
+ /* if it is an MT Tablet PC touch */
+ if ((features->type == TABLETPC2FG) ||
+ (features->type == MTSCREEN)) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ rep_data[2] = 0;
+ rep_data[3] = 0;
+ report_id = 3;
+ error = wacom_set_report(intf,
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 4, 1);
+ if (error >= 0)
+ error = wacom_get_report(intf,
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 4, 1);
+ } while ((error < 0 || rep_data[1] != 4) &&
+ limit++ < WAC_MSG_RETRIES);
+ }
} else if (features->type != TABLETPC &&
features->type != WIRELESS &&
features->device_type == BTN_TOOL_PEN) {
@@ -459,8 +461,8 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
report_id, rep_data, 2, 1);
if (error >= 0)
error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2, 1);
+ WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2, 1);
} while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
}
@@ -498,9 +500,9 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
}
}
- /* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ /* only devices that support touch need to retrieve the info */
if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
- (features->type != BAMBOO_PT))
+ (features->type != BAMBOO_PT) && (features->type != MTSCREEN))
goto out;
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -971,8 +973,10 @@ static int wacom_register_input(struct wacom *wacom)
int error;
input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
+ if (!input_dev) {
+ error = -ENOMEM;
+ goto fail1;
+ }
input_dev->name = wacom_wac->name;
input_dev->dev.parent = &intf->dev;
@@ -982,14 +986,20 @@ static int wacom_register_input(struct wacom *wacom)
input_set_drvdata(input_dev, wacom);
wacom_wac->input = input_dev;
- wacom_setup_input_capabilities(input_dev, wacom_wac);
+ error = wacom_setup_input_capabilities(input_dev, wacom_wac);
+ if (error)
+ goto fail1;
error = input_register_device(input_dev);
- if (error) {
- input_free_device(input_dev);
- wacom_wac->input = NULL;
- }
+ if (error)
+ goto fail2;
+
+ return 0;
+fail2:
+ input_free_device(input_dev);
+ wacom_wac->input = NULL;
+fail1:
return error;
}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index a257bed..ded0e8b 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -768,6 +768,70 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
return 1;
}
+static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
+{
+ int touch_max = wacom->features.touch_max;
+ int i;
+
+ if (!wacom->slots)
+ return -1;
+
+ for (i = 0; i < touch_max; ++i) {
+ if (wacom->slots[i] == contactid)
+ return i;
+ }
+ for (i = 0; i < touch_max; ++i) {
+ if (wacom->slots[i] == -1)
+ return i;
+ }
+ return -1;
+}
+
+static int wacom_mt_touch(struct wacom_wac *wacom)
+{
+ struct input_dev *input = wacom->input;
+ char *data = wacom->data;
+ int i;
+ int current_num_contacts = data[2];
+ int contacts_to_send = 0;
+
+ /* reset the counter by the first packet 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 5 contacts per packet */
+ contacts_to_send = min(5, (int)wacom->num_contacts_left);
+
+ for (i = 0; i < contacts_to_send; i++) {
+ int offset = (WACOM_BYTES_PER_MT_PACKET * i) + 3;
+ bool touch = data[offset] & 0x1;
+ int id = le16_to_cpup((__le16 *)&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 x = le16_to_cpup((__le16 *)&data[offset + 7]);
+ int y = le16_to_cpup((__le16 *)&data[offset + 9]);
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ }
+ 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_tpc_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -806,6 +870,10 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
bool prox;
int x = 0, y = 0;
+ if ((wacom->features.touch_max > 1) ||
+ (len > WACOM_PKGLEN_TPC2FG))
+ return 0;
+
if (!wacom->shared->stylus_in_proximity) {
if (len == WACOM_PKGLEN_TPC1FG) {
prox = data[0] & 0x01;
@@ -873,10 +941,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
switch (len) {
case WACOM_PKGLEN_TPC1FG:
- return wacom_tpc_single_touch(wacom, len);
+ return wacom_tpc_single_touch(wacom, len);
case WACOM_PKGLEN_TPC2FG:
- return wacom_tpc_mt_touch(wacom);
+ return wacom_tpc_mt_touch(wacom);
default:
switch (data[0]) {
@@ -885,6 +953,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
case WACOM_REPORT_TPCST:
return wacom_tpc_single_touch(wacom, len);
+ case WACOM_REPORT_TPCMT:
+ return wacom_mt_touch(wacom);
+
case WACOM_REPORT_PENABLED:
return wacom_tpc_pen(wacom);
}
@@ -1164,6 +1235,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case TABLETPC:
case TABLETPC2FG:
+ case MTSCREEN:
sync = wacom_tpc_irq(wacom_wac, len);
break;
@@ -1237,7 +1309,8 @@ 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 == WIRELESS ||
- (features->type >= INTUOS5S && features->type <= INTUOS5L))
+ (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
+ features->type == MTSCREEN)
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1268,8 +1341,8 @@ static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
return (logical_max * 100) / physical_max;
}
-void wacom_setup_input_capabilities(struct input_dev *input_dev,
- struct wacom_wac *wacom_wac)
+int wacom_setup_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac)
{
struct wacom_features *features = &wacom_wac->features;
int i;
@@ -1465,8 +1538,16 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
break;
case TABLETPC2FG:
+ case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
+ wacom_wac->slots = kmalloc(features->touch_max *
+ sizeof(int), GFP_KERNEL);
+ if (!wacom_wac->slots)
+ return -ENOMEM;
+ for (i = 0; i < features->touch_max; i++)
+ wacom_wac->slots[i] = -1;
+
input_mt_init_slots(input_dev, features->touch_max);
input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
0, MT_TOOL_MAX, 0, 0);
@@ -1552,6 +1633,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
}
break;
}
+ return 0;
}
static const struct wacom_features wacom_features_0x00 =
@@ -1784,6 +1866,9 @@ static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.touch_max = 2 };
+static const struct wacom_features wacom_features_0xE5 =
+ { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255,
+ 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
@@ -1962,6 +2047,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x9F) },
{ USB_DEVICE_WACOM(0xE2) },
{ USB_DEVICE_WACOM(0xE3) },
+ { USB_DEVICE_WACOM(0xE5) },
{ USB_DEVICE_WACOM(0xE6) },
{ USB_DEVICE_WACOM(0xEC) },
{ USB_DEVICE_WACOM(0x47) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 321269c..3dde639 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,10 @@
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
#define WACOM_PKGLEN_WIRELESS 32
+#define WACOM_PKGLEN_MTOUCH 62
+
+/* wacom data size per MT contact */
+#define WACOM_BYTES_PER_MT_PACKET 11
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -41,6 +45,7 @@
#define WACOM_REPORT_INTUOS5PAD 3
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
+#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
@@ -76,6 +81,7 @@ enum {
WACOM_MO,
TABLETPC,
TABLETPC2FG,
+ MTSCREEN,
MAX_TYPE
};
@@ -118,6 +124,8 @@ struct wacom_wac {
struct input_dev *input;
int pid;
int battery_capacity;
+ unsigned num_contacts_left;
+ int *slots;
};
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-04-30 4:10 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-01 4:03 [PATCH 1/2] input : wacom - retrieve maximum number of touch points chris
2012-02-01 4:03 ` [PATCH 2/2] input: wacom - add 0xE5 (MT device) support chris
2012-02-01 11:53 ` [PATCH 1/2] input : wacom - retrieve maximum number of touch points Maurus Cuelenaere
2012-02-01 16:16 ` Chris Bagwell
2012-04-15 22:50 [PATCH 0/2] Add E5 support chris
2012-04-15 22:50 ` [PATCH 2/2] input: wacom - add 0xE5 (MT device) support chris
2012-04-26 1:14 Ping Cheng
2012-04-30 4:10 ` Dmitry Torokhov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.