Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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.