Input: hanwang - add support for Art Master II tablet
authorweixing <weixing@hanwang.com.cn>
Fri, 13 Jul 2012 07:08:42 +0000 (00:08 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 13 Jul 2012 07:14:27 +0000 (00:14 -0700)
This change adds support for old Hanwang Art master II tablet

Signed-off-by: weixing <weixing@hanwang.com.cn>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/tablet/hanwang.c

index b2db3cfe308468c506b791dae639d47a0312d051..5cc04124995c4947d1d9b384f26159092805473b 100644 (file)
@@ -63,6 +63,7 @@ MODULE_LICENSE(DRIVER_LICENSE);
 enum hanwang_tablet_type {
        HANWANG_ART_MASTER_III,
        HANWANG_ART_MASTER_HD,
+       HANWANG_ART_MASTER_II,
 };
 
 struct hanwang {
@@ -99,6 +100,8 @@ static const struct hanwang_features features_array[] = {
          ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 },
        { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD,
          ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 },
+       { 0x8503, "Hanwang Art Master II", HANWANG_ART_MASTER_II,
+         ART_MASTER_PKGLEN_MAX, 0x27de, 0x1cfe, 0x3f, 0x7f, 1024 },
 };
 
 static const int hw_eventtypes[] = {
@@ -127,14 +130,30 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
        struct usb_device *dev = hanwang->usbdev;
        enum hanwang_tablet_type type = hanwang->features->type;
        int i;
-       u16 x, y, p;
+       u16 p;
+
+       if (type == HANWANG_ART_MASTER_II) {
+               hanwang->current_tool = BTN_TOOL_PEN;
+               hanwang->current_id = STYLUS_DEVICE_ID;
+       }
 
        switch (data[0]) {
        case 0x02:      /* data packet */
                switch (data[1]) {
                case 0x80:      /* tool prox out */
-                       hanwang->current_id = 0;
-                       input_report_key(input_dev, hanwang->current_tool, 0);
+                       if (type != HANWANG_ART_MASTER_II) {
+                               hanwang->current_id = 0;
+                               input_report_key(input_dev,
+                                                hanwang->current_tool, 0);
+                       }
+                       break;
+
+               case 0x00:      /* artmaster ii pen leave */
+                       if (type == HANWANG_ART_MASTER_II) {
+                               hanwang->current_id = 0;
+                               input_report_key(input_dev,
+                                                hanwang->current_tool, 0);
+                       }
                        break;
 
                case 0xc2:      /* first time tool prox in */
@@ -154,15 +173,12 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
                        default:
                                hanwang->current_id = 0;
                                dev_dbg(&dev->dev,
-                                       "unknown tablet tool %02x ", data[0]);
+                                       "unknown tablet tool %02x\n", data[0]);
                                break;
                        }
                        break;
 
                default:        /* tool data packet */
-                       x = (data[2] << 8) | data[3];
-                       y = (data[4] << 8) | data[5];
-
                        switch (type) {
                        case HANWANG_ART_MASTER_III:
                                p = (data[6] << 3) |
@@ -171,6 +187,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
                                break;
 
                        case HANWANG_ART_MASTER_HD:
+                       case HANWANG_ART_MASTER_II:
                                p = (data[7] >> 6) | (data[6] << 2);
                                break;
 
@@ -180,17 +197,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
                        }
 
                        input_report_abs(input_dev, ABS_X,
-                                               le16_to_cpup((__le16 *)&x));
+                                        be16_to_cpup((__be16 *)&data[2]));
                        input_report_abs(input_dev, ABS_Y,
-                                               le16_to_cpup((__le16 *)&y));
-                       input_report_abs(input_dev, ABS_PRESSURE,
-                                               le16_to_cpup((__le16 *)&p));
+                                        be16_to_cpup((__be16 *)&data[4]));
+                       input_report_abs(input_dev, ABS_PRESSURE, p);
                        input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f);
                        input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f);
                        input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02);
-                       input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
+
+                       if (type != HANWANG_ART_MASTER_II)
+                               input_report_key(input_dev, BTN_STYLUS2,
+                                                data[1] & 0x04);
+                       else
+                               input_report_key(input_dev, BTN_TOOL_PEN, 1);
+
                        break;
                }
+
                input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
                input_event(input_dev, EV_MSC, MSC_SERIAL,
                                hanwang->features->pid);
@@ -202,8 +225,8 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
 
                switch (type) {
                case HANWANG_ART_MASTER_III:
-                       input_report_key(input_dev, BTN_TOOL_FINGER, data[1] ||
-                                                       data[2] || data[3]);
+                       input_report_key(input_dev, BTN_TOOL_FINGER,
+                                        data[1] || data[2] || data[3]);
                        input_report_abs(input_dev, ABS_WHEEL, data[1]);
                        input_report_key(input_dev, BTN_0, data[2]);
                        for (i = 0; i < 8; i++)
@@ -227,6 +250,10 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
                                         BTN_5 + i, data[6] & (1 << i));
                        }
                        break;
+
+               case HANWANG_ART_MASTER_II:
+                       dev_dbg(&dev->dev, "error packet  %02x\n", data[0]);
+                       return;
                }
 
                input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
@@ -234,7 +261,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
                break;
 
        default:
-               dev_dbg(&dev->dev, "error packet  %02x ", data[0]);
+               dev_dbg(&dev->dev, "error packet  %02x\n", data[0]);
                break;
        }