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