root/kernel/chr_drv/mouse.c

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

DEFINITIONS

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

   1 /*
   2  * Logitech Bus Mouse Driver for Linux
   3  * by James Banks
   4  * 
   5  * Heavily modified by David Giller
   6  *   changed from queue- to counter- driven
   7  *   hacked out a (probably incorrect) mouse_select
   8  *
   9  * Modified again by Nathan Laredo to interface with
  10  *   0.96c-pl1 IRQ handling changes (13JUL92)
  11  *   didn't bother touching select code.
  12  *
  13  * Modified the select() code blindly to conform to the VFS
  14  *   requirements. 92.07.14 - Linus. Somebody should test it out.
  15  * 
  16  * version 0.1
  17  */
  18 
  19 #include        <linux/kernel.h>
  20 #include        <linux/sched.h>
  21 #include        <linux/mouse.h>
  22 #include        <linux/tty.h>
  23 #include        <linux/signal.h>
  24 #include        <linux/errno.h>
  25 
  26 #include        <asm/io.h>
  27 #include        <asm/segment.h>
  28 #include        <asm/system.h>
  29 #include        <asm/irq.h>
  30 
  31 static struct mouse_status mouse;
  32 
  33 static void mouse_interrupt(int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
  34 {
  35         char dx, dy, buttons;
  36 
  37         MSE_INT_OFF();
  38         
  39         outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
  40         dx = (inb(MSE_DATA_PORT) & 0xf);
  41         
  42         outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
  43         dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
  44         
  45         outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
  46         dy = (inb(MSE_DATA_PORT) & 0xf);
  47         
  48         outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
  49         buttons = inb(MSE_DATA_PORT);
  50 
  51         dy |= (buttons & 0xf) << 4;
  52         buttons = ((buttons >> 5) & 0x07);
  53 
  54         mouse.buttons = buttons;
  55         mouse.latch_buttons |= buttons;
  56         mouse.dx += dx;
  57         mouse.dy += dy;
  58         mouse.ready = 1;
  59         if (mouse.inode && mouse.inode->i_wait)
  60                  wake_up(&mouse.inode->i_wait);
  61         
  62         MSE_INT_ON();
  63 }
  64 
  65 static void release_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         MSE_INT_OFF();
  68         mouse.active = 0;
  69         mouse.ready = 0; 
  70         mouse.inode = NULL;
  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.active)
  77                 return -EBUSY;
  78         if (!mouse.present)
  79                 return -EINVAL;
  80         mouse.active = 1;
  81         mouse.ready = 0;
  82         mouse.inode = inode;
  83         mouse.dx = 0;
  84         mouse.dy = 0;   
  85         mouse.buttons = mouse.latch_buttons = 0x80;
  86         MSE_INT_ON();   
  87         if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
  88                 MSE_INT_OFF();
  89                 mouse.active = 0;
  90                 mouse.ready = 0;
  91                 mouse.inode = NULL;
  92                 return -EBUSY;
  93         }
  94         return 0;
  95 }
  96 
  97 static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         return -EINVAL;
 100 }
 101 
 102 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         int i;
 105 
 106         if (count < 3) return -EINVAL;
 107         if (!mouse.ready) return -EAGAIN;
 108         
 109         MSE_INT_OFF();
 110                 
 111         put_fs_byte(mouse.latch_buttons | 0x80, buffer);
 112         
 113         if (mouse.dx < -127) mouse.dx = -127;
 114         if (mouse.dx >  127) mouse.dx =  127;
 115         
 116         put_fs_byte((char)mouse.dx, buffer + 1);
 117         
 118         if (mouse.dy < -127) mouse.dy = -127;
 119         if (mouse.dy >  127) mouse.dy =  127;
 120         
 121         put_fs_byte((char) -mouse.dy, buffer + 2);
 122         
 123         for (i = 3; i < count; i++)
 124                 put_fs_byte(0x00, buffer + i);
 125                 
 126         mouse.dx = 0;
 127         mouse.dy = 0;
 128         mouse.latch_buttons = mouse.buttons;
 129         mouse.ready = 0;
 130         
 131         MSE_INT_ON();
 132         return i;       
 133 }
 134 
 135 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         if (sel_type != SEL_IN)
 138                 return 0;
 139         if (mouse.ready) 
 140                 return 1;
 141         select_wait(&inode->i_wait,wait);
 142         return 0;
 143 }
 144 
 145 static struct file_operations mouse_fops = {
 146         NULL,           /* mouse_seek */
 147         read_mouse,
 148         write_mouse,
 149         NULL,           /* mouse_readdir */
 150         mouse_select,   /* mouse_select */
 151         NULL,           /* mouse_ioctl */
 152         open_mouse,
 153         release_mouse,
 154 };
 155 
 156 long mouse_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {       
 158         int i;
 159 
 160         outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
 161         outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
 162         
 163         for (i = 0; i < 100000; i++); /* busy loop */
 164         if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
 165                 printk("No bus mouse detected.\n");
 166                 mouse.present = 0;
 167                 return kmem_start;
 168         }
 169         chrdev_fops[10] = &mouse_fops;
 170         outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
 171         
 172         MSE_INT_OFF();
 173         
 174         mouse.present = 1;
 175         mouse.active = 0;
 176         mouse.ready = 0;
 177         mouse.buttons = mouse.latch_buttons = 0x80;
 178         mouse.dx = 0;
 179         mouse.dy = 0;
 180         printk("Bus mouse detected and installed.\n");
 181         return kmem_start;
 182 }

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