1 /* 2 * Driver for DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers) 3 * DEC VSXXX-GA mouse (rectangular mouse, with ball) 4 * DEC VSXXX-AB tablet (digitizer with hair cross or stylus) 5 * 6 * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de> 7 * 8 * The packet format was initially taken from a patch to GPM which is (C) 2001 9 * by Karsten Merker <merker@linuxtag.org> 10 * and Maciej W. Rozycki <macro@ds2.pg.gda.pl> 11 * Later on, I had access to the device's documentation (referenced below). 12 */ 13 14 /* 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 */ 29 30 /* 31 * Building an adaptor to DE9 / DB25 RS232 32 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 * 34 * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for 35 * anything if you break your mouse, your computer or whatever! 36 * 37 * In theory, this mouse is a simple RS232 device. In practice, it has got 38 * a quite uncommon plug and the requirement to additionally get a power 39 * supply at +5V and -12V. 40 * 41 * If you look at the socket/jack (_not_ at the plug), we use this pin 42 * numbering: 43 * _______ 44 * / 7 6 5 \ 45 * | 4 --- 3 | 46 * \ 2 1 / 47 * ------- 48 * 49 * DEC socket DE9 DB25 Note 50 * 1 (GND) 5 7 - 51 * 2 (RxD) 2 3 - 52 * 3 (TxD) 3 2 - 53 * 4 (-12V) - - Somewhere from the PSU. At ATX, it's 54 * the thin blue wire at pin 12 of the 55 * ATX power connector. Only required for 56 * VSXXX-AA/-GA mice. 57 * 5 (+5V) - - PSU (red wires of ATX power connector 58 * on pin 4, 6, 19 or 20) or HDD power 59 * connector (also red wire). 60 * 6 (+12V) - - HDD power connector, yellow wire. Only 61 * required for VSXXX-AB digitizer. 62 * 7 (dev. avail.) - - The mouse shorts this one to pin 1. 63 * This way, the host computer can detect 64 * the mouse. To use it with the adaptor, 65 * simply don't connect this pin. 66 * 67 * So to get a working adaptor, you need to connect the mouse with three 68 * wires to a RS232 port and two or three additional wires for +5V, +12V and 69 * -12V to the PSU. 70 * 71 * Flow specification for the link is 4800, 8o1. 72 * 73 * The mice and tablet are described in "VCB02 Video Subsystem - Technical 74 * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine 75 * specific for DEC documentation. Try 76 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1 77 */ 78 79 #include <linux/delay.h> 80 #include <linux/module.h> 81 #include <linux/slab.h> 82 #include <linux/interrupt.h> 83 #include <linux/input.h> 84 #include <linux/serio.h> 85 #include <linux/init.h> 86 87 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" 88 89 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); 90 MODULE_DESCRIPTION(DRIVER_DESC); 91 MODULE_LICENSE("GPL"); 92 93 #undef VSXXXAA_DEBUG 94 #ifdef VSXXXAA_DEBUG 95 #define DBG(x...) printk(x) 96 #else 97 #define DBG(x...) do {} while (0) 98 #endif 99 100 #define VSXXXAA_INTRO_MASK 0x80 101 #define VSXXXAA_INTRO_HEAD 0x80 102 #define IS_HDR_BYTE(x) \ 103 (((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD) 104 105 #define VSXXXAA_PACKET_MASK 0xe0 106 #define VSXXXAA_PACKET_REL 0x80 107 #define VSXXXAA_PACKET_ABS 0xc0 108 #define VSXXXAA_PACKET_POR 0xa0 109 #define MATCH_PACKET_TYPE(data, type) \ 110 (((data) & VSXXXAA_PACKET_MASK) == (type)) 111 112 113 114 struct vsxxxaa { 115 struct input_dev *dev; 116 struct serio *serio; 117 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */ 118 unsigned char buf[BUFLEN]; 119 unsigned char count; 120 unsigned char version; 121 unsigned char country; 122 unsigned char type; 123 char name[64]; 124 char phys[32]; 125 }; 126 127 static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num) 128 { 129 if (num >= mouse->count) { 130 mouse->count = 0; 131 } else { 132 memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num); 133 mouse->count -= num; 134 } 135 } 136 137 static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte) 138 { 139 if (mouse->count == BUFLEN) { 140 printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", 141 mouse->name, mouse->phys); 142 vsxxxaa_drop_bytes(mouse, 1); 143 } 144 145 DBG(KERN_INFO "Queueing byte 0x%02x\n", byte); 146 147 mouse->buf[mouse->count++] = byte; 148 } 149 150 static void vsxxxaa_detection_done(struct vsxxxaa *mouse) 151 { 152 switch (mouse->type) { 153 case 0x02: 154 strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse", 155 sizeof(mouse->name)); 156 break; 157 158 case 0x04: 159 strlcpy(mouse->name, "DEC VSXXX-AB digitizer", 160 sizeof(mouse->name)); 161 break; 162 163 default: 164 snprintf(mouse->name, sizeof(mouse->name), 165 "unknown DEC pointer device (type = 0x%02x)", 166 mouse->type); 167 break; 168 } 169 170 printk(KERN_INFO 171 "Found %s version 0x%02x from country 0x%02x on port %s\n", 172 mouse->name, mouse->version, mouse->country, mouse->phys); 173 } 174 175 /* 176 * Returns number of bytes to be dropped, 0 if packet is okay. 177 */ 178 static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len) 179 { 180 int i; 181 182 /* First byte must be a header byte */ 183 if (!IS_HDR_BYTE(mouse->buf[0])) { 184 DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); 185 return 1; 186 } 187 188 /* Check all following bytes */ 189 for (i = 1; i < packet_len; i++) { 190 if (IS_HDR_BYTE(mouse->buf[i])) { 191 printk(KERN_ERR 192 "Need to drop %d bytes of a broken packet.\n", 193 i - 1); 194 DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n", 195 packet_len, i, mouse->buf[i]); 196 return i - 1; 197 } 198 } 199 200 return 0; 201 } 202 203 static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse, 204 unsigned char type, size_t len) 205 { 206 return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type); 207 } 208 209 static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse) 210 { 211 struct input_dev *dev = mouse->dev; 212 unsigned char *buf = mouse->buf; 213 int left, middle, right; 214 int dx, dy; 215 216 /* 217 * Check for normal stream packets. This is three bytes, 218 * with the first byte's 3 MSB set to 100. 219 * 220 * [0]: 1 0 0 SignX SignY Left Middle Right 221 * [1]: 0 dx dx dx dx dx dx dx 222 * [2]: 0 dy dy dy dy dy dy dy 223 */ 224 225 /* 226 * Low 7 bit of byte 1 are abs(dx), bit 7 is 227 * 0, bit 4 of byte 0 is direction. 228 */ 229 dx = buf[1] & 0x7f; 230 dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1; 231 232 /* 233 * Low 7 bit of byte 2 are abs(dy), bit 7 is 234 * 0, bit 3 of byte 0 is direction. 235 */ 236 dy = buf[2] & 0x7f; 237 dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1; 238 239 /* 240 * Get button state. It's the low three bits 241 * (for three buttons) of byte 0. 242 */ 243 left = buf[0] & 0x04; 244 middle = buf[0] & 0x02; 245 right = buf[0] & 0x01; 246 247 vsxxxaa_drop_bytes(mouse, 3); 248 249 DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", 250 mouse->name, mouse->phys, dx, dy, 251 left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r"); 252 253 /* 254 * Report what we've found so far... 255 */ 256 input_report_key(dev, BTN_LEFT, left); 257 input_report_key(dev, BTN_MIDDLE, middle); 258 input_report_key(dev, BTN_RIGHT, right); 259 input_report_key(dev, BTN_TOUCH, 0); 260 input_report_rel(dev, REL_X, dx); 261 input_report_rel(dev, REL_Y, dy); 262 input_sync(dev); 263 } 264 265 static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse) 266 { 267 struct input_dev *dev = mouse->dev; 268 unsigned char *buf = mouse->buf; 269 int left, middle, right, touch; 270 int x, y; 271 272 /* 273 * Tablet position / button packet 274 * 275 * [0]: 1 1 0 B4 B3 B2 B1 Pr 276 * [1]: 0 0 X5 X4 X3 X2 X1 X0 277 * [2]: 0 0 X11 X10 X9 X8 X7 X6 278 * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0 279 * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6 280 */ 281 282 /* 283 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB 284 * counts down->top while monitor counts top->bottom. 285 */ 286 x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f); 287 y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f); 288 y = 1023 - y; 289 290 /* 291 * Get button state. It's bits <4..1> of byte 0. 292 */ 293 left = buf[0] & 0x02; 294 middle = buf[0] & 0x04; 295 right = buf[0] & 0x08; 296 touch = buf[0] & 0x10; 297 298 vsxxxaa_drop_bytes(mouse, 5); 299 300 DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", 301 mouse->name, mouse->phys, x, y, 302 left ? "L" : "l", middle ? "M" : "m", 303 right ? "R" : "r", touch ? "T" : "t"); 304 305 /* 306 * Report what we've found so far... 307 */ 308 input_report_key(dev, BTN_LEFT, left); 309 input_report_key(dev, BTN_MIDDLE, middle); 310 input_report_key(dev, BTN_RIGHT, right); 311 input_report_key(dev, BTN_TOUCH, touch); 312 input_report_abs(dev, ABS_X, x); 313 input_report_abs(dev, ABS_Y, y); 314 input_sync(dev); 315 } 316 317 static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse) 318 { 319 struct input_dev *dev = mouse->dev; 320 unsigned char *buf = mouse->buf; 321 int left, middle, right; 322 unsigned char error; 323 324 /* 325 * Check for Power-On-Reset packets. These are sent out 326 * after plugging the mouse in, or when explicitly 327 * requested by sending 'T'. 328 * 329 * [0]: 1 0 1 0 R3 R2 R1 R0 330 * [1]: 0 M2 M1 M0 D3 D2 D1 D0 331 * [2]: 0 E6 E5 E4 E3 E2 E1 E0 332 * [3]: 0 0 0 0 0 Left Middle Right 333 * 334 * M: manufacturer location code 335 * R: revision code 336 * E: Error code. If it's in the range of 0x00..0x1f, only some 337 * minor problem occurred. Errors >= 0x20 are considered bad 338 * and the device may not work properly... 339 * D: <0010> == mouse, <0100> == tablet 340 */ 341 342 mouse->version = buf[0] & 0x0f; 343 mouse->country = (buf[1] >> 4) & 0x07; 344 mouse->type = buf[1] & 0x0f; 345 error = buf[2] & 0x7f; 346 347 /* 348 * Get button state. It's the low three bits 349 * (for three buttons) of byte 0. Maybe even the bit <3> 350 * has some meaning if a tablet is attached. 351 */ 352 left = buf[0] & 0x04; 353 middle = buf[0] & 0x02; 354 right = buf[0] & 0x01; 355 356 vsxxxaa_drop_bytes(mouse, 4); 357 vsxxxaa_detection_done(mouse); 358 359 if (error <= 0x1f) { 360 /* No (serious) error. Report buttons */ 361 input_report_key(dev, BTN_LEFT, left); 362 input_report_key(dev, BTN_MIDDLE, middle); 363 input_report_key(dev, BTN_RIGHT, right); 364 input_report_key(dev, BTN_TOUCH, 0); 365 input_sync(dev); 366 367 if (error != 0) 368 printk(KERN_INFO "Your %s on %s reports error=0x%02x\n", 369 mouse->name, mouse->phys, error); 370 371 } 372 373 /* 374 * If the mouse was hot-plugged, we need to force differential mode 375 * now... However, give it a second to recover from it's reset. 376 */ 377 printk(KERN_NOTICE 378 "%s on %s: Forcing standard packet format, " 379 "incremental streaming mode and 72 samples/sec\n", 380 mouse->name, mouse->phys); 381 serio_write(mouse->serio, 'S'); /* Standard format */ 382 mdelay(50); 383 serio_write(mouse->serio, 'R'); /* Incremental */ 384 mdelay(50); 385 serio_write(mouse->serio, 'L'); /* 72 samples/sec */ 386 } 387 388 static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse) 389 { 390 unsigned char *buf = mouse->buf; 391 int stray_bytes; 392 393 /* 394 * Parse buffer to death... 395 */ 396 do { 397 /* 398 * Out of sync? Throw away what we don't understand. Each 399 * packet starts with a byte whose bit 7 is set. Unhandled 400 * packets (ie. which we don't know about or simply b0rk3d 401 * data...) will get shifted out of the buffer after some 402 * activity on the mouse. 403 */ 404 while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { 405 printk(KERN_ERR "%s on %s: Dropping a byte to regain " 406 "sync with mouse data stream...\n", 407 mouse->name, mouse->phys); 408 vsxxxaa_drop_bytes(mouse, 1); 409 } 410 411 /* 412 * Check for packets we know about. 413 */ 414 415 if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) { 416 /* Check for broken packet */ 417 stray_bytes = vsxxxaa_check_packet(mouse, 3); 418 if (!stray_bytes) 419 vsxxxaa_handle_REL_packet(mouse); 420 421 } else if (vsxxxaa_smells_like_packet(mouse, 422 VSXXXAA_PACKET_ABS, 5)) { 423 /* Check for broken packet */ 424 stray_bytes = vsxxxaa_check_packet(mouse, 5); 425 if (!stray_bytes) 426 vsxxxaa_handle_ABS_packet(mouse); 427 428 } else if (vsxxxaa_smells_like_packet(mouse, 429 VSXXXAA_PACKET_POR, 4)) { 430 /* Check for broken packet */ 431 stray_bytes = vsxxxaa_check_packet(mouse, 4); 432 if (!stray_bytes) 433 vsxxxaa_handle_POR_packet(mouse); 434 435 } else { 436 break; /* No REL, ABS or POR packet found */ 437 } 438 439 if (stray_bytes > 0) { 440 printk(KERN_ERR "Dropping %d bytes now...\n", 441 stray_bytes); 442 vsxxxaa_drop_bytes(mouse, stray_bytes); 443 } 444 445 } while (1); 446 } 447 448 static irqreturn_t vsxxxaa_interrupt(struct serio *serio, 449 unsigned char data, unsigned int flags) 450 { 451 struct vsxxxaa *mouse = serio_get_drvdata(serio); 452 453 vsxxxaa_queue_byte(mouse, data); 454 vsxxxaa_parse_buffer(mouse); 455 456 return IRQ_HANDLED; 457 } 458 459 static void vsxxxaa_disconnect(struct serio *serio) 460 { 461 struct vsxxxaa *mouse = serio_get_drvdata(serio); 462 463 serio_close(serio); 464 serio_set_drvdata(serio, NULL); 465 input_unregister_device(mouse->dev); 466 kfree(mouse); 467 } 468 469 static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv) 470 { 471 struct vsxxxaa *mouse; 472 struct input_dev *input_dev; 473 int err = -ENOMEM; 474 475 mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL); 476 input_dev = input_allocate_device(); 477 if (!mouse || !input_dev) 478 goto fail1; 479 480 mouse->dev = input_dev; 481 mouse->serio = serio; 482 strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", 483 sizeof(mouse->name)); 484 snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys); 485 486 input_dev->name = mouse->name; 487 input_dev->phys = mouse->phys; 488 input_dev->id.bustype = BUS_RS232; 489 input_dev->dev.parent = &serio->dev; 490 491 __set_bit(EV_KEY, input_dev->evbit); /* We have buttons */ 492 __set_bit(EV_REL, input_dev->evbit); 493 __set_bit(EV_ABS, input_dev->evbit); 494 __set_bit(BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ 495 __set_bit(BTN_MIDDLE, input_dev->keybit); 496 __set_bit(BTN_RIGHT, input_dev->keybit); 497 __set_bit(BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ 498 __set_bit(REL_X, input_dev->relbit); 499 __set_bit(REL_Y, input_dev->relbit); 500 input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0); 501 input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0); 502 503 serio_set_drvdata(serio, mouse); 504 505 err = serio_open(serio, drv); 506 if (err) 507 goto fail2; 508 509 /* 510 * Request selftest. Standard packet format and differential 511 * mode will be requested after the device ID'ed successfully. 512 */ 513 serio_write(serio, 'T'); /* Test */ 514 515 err = input_register_device(input_dev); 516 if (err) 517 goto fail3; 518 519 return 0; 520 521 fail3: serio_close(serio); 522 fail2: serio_set_drvdata(serio, NULL); 523 fail1: input_free_device(input_dev); 524 kfree(mouse); 525 return err; 526 } 527 528 static struct serio_device_id vsxxaa_serio_ids[] = { 529 { 530 .type = SERIO_RS232, 531 .proto = SERIO_VSXXXAA, 532 .id = SERIO_ANY, 533 .extra = SERIO_ANY, 534 }, 535 { 0 } 536 }; 537 538 MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids); 539 540 static struct serio_driver vsxxxaa_drv = { 541 .driver = { 542 .name = "vsxxxaa", 543 }, 544 .description = DRIVER_DESC, 545 .id_table = vsxxaa_serio_ids, 546 .connect = vsxxxaa_connect, 547 .interrupt = vsxxxaa_interrupt, 548 .disconnect = vsxxxaa_disconnect, 549 }; 550 551 static int __init vsxxxaa_init(void) 552 { 553 return serio_register_driver(&vsxxxaa_drv); 554 } 555 556 static void __exit vsxxxaa_exit(void) 557 { 558 serio_unregister_driver(&vsxxxaa_drv); 559 } 560 561 module_init(vsxxxaa_init); 562 module_exit(vsxxxaa_exit); 563 564