2 * joy-console.c Version 0.14V
4 * Copyright (c) 1998 Andree Borrmann
5 * Copyright (c) 1999 John Dahlstrom
6 * Copyright (c) 1999 David Kuder
7 * Copyright (c) 1999 Vojtech Pavlik
13 * This is a module for the Linux joystick driver, supporting
14 * console (NES, SNES, N64, Multi1, Multi2, PSX) gamepads
15 * connected via parallel port. Up to five such controllers
16 * can be connected to one parallel port.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 * Should you need to contact me, the author, you can do so either by
35 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
36 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
40 #include <asm/system.h>
41 #include <linux/errno.h>
42 #include <linux/ioport.h>
43 #include <linux/joystick.h>
44 #include <linux/kernel.h>
45 #include <linux/module.h>
46 #include <linux/string.h>
47 #include <linux/delay.h>
48 #include <linux/init.h>
51 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
52 MODULE_PARM(js_console
, "2-6i");
53 MODULE_PARM(js_console_2
,"2-6i");
54 MODULE_PARM(js_console_3
,"2-6i");
61 #define JS_MULTI_STICK 4
62 #define JS_MULTI2_STICK 5
65 #define JS_N64_PAD_DPP 8 /* DirectPad Pro compatible layout */
67 #define JS_MAX_PAD JS_N64_PAD_DPP
69 struct js_console_info
{
70 struct pardevice
*port
; /* parport device */
71 int pads
; /* total number of pads */
72 int pad_to_device
[5]; /* pad to js device mapping (js0, js1, etc.) */
73 int snes
; /* SNES pads */
74 int nes
; /* NES pads */
75 int n64
; /* N64 pads */
76 int n64_dpp
; /* bits indicate N64 pads treated 14 button, 2 axis */
77 int multi
; /* Multi joysticks */
78 int multi2
; /* Multi joysticks with 2 buttons */
79 int psx
; /* PSX controllers */
82 static struct js_port
* js_console_port
= NULL
;
84 static int js_console
[] __initdata
= { -1, 0, 0, 0, 0, 0 };
85 static int js_console_2
[] __initdata
= { -1, 0, 0, 0, 0, 0 };
86 static int js_console_3
[] __initdata
= { -1, 0, 0, 0, 0, 0 };
88 static int status_bit
[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
94 #define JS_NES_DELAY 6 /* Delay between bits - 6us */
96 #define JS_NES_LENGTH 8 /* The NES pads use 8 bits of data */
100 #define JS_NES_START 2
101 #define JS_NES_SELECT 3
103 #define JS_NES_DOWN 5
104 #define JS_NES_LEFT 6
105 #define JS_NES_RIGHT 7
107 #define JS_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */
111 #define JS_SNES_START 2
112 #define JS_SNES_SELECT 3
114 #define JS_SNES_DOWN 5
115 #define JS_SNES_LEFT 6
116 #define JS_SNES_RIGHT 7
122 #define JS_NES_POWER 0xfc
123 #define JS_NES_CLOCK 0x01
124 #define JS_NES_LATCH 0x02
127 * js_nes_read_packet() reads a NES/SNES packet.
128 * Each pad uses one bit per byte. So all pads connected to
129 * this port are read in parallel.
132 static void js_nes_read_packet(struct js_console_info
*info
, int length
, unsigned char *data
)
136 JS_PAR_DATA_OUT(JS_NES_POWER
| JS_NES_CLOCK
| JS_NES_LATCH
, info
->port
);
137 udelay(JS_NES_DELAY
* 2);
138 JS_PAR_DATA_OUT(JS_NES_POWER
| JS_NES_CLOCK
, info
->port
);
140 for (i
= 0; i
< length
; i
++) {
141 udelay(JS_NES_DELAY
);
142 JS_PAR_DATA_OUT(JS_NES_POWER
, info
->port
);
143 data
[i
] = JS_PAR_STATUS(info
->port
) ^ ~JS_PAR_STATUS_INVERT
;
144 udelay(JS_NES_DELAY
);
145 JS_PAR_DATA_OUT(JS_NES_POWER
| JS_NES_CLOCK
, info
->port
);
156 #define JS_N64_START 3
158 #define JS_N64_DOWN 5
159 #define JS_N64_LEFT 6
160 #define JS_N64_RIGHT 7
161 #define JS_N64_UNUSED1 8
162 #define JS_N64_UNUSED2 9
169 #define JS_N64_X 23 /* 16 - 23, signed 8-bit int */
170 #define JS_N64_Y 31 /* 24 - 31, signed 8-bit int */
172 #define JS_N64_LENGTH 32 /* N64 bit length, not including stop bit */
173 #define JS_N64_REQUEST_LENGTH 37 /* transmit request sequence is 9 bits long */
174 #define JS_N64_DELAY 133 /* delay between transmit request, and response ready (us) */
175 #define JS_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */
176 #define JS_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */
177 /* JS_N64_DWS > 24 is known to fail */
178 #define JS_N64_POWER_W 0xe2 /* power during write (transmit request) */
179 #define JS_N64_POWER_R 0xfd /* power during read */
180 #define JS_N64_OUT 0x1d /* output bits to the 4 pads */
181 /* Reading the main axes of any N64 pad is known to fail if the corresponding bit */
182 /* in JS_N64_OUT is pulled low on the output port (by any routine) for more */
183 /* than 0.123 consecutive ms */
184 #define JS_N64_CLOCK 0x02 /* clock bits for read */
187 * js_n64_read_packet() reads an N64 packet.
188 * Each pad uses one bit per byte. So all pads connected to this port are read in parallel.
191 static void js_n64_read_packet(struct js_console_info
*info
, unsigned char *data
)
197 * Request the pad to transmit data
202 for (i
= 0; i
< JS_N64_REQUEST_LENGTH
; i
++) {
203 JS_PAR_DATA_OUT(JS_N64_POWER_W
| ((JS_N64_REQUEST
>> i
) & 1 ? JS_N64_OUT
: 0), info
->port
);
206 restore_flags(flags
);
209 * Wait for the pad response to be loaded into the 33-bit register of the adapter
212 udelay(JS_N64_DELAY
);
215 * Grab data (ignoring the last bit, which is a stop bit)
218 for (i
= 0; i
< JS_N64_LENGTH
; i
++) {
219 JS_PAR_DATA_OUT(JS_N64_POWER_R
, info
->port
);
220 data
[i
] = JS_PAR_STATUS(info
->port
);
221 JS_PAR_DATA_OUT(JS_N64_POWER_R
| JS_N64_CLOCK
, info
->port
);
225 * We must wait ~0.2 ms here for the controller to reinitialize before the next read request.
226 * No worries as long as js_console_read is polled less frequently than this.
232 * Multisystem joystick support
235 #define JS_MULTI_LENGTH 5 /* Multi system joystick packet lenght is 5 */
236 #define JS_MULTI2_LENGTH 6 /* One more bit for one more button */
238 #define JS_MULTI_UP 0
239 #define JS_MULTI_DOWN 1
240 #define JS_MULTI_LEFT 2
241 #define JS_MULTI_RIGHT 3
242 #define JS_MULTI_BUTTON 4
243 #define JS_MULTI_BUTTON2 5
246 * js_multi_read_packet() reads a Multisystem joystick packet.
249 static void js_multi_read_packet(struct js_console_info
*info
, int length
, unsigned char *data
)
253 for (i
= 0; i
< length
; i
++) {
254 JS_PAR_DATA_OUT(~(1 << i
), info
->port
);
255 data
[i
] = JS_PAR_STATUS(info
->port
) ^ ~JS_PAR_STATUS_INVERT
;
256 printk(" %d", data
[i
]);
265 #define JS_PSX_DELAY 10
266 #define JS_PSX_LENGTH 8 /* talk to the controller in bytes */
268 #define JS_PSX_NORMAL 0x41 /* Standard Digital controller */
269 #define JS_PSX_NEGCON 0x23 /* NegCon pad */
270 #define JS_PSX_MOUSE 0x12 /* PSX Mouse */
271 #define JS_PSX_ANALOGR 0x73 /* Analog controller in Red mode */
272 #define JS_PSX_ANALOGG 0x53 /* Analog controller in Green mode */
274 #define JS_PSX_JOYR 0x02 /* These are for the Analog/Dual Shock controller in RED mode */
275 #define JS_PSX_JOYL 0x04 /* I'm not sure the exact purpose of these but its in the docs */
276 #define JS_PSX_SELBUT 0x01 /* Standard buttons on almost all PSX controllers. */
277 #define JS_PSX_START 0x08
278 #define JS_PSX_UP 0x10 /* Digital direction pad */
279 #define JS_PSX_RIGHT 0x20
280 #define JS_PSX_DOWN 0x40
281 #define JS_PSX_LEFT 0x80
283 #define JS_PSX_CLOCK 0x04 /* Pin 3 */
284 #define JS_PSX_COMMAND 0x01 /* Pin 1 */
285 #define JS_PSX_POWER 0xf8 /* Pins 5-9 */
286 #define JS_PSX_SELECT 0x02 /* Pin 2 */
287 #define JS_PSX_NOPOWER 0x04
290 * js_psx_command() writes 8bit command and reads 8bit data from
294 static int js_psx_command(struct js_console_info
*info
, int b
)
298 cmd
= (b
&1)?JS_PSX_COMMAND
:0;
299 for (i
=0; i
<8; i
++) {
300 JS_PAR_DATA_OUT(cmd
| JS_PSX_POWER
, info
->port
);
301 udelay(JS_PSX_DELAY
);
302 ret
|= ((JS_PAR_STATUS(info
->port
) ^ JS_PAR_STATUS_INVERT
) & info
->psx
) ? (1<<i
) : 0;
303 cmd
= (b
&1)?JS_PSX_COMMAND
:0;
304 JS_PAR_DATA_OUT(cmd
| JS_PSX_CLOCK
| JS_PSX_POWER
, info
->port
);
305 udelay(JS_PSX_DELAY
);
312 * js_psx_read_packet() reads a whole psx packet and returns
313 * device identifier code.
316 static int js_psx_read_packet(struct js_console_info
*info
, int length
, unsigned char *data
)
324 JS_PAR_DATA_OUT(JS_PSX_POWER
, info
->port
);
326 JS_PAR_DATA_OUT(JS_PSX_CLOCK
| JS_PSX_SELECT
| JS_PSX_POWER
, info
->port
); /* Select pad */
327 udelay(JS_PSX_DELAY
*2);
328 js_psx_command(info
, 0x01); /* Access pad */
329 ret
= js_psx_command(info
, 0x42); /* Get device id */
330 if (js_psx_command(info
, 0)=='Z') /* okay? */
331 for (i
=0; i
<length
; i
++)
332 data
[i
]=js_psx_command(info
, 0);
335 JS_PAR_DATA_OUT(JS_PSX_SELECT
| JS_PSX_CLOCK
| JS_PSX_POWER
, info
->port
);
336 __restore_flags(flags
);
343 * js_console_read() reads and analyzes console pads data.
346 #define JS_MAX_LENGTH JS_N64_LENGTH
348 static int js_console_read(void *xinfo
, int **axes
, int **buttons
)
350 struct js_console_info
*info
= xinfo
;
351 unsigned char data
[JS_MAX_LENGTH
];
360 if (info
->nes
|| info
->snes
) {
362 js_nes_read_packet(info
, info
->snes
? JS_SNES_LENGTH
: JS_NES_LENGTH
, data
);
364 for (i
= 0; i
< 5; i
++) {
366 n
= info
->pad_to_device
[i
];
368 axes
[n
][0] = (data
[JS_SNES_RIGHT
]&s
?1:0) - (data
[JS_SNES_LEFT
]&s
?1:0);
369 axes
[n
][1] = (data
[JS_SNES_DOWN
] &s
?1:0) - (data
[JS_SNES_UP
] &s
?1:0);
371 buttons
[n
][0] = (data
[JS_NES_A
] &s
?1:0) | (data
[JS_NES_B
] &s
?2:0)
372 | (data
[JS_NES_START
]&s
?4:0) | (data
[JS_NES_SELECT
]&s
?8:0);
374 if (info
->snes
& s
) {
375 axes
[n
][0] = (data
[JS_SNES_RIGHT
]&s
?1:0) - (data
[JS_SNES_LEFT
]&s
?1:0);
376 axes
[n
][1] = (data
[JS_SNES_DOWN
] &s
?1:0) - (data
[JS_SNES_UP
] &s
?1:0);
378 buttons
[n
][0] = (data
[JS_SNES_A
] &s
?0x01:0) | (data
[JS_SNES_B
] &s
?0x02:0)
379 | (data
[JS_SNES_X
] &s
?0x04:0) | (data
[JS_SNES_Y
] &s
?0x08:0)
380 | (data
[JS_SNES_L
] &s
?0x10:0) | (data
[JS_SNES_R
] &s
?0x20:0)
381 | (data
[JS_SNES_START
]&s
?0x40:0) | (data
[JS_SNES_SELECT
]&s
?0x80:0);
391 if ( (info
->nes
|| info
->snes
) && (info
->n64
& status_bit
[0]) ) {
392 /* SNES/NES compatibility */
393 udelay(240); /* 200 us delay + 20% tolerance */
396 js_n64_read_packet(info
, data
);
398 for (i
= 0; i
< 5; i
++) {
400 n
= info
->pad_to_device
[i
];
401 if (info
->n64
& s
& ~(data
[JS_N64_UNUSED1
] | data
[JS_N64_UNUSED2
])) {
403 buttons
[n
][0] = ( ((data
[JS_N64_A
]&s
) ? 0x01:0) | ((data
[JS_N64_B
] & s
) ? 0x02:0)
404 | ((data
[JS_N64_Z
]&s
) ? 0x04:0) | ((data
[JS_N64_L
] & s
) ? 0x08:0)
405 | ((data
[JS_N64_R
]&s
) ? 0x10:0) | ((data
[JS_N64_START
]&s
)? 0x20:0)
406 | ((data
[JS_N64_CU
]&s
)? 0x40:0) | ((data
[JS_N64_CR
]&s
) ? 0x80:0)
407 | ((data
[JS_N64_CD
]&s
)?0x100:0) | ((data
[JS_N64_CL
]&s
) ?0x200:0) );
409 if (info
->n64_dpp
& s
) {
410 buttons
[n
][0] |= ((data
[JS_N64_LEFT
]&s
) ? 0x400:0) | ((data
[JS_N64_UP
] & s
)? 0x800:0)
411 |((data
[JS_N64_RIGHT
]&s
)?0x1000:0) | ((data
[JS_N64_DOWN
]&s
)?0x2000:0);
413 axes
[n
][2] = (data
[JS_N64_RIGHT
]&s
?1:0) - (data
[JS_N64_LEFT
]&s
?1:0);
414 axes
[n
][3] = (data
[JS_N64_DOWN
] &s
?1:0) - (data
[JS_N64_UP
] &s
?1:0);
417 /* build int from bits of signed 8-bit int's */
419 axes
[n
][0] = (data
[JS_N64_X
- j
] & s
) ? ~0x7f : 0;
420 axes
[n
][1] = (data
[JS_N64_Y
- j
] & s
) ? ~0x7f : 0;
422 axes
[n
][0] |= (data
[JS_N64_X
- j
] & s
) ? (1 << j
) : 0;
423 axes
[n
][1] |= (data
[JS_N64_Y
- j
] & s
) ? (1 << j
) : 0;
425 /* flip Y-axis for conformity */
426 axes
[n
][1] = -axes
[n
][1];
433 * Multi and Multi2 joysticks
436 if (info
->multi
|| info
->multi2
) {
438 js_multi_read_packet(info
, info
->multi2
? JS_MULTI2_LENGTH
: JS_MULTI_LENGTH
, data
);
440 for (i
= 0; i
< 5; i
++) {
442 n
= info
->pad_to_device
[i
];
443 if (info
->multi
& s
) {
444 axes
[n
][0] = (data
[JS_MULTI_RIGHT
]&s
?1:0) - (data
[JS_MULTI_LEFT
]&s
?1:0);
445 axes
[n
][1] = (data
[JS_MULTI_DOWN
] &s
?1:0) - (data
[JS_MULTI_UP
] &s
?1:0);
447 buttons
[n
][0] = (data
[JS_MULTI_BUTTON
]&s
)?1:0;
449 if (info
->multi2
& s
) {
450 axes
[n
][0] = (data
[JS_MULTI_RIGHT
]&s
?1:0) - (data
[JS_MULTI_LEFT
]&s
?1:0);
451 axes
[n
][1] = (data
[JS_MULTI_DOWN
] &s
?1:0) - (data
[JS_MULTI_UP
] &s
?1:0);
453 buttons
[n
][0] = (data
[JS_MULTI_BUTTON
]&s
)?1:0 | (data
[JS_MULTI_BUTTON2
]&s
)?2:0;
464 for ( i
= 0; i
< 5; i
++ )
465 if ( info
->psx
& status_bit
[i
] ) {
466 n
= info
->pad_to_device
[i
];
472 switch (js_psx_read_packet(info
, 6, data
)) {
476 buttons
[n
][0] |= (data
[0]&JS_PSX_JOYL
?0:0x800) | (data
[0]&JS_PSX_JOYR
?0:0x400);
480 axes
[n
][2] = data
[2];
481 axes
[n
][3] = data
[3];
482 axes
[n
][4] = data
[4];
483 axes
[n
][5] = data
[5];
488 axes
[n
][0] = (data
[0]&JS_PSX_RIGHT
?0:1) - (data
[0]&JS_PSX_LEFT
?0:1);
489 axes
[n
][1] = (data
[0]&JS_PSX_DOWN
?0:1) - (data
[0]&JS_PSX_UP
?0:1);
491 buttons
[n
][0] |= ((~data
[1]&0xf)<<4) | ((~data
[1]&0xf0)>>4) |
492 (data
[0]&JS_PSX_START
?0:0x200) | (data
[0]&JS_PSX_SELBUT
?0:0x100);
503 * open callback: claim parport.
504 * FIXME: if parport_claim() will sleep we can get into mess.
507 int js_console_open(struct js_dev
*dev
)
509 struct js_console_info
*info
= dev
->port
->info
;
510 if (!MOD_IN_USE
&& parport_claim(info
->port
)) return -EBUSY
;
516 * close callback: release parport
519 int js_console_close(struct js_dev
*dev
)
521 struct js_console_info
*info
= dev
->port
->info
;
523 if (!MOD_IN_USE
) parport_release(info
->port
);
528 void cleanup_module(void)
530 struct js_console_info
*info
;
533 while (js_console_port
) {
534 for (i
= 0; i
< js_console_port
->ndevs
; i
++)
535 if (js_console_port
->devs
[i
])
536 js_unregister_device(js_console_port
->devs
[i
]);
537 info
= js_console_port
->info
;
538 parport_unregister_device(info
->port
);
539 js_console_port
= js_unregister_port(js_console_port
);
545 * js_console_init_corr() initializes correction values of
549 static void __init
js_console_init_corr(int num_axes
, int type
, struct js_corr
*corr
)
553 for (i
= 0; i
< num_axes
; i
++) {
554 corr
[i
].type
= JS_CORR_BROKEN
;
558 corr
[i
].coef
[2] = (1 << 29);
559 corr
[i
].coef
[3] = (1 << 29);
562 if (type
== JS_N64_PAD
|| type
== JS_N64_PAD_DPP
) {
563 for (i
= 0; i
< 2; i
++) {
564 corr
[i
].type
= JS_CORR_BROKEN
;
568 corr
[i
].coef
[2] = (1 << 22);
569 corr
[i
].coef
[3] = (1 << 22);
573 if (type
== JS_PSX_ANALOGG
|| type
== JS_PSX_ANALOGR
) {
574 for (i
= 2; i
< 6; i
++) {
575 corr
[i
].type
= JS_CORR_BROKEN
;
577 corr
[i
].coef
[0] = 127 - 2;
578 corr
[i
].coef
[1] = 128 + 2;
579 corr
[i
].coef
[2] = (1 << 29) / (127 - 4);
580 corr
[i
].coef
[3] = (1 << 29) / (127 - 4);
586 * js_console_probe() probes for console gamepads.
587 * Only PSX pads can really be probed for.
590 static struct js_port __init
*js_console_probe(int *config
, struct js_port
*port
)
593 int i
, psx
, axes
[5], buttons
[5], type
[5];
594 unsigned char data
[2]; /* used for PSX probe */
595 struct js_console_info info
;
598 memset(&info
, 0, sizeof(struct js_console_info
));
600 if (config
[0] < 0) return port
;
602 if (config
[0] > 0x10)
603 for (pp
=parport_enumerate(); pp
&& (pp
->base
!=config
[0]); pp
=pp
->next
);
605 for (pp
=parport_enumerate(); pp
&& (config
[0]>0); pp
=pp
->next
) config
[0]--;
608 printk(KERN_ERR
"joy-console: no such parport\n");
612 info
.port
= parport_register_device(pp
, "joystick (console)", NULL
, NULL
, NULL
, PARPORT_DEV_EXCL
, NULL
);
616 if (parport_claim(info
.port
))
618 parport_unregister_device(info
.port
); /* port currently not available ... */
622 for (i
= 0; i
< 5; i
++) {
624 type
[info
.pads
] = config
[i
+1];
625 info
.pad_to_device
[i
] = info
.pads
;
627 switch(config
[i
+1]) {
636 buttons
[info
.pads
] = 8;
637 name
[info
.pads
] = "SNES pad";
638 info
.snes
|= status_bit
[i
];
645 buttons
[info
.pads
] = 4;
646 name
[info
.pads
] = "NES pad";
647 info
.nes
|= status_bit
[i
];
653 buttons
[info
.pads
] = 10;
654 name
[info
.pads
] = "N64 pad";
655 info
.n64
|= status_bit
[i
];
661 buttons
[info
.pads
] = 14;
662 name
[info
.pads
] = "N64 pad (DPP mode)";
663 info
.n64
|= status_bit
[i
];
664 info
.n64_dpp
|= status_bit
[i
];
671 buttons
[info
.pads
] = 1;
672 name
[info
.pads
] = "Multisystem joystick";
673 info
.multi
|= status_bit
[i
];
677 case JS_MULTI2_STICK
:
680 buttons
[info
.pads
] = 2;
681 name
[info
.pads
] = "Multisystem joystick (2 fire)";
682 info
.multi
|= status_bit
[i
];
688 info
.psx
|= status_bit
[i
];
689 psx
= js_psx_read_packet(&info
, 2, data
);
690 psx
= js_psx_read_packet(&info
, 2, data
);
691 info
.psx
&= ~status_bit
[i
];
698 buttons
[info
.pads
] = 10;
699 name
[info
.pads
] = "PSX pad";
700 info
.psx
|= status_bit
[i
];
706 buttons
[info
.pads
] = 12;
707 name
[info
.pads
] = "Analog Red PSX pad";
708 info
.psx
|= status_bit
[i
];
714 buttons
[info
.pads
] = 10;
715 name
[info
.pads
] = "Analog Green PSX pad";
716 info
.psx
|= status_bit
[i
];
722 buttons
[info
.pads
] = 10;
723 name
[info
.pads
] = "NegCon PSX pad";
724 info
.psx
|= status_bit
[i
];
729 printk(KERN_WARNING
"joy-psx: PSX mouse not supported...\n");
733 printk(KERN_ERR
"joy-psx: no PSX controller found...\n");
737 printk(KERN_WARNING
"joy-psx: PSX controller unknown: 0x%x,"
738 " please report to <vojtech@suse.cz>.\n", psx
);
744 printk(KERN_WARNING
"joy-console: pad type %d unknown\n", config
[i
+1]);
749 parport_release(info
.port
);
750 parport_unregister_device(info
.port
);
754 port
= js_register_port(port
, &info
, info
.pads
, sizeof(struct js_console_info
), js_console_read
);
756 for (i
= 0; i
< info
.pads
; i
++) {
757 printk(KERN_INFO
"js%d: %s on %s\n",
758 js_register_device(port
, i
, axes
[i
], buttons
[i
], name
[i
], NULL
, js_console_open
, js_console_close
),
759 name
[i
], info
.port
->port
->name
);
761 js_console_init_corr(axes
[i
], type
[i
], port
->corr
[i
]);
764 parport_release(info
.port
);
769 int __init
js_console_setup(SETUP_PARAM
)
773 for (i
= 0; i
<= ints
[0] && i
< 6; i
++) js_console
[i
] = ints
[i
+1];
776 int __init
js_console_setup_2(SETUP_PARAM
)
780 for (i
= 0; i
<= ints
[0] && i
< 6; i
++) js_console_2
[i
] = ints
[i
+1];
783 int __init
js_console_setup_3(SETUP_PARAM
)
787 for (i
= 0; i
<= ints
[0] && i
< 6; i
++) js_console_3
[i
] = ints
[i
+1];
790 __setup("js_console=", js_console_setup
);
791 __setup("js_console_2=", js_console_setup_2
);
792 __setup("js_console_3=", js_console_setup_3
);
796 int init_module(void)
798 int __init
js_console_init(void)
801 js_console_port
= js_console_probe(js_console
, js_console_port
);
802 js_console_port
= js_console_probe(js_console_2
, js_console_port
);
803 js_console_port
= js_console_probe(js_console_3
, js_console_port
);
805 if (js_console_port
) return 0;
808 printk(KERN_WARNING
"joy-console: no joysticks specified\n");