aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick/gamecon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joystick/gamecon.c')
-rw-r--r--drivers/input/joystick/gamecon.c96
1 files changed, 77 insertions, 19 deletions
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 900587acdb47..ecbdb6b9bbd6 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -7,6 +7,7 @@
7 * Based on the work of: 7 * Based on the work of:
8 * Andree Borrmann John Dahlstrom 8 * Andree Borrmann John Dahlstrom
9 * David Kuder Nathan Hand 9 * David Kuder Nathan Hand
10 * Raphael Assenat
10 */ 11 */
11 12
12/* 13/*
@@ -36,6 +37,7 @@
36#include <linux/init.h> 37#include <linux/init.h>
37#include <linux/parport.h> 38#include <linux/parport.h>
38#include <linux/input.h> 39#include <linux/input.h>
40#include <linux/mutex.h>
39 41
40MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 42MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
41MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); 43MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
@@ -72,8 +74,9 @@ __obsolete_setup("gc_3=");
72#define GC_N64 6 74#define GC_N64 6
73#define GC_PSX 7 75#define GC_PSX 7
74#define GC_DDR 8 76#define GC_DDR 8
77#define GC_SNESMOUSE 9
75 78
76#define GC_MAX 8 79#define GC_MAX 9
77 80
78#define GC_REFRESH_TIME HZ/100 81#define GC_REFRESH_TIME HZ/100
79 82
@@ -83,7 +86,7 @@ struct gc {
83 struct timer_list timer; 86 struct timer_list timer;
84 unsigned char pads[GC_MAX + 1]; 87 unsigned char pads[GC_MAX + 1];
85 int used; 88 int used;
86 struct semaphore sem; 89 struct mutex mutex;
87 char phys[GC_MAX_DEVICES][32]; 90 char phys[GC_MAX_DEVICES][32];
88}; 91};
89 92
@@ -93,7 +96,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
93 96
94static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", 97static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
95 "Multisystem 2-button joystick", "N64 controller", "PSX controller", 98 "Multisystem 2-button joystick", "N64 controller", "PSX controller",
96 "PSX DDR controller" }; 99 "PSX DDR controller", "SNES mouse" };
97/* 100/*
98 * N64 support. 101 * N64 support.
99 */ 102 */
@@ -205,9 +208,12 @@ static void gc_n64_process_packet(struct gc *gc)
205 * NES/SNES support. 208 * NES/SNES support.
206 */ 209 */
207 210
208#define GC_NES_DELAY 6 /* Delay between bits - 6us */ 211#define GC_NES_DELAY 6 /* Delay between bits - 6us */
209#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */ 212#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */
210#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */ 213#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the
214 last 4 bits are unused */
215#define GC_SNESMOUSE_LENGTH 32 /* The SNES mouse uses 32 bits, the first
216 16 bits are equivalent to a gamepad */
211 217
212#define GC_NES_POWER 0xfc 218#define GC_NES_POWER 0xfc
213#define GC_NES_CLOCK 0x01 219#define GC_NES_CLOCK 0x01
@@ -242,11 +248,15 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
242 248
243static void gc_nes_process_packet(struct gc *gc) 249static void gc_nes_process_packet(struct gc *gc)
244{ 250{
245 unsigned char data[GC_SNES_LENGTH]; 251 unsigned char data[GC_SNESMOUSE_LENGTH];
246 struct input_dev *dev; 252 struct input_dev *dev;
247 int i, j, s; 253 int i, j, s, len;
254 char x_rel, y_rel;
255
256 len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
257 (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);
248 258
249 gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); 259 gc_nes_read_packet(gc, len, data);
250 260
251 for (i = 0; i < GC_MAX_DEVICES; i++) { 261 for (i = 0; i < GC_MAX_DEVICES; i++) {
252 262
@@ -269,6 +279,44 @@ static void gc_nes_process_packet(struct gc *gc)
269 for (j = 0; j < 8; j++) 279 for (j = 0; j < 8; j++)
270 input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); 280 input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
271 281
282 if (s & gc->pads[GC_SNESMOUSE]) {
283 /*
284 * The 4 unused bits from SNES controllers appear to be ID bits
285 * so use them to make sure iwe are dealing with a mouse.
286 * gamepad is connected. This is important since
287 * my SNES gamepad sends 1's for bits 16-31, which
288 * cause the mouse pointer to quickly move to the
289 * upper left corner of the screen.
290 */
291 if (!(s & data[12]) && !(s & data[13]) &&
292 !(s & data[14]) && (s & data[15])) {
293 input_report_key(dev, BTN_LEFT, s & data[9]);
294 input_report_key(dev, BTN_RIGHT, s & data[8]);
295
296 x_rel = y_rel = 0;
297 for (j = 0; j < 7; j++) {
298 x_rel <<= 1;
299 if (data[25 + j] & s)
300 x_rel |= 1;
301
302 y_rel <<= 1;
303 if (data[17 + j] & s)
304 y_rel |= 1;
305 }
306
307 if (x_rel) {
308 if (data[24] & s)
309 x_rel = -x_rel;
310 input_report_rel(dev, REL_X, x_rel);
311 }
312
313 if (y_rel) {
314 if (data[16] & s)
315 y_rel = -y_rel;
316 input_report_rel(dev, REL_Y, y_rel);
317 }
318 }
319 }
272 input_sync(dev); 320 input_sync(dev);
273 } 321 }
274} 322}
@@ -524,10 +572,10 @@ static void gc_timer(unsigned long private)
524 gc_n64_process_packet(gc); 572 gc_n64_process_packet(gc);
525 573
526/* 574/*
527 * NES and SNES pads 575 * NES and SNES pads or mouse
528 */ 576 */
529 577
530 if (gc->pads[GC_NES] || gc->pads[GC_SNES]) 578 if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE])
531 gc_nes_process_packet(gc); 579 gc_nes_process_packet(gc);
532 580
533/* 581/*
@@ -552,7 +600,7 @@ static int gc_open(struct input_dev *dev)
552 struct gc *gc = dev->private; 600 struct gc *gc = dev->private;
553 int err; 601 int err;
554 602
555 err = down_interruptible(&gc->sem); 603 err = mutex_lock_interruptible(&gc->mutex);
556 if (err) 604 if (err)
557 return err; 605 return err;
558 606
@@ -562,7 +610,7 @@ static int gc_open(struct input_dev *dev)
562 mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); 610 mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
563 } 611 }
564 612
565 up(&gc->sem); 613 mutex_unlock(&gc->mutex);
566 return 0; 614 return 0;
567} 615}
568 616
@@ -570,13 +618,13 @@ static void gc_close(struct input_dev *dev)
570{ 618{
571 struct gc *gc = dev->private; 619 struct gc *gc = dev->private;
572 620
573 down(&gc->sem); 621 mutex_lock(&gc->mutex);
574 if (!--gc->used) { 622 if (!--gc->used) {
575 del_timer_sync(&gc->timer); 623 del_timer_sync(&gc->timer);
576 parport_write_control(gc->pd->port, 0x00); 624 parport_write_control(gc->pd->port, 0x00);
577 parport_release(gc->pd); 625 parport_release(gc->pd);
578 } 626 }
579 up(&gc->sem); 627 mutex_unlock(&gc->mutex);
580} 628}
581 629
582static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) 630static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
@@ -609,10 +657,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
609 input_dev->open = gc_open; 657 input_dev->open = gc_open;
610 input_dev->close = gc_close; 658 input_dev->close = gc_close;
611 659
612 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); 660 if (pad_type != GC_SNESMOUSE) {
661 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
613 662
614 for (i = 0; i < 2; i++) 663 for (i = 0; i < 2; i++)
615 input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); 664 input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
665 } else
666 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
616 667
617 gc->pads[0] |= gc_status_bit[idx]; 668 gc->pads[0] |= gc_status_bit[idx];
618 gc->pads[pad_type] |= gc_status_bit[idx]; 669 gc->pads[pad_type] |= gc_status_bit[idx];
@@ -630,6 +681,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
630 681
631 break; 682 break;
632 683
684 case GC_SNESMOUSE:
685 set_bit(BTN_LEFT, input_dev->keybit);
686 set_bit(BTN_RIGHT, input_dev->keybit);
687 set_bit(REL_X, input_dev->relbit);
688 set_bit(REL_Y, input_dev->relbit);
689 break;
690
633 case GC_SNES: 691 case GC_SNES:
634 for (i = 4; i < 8; i++) 692 for (i = 4; i < 8; i++)
635 set_bit(gc_snes_btn[i], input_dev->keybit); 693 set_bit(gc_snes_btn[i], input_dev->keybit);
@@ -693,7 +751,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
693 goto err_unreg_pardev; 751 goto err_unreg_pardev;
694 } 752 }
695 753
696 init_MUTEX(&gc->sem); 754 mutex_init(&gc->mutex);
697 gc->pd = pd; 755 gc->pd = pd;
698 init_timer(&gc->timer); 756 init_timer(&gc->timer);
699 gc->timer.data = (long) gc; 757 gc->timer.data = (long) gc;