root/drivers/input/mouse/vsxxxaa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vsxxxaa_drop_bytes
  2. vsxxxaa_queue_byte
  3. vsxxxaa_detection_done
  4. vsxxxaa_check_packet
  5. vsxxxaa_smells_like_packet
  6. vsxxxaa_handle_REL_packet
  7. vsxxxaa_handle_ABS_packet
  8. vsxxxaa_handle_POR_packet
  9. vsxxxaa_parse_buffer
  10. vsxxxaa_interrupt
  11. vsxxxaa_disconnect
  12. vsxxxaa_connect

   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 
  76 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
  77 MODULE_DESCRIPTION(DRIVER_DESC);
  78 MODULE_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 
 101 struct 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 
 114 static 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 
 124 static 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 
 137 static 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  */
 165 static 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 
 190 static 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 
 196 static 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 
 252 static 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 
 304 static 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 
 375 static 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 
 435 static 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 
 446 static 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 
 456 static 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 
 515 static 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 
 525 MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
 526 
 527 static 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 
 538 module_serio_driver(vsxxxaa_drv);

/* [<][>][^][v][top][bottom][index][help] */