diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/tablet/hanwang.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index 3554e30ab41b..0701d948cdf3 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c | |||
@@ -44,6 +44,13 @@ MODULE_LICENSE(DRIVER_LICENSE); | |||
44 | 44 | ||
45 | #define ART_MASTERIII_PKGLEN_MAX 10 | 45 | #define ART_MASTERIII_PKGLEN_MAX 10 |
46 | 46 | ||
47 | /* device IDs */ | ||
48 | #define STYLUS_DEVICE_ID 0x02 | ||
49 | #define TOUCH_DEVICE_ID 0x03 | ||
50 | #define CURSOR_DEVICE_ID 0x06 | ||
51 | #define ERASER_DEVICE_ID 0x0A | ||
52 | #define PAD_DEVICE_ID 0x0F | ||
53 | |||
47 | /* match vendor and interface info */ | 54 | /* match vendor and interface info */ |
48 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ | 55 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ |
49 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ | 56 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ |
@@ -61,6 +68,7 @@ struct hanwang { | |||
61 | struct urb *irq; | 68 | struct urb *irq; |
62 | const struct hanwang_features *features; | 69 | const struct hanwang_features *features; |
63 | unsigned int current_tool; | 70 | unsigned int current_tool; |
71 | unsigned int current_id; | ||
64 | char name[64]; | 72 | char name[64]; |
65 | char phys[32]; | 73 | char phys[32]; |
66 | }; | 74 | }; |
@@ -86,16 +94,22 @@ static const struct hanwang_features features_array[] = { | |||
86 | }; | 94 | }; |
87 | 95 | ||
88 | static const int hw_eventtypes[] = { | 96 | static const int hw_eventtypes[] = { |
89 | EV_KEY, EV_ABS, | 97 | EV_KEY, EV_ABS, EV_MSC, |
90 | }; | 98 | }; |
91 | 99 | ||
92 | static const int hw_absevents[] = { | 100 | static const int hw_absevents[] = { |
93 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, ABS_PRESSURE, | 101 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, |
102 | ABS_PRESSURE, ABS_MISC, | ||
94 | }; | 103 | }; |
95 | 104 | ||
96 | static const int hw_btnevents[] = { | 105 | static const int hw_btnevents[] = { |
97 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_MOUSE, | 106 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, |
98 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 | 107 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, |
108 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, | ||
109 | }; | ||
110 | |||
111 | static const int hw_mscevents[] = { | ||
112 | MSC_SERIAL, | ||
99 | }; | 113 | }; |
100 | 114 | ||
101 | static void hanwang_parse_packet(struct hanwang *hanwang) | 115 | static void hanwang_parse_packet(struct hanwang *hanwang) |
@@ -109,20 +123,24 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
109 | case 0x02: /* data packet */ | 123 | case 0x02: /* data packet */ |
110 | switch (data[1]) { | 124 | switch (data[1]) { |
111 | case 0x80: /* tool prox out */ | 125 | case 0x80: /* tool prox out */ |
126 | hanwang->current_id = 0; | ||
112 | input_report_key(input_dev, hanwang->current_tool, 0); | 127 | input_report_key(input_dev, hanwang->current_tool, 0); |
113 | break; | 128 | break; |
114 | 129 | ||
115 | case 0xc2: /* first time tool prox in */ | 130 | case 0xc2: /* first time tool prox in */ |
116 | switch (data[3] & 0xf0) { | 131 | switch (data[3] & 0xf0) { |
117 | case 0x20: | 132 | case 0x20: |
133 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
118 | hanwang->current_tool = BTN_TOOL_PEN; | 134 | hanwang->current_tool = BTN_TOOL_PEN; |
119 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | 135 | input_report_key(input_dev, BTN_TOOL_PEN, 1); |
120 | break; | 136 | break; |
121 | case 0xa0: | 137 | case 0xa0: |
138 | hanwang->current_id = ERASER_DEVICE_ID; | ||
122 | hanwang->current_tool = BTN_TOOL_RUBBER; | 139 | hanwang->current_tool = BTN_TOOL_RUBBER; |
123 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); | 140 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); |
124 | break; | 141 | break; |
125 | default: | 142 | default: |
143 | hanwang->current_id = 0; | ||
126 | dev_dbg(&dev->dev, | 144 | dev_dbg(&dev->dev, |
127 | "unknown tablet tool %02x ", data[0]); | 145 | "unknown tablet tool %02x ", data[0]); |
128 | break; | 146 | break; |
@@ -144,15 +162,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
144 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | 162 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); |
145 | break; | 163 | break; |
146 | } | 164 | } |
165 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
166 | input_event(input_dev, EV_MSC, MSC_SERIAL, | ||
167 | hanwang->features->pid); | ||
147 | break; | 168 | break; |
148 | 169 | ||
149 | case 0x0c: | 170 | case 0x0c: |
150 | /* roll wheel */ | 171 | /* roll wheel */ |
172 | hanwang->current_id = PAD_DEVICE_ID; | ||
173 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
174 | data[2] || data[3]); | ||
151 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | 175 | input_report_abs(input_dev, ABS_WHEEL, data[1]); |
152 | input_report_key(input_dev, BTN_0, data[2]); | 176 | input_report_key(input_dev, BTN_0, data[2]); |
153 | for (i = 0; i < 8; i++) | 177 | for (i = 0; i < 8; i++) |
154 | input_report_key(input_dev, | 178 | input_report_key(input_dev, |
155 | BTN_1 + i, data[3] & (1 << i)); | 179 | BTN_1 + i, data[3] & (1 << i)); |
180 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
181 | input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
156 | break; | 182 | break; |
157 | 183 | ||
158 | default: | 184 | default: |
@@ -287,6 +313,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id | |||
287 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) | 313 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) |
288 | __set_bit(hw_btnevents[i], input_dev->keybit); | 314 | __set_bit(hw_btnevents[i], input_dev->keybit); |
289 | 315 | ||
316 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) | ||
317 | __set_bit(hw_mscevents[i], input_dev->mscbit); | ||
318 | |||
290 | input_set_abs_params(input_dev, ABS_X, | 319 | input_set_abs_params(input_dev, ABS_X, |
291 | 0, hanwang->features->max_x, 4, 0); | 320 | 0, hanwang->features->max_x, 4, 0); |
292 | input_set_abs_params(input_dev, ABS_Y, | 321 | input_set_abs_params(input_dev, ABS_Y, |