root/kernel/chr_drv/busmouse.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. bus_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  * Modified by Johan Myreen to make room for other mice (9AUG92)
  17  *   removed assignment chr_fops[10] = &mouse_fops; see mouse.c
  18  *   renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
  19  *   renamed this file mouse.c => busmouse.c
  20  */
  21 
  22 #include <linux/kernel.h>
  23 #include <linux/sched.h>
  24 #include <linux/busmouse.h>
  25 #include <linux/tty.h>
  26 #include <linux/signal.h>
  27 #include <linux/errno.h>
  28 
  29 #include <asm/io.h>
  30 #include <asm/segment.h>
  31 #include <asm/system.h>
  32 #include <asm/irq.h>
  33 
  34 static struct mouse_status mouse;
  35 
  36 static void mouse_interrupt(int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38         char dx, dy, buttons;
  39 
  40         MSE_INT_OFF();
  41         outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
  42         dx = (inb(MSE_DATA_PORT) & 0xf);
  43         outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
  44         dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
  45         outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
  46         dy = (inb(MSE_DATA_PORT) & 0xf);
  47         outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
  48         buttons = inb(MSE_DATA_PORT);
  49         dy |= (buttons & 0xf) << 4;
  50         buttons = ((buttons >> 5) & 0x07);
  51         if (dx != 0 || dy != 0 || buttons != mouse.buttons) {
  52           mouse.buttons = buttons;
  53           mouse.dx += dx;
  54           mouse.dy += dy;
  55           mouse.ready = 1;
  56           wake_up_interruptible(&mouse.wait);
  57         }
  58         MSE_INT_ON();
  59 }
  60 
  61 static void release_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63         MSE_INT_OFF();
  64         mouse.active = 0;
  65         mouse.ready = 0;
  66         free_irq(MOUSE_IRQ);
  67 }
  68 
  69 static int open_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71         if (!mouse.present)
  72                 return -EINVAL;
  73         if (mouse.active)
  74                 return -EBUSY;
  75         mouse.active = 1;
  76         mouse.ready = 0;
  77         mouse.dx = 0;
  78         mouse.dy = 0;
  79         mouse.buttons = 0x87;
  80         if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
  81                 mouse.active = 0;
  82                 return -EBUSY;
  83         }
  84         MSE_INT_ON();
  85         return 0;
  86 }
  87 
  88 
  89 static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  90 {
  91         return -EINVAL;
  92 }
  93 
  94 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         int i;
  97 
  98         if (count < 3)
  99                 return -EINVAL;
 100         if (!mouse.ready)
 101                 return -EAGAIN;
 102         MSE_INT_OFF();
 103         put_fs_byte(mouse.buttons | 0x80, buffer);
 104         if (mouse.dx < -127)
 105                 mouse.dx = -127;
 106         if (mouse.dx > 127)
 107                 mouse.dx =  127;
 108         put_fs_byte((char)mouse.dx, buffer + 1);
 109         if (mouse.dy < -127)
 110                 mouse.dy = -127;
 111         if (mouse.dy > 127)
 112                 mouse.dy =  127;
 113         put_fs_byte((char) -mouse.dy, buffer + 2);
 114         for (i = 3; i < count; i++)
 115                 put_fs_byte(0x00, buffer + i);
 116         mouse.dx = 0;
 117         mouse.dy = 0;
 118         mouse.ready = 0;
 119         MSE_INT_ON();
 120         return i;
 121 }
 122 
 123 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         if (sel_type != SEL_IN)
 126                 return 0;
 127         if (mouse.ready)
 128                 return 1;
 129         select_wait(&mouse.wait, wait);
 130         return 0;
 131 }
 132 
 133 struct file_operations bus_mouse_fops = {
 134         NULL,           /* mouse_seek */
 135         read_mouse,
 136         write_mouse,
 137         NULL,           /* mouse_readdir */
 138         mouse_select,   /* mouse_select */
 139         NULL,           /* mouse_ioctl */
 140         NULL,           /* mouse_mmap */
 141         open_mouse,
 142         release_mouse,
 143 };
 144 
 145 unsigned long bus_mouse_init(unsigned long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         int i;
 148 
 149         outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
 150         outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
 151         for (i = 0; i < 100000; i++)
 152                 /* busy loop */;
 153         if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
 154                 mouse.present = 0;
 155                 return kmem_start;
 156         }
 157         outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
 158         MSE_INT_OFF();
 159         mouse.present = 1;
 160         mouse.active = 0;
 161         mouse.ready = 0;
 162         mouse.buttons = 0x87;
 163         mouse.dx = 0;
 164         mouse.dy = 0;
 165         mouse.wait = NULL;
 166         printk("Logitech Bus mouse detected and installed.\n");
 167         return kmem_start;
 168 }

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