Import 2.4.0-test2pre6
[davej-history.git] / drivers / char / joystick / joy-console.c
blobe56da540adde54826b735cf56d0bd04fd9158259
1 /*
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
9 * Sponsored by SuSE
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
39 #include <asm/io.h>
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");
57 #define JS_NO_PAD 0
58 #define JS_SNES_PAD 1
59 #define JS_NES_PAD 2
60 #define JS_NES4_PAD 3
61 #define JS_MULTI_STICK 4
62 #define JS_MULTI2_STICK 5
63 #define JS_PSX_PAD 6
64 #define JS_N64_PAD 7
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 };
91 * NES/SNES support.
94 #define JS_NES_DELAY 6 /* Delay between bits - 6us */
96 #define JS_NES_LENGTH 8 /* The NES pads use 8 bits of data */
98 #define JS_NES_A 0
99 #define JS_NES_B 1
100 #define JS_NES_START 2
101 #define JS_NES_SELECT 3
102 #define JS_NES_UP 4
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 */
109 #define JS_SNES_B 0
110 #define JS_SNES_Y 1
111 #define JS_SNES_START 2
112 #define JS_SNES_SELECT 3
113 #define JS_SNES_UP 4
114 #define JS_SNES_DOWN 5
115 #define JS_SNES_LEFT 6
116 #define JS_SNES_RIGHT 7
117 #define JS_SNES_A 8
118 #define JS_SNES_X 9
119 #define JS_SNES_L 10
120 #define JS_SNES_R 11
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)
134 int i;
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);
150 * N64 support.
153 #define JS_N64_A 0
154 #define JS_N64_B 1
155 #define JS_N64_Z 2
156 #define JS_N64_START 3
157 #define JS_N64_UP 4
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
163 #define JS_N64_L 10
164 #define JS_N64_R 11
165 #define JS_N64_CU 12
166 #define JS_N64_CD 13
167 #define JS_N64_CL 14
168 #define JS_N64_CR 15
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)
193 int i;
194 unsigned long flags;
197 * Request the pad to transmit data
200 save_flags(flags);
201 cli();
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);
204 udelay(JS_N64_DWS);
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)
251 int i;
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]);
258 printk("\n");
262 * PSX support
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
291 * the psx pad.
294 static int js_psx_command(struct js_console_info *info, int b)
296 int i, cmd, ret=0;
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);
306 b >>= 1;
308 return ret;
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)
318 int i, ret;
319 unsigned long flags;
321 __save_flags(flags);
322 __cli();
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);
333 else ret = -1;
335 JS_PAR_DATA_OUT(JS_PSX_SELECT | JS_PSX_CLOCK | JS_PSX_POWER, info->port);
336 __restore_flags(flags);
338 return ret;
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];
353 int i, j, s;
354 int n = 0;
357 * NES and SNES pads
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++) {
365 s = status_bit[i];
366 n = info->pad_to_device[i];
367 if (info->nes & s) {
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);
373 } else
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);
387 * N64 pads
390 if (info->n64) {
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++) {
399 s = status_bit[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);
412 } else {
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 */
418 j = 7;
419 axes[n][0] = (data[JS_N64_X - j] & s) ? ~0x7f : 0;
420 axes[n][1] = (data[JS_N64_Y - j] & s) ? ~0x7f : 0;
421 while ( j-- > 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++) {
441 s = status_bit[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;
448 } else
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;
459 * PSX controllers
462 if (info->psx) {
464 for ( i = 0; i < 5; i++ )
465 if ( info->psx & status_bit[i] ) {
466 n = info->pad_to_device[i];
467 break;
470 buttons[n][0] = 0;
472 switch (js_psx_read_packet(info, 6, data)) {
474 case JS_PSX_ANALOGR:
476 buttons[n][0] |= (data[0]&JS_PSX_JOYL?0:0x800) | (data[0]&JS_PSX_JOYR?0:0x400);
478 case JS_PSX_ANALOGG:
480 axes[n][2] = data[2];
481 axes[n][3] = data[3];
482 axes[n][4] = data[4];
483 axes[n][5] = data[5];
485 case JS_PSX_NORMAL:
486 case JS_PSX_NEGCON:
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);
494 break;
499 return 0;
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;
511 MOD_INC_USE_COUNT;
512 return 0;
516 * close callback: release parport
519 int js_console_close(struct js_dev *dev)
521 struct js_console_info *info = dev->port->info;
522 MOD_DEC_USE_COUNT;
523 if (!MOD_IN_USE) parport_release(info->port);
524 return 0;
527 #ifdef MODULE
528 void cleanup_module(void)
530 struct js_console_info *info;
531 int i;
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);
542 #endif
545 * js_console_init_corr() initializes correction values of
546 * console gamepads.
549 static void __init js_console_init_corr(int num_axes, int type, struct js_corr *corr)
551 int i;
553 for (i = 0; i < num_axes; i++) {
554 corr[i].type = JS_CORR_BROKEN;
555 corr[i].prec = 0;
556 corr[i].coef[0] = 0;
557 corr[i].coef[1] = 0;
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;
565 corr[i].prec = 0;
566 corr[i].coef[0] = 0;
567 corr[i].coef[1] = 0;
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;
576 corr[i].prec = 0;
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)
592 char *name[5];
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;
596 struct parport *pp;
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);
604 else
605 for (pp=parport_enumerate(); pp && (config[0]>0); pp=pp->next) config[0]--;
607 if (!pp) {
608 printk(KERN_ERR "joy-console: no such parport\n");
609 return port;
612 info.port = parport_register_device(pp, "joystick (console)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
613 if (!info.port)
614 return port;
616 if (parport_claim(info.port))
618 parport_unregister_device(info.port); /* port currently not available ... */
619 return port;
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]) {
629 case JS_NO_PAD:
631 break;
633 case JS_SNES_PAD:
635 axes[info.pads] = 2;
636 buttons[info.pads] = 8;
637 name[info.pads] = "SNES pad";
638 info.snes |= status_bit[i];
639 info.pads++;
640 break;
642 case JS_NES_PAD:
644 axes[info.pads] = 2;
645 buttons[info.pads] = 4;
646 name[info.pads] = "NES pad";
647 info.nes |= status_bit[i];
648 info.pads++;
649 break;
651 case JS_N64_PAD:
652 axes[info.pads] = 4;
653 buttons[info.pads] = 10;
654 name[info.pads] = "N64 pad";
655 info.n64 |= status_bit[i];
656 info.pads++;
657 break;
659 case JS_N64_PAD_DPP:
660 axes[info.pads] = 2;
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];
665 info.pads++;
666 break;
668 case JS_MULTI_STICK:
670 axes[info.pads] = 2;
671 buttons[info.pads] = 1;
672 name[info.pads] = "Multisystem joystick";
673 info.multi |= status_bit[i];
674 info.pads++;
675 break;
677 case JS_MULTI2_STICK:
679 axes[info.pads] = 2;
680 buttons[info.pads] = 2;
681 name[info.pads] = "Multisystem joystick (2 fire)";
682 info.multi |= status_bit[i];
683 info.pads++;
684 break;
686 case JS_PSX_PAD:
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];
693 type[i] = psx;
695 switch(psx) {
696 case JS_PSX_NORMAL:
697 axes[info.pads] = 2;
698 buttons[info.pads] = 10;
699 name[info.pads] = "PSX pad";
700 info.psx |= status_bit[i];
701 info.pads++;
702 break;
704 case JS_PSX_ANALOGR:
705 axes[info.pads] = 6;
706 buttons[info.pads] = 12;
707 name[info.pads] = "Analog Red PSX pad";
708 info.psx |= status_bit[i];
709 info.pads++;
710 break;
712 case JS_PSX_ANALOGG:
713 axes[info.pads] = 6;
714 buttons[info.pads] = 10;
715 name[info.pads] = "Analog Green PSX pad";
716 info.psx |= status_bit[i];
717 info.pads++;
718 break;
720 case JS_PSX_NEGCON:
721 axes[info.pads] = 2;
722 buttons[info.pads] = 10;
723 name[info.pads] = "NegCon PSX pad";
724 info.psx |= status_bit[i];
725 info.pads++;
726 break;
728 case JS_PSX_MOUSE:
729 printk(KERN_WARNING "joy-psx: PSX mouse not supported...\n");
730 break;
732 case -1:
733 printk(KERN_ERR "joy-psx: no PSX controller found...\n");
734 break;
736 default:
737 printk(KERN_WARNING "joy-psx: PSX controller unknown: 0x%x,"
738 " please report to <vojtech@suse.cz>.\n", psx);
740 break;
742 default:
744 printk(KERN_WARNING "joy-console: pad type %d unknown\n", config[i+1]);
748 if (!info.pads) {
749 parport_release(info.port);
750 parport_unregister_device(info.port);
751 return 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);
765 return port;
768 #ifndef MODULE
769 int __init js_console_setup(SETUP_PARAM)
771 int i;
772 SETUP_PARSE(6);
773 for (i = 0; i <= ints[0] && i < 6; i++) js_console[i] = ints[i+1];
774 return 1;
776 int __init js_console_setup_2(SETUP_PARAM)
778 int i;
779 SETUP_PARSE(6);
780 for (i = 0; i <= ints[0] && i < 6; i++) js_console_2[i] = ints[i+1];
781 return 1;
783 int __init js_console_setup_3(SETUP_PARAM)
785 int i;
786 SETUP_PARSE(6);
787 for (i = 0; i <= ints[0] && i < 6; i++) js_console_3[i] = ints[i+1];
788 return 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);
793 #endif
795 #ifdef MODULE
796 int init_module(void)
797 #else
798 int __init js_console_init(void)
799 #endif
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;
807 #ifdef MODULE
808 printk(KERN_WARNING "joy-console: no joysticks specified\n");
809 #endif
810 return -ENODEV;