linux/drivers/input/joystick/grip_mp.c
<<
>>
Prefs
   1/*
   2 *  Driver for the Gravis Grip Multiport, a gamepad "hub" that
   3 *  connects up to four 9-pin digital gamepads/joysticks.
   4 *  Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5.
   5 *
   6 *  Thanks to Chris Gassib for helpful advice.
   7 *
   8 *  Copyright (c)      2002 Brian Bonnlander, Bill Soudan
   9 *  Copyright (c) 1998-2000 Vojtech Pavlik
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/slab.h>
  15#include <linux/gameport.h>
  16#include <linux/input.h>
  17#include <linux/delay.h>
  18#include <linux/proc_fs.h>
  19#include <linux/jiffies.h>
  20
  21#define DRIVER_DESC     "Gravis Grip Multiport driver"
  22
  23MODULE_AUTHOR("Brian Bonnlander");
  24MODULE_DESCRIPTION(DRIVER_DESC);
  25MODULE_LICENSE("GPL");
  26
  27#ifdef GRIP_DEBUG
  28#define dbg(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
  29#else
  30#define dbg(format, arg...) do {} while (0)
  31#endif
  32
  33#define GRIP_MAX_PORTS  4
  34/*
  35 * Grip multiport state
  36 */
  37
  38struct grip_port {
  39        struct input_dev *dev;
  40        int mode;
  41        int registered;
  42
  43        /* individual gamepad states */
  44        int buttons;
  45        int xaxes;
  46        int yaxes;
  47        int dirty;     /* has the state been updated? */
  48};
  49
  50struct grip_mp {
  51        struct gameport *gameport;
  52        struct grip_port *port[GRIP_MAX_PORTS];
  53        int reads;
  54        int bads;
  55};
  56
  57/*
  58 * Multiport packet interpretation
  59 */
  60
  61#define PACKET_FULL          0x80000000       /* packet is full                        */
  62#define PACKET_IO_FAST       0x40000000       /* 3 bits per gameport read              */
  63#define PACKET_IO_SLOW       0x20000000       /* 1 bit per gameport read               */
  64#define PACKET_MP_MORE       0x04000000       /* multiport wants to send more          */
  65#define PACKET_MP_DONE       0x02000000       /* multiport done sending                */
  66
  67/*
  68 * Packet status code interpretation
  69 */
  70
  71#define IO_GOT_PACKET        0x0100           /* Got a packet                           */
  72#define IO_MODE_FAST         0x0200           /* Used 3 data bits per gameport read     */
  73#define IO_SLOT_CHANGE       0x0800           /* Multiport physical slot status changed */
  74#define IO_DONE              0x1000           /* Multiport is done sending packets      */
  75#define IO_RETRY             0x4000           /* Try again later to get packet          */
  76#define IO_RESET             0x8000           /* Force multiport to resend all packets  */
  77
  78/*
  79 * Gamepad configuration data.  Other 9-pin digital joystick devices
  80 * may work with the multiport, so this may not be an exhaustive list!
  81 * Commodore 64 joystick remains untested.
  82 */
  83
  84#define GRIP_INIT_DELAY         2000          /*  2 ms */
  85
  86#define GRIP_MODE_NONE          0
  87#define GRIP_MODE_RESET         1
  88#define GRIP_MODE_GP            2
  89#define GRIP_MODE_C64           3
  90
  91static const int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
  92static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
  93
  94static const int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
  95static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
  96
  97static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
  98static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
  99
 100static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
 101
 102static const int init_seq[] = {
 103        1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
 104        1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
 105        1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
 106        0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1 };
 107
 108/* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */
 109
 110static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
 111
 112static int register_slot(int i, struct grip_mp *grip);
 113
 114/*
 115 * Returns whether an odd or even number of bits are on in pkt.
 116 */
 117
 118static int bit_parity(u32 pkt)
 119{
 120        int x = pkt ^ (pkt >> 16);
 121        x ^= x >> 8;
 122        x ^= x >> 4;
 123        x ^= x >> 2;
 124        x ^= x >> 1;
 125        return x & 1;
 126}
 127
 128/*
 129 * Poll gameport; return true if all bits set in 'onbits' are on and
 130 * all bits set in 'offbits' are off.
 131 */
 132
 133static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport* gp, u8 *data)
 134{
 135        int i, nloops;
 136
 137        nloops = gameport_time(gp, u_sec);
 138        for (i = 0; i < nloops; i++) {
 139                *data = gameport_read(gp);
 140                if ((*data & onbits) == onbits &&
 141                    (~(*data) & offbits) == offbits)
 142                        return 1;
 143        }
 144        dbg("gameport timed out after %d microseconds.\n", u_sec);
 145        return 0;
 146}
 147
 148/*
 149 * Gets a 28-bit packet from the multiport.
 150 *
 151 * After getting a packet successfully, commands encoded by sendcode may
 152 * be sent to the multiport.
 153 *
 154 * The multiport clock value is reflected in gameport bit B4.
 155 *
 156 * Returns a packet status code indicating whether packet is valid, the transfer
 157 * mode, and any error conditions.
 158 *
 159 * sendflags:      current I/O status
 160 * sendcode:   data to send to the multiport if sendflags is nonzero
 161 */
 162
 163static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
 164{
 165        u8  raw_data;            /* raw data from gameport */
 166        u8  data_mask;           /* packet data bits from raw_data */
 167        u32 pkt;                 /* packet temporary storage */
 168        int bits_per_read;       /* num packet bits per gameport read */
 169        int portvals = 0;        /* used for port value sanity check */
 170        int i;
 171
 172        /* Gameport bits B0, B4, B5 should first be off, then B4 should come on. */
 173
 174        *packet = 0;
 175        raw_data = gameport_read(gameport);
 176        if (raw_data & 1)
 177                return IO_RETRY;
 178
 179        for (i = 0; i < 64; i++) {
 180                raw_data = gameport_read(gameport);
 181                portvals |= 1 << ((raw_data >> 4) & 3); /* Demux B4, B5 */
 182        }
 183
 184        if (portvals == 1) {                            /* B4, B5 off */
 185                raw_data = gameport_read(gameport);
 186                portvals = raw_data & 0xf0;
 187
 188                if (raw_data & 0x31)
 189                        return IO_RESET;
 190                gameport_trigger(gameport);
 191
 192                if (!poll_until(0x10, 0, 308, gameport, &raw_data))
 193                        return IO_RESET;
 194        } else
 195                return IO_RETRY;
 196
 197        /* Determine packet transfer mode and prepare for packet construction. */
 198
 199        if (raw_data & 0x20) {                 /* 3 data bits/read */
 200                portvals |= raw_data >> 4;     /* Compare B4-B7 before & after trigger */
 201
 202                if (portvals != 0xb)
 203                        return 0;
 204                data_mask = 7;
 205                bits_per_read = 3;
 206                pkt = (PACKET_FULL | PACKET_IO_FAST) >> 28;
 207        } else {                                 /* 1 data bit/read */
 208                data_mask = 1;
 209                bits_per_read = 1;
 210                pkt = (PACKET_FULL | PACKET_IO_SLOW) >> 28;
 211        }
 212
 213        /* Construct a packet.  Final data bits must be zero. */
 214
 215        while (1) {
 216                if (!poll_until(0, 0x10, 77, gameport, &raw_data))
 217                        return IO_RESET;
 218                raw_data = (raw_data >> 5) & data_mask;
 219
 220                if (pkt & PACKET_FULL)
 221                        break;
 222                pkt = (pkt << bits_per_read) | raw_data;
 223
 224                if (!poll_until(0x10, 0, 77, gameport, &raw_data))
 225                        return IO_RESET;
 226        }
 227
 228        if (raw_data)
 229                return IO_RESET;
 230
 231        /* If 3 bits/read used, drop from 30 bits to 28. */
 232
 233        if (bits_per_read == 3) {
 234                pkt = (pkt & 0xffff0000) | ((pkt << 1) & 0xffff);
 235                pkt = (pkt >> 2) | 0xf0000000;
 236        }
 237
 238        if (bit_parity(pkt) == 1)
 239                return IO_RESET;
 240
 241        /* Acknowledge packet receipt */
 242
 243        if (!poll_until(0x30, 0, 77, gameport, &raw_data))
 244                return IO_RESET;
 245
 246        raw_data = gameport_read(gameport);
 247
 248        if (raw_data & 1)
 249                return IO_RESET;
 250
 251        gameport_trigger(gameport);
 252
 253        if (!poll_until(0, 0x20, 77, gameport, &raw_data))
 254                return IO_RESET;
 255
 256        /* Return if we just wanted the packet or multiport wants to send more */
 257
 258        *packet = pkt;
 259        if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
 260                return IO_GOT_PACKET;
 261
 262        if (pkt & PACKET_MP_MORE)
 263                return IO_GOT_PACKET | IO_RETRY;
 264
 265        /* Multiport is done sending packets and is ready to receive data */
 266
 267        if (!poll_until(0x20, 0, 77, gameport, &raw_data))
 268                return IO_GOT_PACKET | IO_RESET;
 269
 270        raw_data = gameport_read(gameport);
 271        if (raw_data & 1)
 272                return IO_GOT_PACKET | IO_RESET;
 273
 274        /* Trigger gameport based on bits in sendcode */
 275
 276        gameport_trigger(gameport);
 277        do {
 278                if (!poll_until(0x20, 0x10, 116, gameport, &raw_data))
 279                        return IO_GOT_PACKET | IO_RESET;
 280
 281                if (!poll_until(0x30, 0, 193, gameport, &raw_data))
 282                        return IO_GOT_PACKET | IO_RESET;
 283
 284                if (raw_data & 1)
 285                        return IO_GOT_PACKET | IO_RESET;
 286
 287                if (sendcode & 1)
 288                        gameport_trigger(gameport);
 289
 290                sendcode >>= 1;
 291        } while (sendcode);
 292
 293        return IO_GOT_PACKET | IO_MODE_FAST;
 294}
 295
 296/*
 297 * Disables and restores interrupts for mp_io(), which does the actual I/O.
 298 */
 299
 300static int multiport_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
 301{
 302        int status;
 303        unsigned long flags;
 304
 305        local_irq_save(flags);
 306        status = mp_io(gameport, sendflags, sendcode, packet);
 307        local_irq_restore(flags);
 308
 309        return status;
 310}
 311
 312/*
 313 * Puts multiport into digital mode.  Multiport LED turns green.
 314 *
 315 * Returns true if a valid digital packet was received, false otherwise.
 316 */
 317
 318static int dig_mode_start(struct gameport *gameport, u32 *packet)
 319{
 320        int i;
 321        int flags, tries = 0, bads = 0;
 322
 323        for (i = 0; i < ARRAY_SIZE(init_seq); i++) {     /* Send magic sequence */
 324                if (init_seq[i])
 325                        gameport_trigger(gameport);
 326                udelay(GRIP_INIT_DELAY);
 327        }
 328
 329        for (i = 0; i < 16; i++)            /* Wait for multiport to settle */
 330                udelay(GRIP_INIT_DELAY);
 331
 332        while (tries < 64 && bads < 8) {    /* Reset multiport and try getting a packet */
 333
 334                flags = multiport_io(gameport, IO_RESET, 0x27, packet);
 335
 336                if (flags & IO_MODE_FAST)
 337                        return 1;
 338
 339                if (flags & IO_RETRY)
 340                        tries++;
 341                else
 342                        bads++;
 343        }
 344        return 0;
 345}
 346
 347/*
 348 * Packet structure: B0-B15   => gamepad state
 349 *                   B16-B20  => gamepad device type
 350 *                   B21-B24  => multiport slot index (1-4)
 351 *
 352 * Known device types: 0x1f (grip pad), 0x0 (no device).  Others may exist.
 353 *
 354 * Returns the packet status.
 355 */
 356
 357static int get_and_decode_packet(struct grip_mp *grip, int flags)
 358{
 359        struct grip_port *port;
 360        u32 packet;
 361        int joytype = 0;
 362        int slot;
 363
 364        /* Get a packet and check for validity */
 365
 366        flags &= IO_RESET | IO_RETRY;
 367        flags = multiport_io(grip->gameport, flags, 0, &packet);
 368        grip->reads++;
 369
 370        if (packet & PACKET_MP_DONE)
 371                flags |= IO_DONE;
 372
 373        if (flags && !(flags & IO_GOT_PACKET)) {
 374                grip->bads++;
 375                return flags;
 376        }
 377
 378        /* Ignore non-gamepad packets, e.g. multiport hardware version */
 379
 380        slot = ((packet >> 21) & 0xf) - 1;
 381        if ((slot < 0) || (slot > 3))
 382                return flags;
 383
 384        port = grip->port[slot];
 385
 386        /*
 387         * Handle "reset" packets, which occur at startup, and when gamepads
 388         * are removed or plugged in.  May contain configuration of a new gamepad.
 389         */
 390
 391        joytype = (packet >> 16) & 0x1f;
 392        if (!joytype) {
 393
 394                if (port->registered) {
 395                        printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
 396                               grip_name[port->mode], slot);
 397                        input_unregister_device(port->dev);
 398                        port->registered = 0;
 399                }
 400                dbg("Reset: grip multiport slot %d\n", slot);
 401                port->mode = GRIP_MODE_RESET;
 402                flags |= IO_SLOT_CHANGE;
 403                return flags;
 404        }
 405
 406        /* Interpret a grip pad packet */
 407
 408        if (joytype == 0x1f) {
 409
 410                int dir = (packet >> 8) & 0xf;          /* eight way directional value */
 411                port->buttons = (~packet) & 0xff;
 412                port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
 413                port->xaxes = (axis_map[dir] & 3) - 1;
 414                port->dirty = 1;
 415
 416                if (port->mode == GRIP_MODE_RESET)
 417                        flags |= IO_SLOT_CHANGE;
 418
 419                port->mode = GRIP_MODE_GP;
 420
 421                if (!port->registered) {
 422                        dbg("New Grip pad in multiport slot %d.\n", slot);
 423                        if (register_slot(slot, grip)) {
 424                                port->mode = GRIP_MODE_RESET;
 425                                port->dirty = 0;
 426                        }
 427                }
 428                return flags;
 429        }
 430
 431        /* Handle non-grip device codes.  For now, just print diagnostics. */
 432
 433        {
 434                static int strange_code = 0;
 435                if (strange_code != joytype) {
 436                        printk(KERN_INFO "Possible non-grip pad/joystick detected.\n");
 437                        printk(KERN_INFO "Got joy type 0x%x and packet 0x%x.\n", joytype, packet);
 438                        strange_code = joytype;
 439                }
 440        }
 441        return flags;
 442}
 443
 444/*
 445 * Returns true if all multiport slot states appear valid.
 446 */
 447
 448static int slots_valid(struct grip_mp *grip)
 449{
 450        int flags, slot, invalid = 0, active = 0;
 451
 452        flags = get_and_decode_packet(grip, 0);
 453        if (!(flags & IO_GOT_PACKET))
 454                return 0;
 455
 456        for (slot = 0; slot < 4; slot++) {
 457                if (grip->port[slot]->mode == GRIP_MODE_RESET)
 458                        invalid = 1;
 459                if (grip->port[slot]->mode != GRIP_MODE_NONE)
 460                        active = 1;
 461        }
 462
 463        /* Return true if no active slot but multiport sent all its data */
 464        if (!active)
 465                return (flags & IO_DONE) ? 1 : 0;
 466
 467        /* Return false if invalid device code received */
 468        return invalid ? 0 : 1;
 469}
 470
 471/*
 472 * Returns whether the multiport was placed into digital mode and
 473 * able to communicate its state successfully.
 474 */
 475
 476static int multiport_init(struct grip_mp *grip)
 477{
 478        int dig_mode, initialized = 0, tries = 0;
 479        u32 packet;
 480
 481        dig_mode = dig_mode_start(grip->gameport, &packet);
 482        while (!dig_mode && tries < 4) {
 483                dig_mode = dig_mode_start(grip->gameport, &packet);
 484                tries++;
 485        }
 486
 487        if (dig_mode)
 488                dbg("multiport_init(): digital mode activated.\n");
 489        else {
 490                dbg("multiport_init(): unable to activate digital mode.\n");
 491                return 0;
 492        }
 493
 494        /* Get packets, store multiport state, and check state's validity */
 495        for (tries = 0; tries < 4096; tries++) {
 496                if (slots_valid(grip)) {
 497                        initialized = 1;
 498                        break;
 499                }
 500        }
 501        dbg("multiport_init(): initialized == %d\n", initialized);
 502        return initialized;
 503}
 504
 505/*
 506 * Reports joystick state to the linux input layer.
 507 */
 508
 509static void report_slot(struct grip_mp *grip, int slot)
 510{
 511        struct grip_port *port = grip->port[slot];
 512        int i;
 513
 514        /* Store button states with linux input driver */
 515
 516        for (i = 0; i < 8; i++)
 517                input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
 518
 519        /* Store axis states with linux driver */
 520
 521        input_report_abs(port->dev, ABS_X, port->xaxes);
 522        input_report_abs(port->dev, ABS_Y, port->yaxes);
 523
 524        /* Tell the receiver of the events to process them */
 525
 526        input_sync(port->dev);
 527
 528        port->dirty = 0;
 529}
 530
 531/*
 532 * Get the multiport state.
 533 */
 534
 535static void grip_poll(struct gameport *gameport)
 536{
 537        struct grip_mp *grip = gameport_get_drvdata(gameport);
 538        int i, npkts, flags;
 539
 540        for (npkts = 0; npkts < 4; npkts++) {
 541                flags = IO_RETRY;
 542                for (i = 0; i < 32; i++) {
 543                        flags = get_and_decode_packet(grip, flags);
 544                        if ((flags & IO_GOT_PACKET) || !(flags & IO_RETRY))
 545                                break;
 546                }
 547                if (flags & IO_DONE)
 548                        break;
 549        }
 550
 551        for (i = 0; i < 4; i++)
 552                if (grip->port[i]->dirty)
 553                        report_slot(grip, i);
 554}
 555
 556/*
 557 * Called when a joystick device file is opened
 558 */
 559
 560static int grip_open(struct input_dev *dev)
 561{
 562        struct grip_mp *grip = input_get_drvdata(dev);
 563
 564        gameport_start_polling(grip->gameport);
 565        return 0;
 566}
 567
 568/*
 569 * Called when a joystick device file is closed
 570 */
 571
 572static void grip_close(struct input_dev *dev)
 573{
 574        struct grip_mp *grip = input_get_drvdata(dev);
 575
 576        gameport_stop_polling(grip->gameport);
 577}
 578
 579/*
 580 * Tell the linux input layer about a newly plugged-in gamepad.
 581 */
 582
 583static int register_slot(int slot, struct grip_mp *grip)
 584{
 585        struct grip_port *port = grip->port[slot];
 586        struct input_dev *input_dev;
 587        int j, t;
 588        int err;
 589
 590        port->dev = input_dev = input_allocate_device();
 591        if (!input_dev)
 592                return -ENOMEM;
 593
 594        input_dev->name = grip_name[port->mode];
 595        input_dev->id.bustype = BUS_GAMEPORT;
 596        input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
 597        input_dev->id.product = 0x0100 + port->mode;
 598        input_dev->id.version = 0x0100;
 599        input_dev->dev.parent = &grip->gameport->dev;
 600
 601        input_set_drvdata(input_dev, grip);
 602
 603        input_dev->open = grip_open;
 604        input_dev->close = grip_close;
 605
 606        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 607
 608        for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
 609                input_set_abs_params(input_dev, t, -1, 1, 0, 0);
 610
 611        for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
 612                if (t > 0)
 613                        set_bit(t, input_dev->keybit);
 614
 615        err = input_register_device(port->dev);
 616        if (err) {
 617                input_free_device(port->dev);
 618                return err;
 619        }
 620
 621        port->registered = 1;
 622
 623        if (port->dirty)                    /* report initial state, if any */
 624                report_slot(grip, slot);
 625
 626        return 0;
 627}
 628
 629static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
 630{
 631        struct grip_mp *grip;
 632        int err;
 633
 634        if (!(grip = kzalloc(sizeof(struct grip_mp), GFP_KERNEL)))
 635                return -ENOMEM;
 636
 637        grip->gameport = gameport;
 638
 639        gameport_set_drvdata(gameport, grip);
 640
 641        err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
 642        if (err)
 643                goto fail1;
 644
 645        gameport_set_poll_handler(gameport, grip_poll);
 646        gameport_set_poll_interval(gameport, 20);
 647
 648        if (!multiport_init(grip)) {
 649                err = -ENODEV;
 650                goto fail2;
 651        }
 652
 653        if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
 654                /* nothing plugged in */
 655                err = -ENODEV;
 656                goto fail2;
 657        }
 658
 659        return 0;
 660
 661fail2:  gameport_close(gameport);
 662fail1:  gameport_set_drvdata(gameport, NULL);
 663        kfree(grip);
 664        return err;
 665}
 666
 667static void grip_disconnect(struct gameport *gameport)
 668{
 669        struct grip_mp *grip = gameport_get_drvdata(gameport);
 670        int i;
 671
 672        for (i = 0; i < 4; i++)
 673                if (grip->port[i]->registered)
 674                        input_unregister_device(grip->port[i]->dev);
 675        gameport_close(gameport);
 676        gameport_set_drvdata(gameport, NULL);
 677        kfree(grip);
 678}
 679
 680static struct gameport_driver grip_drv = {
 681        .driver         = {
 682                .name   = "grip_mp",
 683        },
 684        .description    = DRIVER_DESC,
 685        .connect        = grip_connect,
 686        .disconnect     = grip_disconnect,
 687};
 688
 689module_gameport_driver(grip_drv);
 690