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