1
2
3
4
5
6
7
8
9
10
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/gameport.h>
16#include <linux/input.h>
17#include <linux/delay.h>
18#include <linux/proc_fs.h>
19#include <linux/jiffies.h>
20
21#define DRIVER_DESC "Gravis Grip Multiport driver"
22
23MODULE_AUTHOR("Brian Bonnlander");
24MODULE_DESCRIPTION(DRIVER_DESC);
25MODULE_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#define GRIP_MAX_PORTS 4
34
35
36
37
38struct grip_port {
39 struct input_dev *dev;
40 int mode;
41 int registered;
42
43
44 int buttons;
45 int xaxes;
46 int yaxes;
47 int dirty;
48};
49
50struct grip_mp {
51 struct gameport *gameport;
52 struct grip_port *port[GRIP_MAX_PORTS];
53 int reads;
54 int bads;
55};
56
57
58
59
60
61#define PACKET_FULL 0x80000000
62#define PACKET_IO_FAST 0x40000000
63#define PACKET_IO_SLOW 0x20000000
64#define PACKET_MP_MORE 0x04000000
65#define PACKET_MP_DONE 0x02000000
66
67
68
69
70
71#define IO_GOT_PACKET 0x0100
72#define IO_MODE_FAST 0x0200
73#define IO_SLOT_CHANGE 0x0800
74#define IO_DONE 0x1000
75#define IO_RETRY 0x4000
76#define IO_RESET 0x8000
77
78
79
80
81
82
83
84#define GRIP_INIT_DELAY 2000
85
86#define GRIP_MODE_NONE 0
87#define GRIP_MODE_RESET 1
88#define GRIP_MODE_GP 2
89#define GRIP_MODE_C64 3
90
91static const int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
92static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
93
94static const int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
95static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
96
97static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
98static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
99
100static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
101
102static const int init_seq[] = {
103 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
104 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
105 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
106 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1 };
107
108
109
110static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
111
112static int register_slot(int i, struct grip_mp *grip);
113
114
115
116
117
118static int bit_parity(u32 pkt)
119{
120 int x = pkt ^ (pkt >> 16);
121 x ^= x >> 8;
122 x ^= x >> 4;
123 x ^= x >> 2;
124 x ^= x >> 1;
125 return x & 1;
126}
127
128
129
130
131
132
133static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport* gp, u8 *data)
134{
135 int i, nloops;
136
137 nloops = gameport_time(gp, u_sec);
138 for (i = 0; i < nloops; i++) {
139 *data = gameport_read(gp);
140 if ((*data & onbits) == onbits &&
141 (~(*data) & offbits) == offbits)
142 return 1;
143 }
144 dbg("gameport timed out after %d microseconds.\n", u_sec);
145 return 0;
146}
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
164{
165 u8 raw_data;
166 u8 data_mask;
167 u32 pkt;
168 int bits_per_read;
169 int portvals = 0;
170 int i;
171
172
173
174 *packet = 0;
175 raw_data = gameport_read(gameport);
176 if (raw_data & 1)
177 return IO_RETRY;
178
179 for (i = 0; i < 64; i++) {
180 raw_data = gameport_read(gameport);
181 portvals |= 1 << ((raw_data >> 4) & 3);
182 }
183
184 if (portvals == 1) {
185 raw_data = gameport_read(gameport);
186 portvals = raw_data & 0xf0;
187
188 if (raw_data & 0x31)
189 return IO_RESET;
190 gameport_trigger(gameport);
191
192 if (!poll_until(0x10, 0, 308, gameport, &raw_data))
193 return IO_RESET;
194 } else
195 return IO_RETRY;
196
197
198
199 if (raw_data & 0x20) {
200 portvals |= raw_data >> 4;
201
202 if (portvals != 0xb)
203 return 0;
204 data_mask = 7;
205 bits_per_read = 3;
206 pkt = (PACKET_FULL | PACKET_IO_FAST) >> 28;
207 } else {
208 data_mask = 1;
209 bits_per_read = 1;
210 pkt = (PACKET_FULL | PACKET_IO_SLOW) >> 28;
211 }
212
213
214
215 while (1) {
216 if (!poll_until(0, 0x10, 77, gameport, &raw_data))
217 return IO_RESET;
218 raw_data = (raw_data >> 5) & data_mask;
219
220 if (pkt & PACKET_FULL)
221 break;
222 pkt = (pkt << bits_per_read) | raw_data;
223
224 if (!poll_until(0x10, 0, 77, gameport, &raw_data))
225 return IO_RESET;
226 }
227
228 if (raw_data)
229 return IO_RESET;
230
231
232
233 if (bits_per_read == 3) {
234 pkt = (pkt & 0xffff0000) | ((pkt << 1) & 0xffff);
235 pkt = (pkt >> 2) | 0xf0000000;
236 }
237
238 if (bit_parity(pkt) == 1)
239 return IO_RESET;
240
241
242
243 if (!poll_until(0x30, 0, 77, gameport, &raw_data))
244 return IO_RESET;
245
246 raw_data = gameport_read(gameport);
247
248 if (raw_data & 1)
249 return IO_RESET;
250
251 gameport_trigger(gameport);
252
253 if (!poll_until(0, 0x20, 77, gameport, &raw_data))
254 return IO_RESET;
255
256
257
258 *packet = pkt;
259 if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
260 return IO_GOT_PACKET;
261
262 if (pkt & PACKET_MP_MORE)
263 return IO_GOT_PACKET | IO_RETRY;
264
265
266
267 if (!poll_until(0x20, 0, 77, gameport, &raw_data))
268 return IO_GOT_PACKET | IO_RESET;
269
270 raw_data = gameport_read(gameport);
271 if (raw_data & 1)
272 return IO_GOT_PACKET | IO_RESET;
273
274
275
276 gameport_trigger(gameport);
277 do {
278 if (!poll_until(0x20, 0x10, 116, gameport, &raw_data))
279 return IO_GOT_PACKET | IO_RESET;
280
281 if (!poll_until(0x30, 0, 193, gameport, &raw_data))
282 return IO_GOT_PACKET | IO_RESET;
283
284 if (raw_data & 1)
285 return IO_GOT_PACKET | IO_RESET;
286
287 if (sendcode & 1)
288 gameport_trigger(gameport);
289
290 sendcode >>= 1;
291 } while (sendcode);
292
293 return IO_GOT_PACKET | IO_MODE_FAST;
294}
295
296
297
298
299
300static int multiport_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
301{
302 int status;
303 unsigned long flags;
304
305 local_irq_save(flags);
306 status = mp_io(gameport, sendflags, sendcode, packet);
307 local_irq_restore(flags);
308
309 return status;
310}
311
312
313
314
315
316
317
318static int dig_mode_start(struct gameport *gameport, u32 *packet)
319{
320 int i;
321 int flags, tries = 0, bads = 0;
322
323 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
324 if (init_seq[i])
325 gameport_trigger(gameport);
326 udelay(GRIP_INIT_DELAY);
327 }
328
329 for (i = 0; i < 16; i++)
330 udelay(GRIP_INIT_DELAY);
331
332 while (tries < 64 && bads < 8) {
333
334 flags = multiport_io(gameport, IO_RESET, 0x27, packet);
335
336 if (flags & IO_MODE_FAST)
337 return 1;
338
339 if (flags & IO_RETRY)
340 tries++;
341 else
342 bads++;
343 }
344 return 0;
345}
346
347
348
349
350
351
352
353
354
355
356
357static int get_and_decode_packet(struct grip_mp *grip, int flags)
358{
359 struct grip_port *port;
360 u32 packet;
361 int joytype = 0;
362 int slot;
363
364
365
366 flags &= IO_RESET | IO_RETRY;
367 flags = multiport_io(grip->gameport, flags, 0, &packet);
368 grip->reads++;
369
370 if (packet & PACKET_MP_DONE)
371 flags |= IO_DONE;
372
373 if (flags && !(flags & IO_GOT_PACKET)) {
374 grip->bads++;
375 return flags;
376 }
377
378
379
380 slot = ((packet >> 21) & 0xf) - 1;
381 if ((slot < 0) || (slot > 3))
382 return flags;
383
384 port = grip->port[slot];
385
386
387
388
389
390
391 joytype = (packet >> 16) & 0x1f;
392 if (!joytype) {
393
394 if (port->registered) {
395 printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
396 grip_name[port->mode], slot);
397 input_unregister_device(port->dev);
398 port->registered = 0;
399 }
400 dbg("Reset: grip multiport slot %d\n", slot);
401 port->mode = GRIP_MODE_RESET;
402 flags |= IO_SLOT_CHANGE;
403 return flags;
404 }
405
406
407
408 if (joytype == 0x1f) {
409
410 int dir = (packet >> 8) & 0xf;
411 port->buttons = (~packet) & 0xff;
412 port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
413 port->xaxes = (axis_map[dir] & 3) - 1;
414 port->dirty = 1;
415
416 if (port->mode == GRIP_MODE_RESET)
417 flags |= IO_SLOT_CHANGE;
418
419 port->mode = GRIP_MODE_GP;
420
421 if (!port->registered) {
422 dbg("New Grip pad in multiport slot %d.\n", slot);
423 if (register_slot(slot, grip)) {
424 port->mode = GRIP_MODE_RESET;
425 port->dirty = 0;
426 }
427 }
428 return flags;
429 }
430
431
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
446
447
448static 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
464 if (!active)
465 return (flags & IO_DONE) ? 1 : 0;
466
467
468 return invalid ? 0 : 1;
469}
470
471
472
473
474
475
476static 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
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
507
508
509static void report_slot(struct grip_mp *grip, int slot)
510{
511 struct grip_port *port = grip->port[slot];
512 int i;
513
514
515
516 for (i = 0; i < 8; i++)
517 input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
518
519
520
521 input_report_abs(port->dev, ABS_X, port->xaxes);
522 input_report_abs(port->dev, ABS_Y, port->yaxes);
523
524
525
526 input_sync(port->dev);
527
528 port->dirty = 0;
529}
530
531
532
533
534
535static 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
558
559
560static int grip_open(struct input_dev *dev)
561{
562 struct grip_mp *grip = input_get_drvdata(dev);
563
564 gameport_start_polling(grip->gameport);
565 return 0;
566}
567
568
569
570
571
572static void grip_close(struct input_dev *dev)
573{
574 struct grip_mp *grip = input_get_drvdata(dev);
575
576 gameport_stop_polling(grip->gameport);
577}
578
579
580
581
582
583static 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 int err;
589
590 port->dev = input_dev = input_allocate_device();
591 if (!input_dev)
592 return -ENOMEM;
593
594 input_dev->name = grip_name[port->mode];
595 input_dev->id.bustype = BUS_GAMEPORT;
596 input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
597 input_dev->id.product = 0x0100 + port->mode;
598 input_dev->id.version = 0x0100;
599 input_dev->dev.parent = &grip->gameport->dev;
600
601 input_set_drvdata(input_dev, grip);
602
603 input_dev->open = grip_open;
604 input_dev->close = grip_close;
605
606 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
607
608 for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
609 input_set_abs_params(input_dev, t, -1, 1, 0, 0);
610
611 for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
612 if (t > 0)
613 set_bit(t, input_dev->keybit);
614
615 err = input_register_device(port->dev);
616 if (err) {
617 input_free_device(port->dev);
618 return err;
619 }
620
621 port->registered = 1;
622
623 if (port->dirty)
624 report_slot(grip, slot);
625
626 return 0;
627}
628
629static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
630{
631 struct grip_mp *grip;
632 int err;
633
634 if (!(grip = kzalloc(sizeof(struct grip_mp), GFP_KERNEL)))
635 return -ENOMEM;
636
637 grip->gameport = gameport;
638
639 gameport_set_drvdata(gameport, grip);
640
641 err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
642 if (err)
643 goto fail1;
644
645 gameport_set_poll_handler(gameport, grip_poll);
646 gameport_set_poll_interval(gameport, 20);
647
648 if (!multiport_init(grip)) {
649 err = -ENODEV;
650 goto fail2;
651 }
652
653 if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
654
655 err = -ENODEV;
656 goto fail2;
657 }
658
659 return 0;
660
661fail2: gameport_close(gameport);
662fail1: gameport_set_drvdata(gameport, NULL);
663 kfree(grip);
664 return err;
665}
666
667static void grip_disconnect(struct gameport *gameport)
668{
669 struct grip_mp *grip = gameport_get_drvdata(gameport);
670 int i;
671
672 for (i = 0; i < 4; i++)
673 if (grip->port[i]->registered)
674 input_unregister_device(grip->port[i]->dev);
675 gameport_close(gameport);
676 gameport_set_drvdata(gameport, NULL);
677 kfree(grip);
678}
679
680static struct gameport_driver grip_drv = {
681 .driver = {
682 .name = "grip_mp",
683 },
684 .description = DRIVER_DESC,
685 .connect = grip_connect,
686 .disconnect = grip_disconnect,
687};
688
689module_gameport_driver(grip_drv);
690