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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.18 590 lines 16 kB view raw
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 89MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); 90MODULE_DESCRIPTION (DRIVER_DESC); 91MODULE_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) (((x) & VSXXXAA_INTRO_MASK) \ 103 == 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) (((data) & VSXXXAA_PACKET_MASK) == (type)) 110 111 112 113struct vsxxxaa { 114 struct input_dev *dev; 115 struct serio *serio; 116#define BUFLEN 15 /* At least 5 is needed for a full tablet packet */ 117 unsigned char buf[BUFLEN]; 118 unsigned char count; 119 unsigned char version; 120 unsigned char country; 121 unsigned char type; 122 char name[64]; 123 char phys[32]; 124}; 125 126static void 127vsxxxaa_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 137static void 138vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte) 139{ 140 if (mouse->count == BUFLEN) { 141 printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", 142 mouse->name, mouse->phys); 143 vsxxxaa_drop_bytes (mouse, 1); 144 } 145 DBG (KERN_INFO "Queueing byte 0x%02x\n", byte); 146 147 mouse->buf[mouse->count++] = byte; 148} 149 150static void 151vsxxxaa_detection_done (struct vsxxxaa *mouse) 152{ 153 switch (mouse->type) { 154 case 0x02: 155 strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse", 156 sizeof (mouse->name)); 157 break; 158 159 case 0x04: 160 strlcpy (mouse->name, "DEC VSXXX-AB digitizer", 161 sizeof (mouse->name)); 162 break; 163 164 default: 165 snprintf (mouse->name, sizeof (mouse->name), 166 "unknown DEC pointer device (type = 0x%02x)", 167 mouse->type); 168 break; 169 } 170 171 printk (KERN_INFO 172 "Found %s version 0x%02x from country 0x%02x on port %s\n", 173 mouse->name, mouse->version, mouse->country, mouse->phys); 174} 175 176/* 177 * Returns number of bytes to be dropped, 0 if packet is okay. 178 */ 179static int 180vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len) 181{ 182 int i; 183 184 /* First byte must be a header byte */ 185 if (!IS_HDR_BYTE (mouse->buf[0])) { 186 DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); 187 return 1; 188 } 189 190 /* Check all following bytes */ 191 if (packet_len > 1) { 192 for (i = 1; i < packet_len; i++) { 193 if (IS_HDR_BYTE (mouse->buf[i])) { 194 printk (KERN_ERR "Need to drop %d bytes " 195 "of a broken packet.\n", 196 i - 1); 197 DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n", 198 packet_len, i, mouse->buf[i]); 199 return i - 1; 200 } 201 } 202 } 203 204 return 0; 205} 206 207static __inline__ int 208vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len) 209{ 210 return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type); 211} 212 213static void 214vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs) 215{ 216 struct input_dev *dev = mouse->dev; 217 unsigned char *buf = mouse->buf; 218 int left, middle, right; 219 int dx, dy; 220 221 /* 222 * Check for normal stream packets. This is three bytes, 223 * with the first byte's 3 MSB set to 100. 224 * 225 * [0]: 1 0 0 SignX SignY Left Middle Right 226 * [1]: 0 dx dx dx dx dx dx dx 227 * [2]: 0 dy dy dy dy dy dy dy 228 */ 229 230 /* 231 * Low 7 bit of byte 1 are abs(dx), bit 7 is 232 * 0, bit 4 of byte 0 is direction. 233 */ 234 dx = buf[1] & 0x7f; 235 dx *= ((buf[0] >> 4) & 0x01)? 1: -1; 236 237 /* 238 * Low 7 bit of byte 2 are abs(dy), bit 7 is 239 * 0, bit 3 of byte 0 is direction. 240 */ 241 dy = buf[2] & 0x7f; 242 dy *= ((buf[0] >> 3) & 0x01)? -1: 1; 243 244 /* 245 * Get button state. It's the low three bits 246 * (for three buttons) of byte 0. 247 */ 248 left = (buf[0] & 0x04)? 1: 0; 249 middle = (buf[0] & 0x02)? 1: 0; 250 right = (buf[0] & 0x01)? 1: 0; 251 252 vsxxxaa_drop_bytes (mouse, 3); 253 254 DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", 255 mouse->name, mouse->phys, dx, dy, 256 left? "L": "l", middle? "M": "m", right? "R": "r"); 257 258 /* 259 * Report what we've found so far... 260 */ 261 input_regs (dev, regs); 262 input_report_key (dev, BTN_LEFT, left); 263 input_report_key (dev, BTN_MIDDLE, middle); 264 input_report_key (dev, BTN_RIGHT, right); 265 input_report_key (dev, BTN_TOUCH, 0); 266 input_report_rel (dev, REL_X, dx); 267 input_report_rel (dev, REL_Y, dy); 268 input_sync (dev); 269} 270 271static void 272vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs) 273{ 274 struct input_dev *dev = mouse->dev; 275 unsigned char *buf = mouse->buf; 276 int left, middle, right, touch; 277 int x, y; 278 279 /* 280 * Tablet position / button packet 281 * 282 * [0]: 1 1 0 B4 B3 B2 B1 Pr 283 * [1]: 0 0 X5 X4 X3 X2 X1 X0 284 * [2]: 0 0 X11 X10 X9 X8 X7 X6 285 * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0 286 * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6 287 */ 288 289 /* 290 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB 291 * counts down->top while monitor counts top->bottom. 292 */ 293 x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f); 294 y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f); 295 y = 1023 - y; 296 297 /* 298 * Get button state. It's bits <4..1> of byte 0. 299 */ 300 left = (buf[0] & 0x02)? 1: 0; 301 middle = (buf[0] & 0x04)? 1: 0; 302 right = (buf[0] & 0x08)? 1: 0; 303 touch = (buf[0] & 0x10)? 1: 0; 304 305 vsxxxaa_drop_bytes (mouse, 5); 306 307 DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", 308 mouse->name, mouse->phys, x, y, 309 left? "L": "l", middle? "M": "m", 310 right? "R": "r", touch? "T": "t"); 311 312 /* 313 * Report what we've found so far... 314 */ 315 input_regs (dev, regs); 316 input_report_key (dev, BTN_LEFT, left); 317 input_report_key (dev, BTN_MIDDLE, middle); 318 input_report_key (dev, BTN_RIGHT, right); 319 input_report_key (dev, BTN_TOUCH, touch); 320 input_report_abs (dev, ABS_X, x); 321 input_report_abs (dev, ABS_Y, y); 322 input_sync (dev); 323} 324 325static void 326vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs) 327{ 328 struct input_dev *dev = mouse->dev; 329 unsigned char *buf = mouse->buf; 330 int left, middle, right; 331 unsigned char error; 332 333 /* 334 * Check for Power-On-Reset packets. These are sent out 335 * after plugging the mouse in, or when explicitely 336 * requested by sending 'T'. 337 * 338 * [0]: 1 0 1 0 R3 R2 R1 R0 339 * [1]: 0 M2 M1 M0 D3 D2 D1 D0 340 * [2]: 0 E6 E5 E4 E3 E2 E1 E0 341 * [3]: 0 0 0 0 0 Left Middle Right 342 * 343 * M: manufacturer location code 344 * R: revision code 345 * E: Error code. If it's in the range of 0x00..0x1f, only some 346 * minor problem occured. Errors >= 0x20 are considered bad 347 * and the device may not work properly... 348 * D: <0010> == mouse, <0100> == tablet 349 */ 350 351 mouse->version = buf[0] & 0x0f; 352 mouse->country = (buf[1] >> 4) & 0x07; 353 mouse->type = buf[1] & 0x0f; 354 error = buf[2] & 0x7f; 355 356 /* 357 * Get button state. It's the low three bits 358 * (for three buttons) of byte 0. Maybe even the bit <3> 359 * has some meaning if a tablet is attached. 360 */ 361 left = (buf[0] & 0x04)? 1: 0; 362 middle = (buf[0] & 0x02)? 1: 0; 363 right = (buf[0] & 0x01)? 1: 0; 364 365 vsxxxaa_drop_bytes (mouse, 4); 366 vsxxxaa_detection_done (mouse); 367 368 if (error <= 0x1f) { 369 /* No (serious) error. Report buttons */ 370 input_regs (dev, regs); 371 input_report_key (dev, BTN_LEFT, left); 372 input_report_key (dev, BTN_MIDDLE, middle); 373 input_report_key (dev, BTN_RIGHT, right); 374 input_report_key (dev, BTN_TOUCH, 0); 375 input_sync (dev); 376 377 if (error != 0) 378 printk (KERN_INFO "Your %s on %s reports error=0x%02x\n", 379 mouse->name, mouse->phys, error); 380 381 } 382 383 /* 384 * If the mouse was hot-plugged, we need to force differential mode 385 * now... However, give it a second to recover from it's reset. 386 */ 387 printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " 388 "incremental streaming mode and 72 samples/sec\n", 389 mouse->name, mouse->phys); 390 mouse->serio->write (mouse->serio, 'S'); /* Standard format */ 391 mdelay (50); 392 mouse->serio->write (mouse->serio, 'R'); /* Incremental */ 393 mdelay (50); 394 mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */ 395} 396 397static void 398vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs) 399{ 400 unsigned char *buf = mouse->buf; 401 int stray_bytes; 402 403 /* 404 * Parse buffer to death... 405 */ 406 do { 407 /* 408 * Out of sync? Throw away what we don't understand. Each 409 * packet starts with a byte whose bit 7 is set. Unhandled 410 * packets (ie. which we don't know about or simply b0rk3d 411 * data...) will get shifted out of the buffer after some 412 * activity on the mouse. 413 */ 414 while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { 415 printk (KERN_ERR "%s on %s: Dropping a byte to regain " 416 "sync with mouse data stream...\n", 417 mouse->name, mouse->phys); 418 vsxxxaa_drop_bytes (mouse, 1); 419 } 420 421 /* 422 * Check for packets we know about. 423 */ 424 425 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) { 426 /* Check for broken packet */ 427 stray_bytes = vsxxxaa_check_packet (mouse, 3); 428 if (stray_bytes > 0) { 429 printk (KERN_ERR "Dropping %d bytes now...\n", 430 stray_bytes); 431 vsxxxaa_drop_bytes (mouse, stray_bytes); 432 continue; 433 } 434 435 vsxxxaa_handle_REL_packet (mouse, regs); 436 continue; /* More to parse? */ 437 } 438 439 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) { 440 /* Check for broken packet */ 441 stray_bytes = vsxxxaa_check_packet (mouse, 5); 442 if (stray_bytes > 0) { 443 printk (KERN_ERR "Dropping %d bytes now...\n", 444 stray_bytes); 445 vsxxxaa_drop_bytes (mouse, stray_bytes); 446 continue; 447 } 448 449 vsxxxaa_handle_ABS_packet (mouse, regs); 450 continue; /* More to parse? */ 451 } 452 453 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) { 454 /* Check for broken packet */ 455 stray_bytes = vsxxxaa_check_packet (mouse, 4); 456 if (stray_bytes > 0) { 457 printk (KERN_ERR "Dropping %d bytes now...\n", 458 stray_bytes); 459 vsxxxaa_drop_bytes (mouse, stray_bytes); 460 continue; 461 } 462 463 vsxxxaa_handle_POR_packet (mouse, regs); 464 continue; /* More to parse? */ 465 } 466 467 break; /* No REL, ABS or POR packet found */ 468 } while (1); 469} 470 471static irqreturn_t 472vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags, 473 struct pt_regs *regs) 474{ 475 struct vsxxxaa *mouse = serio_get_drvdata (serio); 476 477 vsxxxaa_queue_byte (mouse, data); 478 vsxxxaa_parse_buffer (mouse, regs); 479 480 return IRQ_HANDLED; 481} 482 483static void 484vsxxxaa_disconnect (struct serio *serio) 485{ 486 struct vsxxxaa *mouse = serio_get_drvdata (serio); 487 488 serio_close (serio); 489 serio_set_drvdata (serio, NULL); 490 input_unregister_device (mouse->dev); 491 kfree (mouse); 492} 493 494static int 495vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) 496{ 497 struct vsxxxaa *mouse; 498 struct input_dev *input_dev; 499 int err = -ENOMEM; 500 501 mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); 502 input_dev = input_allocate_device (); 503 if (!mouse || !input_dev) 504 goto fail; 505 506 mouse->dev = input_dev; 507 mouse->serio = serio; 508 strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", 509 sizeof (mouse->name)); 510 snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys); 511 512 input_dev->name = mouse->name; 513 input_dev->phys = mouse->phys; 514 input_dev->id.bustype = BUS_RS232; 515 input_dev->cdev.dev = &serio->dev; 516 input_dev->private = mouse; 517 518 set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ 519 set_bit (EV_REL, input_dev->evbit); 520 set_bit (EV_ABS, input_dev->evbit); 521 set_bit (BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ 522 set_bit (BTN_MIDDLE, input_dev->keybit); 523 set_bit (BTN_RIGHT, input_dev->keybit); 524 set_bit (BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ 525 set_bit (REL_X, input_dev->relbit); 526 set_bit (REL_Y, input_dev->relbit); 527 input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0); 528 input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0); 529 530 serio_set_drvdata (serio, mouse); 531 532 err = serio_open (serio, drv); 533 if (err) 534 goto fail; 535 536 /* 537 * Request selftest. Standard packet format and differential 538 * mode will be requested after the device ID'ed successfully. 539 */ 540 serio->write (serio, 'T'); /* Test */ 541 542 input_register_device (input_dev); 543 544 return 0; 545 546 fail: serio_set_drvdata (serio, NULL); 547 input_free_device (input_dev); 548 kfree (mouse); 549 return err; 550} 551 552static struct serio_device_id vsxxaa_serio_ids[] = { 553 { 554 .type = SERIO_RS232, 555 .proto = SERIO_VSXXXAA, 556 .id = SERIO_ANY, 557 .extra = SERIO_ANY, 558 }, 559 { 0 } 560}; 561 562MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids); 563 564static struct serio_driver vsxxxaa_drv = { 565 .driver = { 566 .name = "vsxxxaa", 567 }, 568 .description = DRIVER_DESC, 569 .id_table = vsxxaa_serio_ids, 570 .connect = vsxxxaa_connect, 571 .interrupt = vsxxxaa_interrupt, 572 .disconnect = vsxxxaa_disconnect, 573}; 574 575static int __init 576vsxxxaa_init (void) 577{ 578 serio_register_driver(&vsxxxaa_drv); 579 return 0; 580} 581 582static void __exit 583vsxxxaa_exit (void) 584{ 585 serio_unregister_driver(&vsxxxaa_drv); 586} 587 588module_init (vsxxxaa_init); 589module_exit (vsxxxaa_exit); 590