xref: /OK3568_Linux_fs/kernel/Documentation/input/gameport-programming.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2*4882a593SmuzhiyunProgramming gameport drivers
3*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunA basic classic gameport
6*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunIf the gameport doesn't provide more than the inb()/outb() functionality,
9*4882a593Smuzhiyunthe code needed to register it with the joystick drivers is simple::
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun	struct gameport gameport;
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun	gameport.io = MY_IO_ADDRESS;
14*4882a593Smuzhiyun	gameport_register_port(&gameport);
15*4882a593Smuzhiyun
16*4882a593SmuzhiyunMake sure struct gameport is initialized to 0 in all other fields. The
17*4882a593Smuzhiyungameport generic code will take care of the rest.
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunIf your hardware supports more than one io address, and your driver can
20*4882a593Smuzhiyunchoose which one to program the hardware to, starting from the more exotic
21*4882a593Smuzhiyunaddresses is preferred, because the likelihood of clashing with the standard
22*4882a593Smuzhiyun0x201 address is smaller.
23*4882a593Smuzhiyun
24*4882a593SmuzhiyunEg. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
25*4882a593Smuzhiyun0x218 would be the address of first choice.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunIf your hardware supports a gameport address that is not mapped to ISA io
28*4882a593Smuzhiyunspace (is above 0x1000), use that one, and don't map the ISA mirror.
29*4882a593Smuzhiyun
30*4882a593SmuzhiyunAlso, always request_region() on the whole io space occupied by the
31*4882a593Smuzhiyungameport. Although only one ioport is really used, the gameport usually
32*4882a593Smuzhiyunoccupies from one to sixteen addresses in the io space.
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunPlease also consider enabling the gameport on the card in the ->open()
35*4882a593Smuzhiyuncallback if the io is mapped to ISA space - this way it'll occupy the io
36*4882a593Smuzhiyunspace only when something really is using it. Disable it again in the
37*4882a593Smuzhiyun->close() callback. You also can select the io address in the ->open()
38*4882a593Smuzhiyuncallback, so that it doesn't fail if some of the possible addresses are
39*4882a593Smuzhiyunalready occupied by other gameports.
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunMemory mapped gameport
42*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~
43*4882a593Smuzhiyun
44*4882a593SmuzhiyunWhen a gameport can be accessed through MMIO, this way is preferred, because
45*4882a593Smuzhiyunit is faster, allowing more reads per second. Registering such a gameport
46*4882a593Smuzhiyunisn't as easy as a basic IO one, but not so much complex::
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun	struct gameport gameport;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun	void my_trigger(struct gameport *gameport)
51*4882a593Smuzhiyun	{
52*4882a593Smuzhiyun		my_mmio = 0xff;
53*4882a593Smuzhiyun	}
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun	unsigned char my_read(struct gameport *gameport)
56*4882a593Smuzhiyun	{
57*4882a593Smuzhiyun		return my_mmio;
58*4882a593Smuzhiyun	}
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun	gameport.read = my_read;
61*4882a593Smuzhiyun	gameport.trigger = my_trigger;
62*4882a593Smuzhiyun	gameport_register_port(&gameport);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun.. _gameport_pgm_cooked_mode:
65*4882a593Smuzhiyun
66*4882a593SmuzhiyunCooked mode gameport
67*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~
68*4882a593Smuzhiyun
69*4882a593SmuzhiyunThere are gameports that can report the axis values as numbers, that means
70*4882a593Smuzhiyunthe driver doesn't have to measure them the old way - an ADC is built into
71*4882a593Smuzhiyunthe gameport. To register a cooked gameport::
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun	struct gameport gameport;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun	int my_cooked_read(struct gameport *gameport, int *axes, int *buttons)
76*4882a593Smuzhiyun	{
77*4882a593Smuzhiyun		int i;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun		for (i = 0; i < 4; i++)
80*4882a593Smuzhiyun			axes[i] = my_mmio[i];
81*4882a593Smuzhiyun		buttons[i] = my_mmio[4];
82*4882a593Smuzhiyun	}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun	int my_open(struct gameport *gameport, int mode)
85*4882a593Smuzhiyun	{
86*4882a593Smuzhiyun		return -(mode != GAMEPORT_MODE_COOKED);
87*4882a593Smuzhiyun	}
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun	gameport.cooked_read = my_cooked_read;
90*4882a593Smuzhiyun	gameport.open = my_open;
91*4882a593Smuzhiyun	gameport.fuzz = 8;
92*4882a593Smuzhiyun	gameport_register_port(&gameport);
93*4882a593Smuzhiyun
94*4882a593SmuzhiyunThe only confusing thing here is the fuzz value. Best determined by
95*4882a593Smuzhiyunexperimentation, it is the amount of noise in the ADC data. Perfect
96*4882a593Smuzhiyungameports can set this to zero, most common have fuzz between 8 and 32.
97*4882a593SmuzhiyunSee analog.c and input.c for handling of fuzz - the fuzz value determines
98*4882a593Smuzhiyunthe size of a gaussian filter window that is used to eliminate the noise
99*4882a593Smuzhiyunin the data.
100*4882a593Smuzhiyun
101*4882a593SmuzhiyunMore complex gameports
102*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~
103*4882a593Smuzhiyun
104*4882a593SmuzhiyunGameports can support both raw and cooked modes. In that case combine either
105*4882a593Smuzhiyunexamples 1+2 or 1+3. Gameports can support internal calibration - see below,
106*4882a593Smuzhiyunand also lightning.c and analog.c on how that works. If your driver supports
107*4882a593Smuzhiyunmore than one gameport instance simultaneously, use the ->private member of
108*4882a593Smuzhiyunthe gameport struct to point to your data.
109*4882a593Smuzhiyun
110*4882a593SmuzhiyunUnregistering a gameport
111*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~
112*4882a593Smuzhiyun
113*4882a593SmuzhiyunSimple::
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun    gameport_unregister_port(&gameport);
116*4882a593Smuzhiyun
117*4882a593SmuzhiyunThe gameport structure
118*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun.. note::
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun    This section is outdated. There are several fields here that don't
123*4882a593Smuzhiyun    match what's there at include/linux/gameport.h.
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun::
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun    struct gameport {
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	void *private;
130*4882a593Smuzhiyun
131*4882a593SmuzhiyunA private pointer for free use in the gameport driver. (Not the joystick
132*4882a593Smuzhiyundriver!)
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun::
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun	int number;
137*4882a593Smuzhiyun
138*4882a593SmuzhiyunNumber assigned to the gameport when registered. Informational purpose only.
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun::
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun	int io;
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunI/O address for use with raw mode. You have to either set this, or ->read()
145*4882a593Smuzhiyunto some value if your gameport supports raw mode.
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun::
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun	int speed;
150*4882a593Smuzhiyun
151*4882a593SmuzhiyunRaw mode speed of the gameport reads in thousands of reads per second.
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun::
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun	int fuzz;
156*4882a593Smuzhiyun
157*4882a593SmuzhiyunIf the gameport supports cooked mode, this should be set to a value that
158*4882a593Smuzhiyunrepresents the amount of noise in the data. See
159*4882a593Smuzhiyun:ref:`gameport_pgm_cooked_mode`.
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun::
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun	void (*trigger)(struct gameport *);
164*4882a593Smuzhiyun
165*4882a593SmuzhiyunTrigger. This function should trigger the ns558 oneshots. If set to NULL,
166*4882a593Smuzhiyunoutb(0xff, io) will be used.
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun::
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun	unsigned char (*read)(struct gameport *);
171*4882a593Smuzhiyun
172*4882a593SmuzhiyunRead the buttons and ns558 oneshot bits. If set to NULL, inb(io) will be
173*4882a593Smuzhiyunused instead.
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun::
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun	int (*cooked_read)(struct gameport *, int *axes, int *buttons);
178*4882a593Smuzhiyun
179*4882a593SmuzhiyunIf the gameport supports cooked mode, it should point this to its cooked
180*4882a593Smuzhiyunread function. It should fill axes[0..3] with four values of the joystick axes
181*4882a593Smuzhiyunand buttons[0] with four bits representing the buttons.
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun::
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun	int (*calibrate)(struct gameport *, int *axes, int *max);
186*4882a593Smuzhiyun
187*4882a593SmuzhiyunFunction for calibrating the ADC hardware. When called, axes[0..3] should be
188*4882a593Smuzhiyunpre-filled by cooked data by the caller, max[0..3] should be pre-filled with
189*4882a593Smuzhiyunexpected maximums for each axis. The calibrate() function should set the
190*4882a593Smuzhiyunsensitivity of the ADC hardware so that the maximums fit in its range and
191*4882a593Smuzhiyunrecompute the axes[] values to match the new sensitivity or re-read them from
192*4882a593Smuzhiyunthe hardware so that they give valid values.
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun::
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun	int (*open)(struct gameport *, int mode);
197*4882a593Smuzhiyun
198*4882a593SmuzhiyunOpen() serves two purposes. First a driver either opens the port in raw or
199*4882a593Smuzhiyunin cooked mode, the open() callback can decide which modes are supported.
200*4882a593SmuzhiyunSecond, resource allocation can happen here. The port can also be enabled
201*4882a593Smuzhiyunhere. Prior to this call, other fields of the gameport struct (namely the io
202*4882a593Smuzhiyunmember) need not to be valid.
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun::
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun	void (*close)(struct gameport *);
207*4882a593Smuzhiyun
208*4882a593SmuzhiyunClose() should free the resources allocated by open, possibly disabling the
209*4882a593Smuzhiyungameport.
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun::
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun	struct gameport_dev *dev;
214*4882a593Smuzhiyun	struct gameport *next;
215*4882a593Smuzhiyun
216*4882a593SmuzhiyunFor internal use by the gameport layer.
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun::
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun    };
221*4882a593Smuzhiyun
222*4882a593SmuzhiyunEnjoy!
223