gameport.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: gameport.c,v 1.5 2000/05/29 10:54:53 vojtech Exp $
  3.  *
  4.  *  Copyright (c) 1999-2000 Vojtech Pavlik
  5.  *
  6.  *  Sponsored by SuSE
  7.  */
  8. /*
  9.  * Generic gameport layer
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or 
  15.  * (at your option) any later version.
  16.  * 
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  * 
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25.  * 
  26.  * Should you need to contact me, the author, you can do so either by
  27.  * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  28.  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  29.  */
  30. #include <asm/io.h>
  31. #include <linux/module.h>
  32. #include <linux/ioport.h>
  33. #include <linux/init.h>
  34. #include <linux/gameport.h>
  35. #include <linux/slab.h>
  36. #include <linux/isapnp.h>
  37. #include <linux/stddef.h>
  38. #include <linux/delay.h>
  39. MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
  40. MODULE_LICENSE("GPL");
  41. EXPORT_SYMBOL(gameport_register_port);
  42. EXPORT_SYMBOL(gameport_unregister_port);
  43. EXPORT_SYMBOL(gameport_register_device);
  44. EXPORT_SYMBOL(gameport_unregister_device);
  45. EXPORT_SYMBOL(gameport_open);
  46. EXPORT_SYMBOL(gameport_close);
  47. EXPORT_SYMBOL(gameport_rescan);
  48. EXPORT_SYMBOL(gameport_cooked_read);
  49. static struct gameport *gameport_list;
  50. static struct gameport_dev *gameport_dev;
  51. static int gameport_number;
  52. /*
  53.  * gameport_measure_speed() measures the gameport i/o speed.
  54.  */
  55. static int gameport_measure_speed(struct gameport *gameport)
  56. {
  57. #if defined(__i386__) || defined(__x86_64__)
  58. #define GET_TIME(x)     do { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } while (0)
  59. #define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193180L/HZ:0))
  60. unsigned int i, t, t1, t2, t3, tx;
  61. unsigned long flags;
  62. if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
  63. return 0;
  64. tx = 1 << 30;
  65. for(i = 0; i < 50; i++) {
  66. save_flags(flags); /* Yes, all CPUs */
  67. cli();
  68. GET_TIME(t1);
  69. for(t = 0; t < 50; t++) gameport_read(gameport);
  70. GET_TIME(t2);
  71. GET_TIME(t3);
  72. restore_flags(flags);
  73. udelay(i * 10);
  74. if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
  75. }
  76. return 59659 / (tx < 1 ? 1 : tx);
  77. #else
  78. unsigned int j, t = 0;
  79. j = jiffies; while (j == jiffies);
  80. j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); }
  81. return t * HZ / 1000;
  82. #endif
  83. gameport_close(gameport);
  84. }
  85. static void gameport_find_dev(struct gameport *gameport)
  86. {
  87.         struct gameport_dev *dev = gameport_dev;
  88.         while (dev && !gameport->dev) {
  89. if (dev->connect)
  90.                  dev->connect(gameport, dev);
  91.                 dev = dev->next;
  92.         }
  93. }
  94. void gameport_rescan(struct gameport *gameport)
  95. {
  96. gameport_close(gameport);
  97. gameport_find_dev(gameport);
  98. }
  99. void gameport_register_port(struct gameport *gameport)
  100. {
  101. gameport->number = gameport_number++;
  102. gameport->next = gameport_list;
  103. gameport_list = gameport;
  104. gameport->speed = gameport_measure_speed(gameport);
  105. gameport_find_dev(gameport);
  106. }
  107. void gameport_unregister_port(struct gameport *gameport)
  108. {
  109.         struct gameport **gameportptr = &gameport_list;
  110.         while (*gameportptr && (*gameportptr != gameport)) gameportptr = &((*gameportptr)->next);
  111.         *gameportptr = (*gameportptr)->next;
  112. if (gameport->dev && gameport->dev->disconnect)
  113. gameport->dev->disconnect(gameport);
  114. gameport_number--;
  115. }
  116. void gameport_register_device(struct gameport_dev *dev)
  117. {
  118. struct gameport *gameport = gameport_list;
  119. dev->next = gameport_dev;
  120. gameport_dev = dev;
  121. while (gameport) {
  122. if (!gameport->dev && dev->connect)
  123. dev->connect(gameport, dev);
  124. gameport = gameport->next;
  125. }
  126. }
  127. void gameport_unregister_device(struct gameport_dev *dev)
  128. {
  129.         struct gameport_dev **devptr = &gameport_dev;
  130. struct gameport *gameport = gameport_list;
  131.         while (*devptr && (*devptr != dev)) devptr = &((*devptr)->next);
  132.         *devptr = (*devptr)->next;
  133. while (gameport) {
  134. if (gameport->dev == dev && dev->disconnect)
  135. dev->disconnect(gameport);
  136. gameport_find_dev(gameport);
  137. gameport = gameport->next;
  138. }
  139. }
  140. int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode)
  141. {
  142. if (gameport->open) {
  143. if (gameport->open(gameport, mode))
  144. return -1;
  145. } else {
  146. if (mode != GAMEPORT_MODE_RAW)
  147. return -1;
  148. }
  149. if (gameport->dev)
  150. return -1;
  151. gameport->dev = dev;
  152. return 0;
  153. }
  154. void gameport_close(struct gameport *gameport)
  155. {
  156. gameport->dev = NULL;
  157. if (gameport->close) gameport->close(gameport);
  158. }