linux/drivers/input/mouse/vsxxxaa.c
<<
>>
Prefs
   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)                  \
 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
 114struct 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
 127static 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
 137static 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
 150static 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 */
 178static 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
 203static 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
 209static 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
 265static 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
 317static 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
 388static 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
 448static 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
 459static 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
 469static 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
 528static 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
 538MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
 539
 540static 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
 551module_serio_driver(vsxxxaa_drv);
 552