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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Microsoft busmouse driver based on Logitech driver (see busmouse.c)
  3.  *
  4.  * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
  5.  *
  6.  * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
  7.  *    8/28/92
  8.  *
  9.  * Microsoft Bus Mouse support folded into 0.97pl4 code
  10.  *    by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
  11.  * Changes:  Logitech and Microsoft support in the same kernel.
  12.  *           Defined new constants in busmouse.h for MS mice.
  13.  *           Added int mse_busmouse_type to distinguish busmouse types
  14.  *           Added a couple of new functions to handle differences in using
  15.  *             MS vs. Logitech (where the int variable wasn't appropriate).
  16.  *
  17.  * Modified by Peter Cervasio (address above) (26SEP92)
  18.  * Changes:  Included code to (properly?) detect when a Microsoft mouse is
  19.  *           really attached to the machine.  Don't know what this does to
  20.  *           Logitech bus mice, but all it does is read ports.
  21.  *
  22.  * Modified by Christoph Niemann (niemann@rubdv15.etdv.ruhr-uni-bochum.de)
  23.  * Changes:  Better interrupt-handler (like in busmouse.c).
  24.  *      Some changes to reduce code-size.
  25.  *      Changed detection code to use inb_p() instead of doing empty
  26.  *      loops to delay i/o.
  27.  *
  28.  * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
  29.  *
  30.  * Converted to use new generic busmouse code.  5 Apr 1998
  31.  *   Russell King <rmk@arm.uk.linux.org>
  32.  *
  33.  * version 0.3b
  34.  */
  35. #include <linux/module.h>
  36. #include <linux/kernel.h>
  37. #include <linux/ioport.h>
  38. #include <linux/sched.h>
  39. #include <linux/logibusmouse.h>
  40. #include <linux/signal.h>
  41. #include <linux/errno.h>
  42. #include <linux/miscdevice.h>
  43. #include <linux/random.h>
  44. #include <linux/poll.h>
  45. #include <linux/init.h>
  46. #include <asm/io.h>
  47. #include <asm/uaccess.h>
  48. #include <asm/system.h>
  49. #include <asm/irq.h>
  50. #include "busmouse.h"
  51. static int msedev;
  52. static int mouse_irq = MOUSE_IRQ;
  53. MODULE_PARM(mouse_irq, "i");
  54. #ifndef MODULE
  55. static int __init msmouse_setup(char *str)
  56. {
  57.         int ints[4];
  58.         str = get_options(str, ARRAY_SIZE(ints), ints);
  59. if (ints[0] > 0)
  60. mouse_irq=ints[1];
  61. return 1;
  62. }
  63. __setup("msmouse=",msmouse_setup);
  64. #endif /* !MODULE */
  65. static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  66. {
  67.         char dx, dy;
  68. unsigned char buttons;
  69. outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  70. outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
  71. outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
  72. dx = inb(MS_MSE_DATA_PORT);
  73. outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
  74. dy = inb(MS_MSE_DATA_PORT);
  75. outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
  76. buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
  77. outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  78. outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
  79. /* why did the original have:
  80.  * if (dx != 0 || dy != 0 || buttons != mouse.buttons ||
  81.  *    ((~buttons) & 0x07))
  82.  *    ^^^^^^^^^^^^^^^^^^^ this?
  83.  */
  84. busmouse_add_movementbuttons(msedev, dx, -dy, buttons);
  85. }
  86. static int release_mouse(struct inode * inode, struct file * file)
  87. {
  88. MS_MSE_INT_OFF();
  89. free_irq(mouse_irq, NULL);
  90. return 0;
  91. }
  92. static int open_mouse(struct inode * inode, struct file * file)
  93. {
  94. if (request_irq(mouse_irq, ms_mouse_interrupt, 0, "MS Busmouse", NULL))
  95. return -EBUSY;
  96. outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
  97. MS_MSE_INT_ON();
  98. return 0;
  99. }
  100. static struct busmouse msbusmouse = {
  101. MICROSOFT_BUSMOUSE, "msbusmouse", THIS_MODULE, open_mouse, release_mouse, 0
  102. };
  103. static int __init ms_bus_mouse_init(void)
  104. {
  105. int present = 0;
  106. int mse_byte, i;
  107. if (check_region(MS_MSE_CONTROL_PORT, 0x04))
  108. return -ENODEV;
  109. if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
  110. mse_byte = inb_p(MS_MSE_SIGNATURE_PORT);
  111. for (i = 0; i < 4; i++) {
  112. if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
  113. if (inb_p(MS_MSE_SIGNATURE_PORT) == mse_byte)
  114. present = 1;
  115. else
  116. present = 0;
  117. } else
  118. present = 0;
  119. }
  120. }
  121. if (present == 0)
  122. return -EIO;
  123. if (!request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse"))
  124. return -EIO;
  125. MS_MSE_INT_OFF();
  126. msedev = register_busmouse(&msbusmouse);
  127. if (msedev < 0) {
  128. printk(KERN_WARNING "Unable to register msbusmouse driver.n");
  129. release_region(MS_MSE_CONTROL_PORT, 0x04);
  130. }
  131. else
  132. printk(KERN_INFO "Microsoft BusMouse detected and installed.n");
  133. return msedev < 0 ? msedev : 0;
  134. }
  135. static void __exit ms_bus_mouse_exit(void)
  136. {
  137. unregister_busmouse(msedev);
  138. release_region(MS_MSE_CONTROL_PORT, 0x04);
  139. }
  140. module_init(ms_bus_mouse_init)
  141. module_exit(ms_bus_mouse_exit)
  142. MODULE_LICENSE("GPL");
  143. EXPORT_NO_SYMBOLS;