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