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