Input: wacom - 3rd gen Bamboo P&Touch packet support
authorChris Bagwell <chris@cnpbagwell.com>
Thu, 27 Oct 2011 05:34:21 +0000 (22:34 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 27 Oct 2011 05:36:10 +0000 (22:36 -0700)
3rd generation Bamboo Pen and Touch tablets reuse the older
stylus packet but add an extra fixed zero pad byte to end.

The touch packets are quite different since it supports tracking
of up to 16 touches. The packet is 64-byte fixed size but contains
up to 15 smaller messages indicating data for a single touch or
for tablet button presses.

Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Acked-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h

index d1ced32..164bb55 100644 (file)
@@ -836,6 +836,64 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
        return 0;
 }
 
+static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
+{
+       struct input_dev *input = wacom->input;
+       int slot_id = data[0] - 2;  /* data[0] is between 2 and 17 */
+       bool touch = data[1] & 0x80;
+
+       touch = touch && !wacom->shared->stylus_in_proximity;
+
+       input_mt_slot(input, slot_id);
+       input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
+
+       if (touch) {
+               int x = (data[2] << 4) | (data[4] >> 4);
+               int y = (data[3] << 4) | (data[4] & 0x0f);
+               int w = data[6];
+
+               input_report_abs(input, ABS_MT_POSITION_X, x);
+               input_report_abs(input, ABS_MT_POSITION_Y, y);
+               input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
+       }
+}
+
+static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
+{
+       struct input_dev *input = wacom->input;
+
+       input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
+       input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
+       input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
+       input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
+}
+
+static int wacom_bpt3_touch(struct wacom_wac *wacom)
+{
+       struct input_dev *input = wacom->input;
+       unsigned char *data = wacom->data;
+       int count = data[1] & 0x03;
+       int i;
+
+       /* data has up to 7 fixed sized 8-byte messages starting at data[2] */
+       for (i = 0; i < count; i++) {
+               int offset = (8 * i) + 2;
+               int msg_id = data[offset];
+
+               if (msg_id >= 2 && msg_id <= 17)
+                       wacom_bpt3_touch_msg(wacom, data + offset);
+               else if (msg_id == 128)
+                       wacom_bpt3_button_msg(wacom, data + offset);
+
+       }
+
+       input_mt_report_pointer_emulation(input, true);
+
+       input_sync(input);
+
+       return 0;
+}
+
 static int wacom_bpt_pen(struct wacom_wac *wacom)
 {
        struct input_dev *input = wacom->input;
@@ -906,7 +964,9 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
 {
        if (len == WACOM_PKGLEN_BBTOUCH)
                return wacom_bpt_touch(wacom);
-       else if (len == WACOM_PKGLEN_BBFUN)
+       else if (len == WACOM_PKGLEN_BBTOUCH3)
+               return wacom_bpt3_touch(wacom);
+       else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN)
                return wacom_bpt_pen(wacom);
 
        return 0;
@@ -1025,9 +1085,9 @@ void wacom_setup_device_quirks(struct wacom_features *features)
            features->type == BAMBOO_PT)
                features->quirks |= WACOM_QUIRK_MULTI_INPUT;
 
-       /* quirks for bamboo touch */
+       /* quirk for bamboo touch with 2 low res touches */
        if (features->type == BAMBOO_PT &&
-           features->device_type == BTN_TOOL_DOUBLETAP) {
+           features->pktlen == WACOM_PKGLEN_BBTOUCH) {
                features->x_max <<= 5;
                features->y_max <<= 5;
                features->x_fuzz <<= 5;
@@ -1213,7 +1273,21 @@ 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, 2);
+                       if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
+                               __set_bit(BTN_TOOL_TRIPLETAP,
+                                         input_dev->keybit);
+                               __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,
                                             0, features->x_max,
                                             features->x_fuzz, 0);
@@ -1479,6 +1553,15 @@ static const struct wacom_features wacom_features_0xDA =
 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 };
+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 };
+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 };
 static const struct wacom_features wacom_features_0x6004 =
        { "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1574,6 +1657,9 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD8) },
        { USB_DEVICE_WACOM(0xDA) },
        { USB_DEVICE_WACOM(0xDB) },
+       { USB_DEVICE_WACOM(0xDD) },
+       { USB_DEVICE_WACOM(0xDE) },
+       { USB_DEVICE_WACOM(0xDF) },
        { USB_DEVICE_WACOM(0xF0) },
        { USB_DEVICE_WACOM(0xCC) },
        { USB_DEVICE_WACOM(0x90) },
index af94e6d..27f1d1c 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/types.h>
 
 /* maximum packet length for USB devices */
-#define WACOM_PKGLEN_MAX       32
+#define WACOM_PKGLEN_MAX       64
 
 /* packet length for individual models */
 #define WACOM_PKGLEN_PENPRTN    7
@@ -23,6 +23,7 @@
 #define WACOM_PKGLEN_TPC2FG    14
 #define WACOM_PKGLEN_BBTOUCH   20
 #define WACOM_PKGLEN_BBTOUCH3  64
+#define WACOM_PKGLEN_BBPEN     10
 
 /* device IDs */
 #define STYLUS_DEVICE_ID       0x02