root/kernel/chr_drv/msbusmouse.c

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

DEFINITIONS

This source file includes following definitions.
  1. ms_mouse_interrupt
  2. release_mouse
  3. open_mouse
  4. write_mouse
  5. read_mouse
  6. mouse_select
  7. ms_bus_mouse_init

   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  * version 0.3
  23  */
  24 
  25 #include <linux/kernel.h>
  26 #include <linux/sched.h>
  27 #include <linux/busmouse.h>
  28 #include <linux/tty.h>
  29 #include <linux/signal.h>
  30 #include <linux/errno.h>
  31 
  32 #include <asm/io.h>
  33 #include <asm/segment.h>
  34 #include <asm/system.h>
  35 #include <asm/irq.h>
  36 
  37 static struct mouse_status mouse;
  38 
  39 static void ms_mouse_interrupt(int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         char dx, dy, buttons;
  42 
  43         outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  44         outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
  45 
  46         outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
  47         dx = inb(MS_MSE_DATA_PORT);
  48 
  49         outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
  50         dy = inb(MS_MSE_DATA_PORT);
  51 
  52         outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
  53         buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
  54 
  55         outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
  56         outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
  57 
  58         mouse.buttons = buttons;
  59         mouse.latch_buttons |= buttons;
  60         mouse.dx += dx;
  61         mouse.dy += dy;
  62         mouse.ready = 1;
  63         wake_up_interruptible(&mouse.wait);
  64 }
  65 
  66 static void release_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         MS_MSE_INT_OFF();
  69         mouse.active = 0;
  70         mouse.ready = 0; 
  71         free_irq(MOUSE_IRQ);
  72 }
  73 
  74 static int open_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         if (!mouse.present)
  77                 return -EINVAL;
  78         if (mouse.active)
  79                 return -EBUSY;
  80         mouse.active = 1;
  81         mouse.ready = 0;
  82         mouse.dx = 0;
  83         mouse.dy = 0;   
  84         mouse.buttons = mouse.latch_buttons = 0x80;
  85         if (request_irq(MOUSE_IRQ, ms_mouse_interrupt)) {
  86                 mouse.active = 0;
  87                 return -EBUSY;
  88         }
  89         outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
  90         MS_MSE_INT_ON();        
  91         return 0;
  92 }
  93 
  94 
  95 static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97         return -EINVAL;
  98 }
  99 
 100 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         int i;
 103 
 104         if (count < 3)
 105                 return -EINVAL;
 106         if (!mouse.ready)
 107                 return -EAGAIN;
 108         put_fs_byte(mouse.latch_buttons | 0x80, buffer);
 109         if (mouse.dx < -127)
 110                 mouse.dx = -127;
 111         if (mouse.dx > 127)
 112                 mouse.dx =  127;
 113         put_fs_byte((char)mouse.dx, buffer + 1);
 114         if (mouse.dy < -127)
 115                 mouse.dy = -127;
 116         if (mouse.dy > 127)
 117                 mouse.dy =  127;
 118         put_fs_byte((char) -mouse.dy, buffer + 2);
 119         for (i = 3; i < count; i++)
 120                 put_fs_byte(0x00, buffer + i);
 121         mouse.dx = 0;
 122         mouse.dy = 0;
 123         mouse.latch_buttons = mouse.buttons;
 124         mouse.ready = 0;
 125         return i;       
 126 }
 127 
 128 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         if (sel_type != SEL_IN)
 131                 return 0;
 132         if (mouse.ready) 
 133                 return 1;
 134         select_wait(&mouse.wait,wait);
 135         return 0;
 136 }
 137 
 138 struct file_operations ms_bus_mouse_fops = {
 139         NULL,           /* mouse_seek */
 140         read_mouse,
 141         write_mouse,
 142         NULL,           /* mouse_readdir */
 143         mouse_select,   /* mouse_select */
 144         NULL,           /* mouse_ioctl */
 145         NULL,           /* mouse_mmap */
 146         open_mouse,
 147         release_mouse,
 148 };
 149 
 150 #define MS_DELAY 100000
 151 
 152 unsigned long ms_bus_mouse_init(unsigned long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154         register int mse_byte;
 155         int i, delay_val, msfound = 1;
 156 
 157         mouse.present = 0;
 158         mouse.active = mouse.ready = 0;
 159         mouse.buttons = mouse.latch_buttons = 0x80;
 160         mouse.dx = mouse.dy = 0;
 161         mouse.wait = NULL;
 162         if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) {
 163                 for (delay_val=0; delay_val<MS_DELAY;)
 164                         delay_val++;
 165 
 166                 mse_byte = inb(MS_MSE_SIGNATURE_PORT);
 167                 for (delay_val=0; delay_val<MS_DELAY; )
 168                         delay_val++;
 169 
 170                 for (i = 0; i < 4; i++) {
 171                         for (delay_val=0; delay_val<MS_DELAY;)
 172                                 delay_val++;
 173                         if (inb(MS_MSE_SIGNATURE_PORT) == 0xde) {
 174                                 for (delay_val=0; delay_val<MS_DELAY; )
 175                                         delay_val++;
 176                                 if (inb(MS_MSE_SIGNATURE_PORT) == mse_byte)
 177                                         msfound = 0;
 178                                 else
 179                                         msfound = 1;
 180                         } else
 181                                 msfound = 1;
 182                 }
 183         }
 184         if (msfound == 1) {
 185                 return kmem_start;
 186         }
 187         MS_MSE_INT_OFF();
 188         mouse.present = 1;
 189         printk("Microsoft Bus mouse detected and installed.\n");
 190         return kmem_start;
 191 }

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