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         mouse.buttons = buttons;
  52         mouse.latch_buttons |= buttons;
  53         mouse.dx += dx;
  54         mouse.dy += dy;
  55         mouse.ready = 1;
  56         wake_up_interruptible(&mouse.wait);
  57         MSE_INT_ON();
  58 }
  59 
  60 static void release_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62         MSE_INT_OFF();
  63         mouse.active = 0;
  64         mouse.ready = 0;
  65         free_irq(MOUSE_IRQ);
  66 }
  67 
  68 static int open_mouse(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70         if (!mouse.present)
  71                 return -EINVAL;
  72         if (mouse.active)
  73                 return -EBUSY;
  74         mouse.active = 1;
  75         mouse.ready = 0;
  76         mouse.dx = 0;
  77         mouse.dy = 0;
  78         mouse.buttons = mouse.latch_buttons = 0x80;
  79         if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
  80                 mouse.active = 0;
  81                 return -EBUSY;
  82         }
  83         MSE_INT_ON();
  84         return 0;
  85 }
  86 
  87 
  88 static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         return -EINVAL;
  91 }
  92 
  93 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95         int i;
  96 
  97         if (count < 3)
  98                 return -EINVAL;
  99         if (!mouse.ready)
 100                 return -EAGAIN;
 101         MSE_INT_OFF();
 102         put_fs_byte(mouse.latch_buttons | 0x80, buffer);
 103         if (mouse.dx < -127)
 104                 mouse.dx = -127;
 105         if (mouse.dx > 127)
 106                 mouse.dx =  127;
 107         put_fs_byte((char)mouse.dx, buffer + 1);
 108         if (mouse.dy < -127)
 109                 mouse.dy = -127;
 110         if (mouse.dy > 127)
 111                 mouse.dy =  127;
 112         put_fs_byte((char) -mouse.dy, buffer + 2);
 113         for (i = 3; i < count; i++)
 114                 put_fs_byte(0x00, buffer + i);
 115         mouse.dx = 0;
 116         mouse.dy = 0;
 117         mouse.latch_buttons = mouse.buttons;
 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 = mouse.latch_buttons = 0x80;
 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] */