root/drivers/char/msbusmouse.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ms_mouse_interrupt
  2. fasync_mouse
  3. release_mouse
  4. open_mouse
  5. write_mouse
  6. read_mouse
  7. mouse_select
  8. init_module
  9. cleanup_module

   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  * version 0.3b
  31  */
  32 
  33 #ifdef MODULE
  34 #include <linux/module.h>
  35 #include <linux/version.h>
  36 #else
  37 #define MOD_INC_USE_COUNT
  38 #define MOD_DEC_USE_COUNT
  39 #endif
  40 
  41 #include <linux/kernel.h>
  42 #include <linux/ioport.h>
  43 #include <linux/sched.h>
  44 #include <linux/busmouse.h>
  45 #include <linux/signal.h>
  46 #include <linux/errno.h>
  47 #include <linux/mouse.h>
  48 
  49 #include <asm/io.h>
  50 #include <asm/segment.h>
  51 #include <asm/system.h>
  52 #include <asm/irq.h>
  53 
  54 static struct mouse_status mouse;
  55 
  56 static void ms_mouse_interrupt(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58         char dx, dy;
  59         unsigned char buttons;
  60 
  61         outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  62         outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
  63 
  64         outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
  65         dx = inb(MS_MSE_DATA_PORT);
  66 
  67         outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
  68         dy = inb(MS_MSE_DATA_PORT);
  69 
  70         outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
  71         buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
  72 
  73         outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  74         outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
  75 
  76         if (dx != 0 || dy != 0 || buttons != mouse.buttons || ((~buttons) & 0x07)) {
  77                 mouse.buttons = buttons;
  78                 mouse.dx += dx;
  79                 mouse.dy += dy;
  80                 mouse.ready = 1;
  81                 wake_up_interruptible(&mouse.wait);
  82                 if (mouse.fasyncptr)
  83                         kill_fasync(mouse.fasyncptr, SIGIO);
  84         }
  85 }
  86 
  87 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89         int retval;
  90 
  91         retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
  92         if (retval < 0)
  93                 return retval;
  94         return 0;
  95 }
  96 
  97 static void release_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         MS_MSE_INT_OFF();
 100         mouse.active = mouse.ready = 0; 
 101         free_irq(MOUSE_IRQ);
 102         fasync_mouse(inode, file, 0);
 103 }
 104 
 105 static int open_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         if (!mouse.present)
 108                 return -EINVAL;
 109         if (mouse.active)
 110                 return -EBUSY;
 111         mouse.active = 1;
 112         mouse.ready = mouse.dx = mouse.dy = 0;  
 113         mouse.buttons = 0x80;
 114         if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse")) {
 115                 mouse.active = 0;
 116                 return -EBUSY;
 117         }
 118         outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
 119         MS_MSE_INT_ON();        
 120         return 0;
 121 }
 122 
 123 
 124 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         return -EINVAL;
 127 }
 128 
 129 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131         int i, dx, dy;
 132 
 133         if (count < 3)
 134                 return -EINVAL;
 135         if (!mouse.ready)
 136                 return -EAGAIN;
 137         put_user(mouse.buttons | 0x80, buffer);
 138         dx = mouse.dx < -127 ? -127 : mouse.dx > 127 ?  127 :  mouse.dx;
 139         dy = mouse.dy < -127 ?  127 : mouse.dy > 127 ? -127 : -mouse.dy;
 140         put_user((char)dx, buffer + 1);
 141         put_user((char)dy, buffer + 2);
 142         for (i = 3; i < count; i++)
 143                 put_user(0x00, buffer + i);
 144         mouse.dx -= dx;
 145         mouse.dy += dy;
 146         mouse.ready = 0;
 147         return i;       
 148 }
 149 
 150 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152         if (sel_type != SEL_IN)
 153                 return 0;
 154         if (mouse.ready) 
 155                 return 1;
 156         select_wait(&mouse.wait,wait);
 157         return 0;
 158 }
 159 
 160 struct file_operations ms_bus_mouse_fops = {
 161         NULL,           /* mouse_seek */
 162         read_mouse,
 163         write_mouse,
 164         NULL,           /* mouse_readdir */
 165         mouse_select,   /* mouse_select */
 166         NULL,           /* mouse_ioctl */
 167         NULL,           /* mouse_mmap */
 168         open_mouse,
 169         release_mouse,
 170         NULL,
 171         fasync_mouse,
 172 };
 173 
 174 static struct mouse ms_bus_mouse = {
 175         MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops
 176 };
 177 
 178 #ifdef MODULE
 179 char kernel_version[] = UTS_RELEASE;
 180 
 181 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 #else
 183 unsigned long ms_bus_mouse_init(unsigned long kmem_start)
 184 #endif
 185 {
 186         int mse_byte, i;
 187 
 188         mouse.present = mouse.active = mouse.ready = 0;
 189         mouse.buttons = 0x80;
 190         mouse.dx = mouse.dy = 0;
 191         mouse.wait = NULL;
 192 
 193         if (check_region(MS_MSE_CONTROL_PORT, 0x04))
 194                 return -ENODEV;
 195 
 196         if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
 197 
 198                 mse_byte = inb_p(MS_MSE_SIGNATURE_PORT);
 199 
 200                 for (i = 0; i < 4; i++) {
 201                         if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
 202                                 if (inb_p(MS_MSE_SIGNATURE_PORT) == mse_byte)
 203                                         mouse.present = 1;
 204                                 else
 205                                         mouse.present = 0;
 206                         } else
 207                                 mouse.present = 0;
 208                 }
 209         }
 210         if (mouse.present == 0) {
 211 #ifdef MODULE
 212           return -EIO;
 213 #else
 214                 return kmem_start;
 215 #endif
 216         }
 217         MS_MSE_INT_OFF();
 218         request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse");
 219         printk("Microsoft BusMouse detected and installed.\n");
 220         mouse_register(&ms_bus_mouse);
 221 #ifdef MODULE
 222         return 0;
 223 #else
 224         return kmem_start;
 225 #endif
 226 }
 227 
 228 #ifdef MODULE
 229 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         if (MOD_IN_USE)
 232                 printk("msbusmouse: in use, remove delayed\n");
 233         else {
 234                 mouse_deregister(&ms_bus_mouse);
 235                 release_region(MS_MSE_CONTROL_PORT, 0x04);
 236         }
 237 }
 238 #endif
 239 

/* [previous][next][first][last][top][bottom][index][help] */