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.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index aa3ef89d8188..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/*
@@ -73,8 +74,9 @@ __obsolete_setup("gc_3=");
73#define GC_N64 6 74#define GC_N64 6
74#define GC_PSX 7 75#define GC_PSX 7
75#define GC_DDR 8 76#define GC_DDR 8
77#define GC_SNESMOUSE 9
76 78
77#define GC_MAX 8 79#define GC_MAX 9
78 80
79#define GC_REFRESH_TIME HZ/100 81#define GC_REFRESH_TIME HZ/100
80 82
@@ -94,7 +96,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
94 96
95static 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",
96 "Multisystem 2-button joystick", "N64 controller", "PSX controller", 98 "Multisystem 2-button joystick", "N64 controller", "PSX controller",
97 "PSX DDR controller" }; 99 "PSX DDR controller", "SNES mouse" };
98/* 100/*
99 * N64 support. 101 * N64 support.
100 */ 102 */
@@ -206,9 +208,12 @@ static void gc_n64_process_packet(struct gc *gc)
206 * NES/SNES support. 208 * NES/SNES support.
207 */ 209 */
208 210
209#define GC_NES_DELAY 6 /* Delay between bits - 6us */ 211#define GC_NES_DELAY 6 /* Delay between bits - 6us */
210#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 */
211#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 */
212 217
213#define GC_NES_POWER 0xfc 218#define GC_NES_POWER 0xfc
214#define GC_NES_CLOCK 0x01 219#define GC_NES_CLOCK 0x01
@@ -243,11 +248,15 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
243 248
244static void gc_nes_process_packet(struct gc *gc) 249static void gc_nes_process_packet(struct gc *gc)
245{ 250{
246 unsigned char data[GC_SNES_LENGTH]; 251 unsigned char data[GC_SNESMOUSE_LENGTH];
247 struct input_dev *dev; 252 struct input_dev *dev;
248 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);
249 258
250 gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); 259 gc_nes_read_packet(gc, len, data);
251 260
252 for (i = 0; i < GC_MAX_DEVICES; i++) { 261 for (i = 0; i < GC_MAX_DEVICES; i++) {
253 262
@@ -270,6 +279,44 @@ static void gc_nes_process_packet(struct gc *gc)
270 for (j = 0; j < 8; j++) 279 for (j = 0; j < 8; j++)
271 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]]);
272 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 }
273 input_sync(dev); 320 input_sync(dev);
274 } 321 }
275} 322}
@@ -525,10 +572,10 @@ static void gc_timer(unsigned long private)
525 gc_n64_process_packet(gc); 572 gc_n64_process_packet(gc);
526 573
527/* 574/*
528 * NES and SNES pads 575 * NES and SNES pads or mouse
529 */ 576 */
530 577
531 if (gc->pads[GC_NES] || gc->pads[GC_SNES]) 578 if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE])
532 gc_nes_process_packet(gc); 579 gc_nes_process_packet(gc);
533 580
534/* 581/*
@@ -610,10 +657,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
610 input_dev->open = gc_open; 657 input_dev->open = gc_open;
611 input_dev->close = gc_close; 658 input_dev->close = gc_close;
612 659
613 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);
614 662
615 for (i = 0; i < 2; i++) 663 for (i = 0; i < 2; i++)
616 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);
617 667
618 gc->pads[0] |= gc_status_bit[idx]; 668 gc->pads[0] |= gc_status_bit[idx];
619 gc->pads[pad_type] |= gc_status_bit[idx]; 669 gc->pads[pad_type] |= gc_status_bit[idx];
@@ -631,6 +681,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
631 681
632 break; 682 break;
633 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
634 case GC_SNES: 691 case GC_SNES:
635 for (i = 4; i < 8; i++) 692 for (i = 4; i < 8; i++)
636 set_bit(gc_snes_btn[i], input_dev->keybit); 693 set_bit(gc_snes_btn[i], input_dev->keybit);