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

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