Commit 8a90c034 authored by weixing's avatar weixing Committed by Dmitry Torokhov

Input: hanwang - add support for Art Master II tablet

This change adds support for old Hanwang Art master II tablet
Signed-off-by: default avatarweixing <weixing@hanwang.com.cn>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 8314f532
...@@ -63,6 +63,7 @@ MODULE_LICENSE(DRIVER_LICENSE); ...@@ -63,6 +63,7 @@ MODULE_LICENSE(DRIVER_LICENSE);
enum hanwang_tablet_type { enum hanwang_tablet_type {
HANWANG_ART_MASTER_III, HANWANG_ART_MASTER_III,
HANWANG_ART_MASTER_HD, HANWANG_ART_MASTER_HD,
HANWANG_ART_MASTER_II,
}; };
struct hanwang { struct hanwang {
...@@ -99,6 +100,8 @@ static const struct hanwang_features features_array[] = { ...@@ -99,6 +100,8 @@ static const struct hanwang_features features_array[] = {
ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 },
{ 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD,
ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, 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[] = { static const int hw_eventtypes[] = {
...@@ -127,14 +130,30 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -127,14 +130,30 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
struct usb_device *dev = hanwang->usbdev; struct usb_device *dev = hanwang->usbdev;
enum hanwang_tablet_type type = hanwang->features->type; enum hanwang_tablet_type type = hanwang->features->type;
int i; 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]) { switch (data[0]) {
case 0x02: /* data packet */ case 0x02: /* data packet */
switch (data[1]) { switch (data[1]) {
case 0x80: /* tool prox out */ case 0x80: /* tool prox out */
if (type != HANWANG_ART_MASTER_II) {
hanwang->current_id = 0; hanwang->current_id = 0;
input_report_key(input_dev, hanwang->current_tool, 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; break;
case 0xc2: /* first time tool prox in */ case 0xc2: /* first time tool prox in */
...@@ -154,15 +173,12 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -154,15 +173,12 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
default: default:
hanwang->current_id = 0; hanwang->current_id = 0;
dev_dbg(&dev->dev, dev_dbg(&dev->dev,
"unknown tablet tool %02x ", data[0]); "unknown tablet tool %02x\n", data[0]);
break; break;
} }
break; break;
default: /* tool data packet */ default: /* tool data packet */
x = (data[2] << 8) | data[3];
y = (data[4] << 8) | data[5];
switch (type) { switch (type) {
case HANWANG_ART_MASTER_III: case HANWANG_ART_MASTER_III:
p = (data[6] << 3) | p = (data[6] << 3) |
...@@ -171,6 +187,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -171,6 +187,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
break; break;
case HANWANG_ART_MASTER_HD: case HANWANG_ART_MASTER_HD:
case HANWANG_ART_MASTER_II:
p = (data[7] >> 6) | (data[6] << 2); p = (data[7] >> 6) | (data[6] << 2);
break; break;
...@@ -180,17 +197,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -180,17 +197,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
} }
input_report_abs(input_dev, ABS_X, 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, input_report_abs(input_dev, ABS_Y,
le16_to_cpup((__le16 *)&y)); be16_to_cpup((__be16 *)&data[4]));
input_report_abs(input_dev, ABS_PRESSURE, input_report_abs(input_dev, ABS_PRESSURE, p);
le16_to_cpup((__le16 *)&p));
input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f);
input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); 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_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; break;
} }
input_report_abs(input_dev, ABS_MISC, hanwang->current_id); input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
input_event(input_dev, EV_MSC, MSC_SERIAL, input_event(input_dev, EV_MSC, MSC_SERIAL,
hanwang->features->pid); hanwang->features->pid);
...@@ -202,8 +225,8 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -202,8 +225,8 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
switch (type) { switch (type) {
case HANWANG_ART_MASTER_III: case HANWANG_ART_MASTER_III:
input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || input_report_key(input_dev, BTN_TOOL_FINGER,
data[2] || data[3]); data[1] || data[2] || data[3]);
input_report_abs(input_dev, ABS_WHEEL, data[1]); input_report_abs(input_dev, ABS_WHEEL, data[1]);
input_report_key(input_dev, BTN_0, data[2]); input_report_key(input_dev, BTN_0, data[2]);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
...@@ -227,6 +250,10 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -227,6 +250,10 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
BTN_5 + i, data[6] & (1 << i)); BTN_5 + i, data[6] & (1 << i));
} }
break; 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); input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
...@@ -234,7 +261,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang) ...@@ -234,7 +261,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
break; break;
default: default:
dev_dbg(&dev->dev, "error packet %02x ", data[0]); dev_dbg(&dev->dev, "error packet %02x\n", data[0]);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment