summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--configure.in4
-rwxr-xr-xsrc/2.6.19/wacom_wac.c58
-rwxr-xr-xsrc/2.6.24/wacom.h4
-rwxr-xr-xsrc/2.6.24/wacom_sys.c154
-rwxr-xr-xsrc/2.6.26/wacom.h4
-rwxr-xr-xsrc/2.6.26/wacom_sys.c161
-rwxr-xr-xsrc/2.6.27/wacom.h4
-rw-r--r--src/2.6.28/wacom_sys.c168
-rwxr-xr-xsrc/2.6.28/wacom_wac.c23
-rwxr-xr-xsrc/2.6.28/wacom_wac.h9
-rw-r--r--src/util/10-linuxwacom.fdi4
-rwxr-xr-xsrc/xdrv/wcmCommon.c67
-rwxr-xr-xsrc/xdrv/wcmConfig.c45
-rwxr-xr-xsrc/xdrv/wcmISDV4.c268
-rwxr-xr-xsrc/xdrv/wcmSerial.c2
-rw-r--r--src/xdrv/wcmTouchFilter.c7
-rwxr-xr-xsrc/xdrv/wcmUSB.c2
-rwxr-xr-xsrc/xdrv/wcmValidateDevice.c95
-rwxr-xr-xsrc/xdrv/xf86Wacom.c88
-rwxr-xr-xsrc/xdrv/xf86WacomDefs.h2
21 files changed, 694 insertions, 481 deletions
diff --git a/ChangeLog b/ChangeLog
index 6120e46..059e4c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-30 Ping Cheng <pingc@wacom.com>
+ * Fixed a kernel driver bug for E3
+ * Updated serial ISDv4 support with newer protocol
+ * Support suspend/resume for kernel 2.6.26 and later
+ * Label 0.8.5-5
+
2009-11-13 Ping Cheng <pingc@wacom.com>
* Allow multiple tools defined with one type
* Label 0.8.5-4
diff --git a/configure.in b/configure.in
index 1a22de0..c87b84f 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
AC_PREREQ(2.58)
-AC_INIT(linuxwacom, 0.8.5-2)
+AC_INIT(linuxwacom, 0.8.5)
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
@@ -600,7 +600,7 @@ if test "$WCM_XORG_XSERVER_1_6" == yes; then
fi
fi
-if test "$WCM_XORG_XSERVER_1_4" == yes -a "$WCM_XORG_XSERVER_1_6" != yes; then
+if test "$WCM_XORG_XSERVER_1_4" == yes -a "$WCM_XORG_XSERVER_1_5_2" != yes; then
WCM_XDRIVER_QUIRKS="$WCM_XDRIVER_QUIRKS Uninit-called"
fi
diff --git a/src/2.6.19/wacom_wac.c b/src/2.6.19/wacom_wac.c
index 8bf5b49..2faa652 100755
--- a/src/2.6.19/wacom_wac.c
+++ b/src/2.6.19/wacom_wac.c
@@ -609,15 +609,15 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */
if (urb->actual_length == 5) { /* with touch */
- prox = data[0] & 0x03;
+ prox = data[0] & 0x01;
} else { /* with capacity */
- prox = data[1] & 0x03;
+ prox = data[1] & 0x01;
}
if (!stylusInProx) { /* stylus not in prox */
if (prox) {
if (touchInProx) {
- wacom->tool[1] = BTN_TOOL_DOUBLETAP;
+ wacom->tool[0] = BTN_TOOL_DOUBLETAP;
wacom->id[0] = TOUCH_DEVICE_ID;
if (urb->actual_length != 5) {
wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
@@ -630,13 +630,13 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_TOUCH, 1);
}
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
- wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
+ wacom_report_key(wcombo, wacom->tool[0], prox & 0x01);
touchOut = 1;
return 1;
}
} else {
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
- wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
+ wacom_report_key(wcombo, wacom->tool[0], prox & 0x01);
wacom_report_key(wcombo, BTN_TOUCH, 0);
touchOut = 0;
touchInProx = 1;
@@ -644,7 +644,7 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
}
} else if (touchOut || !prox) { /* force touch out-prox */
wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID);
- wacom_report_key(wcombo, wacom->tool[1], 0);
+ wacom_report_key(wcombo, wacom->tool[0], 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
touchOut = 0;
touchInProx = 1;
@@ -655,38 +655,14 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
touchInProx = 0;
- wacom->id[0] = ERASER_DEVICE_ID;
-
- /*
- * if going from out of proximity into proximity select between the eraser
- * and the pen based on the state of the stylus2 button, choose eraser if
- * pressed else choose pen. if not a proximity change from out to in, send
- * an out of proximity for previous tool then a in for new tool.
- */
- if (prox) { /* in prox */
- if (!wacom->tool[0]) {
- /* Going into proximity select tool */
- wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
- if (wacom->tool[1] == BTN_TOOL_PEN)
+ if (prox) { /* pen in prox */
+ if (!wacom->id[0]) {
+ wacom->tool[0] = (data[1] & 0x0c) ?
+ BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+ if (wacom->tool[0] == BTN_TOOL_PEN)
wacom->id[0] = STYLUS_DEVICE_ID;
- } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) {
- /*
- * was entered with stylus2 pressed
- * report out proximity for previous tool
- */
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
- wacom_report_key(wcombo, wacom->tool[1], 0);
- wacom_input_sync(wcombo);
-
- /* set new tool */
- wacom->tool[1] = BTN_TOOL_PEN;
- wacom->id[0] = STYLUS_DEVICE_ID;
- return 0;
- }
- if (wacom->tool[1] != BTN_TOOL_RUBBER) {
- /* Unknown tool selected default to pen tool */
- wacom->tool[1] = BTN_TOOL_PEN;
- wacom->id[0] = STYLUS_DEVICE_ID;
+ else
+ wacom->id[0] = ERASER_DEVICE_ID;
}
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
@@ -698,15 +674,19 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
wacom_report_key(wcombo, BTN_TOUCH, pressure);
} else {
+ wacom_report_abs(wcombo, ABS_X, 0);
+ wacom_report_abs(wcombo, ABS_Y, 0);
wacom_report_abs(wcombo, ABS_PRESSURE, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
wacom_report_key(wcombo, BTN_STYLUS, 0);
wacom_report_key(wcombo, BTN_STYLUS2, 0);
+ wacom->id[0] = 0;
+ /* pen is out so touch can be enabled now */
+ touchInProx = 1;
}
- wacom_report_key(wcombo, wacom->tool[1], prox);
+ wacom_report_key(wcombo, wacom->tool[0], prox);
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
stylusInProx = prox;
- wacom->tool[0] = prox;
return 1;
}
return 0;
diff --git a/src/2.6.24/wacom.h b/src/2.6.24/wacom.h
index 468f2bc..f292cfc 100755
--- a/src/2.6.24/wacom.h
+++ b/src/2.6.24/wacom.h
@@ -84,9 +84,9 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.46-pc0.6"
+#define DRIVER_VERSION "v1.46-pc0.7"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
+#define DRIVER_DESC "USB Wacom tablet driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/src/2.6.24/wacom_sys.c b/src/2.6.24/wacom_sys.c
index bd6f83b..571d3dc 100755
--- a/src/2.6.24/wacom_sys.c
+++ b/src/2.6.24/wacom_sys.c
@@ -1,7 +1,7 @@
/*
* drivers/input/tablet/wacom_sys.c
*
- * USB Wacom Graphire and Wacom Intuos tablet support - system specific code
+ * USB Wacom tablet support - system specific code
*/
/*
@@ -270,7 +270,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) ||
+ (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP)) {
input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0);
input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
@@ -279,7 +280,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
input_dev->evbit[0] |= BIT_MASK(EV_MSC);
input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
@@ -287,10 +288,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
- struct wacom_wac *wacom_wac)
+ struct wacom_features *features)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct wacom_features *features = wacom_wac->features;
char limit = 0;
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0;
unsigned char *report;
@@ -335,6 +335,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
+ }
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
features->x_phy =
@@ -343,6 +348,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->x_max =
(wacom_le16_to_cpu(&report[i+3]));
@@ -361,7 +369,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
- if (strstr(features->name, "Wacom ISDv4 E")) {
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
features->y_phy =
@@ -375,6 +386,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
i += 4;
}
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->y_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
@@ -412,17 +426,86 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
return result;
}
+static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features)
+{
+ char rep_data[4], limit = 0, report_id = 2;
+ int error = -ENOMEM;
+ /*
+ * Ask to report tablet data if it is 2FGT or not a Tablet PC.
+ * Repeat 3 times since on some systems the first 2 may fail.
+ */
+
+ if (features->device_type == BTN_TOOL_TRIPLETAP) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ report_id = 3;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 3);
+ } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
+ } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) {
+ do {
+ rep_data[0] = 2;
+ rep_data[1] = 2;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 2);
+ } while ((error < 0 || rep_data[1] != 2) && limit++ < 3);
+ }
+ return error;
+}
+
+static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ struct wacom_features *features)
+{
+ int error = 0;
+ struct usb_host_interface *interface = intf->cur_altsetting;
+ struct hid_descriptor *hid_desc;
+
+ /* default device to penabled */
+ features->device_type = BTN_TOOL_PEN;
+
+ /* only Tablet PCs need to retrieve the info */
+ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+ goto out;
+
+ if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+ if (usb_get_extra_descriptor(&interface->endpoint[0],
+ HID_DEVICET_REPORT, &hid_desc)) {
+ printk("wacom: can not retrieve extra class descriptor\n");
+ error = 1;
+ goto out;
+ }
+ }
+ error = wacom_parse_hid(intf, hid_desc, features);
+ if (error)
+ goto out;
+
+ /* touch device found but size is not defined. use default */
+ if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+ features->x_max = 1023;
+ features->y_max = 1023;
+ }
+
+ out:
+ return error;
+}
+
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_endpoint_descriptor *endpoint;
struct wacom *wacom;
struct wacom_wac *wacom_wac;
struct input_dev *input_dev;
int error = -ENOMEM;
- char rep_data[2], limit = 0, report_id = 2;
- struct hid_descriptor *hid_desc;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
@@ -446,10 +529,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom_wac->features = get_wacom_feature(id);
BUG_ON(wacom_wac->features->pktlen > WACOM_PKGLEN_MAX);
- /* default device to penabled */
- if (wacom_wac->features->device_type)
- wacom_wac->features->device_type = BTN_TOOL_PEN;
-
input_dev->name = wacom_wac->features->name;
wacom->wacom_wac = wacom_wac;
usb_to_input_id(dev, &input_dev->id);
@@ -463,26 +542,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) {
-
- /* TabletPC need to retrieve the physical and logical maximum from report descriptor */
- if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
- if (usb_get_extra_descriptor(&interface->endpoint[0],
- HID_DEVICET_REPORT, &hid_desc)) {
- printk("wacom: can not retrive extra class descriptor\n");
- goto fail2;
- }
- }
- error = wacom_parse_hid(intf, hid_desc, wacom_wac);
- if (error)
- goto fail2;
-
- /* touch device found but size is not defined. use default */
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP && !wacom_wac->features->x_max) {
- wacom_wac->features->x_max = 1023;
- wacom_wac->features->y_max = 1023;
- }
- }
+ error = wacom_retrieve_hid_descriptor(intf, wacom_wac->features);
+ if (error)
+ goto fail2;
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
@@ -504,30 +566,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail3;
- /* Ask the tablet to report tablet data if it is not a regular Tablet PC.
- * Repeat 3 times since on some systems the first 2 may fail.
- */
- if (wacom_wac->features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- report_id = 3;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2);
- if (error >= 0)
- error = usb_get_report(intf,
- WAC_HID_FEATURE_REPORT, report_id,
- rep_data, 3);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
- } else if (wacom_wac->features->type != TABLETPC) {
- do {
- rep_data[0] = 2;
- rep_data[1] = 2;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2);
- if(error >= 0)
- error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2);
- } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 3);
- }
+ /* switch to wacom mode if needed */
+ wacom_reset_report(intf, wacom_wac->features);
usb_set_intfdata(intf, wacom);
return 0;
diff --git a/src/2.6.26/wacom.h b/src/2.6.26/wacom.h
index b6762fe..f530c4c 100755
--- a/src/2.6.26/wacom.h
+++ b/src/2.6.26/wacom.h
@@ -87,9 +87,9 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.49-pc-2"
+#define DRIVER_VERSION "v1.49-pc-3"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
+#define DRIVER_DESC "USB Wacom tablet driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/src/2.6.26/wacom_sys.c b/src/2.6.26/wacom_sys.c
index af1102e..b6aa0b2 100755
--- a/src/2.6.26/wacom_sys.c
+++ b/src/2.6.26/wacom_sys.c
@@ -1,7 +1,7 @@
/*
* drivers/input/tablet/wacom_sys.c
*
- * USB Wacom Graphire and Wacom Intuos tablet support - system specific code
+ * USB Wacom tablet support - system specific code
*/
/*
@@ -287,7 +287,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) ||
+ (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP)) {
input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0);
input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
@@ -296,7 +297,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
input_dev->evbit[0] |= BIT_MASK(EV_MSC);
input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
@@ -304,10 +305,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
- struct wacom_wac *wacom_wac)
+ struct wacom_features *features)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct wacom_features *features = wacom_wac->features;
char limit = 0;
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0;
unsigned char *report;
@@ -352,6 +352,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
+ }
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
features->x_phy =
@@ -360,6 +365,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->x_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
@@ -377,7 +385,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
- if (strstr(features->name, "Wacom ISDv4 E")) {
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
features->y_phy =
@@ -391,6 +402,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
i += 4;
}
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->y_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
@@ -427,18 +441,86 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
kfree(report);
return result;
}
+static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features)
+{
+ char rep_data[4], limit = 0, report_id = 2;
+ int error = -ENOMEM;
+ /*
+ * Ask to report tablet data if it is 2FGT or not a Tablet PC.
+ * Repeat 3 times since on some systems the first 2 may fail.
+ */
+
+ if (features->device_type == BTN_TOOL_TRIPLETAP) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ report_id = 3;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 3);
+ } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
+ } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) {
+ do {
+ rep_data[0] = 2;
+ rep_data[1] = 2;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 2);
+ } while ((error < 0 || rep_data[1] != 2) && limit++ < 3);
+ }
+ return error;
+}
+
+static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ struct wacom_features *features)
+{
+ int error = 0;
+ struct usb_host_interface *interface = intf->cur_altsetting;
+ struct hid_descriptor *hid_desc;
+
+ /* default device to penabled */
+ features->device_type = BTN_TOOL_PEN;
+
+ /* only Tablet PCs need to retrieve the info */
+ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+ goto out;
+
+ if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+ if (usb_get_extra_descriptor(&interface->endpoint[0],
+ HID_DEVICET_REPORT, &hid_desc)) {
+ printk("wacom: can not retrieve extra class descriptor\n");
+ error = 1;
+ goto out;
+ }
+ }
+ error = wacom_parse_hid(intf, hid_desc, features);
+ if (error)
+ goto out;
+
+ /* touch device found but size is not defined. use default */
+ if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+ features->x_max = 1023;
+ features->y_max = 1023;
+ }
+
+ out:
+ return error;
+}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_endpoint_descriptor *endpoint;
struct wacom *wacom;
struct wacom_wac *wacom_wac;
struct input_dev *input_dev;
int error = -ENOMEM;
- char rep_data[2], limit = 0, report_id = 2;
- struct hid_descriptor *hid_desc;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
@@ -464,10 +546,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom_wac->features = get_wacom_feature(id);
BUG_ON(wacom_wac->features->pktlen > WACOM_PKGLEN_MAX);
- /* default device to penabled */
- if (features->device_type)
- features->device_type = BTN_TOOL_PEN;
-
input_dev->name = wacom_wac->features->name;
wacom->wacom_wac = wacom_wac;
usb_to_input_id(dev, &input_dev->id);
@@ -481,26 +559,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) {
-
- /* TabletPC need to retrieve the physical and logical maximum from report descriptor */
- if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
- if (usb_get_extra_descriptor(&interface->endpoint[0],
- HID_DEVICET_REPORT, &hid_desc)) {
- printk("wacom: can not retrive extra class descriptor\n");
- goto fail2;
- }
- }
- error = wacom_parse_hid(intf, hid_desc, wacom_wac);
- if (error)
- goto fail2;
-
- /* touch device found but size is not defined. use default */
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP && !wacom_wac->features->x_max) {
- wacom_wac->features->x_max = 1023;
- wacom_wac->features->y_max = 1023;
- }
- }
+ error = wacom_retrieve_hid_descriptor(intf, wacom_wac->features);
+ if (error)
+ goto fail2;
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
@@ -522,30 +583,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail3;
- /* Ask the tablet to report tablet data if it is not a regular Tablet PC.
- * Repeat 3 times since on some systems the first 2 may fail.
- */
- if (wacom_wac->features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- report_id = 3;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2);
- if (error >= 0)
- error = usb_get_report(intf,
- WAC_HID_FEATURE_REPORT, report_id,
- rep_data, 3);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
- } else if (wacom_wac->features->type != TABLETPC) {
- do {
- rep_data[0] = 2;
- rep_data[1] = 2;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2);
- if(error >= 0)
- error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2);
- } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 3);
- }
+ /* switch to wacom mode if needed */
+ wacom_reset_report(intf, wacom_wac->features);
usb_set_intfdata(intf, wacom);
return 0;
@@ -586,12 +625,16 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
static int wacom_resume(struct usb_interface *intf)
{
struct wacom *wacom = usb_get_intfdata(intf);
+ struct wacom_features *features = wacom->wacom_wac->features;
int rv;
mutex_lock(&wacom->lock);
- if (wacom->open)
+ if (wacom->open) {
rv = usb_submit_urb(wacom->irq, GFP_NOIO);
- else
+ /* switch to wacom mode if needed */
+ if (!wacom_retrieve_hid_descriptor(intf, features))
+ wacom_reset_report(intf, features);
+ } else
rv = 0;
mutex_unlock(&wacom->lock);
diff --git a/src/2.6.27/wacom.h b/src/2.6.27/wacom.h
index da2ac83..83eacd9 100755
--- a/src/2.6.27/wacom.h
+++ b/src/2.6.27/wacom.h
@@ -87,9 +87,9 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.49-pc-2"
+#define DRIVER_VERSION "v1.49-pc-3"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
+#define DRIVER_DESC "USB Wacom tablet driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/src/2.6.28/wacom_sys.c b/src/2.6.28/wacom_sys.c
index e9c27f7..155f70e 100644
--- a/src/2.6.28/wacom_sys.c
+++ b/src/2.6.28/wacom_sys.c
@@ -1,7 +1,7 @@
/*
* drivers/input/tablet/wacom_sys.c
*
- * USB Wacom Graphire and Wacom Intuos tablet support - system specific code
+ * USB Wacom tablet support - system specific code
*/
/*
@@ -282,7 +282,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) ||
+ (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP)) {
input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0);
input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
@@ -291,7 +292,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
input_dev->evbit[0] |= BIT_MASK(EV_MSC);
input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
@@ -299,10 +300,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
- struct wacom_wac *wacom_wac)
+ struct wacom_features *features)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct wacom_features *features = wacom_wac->features;
char limit = 0;
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0;
unsigned char *report;
@@ -350,6 +350,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
+ }
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
features->x_phy =
@@ -358,6 +363,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -377,7 +385,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_DOUBLETAP;
- if (strstr(features->name, "Wacom ISDv4 E")) {
+ if (features->type == TABLETPC2FG) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ features->device_type = BTN_TOOL_TRIPLETAP;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
features->y_phy =
@@ -391,6 +402,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
i += 4;
}
} else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type == TABLETPC2FG)
+ features->pktlen = WACOM_PKGLEN_PENABLED;
features->device_type = BTN_TOOL_PEN;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -431,18 +445,87 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
return result;
}
+static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features)
+{
+ char rep_data[4], limit = 0, report_id = 2;
+ int error = -ENOMEM;
+ /*
+ * Ask to report tablet data if it is 2FGT or not a Tablet PC.
+ * Repeat 3 times since on some systems the first 2 may fail.
+ */
+
+ if (features->device_type == BTN_TOOL_TRIPLETAP) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ report_id = 3;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 3);
+ } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
+ } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) {
+ do {
+ rep_data[0] = 2;
+ rep_data[1] = 2;
+ error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, 2);
+ if (error >= 0)
+ error = usb_get_report(intf,
+ WAC_HID_FEATURE_REPORT, report_id,
+ rep_data, 2);
+ } while ((error < 0 || rep_data[1] != 2) && limit++ < 3);
+ }
+ return error;
+}
+
+static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ struct wacom_features *features)
+{
+ int error = 0;
+ struct usb_host_interface *interface = intf->cur_altsetting;
+ struct hid_descriptor *hid_desc;
+
+ /* default device to penabled */
+ features->device_type = BTN_TOOL_PEN;
+
+ /* only Tablet PCs need to retrieve the info */
+ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+ goto out;
+
+ if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+ if (usb_get_extra_descriptor(&interface->endpoint[0],
+ HID_DEVICET_REPORT, &hid_desc)) {
+ printk("wacom: can not retrieve extra class descriptor\n");
+ error = 1;
+ goto out;
+ }
+ }
+ error = wacom_parse_hid(intf, hid_desc, features);
+ if (error)
+ goto out;
+
+ /* touch device found but size is not defined. use default */
+ if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+ features->x_max = 1023;
+ features->y_max = 1023;
+ }
+
+ out:
+ return error;
+}
+
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_endpoint_descriptor *endpoint;
struct wacom *wacom;
struct wacom_wac *wacom_wac;
struct wacom_features *features;
struct input_dev *input_dev;
int error = -ENOMEM;
- char rep_data[4], limit = 0, report_id = 2;
- struct hid_descriptor *hid_desc;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
@@ -468,10 +551,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom_wac->features = features = get_wacom_feature(id);
BUG_ON(features->pktlen > WACOM_PKGLEN_MAX);
- /* default device to penabled */
- if (features->device_type)
- features->device_type = BTN_TOOL_PEN;
-
input_dev->name = wacom_wac->features->name;
wacom->wacom_wac = wacom_wac;
usb_to_input_id(dev, &input_dev->id);
@@ -485,26 +564,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- if (features->type == TABLETPC || features->type == TABLETPC2FG) {
-
- /* TabletPC need to retrieve the physical and logical maximum from report descriptor */
- if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
- if (usb_get_extra_descriptor(&interface->endpoint[0],
- HID_DEVICET_REPORT, &hid_desc)) {
- printk("wacom: can not retrive extra class descriptor\n");
- goto fail2;
- }
- }
- error = wacom_parse_hid(intf, hid_desc, wacom_wac);
- if (error)
- goto fail2;
-
- /* touch device found but size is not defined. use default */
- if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
- features->x_max = 1023;
- features->y_max = 1023;
- }
- }
+ /* Retrieve the physical and logical size for OEM devices */
+ error = wacom_retrieve_hid_descriptor(intf, features);
+ if (error)
+ goto fail2;
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
@@ -528,35 +591,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail3;
- /*
- * Ask the tablet to report tablet data if it is not a regular Tablet PC.
- * Repeat 3 times since on some systems the first 2 may fail.
- */
-
- if (features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- report_id = 3;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2);
- if (error >= 0)
- error = usb_get_report(intf,
- WAC_HID_FEATURE_REPORT, report_id,
- rep_data, 3);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < 3);
- } else if (features->type != TABLETPC) {
- do {
- rep_data[0] = 2;
- rep_data[1] = 2;
- error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2);
- if (error >= 0)
- error = usb_get_report(intf,
- WAC_HID_FEATURE_REPORT, report_id,
- rep_data, 2);
- } while ((error < 0 || rep_data[1] != 2) && limit++ < 3);
- }
+ /* switch to wacom mode if needed */
+ wacom_reset_report(intf, features);
usb_set_intfdata(intf, wacom);
return 0;
@@ -598,12 +634,16 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
static int wacom_resume(struct usb_interface *intf)
{
struct wacom *wacom = usb_get_intfdata(intf);
+ struct wacom_features *features = wacom->wacom_wac->features;
int rv;
mutex_lock(&wacom->lock);
- if (wacom->open)
+ if (wacom->open) {
rv = usb_submit_urb(wacom->irq, GFP_NOIO);
- else
+ /* switch to wacom mode if needed */
+ if (!wacom_retrieve_hid_descriptor(intf, features))
+ wacom_reset_report(intf, features);
+ } else
rv = 0;
mutex_unlock(&wacom->lock);
diff --git a/src/2.6.28/wacom_wac.c b/src/2.6.28/wacom_wac.c
index 39b5d68..20ab051 100755
--- a/src/2.6.28/wacom_wac.c
+++ b/src/2.6.28/wacom_wac.c
@@ -1,7 +1,7 @@
/*
* drivers/input/tablet/wacom_wac.c
*
- * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
+ * USB Wacom tablet support - Wacom specific code
*
*/
@@ -14,14 +14,6 @@
#include "wacom.h"
#include "wacom_wac.h"
-/* packet length for individual models */
-#define WACOM_PKGLEN_PENPRTN 7
-#define WACOM_PKGLEN_GRAPHIRE 8
-#define WACOM_PKGLEN_BBFUN 9
-#define WACOM_PKGLEN_INTUOS 10
-#define WACOM_PKGLEN_TPC1FG 5
-#define WACOM_PKGLEN_TPC2FG 14
-
static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
{
unsigned char *data = wacom->data;
@@ -846,7 +838,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
return wacom_intuos_irq(wacom_wac, wcombo);
case TABLETPC:
-
case TABLETPC2FG:
return wacom_tpc_irq(wacom_wac, wcombo);
@@ -893,7 +884,7 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
/* fall through */
case TABLETPC:
input_dev_tpc(input_dev, wacom_wac);
- if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP)
+ if (wacom_wac->features->device_type != BTN_TOOL_PEN)
break; /* no need to process stylus stuff */
/* fall through */
@@ -964,11 +955,11 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ },
{ "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE },
{ "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE },
- { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL },
- { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC },
- { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC },
- { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC },
- { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC },
+ { "Wacom DTU1931", WACOM_PKGLEN_PENABLED, 37832, 30305, 511, 0, PL },
+ { "Wacom ISDv4 90", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC },
+ { "Wacom ISDv4 93", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC },
+ { "Wacom ISDv4 9A", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC },
+ { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC },
{ "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG },
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG },
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS },
diff --git a/src/2.6.28/wacom_wac.h b/src/2.6.28/wacom_wac.h
index 37e0eb3..39c2516 100755
--- a/src/2.6.28/wacom_wac.h
+++ b/src/2.6.28/wacom_wac.h
@@ -12,6 +12,15 @@
/* maximum packet length for USB devices */
#define WACOM_PKGLEN_MAX 32
+/* packet length for individual models */
+#define WACOM_PKGLEN_PENPRTN 7
+#define WACOM_PKGLEN_GRAPHIRE 8
+#define WACOM_PKGLEN_BBFUN 9
+#define WACOM_PKGLEN_INTUOS 10
+#define WACOM_PKGLEN_PENABLED 8
+#define WACOM_PKGLEN_TPC1FG 5
+#define WACOM_PKGLEN_TPC2FG 14
+
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
#define TOUCH_DEVICE_ID 0x03
diff --git a/src/util/10-linuxwacom.fdi b/src/util/10-linuxwacom.fdi
index f0b6ab2..2d131cf 100644
--- a/src/util/10-linuxwacom.fdi
+++ b/src/util/10-linuxwacom.fdi
@@ -14,7 +14,7 @@
</match>
</match>
<match key="info.capabilities" contains="serial">
- <match key="@info.parent:pnp.id" contains_outof="WACf001;WACf002;WACf003;WACf004;WACf005;WACf006;WACf007;WACf008;WACf009;WACf00a;WACf00b;WACf00c;FUJ02e5">
+ <match key="@info.parent:pnp.id" contains_outof="WACf;FUJ02e5;FUJ02e7">
<append key="info.capabilities" type="strlist">input</append>
<merge key="input.x11_driver" type="string">wacom</merge>
<merge key="input.x11_options.Type" type="string">stylus</merge>
@@ -22,7 +22,7 @@
<merge key="input.device" type="copy_property">serial.device</merge>
<append key="info.callouts.add" type="strlist">hal-setup-wacom</append>
<append key="wacom.types" type="strlist">eraser</append>
- <match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009">
+ <match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009;WACf008A;WACf00B;WACf00C;WACf00D;WACf00E;WACf010;FUJ02e7">
<!-- Serial tablets with touch capabilities -->
<append key="wacom.types" type="strlist">touch</append>
</match>
diff --git a/src/xdrv/wcmCommon.c b/src/xdrv/wcmCommon.c
index a67e229..f80eab1 100755
--- a/src/xdrv/wcmCommon.c
+++ b/src/xdrv/wcmCommon.c
@@ -32,16 +32,6 @@
*/
#define XF86_BUTTON1_BUG
-WacomDeviceClass* wcmDeviceClasses[] =
-{
-#ifdef WCM_ENABLE_LINUXINPUT
- &gWacomUSBDevice,
-#endif
- &gWacomISDV4Device,
- &gWacomSerialDevice,
- NULL
-};
-
extern int xf86WcmDevSwitchModeCall(LocalDevicePtr local, int mode);
extern void xf86WcmChangeScreen(LocalDevicePtr local, int value);
extern void xf86WcmTilt2R(WacomDeviceStatePtr ds);
@@ -736,7 +726,6 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds)
v4 = ty;
}
v5 = wheel;
-
DBG(6, priv->debugLevel, ErrorF("[%s] %s prox=%d\tx=%d"
"\ty=%d\tz=%d\tv3=%d\tv4=%d\tv5=%d\tid=%d"
"\tserial=%u\tbutton=%s\tbuttons=%d\n",
@@ -1018,49 +1007,6 @@ static int xf86WcmSuppress(WacomCommonPtr common, const WacomDeviceState* dsOrig
return returnV;
}
-/*****************************************************************************
- * xf86WcmOpen --
- ****************************************************************************/
-
-Bool xf86WcmOpen(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
- WacomCommonPtr common = priv->common;
- WacomDeviceClass** ppDevCls;
- char id[BUFFER_SIZE];
- float version;
-
- DBG(1, priv->debugLevel, ErrorF("opening %s\n", common->wcmDevice));
-
- local->fd = xf86OpenSerial(local->options);
- if (local->fd < 0)
- {
- ErrorF("Error opening %s : %s\n", common->wcmDevice,
- strerror(errno));
- return !Success;
- }
-
- /* Detect device class; default is serial device */
- for (ppDevCls=wcmDeviceClasses; *ppDevCls!=NULL; ++ppDevCls)
- {
- if ((*ppDevCls)->Detect(local))
- {
- common->wcmDevCls = *ppDevCls;
- break;
- }
- }
-
- /* Initialize the tablet */
- if(common->wcmDevCls->Init(local, id, &version) != Success ||
- xf86WcmInitTablet(local, id, version) != Success)
- {
- xf86CloseSerial(local->fd);
- local->fd = -1;
- return !Success;
- }
- return Success;
-}
-
/* reset raw data counters for filters */
static void resetSampleCounter(const WacomChannelPtr pChannel)
{
@@ -1196,8 +1142,12 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
if (pChannel->nSamples < common->wcmRawSample) ++pChannel->nSamples;
+/* gesture needs keystroke */
+#ifndef WCM_KEY_SENDING_SUPPORT
+ common->wcmGesture = 0;
+#endif
/* process second finger data if exists */
- if (ds.device_type == TOUCH_ID)
+ if ((ds.device_type == TOUCH_ID) && common->wcmTouch && common->wcmGesture)
{
WacomChannelPtr pOtherChannel;
WacomDeviceState dsOther;
@@ -1211,7 +1161,7 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
/* This is the only place to reset gesture mode
* once a gesture mode is entered */
- if (!ds.proximity && !dsOther.proximity && common->wcmGestureMode)
+ if (!ds.proximity && !dsOther.proximity)
{
common->wcmGestureMode = 0;
@@ -1223,12 +1173,11 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
{
/* don't move the cursor if in gesture mode
* wait for second finger data to process gestures */
- if (!channel && common->wcmTouch &&
- common->wcmGesture && common->wcmGestureMode)
+ if (!channel && common->wcmGestureMode)
goto ret;
/* process gesture when both touch and geature are enabled */
- if (channel && common->wcmTouch && common->wcmGesture)
+ if (channel)
{
xf86WcmFingerTapToClick(common);
goto ret;
diff --git a/src/xdrv/wcmConfig.c b/src/xdrv/wcmConfig.c
index 7613fdf..ec99bf8 100755
--- a/src/xdrv/wcmConfig.c
+++ b/src/xdrv/wcmConfig.c
@@ -20,9 +20,10 @@
#include "xf86Wacom.h"
#include "wcmFilter.h"
#ifdef WCM_XORG_XSERVER_1_4
- extern Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id);
- extern Bool wcmIsAValidType(char* device, LocalDevicePtr local);
+ extern Bool xf86WcmIsWacomDevice (char* fname);
+ extern Bool wcmIsAValidType(const char *type, unsigned long* keys);
extern int wcmIsDuplicate(char* device, LocalDevicePtr local);
+ extern int wcmDeviceTypeKeys(LocalDevicePtr local, unsigned long* keys);
#endif
/*****************************************************************************
@@ -443,13 +444,11 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
LocalDevicePtr fakeLocal = NULL;
WacomDevicePtr priv = NULL;
WacomCommonPtr common = NULL;
+ const char* type;
char *s, b[12];
int i, oldButton;
LocalDevicePtr localDevices;
-#ifdef WCM_XORG_XSERVER_1_4
char* device;
- struct input_id id;
-#endif
WacomToolPtr tool = NULL;
WacomToolAreaPtr area = NULL;
@@ -466,37 +465,42 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
*/
xf86CollectInputOptions(fakeLocal, default_options, NULL);
-#ifdef WCM_XORG_XSERVER_1_4
device = xf86CheckStrOption(fakeLocal->options, "Device", NULL);
fakeLocal->name = dev->identifier;
+ /* Type is mandatory */
+ type = xf86FindOptionValue(fakeLocal->options, "Type");
+
/* leave the undefined for auto-dev (if enabled) to deal with */
+#ifdef WCM_XORG_XSERVER_1_4
if(device)
{
- if (!xf86WcmIsWacomDevice(device, &id))
- goto SetupProc_fail;
+ unsigned long keys[NBITS(KEY_MAX)];
+ if (!xf86WcmIsWacomDevice(device))
+ goto SetupProc_fail;
- /* check if the type is valid for the device */
- if(!wcmIsAValidType(device, fakeLocal))
- goto SetupProc_fail;
+ /* initialize supported keys */
+ wcmDeviceTypeKeys(fakeLocal, keys);
- /* check if the device has been added */
+ /* check if the type is valid for the device */
+ if(!wcmIsAValidType(type, keys))
+ goto SetupProc_fail;
+
+ /* check if the device has been added */
if (wcmIsDuplicate(device, fakeLocal))
goto SetupProc_fail;
}
#endif /* WCM_XORG_XSERVER_1_4 */
- /* Type is mandatory */
- s = xf86FindOptionValue(fakeLocal->options, "Type");
- if (s && (xf86NameCmp(s, "stylus") == 0))
+ if (type && (xf86NameCmp(type, "stylus") == 0))
local = xf86WcmAllocateStylus();
- else if (s && (xf86NameCmp(s, "touch") == 0))
+ else if (type && (xf86NameCmp(type, "touch") == 0))
local = xf86WcmAllocateTouch();
- else if (s && (xf86NameCmp(s, "cursor") == 0))
+ else if (type && (xf86NameCmp(type, "cursor") == 0))
local = xf86WcmAllocateCursor();
- else if (s && (xf86NameCmp(s, "eraser") == 0))
+ else if (type && (xf86NameCmp(type, "eraser") == 0))
local = xf86WcmAllocateEraser();
- else if (s && (xf86NameCmp(s, "pad") == 0))
+ else if (type && (xf86NameCmp(type, "pad") == 0))
local = xf86WcmAllocatePad();
else
{
@@ -879,7 +883,8 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
xf86Msg(X_CONFIG, "%s: Touch is enabled \n", common->wcmDevice);
/* Touch gesture applies to the whole tablet */
- common->wcmGesture = xf86SetBoolOption(local->options, "Touch", common->wcmGestureDefault);
+ common->wcmGesture = xf86SetBoolOption(local->options, "Gesture",
+ common->wcmGestureDefault);
if ( common->wcmGesture )
xf86Msg(X_CONFIG, "%s: Touch gesture is enabled \n", common->wcmDevice);
diff --git a/src/xdrv/wcmISDV4.c b/src/xdrv/wcmISDV4.c
index da6d4ab..bf667db 100755
--- a/src/xdrv/wcmISDV4.c
+++ b/src/xdrv/wcmISDV4.c
@@ -102,7 +102,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data)
err = xf86WcmWrite(local->fd, WC_ISDV4_STOP, strlen(WC_ISDV4_STOP));
if (err == -1)
{
- ErrorF("Wacom xf86WcmWrite ISDV4_STOP error : %s\n", strerror(errno));
+ xf86Msg(X_WARNING, "Wacom xf86WcmWrite ISDV4_STOP error : %s\n",
+ strerror(errno));
return !Success;
}
@@ -113,13 +114,13 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data)
/* Send query command to the tablet */
if (!xf86WcmWriteWait(local->fd, query))
{
- ErrorF("Wacom unable to xf86WcmWrite request %s ISDV4 query command "
- "after %d tries\n", query, MAXTRY);
+ xf86Msg(X_WARNING, "Wacom unable to xf86WcmWrite request %s ISDV4"
+ " query command after %d tries\n", query, MAXTRY);
return !Success;
}
/* Read the control data */
- if (!xf86WcmWaitForTablet(local->fd, data, 11))
+ if (!xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL))
{
/* Try 19200 if it is not a touch query */
if (common->wcmISDV4Speed != 19200 && strcmp(query, WC_ISDV4_TOUCH_QUERY))
@@ -131,8 +132,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data)
}
else
{
- ErrorF("Wacom unable to read ISDV4 %s data "
- "after %d tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed);
+ xf86Msg(X_WARNING, "Wacom unable to read ISDV4 %s data after %d"
+ " tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed);
return !Success;
}
}
@@ -150,11 +151,12 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data)
}
else
{
- /* Reread the control data since with some vendors it fails the first time */
- xf86WcmWaitForTablet(local->fd, data, 11);
+ /* Reread the control data since it may fail the first time */
+ xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL);
if ( !(data[0] & 0x40) )
{
- ErrorF("Wacom ISDV4 control data (%x) error in %s query\n", data[0], query);
+ xf86Msg(X_WARNING, "Wacom ISDV4 control data (%x) error in %s"
+ " query\n", data[0], query);
return !Success;
}
}
@@ -171,11 +173,8 @@ static void isdv4InitISDV4(WacomCommonPtr common, const char* id, float version)
{
/* set parameters */
common->wcmProtocolLevel = 4;
- common->wcmPktLength = WACOM_PKGLEN_TPC; /* length of a packet
- * device packets are 9 bytes
- * resistive touch is 5 bytes
- * capacitive touch is 7 bytes
- */
+ /* length of a packet */
+ common->wcmPktLength = WACOM_PKGLEN_TPC;
/* digitizer X resolution in points/inch */
common->wcmResolX = 2540;
@@ -198,12 +197,13 @@ static int isdv4GetRanges(LocalDevicePtr local)
char data[BUFFER_SIZE];
WacomDevicePtr priv = (WacomDevicePtr)local->private;
WacomCommonPtr common = priv->common;
- char * s;
+ int ret = Success;
DBG(2, priv->debugLevel, ErrorF("getting ISDV4 Ranges\n"));
/* Send query command to the tablet */
- if (isdv4Query(local, WC_ISDV4_QUERY, data) == Success)
+ ret = isdv4Query(local, WC_ISDV4_QUERY, data);
+ if (ret == Success)
{
/* transducer data */
common->wcmMaxZ = ( data[5] | ((data[6] & 0x07) << 7) );
@@ -219,77 +219,117 @@ static int isdv4GetRanges(LocalDevicePtr local)
}
common->wcmVersion = ( data[10] | (data[9] << 7) );
+
+ /* default to no pen 2FGT if size is undefined */
+ if (!common->wcmMaxX || !common->wcmMaxY)
+ common->tablet_id = 0xe2;
+
+ DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges Pen speed=%d "
+ "maxX=%d maxY=%d maxZ=%d TouchresX=%d TouchresY=%d \n",
+ common->wcmISDV4Speed, common->wcmMaxX, common->wcmMaxY,
+ common->wcmMaxZ, common->wcmResolX, common->wcmResolY));
}
- else
- return !Success;
- if (common->wcmISDV4Speed != 19200)
+ /* Touch might be supported. Send a touch query command */
+ common->wcmISDV4Speed = 38400;
+ if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success)
{
- /* default to 0x93 (resistive touch) */
- common->wcmPktLength = WACOM_PKGLEN_TOUCH0;
- common->tablet_id = 0x93;
-
- /* Touch might be supported. Send a touch query command */
- if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success)
+ switch(data[2] & 0x07)
{
- /* (data[2] & 0x07) == 0 is for resistive touch */
- if (!(data[2] & 0x07) && data[1])
- {
- common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]);
- }
+ case 0x00: /* resistive touch & pen */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH0;
+ common->tablet_id = 0x93;
+ break;
+ case 0x01: /* capacitive touch & pen */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH;
+ common->tablet_id = 0x9a;
+ break;
+ case 0x02: /* resistive touch */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH0;
+ common->tablet_id = 0x93;
+ break;
+ case 0x03: /* capacitive touch */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH;
+ common->tablet_id = 0x9f;
+ break;
+ case 0x04: /* capacitive touch */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH;
+ common->tablet_id = 0x9f;
+ break;
+ case 0x05:
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH2FG;
+ /* a penabled */
+ if (common->tablet_id == 0x90)
+ common->tablet_id = 0xe3;
+ break;
+ }
- if ((data[0] & 0x41) && (data[2] & 0x07))
- {
- /* tablet model */
- switch (data[2] & 0x07)
+ switch(data[0] & 0x3f)
+ {
+ /* single finger touch */
+ case 0x01:
+ if ((common->tablet_id != 0x93) &&
+ (common->tablet_id != 0x9A) &&
+ (common->tablet_id != 0x9F))
{
- case 0x01:
- common->wcmPktLength = WACOM_PKGLEN_TOUCH;
- common->tablet_id = 0x9A;
- break;
- case 0x02:
- case 0x04:
- common->wcmPktLength = WACOM_PKGLEN_TOUCH;
- common->tablet_id = 0x9F;
- break;
+ xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)"
+ " mismatch with data id (0x01) \n",
+ local->name, common->tablet_id);
+ return ret;
}
-
- /* touch logical size for tablet PC with touch */
- if (data[1])
+ break;
+ /* 2FGT */
+ case 0x03:
+ if ((common->tablet_id != 0xE2) &&
+ (common->tablet_id != 0xE3))
{
- common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]);
+ xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)"
+ " mismatch with data id (0x03) \n",
+ local->name, common->tablet_id);
+ return ret;
}
+ break;
+ }
- /* Max capacity */
- common->wcmMaxCapacity = (int)(1 << data[7]);
-
- if (common->wcmMaxCapacity)
- {
- common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 *
- ((data[3] << 9) | (data[4] << 2) | ((data[2] & 0x60) >> 5)));
- common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 *
- ((data[5] << 9) | (data[6] << 2) | ((data[2] & 0x18) >> 3)));
- }
- }
+ /* don't overwrite the default */
+ if ((data[2] & 0x78) | data[3] | data[4] | data[5] | data[6])
+ {
+ common->wcmMaxTouchX = ((data[3] << 9) |
+ (data[4] << 2) | ((data[2] & 0x60) >> 5));
+ common->wcmMaxTouchY = ((data[5] << 9) |
+ (data[6] << 2) | ((data[2] & 0x18) >> 3));
}
+ else if (data[1])
+ common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]);
- s = xf86FindOptionValue(local->options, "Touch");
- if ( !s || (strstr(s, "on")) ) /* touch option is on */
+ if (data[1])
{
- common->wcmTouch = 1;
+ common->wcmTouchResolX = common->wcmTouchResolY = 10;
+ common->wcmTouchDefault = 1;
}
+ else
+ common->wcmTouchDefault = 0;
- /* TouchDefault was off for all devices
- * defaults to enable when it is a touch device
- */
- common->wcmTouchDefault = 1;
- }
+ /* updated touch info */
+ common->wcmTouch = xf86SetBoolOption(local->options, "Touch",
+ common->wcmTouchDefault);
- DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges speed=%d maxX=%d maxY=%d "
- "maxZ=%d TouchresX=%d TouchresY=%d \n", common->wcmISDV4Speed,
- common->wcmMaxX, common->wcmMaxY, common->wcmMaxZ,
- common->wcmResolX, common->wcmResolY));
- return Success;
+ if ((common->tablet_id == 0xE2) ||
+ (common->tablet_id == 0xE3))
+ common->wcmGestureDefault = 1;
+
+ common->wcmGesture = xf86SetBoolOption(local->options, "Gesture",
+ common->wcmGestureDefault);
+
+ common->wcmVersion = ( data[10] | (data[9] << 7) );
+ ret = Success;
+
+ DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges touch speed=%d "
+ "maxX=%d maxY=%d TouchresX=%d TouchresY=%d \n",
+ common->wcmISDV4Speed, common->wcmMaxTouchX, common->wcmMaxTouchY,
+ common->wcmTouchResolX, common->wcmTouchResolY));
+ }
+ return ret;
}
static int isdv4StartTablet(LocalDevicePtr local)
@@ -313,64 +353,28 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
WacomDevicePtr priv = (WacomDevicePtr)local->private;
WacomCommonPtr common = priv->common;
WacomDeviceState* last = &common->wcmChannel[0].valid.state;
+ WacomDeviceState* lastTemp = &common->wcmChannel[1].valid.state;
WacomDeviceState* ds;
int n, cur_type, channel = 0;
- static int touchInProx;
DBG(10, common->debugLevel, ErrorF("isdv4Parse \n"));
- channel = 0;
/* determine the type of message (touch or stylus)*/
- if (data[0] & 0x18) /* not a pen */
+ if (data[0] & 0x10) /* a touch data */
{
- if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && last->proximity ) ||
- !common->wcmTouch )
+ if ((last->device_id != TOUCH_DEVICE_ID && last->device_id &&
+ last->proximity) || !common->wcmTouch)
{
- if ((data[0] & 0x10) && (!(data[0] & 0x01))) /* a touch out-prox data */
- touchInProx = 0;
- else
- touchInProx = 1;
-
/* ignore touch event */
return common->wcmPktLength;
}
- else
- {
- if (data[0] & 0x10) /* a touch data */
- {
- if (!touchInProx)
- {
- channel = 1;
- }
- else if (!(data[0] & 0x01)) /* touch out-prox */
- {
- touchInProx = 0;
- channel = 0;
- }
- else
- {
- /* ignore touch event */
- return common->wcmPktLength;
- }
- }
- else
- {
- /* ignore touch event */
- return common->wcmPktLength;
- }
- }
}
else
{
/* touch was in control */
- if (common->wcmChannel[1].valid.state.proximity)
- {
+ if (last->proximity && last->device_id == TOUCH_DEVICE_ID)
/* let touch go */
- xf86WcmSoftOut(common, 1);
- return 0;
- }
- common->wcmPktLength = WACOM_PKGLEN_TPC;
- channel = 0;
+ xf86WcmSoftOut(common, channel);
}
if (common->buffer + common->bufpos - data < common->wcmPktLength)
@@ -379,25 +383,18 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
return common->wcmPktLength;
}
- if ((n = xf86WcmSerialValidate(common,data)) > 0)
+ /* Coordinate data bit check */
+ if (data[0] & 0x40) /* control data */
+ return common->wcmPktLength;
+ else if ((n = xf86WcmSerialValidate(common,data)) > 0)
return n;
- else
- {
- /* Coordinate data bit check */
- if (data[0] & 0x40) /* control data */
- return common->wcmPktLength;
- }
/* pick up where we left off, minus relative values */
ds = &common->wcmChannel[channel].work;
RESET_RELATIVE(*ds);
- if (common->wcmPktLength == WACOM_PKGLEN_TOUCH0 ||
- common->wcmPktLength == WACOM_PKGLEN_TOUCH) /* a touch */
+ if (common->wcmPktLength != WACOM_PKGLEN_TPC) /* a touch */
{
- /* touch without capacity has 5 bytes of data
- * touch with capacity has 7 bytes of data
- */
ds->x = (((int)data[1]) << 7) | ((int)data[2]);
ds->y = (((int)data[3]) << 7) | ((int)data[4]);
if (common->wcmPktLength == WACOM_PKGLEN_TOUCH)
@@ -407,6 +404,27 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
ds->buttons = ds->proximity = data[0] & 0x01;
ds->device_type = TOUCH_ID;
ds->device_id = TOUCH_DEVICE_ID;
+
+ if (common->wcmPktLength == WACOM_PKGLEN_TOUCH2FG)
+ {
+ if ((data[0] & 0x02) || (!(data[0] & 0x02) &&
+ lastTemp->proximity))
+ {
+ /* Got 2FGT. Send the first one if received */
+ if (ds->proximity || (!ds->proximity &&
+ last->proximity))
+ xf86WcmEvent(common, channel, ds);
+
+ channel = 1;
+ ds = &common->wcmChannel[channel].work;
+ RESET_RELATIVE(*ds);
+ ds->x = (((int)data[7]) << 7) | ((int)data[8]);
+ ds->y = (((int)data[9]) << 7) | ((int)data[10]);
+ ds->device_type = TOUCH_ID;
+ ds->device_id = TOUCH_DEVICE_ID;
+ ds->proximity = data[0] & 0x02;
+ }
+ }
DBG(8, priv->debugLevel, ErrorF("isdv4Parse MultiTouch "
"%s proximity \n", ds->proximity ? "in" : "out of"));
}
diff --git a/src/xdrv/wcmSerial.c b/src/xdrv/wcmSerial.c
index 9b9a1b7..a7fc2b3 100755
--- a/src/xdrv/wcmSerial.c
+++ b/src/xdrv/wcmSerial.c
@@ -1307,7 +1307,7 @@ int xf86WcmSerialValidate(WacomCommonPtr common, const unsigned char* data)
{
bad = 1;
if (i!=0 && (data[i] & HEADER_BIT)) {
- ErrorF("xf86WcmSerialValidate: bad magic at %d "
+ xf86Msg(X_WARNING, "xf86WcmSerialValidate: bad magic at %d "
"v=%x l=%d\n", i, data[i], common->wcmPktLength);
return i;
}
diff --git a/src/xdrv/wcmTouchFilter.c b/src/xdrv/wcmTouchFilter.c
index 23971a3..7e8d52d 100644
--- a/src/xdrv/wcmTouchFilter.c
+++ b/src/xdrv/wcmTouchFilter.c
@@ -17,9 +17,10 @@
*/
#include "xf86Wacom.h"
+#ifdef WCM_KEY_SENDING_SUPPORT
#include <math.h>
-// Defines for 2FC Gesture
+/* Defines for 2FC Gesture */
#define WACOM_DIST_IN_POINT 300
#define WACOM_APART_IN_POINT 350
#define WACOM_MOTION_IN_POINT 50
@@ -34,7 +35,7 @@
#define GESTURE_ZOOM_MODE 4
-// Defines for Tap Add-a-Finger to Click
+/* Defines for Tap Add-a-Finger to Click */
#define WACOM_TAP_TIME_IN_MS 150
extern void xf86WcmRotateCoordinates(LocalDevicePtr local, int x, int y);
@@ -389,4 +390,4 @@ static void xf86WcmFingerZoom(WacomDevicePtr priv)
common->wcmGestureState[1] = ds[1];
}
}
-
+#endif /* WCM_KEY_SENDING_SUPPORT */
diff --git a/src/xdrv/wcmUSB.c b/src/xdrv/wcmUSB.c
index 2fc5f0c..bfb4c44 100755
--- a/src/xdrv/wcmUSB.c
+++ b/src/xdrv/wcmUSB.c
@@ -375,7 +375,7 @@ static Bool usbDetect(LocalDevicePtr local)
if (err < 0)
{
- ErrorF("usbDetect: can not ioctl version\n");
+ xf86Msg(X_WARNING, "usbDetect: can not ioctl version\n");
return 0;
}
#ifdef EVIOCGRAB
diff --git a/src/xdrv/wcmValidateDevice.c b/src/xdrv/wcmValidateDevice.c
index c079e73..a265286 100755
--- a/src/xdrv/wcmValidateDevice.c
+++ b/src/xdrv/wcmValidateDevice.c
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#endif
+ #include <linux/serial.h>
/*****************************************************************************
* xf86WcmCheckSource - Check if there is another source defined this device
@@ -151,42 +152,106 @@ static struct
{ "pad", BTN_TOOL_FINGER }
};
-static Bool checkValidType(char* type, unsigned long* keys)
+/* validate tool type for device/product */
+Bool wcmIsAValidType(const char* type, unsigned long* keys)
{
int j, ret = FALSE;
+ErrorF("wcmIsAValidType type %s \n", type);
+ if (!type)
+ return ret;
/* walkthrough all types */
for (j = 0; j < sizeof (wcmType) / sizeof (wcmType [0]); j++)
{
if (!strcmp(wcmType[j].type, type))
if (ISBITSET (keys, wcmType[j].tool))
+ {
ret = TRUE;
+ break;
+ }
}
+ErrorF("wcmIsAValidType found type %s %d \n", type, ret);
return ret;
}
-/* validate tool type for device/product */
-Bool wcmIsAValidType(char* device, LocalDevicePtr local)
+/* Choose valid types according to device ID */
+int wcmDeviceTypeKeys(LocalDevicePtr local, unsigned long* keys)
{
- Bool ret = FALSE;
- int fd = -1;
- unsigned long keys[NBITS(KEY_MAX)];
- char* type = xf86FindOptionValue(local->options, "Type");
+ int ret = 1, i, fd = -1;
+ unsigned int id = 0;
+ char* device, *stopstring;
+ char* str = strstr(local->name, "WACf");
+ struct serial_struct tmp;
+
+ device = xf86SetStrOption(local->options, "Device", NULL);
SYSCALL(fd = open(device, O_RDONLY));
if (fd < 0)
- return FALSE;
-
- /* test if the tool is defined in the kernel */
- if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
{
- xf86Msg(X_ERROR, "WACOM: wcmIsAValidType unable to ioctl key bits.\n");
- return FALSE;
+ xf86Msg(X_WARNING, "%s: failed to open %s in "
+ "wcmDeviceTypeKeys.\n", local->name, device);
+ return 0;
}
- close(fd);
- ret = checkValidType(type, keys);
+ /* we have tried memset. it doesn't work */
+ for (i=0; i<NBITS(KEY_MAX); i++)
+ keys[i] = 0;
+
+ /* serial ISDV4 devices */
+ if (ioctl(fd, TIOCGSERIAL, &tmp) == 0)
+ {
+ if (str) /* id in name */
+ {
+ str = str + 4;
+ if (str)
+ id = (int)strtol(str, &stopstring, 16);
+
+ }
+ else /* id in file /sys/class/tty/%str/device/id */
+ {
+ FILE *file;
+ char sysfs_id[256];
+ str = strstr(device, "ttyS");
+ snprintf(sysfs_id, sizeof(sysfs_id),
+ "/sys/class/tty/%s/device/id", str);
+ file = fopen(sysfs_id, "r");
+
+ if (file)
+ {
+ /* make sure we fall to default */
+ if (fscanf(file, "WACf%x\n", &id) <= 0)
+ id = 0;
+ }
+ }
+ /* default to penabled */
+ keys[LONG(BTN_TOOL_PEN)] |= BIT(BTN_TOOL_PEN);
+ keys[LONG(BTN_TOOL_RUBBER)] |= BIT(BTN_TOOL_RUBBER);
+ /* id < 0x008 are only penabled */
+ if (id > 0x007)
+ {
+ keys[LONG(BTN_TOOL_DOUBLETAP)] |= BIT(BTN_TOOL_DOUBLETAP);
+ }
+
+ /* no pen 2FGT */
+ if (id == 0x010)
+ {
+ keys[LONG(BTN_TOOL_PEN)] &= ~BIT(BTN_TOOL_PEN);
+ keys[LONG(BTN_TOOL_RUBBER)] &= ~BIT(BTN_TOOL_RUBBER);
+ }
+ }
+ else /* USB devices */
+ {
+ /* test if the tool is defined in the kernel */
+ if (ioctl(fd, EVIOCGBIT(EV_KEY, (sizeof(unsigned long)
+ * NBITS(KEY_MAX))), keys) < 0)
+ {
+ xf86Msg(X_ERROR, "%s: wcmDeviceTypeKeys unable to "
+ "ioctl USB key bits.\n", local->name);
+ ret = 0;
+ }
+ }
+ close(fd);
return ret;
}
#endif /* WCM_XORG_XSERVER_1_4 */
diff --git a/src/xdrv/xf86Wacom.c b/src/xdrv/xf86Wacom.c
index 173fa8f..38c382d 100755
--- a/src/xdrv/xf86Wacom.c
+++ b/src/xdrv/xf86Wacom.c
@@ -85,11 +85,12 @@
* 2009-10-15 47-pc0.8.4-4 - added calibration-only wacomcpl
* 2009-10-19 47-pc0.8.5 - Added support for TPC (0xE2, 0xE3 & 0x9F)
* 2009-10-31 47-pc0.8.5-1 - Avoid duplicated devices for Xorg 1.4 and later
- * 2009-11-6 47-pc0.8.5-2 - Validate tool type associated with device
- * 2009-11-6 47-pc0.8.5-4 - Allow multiple tools to be defined for one type
+ * 2009-11-06 47-pc0.8.5-2 - Validate tool type associated with device
+ * 2009-11-11 47-pc0.8.5-4 - Allow multiple tools to be defined for one type
+ * 2009-11-24 47-pc0.8.5-5 - Support hotplugging for serial ISDV4
*/
-static const char identification[] = "$Identification: 47-0.8.5-4 $";
+static const char identification[] = "$Identification: 47-0.8.5-5 $";
/****************************************************************************/
@@ -102,6 +103,16 @@ static const char identification[] = "$Identification: 47-0.8.5-4 $";
#endif
#endif
+WacomDeviceClass* wcmDeviceClasses[] =
+{
+#ifdef WCM_ENABLE_LINUXINPUT
+ &gWacomUSBDevice,
+#endif
+ &gWacomISDV4Device,
+ &gWacomSerialDevice,
+ NULL
+};
+
static int xf86WcmDevOpen(DeviceIntPtr pWcm);
static void xf86WcmDevReadInput(LocalDevicePtr local);
static void xf86WcmDevControlProc(DeviceIntPtr device, PtrCtrl* ctrl);
@@ -554,18 +565,24 @@ static int xf86WcmRegisterX11Devices (LocalDevicePtr local)
}
#ifdef WCM_XORG_XSERVER_1_4
-Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id)
+Bool xf86WcmIsWacomDevice (char* fname)
{
int fd = -1;
+ struct input_id id;
SYSCALL(fd = open(fname, O_RDONLY));
if (fd < 0)
return FALSE;
- ioctl(fd, EVIOCGID, id);
- close(fd);
+ if (ioctl(fd, EVIOCGID, &id) < 0)
+ {
+ SYSCALL(close(fd));
+ return FALSE;
+ }
- if (id->vendor == 0x056a)
+ SYSCALL(close(fd));
+
+ if (id.vendor == 0x056a)
return TRUE;
else
return FALSE;
@@ -615,6 +632,49 @@ char *xf86WcmEventAutoDevProbe (LocalDevicePtr local)
#endif
/*****************************************************************************
+ * xf86WcmOpen --
+ ****************************************************************************/
+
+Bool xf86WcmOpen(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ WacomDeviceClass** ppDevCls;
+ char id[BUFFER_SIZE];
+ float version;
+
+ DBG(1, priv->debugLevel, ErrorF("opening %s\n", common->wcmDevice));
+
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd < 0)
+ {
+ ErrorF("Error opening %s : %s\n", common->wcmDevice,
+ strerror(errno));
+ return !Success;
+ }
+
+ /* Detect device class; default is serial device */
+ for (ppDevCls=wcmDeviceClasses; *ppDevCls!=NULL; ++ppDevCls)
+ {
+ if ((*ppDevCls)->Detect(local))
+ {
+ common->wcmDevCls = *ppDevCls;
+ break;
+ }
+ }
+
+ /* Initialize the tablet */
+ if(common->wcmDevCls->Init(local, id, &version) != Success ||
+ xf86WcmInitTablet(local, id, version) != Success)
+ {
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return !Success;
+ }
+ return Success;
+}
+
+/*****************************************************************************
* xf86WcmDevOpen --
* Open the physical device and init information structs.
****************************************************************************/
@@ -777,14 +837,18 @@ void xf86WcmReadPacket(LocalDevicePtr local)
*/
if (common->wcmForceDevice == DEVICE_ISDV4 && common->wcmDevCls != &gWacomUSBDevice)
{
- common->wcmPktLength = WACOM_PKGLEN_TPC;
data = common->buffer;
- if ( data[0] & 0x18 )
+ if (data[0])
+ common->wcmPktLength = WACOM_PKGLEN_TPC;
+
+ if ( data[0] & 0x10 )
{
- if (common->wcmMaxCapacity)
+ /* set touch PktLength */
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH0;
+ if ((common->tablet_id == 0x9a) || (common->tablet_id == 0x9f))
common->wcmPktLength = WACOM_PKGLEN_TOUCH;
- else
- common->wcmPktLength = WACOM_PKGLEN_TOUCH0;
+ if ((common->tablet_id == 0xe2) || (common->tablet_id == 0xe3))
+ common->wcmPktLength = WACOM_PKGLEN_TOUCH2FG;
}
}
diff --git a/src/xdrv/xf86WacomDefs.h b/src/xdrv/xf86WacomDefs.h
index b155b24..1a93749 100755
--- a/src/xdrv/xf86WacomDefs.h
+++ b/src/xdrv/xf86WacomDefs.h
@@ -56,6 +56,8 @@
#define WACOM_PKGLEN_TOUCH 7
#define WACOM_PKGLEN_GRAPHIRE 8
#define WACOM_PKGLEN_TPC 9
+#define WACOM_PKGLEN_TPCCTL 11
+#define WACOM_PKGLEN_TOUCH2FG 13
/* defines to discriminate second side button and the eraser */
#define ERASER_PROX 4