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