OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [input/] [joystick/] [grip_mp.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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;
324
        int flags, tries = 0, bads = 0;
325
 
326
        for (i = 0; i < ARRAY_SIZE(init_seq); 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
                        if (register_slot(slot, grip)) {
427
                                port->mode = GRIP_MODE_RESET;
428
                                port->dirty = 0;
429
                        }
430
                }
431
                return flags;
432
        }
433
 
434
        /* Handle non-grip device codes.  For now, just print diagnostics. */
435
 
436
        {
437
                static int strange_code = 0;
438
                if (strange_code != joytype) {
439
                        printk(KERN_INFO "Possible non-grip pad/joystick detected.\n");
440
                        printk(KERN_INFO "Got joy type 0x%x and packet 0x%x.\n", joytype, packet);
441
                        strange_code = joytype;
442
                }
443
        }
444
        return flags;
445
}
446
 
447
/*
448
 * Returns true if all multiport slot states appear valid.
449
 */
450
 
451
static int slots_valid(struct grip_mp *grip)
452
{
453
        int flags, slot, invalid = 0, active = 0;
454
 
455
        flags = get_and_decode_packet(grip, 0);
456
        if (!(flags & IO_GOT_PACKET))
457
                return 0;
458
 
459
        for (slot = 0; slot < 4; slot++) {
460
                if (grip->port[slot]->mode == GRIP_MODE_RESET)
461
                        invalid = 1;
462
                if (grip->port[slot]->mode != GRIP_MODE_NONE)
463
                        active = 1;
464
        }
465
 
466
        /* Return true if no active slot but multiport sent all its data */
467
        if (!active)
468
                return (flags & IO_DONE) ? 1 : 0;
469
 
470
        /* Return false if invalid device code received */
471
        return invalid ? 0 : 1;
472
}
473
 
474
/*
475
 * Returns whether the multiport was placed into digital mode and
476
 * able to communicate its state successfully.
477
 */
478
 
479
static int multiport_init(struct grip_mp *grip)
480
{
481
        int dig_mode, initialized = 0, tries = 0;
482
        u32 packet;
483
 
484
        dig_mode = dig_mode_start(grip->gameport, &packet);
485
        while (!dig_mode && tries < 4) {
486
                dig_mode = dig_mode_start(grip->gameport, &packet);
487
                tries++;
488
        }
489
 
490
        if (dig_mode)
491
                dbg("multiport_init(): digital mode activated.\n");
492
        else {
493
                dbg("multiport_init(): unable to activate digital mode.\n");
494
                return 0;
495
        }
496
 
497
        /* Get packets, store multiport state, and check state's validity */
498
        for (tries = 0; tries < 4096; tries++) {
499
                if (slots_valid(grip)) {
500
                        initialized = 1;
501
                        break;
502
                }
503
        }
504
        dbg("multiport_init(): initialized == %d\n", initialized);
505
        return initialized;
506
}
507
 
508
/*
509
 * Reports joystick state to the linux input layer.
510
 */
511
 
512
static void report_slot(struct grip_mp *grip, int slot)
513
{
514
        struct grip_port *port = grip->port[slot];
515
        int i;
516
 
517
        /* Store button states with linux input driver */
518
 
519
        for (i = 0; i < 8; i++)
520
                input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
521
 
522
        /* Store axis states with linux driver */
523
 
524
        input_report_abs(port->dev, ABS_X, port->xaxes);
525
        input_report_abs(port->dev, ABS_Y, port->yaxes);
526
 
527
        /* Tell the receiver of the events to process them */
528
 
529
        input_sync(port->dev);
530
 
531
        port->dirty = 0;
532
}
533
 
534
/*
535
 * Get the multiport state.
536
 */
537
 
538
static void grip_poll(struct gameport *gameport)
539
{
540
        struct grip_mp *grip = gameport_get_drvdata(gameport);
541
        int i, npkts, flags;
542
 
543
        for (npkts = 0; npkts < 4; npkts++) {
544
                flags = IO_RETRY;
545
                for (i = 0; i < 32; i++) {
546
                        flags = get_and_decode_packet(grip, flags);
547
                        if ((flags & IO_GOT_PACKET) || !(flags & IO_RETRY))
548
                                break;
549
                }
550
                if (flags & IO_DONE)
551
                        break;
552
        }
553
 
554
        for (i = 0; i < 4; i++)
555
                if (grip->port[i]->dirty)
556
                        report_slot(grip, i);
557
}
558
 
