1e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2e2ba5731SMauro Carvalho ChehabProgramming gameport drivers 3e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4e2ba5731SMauro Carvalho Chehab 5e2ba5731SMauro Carvalho ChehabA basic classic gameport 6e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~ 7e2ba5731SMauro Carvalho Chehab 8e2ba5731SMauro Carvalho ChehabIf the gameport doesn't provide more than the inb()/outb() functionality, 9e2ba5731SMauro Carvalho Chehabthe code needed to register it with the joystick drivers is simple:: 10e2ba5731SMauro Carvalho Chehab 11e2ba5731SMauro Carvalho Chehab struct gameport gameport; 12e2ba5731SMauro Carvalho Chehab 13e2ba5731SMauro Carvalho Chehab gameport.io = MY_IO_ADDRESS; 14e2ba5731SMauro Carvalho Chehab gameport_register_port(&gameport); 15e2ba5731SMauro Carvalho Chehab 16e2ba5731SMauro Carvalho ChehabMake sure struct gameport is initialized to 0 in all other fields. The 17e2ba5731SMauro Carvalho Chehabgameport generic code will take care of the rest. 18e2ba5731SMauro Carvalho Chehab 19e2ba5731SMauro Carvalho ChehabIf your hardware supports more than one io address, and your driver can 20e2ba5731SMauro Carvalho Chehabchoose which one to program the hardware to, starting from the more exotic 21e2ba5731SMauro Carvalho Chehabaddresses is preferred, because the likelihood of clashing with the standard 22e2ba5731SMauro Carvalho Chehab0x201 address is smaller. 23e2ba5731SMauro Carvalho Chehab 24*ebe14885SRandy DunlapE.g. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then 25e2ba5731SMauro Carvalho Chehab0x218 would be the address of first choice. 26e2ba5731SMauro Carvalho Chehab 27e2ba5731SMauro Carvalho ChehabIf your hardware supports a gameport address that is not mapped to ISA io 28e2ba5731SMauro Carvalho Chehabspace (is above 0x1000), use that one, and don't map the ISA mirror. 29e2ba5731SMauro Carvalho Chehab 30e2ba5731SMauro Carvalho ChehabAlso, always request_region() on the whole io space occupied by the 31e2ba5731SMauro Carvalho Chehabgameport. Although only one ioport is really used, the gameport usually 32e2ba5731SMauro Carvalho Chehaboccupies from one to sixteen addresses in the io space. 33e2ba5731SMauro Carvalho Chehab 34e2ba5731SMauro Carvalho ChehabPlease also consider enabling the gameport on the card in the ->open() 35e2ba5731SMauro Carvalho Chehabcallback if the io is mapped to ISA space - this way it'll occupy the io 36e2ba5731SMauro Carvalho Chehabspace only when something really is using it. Disable it again in the 37e2ba5731SMauro Carvalho Chehab->close() callback. You also can select the io address in the ->open() 38e2ba5731SMauro Carvalho Chehabcallback, so that it doesn't fail if some of the possible addresses are 39e2ba5731SMauro Carvalho Chehabalready occupied by other gameports. 40e2ba5731SMauro Carvalho Chehab 41e2ba5731SMauro Carvalho ChehabMemory mapped gameport 42e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~ 43e2ba5731SMauro Carvalho Chehab 44e2ba5731SMauro Carvalho ChehabWhen a gameport can be accessed through MMIO, this way is preferred, because 45e2ba5731SMauro Carvalho Chehabit is faster, allowing more reads per second. Registering such a gameport 46e2ba5731SMauro Carvalho Chehabisn't as easy as a basic IO one, but not so much complex:: 47e2ba5731SMauro Carvalho Chehab 48e2ba5731SMauro Carvalho Chehab struct gameport gameport; 49e2ba5731SMauro Carvalho Chehab 50e2ba5731SMauro Carvalho Chehab void my_trigger(struct gameport *gameport) 51e2ba5731SMauro Carvalho Chehab { 52e2ba5731SMauro Carvalho Chehab my_mmio = 0xff; 53e2ba5731SMauro Carvalho Chehab } 54e2ba5731SMauro Carvalho Chehab 55e2ba5731SMauro Carvalho Chehab unsigned char my_read(struct gameport *gameport) 56e2ba5731SMauro Carvalho Chehab { 57e2ba5731SMauro Carvalho Chehab return my_mmio; 58e2ba5731SMauro Carvalho Chehab } 59e2ba5731SMauro Carvalho Chehab 60e2ba5731SMauro Carvalho Chehab gameport.read = my_read; 61e2ba5731SMauro Carvalho Chehab gameport.trigger = my_trigger; 62e2ba5731SMauro Carvalho Chehab gameport_register_port(&gameport); 63e2ba5731SMauro Carvalho Chehab 64e2ba5731SMauro Carvalho Chehab.. _gameport_pgm_cooked_mode: 65e2ba5731SMauro Carvalho Chehab 66e2ba5731SMauro Carvalho ChehabCooked mode gameport 67e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~ 68e2ba5731SMauro Carvalho Chehab 69e2ba5731SMauro Carvalho ChehabThere are gameports that can report the axis values as numbers, that means 70e2ba5731SMauro Carvalho Chehabthe driver doesn't have to measure them the old way - an ADC is built into 71e2ba5731SMauro Carvalho Chehabthe gameport. To register a cooked gameport:: 72e2ba5731SMauro Carvalho Chehab 73e2ba5731SMauro Carvalho Chehab struct gameport gameport; 74e2ba5731SMauro Carvalho Chehab 75e2ba5731SMauro Carvalho Chehab int my_cooked_read(struct gameport *gameport, int *axes, int *buttons) 76e2ba5731SMauro Carvalho Chehab { 77e2ba5731SMauro Carvalho Chehab int i; 78e2ba5731SMauro Carvalho Chehab 79e2ba5731SMauro Carvalho Chehab for (i = 0; i < 4; i++) 80e2ba5731SMauro Carvalho Chehab axes[i] = my_mmio[i]; 81*ebe14885SRandy Dunlap buttons[0] = my_mmio[4]; 82e2ba5731SMauro Carvalho Chehab } 83e2ba5731SMauro Carvalho Chehab 84e2ba5731SMauro Carvalho Chehab int my_open(struct gameport *gameport, int mode) 85e2ba5731SMauro Carvalho Chehab { 86e2ba5731SMauro Carvalho Chehab return -(mode != GAMEPORT_MODE_COOKED); 87e2ba5731SMauro Carvalho Chehab } 88e2ba5731SMauro Carvalho Chehab 89e2ba5731SMauro Carvalho Chehab gameport.cooked_read = my_cooked_read; 90e2ba5731SMauro Carvalho Chehab gameport.open = my_open; 91e2ba5731SMauro Carvalho Chehab gameport.fuzz = 8; 92e2ba5731SMauro Carvalho Chehab gameport_register_port(&gameport); 93e2ba5731SMauro Carvalho Chehab 94e2ba5731SMauro Carvalho ChehabThe only confusing thing here is the fuzz value. Best determined by 95e2ba5731SMauro Carvalho Chehabexperimentation, it is the amount of noise in the ADC data. Perfect 96e2ba5731SMauro Carvalho Chehabgameports can set this to zero, most common have fuzz between 8 and 32. 97e2ba5731SMauro Carvalho ChehabSee analog.c and input.c for handling of fuzz - the fuzz value determines 98e2ba5731SMauro Carvalho Chehabthe size of a gaussian filter window that is used to eliminate the noise 99e2ba5731SMauro Carvalho Chehabin the data. 100e2ba5731SMauro Carvalho Chehab 101e2ba5731SMauro Carvalho ChehabMore complex gameports 102e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~ 103e2ba5731SMauro Carvalho Chehab 104e2ba5731SMauro Carvalho ChehabGameports can support both raw and cooked modes. In that case combine either 105e2ba5731SMauro Carvalho Chehabexamples 1+2 or 1+3. Gameports can support internal calibration - see below, 106e2ba5731SMauro Carvalho Chehaband also lightning.c and analog.c on how that works. If your driver supports 107e2ba5731SMauro Carvalho Chehabmore than one gameport instance simultaneously, use the ->private member of 108e2ba5731SMauro Carvalho Chehabthe gameport struct to point to your data. 109e2ba5731SMauro Carvalho Chehab 110e2ba5731SMauro Carvalho ChehabUnregistering a gameport 111e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~ 112e2ba5731SMauro Carvalho Chehab 113e2ba5731SMauro Carvalho ChehabSimple:: 114e2ba5731SMauro Carvalho Chehab 115e2ba5731SMauro Carvalho Chehab gameport_unregister_port(&gameport); 116e2ba5731SMauro Carvalho Chehab 117e2ba5731SMauro Carvalho ChehabThe gameport structure 118e2ba5731SMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~ 119e2ba5731SMauro Carvalho Chehab 120e2ba5731SMauro Carvalho Chehab:: 121e2ba5731SMauro Carvalho Chehab 122e2ba5731SMauro Carvalho Chehab struct gameport { 123e2ba5731SMauro Carvalho Chehab 124*ebe14885SRandy Dunlap void *port_data; 125e2ba5731SMauro Carvalho Chehab 126e2ba5731SMauro Carvalho ChehabA private pointer for free use in the gameport driver. (Not the joystick 127e2ba5731SMauro Carvalho Chehabdriver!) 128e2ba5731SMauro Carvalho Chehab 129e2ba5731SMauro Carvalho Chehab:: 130e2ba5731SMauro Carvalho Chehab 131*ebe14885SRandy Dunlap char name[32]; 132e2ba5731SMauro Carvalho Chehab 133*ebe14885SRandy DunlapDriver's name as set by driver calling gameport_set_name(). Informational 134*ebe14885SRandy Dunlappurpose only. 135*ebe14885SRandy Dunlap 136*ebe14885SRandy Dunlap:: 137*ebe14885SRandy Dunlap 138*ebe14885SRandy Dunlap char phys[32]; 139*ebe14885SRandy Dunlap 140*ebe14885SRandy Dunlapgameport's physical name/description as set by driver calling gameport_set_phys(). 141*ebe14885SRandy DunlapInformational purpose only. 142e2ba5731SMauro Carvalho Chehab 143e2ba5731SMauro Carvalho Chehab:: 144e2ba5731SMauro Carvalho Chehab 145e2ba5731SMauro Carvalho Chehab int io; 146e2ba5731SMauro Carvalho Chehab 147e2ba5731SMauro Carvalho ChehabI/O address for use with raw mode. You have to either set this, or ->read() 148e2ba5731SMauro Carvalho Chehabto some value if your gameport supports raw mode. 149e2ba5731SMauro Carvalho Chehab 150e2ba5731SMauro Carvalho Chehab:: 151e2ba5731SMauro Carvalho Chehab 152e2ba5731SMauro Carvalho Chehab int speed; 153e2ba5731SMauro Carvalho Chehab 154e2ba5731SMauro Carvalho ChehabRaw mode speed of the gameport reads in thousands of reads per second. 155e2ba5731SMauro Carvalho Chehab 156e2ba5731SMauro Carvalho Chehab:: 157e2ba5731SMauro Carvalho Chehab 158e2ba5731SMauro Carvalho Chehab int fuzz; 159e2ba5731SMauro Carvalho Chehab 160e2ba5731SMauro Carvalho ChehabIf the gameport supports cooked mode, this should be set to a value that 161e2ba5731SMauro Carvalho Chehabrepresents the amount of noise in the data. See 162e2ba5731SMauro Carvalho Chehab:ref:`gameport_pgm_cooked_mode`. 163e2ba5731SMauro Carvalho Chehab 164e2ba5731SMauro Carvalho Chehab:: 165e2ba5731SMauro Carvalho Chehab 166e2ba5731SMauro Carvalho Chehab void (*trigger)(struct gameport *); 167e2ba5731SMauro Carvalho Chehab 168e2ba5731SMauro Carvalho ChehabTrigger. This function should trigger the ns558 oneshots. If set to NULL, 169e2ba5731SMauro Carvalho Chehaboutb(0xff, io) will be used. 170e2ba5731SMauro Carvalho Chehab 171e2ba5731SMauro Carvalho Chehab:: 172e2ba5731SMauro Carvalho Chehab 173e2ba5731SMauro Carvalho Chehab unsigned char (*read)(struct gameport *); 174e2ba5731SMauro Carvalho Chehab 175e2ba5731SMauro Carvalho ChehabRead the buttons and ns558 oneshot bits. If set to NULL, inb(io) will be 176e2ba5731SMauro Carvalho Chehabused instead. 177e2ba5731SMauro Carvalho Chehab 178e2ba5731SMauro Carvalho Chehab:: 179e2ba5731SMauro Carvalho Chehab 180e2ba5731SMauro Carvalho Chehab int (*cooked_read)(struct gameport *, int *axes, int *buttons); 181e2ba5731SMauro Carvalho Chehab 182e2ba5731SMauro Carvalho ChehabIf the gameport supports cooked mode, it should point this to its cooked 183e2ba5731SMauro Carvalho Chehabread function. It should fill axes[0..3] with four values of the joystick axes 184e2ba5731SMauro Carvalho Chehaband buttons[0] with four bits representing the buttons. 185e2ba5731SMauro Carvalho Chehab 186e2ba5731SMauro Carvalho Chehab:: 187e2ba5731SMauro Carvalho Chehab 188e2ba5731SMauro Carvalho Chehab int (*calibrate)(struct gameport *, int *axes, int *max); 189e2ba5731SMauro Carvalho Chehab 190e2ba5731SMauro Carvalho ChehabFunction for calibrating the ADC hardware. When called, axes[0..3] should be 191e2ba5731SMauro Carvalho Chehabpre-filled by cooked data by the caller, max[0..3] should be pre-filled with 192e2ba5731SMauro Carvalho Chehabexpected maximums for each axis. The calibrate() function should set the 193e2ba5731SMauro Carvalho Chehabsensitivity of the ADC hardware so that the maximums fit in its range and 194e2ba5731SMauro Carvalho Chehabrecompute the axes[] values to match the new sensitivity or re-read them from 195e2ba5731SMauro Carvalho Chehabthe hardware so that they give valid values. 196e2ba5731SMauro Carvalho Chehab 197e2ba5731SMauro Carvalho Chehab:: 198e2ba5731SMauro Carvalho Chehab 199e2ba5731SMauro Carvalho Chehab int (*open)(struct gameport *, int mode); 200e2ba5731SMauro Carvalho Chehab 201e2ba5731SMauro Carvalho ChehabOpen() serves two purposes. First a driver either opens the port in raw or 202e2ba5731SMauro Carvalho Chehabin cooked mode, the open() callback can decide which modes are supported. 203e2ba5731SMauro Carvalho ChehabSecond, resource allocation can happen here. The port can also be enabled 204e2ba5731SMauro Carvalho Chehabhere. Prior to this call, other fields of the gameport struct (namely the io 205e2ba5731SMauro Carvalho Chehabmember) need not to be valid. 206e2ba5731SMauro Carvalho Chehab 207e2ba5731SMauro Carvalho Chehab:: 208e2ba5731SMauro Carvalho Chehab 209e2ba5731SMauro Carvalho Chehab void (*close)(struct gameport *); 210e2ba5731SMauro Carvalho Chehab 211e2ba5731SMauro Carvalho ChehabClose() should free the resources allocated by open, possibly disabling the 212e2ba5731SMauro Carvalho Chehabgameport. 213e2ba5731SMauro Carvalho Chehab 214e2ba5731SMauro Carvalho Chehab:: 215e2ba5731SMauro Carvalho Chehab 216*ebe14885SRandy Dunlap struct timer_list poll_timer; 217*ebe14885SRandy Dunlap unsigned int poll_interval; /* in msecs */ 218*ebe14885SRandy Dunlap spinlock_t timer_lock; 219*ebe14885SRandy Dunlap unsigned int poll_cnt; 220*ebe14885SRandy Dunlap void (*poll_handler)(struct gameport *); 221*ebe14885SRandy Dunlap struct gameport *parent, *child; 222*ebe14885SRandy Dunlap struct gameport_driver *drv; 223*ebe14885SRandy Dunlap struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ 224*ebe14885SRandy Dunlap struct device dev; 225*ebe14885SRandy Dunlap struct list_head node; 226e2ba5731SMauro Carvalho Chehab 227e2ba5731SMauro Carvalho ChehabFor internal use by the gameport layer. 228e2ba5731SMauro Carvalho Chehab 229e2ba5731SMauro Carvalho Chehab:: 230e2ba5731SMauro Carvalho Chehab 231e2ba5731SMauro Carvalho Chehab }; 232e2ba5731SMauro Carvalho Chehab 233e2ba5731SMauro Carvalho ChehabEnjoy! 234