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