1/*
2 * $Id: analog.c,v 1.1.1.1 2008/10/15 03:26:32 james26_jang Exp $
3 *
4 *  Copyright (c) 1996-2000 Vojtech Pavlik
5 *
6 *  Sponsored by SuSE
7 */
8
9/*
10 * Analog joystick and gamepad driver for Linux
11 */
12
13/*
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.
18 *
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.
23 *
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
27 *
28 * Should you need to contact me, the author, you can do so either by
29 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
30 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
31 */
32
33#include <linux/config.h>
34#include <linux/delay.h>
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/slab.h>
38#include <linux/bitops.h>
39#include <linux/init.h>
40#include <linux/input.h>
41#include <linux/gameport.h>
42#include <asm/timex.h>
43
44MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
45MODULE_DESCRIPTION("Analog joystick and gamepad driver for Linux");
46MODULE_LICENSE("GPL");
47
48/*
49 * Option parsing.
50 */
51
52#define ANALOG_PORTS		16
53
54static char *js[ANALOG_PORTS];
55static int analog_options[ANALOG_PORTS];
56MODULE_PARM(js, "1-" __MODULE_STRING(ANALOG_PORTS) "s");
57MODULE_PARM_DESC(js, "Analog joystick options");
58
59/*
60 * Times, feature definitions.
61 */
62
63#define ANALOG_RUDDER		0x00004
64#define ANALOG_THROTTLE		0x00008
65#define ANALOG_AXES_STD		0x0000f
66#define ANALOG_BTNS_STD		0x000f0
67
68#define ANALOG_BTNS_CHF		0x00100
69#define ANALOG_HAT1_CHF		0x00200
70#define ANALOG_HAT2_CHF		0x00400
71#define ANALOG_HAT_FCS		0x00800
72#define ANALOG_HATS_ALL		0x00e00
73#define ANALOG_BTN_TL		0x01000
74#define ANALOG_BTN_TR		0x02000
75#define ANALOG_BTN_TL2		0x04000
76#define ANALOG_BTN_TR2		0x08000
77#define ANALOG_BTNS_TLR		0x03000
78#define ANALOG_BTNS_TLR2	0x0c000
79#define ANALOG_BTNS_GAMEPAD	0x0f000
80
81#define ANALOG_HBTN_CHF		0x10000
82#define ANALOG_ANY_CHF		0x10700
83#define ANALOG_SAITEK		0x20000
84#define ANALOG_EXTENSIONS	0x7ff00
85#define ANALOG_GAMEPAD		0x80000
86
87#define ANALOG_MAX_TIME		3	/* 3 ms */
88#define ANALOG_LOOP_TIME	2000	/* 2 * loop */
89#define ANALOG_REFRESH_TIME	HZ/100	/* 10 ms */
90#define ANALOG_SAITEK_DELAY	200	/* 200 us */
91#define ANALOG_SAITEK_TIME	2000	/* 2000 us */
92#define ANALOG_AXIS_TIME	2	/* 2 * refresh */
93#define ANALOG_INIT_RETRIES	8	/* 8 times */
94#define ANALOG_FUZZ_BITS	2	/* 2 bit more */
95#define ANALOG_FUZZ_MAGIC	36	/* 36 u*ms/loop */
96
97#define ANALOG_MAX_NAME_LENGTH  128
98
99static short analog_axes[] = { ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE };
100static short analog_hats[] = { ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y };
101static short analog_pads[] = { BTN_Y, BTN_Z, BTN_TL, BTN_TR };
102static short analog_exts[] = { ANALOG_HAT1_CHF, ANALOG_HAT2_CHF, ANALOG_HAT_FCS };
103static short analog_pad_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_TL2, BTN_TR2, BTN_SELECT, BTN_START, BTN_MODE, BTN_BASE };
104static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2,
105				  BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_BASE6 };
106
107static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
108
109struct analog {
110	struct input_dev dev;
111	int mask;
112	short *buttons;
113	char name[ANALOG_MAX_NAME_LENGTH];
114};
115
116struct analog_port {
117	struct gameport *gameport;
118	struct timer_list timer;
119	struct analog analog[2];
120	unsigned char mask;
121	char saitek;
122	char cooked;
123	int bads;
124	int reads;
125	int speed;
126	int loop;
127	int fuzz;
128	int axes[4];
129	int buttons;
130	int initial[4];
131	int used;
132	int axtime;
133};
134
135/*
136 * Time macros.
137 */
138
139#ifdef __i386__
140#define GET_TIME(x)	do { if (cpu_has_tsc) rdtscl(x); else { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } } while (0)
141#define DELTA(x,y)	(cpu_has_tsc?((y)-(x)):((x)-(y)+((x)<(y)?1193180L/HZ:0)))
142#define TIME_NAME	(cpu_has_tsc?"TSC":"PIT")
143#elif __x86_64__
144#define GET_TIME(x)	rdtscl(x)
145#define DELTA(x,y)	((y)-(x))
146#define TIME_NAME	"TSC"
147#elif __alpha__
148#define GET_TIME(x)	((x) = get_cycles())
149#define DELTA(x,y)	((y)-(x))
150#define TIME_NAME	"PCC"
151#else
152#define FAKE_TIME
153static unsigned long analog_faketime = 0;
154#define GET_TIME(x)     do { x = analog_faketime++; } while(0)
155#define DELTA(x,y)	((y)-(x))
156#define TIME_NAME	"Unreliable"
157#warning Precise timer not defined for this architecture.
158#endif
159
160/*
161 * analog_decode() decodes analog joystick data and reports input events.
162 */
163
164static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
165{
166	struct input_dev *dev = &analog->dev;
167	int i, j;
168
169	if (analog->mask & ANALOG_HAT_FCS)
170		for (i = 0; i < 4; i++)
171			if (axes[3] < ((initial[3] * ((i << 1) + 1)) >> 3)) {
172				buttons |= 1 << (i + 14);
173				break;
174			}
175
176	for (i = j = 0; i < 6; i++)
177		if (analog->mask & (0x10 << i))
178			input_report_key(dev, analog->buttons[j++], (buttons >> i) & 1);
179
180	if (analog->mask & ANALOG_HBTN_CHF)
181		for (i = 0; i < 4; i++)
182			input_report_key(dev, analog->buttons[j++], (buttons >> (i + 10)) & 1);
183
184	if (analog->mask & ANALOG_BTN_TL)
185		input_report_key(dev, analog_pads[0], axes[2] < (initial[2] >> 1));
186	if (analog->mask & ANALOG_BTN_TR)
187		input_report_key(dev, analog_pads[1], axes[3] < (initial[3] >> 1));
188	if (analog->mask & ANALOG_BTN_TL2)
189		input_report_key(dev, analog_pads[2], axes[2] > (initial[2] + (initial[2] >> 1)));
190	if (analog->mask & ANALOG_BTN_TR2)
191		input_report_key(dev, analog_pads[3], axes[3] > (initial[3] + (initial[3] >> 1)));
192
193	for (i = j = 0; i < 4; i++)
194		if (analog->mask & (1 << i))
195			input_report_abs(dev, analog_axes[j++], axes[i]);
196
197	for (i = j = 0; i < 3; i++)
198		if (analog->mask & analog_exts[i]) {
199			input_report_abs(dev, analog_hats[j++],
200				((buttons >> ((i << 2) + 7)) & 1) - ((buttons >> ((i << 2) + 9)) & 1));
201			input_report_abs(dev, analog_hats[j++],
202				((buttons >> ((i << 2) + 8)) & 1) - ((buttons >> ((i << 2) + 6)) & 1));
203		}
204}
205
206/*
207 * analog_cooked_read() reads analog joystick data.
208 */
209
210static int analog_cooked_read(struct analog_port *port)
211{
212	struct gameport *gameport = port->gameport;
213	unsigned int time[4], start, loop, now, loopout, timeout;
214	unsigned char data[4], this, last;
215	unsigned long flags;
216	int i, j;
217
218	loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
219	timeout = ANALOG_MAX_TIME * port->speed;
220
221	__save_flags(flags);
222	__cli();
223	gameport_trigger(gameport);
224	GET_TIME(now);
225	__restore_flags(flags);
226
227	start = now;
228	this = port->mask;
229	i = 0;
230
231	do {
232		loop = now;
233		last = this;
234
235		__cli();
236		this = gameport_read(gameport) & port->mask;
237		GET_TIME(now);
238		__restore_flags(flags);
239
240		if ((last ^ this) && (DELTA(loop, now) < loopout)) {
241			data[i] = last ^ this;
242			time[i] = now;
243			i++;
244		}
245
246	} while (this && (i < 4) && (DELTA(start, now) < timeout));
247
248	this <<= 4;
249
250	for (--i; i >= 0; i--) {
251		this |= data[i];
252		for (j = 0; j < 4; j++)
253			if (data[i] & (1 << j))
254				port->axes[j] = (DELTA(start, time[i]) << ANALOG_FUZZ_BITS) / port->loop;
255	}
256
257	return -(this != port->mask);
258}
259
260static int analog_button_read(struct analog_port *port, char saitek, char chf)
261{
262	unsigned char u;
263	int t = 1, i = 0;
264	int strobe = gameport_time(port->gameport, ANALOG_SAITEK_TIME);
265
266	u = gameport_read(port->gameport);
267
268	if (!chf) {
269		port->buttons = (~u >> 4) & 0xf;
270		return 0;
271	}
272
273	port->buttons = 0;
274
275	while ((~u & 0xf0) && (i < 16) && t) {
276		port->buttons |= 1 << analog_chf[(~u >> 4) & 0xf];
277		if (!saitek) return 0;
278		udelay(ANALOG_SAITEK_DELAY);
279		t = strobe;
280		gameport_trigger(port->gameport);
281		while (((u = gameport_read(port->gameport)) & port->mask) && t) t--;
282		i++;
283	}
284
285	return -(!t || (i == 16));
286}
287
288/*
289 * analog_timer() repeatedly polls the Analog joysticks.
290 */
291
292static void analog_timer(unsigned long data)
293{
294	struct analog_port *port = (void *) data;
295	int i;
296
297	char saitek = !!(port->analog[0].mask & ANALOG_SAITEK);
298	char chf = !!(port->analog[0].mask & ANALOG_ANY_CHF);
299
300	if (port->cooked) {
301		port->bads -= gameport_cooked_read(port->gameport, port->axes, &port->buttons);
302		if (chf)
303			port->buttons = port->buttons ? (1 << analog_chf[port->buttons]) : 0;
304		port->reads++;
305	} else {
306		if (!port->axtime--) {
307			port->bads -= analog_cooked_read(port);
308			port->bads -= analog_button_read(port, saitek, chf);
309			port->reads++;
310			port->axtime = ANALOG_AXIS_TIME - 1;
311		} else {
312			if (!saitek)
313				analog_button_read(port, saitek, chf);
314		}
315	}
316
317	for (i = 0; i < 2; i++)
318		if (port->analog[i].mask)
319			analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
320
321	mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
322}
323
324/*
325 * analog_open() is a callback from the input open routine.
326 */
327
328static int analog_open(struct input_dev *dev)
329{
330	struct analog_port *port = dev->private;
331	if (!port->used++)
332		mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
333	return 0;
334}
335
336/*
337 * analog_close() is a callback from the input close routine.
338 */
339
340static void analog_close(struct input_dev *dev)
341{
342	struct analog_port *port = dev->private;
343	if (!--port->used)
344		del_timer(&port->timer);
345}
346
347/*
348 * analog_calibrate_timer() calibrates the timer and computes loop
349 * and timeout values for a joystick port.
350 */
351
352static void analog_calibrate_timer(struct analog_port *port)
353{
354	struct gameport *gameport = port->gameport;
355	unsigned int i, t, tx, t1, t2, t3;
356	unsigned long flags;
357
358	save_flags(flags);
359	cli();
360	GET_TIME(t1);
361#ifdef FAKE_TIME
362	analog_faketime += 830;
363#endif
364	udelay(1000);
365	GET_TIME(t2);
366	GET_TIME(t3);
367	restore_flags(flags);
368
369	port->speed = DELTA(t1, t2) - DELTA(t2, t3);
370
371	tx = ~0;
372
373	for (i = 0; i < 50; i++) {
374		save_flags(flags);
375		cli();
376		GET_TIME(t1);
377		for (t = 0; t < 50; t++) { gameport_read(gameport); GET_TIME(t2); }
378		GET_TIME(t3);
379		restore_flags(flags);
380		udelay(i);
381		t = DELTA(t1, t2) - DELTA(t2, t3);
382		if (t < tx) tx = t;
383	}
384
385        port->loop = tx / 50;
386}
387
388/*
389 * analog_name() constructs a name for an analog joystick.
390 */
391
392static void analog_name(struct analog *analog)
393{
394	sprintf(analog->name, "Analog %d-axis %d-button",
395		hweight8(analog->mask & ANALOG_AXES_STD),
396		hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
397		hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
398
399	if (analog->mask & ANALOG_HATS_ALL)
400		sprintf(analog->name, "%s %d-hat",
401			analog->name, hweight16(analog->mask & ANALOG_HATS_ALL));
402
403	if (analog->mask & ANALOG_HAT_FCS)
404			strcat(analog->name, " FCS");
405	if (analog->mask & ANALOG_ANY_CHF)
406			strcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF");
407
408	strcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick");
409}
410
411/*
412 * analog_init_device()
413 */
414
415static void analog_init_device(struct analog_port *port, struct analog *analog, int index)
416{
417	int i, j, t, v, w, x, y, z;
418
419	analog_name(analog);
420
421	analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
422
423	analog->dev.name = analog->name;
424	analog->dev.idbus = BUS_GAMEPORT;
425	analog->dev.idvendor = GAMEPORT_ID_VENDOR_ANALOG;
426	analog->dev.idproduct = analog->mask >> 4;
427	analog->dev.idversion = 0x0100;
428
429	analog->dev.open = analog_open;
430	analog->dev.close = analog_close;
431	analog->dev.private = port;
432	analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
433
434	for (i = j = 0; i < 4; i++)
435		if (analog->mask & (1 << i)) {
436
437			t = analog_axes[j];
438			x = port->axes[i];
439			y = (port->axes[0] + port->axes[1]) >> 1;
440			z = y - port->axes[i];
441			z = z > 0 ? z : -z;
442			v = (x >> 3);
443			w = (x >> 3);
444
445			set_bit(t, analog->dev.absbit);
446
447			if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
448				x = y;
449
450			if (analog->mask & ANALOG_SAITEK) {
451				if (i == 2) x = port->axes[i];
452				v = x - (x >> 2);
453				w = (x >> 4);
454			}
455
456			analog->dev.absmax[t] = (x << 1) - v;
457			analog->dev.absmin[t] = v;
458			analog->dev.absfuzz[t] = port->fuzz;
459			analog->dev.absflat[t] = w;
460
461			j++;
462		}
463
464	for (i = j = 0; i < 3; i++)
465		if (analog->mask & analog_exts[i])
466			for (x = 0; x < 2; x++) {
467				t = analog_hats[j++];
468				set_bit(t, analog->dev.absbit);
469				analog->dev.absmax[t] = 1;
470				analog->dev.absmin[t] = -1;
471			}
472
473	for (i = j = 0; i < 4; i++)
474		if (analog->mask & (0x10 << i))
475			set_bit(analog->buttons[j++], analog->dev.keybit);
476
477	if (analog->mask & ANALOG_BTNS_CHF)
478		for (i = 0; i < 2; i++)
479			set_bit(analog->buttons[j++], analog->dev.keybit);
480
481	if (analog->mask & ANALOG_HBTN_CHF)
482		for (i = 0; i < 4; i++)
483			set_bit(analog->buttons[j++], analog->dev.keybit);
484
485	for (i = 0; i < 4; i++)
486		if (analog->mask & (ANALOG_BTN_TL << i))
487			set_bit(analog_pads[i], analog->dev.keybit);
488
489	analog_decode(analog, port->axes, port->initial, port->buttons);
490
491	input_register_device(&analog->dev);
492
493	printk(KERN_INFO "input%d: %s at gameport%d.%d",
494		analog->dev.number, analog->name, port->gameport->number, index);
495
496	if (port->cooked)
497		printk(" [ADC port]\n");
498	else
499		printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
500		port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
501		port->speed > 10000 ? "M" : "k",
502		port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
503				    : (port->loop * 1000000) / port->speed);
504}
505
506/*
507 * analog_init_devices() sets up device-specific values and registers the input devices.
508 */
509
510static int analog_init_masks(struct analog_port *port)
511{
512	int i;
513	struct analog *analog = port->analog;
514	int max[4];
515
516	if (!port->mask)
517		return -1;
518
519	if ((port->mask & 3) != 3 && port->mask != 0xc) {
520		printk(KERN_WARNING "analog.c: Unknown joystick device found  "
521			"(data=%#x, gameport%d), probably not analog joystick.\n",
522			port->mask, port->gameport->number);
523		return -1;
524	}
525
526	i = port->gameport->number < ANALOG_PORTS ? analog_options[port->gameport->number] : 0xff;
527
528	analog[0].mask = i & 0xfffff;
529
530	analog[0].mask &= ~(ANALOG_AXES_STD | ANALOG_HAT_FCS | ANALOG_BTNS_GAMEPAD)
531			| port->mask | ((port->mask << 8) & ANALOG_HAT_FCS)
532			| ((port->mask << 10) & ANALOG_BTNS_TLR) | ((port->mask << 12) & ANALOG_BTNS_TLR2);
533
534	analog[0].mask &= ~(ANALOG_HAT2_CHF)
535			| ((analog[0].mask & ANALOG_HBTN_CHF) ? 0 : ANALOG_HAT2_CHF);
536
537	analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_BTN_TR | ANALOG_BTN_TR2)
538			| ((~analog[0].mask & ANALOG_HAT_FCS) >> 8)
539			| ((~analog[0].mask & ANALOG_HAT_FCS) << 2)
540			| ((~analog[0].mask & ANALOG_HAT_FCS) << 4);
541
542	analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_RUDDER)
543			| (((~analog[0].mask & ANALOG_BTNS_TLR ) >> 10)
544			&  ((~analog[0].mask & ANALOG_BTNS_TLR2) >> 12));
545
546	analog[1].mask = ((i >> 20) & 0xff) | ((i >> 12) & 0xf0000);
547
548	analog[1].mask &= (analog[0].mask & ANALOG_EXTENSIONS) ? ANALOG_GAMEPAD
549			: (((ANALOG_BTNS_STD | port->mask) & ~analog[0].mask) | ANALOG_GAMEPAD);
550
551	if (port->cooked) {
552
553		for (i = 0; i < 4; i++) max[i] = port->axes[i] << 1;
554
555		if ((analog[0].mask & 0x7) == 0x7) max[2] = (max[0] + max[1]) >> 1;
556		if ((analog[0].mask & 0xb) == 0xb) max[3] = (max[0] + max[1]) >> 1;
557		if ((analog[0].mask & ANALOG_BTN_TL) && !(analog[0].mask & ANALOG_BTN_TL2)) max[2] >>= 1;
558		if ((analog[0].mask & ANALOG_BTN_TR) && !(analog[0].mask & ANALOG_BTN_TR2)) max[3] >>= 1;
559		if ((analog[0].mask & ANALOG_HAT_FCS)) max[3] >>= 1;
560
561		gameport_calibrate(port->gameport, port->axes, max);
562	}
563
564	for (i = 0; i < 4; i++)
565		port->initial[i] = port->axes[i];
566
567	return -!(analog[0].mask || analog[1].mask);
568}
569
570static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port)
571{
572	int i, t, u, v;
573
574	gameport->private = port;
575	port->gameport = gameport;
576	init_timer(&port->timer);
577	port->timer.data = (long) port;
578	port->timer.function = analog_timer;
579
580	if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) {
581
582		analog_calibrate_timer(port);
583
584		gameport_trigger(gameport);
585		t = gameport_read(gameport);
586		wait_ms(ANALOG_MAX_TIME);
587		port->mask = (gameport_read(gameport) ^ t) & t & 0xf;
588		port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS;
589
590		for (i = 0; i < ANALOG_INIT_RETRIES; i++) {
591			if (!analog_cooked_read(port)) break;
592			wait_ms(ANALOG_MAX_TIME);
593		}
594
595		u = v = 0;
596
597		wait_ms(ANALOG_MAX_TIME);
598		t = gameport_time(gameport, ANALOG_MAX_TIME * 1000);
599		gameport_trigger(gameport);
600		while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++;
601		udelay(ANALOG_SAITEK_DELAY);
602		t = gameport_time(gameport, ANALOG_SAITEK_TIME);
603		gameport_trigger(gameport);
604		while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++;
605
606		if (v < (u >> 1) && port->gameport->number < ANALOG_PORTS) {
607			analog_options[port->gameport->number] |=
608				ANALOG_SAITEK | ANALOG_BTNS_CHF | ANALOG_HBTN_CHF | ANALOG_HAT1_CHF;
609			return 0;
610		}
611
612		gameport_close(gameport);
613	}
614
615	if (!gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) {
616
617		for (i = 0; i < ANALOG_INIT_RETRIES; i++)
618			if (!gameport_cooked_read(gameport, port->axes, &port->buttons))
619				break;
620		for (i = 0; i < 4; i++)
621			if (port->axes[i] != -1) port->mask |= 1 << i;
622
623		port->fuzz = gameport->fuzz;
624		port->cooked = 1;
625		return 0;
626	}
627
628	if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW))
629		return 0;
630
631	return -1;
632}
633
634static void analog_connect(struct gameport *gameport, struct gameport_dev *dev)
635{
636	struct analog_port *port;
637	int i;
638
639	if (!(port = kmalloc(sizeof(struct analog_port), GFP_KERNEL)))
640		return;
641	memset(port, 0, sizeof(struct analog_port));
642
643	if (analog_init_port(gameport, dev, port)) {
644		kfree(port);
645		return;
646	}
647
648	if (analog_init_masks(port)) {
649		gameport_close(gameport);
650		kfree(port);
651		return;
652	}
653
654	for (i = 0; i < 2; i++)
655		if (port->analog[i].mask)
656			analog_init_device(port, port->analog + i, i);
657}
658
659static void analog_disconnect(struct gameport *gameport)
660{
661	int i;
662
663	struct analog_port *port = gameport->private;
664	for (i = 0; i < 2; i++)
665		if (port->analog[i].mask)
666			input_unregister_device(&port->analog[i].dev);
667	gameport_close(gameport);
668	printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on gameport%d failed\n",
669		port->bads, port->reads, port->reads ? (port->bads * 100 / port->reads) : 0,
670		port->gameport->number);
671	kfree(port);
672}
673
674struct analog_types {
675	char *name;
676	int value;
677};
678
679struct analog_types analog_types[] = {
680	{ "none",	0x00000000 },
681	{ "auto",	0x000000ff },
682	{ "2btn",	0x0000003f },
683	{ "y-joy",	0x0cc00033 },
684	{ "y-pad",	0x8cc80033 },
685	{ "fcs",	0x000008f7 },
686	{ "chf",	0x000002ff },
687	{ "fullchf",	0x000007ff },
688	{ "gamepad",	0x000830f3 },
689	{ "gamepad8",	0x0008f0f3 },
690	{ NULL, 0 }
691};
692
693static void analog_parse_options(void)
694{
695	int i, j;
696	char *end;
697
698	for (i = 0; i < ANALOG_PORTS && js[i]; i++) {
699
700		for (j = 0; analog_types[j].name; j++)
701			if (!strcmp(analog_types[j].name, js[i])) {
702				analog_options[i] = analog_types[j].value;
703				break;
704			}
705		if (analog_types[j].name) continue;
706
707		analog_options[i] = simple_strtoul(js[i], &end, 0);
708		if (end != js[i]) continue;
709
710		analog_options[i] = 0xff;
711		if (!strlen(js[i])) continue;
712
713		printk(KERN_WARNING "analog.c: Bad config for port %d - \"%s\"\n", i, js[i]);
714	}
715
716	for (; i < ANALOG_PORTS; i++)
717		analog_options[i] = 0xff;
718}
719
720/*
721 * The gameport device structure.
722 */
723
724static struct gameport_dev analog_dev = {
725	connect:	analog_connect,
726	disconnect:	analog_disconnect,
727};
728
729#ifndef MODULE
730static int __init analog_setup(char *str)
731{
732	char *s = str;
733	int i = 0;
734
735	if (!str || !*str) return 0;
736
737	while ((str = s) && (i < ANALOG_PORTS)) {
738		if ((s = strchr(str,','))) *s++ = 0;
739		js[i++] = str;
740	}
741
742	return 1;
743}
744__setup("js=", analog_setup);
745#endif
746
747int __init analog_init(void)
748{
749	analog_parse_options();
750	gameport_register_device(&analog_dev);
751	return 0;
752}
753
754void __exit analog_exit(void)
755{
756	gameport_unregister_device(&analog_dev);
757}
758
759module_init(analog_init);
760module_exit(analog_exit);
761