diff options
| author | weixing <weixing@hanwang.com.cn> | 2012-07-13 03:08:42 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-13 03:14:27 -0400 |
| commit | 8a90c034ae0d4282e2aeb9cf8311dc90c855d815 (patch) | |
| tree | 475d003d61378939ef6b6c328a39856999f1e9d2 | |
| parent | 8314f532ebd55f1d6dc23b143cda3c1714ffe201 (diff) | |
Input: hanwang - add support for Art Master II tablet
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>
| -rw-r--r-- | drivers/input/tablet/hanwang.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index b2db3cfe3084..5cc04124995c 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c | |||
| @@ -63,6 +63,7 @@ MODULE_LICENSE(DRIVER_LICENSE); | |||
| 63 | enum hanwang_tablet_type { | 63 | enum hanwang_tablet_type { |
| 64 | HANWANG_ART_MASTER_III, | 64 | HANWANG_ART_MASTER_III, |
| 65 | HANWANG_ART_MASTER_HD, | 65 | HANWANG_ART_MASTER_HD, |
| 66 | HANWANG_ART_MASTER_II, | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | struct hanwang { | 69 | struct hanwang { |
| @@ -99,6 +100,8 @@ static const struct hanwang_features features_array[] = { | |||
| 99 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, | 100 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, |
| 100 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, | 101 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, |
| 101 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, | 102 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, |
| 103 | { 0x8503, "Hanwang Art Master II", HANWANG_ART_MASTER_II, | ||
| 104 | ART_MASTER_PKGLEN_MAX, 0x27de, 0x1cfe, 0x3f, 0x7f, 1024 }, | ||
| 102 | }; | 105 | }; |
| 103 | 106 | ||
| 104 | static const int hw_eventtypes[] = { | 107 | static const int hw_eventtypes[] = { |
| @@ -127,14 +130,30 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 127 | struct usb_device *dev = hanwang->usbdev; | 130 | struct usb_device *dev = hanwang->usbdev; |
| 128 | enum hanwang_tablet_type type = hanwang->features->type; | 131 | enum hanwang_tablet_type type = hanwang->features->type; |
| 129 | int i; | 132 | int i; |
| 130 | u16 x, y, p; | 133 | u16 p; |
| 134 | |||
| 135 | if (type == HANWANG_ART_MASTER_II) { | ||
| 136 | hanwang->current_tool = BTN_TOOL_PEN; | ||
| 137 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
| 138 | } | ||
| 131 | 139 | ||
| 132 | switch (data[0]) { | 140 | switch (data[0]) { |
| 133 | case 0x02: /* data packet */ | 141 | case 0x02: /* data packet */ |
| 134 | switch (data[1]) { | 142 | switch (data[1]) { |
| 135 | case 0x80: /* tool prox out */ | 143 | case 0x80: /* tool prox out */ |
| 136 | hanwang->current_id = 0; | 144 | if (type != HANWANG_ART_MASTER_II) { |
| 137 | input_report_key(input_dev, hanwang->current_tool, 0); | 145 | hanwang->current_id = 0; |
| 146 | input_report_key(input_dev, | ||
| 147 | hanwang->current_tool, 0); | ||
| 148 | } | ||
| 149 | break; | ||
| 150 | |||
| 151 | case 0x00: /* artmaster ii pen leave */ | ||
| 152 | if (type == HANWANG_ART_MASTER_II) { | ||
| 153 | hanwang->current_id = 0; | ||
| 154 | input_report_key(input_dev, | ||
| 155 | hanwang->current_tool, 0); | ||
| 156 | } | ||
| 138 | break; | 157 | break; |
| 139 | 158 | ||
| 140 | case 0xc2: /* first time tool prox in */ | 159 | case 0xc2: /* first time tool prox in */ |
| @@ -154,15 +173,12 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 154 | default: | 173 | default: |
| 155 | hanwang->current_id = 0; | 174 | hanwang->current_id = 0; |
| 156 | dev_dbg(&dev->dev, | 175 | dev_dbg(&dev->dev, |
| 157 | "unknown tablet tool %02x ", data[0]); | 176 | "unknown tablet tool %02x\n", data[0]); |
| 158 | break; | 177 | break; |
| 159 | } | 178 | } |
| 160 | break; | 179 | break; |
| 161 | 180 | ||
| 162 | default: /* tool data packet */ | 181 | default: /* tool data packet */ |
| 163 | x = (data[2] << 8) | data[3]; | ||
| 164 | y = (data[4] << 8) | data[5]; | ||
| 165 | |||
| 166 | switch (type) { | 182 | switch (type) { |
| 167 | case HANWANG_ART_MASTER_III: | 183 | case HANWANG_ART_MASTER_III: |
| 168 | p = (data[6] << 3) | | 184 | p = (data[6] << 3) | |
| @@ -171,6 +187,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 171 | break; | 187 | break; |
| 172 | 188 | ||
| 173 | case HANWANG_ART_MASTER_HD: | 189 | case HANWANG_ART_MASTER_HD: |
| 190 | case HANWANG_ART_MASTER_II: | ||
| 174 | p = (data[7] >> 6) | (data[6] << 2); | 191 | p = (data[7] >> 6) | (data[6] << 2); |
| 175 | break; | 192 | break; |
| 176 | 193 | ||
| @@ -180,17 +197,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 180 | } | 197 | } |
| 181 | 198 | ||
| 182 | input_report_abs(input_dev, ABS_X, | 199 | input_report_abs(input_dev, ABS_X, |
| 183 | le16_to_cpup((__le16 *)&x)); | 200 | be16_to_cpup((__be16 *)&data[2])); |
| 184 | input_report_abs(input_dev, ABS_Y, | 201 | input_report_abs(input_dev, ABS_Y, |
| 185 | le16_to_cpup((__le16 *)&y)); | 202 | be16_to_cpup((__be16 *)&data[4])); |
| 186 | input_report_abs(input_dev, ABS_PRESSURE, | 203 | input_report_abs(input_dev, ABS_PRESSURE, p); |
| 187 | le16_to_cpup((__le16 *)&p)); | ||
| 188 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); | 204 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); |
| 189 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); | 205 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); |
| 190 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); | 206 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); |
| 191 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | 207 | |
| 208 | if (type != HANWANG_ART_MASTER_II) | ||
| 209 | input_report_key(input_dev, BTN_STYLUS2, | ||
| 210 | data[1] & 0x04); | ||
| 211 | else | ||
| 212 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | ||
| 213 | |||
| 192 | break; | 214 | break; |
| 193 | } | 215 | } |
| 216 | |||
| 194 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | 217 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); |
| 195 | input_event(input_dev, EV_MSC, MSC_SERIAL, | 218 | input_event(input_dev, EV_MSC, MSC_SERIAL, |
| 196 | hanwang->features->pid); | 219 | hanwang->features->pid); |
| @@ -202,8 +225,8 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 202 | 225 | ||
| 203 | switch (type) { | 226 | switch (type) { |
| 204 | case HANWANG_ART_MASTER_III: | 227 | case HANWANG_ART_MASTER_III: |
| 205 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | 228 | input_report_key(input_dev, BTN_TOOL_FINGER, |
| 206 | data[2] || data[3]); | 229 | data[1] || data[2] || data[3]); |
| 207 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | 230 | input_report_abs(input_dev, ABS_WHEEL, data[1]); |
| 208 | input_report_key(input_dev, BTN_0, data[2]); | 231 | input_report_key(input_dev, BTN_0, data[2]); |
| 209 | for (i = 0; i < 8; i++) | 232 | for (i = 0; i < 8; i++) |
| @@ -227,6 +250,10 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 227 | BTN_5 + i, data[6] & (1 << i)); | 250 | BTN_5 + i, data[6] & (1 << i)); |
| 228 | } | 251 | } |
| 229 | break; | 252 | break; |
| 253 | |||
| 254 | case HANWANG_ART_MASTER_II: | ||
| 255 | dev_dbg(&dev->dev, "error packet %02x\n", data[0]); | ||
| 256 | return; | ||
| 230 | } | 257 | } |
| 231 | 258 | ||
| 232 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | 259 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); |
| @@ -234,7 +261,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang) | |||
| 234 | break; | 261 | break; |
| 235 | 262 | ||
| 236 | default: | 263 | default: |
| 237 | dev_dbg(&dev->dev, "error packet %02x ", data[0]); | 264 | dev_dbg(&dev->dev, "error packet %02x\n", data[0]); |
| 238 | break; | 265 | break; |
| 239 | } | 266 | } |
| 240 | 267 | ||
