2 * $Id: db9.c,v 1.5 2000/05/29 20:39:38 vojtech Exp $
4 * Copyright (c) 1999 Vojtech Pavlik
6 * Based on the work of:
7 * Andree Borrmann Mats Sjövall
13 * Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver for Linux
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 * Should you need to contact me, the author, you can do so either by
32 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
33 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/delay.h>
39 #include <linux/init.h>
40 #include <linux/parport.h>
41 #include <linux/input.h>
43 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
44 MODULE_PARM(db9
, "2i");
45 MODULE_PARM(db9_2
, "2i");
46 MODULE_PARM(db9_3
, "2i");
48 #define DB9_MULTI_STICK 0x01
49 #define DB9_MULTI2_STICK 0x02
50 #define DB9_GENESIS_PAD 0x03
51 #define DB9_GENESIS5_PAD 0x05
52 #define DB9_GENESIS6_PAD 0x06
53 #define DB9_SATURN_PAD 0x07
54 #define DB9_MULTI_0802 0x08
55 #define DB9_MULTI_0802_2 0x09
56 #define DB9_CD32_PAD 0x0A
57 #define DB9_MAX_PAD 0x0B
62 #define DB9_RIGHT 0x08
63 #define DB9_FIRE1 0x10
64 #define DB9_FIRE2 0x20
65 #define DB9_FIRE3 0x40
66 #define DB9_FIRE4 0x80
68 #define DB9_NORMAL 0x0a
69 #define DB9_NOSELECT 0x08
71 #define DB9_SATURN0 0x00
72 #define DB9_SATURN1 0x02
73 #define DB9_SATURN2 0x04
74 #define DB9_SATURN3 0x06
76 #define DB9_GENESIS6_DELAY 14
77 #define DB9_REFRESH_TIME HZ/100
79 static int db9
[] __initdata
= { -1, 0 };
80 static int db9_2
[] __initdata
= { -1, 0 };
81 static int db9_3
[] __initdata
= { -1, 0 };
84 struct input_dev dev
[2];
85 struct timer_list timer
;
91 static struct db9
*db9_base
[3];
93 static short db9_multi_btn
[] = { BTN_TRIGGER
, BTN_THUMB
};
94 static short db9_genesis_btn
[] = { BTN_START
, BTN_A
, BTN_B
, BTN_C
, BTN_X
, BTN_Y
, BTN_Z
, BTN_MODE
};
95 static short db9_cd32_btn
[] = { BTN_A
, BTN_B
, BTN_C
, BTN_X
, BTN_Y
, BTN_Z
, BTN_TL
, BTN_TR
, BTN_START
};
97 static char db9_buttons
[DB9_MAX_PAD
] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
98 static short *db9_btn
[DB9_MAX_PAD
] = { db9_multi_btn
, db9_multi_btn
, db9_genesis_btn
, NULL
, db9_genesis_btn
,
99 db9_genesis_btn
, db9_cd32_btn
, db9_multi_btn
, db9_multi_btn
, db9_cd32_btn
};
100 static char *db9_name
[DB9_MAX_PAD
] = { NULL
, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
101 NULL
, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
102 "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
104 static void db9_timer(unsigned long private)
106 struct db9
*db9
= (void *) private;
107 struct parport
*port
= db9
->pd
->port
;
108 struct input_dev
*dev
= db9
->dev
;
112 case DB9_MULTI_0802_2
:
114 data
= parport_read_data(port
) >> 3;
116 input_report_abs(dev
+ 1, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
117 input_report_abs(dev
+ 1, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
118 input_report_key(dev
+ 1, BTN_TRIGGER
, ~data
&DB9_FIRE1
);
122 data
= parport_read_status(port
) >> 3;
124 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
125 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
126 input_report_key(dev
, BTN_TRIGGER
, data
&DB9_FIRE1
);
129 case DB9_MULTI_STICK
:
131 data
= parport_read_data(port
);
133 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
134 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
135 input_report_key(dev
, BTN_TRIGGER
, ~data
&DB9_FIRE1
);
138 case DB9_MULTI2_STICK
:
140 data
= parport_read_data(port
);
142 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
143 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
144 input_report_key(dev
, BTN_TRIGGER
, ~data
&DB9_FIRE1
);
145 input_report_key(dev
, BTN_THUMB
, ~data
&DB9_FIRE2
);
148 case DB9_GENESIS_PAD
:
150 parport_write_control(port
, DB9_NOSELECT
);
151 data
= parport_read_data(port
);
153 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
154 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
155 input_report_key(dev
, BTN_B
, ~data
&DB9_FIRE1
);
156 input_report_key(dev
, BTN_C
, ~data
&DB9_FIRE2
);
158 parport_write_control(port
, DB9_NORMAL
);
159 data
=parport_read_data(port
);
161 input_report_key(dev
, BTN_A
, ~data
&DB9_FIRE1
);
162 input_report_key(dev
, BTN_START
, ~data
&DB9_FIRE2
);
165 case DB9_GENESIS5_PAD
:
167 parport_write_control(port
, DB9_NOSELECT
);
168 data
=parport_read_data(port
);
170 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
171 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
172 input_report_key(dev
, BTN_B
, ~data
&DB9_FIRE1
);
173 input_report_key(dev
, BTN_C
, ~data
&DB9_FIRE2
);
175 parport_write_control(port
, DB9_NORMAL
);
176 data
=parport_read_data(port
);
178 input_report_key(dev
, BTN_A
, ~data
&DB9_FIRE1
);
179 input_report_key(dev
, BTN_X
, ~data
&DB9_FIRE2
);
180 input_report_key(dev
, BTN_Y
, ~data
&DB9_LEFT
);
181 input_report_key(dev
, BTN_START
, ~data
&DB9_RIGHT
);
184 case DB9_GENESIS6_PAD
:
186 parport_write_control(port
, DB9_NOSELECT
); /* 1 */
187 udelay(DB9_GENESIS6_DELAY
);
188 data
=parport_read_data(port
);
190 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
191 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
192 input_report_key(dev
, BTN_B
, ~data
&DB9_FIRE1
);
193 input_report_key(dev
, BTN_C
, ~data
&DB9_FIRE2
);
195 parport_write_control(port
, DB9_NORMAL
);
196 udelay(DB9_GENESIS6_DELAY
);
197 data
=parport_read_data(port
);
199 input_report_key(dev
, BTN_A
, ~data
&DB9_FIRE1
);
200 input_report_key(dev
, BTN_X
, ~data
&DB9_FIRE2
);
202 parport_write_control(port
, DB9_NOSELECT
); /* 2 */
203 udelay(DB9_GENESIS6_DELAY
);
204 parport_write_control(port
, DB9_NORMAL
);
205 udelay(DB9_GENESIS6_DELAY
);
206 parport_write_control(port
, DB9_NOSELECT
); /* 3 */
207 udelay(DB9_GENESIS6_DELAY
);
208 data
=parport_read_data(port
);
210 input_report_key(dev
, BTN_Y
, ~data
&DB9_LEFT
);
211 input_report_key(dev
, BTN_Z
, ~data
&DB9_DOWN
);
212 input_report_key(dev
, BTN_MODE
, ~data
&DB9_UP
);
213 input_report_key(dev
, BTN_START
, ~data
&DB9_RIGHT
);
215 parport_write_control(port
, DB9_NORMAL
);
216 udelay(DB9_GENESIS6_DELAY
);
217 parport_write_control(port
, DB9_NOSELECT
); /* 4 */
218 udelay(DB9_GENESIS6_DELAY
);
219 parport_write_control(port
, DB9_NORMAL
);
224 parport_write_control(port
, DB9_SATURN0
);
225 data
= parport_read_data(port
);
227 input_report_key(dev
, BTN_Y
, ~data
&DB9_LEFT
);
228 input_report_key(dev
, BTN_Z
, ~data
&DB9_DOWN
);
229 input_report_key(dev
, BTN_TL
,~data
&DB9_UP
);
230 input_report_key(dev
, BTN_TR
,~data
&DB9_RIGHT
);
232 parport_write_control(port
, DB9_SATURN2
);
233 data
= parport_read_data(port
);
235 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
236 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
238 parport_write_control(port
, DB9_NORMAL
);
239 data
= parport_read_data(port
);
241 input_report_key(dev
, BTN_A
, ~data
&DB9_LEFT
);
242 input_report_key(dev
, BTN_B
, ~data
&DB9_UP
);
243 input_report_key(dev
, BTN_C
, ~data
&DB9_DOWN
);
244 input_report_key(dev
, BTN_X
, ~data
&DB9_RIGHT
);
249 data
=parport_read_data(port
);
251 input_report_abs(dev
, ABS_X
, (data
&DB9_DOWN
?0:1) - (data
&DB9_UP
?0:1));
252 input_report_abs(dev
, ABS_Y
, (data
&DB9_RIGHT
?0:1) - (data
&DB9_LEFT
?0:1));
254 parport_write_control(port
, 0x0a);
256 for (i
= 0; i
< 7; i
++) {
257 data
= parport_read_data(port
);
258 parport_write_control(port
, 0x02);
259 parport_write_control(port
, 0x0a);
260 input_report_key(dev
, db9_cd32_btn
[i
], ~data
&DB9_FIRE2
);
263 parport_write_control(port
, 0x00);
267 mod_timer(&db9
->timer
, jiffies
+ DB9_REFRESH_TIME
);
270 static int db9_open(struct input_dev
*dev
)
272 struct db9
*db9
= dev
->private;
273 struct parport
*port
= db9
->pd
->port
;
276 parport_claim(db9
->pd
);
277 parport_write_data(port
, 0xff);
278 parport_data_reverse(port
);
279 parport_write_control(port
, DB9_NORMAL
);
280 mod_timer(&db9
->timer
, jiffies
+ DB9_REFRESH_TIME
);
286 static void db9_close(struct input_dev
*dev
)
288 struct db9
*db9
= dev
->private;
289 struct parport
*port
= db9
->pd
->port
;
292 del_timer(&db9
->timer
);
293 parport_write_control(port
, 0x00);
294 parport_data_forward(port
);
295 parport_release(db9
->pd
);
299 static struct db9 __init
*db9_probe(int *config
)
307 if (config
[1] < 1 || config
[1] >= DB9_MAX_PAD
|| !db9_buttons
[config
[1]]) {
308 printk(KERN_ERR
"db9.c: bad config\n");
312 for (pp
= parport_enumerate(); pp
&& (config
[0] > 0); pp
= pp
->next
)
316 printk(KERN_ERR
"db9.c: no such parport\n");
320 if (!(pp
->modes
& PARPORT_MODE_TRISTATE
) && config
[1] != DB9_MULTI_0802
) {
321 printk(KERN_ERR
"db9.c: specified parport is not bidirectional\n");
325 if (!(db9
= kmalloc(sizeof(struct db9
), GFP_KERNEL
)))
327 memset(db9
, 0, sizeof(struct db9
));
329 db9
->mode
= config
[1];
330 init_timer(&db9
->timer
);
331 db9
->timer
.data
= (long) db9
;
332 db9
->timer
.function
= db9_timer
;
334 db9
->pd
= parport_register_device(pp
, "db9", NULL
, NULL
, NULL
, PARPORT_DEV_EXCL
, NULL
);
337 printk(KERN_ERR
"db9.c: parport busy already - lp.o loaded?\n");
342 for (i
= 0; i
< 1 + (db9
->mode
== DB9_MULTI_0802_2
); i
++) {
344 db9
->dev
[i
].private = db9
;
345 db9
->dev
[i
].open
= db9_open
;
346 db9
->dev
[i
].close
= db9_close
;
348 db9
->dev
[i
].name
= db9_name
[db9
->mode
];
349 db9
->dev
[i
].idbus
= BUS_PARPORT
;
350 db9
->dev
[i
].idvendor
= 0x0002;
351 db9
->dev
[i
].idproduct
= config
[1];
352 db9
->dev
[i
].idversion
= 0x0100;
354 db9
->dev
[i
].evbit
[0] = BIT(EV_KEY
) | BIT(EV_ABS
);
355 db9
->dev
[i
].absbit
[0] = BIT(ABS_X
) | BIT(ABS_Y
);
357 for (j
= 0; j
< db9_buttons
[db9
->mode
]; j
++)
358 set_bit(db9_btn
[db9
->mode
][j
], db9
->dev
[i
].keybit
);
360 db9
->dev
[i
].absmin
[ABS_X
] = -1; db9
->dev
[i
].absmax
[ABS_X
] = 1;
361 db9
->dev
[i
].absmin
[ABS_Y
] = -1; db9
->dev
[i
].absmax
[ABS_Y
] = 1;
363 input_register_device(db9
->dev
+ i
);
364 printk(KERN_INFO
"input%d: %s on %s\n",
365 db9
->dev
[i
].number
, db9_name
[db9
->mode
], db9
->pd
->port
->name
);
372 int __init
db9_setup(char *str
)
375 get_options(str
, ARRAY_SIZE(ints
), ints
);
376 for (i
= 0; i
<= ints
[0] && i
< 2; i
++) db9
[i
] = ints
[i
+ 1];
379 int __init
db9_setup_2(char *str
)
382 get_options(str
, ARRAY_SIZE(ints
), ints
);
383 for (i
= 0; i
<= ints
[0] && i
< 2; i
++) db9_2
[i
] = ints
[i
+ 1];
386 int __init
db9_setup_3(char *str
)
389 get_options(str
, ARRAY_SIZE(ints
), ints
);
390 for (i
= 0; i
<= ints
[0] && i
< 2; i
++) db9_3
[i
] = ints
[i
+ 1];
393 __setup("db9=", db9_setup
);
394 __setup("db9_2=", db9_setup_2
);
395 __setup("db9_3=", db9_setup_3
);
398 int __init
db9_init(void)
400 db9_base
[0] = db9_probe(db9
);
401 db9_base
[1] = db9_probe(db9_2
);
402 db9_base
[2] = db9_probe(db9_3
);
404 if (db9_base
[0] || db9_base
[1] || db9_base
[2])
410 void __exit
db9_exit(void)
414 for (i
= 0; i
< 3; i
++)
416 for (j
= 0; j
< 1 + (db9_base
[i
]->mode
== DB9_MULTI_0802_2
); j
++)
417 input_unregister_device(db9_base
[i
]->dev
+ j
);
418 parport_unregister_device(db9_base
[i
]->pd
);
422 module_init(db9_init
);
423 module_exit(db9_exit
);