1
2
3
4
5
6
7
8
9
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
24MODULE_AUTHOR("Brian Bonnlander");
25MODULE_DESCRIPTION(DRIVER_DESC);
26MODULE_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
37
38
39struct grip_port {
40 struct input_dev *dev;
41 int mode;
42 int registered;
43
44
45 int buttons;
46 int xaxes;
47 int yaxes;
48 int dirty;
49};
50
51struct grip_mp {
52 struct gameport *gameport;
53 struct grip_port *port[GRIP_MAX_PORTS];
54 int reads;
55 int bads;
56};
57
58
59
60
61
62#define PACKET_FULL 0x80000000
63#define PACKET_IO_FAST 0x40000000
64#define PACKET_IO_SLOW 0x20000000
65#define PACKET_MP_MORE 0x04000000
66#define PACKET_MP_DONE 0x02000000
67
68
69
70
71
72#define IO_GOT_PACKET 0x0100
73#define IO_MODE_FAST 0x0200
74#define IO_SLOT_CHANGE 0x0800
75#define IO_DONE 0x1000
76#define IO_RETRY 0x4000
77#define IO_RESET 0x8000
78
79
80
81
82
83
84
85#define GRIP_INIT_DELAY 2000
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
92static const int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
93static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
94
95static const int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
96static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
97
98static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
99static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
100
101static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
102
103static 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
110
111static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
112
113static int register_slot(int i, struct grip_mp *grip);
114
115
116
117
118
119static 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
131
132
133
134static 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
165{
166 u8 raw_data;
167 u8 data_mask;
168 u32 pkt;
169 int bits_per_read;
170 int portvals = 0;
171 int i;
172
173
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);
183 }
184
185 if (portvals == 1) {
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
199
200 if (raw_data & 0x20) {
201 portvals |= raw_data >> 4;
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 {
209 data_mask = 1;
210 bits_per_read = 1;
211 pkt = (PACKET_FULL | PACKET_IO_SLOW) >> 28;
212 }
213
214
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
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
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
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
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
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
299
300
301static 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
315
316
317
318
319static 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++) {
325 if (init_seq[i])
326 gameport_trigger(gameport);
327 udelay(GRIP_INIT_DELAY);
328 }
329
330 for (i = 0; i < 16; i++)
331 udelay(GRIP_INIT_DELAY);
332
333 while (tries < 64 && bads < 8) {
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
350
351
352
353
354
355
356
357
358static 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
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
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
389
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
408
409 if (joytype == 0x1f) {
410
411 int dir = (packet >> 8) & 0xf;
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
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
447
448
449static 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
465 if (!active)
466 return (flags & IO_DONE) ? 1 : 0;
467
468
469 return invalid ? 0 : 1;
470}
471
472
473
474
475
476
477static 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
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
508
509
510static void report_slot(struct grip_mp *grip, int slot)
511{
512 struct grip_port *port = grip->port[slot];
513 int i;
514
515
516
517 for (i = 0; i < 8; i++)
518 input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
519
520
521
522 input_report_abs(port->dev, ABS_X, port->xaxes);
523 input_report_abs(port->dev, ABS_Y, port->yaxes);
524
525
526
527 input_sync(port->dev);
528
529 port->dirty = 0;
530}
531
532
533
534
535
536static 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
559
560
561static 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
571
572
573static 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
582
583
584static 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)
625 report_slot(grip, slot);
626
627 return 0;
628}
629
630static 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
656 err = -ENODEV;
657 goto fail2;
658 }
659
660 return 0;
661
662fail2: gameport_close(gameport);
663fail1: gameport_set_drvdata(gameport, NULL);
664 kfree(grip);
665 return err;
666}
667
668static 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
681static 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
690module_gameport_driver(grip_drv);
691