2 * $Id: gameport.c,v 1.5 2000/05/29 10:54:53 vojtech Exp $
4 * Copyright (c) 1999-2000 Vojtech Pavlik
10 * Generic gameport layer
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@suse.cz>, or by paper mail:
30 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
34 #include <linux/module.h>
35 #include <linux/ioport.h>
36 #include <linux/init.h>
37 #include <linux/gameport.h>
38 #include <linux/malloc.h>
39 #include <linux/isapnp.h>
40 #include <linux/stddef.h>
41 #include <linux/delay.h>
43 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
45 EXPORT_SYMBOL(gameport_register_port
);
46 EXPORT_SYMBOL(gameport_unregister_port
);
47 EXPORT_SYMBOL(gameport_register_device
);
48 EXPORT_SYMBOL(gameport_unregister_device
);
49 EXPORT_SYMBOL(gameport_open
);
50 EXPORT_SYMBOL(gameport_close
);
51 EXPORT_SYMBOL(gameport_rescan
);
52 EXPORT_SYMBOL(gameport_cooked_read
);
54 static struct gameport
*gameport_list
;
55 static struct gameport_dev
*gameport_dev
;
56 static int gameport_number
;
59 * gameport_measure_speed() measures the gameport i/o speed.
62 static int gameport_measure_speed(struct gameport
*gameport
)
66 #define GET_TIME(x) do { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } while (0)
67 #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193180L/HZ:0))
69 unsigned int i
, t
, t1
, t2
, t3
, tx
;
72 if (gameport_open(gameport
, NULL
, GAMEPORT_MODE_RAW
))
77 for(i
= 0; i
< 50; i
++) {
78 save_flags(flags
); /* Yes, all CPUs */
81 for(t
= 0; t
< 50; t
++) gameport_read(gameport
);
86 if ((t
= DELTA(t2
,t1
) - DELTA(t3
,t2
)) < tx
) tx
= t
;
89 return 59659 / (tx
< 1 ? 1 : tx
);
93 unsigned int j
, t
= 0;
95 j
= jiffies
; while (j
== jiffies
);
96 j
= jiffies
; while (j
== jiffies
) { t
++; gameport_read(gameport
); }
102 gameport_close(gameport
);
105 static void gameport_find_dev(struct gameport
*gameport
)
107 struct gameport_dev
*dev
= gameport_dev
;
109 while (dev
&& !gameport
->dev
) {
111 dev
->connect(gameport
, dev
);
116 void gameport_rescan(struct gameport
*gameport
)
118 gameport_close(gameport
);
119 gameport_find_dev(gameport
);
122 void gameport_register_port(struct gameport
*gameport
)
124 gameport
->number
= gameport_number
++;
125 gameport
->next
= gameport_list
;
126 gameport_list
= gameport
;
128 gameport
->speed
= gameport_measure_speed(gameport
);
130 gameport_find_dev(gameport
);
133 void gameport_unregister_port(struct gameport
*gameport
)
135 struct gameport
**gameportptr
= &gameport_list
;
137 while (*gameportptr
&& (*gameportptr
!= gameport
)) gameportptr
= &((*gameportptr
)->next
);
138 *gameportptr
= (*gameportptr
)->next
;
140 if (gameport
->dev
&& gameport
->dev
->disconnect
)
141 gameport
->dev
->disconnect(gameport
);
146 void gameport_register_device(struct gameport_dev
*dev
)
148 struct gameport
*gameport
= gameport_list
;
150 dev
->next
= gameport_dev
;
154 if (!gameport
->dev
&& dev
->connect
)
155 dev
->connect(gameport
, dev
);
156 gameport
= gameport
->next
;
160 void gameport_unregister_device(struct gameport_dev
*dev
)
162 struct gameport_dev
**devptr
= &gameport_dev
;
163 struct gameport
*gameport
= gameport_list
;
165 while (*devptr
&& (*devptr
!= dev
)) devptr
= &((*devptr
)->next
);
166 *devptr
= (*devptr
)->next
;
169 if (gameport
->dev
== dev
&& dev
->disconnect
)
170 dev
->disconnect(gameport
);
171 gameport_find_dev(gameport
);
172 gameport
= gameport
->next
;
176 int gameport_open(struct gameport
*gameport
, struct gameport_dev
*dev
, int mode
)
178 if (gameport
->open
) {
179 if (gameport
->open(gameport
, mode
))
182 if (mode
!= GAMEPORT_MODE_RAW
)
194 void gameport_close(struct gameport
*gameport
)
196 gameport
->dev
= NULL
;
197 if (gameport
->close
) gameport
->close(gameport
);