Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: add support for Wacom protocol 4 serial tablets

Recent version of xf86-input-wacom no longer support directly accessing
serial tablets. Instead xf86-input-wacom now expects all wacom tablets to
be driven by the kernel and to show up as evdev devices.

This has caused old serial Wacom tablets to stop working for people who still
have such tablets. Julian Squires has written a serio input driver to fix this:
https://github.com/tokenrove/wacom-serial-iv

This is a cleaned up version of this driver with improved Graphire support
(I own an old Graphire myself).

Signed-off-by: Julian Squires <julian@cipht.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Hans de Goede and committed by
Dmitry Torokhov
b4e05923 997502f8

+635
+7
MAINTAINERS
··· 9708 9708 S: Maintained 9709 9709 F: drivers/mmc/host/wbsd.* 9710 9710 9711 + WACOM PROTOCOL 4 SERIAL TABLETS 9712 + M: Julian Squires <julian@cipht.net> 9713 + M: Hans de Goede <hdegoede@redhat.com> 9714 + L: linux-input@vger.kernel.org 9715 + S: Maintained 9716 + F: drivers/input/tablet/wacom_serial4.c 9717 + 9711 9718 WATCHDOG DEVICE DRIVERS 9712 9719 M: Wim Van Sebroeck <wim@iguana.be> 9713 9720 L: linux-watchdog@vger.kernel.org
+10
drivers/input/tablet/Kconfig
··· 89 89 To compile this driver as a module, choose M here: the 90 90 module will be called wacom. 91 91 92 + config TABLET_SERIAL_WACOM4 93 + tristate "Wacom protocol 4 serial tablet support" 94 + select SERIO 95 + help 96 + Say Y here if you want to use Wacom protocol 4 serial tablets. 97 + E.g. serial versions of the Cintiq, Graphire or Penpartner. 98 + 99 + To compile this driver as a module, choose M here: the 100 + module will be called wacom_serial4. 101 + 92 102 endif
+1
drivers/input/tablet/Makefile
··· 11 11 obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o 12 12 obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o 13 13 obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o 14 + obj-$(CONFIG_TABLET_SERIAL_WACOM4) += wacom_serial4.o
+616
drivers/input/tablet/wacom_serial4.c
··· 1 + /* 2 + * Wacom protocol 4 serial tablet driver 3 + * 4 + * Copyright 2014 Hans de Goede <hdegoede@redhat.com> 5 + * Copyright 2011-2012 Julian Squires <julian@cipht.net> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version of 2 of the License, or (at your 10 + * option) any later version. See the file COPYING in the main directory of 11 + * this archive for more details. 12 + * 13 + * Many thanks to Bill Seremetis, without whom PenPartner support 14 + * would not have been possible. Thanks to Patrick Mahoney. 15 + * 16 + * This driver was developed with reference to much code written by others, 17 + * particularly: 18 + * - elo, gunze drivers by Vojtech Pavlik <vojtech@ucw.cz>; 19 + * - wacom_w8001 driver by Jaya Kumar <jayakumar.lkml@gmail.com>; 20 + * - the USB wacom input driver, credited to many people 21 + * (see drivers/input/tablet/wacom.h); 22 + * - new and old versions of linuxwacom / xf86-input-wacom credited to 23 + * Frederic Lepied, France. <Lepied@XFree86.org> and 24 + * Ping Cheng, Wacom. <pingc@wacom.com>; 25 + * - and xf86wacom.c (a presumably ancient version of the linuxwacom code), 26 + * by Frederic Lepied and Raph Levien <raph@gtk.org>. 27 + * 28 + * To do: 29 + * - support pad buttons; (requires access to a model with pad buttons) 30 + * - support (protocol 4-style) tilt (requires access to a > 1.4 rom model) 31 + */ 32 + 33 + /* 34 + * Wacom serial protocol 4 documentation taken from linuxwacom-0.9.9 code, 35 + * protocol 4 uses 7 or 9 byte of data in the following format: 36 + * 37 + * Byte 1 38 + * bit 7 Sync bit always 1 39 + * bit 6 Pointing device detected 40 + * bit 5 Cursor = 0 / Stylus = 1 41 + * bit 4 Reserved 42 + * bit 3 1 if a button on the pointing device has been pressed 43 + * bit 2 P0 (optional) 44 + * bit 1 X15 45 + * bit 0 X14 46 + * 47 + * Byte 2 48 + * bit 7 Always 0 49 + * bits 6-0 = X13 - X7 50 + * 51 + * Byte 3 52 + * bit 7 Always 0 53 + * bits 6-0 = X6 - X0 54 + * 55 + * Byte 4 56 + * bit 7 Always 0 57 + * bit 6 B3 58 + * bit 5 B2 59 + * bit 4 B1 60 + * bit 3 B0 61 + * bit 2 P1 (optional) 62 + * bit 1 Y15 63 + * bit 0 Y14 64 + * 65 + * Byte 5 66 + * bit 7 Always 0 67 + * bits 6-0 = Y13 - Y7 68 + * 69 + * Byte 6 70 + * bit 7 Always 0 71 + * bits 6-0 = Y6 - Y0 72 + * 73 + * Byte 7 74 + * bit 7 Always 0 75 + * bit 6 Sign of pressure data; or wheel-rel for cursor tool 76 + * bit 5 P7; or REL1 for cursor tool 77 + * bit 4 P6; or REL0 for cursor tool 78 + * bit 3 P5 79 + * bit 2 P4 80 + * bit 1 P3 81 + * bit 0 P2 82 + * 83 + * byte 8 and 9 are optional and present only 84 + * in tilt mode. 85 + * 86 + * Byte 8 87 + * bit 7 Always 0 88 + * bit 6 Sign of tilt X 89 + * bit 5 Xt6 90 + * bit 4 Xt5 91 + * bit 3 Xt4 92 + * bit 2 Xt3 93 + * bit 1 Xt2 94 + * bit 0 Xt1 95 + * 96 + * Byte 9 97 + * bit 7 Always 0 98 + * bit 6 Sign of tilt Y 99 + * bit 5 Yt6 100 + * bit 4 Yt5 101 + * bit 3 Yt4 102 + * bit 2 Yt3 103 + * bit 1 Yt2 104 + * bit 0 Yt1 105 + */ 106 + 107 + #include <linux/completion.h> 108 + #include <linux/init.h> 109 + #include <linux/input.h> 110 + #include <linux/interrupt.h> 111 + #include <linux/kernel.h> 112 + #include <linux/module.h> 113 + #include <linux/serio.h> 114 + #include <linux/slab.h> 115 + #include <linux/string.h> 116 + #include "wacom_wac.h" 117 + 118 + MODULE_AUTHOR("Julian Squires <julian@cipht.net>, Hans de Goede <hdegoede@redhat.com>"); 119 + MODULE_DESCRIPTION("Wacom protocol 4 serial tablet driver"); 120 + MODULE_LICENSE("GPL"); 121 + 122 + #define REQUEST_MODEL_AND_ROM_VERSION "~#" 123 + #define REQUEST_MAX_COORDINATES "~C\r" 124 + #define REQUEST_CONFIGURATION_STRING "~R\r" 125 + #define REQUEST_RESET_TO_PROTOCOL_IV "\r#" 126 + /* 127 + * Note: sending "\r$\r" causes at least the Digitizer II to send 128 + * packets in ASCII instead of binary. "\r#" seems to undo that. 129 + */ 130 + 131 + #define COMMAND_START_SENDING_PACKETS "ST\r" 132 + #define COMMAND_STOP_SENDING_PACKETS "SP\r" 133 + #define COMMAND_MULTI_MODE_INPUT "MU1\r" 134 + #define COMMAND_ORIGIN_IN_UPPER_LEFT "OC1\r" 135 + #define COMMAND_ENABLE_ALL_MACRO_BUTTONS "~M0\r" 136 + #define COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS "~M1\r" 137 + #define COMMAND_TRANSMIT_AT_MAX_RATE "IT0\r" 138 + #define COMMAND_DISABLE_INCREMENTAL_MODE "IN0\r" 139 + #define COMMAND_ENABLE_CONTINUOUS_MODE "SR\r" 140 + #define COMMAND_ENABLE_PRESSURE_MODE "PH1\r" 141 + #define COMMAND_Z_FILTER "ZF1\r" 142 + 143 + /* Note that this is a protocol 4 packet without tilt information. */ 144 + #define PACKET_LENGTH 7 145 + #define DATA_SIZE 32 146 + 147 + /* flags */ 148 + #define F_COVERS_SCREEN 0x01 149 + #define F_HAS_STYLUS2 0x02 150 + #define F_HAS_SCROLLWHEEL 0x04 151 + 152 + enum { STYLUS = 1, ERASER, CURSOR }; 153 + 154 + static const struct { 155 + int device_id; 156 + int input_id; 157 + } tools[] = { 158 + { 0, 0 }, 159 + { STYLUS_DEVICE_ID, BTN_TOOL_PEN }, 160 + { ERASER_DEVICE_ID, BTN_TOOL_RUBBER }, 161 + { CURSOR_DEVICE_ID, BTN_TOOL_MOUSE }, 162 + }; 163 + 164 + struct wacom { 165 + struct input_dev *dev; 166 + struct completion cmd_done; 167 + int result; 168 + u8 expect; 169 + u8 eraser_mask; 170 + unsigned int extra_z_bits; 171 + unsigned int flags; 172 + unsigned int res_x, res_y; 173 + unsigned int max_x, max_y; 174 + unsigned int tool; 175 + unsigned int idx; 176 + u8 data[DATA_SIZE]; 177 + char phys[32]; 178 + }; 179 + 180 + enum { 181 + MODEL_CINTIQ = 0x504C, /* PL */ 182 + MODEL_CINTIQ2 = 0x4454, /* DT */ 183 + MODEL_DIGITIZER_II = 0x5544, /* UD */ 184 + MODEL_GRAPHIRE = 0x4554, /* ET */ 185 + MODEL_PENPARTNER = 0x4354, /* CT */ 186 + }; 187 + 188 + static void wacom_handle_model_response(struct wacom *wacom) 189 + { 190 + int major_v, minor_v, r = 0; 191 + char *p; 192 + 193 + p = strrchr(wacom->data, 'V'); 194 + if (p) 195 + r = sscanf(p + 1, "%u.%u", &major_v, &minor_v); 196 + if (r != 2) 197 + major_v = minor_v = 0; 198 + 199 + switch (wacom->data[2] << 8 | wacom->data[3]) { 200 + case MODEL_CINTIQ: /* UNTESTED */ 201 + case MODEL_CINTIQ2: 202 + if ((wacom->data[2] << 8 | wacom->data[3]) == MODEL_CINTIQ) { 203 + wacom->dev->name = "Wacom Cintiq"; 204 + wacom->dev->id.version = MODEL_CINTIQ; 205 + } else { 206 + wacom->dev->name = "Wacom Cintiq II"; 207 + wacom->dev->id.version = MODEL_CINTIQ2; 208 + } 209 + wacom->res_x = 508; 210 + wacom->res_y = 508; 211 + 212 + switch (wacom->data[5] << 8 | wacom->data[6]) { 213 + case 0x3731: /* PL-710 */ 214 + wacom->res_x = 2540; 215 + wacom->res_y = 2540; 216 + /* fall through */ 217 + case 0x3535: /* PL-550 */ 218 + case 0x3830: /* PL-800 */ 219 + wacom->extra_z_bits = 2; 220 + } 221 + 222 + wacom->flags = F_COVERS_SCREEN; 223 + break; 224 + 225 + case MODEL_PENPARTNER: 226 + wacom->dev->name = "Wacom Penpartner"; 227 + wacom->dev->id.version = MODEL_PENPARTNER; 228 + wacom->res_x = 1000; 229 + wacom->res_y = 1000; 230 + break; 231 + 232 + case MODEL_GRAPHIRE: 233 + wacom->dev->name = "Wacom Graphire"; 234 + wacom->dev->id.version = MODEL_GRAPHIRE; 235 + wacom->res_x = 1016; 236 + wacom->res_y = 1016; 237 + wacom->max_x = 5103; 238 + wacom->max_y = 3711; 239 + wacom->extra_z_bits = 2; 240 + wacom->eraser_mask = 0x08; 241 + wacom->flags = F_HAS_STYLUS2 | F_HAS_SCROLLWHEEL; 242 + break; 243 + 244 + case MODEL_DIGITIZER_II: 245 + wacom->dev->name = "Wacom Digitizer II"; 246 + wacom->dev->id.version = MODEL_DIGITIZER_II; 247 + if (major_v == 1 && minor_v <= 2) 248 + wacom->extra_z_bits = 0; /* UNTESTED */ 249 + break; 250 + 251 + default: 252 + dev_err(&wacom->dev->dev, "Unsupported Wacom model %s\n", 253 + wacom->data); 254 + wacom->result = -ENODEV; 255 + return; 256 + } 257 + 258 + dev_info(&wacom->dev->dev, "%s tablet, version %u.%u\n", 259 + wacom->dev->name, major_v, minor_v); 260 + } 261 + 262 + static void wacom_handle_configuration_response(struct wacom *wacom) 263 + { 264 + int r, skip; 265 + 266 + dev_dbg(&wacom->dev->dev, "Configuration string: %s\n", wacom->data); 267 + r = sscanf(wacom->data, "~R%x,%u,%u,%u,%u", &skip, &skip, &skip, 268 + &wacom->res_x, &wacom->res_y); 269 + if (r != 5) 270 + dev_warn(&wacom->dev->dev, "could not get resolution\n"); 271 + } 272 + 273 + static void wacom_handle_coordinates_response(struct wacom *wacom) 274 + { 275 + int r; 276 + 277 + dev_dbg(&wacom->dev->dev, "Coordinates string: %s\n", wacom->data); 278 + r = sscanf(wacom->data, "~C%u,%u", &wacom->max_x, &wacom->max_y); 279 + if (r != 2) 280 + dev_warn(&wacom->dev->dev, "could not get max coordinates\n"); 281 + } 282 + 283 + static void wacom_handle_response(struct wacom *wacom) 284 + { 285 + if (wacom->data[0] != '~' || wacom->data[1] != wacom->expect) { 286 + dev_err(&wacom->dev->dev, 287 + "Wacom got an unexpected response: %s\n", wacom->data); 288 + wacom->result = -EIO; 289 + } else { 290 + wacom->result = 0; 291 + 292 + switch (wacom->data[1]) { 293 + case '#': 294 + wacom_handle_model_response(wacom); 295 + break; 296 + case 'R': 297 + wacom_handle_configuration_response(wacom); 298 + break; 299 + case 'C': 300 + wacom_handle_coordinates_response(wacom); 301 + break; 302 + } 303 + } 304 + 305 + complete(&wacom->cmd_done); 306 + } 307 + 308 + static void wacom_handle_packet(struct wacom *wacom) 309 + { 310 + u8 in_proximity_p, stylus_p, button; 311 + unsigned int tool; 312 + int x, y, z; 313 + 314 + in_proximity_p = wacom->data[0] & 0x40; 315 + stylus_p = wacom->data[0] & 0x20; 316 + button = (wacom->data[3] & 0x78) >> 3; 317 + x = (wacom->data[0] & 3) << 14 | wacom->data[1]<<7 | wacom->data[2]; 318 + y = (wacom->data[3] & 3) << 14 | wacom->data[4]<<7 | wacom->data[5]; 319 + 320 + if (in_proximity_p && stylus_p) { 321 + z = wacom->data[6] & 0x7f; 322 + if (wacom->extra_z_bits >= 1) 323 + z = z << 1 | (wacom->data[3] & 0x4) >> 2; 324 + if (wacom->extra_z_bits > 1) 325 + z = z << 1 | (wacom->data[0] & 0x4) >> 2; 326 + z = z ^ (0x40 << wacom->extra_z_bits); 327 + } else { 328 + z = -1; 329 + } 330 + 331 + if (stylus_p) 332 + tool = (button & wacom->eraser_mask) ? ERASER : STYLUS; 333 + else 334 + tool = CURSOR; 335 + 336 + if (tool != wacom->tool && wacom->tool != 0) { 337 + input_report_key(wacom->dev, tools[wacom->tool].input_id, 0); 338 + input_sync(wacom->dev); 339 + } 340 + wacom->tool = tool; 341 + 342 + input_report_key(wacom->dev, tools[tool].input_id, in_proximity_p); 343 + input_report_abs(wacom->dev, ABS_MISC, 344 + in_proximity_p ? tools[tool].device_id : 0); 345 + input_report_abs(wacom->dev, ABS_X, x); 346 + input_report_abs(wacom->dev, ABS_Y, y); 347 + input_report_abs(wacom->dev, ABS_PRESSURE, z); 348 + if (stylus_p) { 349 + input_report_key(wacom->dev, BTN_TOUCH, button & 1); 350 + input_report_key(wacom->dev, BTN_STYLUS, button & 2); 351 + input_report_key(wacom->dev, BTN_STYLUS2, button & 4); 352 + } else { 353 + input_report_key(wacom->dev, BTN_LEFT, button & 1); 354 + input_report_key(wacom->dev, BTN_RIGHT, button & 2); 355 + input_report_key(wacom->dev, BTN_MIDDLE, button & 4); 356 + /* handle relative wheel for non-stylus device */ 357 + z = (wacom->data[6] & 0x30) >> 4; 358 + if (wacom->data[6] & 0x40) 359 + z = -z; 360 + input_report_rel(wacom->dev, REL_WHEEL, z); 361 + } 362 + input_sync(wacom->dev); 363 + } 364 + 365 + static void wacom_clear_data_buf(struct wacom *wacom) 366 + { 367 + memset(wacom->data, 0, DATA_SIZE); 368 + wacom->idx = 0; 369 + } 370 + 371 + static irqreturn_t wacom_interrupt(struct serio *serio, unsigned char data, 372 + unsigned int flags) 373 + { 374 + struct wacom *wacom = serio_get_drvdata(serio); 375 + 376 + if (data & 0x80) 377 + wacom->idx = 0; 378 + 379 + /* 380 + * We're either expecting a carriage return-terminated ASCII 381 + * response string, or a seven-byte packet with the MSB set on 382 + * the first byte. 383 + * 384 + * Note however that some tablets (the PenPartner, for 385 + * example) don't send a carriage return at the end of a 386 + * command. We handle these by waiting for timeout. 387 + */ 388 + if (data == '\r' && !(wacom->data[0] & 0x80)) { 389 + wacom_handle_response(wacom); 390 + wacom_clear_data_buf(wacom); 391 + return IRQ_HANDLED; 392 + } 393 + 394 + /* Leave place for 0 termination */ 395 + if (wacom->idx > (DATA_SIZE - 2)) { 396 + dev_dbg(&wacom->dev->dev, 397 + "throwing away %d bytes of garbage\n", wacom->idx); 398 + wacom_clear_data_buf(wacom); 399 + } 400 + wacom->data[wacom->idx++] = data; 401 + 402 + if (wacom->idx == PACKET_LENGTH && (wacom->data[0] & 0x80)) { 403 + wacom_handle_packet(wacom); 404 + wacom_clear_data_buf(wacom); 405 + } 406 + 407 + return IRQ_HANDLED; 408 + } 409 + 410 + static void wacom_disconnect(struct serio *serio) 411 + { 412 + struct wacom *wacom = serio_get_drvdata(serio); 413 + 414 + serio_close(serio); 415 + serio_set_drvdata(serio, NULL); 416 + input_unregister_device(wacom->dev); 417 + kfree(wacom); 418 + } 419 + 420 + static int wacom_send(struct serio *serio, const u8 *command) 421 + { 422 + int err = 0; 423 + 424 + for (; !err && *command; command++) 425 + err = serio_write(serio, *command); 426 + 427 + return err; 428 + } 429 + 430 + static int wacom_send_setup_string(struct wacom *wacom, struct serio *serio) 431 + { 432 + const u8 *cmd; 433 + 434 + switch (wacom->dev->id.version) { 435 + case MODEL_CINTIQ: /* UNTESTED */ 436 + cmd = COMMAND_ORIGIN_IN_UPPER_LEFT 437 + COMMAND_TRANSMIT_AT_MAX_RATE 438 + COMMAND_ENABLE_CONTINUOUS_MODE 439 + COMMAND_START_SENDING_PACKETS; 440 + break; 441 + 442 + case MODEL_PENPARTNER: 443 + cmd = COMMAND_ENABLE_PRESSURE_MODE 444 + COMMAND_START_SENDING_PACKETS; 445 + break; 446 + 447 + default: 448 + cmd = COMMAND_MULTI_MODE_INPUT 449 + COMMAND_ORIGIN_IN_UPPER_LEFT 450 + COMMAND_ENABLE_ALL_MACRO_BUTTONS 451 + COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS 452 + COMMAND_TRANSMIT_AT_MAX_RATE 453 + COMMAND_DISABLE_INCREMENTAL_MODE 454 + COMMAND_ENABLE_CONTINUOUS_MODE 455 + COMMAND_Z_FILTER 456 + COMMAND_START_SENDING_PACKETS; 457 + break; 458 + } 459 + 460 + return wacom_send(serio, cmd); 461 + } 462 + 463 + static int wacom_send_and_wait(struct wacom *wacom, struct serio *serio, 464 + const u8 *cmd, const char *desc) 465 + { 466 + int err; 467 + unsigned long u; 468 + 469 + wacom->expect = cmd[1]; 470 + init_completion(&wacom->cmd_done); 471 + 472 + err = wacom_send(serio, cmd); 473 + if (err) 474 + return err; 475 + 476 + u = wait_for_completion_timeout(&wacom->cmd_done, HZ); 477 + if (u == 0) { 478 + /* Timeout, process what we've received. */ 479 + wacom_handle_response(wacom); 480 + } 481 + 482 + wacom->expect = 0; 483 + return wacom->result; 484 + } 485 + 486 + static int wacom_setup(struct wacom *wacom, struct serio *serio) 487 + { 488 + int err; 489 + 490 + /* Note that setting the link speed is the job of inputattach. 491 + * We assume that reset negotiation has already happened, 492 + * here. */ 493 + err = wacom_send_and_wait(wacom, serio, REQUEST_MODEL_AND_ROM_VERSION, 494 + "model and version"); 495 + if (err) 496 + return err; 497 + 498 + if (!(wacom->res_x && wacom->res_y)) { 499 + err = wacom_send_and_wait(wacom, serio, 500 + REQUEST_CONFIGURATION_STRING, 501 + "configuration string"); 502 + if (err) 503 + return err; 504 + } 505 + 506 + if (!(wacom->max_x && wacom->max_y)) { 507 + err = wacom_send_and_wait(wacom, serio, 508 + REQUEST_MAX_COORDINATES, 509 + "coordinates string"); 510 + if (err) 511 + return err; 512 + } 513 + 514 + return wacom_send_setup_string(wacom, serio); 515 + } 516 + 517 + static int wacom_connect(struct serio *serio, struct serio_driver *drv) 518 + { 519 + struct wacom *wacom; 520 + struct input_dev *input_dev; 521 + int err = -ENOMEM; 522 + 523 + wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); 524 + input_dev = input_allocate_device(); 525 + if (!wacom || !input_dev) 526 + goto free_device; 527 + 528 + wacom->dev = input_dev; 529 + wacom->extra_z_bits = 1; 530 + wacom->eraser_mask = 0x04; 531 + wacom->tool = wacom->idx = 0; 532 + snprintf(wacom->phys, sizeof(wacom->phys), "%s/input0", serio->phys); 533 + input_dev->phys = wacom->phys; 534 + input_dev->id.bustype = BUS_RS232; 535 + input_dev->id.vendor = SERIO_WACOM_IV; 536 + input_dev->id.product = serio->id.extra; 537 + input_dev->dev.parent = &serio->dev; 538 + 539 + input_dev->evbit[0] = 540 + BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_REL); 541 + set_bit(ABS_MISC, input_dev->absbit); 542 + set_bit(BTN_TOOL_PEN, input_dev->keybit); 543 + set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 544 + set_bit(BTN_TOOL_MOUSE, input_dev->keybit); 545 + set_bit(BTN_TOUCH, input_dev->keybit); 546 + set_bit(BTN_STYLUS, input_dev->keybit); 547 + set_bit(BTN_LEFT, input_dev->keybit); 548 + set_bit(BTN_RIGHT, input_dev->keybit); 549 + set_bit(BTN_MIDDLE, input_dev->keybit); 550 + 551 + serio_set_drvdata(serio, wacom); 552 + 553 + err = serio_open(serio, drv); 554 + if (err) 555 + goto free_device; 556 + 557 + err = wacom_setup(wacom, serio); 558 + if (err) 559 + goto close_serio; 560 + 561 + set_bit(INPUT_PROP_DIRECT, input_dev->propbit); 562 + if (!(wacom->flags & F_COVERS_SCREEN)) 563 + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); 564 + 565 + if (wacom->flags & F_HAS_STYLUS2) 566 + __set_bit(BTN_STYLUS2, input_dev->keybit); 567 + 568 + if (wacom->flags & F_HAS_SCROLLWHEEL) 569 + __set_bit(REL_WHEEL, input_dev->relbit); 570 + 571 + input_abs_set_res(wacom->dev, ABS_X, wacom->res_x); 572 + input_abs_set_res(wacom->dev, ABS_Y, wacom->res_y); 573 + input_set_abs_params(wacom->dev, ABS_X, 0, wacom->max_x, 0, 0); 574 + input_set_abs_params(wacom->dev, ABS_Y, 0, wacom->max_y, 0, 0); 575 + input_set_abs_params(wacom->dev, ABS_PRESSURE, -1, 576 + (1 << (7 + wacom->extra_z_bits)) - 1, 0, 0); 577 + 578 + err = input_register_device(wacom->dev); 579 + if (err) 580 + goto close_serio; 581 + 582 + return 0; 583 + 584 + close_serio: 585 + serio_close(serio); 586 + free_device: 587 + serio_set_drvdata(serio, NULL); 588 + input_free_device(input_dev); 589 + kfree(wacom); 590 + return err; 591 + } 592 + 593 + static struct serio_device_id wacom_serio_ids[] = { 594 + { 595 + .type = SERIO_RS232, 596 + .proto = SERIO_WACOM_IV, 597 + .id = SERIO_ANY, 598 + .extra = SERIO_ANY, 599 + }, 600 + { 0 } 601 + }; 602 + 603 + MODULE_DEVICE_TABLE(serio, wacom_serio_ids); 604 + 605 + static struct serio_driver wacom_drv = { 606 + .driver = { 607 + .name = "wacom_serial4", 608 + }, 609 + .description = "Wacom protocol 4 serial tablet driver", 610 + .id_table = wacom_serio_ids, 611 + .interrupt = wacom_interrupt, 612 + .connect = wacom_connect, 613 + .disconnect = wacom_disconnect, 614 + }; 615 + 616 + module_serio_driver(wacom_drv);
+1
include/uapi/linux/serio.h
··· 76 76 #define SERIO_HAMPSHIRE 0x3b 77 77 #define SERIO_PS2MULT 0x3c 78 78 #define SERIO_TSC40 0x3d 79 + #define SERIO_WACOM_IV 0x3e 79 80 80 81 #endif /* _UAPI_SERIO_H */