Lines 1-17
Link Here
|
1 |
/* |
1 |
/* |
2 |
* $Id: gamecon.c,v 1.14 2001/04/29 22:42:14 vojtech Exp $ |
2 |
* $Id: gamecon.c,v 1.22 2002/07/01 15:42:25 vojtech Exp $ |
3 |
* |
3 |
* |
4 |
* Copyright (c) 1999-2001 Vojtech Pavlik |
4 |
* Copyright (c) 1999-2001 Vojtech Pavlik |
5 |
* |
5 |
* |
6 |
* Based on the work of: |
6 |
* Based on the work of: |
7 |
* Andree Borrmann John Dahlstrom |
7 |
* Andree Borrmann John Dahlstrom |
8 |
* David Kuder Nathan Hand |
8 |
* David Kuder Nathan Hand |
9 |
* |
9 |
* Peter Nelson |
10 |
* Sponsored by SuSE |
|
|
11 |
*/ |
10 |
*/ |
12 |
|
11 |
|
13 |
/* |
12 |
/* |
14 |
* NES, SNES, N64, Multi1, Multi2, PSX gamepad driver for Linux |
13 |
* NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux |
15 |
*/ |
14 |
*/ |
16 |
|
15 |
|
17 |
/* |
16 |
/* |
Lines 30-37
Link Here
|
30 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
29 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
31 |
* |
30 |
* |
32 |
* Should you need to contact me, the author, you can do so either by |
31 |
* Should you need to contact me, the author, you can do so either by |
33 |
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: |
32 |
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
34 |
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic |
33 |
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
35 |
*/ |
34 |
*/ |
36 |
|
35 |
|
37 |
#include <linux/kernel.h> |
36 |
#include <linux/kernel.h> |
Lines 41-51
Link Here
|
41 |
#include <linux/parport.h> |
40 |
#include <linux/parport.h> |
42 |
#include <linux/input.h> |
41 |
#include <linux/input.h> |
43 |
|
42 |
|
44 |
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
43 |
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
|
|
44 |
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); |
45 |
MODULE_LICENSE("GPL"); |
45 |
MODULE_LICENSE("GPL"); |
|
|
46 |
|
46 |
MODULE_PARM(gc, "2-6i"); |
47 |
MODULE_PARM(gc, "2-6i"); |
47 |
MODULE_PARM(gc_2,"2-6i"); |
48 |
MODULE_PARM(gc_2,"2-6i"); |
48 |
MODULE_PARM(gc_3,"2-6i"); |
49 |
MODULE_PARM(gc_3,"2-6i"); |
|
|
50 |
MODULE_PARM(gc_psx_delay, "i"); |
51 |
MODULE_PARM(gc_psx_ddr, "i"); |
49 |
|
52 |
|
50 |
#define GC_SNES 1 |
53 |
#define GC_SNES 1 |
51 |
#define GC_NES 2 |
54 |
#define GC_NES 2 |
Lines 213-219
static void gc_multi_read_packet(struct
Link Here
|
213 |
* |
216 |
* |
214 |
*/ |
217 |
*/ |
215 |
|
218 |
|
216 |
#define GC_PSX_DELAY 60 /* 60 usec */ |
219 |
#define GC_PSX_DELAY 25 /* 25 usec */ |
217 |
#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */ |
220 |
#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */ |
218 |
|
221 |
|
219 |
#define GC_PSX_MOUSE 1 /* Mouse */ |
222 |
#define GC_PSX_MOUSE 1 /* Mouse */ |
Lines 223-257
static void gc_multi_read_packet(struct
Link Here
|
223 |
#define GC_PSX_RUMBLE 7 /* Rumble in Red mode */ |
226 |
#define GC_PSX_RUMBLE 7 /* Rumble in Red mode */ |
224 |
|
227 |
|
225 |
#define GC_PSX_CLOCK 0x04 /* Pin 4 */ |
228 |
#define GC_PSX_CLOCK 0x04 /* Pin 4 */ |
226 |
#define GC_PSX_COMMAND 0x01 /* Pin 1 */ |
229 |
#define GC_PSX_COMMAND 0x01 /* Pin 2 */ |
227 |
#define GC_PSX_POWER 0xf8 /* Pins 5-9 */ |
230 |
#define GC_PSX_POWER 0xf8 /* Pins 5-9 */ |
228 |
#define GC_PSX_SELECT 0x02 /* Pin 3 */ |
231 |
#define GC_PSX_SELECT 0x02 /* Pin 3 */ |
229 |
|
232 |
|
230 |
#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */ |
233 |
#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */ |
231 |
#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */ |
234 |
#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */ |
232 |
|
235 |
|
|
|
236 |
static int gc_psx_delay = GC_PSX_DELAY; |
237 |
static int gc_psx_ddr = 0; |
233 |
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; |
238 |
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; |
234 |
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, |
239 |
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, |
235 |
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; |
240 |
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; |
|
|
241 |
static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; |
236 |
|
242 |
|
237 |
/* |
243 |
/* |
238 |
* gc_psx_command() writes 8bit command and reads 8bit data from |
244 |
* gc_psx_command() writes 8bit command and reads 8bit data from |
239 |
* the psx pad. |
245 |
* the psx pad. |
240 |
*/ |
246 |
*/ |
241 |
|
247 |
|
242 |
static int gc_psx_command(struct gc *gc, int b) |
248 |
static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_PSX_LENGTH]) |
243 |
{ |
249 |
{ |
244 |
int i, cmd, data = 0; |
250 |
int i, j, cmd, read; |
|
|
251 |
for (i = 0; i < 5; i++) |
252 |
data[i] = 0; |
245 |
|
253 |
|
246 |
for (i = 0; i < 8; i++, b >>= 1) { |
254 |
for (i = 0; i < 8; i++, b >>= 1) { |
247 |
cmd = (b & 1) ? GC_PSX_COMMAND : 0; |
255 |
cmd = (b & 1) ? GC_PSX_COMMAND : 0; |
248 |
parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); |
256 |
parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); |
249 |
udelay(GC_PSX_DELAY); |
257 |
udelay(gc_psx_delay); |
250 |
data |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0; |
258 |
read = parport_read_status(gc->pd->port) ^ 0x80; |
|
|
259 |
for (j = 0; j < 5; j++) |
260 |
data[j] |= (read & gc_status_bit[j] & gc->pads[GC_PSX]) ? (1 << i) : 0; |
251 |
parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); |
261 |
parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); |
252 |
udelay(GC_PSX_DELAY); |
262 |
udelay(gc_psx_delay); |
253 |
} |
263 |
} |
254 |
return data; |
|
|
255 |
} |
264 |
} |
256 |
|
265 |
|
257 |
/* |
266 |
/* |
Lines 259-289
static int gc_psx_command(struct gc *gc,
Link Here
|
259 |
* device identifier code. |
268 |
* device identifier code. |
260 |
*/ |
269 |
*/ |
261 |
|
270 |
|
262 |
static int gc_psx_read_packet(struct gc *gc, unsigned char *data) |
271 |
static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_LENGTH], unsigned char id[5]) |
263 |
{ |
272 |
{ |
264 |
int i, id; |
273 |
int i, j, max_len = 0; |
265 |
unsigned long flags; |
274 |
unsigned long flags; |
|
|
275 |
unsigned char data2[5]; |
266 |
|
276 |
|
267 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ |
277 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ |
268 |
udelay(GC_PSX_DELAY * 2); |
278 |
udelay(gc_psx_delay); |
269 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ |
279 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ |
270 |
udelay(GC_PSX_DELAY * 2); |
280 |
udelay(gc_psx_delay); |
271 |
|
281 |
|
272 |
__save_flags(flags); |
282 |
__save_flags(flags); |
273 |
__cli(); |
283 |
__cli(); |
274 |
|
284 |
|
275 |
gc_psx_command(gc, 0x01); /* Access pad */ |
285 |
gc_psx_command(gc, 0x01, data2); /* Access pad */ |
276 |
id = gc_psx_command(gc, 0x42); /* Get device id */ |
286 |
gc_psx_command(gc, 0x42, id); /* Get device ids */ |
277 |
if (gc_psx_command(gc, 0) == 0x5a) { /* Okay? */ |
287 |
gc_psx_command(gc, 0, data2); /* Dump status */ |
278 |
for (i = 0; i < GC_PSX_LEN(id) * 2; i++) |
288 |
|
279 |
data[i] = gc_psx_command(gc, 0); |
289 |
for (i =0; i < 5; i++) /* Find the longest pad */ |
280 |
} else id = 0; |
290 |
if((gc_status_bit[i] & gc->pads[GC_PSX]) && (GC_PSX_LEN(id[i]) > max_len)) |
|
|
291 |
max_len = GC_PSX_LEN(id[i]); |
292 |
|
293 |
for (i = 0; i < max_len * 2; i++) { /* Read in all the data */ |
294 |
gc_psx_command(gc, 0, data2); |
295 |
for (j = 0; j < 5; j++) |
296 |
data[j][i] = data2[j]; |
297 |
} |
281 |
|
298 |
|
282 |
__restore_flags(flags); |
299 |
__restore_flags(flags); |
283 |
|
300 |
|
284 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); |
301 |
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); |
285 |
|
302 |
|
286 |
return GC_PSX_ID(id); |
303 |
for(i = 0; i < 5; i++) /* Set id's to the real value */ |
|
|
304 |
id[i] = GC_PSX_ID(id[i]); |
287 |
} |
305 |
} |
288 |
|
306 |
|
289 |
/* |
307 |
/* |
Lines 297-302
static void gc_timer(unsigned long priva
Link Here
|
297 |
struct gc *gc = (void *) private; |
315 |
struct gc *gc = (void *) private; |
298 |
struct input_dev *dev = gc->dev; |
316 |
struct input_dev *dev = gc->dev; |
299 |
unsigned char data[GC_MAX_LENGTH]; |
317 |
unsigned char data[GC_MAX_LENGTH]; |
|
|
318 |
unsigned char data_psx[5][GC_PSX_LENGTH]; |
300 |
int i, j, s; |
319 |
int i, j, s; |
301 |
|
320 |
|
302 |
/* |
321 |
/* |
Lines 389-434
static void gc_timer(unsigned long priva
Link Here
|
389 |
|
408 |
|
390 |
if (gc->pads[GC_PSX]) { |
409 |
if (gc->pads[GC_PSX]) { |
391 |
|
410 |
|
392 |
for (i = 0; i < 5; i++) |
411 |
gc_psx_read_packet(gc, data_psx, data); |
393 |
if (gc->pads[GC_PSX] & gc_status_bit[i]) |
|
|
394 |
break; |
395 |
|
396 |
switch (gc_psx_read_packet(gc, data)) { |
397 |
|
398 |
case GC_PSX_RUMBLE: |
399 |
|
400 |
input_report_key(dev + i, BTN_THUMB, ~data[0] & 0x04); |
401 |
input_report_key(dev + i, BTN_THUMB2, ~data[0] & 0x02); |
402 |
|
403 |
case GC_PSX_NEGCON: |
404 |
case GC_PSX_ANALOG: |
405 |
|
406 |
for (j = 0; j < 4; j++) |
407 |
input_report_abs(dev + i, gc_psx_abs[j], data[j + 2]); |
408 |
|
409 |
input_report_abs(dev + i, ABS_HAT0X, !(data[0] & 0x20) - !(data[0] & 0x80)); |
410 |
input_report_abs(dev + i, ABS_HAT0Y, !(data[0] & 0x40) - !(data[0] & 0x10)); |
411 |
|
412 |
for (j = 0; j < 8; j++) |
413 |
input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j)); |
414 |
|
415 |
input_report_key(dev + i, BTN_START, ~data[0] & 0x08); |
416 |
input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); |
417 |
|
418 |
break; |
419 |
|
420 |
case GC_PSX_NORMAL: |
421 |
|
422 |
input_report_abs(dev + i, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); |
423 |
input_report_abs(dev + i, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); |
424 |
|
425 |
for (j = 0; j < 8; j++) |
426 |
input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j)); |
427 |
|
412 |
|
428 |
input_report_key(dev + i, BTN_START, ~data[0] & 0x08); |
413 |
for (i = 0; i < 5; i++) { |
429 |
input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); |
414 |
switch (data[i]) { |
|
|
415 |
|
416 |
case GC_PSX_RUMBLE: |
417 |
|
418 |
input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04); |
419 |
input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02); |
420 |
|
421 |
case GC_PSX_NEGCON: |
422 |
case GC_PSX_ANALOG: |
423 |
|
424 |
if(gc_psx_ddr == 1) { |
425 |
for(j = 0; j < 4; j++) |
426 |
input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); |
427 |
} else { |
428 |
for (j = 0; j < 4; j++) |
429 |
input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]); |
430 |
|
431 |
input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); |
432 |
input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); |
433 |
} |
434 |
|
435 |
for (j = 0; j < 8; j++) |
436 |
input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); |
437 |
|
438 |
input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08); |
439 |
input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01); |
440 |
|
441 |
break; |
442 |
|
443 |
case GC_PSX_NORMAL: |
444 |
if(gc_psx_ddr == 1) { |
445 |
for(j = 0; j < 4; j++) |
446 |
input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); |
447 |
} else { |
448 |
input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); |
449 |
input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); |
450 |
|
451 |
/* for some reason if the extra axes are left unset they drift */ |
452 |
for (j = 0; j < 4; j++) |
453 |
input_report_abs(dev + i, gc_psx_abs[j+2], 128); |
454 |
} |
455 |
|
456 |
for (j = 0; j < 8; j++) |
457 |
input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); |
458 |
|
459 |
input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08); |
460 |
input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01); |
461 |
|
462 |
break; |
430 |
|
463 |
|
431 |
break; |
464 |
case 0: /* not a pad, ignore */ |
|
|
465 |
break; |
466 |
} |
432 |
} |
467 |
} |
433 |
} |
468 |
} |
434 |
|
469 |
|
Lines 460-467
static struct gc __init *gc_probe(int *c
Link Here
|
460 |
{ |
495 |
{ |
461 |
struct gc *gc; |
496 |
struct gc *gc; |
462 |
struct parport *pp; |
497 |
struct parport *pp; |
463 |
int i, j, psx; |
498 |
int i, j; |
464 |
unsigned char data[32]; |
|
|
465 |
|
499 |
|
466 |
if (config[0] < 0) |
500 |
if (config[0] < 0) |
467 |
return NULL; |
501 |
return NULL; |
Lines 550-596
static struct gc __init *gc_probe(int *c
Link Here
|
550 |
break; |
584 |
break; |
551 |
|
585 |
|
552 |
case GC_PSX: |
586 |
case GC_PSX: |
553 |
|
587 |
if(gc_psx_ddr == 1) { |
554 |
psx = gc_psx_read_packet(gc, data); |
588 |
for (j = 0; j < 4; j++) |
555 |
|
589 |
set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit); |
556 |
switch(psx) { |
590 |
} else { |
557 |
case GC_PSX_NEGCON: |
591 |
for (j = 0; j < 6; j++) { |
558 |
case GC_PSX_NORMAL: |
592 |
set_bit(gc_psx_abs[j], gc->dev[i].absbit); |
559 |
case GC_PSX_ANALOG: |
593 |
gc->dev[i].absmin[gc_psx_abs[j]] = 4; |
560 |
case GC_PSX_RUMBLE: |
594 |
gc->dev[i].absmax[gc_psx_abs[j]] = 252; |
561 |
|
595 |
gc->dev[i].absflat[gc_psx_abs[j]] = 2; |
562 |
for (j = 0; j < 6; j++) { |
596 |
} |
563 |
psx = gc_psx_abs[j]; |
|
|
564 |
set_bit(psx, gc->dev[i].absbit); |
565 |
if (j < 4) { |
566 |
gc->dev[i].absmin[psx] = 4; |
567 |
gc->dev[i].absmax[psx] = 252; |
568 |
gc->dev[i].absflat[psx] = 2; |
569 |
} else { |
570 |
gc->dev[i].absmin[psx] = -1; |
571 |
gc->dev[i].absmax[psx] = 1; |
572 |
} |
573 |
} |
574 |
|
575 |
for (j = 0; j < 12; j++) |
576 |
set_bit(gc_psx_btn[j], gc->dev[i].keybit); |
577 |
|
578 |
break; |
579 |
|
580 |
case 0: |
581 |
gc->pads[GC_PSX] &= ~gc_status_bit[i]; |
582 |
printk(KERN_ERR "gamecon.c: No PSX controller found.\n"); |
583 |
break; |
584 |
|
585 |
default: |
586 |
gc->pads[GC_PSX] &= ~gc_status_bit[i]; |
587 |
printk(KERN_WARNING "gamecon.c: Unsupported PSX controller %#x," |
588 |
" please report to <vojtech@suse.cz>.\n", psx); |
589 |
} |
597 |
} |
|
|
598 |
|
599 |
for (j = 0; j < 12; j++) |
600 |
set_bit(gc_psx_btn[j], gc->dev[i].keybit); |
601 |
|
590 |
break; |
602 |
break; |
591 |
} |
603 |
} |
592 |
|
604 |
|
593 |
gc->dev[i].name = gc_names[config[i + 1]]; |
605 |
gc->dev[i].name = gc_names[config[i + 1]]; |
|
|
606 |
gc->dev[i].phys = gc->phys[i]; |
594 |
gc->dev[i].idbus = BUS_PARPORT; |
607 |
gc->dev[i].idbus = BUS_PARPORT; |
595 |
gc->dev[i].idvendor = 0x0001; |
608 |
gc->dev[i].idvendor = 0x0001; |
596 |
gc->dev[i].idproduct = config[i + 1]; |
609 |
gc->dev[i].idproduct = config[i + 1]; |
Lines 608-614
static struct gc __init *gc_probe(int *c
Link Here
|
608 |
for (i = 0; i < 5; i++) |
621 |
for (i = 0; i < 5; i++) |
609 |
if (gc->pads[0] & gc_status_bit[i]) { |
622 |
if (gc->pads[0] & gc_status_bit[i]) { |
610 |
input_register_device(gc->dev + i); |
623 |
input_register_device(gc->dev + i); |
611 |
printk(KERN_INFO "input%d: %s on %s\n", gc->dev[i].number, gc->dev[i].name, gc->pd->port->name); |
624 |
printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name); |
612 |
} |
625 |
} |
613 |
|
626 |
|
614 |
return gc; |
627 |
return gc; |
Lines 636-644
int __init gc_setup_3(char *str)
Link Here
|
636 |
for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1]; |
649 |
for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1]; |
637 |
return 1; |
650 |
return 1; |
638 |
} |
651 |
} |
|
|
652 |
int __init gc_psx_setup(char *str) |
653 |
{ |
654 |
get_option(&str, &gc_psx_delay); |
655 |
return 1; |
656 |
} |
657 |
int __init gc_psx_ddr(char *str) |
658 |
{ |
659 |
get_option(&str, &gc_psx_ddr); |
660 |
return 1; |
661 |
} |
639 |
__setup("gc=", gc_setup); |
662 |
__setup("gc=", gc_setup); |
640 |
__setup("gc_2=", gc_setup_2); |
663 |
__setup("gc_2=", gc_setup_2); |
641 |
__setup("gc_3=", gc_setup_3); |
664 |
__setup("gc_3=", gc_setup_3); |
|
|
665 |
__setup("gc_psx_delay=", gc_psx_setup); |
666 |
__setup("gc_psx_ddr=", gc_psx_ddr); |
642 |
#endif |
667 |
#endif |
643 |
|
668 |
|
644 |
int __init gc_init(void) |
669 |
int __init gc_init(void) |