559
/*
560
 * Called when a joystick device file is opened
561
 */
562
 
563
static int grip_open(struct input_dev *dev)
564
{
565
        struct grip_mp *grip = input_get_drvdata(dev);
566
 
567
        gameport_start_polling(grip->gameport);
568
        return 0;
569
}
570
 
571
/*
572
 * Called when a joystick device file is closed
573
 */
574
 
575
static void grip_close(struct input_dev *dev)
576
{
577
        struct grip_mp *grip = input_get_drvdata(dev);
578
 
579
        gameport_stop_polling(grip->gameport);
580
}
581
 
582
/*
583
 * Tell the linux input layer about a newly plugged-in gamepad.
584
 */
585
 
586
static int register_slot(int slot, struct grip_mp *grip)
587
{
588
        struct grip_port *port = grip->port[slot];
589
        struct input_dev *input_dev;
590
        int j, t;
591
        int err;
592
 
593
        port->dev = input_dev = input_allocate_device();
594
        if (!input_dev)
595
                return -ENOMEM;
596
 
597
        input_dev->name = grip_name[port->mode];
598
        input_dev->id.bustype = BUS_GAMEPORT;
599
        input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
600
        input_dev->id.product = 0x0100 + port->mode;
601
        input_dev->id.version = 0x0100;
602
        input_dev->dev.parent = &grip->gameport->dev;
603
 
604
        input_set_drvdata(input_dev, grip);
605
 
606
        input_dev->open = grip_open;
607
        input_dev->close = grip_close;
608
 
609
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
610
 
611
        for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
612
                input_set_abs_params(input_dev, t, -1, 1, 0, 0);
613
 
614
        for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
615
                if (t > 0)
616
                        set_bit(t, input_dev->keybit);
617
 
618
        err = input_register_device(port->dev);
619
        if (err) {
620
                input_free_device(port->dev);
621
                return err;
622
        }
623
 
624
        port->registered = 1;
625
 
626
        if (port->dirty)                    /* report initial state, if any */
627
                report_slot(grip, slot);
628
 
629
        return 0;
630
}
631
 
632
static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
633
{
634
        struct grip_mp *grip;
635
        int err;
636
 
637
        if (!(grip = kzalloc(sizeof(struct grip_mp), GFP_KERNEL)))
638
                return -ENOMEM;
639
 
640
        grip->gameport = gameport;
641
 
642
        gameport_set_drvdata(gameport, grip);
643
 
644
        err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
645
        if (err)
646
                goto fail1;
647
 
648
        gameport_set_poll_handler(gameport, grip_poll);
649
        gameport_set_poll_interval(gameport, 20);
650
 
651
        if (!multiport_init(grip)) {
652
                err = -ENODEV;
653
                goto fail2;
654
        }
655
 
656
        if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
657
                /* nothing plugged in */
658
                err = -ENODEV;
659
                goto fail2;
660
        }
661
 
662
        return 0;
663
 
664
fail2:  gameport_close(gameport);
665
fail1:  gameport_set_drvdata(gameport, NULL);
666
        kfree(grip);
667
        return err;
668
}
669
 
670
static void grip_disconnect(struct gameport *gameport)
671
{
672
        struct grip_mp *grip = gameport_get_drvdata(gameport);
673
        int i;
674
 
675
        for (i = 0; i < 4; i++)
676
                if (grip->port[i]->registered)
677
                        input_unregister_device(grip->port[i]->dev);
678
        gameport_close(gameport);
679
        gameport_set_drvdata(gameport, NULL);
680
        kfree(grip);
681
}
682
 
683
static struct gameport_driver grip_drv = {
684
        .driver         = {
685
                .name   = "grip_mp",
686
        },
687
        .description    = DRIVER_DESC,
688
        .connect        = grip_connect,
689
        .disconnect     = grip_disconnect,
690
};
691
 
692
static int __init grip_init(void)
693
{
694
        gameport_register_driver(&grip_drv);
695
        return 0;
696
}
697
 
698
static void __exit grip_exit(void)
699
{
700
        gameport_unregister_driver(&grip_drv);
701
}
702
 
703
module_init(grip_init);
704
module_exit(grip_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.