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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Logitech Bus Mouse Driver for Linux
  3.  * by James Banks
  4.  *
  5.  * Mods by Matthew Dillon
  6.  *   calls verify_area()
  7.  *   tracks better when X is busy or paging
  8.  *
  9.  * Heavily modified by David Giller
  10.  *   changed from queue- to counter- driven
  11.  *   hacked out a (probably incorrect) mouse_select
  12.  *
  13.  * Modified again by Nathan Laredo to interface with
  14.  *   0.96c-pl1 IRQ handling changes (13JUL92)
  15.  *   didn't bother touching select code.
  16.  *
  17.  * Modified the select() code blindly to conform to the VFS
  18.  *   requirements. 92.07.14 - Linus. Somebody should test it out.
  19.  *
  20.  * Modified by Johan Myreen to make room for other mice (9AUG92)
  21.  *   removed assignment chr_fops[10] = &mouse_fops; see mouse.c
  22.  *   renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
  23.  *   renamed this file mouse.c => busmouse.c
  24.  *
  25.  * Minor addition by Cliff Matthews
  26.  *   added fasync support
  27.  *
  28.  * Modularised 6-Sep-95 Philip Blundell <pjb27@cam.ac.uk> 
  29.  *
  30.  * Replaced dumb busy loop with udelay()  16 Nov 95
  31.  *   Nathan Laredo <laredo@gnu.ai.mit.edu>
  32.  *
  33.  * Track I/O ports with request_region().  12 Dec 95 Philip Blundell
  34.  *
  35.  * Converted to use new generic busmouse code.  5 Apr 1998
  36.  *   Russell King <rmk@arm.uk.linux.org>
  37.  */
  38. #include <linux/module.h>
  39. #include <linux/kernel.h>
  40. #include <linux/sched.h>
  41. #include <linux/init.h>
  42. #include <linux/logibusmouse.h>
  43. #include <linux/signal.h>
  44. #include <linux/errno.h>
  45. #include <linux/mm.h>
  46. #include <linux/poll.h>
  47. #include <linux/miscdevice.h>
  48. #include <linux/random.h>
  49. #include <linux/delay.h>
  50. #include <linux/ioport.h>
  51. #include <asm/io.h>
  52. #include <asm/uaccess.h>
  53. #include <asm/system.h>
  54. #include <asm/irq.h>
  55. #include "busmouse.h"
  56. static int msedev;
  57. static int mouse_irq = MOUSE_IRQ;
  58. MODULE_PARM(mouse_irq, "i");
  59. #ifndef MODULE
  60. static int __init bmouse_setup(char *str)
  61. {
  62. int ints[4];
  63. str = get_options(str, ARRAY_SIZE(ints), ints);
  64. if (ints[0] > 0)
  65. mouse_irq=ints[1];
  66. return 1;
  67. }
  68. __setup("logi_busmouse=", bmouse_setup);
  69. #endif /* !MODULE */
  70. static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  71. {
  72. char dx, dy;
  73. unsigned char buttons;
  74. outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
  75. dx = (inb(MSE_DATA_PORT) & 0xf);
  76. outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
  77. dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
  78. outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
  79. dy = (inb(MSE_DATA_PORT) & 0xf);
  80. outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
  81. buttons = inb(MSE_DATA_PORT);
  82. dy |= (buttons & 0xf) << 4;
  83. buttons = ((buttons >> 5) & 0x07);
  84. busmouse_add_movementbuttons(msedev, dx, -dy, buttons);
  85. MSE_INT_ON();
  86. }
  87. /*
  88.  * close access to the mouse
  89.  */
  90. static int close_mouse(struct inode * inode, struct file * file)
  91. {
  92. MSE_INT_OFF();
  93. free_irq(mouse_irq, NULL);
  94. return 0;
  95. }
  96. /*
  97.  * open access to the mouse
  98.  */
  99. static int open_mouse(struct inode * inode, struct file * file)
  100. {
  101. if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse", NULL))
  102. return -EBUSY;
  103. MSE_INT_ON();
  104. return 0;
  105. }
  106. static struct busmouse busmouse = {
  107. LOGITECH_BUSMOUSE, "busmouse", THIS_MODULE, open_mouse, close_mouse, 7
  108. };
  109. static int __init logi_busmouse_init(void)
  110. {
  111. if (check_region(LOGIBM_BASE, LOGIBM_EXTENT))
  112. return -EIO;
  113. outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
  114. outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
  115. udelay(100L); /* wait for reply from mouse */
  116. if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE)
  117. return -EIO;
  118. outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
  119. MSE_INT_OFF();
  120. request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse");
  121. msedev = register_busmouse(&busmouse);
  122. if (msedev < 0)
  123. printk(KERN_WARNING "Unable to register busmouse driver.n");
  124. else
  125. printk(KERN_INFO "Logitech busmouse installed.n");
  126. return msedev < 0 ? msedev : 0;
  127. }
  128. static void __exit logi_busmouse_cleanup (void)
  129. {
  130. unregister_busmouse(msedev);
  131. release_region(LOGIBM_BASE, LOGIBM_EXTENT);
  132. }
  133. module_init(logi_busmouse_init);
  134. module_exit(logi_busmouse_cleanup);
  135. MODULE_LICENSE("GPL");
  136. EXPORT_NO_SYMBOLS;