* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / char / joystick / joy-turbografx.c
blobfdf1aa43300fcbd1b71ba9ca8ce77f44bd9da64d
1 /*
2 * joy-turbografx.c Version 1.2
4 * Copyright (c) 1998 Vojtech Pavlik
5 */
7 /*
8 * This is a module for the Linux joystick driver, supporting
9 * Steffen Schwenke's <schwenke@burg-halle.de> TurboGraFX parallel port
10 * interface.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Should you need to contact me, the author, you can do so either by
29 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
30 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
33 #include <asm/io.h>
34 #include <asm/system.h>
35 #include <linux/errno.h>
36 #include <linux/ioport.h>
37 #include <linux/joystick.h>
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/string.h>
41 #include <linux/delay.h>
44 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
45 MODULE_PARM(js_tg, "2-8i");
46 MODULE_PARM(js_tg_2, "2-8i");
47 MODULE_PARM(js_tg_3, "2-8i");
49 #define JS_TG_BUTTON1 0x08
50 #define JS_TG_UP 0x10
51 #define JS_TG_DOWN 0x20
52 #define JS_TG_LEFT 0x40
53 #define JS_TG_RIGHT 0x80
55 #define JS_TG_BUTTON2 0x02
56 #define JS_TG_BUTTON3 0x04
57 #define JS_TG_BUTTON4 0x01
58 #define JS_TG_BUTTON5 0x08
60 static struct js_port* js_tg_port = NULL;
62 static int js_tg[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
63 static int js_tg_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
64 static int js_tg_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
66 struct js_tg_info {
67 #ifdef USE_PARPORT
68 struct pardevice *port; /* parport device */
69 #else
70 int port; /* hw port */
71 #endif
72 int sticks; /* joysticks connected */
76 * js_tg_read() reads and analyzes tg joystick data.
79 static int js_tg_read(void *xinfo, int **axes, int **buttons)
81 struct js_tg_info *info = xinfo;
82 int data1, data2, i;
84 for (i = 0; i < 7; i++)
85 if ((info->sticks >> i) & 1) {
87 JS_PAR_DATA_OUT(~(1 << i), info->port);
88 data1 = JS_PAR_STATUS(info->port) ^ ~JS_PAR_STATUS_INVERT;
89 data2 = JS_PAR_CTRL_IN(info->port) ^ JS_PAR_CTRL_INVERT;
91 axes[i][0] = ((data1 & JS_TG_RIGHT) ? 1 : 0) - ((data1 & JS_TG_LEFT) ? 1 : 0);
92 axes[i][1] = ((data1 & JS_TG_DOWN ) ? 1 : 0) - ((data1 & JS_TG_UP ) ? 1 : 0);
94 buttons[i][0] = ((data1 & JS_TG_BUTTON1) ? 0x01 : 0) | ((data2 & JS_TG_BUTTON2) ? 0x02 : 0)
95 | ((data2 & JS_TG_BUTTON3) ? 0x04 : 0) | ((data2 & JS_TG_BUTTON4) ? 0x08 : 0)
96 | ((data2 & JS_TG_BUTTON5) ? 0x10 : 0);
100 return 0;
104 * open callback: claim parport.
107 int js_tg_open(struct js_dev *dev)
109 struct js_tg_info *info = dev->port->info;
111 if (!MOD_IN_USE) {
112 #ifdef USE_PARPORT
113 if (parport_claim(info->port)) return -EBUSY;
114 #endif
115 JS_PAR_CTRL_OUT(0x04, info->port);
117 MOD_INC_USE_COUNT;
118 return 0;
122 * close callback: release parport
125 int js_tg_close(struct js_dev *dev)
127 struct js_tg_info *info = dev->port->info;
129 MOD_DEC_USE_COUNT;
130 if (!MOD_IN_USE) {
131 JS_PAR_CTRL_OUT(0x00, info->port);
132 #ifdef USE_PARPORT
133 parport_release(info->port);
134 #endif
136 return 0;
139 #ifdef MODULE
140 void cleanup_module(void)
142 struct js_tg_info *info;
143 int i;
145 while (js_tg_port != NULL) {
146 for (i = 0; i < js_tg_port->ndevs; i++)
147 if (js_tg_port->devs[i] != NULL)
148 js_unregister_device(js_tg_port->devs[i]);
149 info = js_tg_port->info;
150 #ifdef USE_PARPORT
151 parport_unregister_device(info->port);
152 #else
153 release_region(info->port, 3);
154 #endif
155 js_tg_port = js_unregister_port(js_tg_port);
158 #endif
161 * js_tg_init_corr() initializes correction values of
162 * tg gamepads.
165 static void __init js_tg_init_corr(int sticks, struct js_corr **corr)
167 int i, j;
169 for (i = 0; i < 7; i++)
170 if ((sticks >> i) & 1)
171 for (j = 0; j < 2; j++) {
172 corr[i][j].type = JS_CORR_BROKEN;
173 corr[i][j].prec = 0;
174 corr[i][j].coef[0] = 0;
175 corr[i][j].coef[1] = 0;
176 corr[i][j].coef[2] = (1 << 29);
177 corr[i][j].coef[3] = (1 << 29);
182 * js_tg_probe() probes for tg gamepads.
185 static struct js_port __init *js_tg_probe(int *config, struct js_port *port)
187 struct js_tg_info iniinfo;
188 struct js_tg_info *info = &iniinfo;
189 int i;
191 if (config[0] < 0) return port;
193 #ifdef USE_PARPORT
195 struct parport *pp;
197 if (config[0] > 0x10)
198 for (pp=parport_enumerate(); pp != NULL && (pp->base!=config[0]); pp=pp->next);
199 else
200 for (pp=parport_enumerate(); pp != NULL && (config[0]>0); pp=pp->next) config[0]--;
202 if (pp == NULL) {
203 printk(KERN_ERR "joy-tg: no such parport\n");
204 return port;
207 info->port = parport_register_device(pp, "joystick (turbografx)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
208 if (!info->port)
209 return port;
211 #else
212 info->port = config[0];
213 if (check_region(info->port, 3)) return port;
214 request_region(info->port, 3, "joystick (turbografx)");
215 #endif
217 port = js_register_port(port, info, 7, sizeof(struct js_tg_info), js_tg_read);
218 info = port->info;
220 info->sticks = 0;
222 for (i = 0; i < 7; i++)
223 if (config[i+1] > 0 && config[i+1] < 6) {
224 #ifdef USE_PARPORT
225 printk(KERN_INFO "js%d: Multisystem joystick on %s\n",
226 js_register_device(port, i, 2, config[i+1], "Multisystem joystick", js_tg_open, js_tg_close),
227 info->port->port->name);
228 #else
229 printk(KERN_INFO "js%d: Multisystem joystick at %#x\n",
230 js_register_device(port, i, 2, config[i+1], "Multisystem joystick", js_tg_open, js_tg_close),
231 info->port);
232 #endif
233 info->sticks |= (1 << i);
236 if (!info->sticks) {
237 #ifdef USE_PARPORT
238 parport_unregister_device(info->port);
239 #else
240 release_region(info->port, 3);
241 #endif
242 return port;
245 js_tg_init_corr(info->sticks, port->corr);
247 return port;
250 #ifndef MODULE
251 void __init js_tg_setup(char *str, int *ints)
253 int i;
255 if (!strcmp(str,"js_tg"))
256 for (i = 0; i <= ints[0] && i < 2; i++) js_tg[i] = ints[i+1];
257 if (!strcmp(str,"js_tg_2"))
258 for (i = 0; i <= ints[0] && i < 2; i++) js_tg_2[i] = ints[i+1];
259 if (!strcmp(str,"js_tg_3"))
260 for (i = 0; i <= ints[0] && i < 2; i++) js_tg_3[i] = ints[i+1];
263 #endif
265 #ifdef MODULE
266 int init_module(void)
267 #else
268 int __init js_tg_init(void)
269 #endif
271 js_tg_port = js_tg_probe(js_tg, js_tg_port);
272 js_tg_port = js_tg_probe(js_tg_2, js_tg_port);
273 js_tg_port = js_tg_probe(js_tg_3, js_tg_port);
275 if (js_tg_port) return 0;
277 #ifdef MODULE
278 printk(KERN_WARNING "joy-tg: no joysticks specified\n");
279 #endif
280 return -ENODEV;