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