* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / char / joystick / joy-analog.c
blobfdf04b212e24545fe77e34bea7626b528ca27612
1 /*
2 * joy-analog.c Version 1.2
4 * Copyright (c) 1996-1998 Vojtech Pavlik
5 */
7 /*
8 * This is a module for the Linux joystick driver, supporting
9 * up to two analog (or CHF/FCS) joysticks on a single joystick port.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * Should you need to contact me, the author, you can do so either by
28 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
29 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
32 #include <asm/io.h>
33 #include <linux/delay.h>
34 #include <linux/errno.h>
35 #include <linux/ioport.h>
36 #include <linux/joystick.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/string.h>
41 #define JS_AN_MAX_TIME 3000
43 static int js_an_port_list[] __initdata = {0x201, 0};
44 static struct js_port* js_an_port __initdata = NULL;
46 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
47 MODULE_PARM(js_an, "2-24i");
49 static int js_an[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
51 #include "joy-analog.h"
54 * js_an_read() reads analog joystick data.
57 static int js_an_read(void *xinfo, int **axes, int **buttons)
59 struct js_an_info *info = xinfo;
60 unsigned char buf[4];
61 int time[4];
62 unsigned char u, v, a;
63 unsigned int t, t1;
64 int i, j;
65 int timeout;
66 int io = info->io;
68 timeout = (JS_AN_MAX_TIME * js_time_speed_a) >> 10;
70 info->buttons = (~inb(io) & JS_AN_BUTTONS_STD) >> 4;
72 i = 0;
73 u = a = ((info->mask[0] | info->mask[1]) & JS_AN_AXES_STD) | (info->extensions & JS_AN_HAT_FCS)
74 | ((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2) | ((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
76 outb(0xff,io);
77 t = js_get_time_a();
78 do {
79 v = inb(io) & a;
80 t1 = js_get_time_a();
81 if (u ^ v) {
82 time[i] = js_delta_a(t1,t);
83 buf[i] = u ^ v;
84 u = v;
85 i++;
87 } while (v && js_delta_a(t1,t) < timeout);
89 for (--i; i >= 0; i--)
90 for (j = 0; j < 4; j++)
91 if (buf[i] & (1 << j)) info->axes[j] = (time[i] << 10) / js_time_speed_a;
93 js_an_decode(info, axes, buttons);
95 return 0;
99 * js_an_open() is a callback from the file open routine.
102 static int js_an_open(struct js_dev *jd)
104 MOD_INC_USE_COUNT;
105 return 0;
109 * js_an_close() is a callback from the file release routine.
112 static int js_an_close(struct js_dev *jd)
114 MOD_DEC_USE_COUNT;
115 return 0;
119 * js_an_probe() probes for analog joysticks.
122 static struct js_port __init *js_an_probe(int io, int mask0, int mask1, struct js_port *port)
124 struct js_an_info info;
125 int i, numdev;
126 unsigned char u;
128 if (io < 0) return port;
130 if (check_region(io, 1)) return port;
132 if (((u = inb(io)) & 3) == 3) return port;
133 outb(0xff,io);
134 u = inb(io);
135 udelay(JS_AN_MAX_TIME);
136 u = (inb(io) ^ u) & u;
138 if (!u) return port;
139 if (u & 0xf0) return port;
141 if ((numdev = js_an_probe_devs(&info, u, mask0, mask1, port)) <= 0)
142 return port;
144 info.io = io;
145 request_region(info.io, 1, "joystick (analog)");
146 port = js_register_port(port, &info, numdev, sizeof(struct js_an_info), js_an_read);
148 for (i = 0; i < numdev; i++)
149 printk(KERN_INFO "js%d: %s at %#x\n",
150 js_register_device(port, i, js_an_axes(i, &info), js_an_buttons(i, &info),
151 js_an_name(i, &info), js_an_open, js_an_close),
152 js_an_name(i, &info), info.io);
154 js_an_read(port->info, port->axes, port->buttons);
155 js_an_init_corr(port->info, port->axes, port->corr, 8);
157 return port;
160 #ifndef MODULE
161 void __init js_an_setup(char *str, int *ints)
163 int i;
164 for (i = 0; i <= ints[0] && i < 24; i++) js_an[i] = ints[i+1];
166 #endif
168 #ifdef MODULE
169 int init_module(void)
170 #else
171 int __init js_an_init(void)
172 #endif
174 int i;
176 if (js_an[0] >= 0) {
177 for (i = 0; (js_an[i*3] >= 0) && i < 8; i++)
178 js_an_port = js_an_probe(js_an[i*3], js_an[i*3+1], js_an[i*3+2], js_an_port);
179 } else {
180 for (i = 0; js_an_port_list[i]; i++)
181 js_an_port = js_an_probe(js_an_port_list[i], 0, 0, js_an_port);
183 if (js_an_port) return 0;
185 #ifdef MODULE
186 printk(KERN_WARNING "joy-analog: no joysticks found\n");
187 #endif
189 return -ENODEV;
192 #ifdef MODULE
193 void cleanup_module(void)
195 int i;
196 struct js_an_info *info;
198 while (js_an_port != NULL) {
199 for (i = 0; i < js_an_port->ndevs; i++)
200 if (js_an_port->devs[i] != NULL)
201 js_unregister_device(js_an_port->devs[i]);
202 info = js_an_port->info;
203 release_region(info->io, 1);
204 js_an_port = js_unregister_port(js_an_port);
208 #endif