/* * Amiga Mouse Driver for Linux 68k by Michael Rausch * based upon: * * Logitech Bus Mouse Driver for Linux * by James Banks * * Mods by Matthew Dillon * calls verify_area() * tracks better when X is busy or paging * * Heavily modified by David Giller * changed from queue- to counter- driven * hacked out a (probably incorrect) mouse_poll * * Modified again by Nathan Laredo to interface with * 0.96c-pl1 IRQ handling changes (13JUL92) * didn't bother touching poll code. * * Modified the poll() code blindly to conform to the VFS * requirements. 92.07.14 - Linus. Somebody should test it out. * * Modified by Johan Myreen to make room for other mice (9AUG92) * removed assignment chr_fops[10] = &mouse_fops; see mouse.c * renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public. * renamed this file mouse.c => busmouse.c * * Modified for use in the 1.3 kernels by Jes Sorensen. * * Moved the isr-allocation to the mouse_{open,close} calls, as there * is no reason to service the mouse in the vertical blank isr if * the mouse is not in use. Jes Sorensen * * Converted to use new generic busmouse code. 5 Apr 1998 * Russell King */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "busmouse.h" #if AMIGA_OLD_INT #define AMI_MSE_INT_ON() mouseint_allowed = 1 #define AMI_MSE_INT_OFF() mouseint_allowed = 0 static int mouseint_allowed; #endif static int msedev; static void mouse_interrupt(int irq, void *dummy, struct pt_regs *fp) { static int lastx=0, lasty=0; int dx, dy; int nx, ny; unsigned char buttons; unsigned short joy0dat, potgor; #if AMIGA_OLD_INT if(!mouseint_allowed) return; AMI_MSE_INT_OFF(); #endif /* * This routine assumes, just like Kickstart, that the mouse * has not moved more than 127 ticks since last VBL. */ joy0dat = custom.joy0dat; nx = joy0dat & 0xff; ny = joy0dat >> 8; dx = nx - lastx; if (dx < - 127) dx = (256 + nx) - lastx; if (dx > 127) dx = (nx - 256) - lastx; dy = ny - lasty; if (dy < - 127) dy = (256 + ny) - lasty; if (dy > 127) dy = (ny - 256) - lasty; lastx = nx; lasty = ny; #if 0 dx = -lastdx; dx += (lastdx = joy0dat & 0xff); if (dx < -127) dx = -255-dx; /* underrun */ else if (dx > 127) dx = 255-dx; /* overflow */ dy = -lastdy; dy += (lastdy = joy0dat >> 8); if (dy < -127) dy = -255-dy; else if (dy > 127) dy = 255-dy; #endif potgor = custom.potgor; buttons = (ciaa.pra & 0x40 ? 4 : 0) | /* left button; note that the bits are low-active, as are the expected results -> double negation */ #if 1 (potgor & 0x0100 ? 2 : 0) | /* middle button; emulation goes here */ #endif (potgor & 0x0400 ? 1 : 0); /* right button */ busmouse_add_movementbuttons(msedev, dx, -dy, buttons); #if AMIGA_OLD_INT AMI_MSE_INT_ON(); #endif } /* * close access to the mouse */ static int release_mouse(struct inode * inode, struct file * file) { free_irq(IRQ_AMIGA_VERTB, mouse_interrupt); #if AMIGA_OLD_INT AMI_MSE_INT_OFF(); #endif return 0; } /* * open access to the mouse, currently only one open is * allowed. */ static int open_mouse(struct inode * inode, struct file * file) { /* * use VBL to poll mouse deltas */ if(request_irq(IRQ_AMIGA_VERTB, mouse_interrupt, 0, "Amiga mouse", mouse_interrupt)) { printk(KERN_INFO "Installing Amiga mouse failed.\n"); return -EIO; } #if AMIGA_OLD_INT AMI_MSE_INT_ON(); #endif return 0; } static struct busmouse amigamouse = { AMIGAMOUSE_MINOR, "amigamouse", THIS_MODULE, open_mouse, release_mouse, 7 }; static int __init amiga_mouse_init(void) { if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) return -ENODEV; if (!request_mem_region(CUSTOM_PHYSADDR+10, 2, "amigamouse [Denise]")) return -EBUSY; custom.joytest = 0; /* reset counters */ #if AMIGA_OLD_INT AMI_MSE_INT_OFF(); #endif msedev = register_busmouse(&amigamouse); if (msedev < 0) printk(KERN_WARNING "Unable to install Amiga mouse driver.\n"); else printk(KERN_INFO "Amiga mouse installed.\n"); return msedev < 0 ? msedev : 0; } static void __exit amiga_mouse_exit(void) { unregister_busmouse(msedev); release_mem_region(CUSTOM_PHYSADDR+10, 2); } module_init(amiga_mouse_init); module_exit(amiga_mouse_exit); MODULE_LICENSE("GPL");