2 * joy-analog.c Version 1.2
4 * Copyright (c) 1996-1998 Vojtech Pavlik
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
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
;
62 unsigned char u
, v
, a
;
68 timeout
= (JS_AN_MAX_TIME
* js_time_speed_a
) >> 10;
70 info
->buttons
= (~inb(io
) & JS_AN_BUTTONS_STD
) >> 4;
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);
82 time
[i
] = js_delta_a(t1
,t
);
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
);
99 * js_an_open() is a callback from the file open routine.
102 static int js_an_open(struct js_dev
*jd
)
109 * js_an_close() is a callback from the file release routine.
112 static int js_an_close(struct js_dev
*jd
)
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
;
128 if (io
< 0) return port
;
130 if (check_region(io
, 1)) return port
;
132 if (((u
= inb(io
)) & 3) == 3) return port
;
135 udelay(JS_AN_MAX_TIME
);
136 u
= (inb(io
) ^ u
) & u
;
139 if (u
& 0xf0) return port
;
141 if ((numdev
= js_an_probe_devs(&info
, u
, mask0
, mask1
, port
)) <= 0)
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);
161 void __init
js_an_setup(char *str
, int *ints
)
164 for (i
= 0; i
<= ints
[0] && i
< 24; i
++) js_an
[i
] = ints
[i
+1];
169 int init_module(void)
171 int __init
js_an_init(void)
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
);
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;
186 printk(KERN_WARNING
"joy-analog: no joysticks found\n");
193 void cleanup_module(void)
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
);