2 * joy-analog.h Version 1.2
4 * Copyright (c) 1996-1998 Vojtech Pavlik
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
53 } js_an_hat_to_axis
[] = {{ 0, 0}, { 0,-1}, { 1, 0}, { 0, 1}, {-1, 0}};
57 unsigned char mask
[2];
58 unsigned int extensions
;
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
)
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;
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)) {
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
)
152 * js_an_init_corr() initializes the correction values for
156 static void __init
js_an_init_corr(struct js_an_info
*info
, int **axes
, struct js_corr
**corr
, int prec
)
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;
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
;
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);
212 if (info
->extensions
& JS_AN_HAT_FCS
) {
213 info
->mask
[0] &= ~JS_AN_HAT_FCS
;
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;
221 if (!(info
->mask
[0] | info
->mask
[1])) return -1;
227 info
->mask
[0] = 0xf3; /* joystick 0, assuming 4-button */
230 info
->mask
[0] = 0xfb; /* 3-axis, 4-button joystick */
233 info
->mask
[0] = 0xcc; /* joystick 1 */
236 info
->mask
[0] = 0x33; /* joysticks 0 and 1 */
237 info
->mask
[1] = 0xcc;
240 printk(KERN_WARNING
"joy-analog: Unknown joystick device detected "
241 "(data=%#x), contact <vojtech@ucw.cz>\n", exist
);
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",
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",
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
;