* better
[mascara-docs.git] / i386 / linux-2.3.21 / drivers / char / joystick / joy-analog.h
blob06c0079a4a0d971fb689b4e622abdbee3e8a20c8
1 /*
2 * joy-analog.h Version 1.2
4 * Copyright (c) 1996-1998 Vojtech Pavlik
5 */
7 /*
8 * This file is designed to be included in any joystick driver
9 * that communicates with standard analog joysticks. This currently
10 * is: joy-analog.c, joy-assasin.c, and joy-lightning.c
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 #define JS_AN_AXES_STD 0x0f
34 #define JS_AN_BUTTONS_STD 0xf0
36 #define JS_AN_BUTTONS_CHF 0x01
37 #define JS_AN_HAT1_CHF 0x02
38 #define JS_AN_HAT2_CHF 0x04
39 #define JS_AN_ANY_CHF 0x07
40 #define JS_AN_HAT_FCS 0x08
41 #define JS_AN_HATS_ALL 0x0e
42 #define JS_AN_BUTTON_PXY_X 0x10
43 #define JS_AN_BUTTON_PXY_Y 0x20
44 #define JS_AN_BUTTON_PXY_U 0x40
45 #define JS_AN_BUTTON_PXY_V 0x80
46 #define JS_AN_BUTTONS_PXY_XY 0x30
47 #define JS_AN_BUTTONS_PXY_UV 0xc0
48 #define JS_AN_BUTTONS_PXY 0xf0
50 static struct {
51 int x;
52 int y;
53 } js_an_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1, 0}, { 0, 1}, {-1, 0}};
55 struct js_an_info {
56 int io;
57 unsigned char mask[2];
58 unsigned int extensions;
59 int axes[4];
60 int initial[4];
61 unsigned char buttons;
65 * js_an_decode() decodes analog joystick data.
68 static void js_an_decode(struct js_an_info *info, int **axes, int **buttons)
70 int i, j, k;
71 int hat1, hat2, hat3;
73 hat1 = hat2 = hat3 = 0;
74 if (info->mask[0] & JS_AN_BUTTONS_STD) buttons[0][0] = 0;
75 if (info->mask[1] & JS_AN_BUTTONS_STD) buttons[1][0] = 0;
77 if (info->extensions & JS_AN_ANY_CHF) {
78 switch (info->buttons) {
79 case 0x1: buttons[0][0] = 0x01; break;
80 case 0x2: buttons[0][0] = 0x02; break;
81 case 0x4: buttons[0][0] = 0x04; break;
82 case 0x8: buttons[0][0] = 0x08; break;
83 case 0x5: buttons[0][0] = 0x10; break;
84 case 0x9: buttons[0][0] = 0x20; break;
85 case 0xf: hat1 = 1; break;
86 case 0xb: hat1 = 2; break;
87 case 0x7: hat1 = 3; break;
88 case 0x3: hat1 = 4; break;
89 case 0xe: hat2 = 1; break;
90 case 0xa: hat2 = 2; break;
91 case 0x6: hat2 = 3; break;
92 case 0xc: hat2 = 4; break;
94 k = info->extensions & JS_AN_BUTTONS_CHF ? 6 : 4;
95 } else {
96 for (i = 1; i >= 0; i--)
97 for (j = k = 0; j < 4; j++)
98 if (info->mask[i] & (0x10 << j))
99 buttons[i][0] |= ((info->buttons >> j) & 1) << k++;
102 if (info->extensions & JS_AN_BUTTON_PXY_X)
103 buttons[0][0] |= (info->axes[2] < (info->initial[2] >> 1)) << k++;
104 if (info->extensions & JS_AN_BUTTON_PXY_Y)
105 buttons[0][0] |= (info->axes[3] < (info->initial[3] >> 1)) << k++;
106 if (info->extensions & JS_AN_BUTTON_PXY_U)
107 buttons[0][0] |= (info->axes[2] > (info->initial[2] + (info->initial[2] >> 1))) << k++;
108 if (info->extensions & JS_AN_BUTTON_PXY_V)
109 buttons[0][0] |= (info->axes[3] > (info->initial[3] + (info->initial[3] >> 1))) << k++;
111 if (info->extensions & JS_AN_HAT_FCS)
112 for (j = 0; j < 4; j++)
113 if (info->axes[3] < ((info->initial[3] * ((j << 1) + 1)) >> 3)) {
114 hat3 = j + 1;
115 break;
118 for (i = 1; i >= 0; i--)
119 for (j = k = 0; j < 4; j++)
120 if (info->mask[i] & (1 << j))
121 axes[i][k++] = info->axes[j];
123 if (info->extensions & JS_AN_HAT1_CHF) {
124 axes[0][k++] = js_an_hat_to_axis[hat1].x;
125 axes[0][k++] = js_an_hat_to_axis[hat1].y;
127 if (info->extensions & JS_AN_HAT2_CHF) {
128 axes[0][k++] = js_an_hat_to_axis[hat2].x;
129 axes[0][k++] = js_an_hat_to_axis[hat2].y;
131 if (info->extensions & JS_AN_HAT_FCS) {
132 axes[0][k++] = js_an_hat_to_axis[hat3].x;
133 axes[0][k++] = js_an_hat_to_axis[hat3].y;
138 * js_an_count_bits() counts set bits in a byte.
141 static inline int js_an_count_bits(unsigned long c)
143 int i = 0;
144 while (c) {
145 i += c & 1;
146 c >>= 1;
148 return i;
152 * js_an_init_corr() initializes the correction values for
153 * analog joysticks.
156 static void __init js_an_init_corr(struct js_an_info *info, int **axes, struct js_corr **corr, int prec)
158 int i, j, t;
160 for (i = 0; i < 2; i++)
161 for (j = 0; j < js_an_count_bits(info->mask[i] & 0xf); j++) {
163 if ((j == 2 && (info->mask[i] & 0xb) == 0xb) ||
164 (j == 3 && (info->mask[i] & 0xf) == 0xf)) {
165 t = (axes[i][0] + axes[i][1]) >> 1;
166 } else {
167 t = axes[i][j];
170 corr[i][j].type = JS_CORR_BROKEN;
171 corr[i][j].prec = prec;
172 corr[i][j].coef[0] = t - (t >> 3);
173 corr[i][j].coef[1] = t + (t >> 3);
174 corr[i][j].coef[2] = (1 << 29) / (t - (t >> 2) + 1);
175 corr[i][j].coef[3] = (1 << 29) / (t - (t >> 2) + 1);
178 i = js_an_count_bits(info->mask[0] & 0xf);
180 for (j = i; j < i + (js_an_count_bits(info->extensions & JS_AN_HATS_ALL) << 1); j++) {
181 corr[0][j].type = JS_CORR_BROKEN;
182 corr[0][j].prec = 0;
183 corr[0][j].coef[0] = 0;
184 corr[0][j].coef[1] = 0;
185 corr[0][j].coef[2] = (1 << 29);
186 corr[0][j].coef[3] = (1 << 29);
189 for (i = 0; i < 4; i++)
190 info->initial[i] = info->axes[i];
195 * js_an_probe_devs() probes for analog joysticks.
198 static int __init js_an_probe_devs(struct js_an_info *info, int exist, int mask0, int mask1, struct js_port *port)
200 info->mask[0] = info->mask[1] = info->extensions = 0;
202 if (mask0 || mask1) {
203 info->mask[0] = mask0 & (exist | 0xf0);
204 info->mask[1] = mask1 & (exist | 0xf0) & ~info->mask[0];
205 info->extensions = (mask0 >> 8) & ((exist & JS_AN_HAT_FCS) | ((exist << 2) & JS_AN_BUTTONS_PXY_XY) |
206 ((exist << 4) & JS_AN_BUTTONS_PXY_UV) | JS_AN_ANY_CHF);
207 if (info->extensions & JS_AN_BUTTONS_PXY) {
208 info->mask[0] &= ~((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2);
209 info->mask[0] &= ~((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
210 info->mask[1] = 0;
212 if (info->extensions & JS_AN_HAT_FCS) {
213 info->mask[0] &= ~JS_AN_HAT_FCS;
214 info->mask[1] = 0;
215 info->extensions &= ~(JS_AN_BUTTON_PXY_Y | JS_AN_BUTTON_PXY_U);
217 if (info->extensions & JS_AN_ANY_CHF) {
218 info->mask[0] |= 0xf0;
219 info->mask[1] = 0;
221 if (!(info->mask[0] | info->mask[1])) return -1;
222 } else {
223 switch (exist) {
224 case 0x0:
225 return -1;
226 case 0x3:
227 info->mask[0] = 0xf3; /* joystick 0, assuming 4-button */
228 break;
229 case 0xb:
230 info->mask[0] = 0xfb; /* 3-axis, 4-button joystick */
231 break;
232 case 0xc:
233 info->mask[0] = 0xcc; /* joystick 1 */
234 break;
235 case 0xf:
236 info->mask[0] = 0x33; /* joysticks 0 and 1 */
237 info->mask[1] = 0xcc;
238 break;
239 default:
240 printk(KERN_WARNING "joy-analog: Unknown joystick device detected "
241 "(data=%#x), contact <vojtech@ucw.cz>\n", exist);
242 return -1;
246 return !!info->mask[0] + !!info->mask[1];
250 * js_an_axes() returns the number of axes for an analog joystick.
253 static inline int js_an_axes(int i, struct js_an_info *info)
255 return js_an_count_bits(info->mask[i] & 0x0f) + js_an_count_bits(info->extensions & JS_AN_HATS_ALL) * 2;
259 * js_an_buttons() returns the number of buttons for an analog joystick.
262 static inline int js_an_buttons(int i, struct js_an_info *info)
264 return js_an_count_bits(info->mask[i] & 0xf0) +
265 (info->extensions & JS_AN_BUTTONS_CHF) * 2 +
266 js_an_count_bits(info->extensions & JS_AN_BUTTONS_PXY);
270 * js_an_name() constructs a name for an analog joystick.
273 static char js_an_name_buf[128] __initdata = "";
275 static char __init *js_an_name(int i, struct js_an_info *info)
278 sprintf(js_an_name_buf, "Analog %d-axis %d-button",
279 js_an_count_bits(info->mask[i] & 0x0f),
280 js_an_buttons(i, info));
282 if (info->extensions & JS_AN_HATS_ALL)
283 sprintf(js_an_name_buf, "%s %d-hat",
284 js_an_name_buf,
285 js_an_count_bits(info->extensions & JS_AN_HATS_ALL));
287 strcat(js_an_name_buf, " joystick");
289 if (info->extensions)
290 sprintf(js_an_name_buf, "%s with%s%s%s extensions",
291 js_an_name_buf,
292 info->extensions & JS_AN_ANY_CHF ? " CHF" : "",
293 info->extensions & JS_AN_HAT_FCS ? " FCS" : "",
294 info->extensions & JS_AN_BUTTONS_PXY ? " XY-button" : "");
296 return js_an_name_buf;