pcigame.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: pcigame.c,v 1.10 2001/04/26 10:24:46 vojtech Exp $
  3.  *
  4.  *  Copyright (c) 2000-2001 Vojtech Pavlik
  5.  *
  6.  *  Based on the work of:
  7.  * Raymond Ingles
  8.  *
  9.  *  Sponsored by SuSE
  10.  */
  11. /*
  12.  * Trident 4DWave and Aureal Vortex gameport driver for Linux
  13.  */
  14. /*
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2 of the License, or
  18.  * (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; if not, write to the Free Software
  27.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  28.  *
  29.  * Should you need to contact me, the author, you can do so either by
  30.  * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  31.  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  32.  */
  33. #include <asm/io.h>
  34. #include <linux/delay.h>
  35. #include <linux/errno.h>
  36. #include <linux/ioport.h>
  37. #include <linux/kernel.h>
  38. #include <linux/module.h>
  39. #include <linux/pci.h>
  40. #include <linux/init.h>
  41. #include <linux/slab.h>
  42. #include <linux/gameport.h>
  43. #include <linux/pci_gameport.h>
  44. #define PCI_VENDOR_ID_AUREAL 0x12eb
  45. #define PCIGAME_DATA_WAIT 20 /* 20 ms */
  46. static struct pcigame_data pcigame_data[] __devinitdata = {
  47. { 0x00030, 0x00031, 0x00034, 2, 0xffff, 0x80 },
  48. { 0x1100c, 0x11008, 0x11010, 4, 0x1fff, 0x40 },
  49. { 0x2880c, 0x28808, 0x28810, 4, 0x1fff, 0x40 },
  50. { 0 }
  51. };
  52. static unsigned char pcigame_read(struct gameport *gameport)
  53. {
  54. struct pcigame *pcigame = gameport->driver;
  55. return readb(pcigame->base + pcigame->data->legacy);
  56. }
  57. static void pcigame_trigger(struct gameport *gameport)
  58. {
  59. struct pcigame *pcigame = gameport->driver;
  60. writeb(0xff, pcigame->base + pcigame->data->legacy);
  61. }
  62. static int pcigame_cooked_read(struct gameport *gameport, int *axes, int *buttons)
  63. {
  64.         struct pcigame *pcigame = gameport->driver;
  65. int i;
  66. *buttons = (~readb(pcigame->base + pcigame->data->legacy) >> 4) & 0xf;
  67. for (i = 0; i < 4; i++) {
  68. axes[i] = readw(pcigame->base + pcigame->data->axes + i * pcigame->data->axsize);
  69. if (axes[i] == pcigame->data->axmax) axes[i] = -1;
  70. }
  71.         
  72.         return 0;
  73. }
  74. static int pcigame_open(struct gameport *gameport, int mode)
  75. {
  76. struct pcigame *pcigame = gameport->driver;
  77. switch (mode) {
  78. case GAMEPORT_MODE_COOKED:
  79. writeb(pcigame->data->adcmode, pcigame->base + pcigame->data->gcr);
  80. wait_ms(PCIGAME_DATA_WAIT);
  81. return 0;
  82. case GAMEPORT_MODE_RAW:
  83. writeb(0, pcigame->base + pcigame->data->gcr);
  84. return 0;
  85. default:
  86. return -1;
  87. }
  88. return 0;
  89. }
  90. struct pcigame *pcigame_attach(struct pci_dev *dev, int type)
  91. {
  92. struct pcigame *pcigame;
  93. int i;
  94. if (!(pcigame = kmalloc(sizeof(struct pcigame), GFP_KERNEL)))
  95. return NULL;
  96.         memset(pcigame, 0, sizeof(struct pcigame));
  97. pcigame->data = pcigame_data + type;
  98. pcigame->dev = dev;
  99. pcigame->gameport.driver = pcigame;
  100. pcigame->gameport.fuzz = 64;
  101. pcigame->gameport.read = pcigame_read;
  102. pcigame->gameport.trigger = pcigame_trigger;
  103. pcigame->gameport.cooked_read = pcigame_cooked_read;
  104. pcigame->gameport.open = pcigame_open;
  105. for (i = 0; i < 6; i++)
  106. if (~pci_resource_flags(dev, i) & IORESOURCE_IO)
  107. break;
  108. if(i==6)
  109. return NULL;
  110. pci_enable_device(dev);
  111. pcigame->base = ioremap(pci_resource_start(pcigame->dev, i),
  112. pci_resource_len(pcigame->dev, i));
  113. gameport_register_port(&pcigame->gameport);
  114. printk(KERN_INFO "gameport%d: %s at pci%02x:%02x.%x speed %d kHzn",
  115. pcigame->gameport.number, dev->name, dev->bus->number,
  116. PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), pcigame->gameport.speed);
  117. return pcigame;
  118. }
  119. EXPORT_SYMBOL_GPL(pcigame_attach);
  120. void pcigame_detach(struct pcigame *game)
  121. {
  122. gameport_unregister_port(&game->gameport);
  123. iounmap(game->base);
  124. kfree(game);
  125. }
  126. EXPORT_SYMBOL_GPL(pcigame_detach);
  127. static __devinit int pcigame_probe(struct pci_dev *dev, const struct pci_device_id *id)
  128. {
  129. struct pcigame *r = pcigame_attach(dev, id->driver_data);
  130. if(r == NULL)
  131. return -1;
  132. pci_set_drvdata(dev, r);
  133. return 0;
  134. }
  135. static void __devexit pcigame_remove(struct pci_dev *dev)
  136. {
  137. struct pcigame *pcigame = pci_get_drvdata(dev);
  138. pcigame_detach(pcigame);
  139. }
  140. static struct pci_device_id pcigame_id_table[] __devinitdata =
  141. {
  142. /* If the trident is configured in audio grabs it and we get called by
  143.    that */
  144. #if !defined(CONFIG_SOUND_TRIDENT) && !defined(CONFIG_SOUND_TRIDENT_MODULE)
  145.  { PCI_VENDOR_ID_TRIDENT, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
  146.  { PCI_VENDOR_ID_TRIDENT, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
  147.  { PCI_VENDOR_ID_AL,      0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
  148. #endif 
  149.  { PCI_VENDOR_ID_AUREAL,  0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_VORTEX  },
  150.  { PCI_VENDOR_ID_AUREAL,  0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_VORTEX2 },
  151.  { 0 }};
  152. static struct pci_driver pcigame_driver = {
  153. name: "pcigame",
  154. id_table: pcigame_id_table,
  155. probe: pcigame_probe,
  156. remove: __devexit_p(pcigame_remove),
  157. };
  158. int __init pcigame_init(void)
  159. {
  160. pci_module_init(&pcigame_driver);
  161. /* Needed by other modules */
  162. return 0;
  163. }
  164. void __exit pcigame_exit(void)
  165. {
  166. pci_unregister_driver(&pcigame_driver);
  167. }
  168. module_init(pcigame_init);
  169. module_exit(pcigame_exit);
  170. MODULE_LICENSE("GPL");