Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /* * 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_select * * Modified again by Nathan Laredo to interface with * 0.96c-pl1 IRQ handling changes (13JUL92) * didn't bother touching select code. * * Modified the select() 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 * * Minor addition by Cliff Matthews * added fasync support * * Modularised 6-Sep-95 Philip Blundell <pjb27@cam.ac.uk> * * Replaced dumb busy loop with udelay() 16 Nov 95 * Nathan Laredo <laredo@gnu.ai.mit.edu> * * Track I/O ports with request_region(). 12 Dec 95 Philip Blundell * * Converted to use new generic busmouse code. 5 Apr 1998 * Russell King <rmk@arm.uk.linux.org> */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/logibusmouse.h> #include <linux/signal.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/poll.h> #include <linux/miscdevice.h> #include <linux/random.h> #include <linux/delay.h> #include <linux/ioport.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> #include <asm/irq.h> #include "busmouse.h" static int msedev; static int mouse_irq = MOUSE_IRQ; MODULE_PARM(mouse_irq, "i"); #ifndef MODULE static int __init bmouse_setup(char *str) { int ints[4]; str = get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] > 0) mouse_irq=ints[1]; return 1; } __setup("logi_busmouse=", bmouse_setup); #endif /* !MODULE */ static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) { char dx, dy; unsigned char buttons; outb(MSE_READ_X_LOW, MSE_CONTROL_PORT); dx = (inb(MSE_DATA_PORT) & 0xf); outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT); dx |= (inb(MSE_DATA_PORT) & 0xf) << 4; outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT ); dy = (inb(MSE_DATA_PORT) & 0xf); outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT); buttons = inb(MSE_DATA_PORT); dy |= (buttons & 0xf) << 4; buttons = ((buttons >> 5) & 0x07); busmouse_add_movementbuttons(msedev, dx, -dy, buttons); MSE_INT_ON(); } /* * close access to the mouse */ static int close_mouse(struct inode * inode, struct file * file) { MSE_INT_OFF(); free_irq(mouse_irq, NULL); return 0; } /* * open access to the mouse */ static int open_mouse(struct inode * inode, struct file * file) { if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse", NULL)) return -EBUSY; MSE_INT_ON(); return 0; } static struct busmouse busmouse = { LOGITECH_BUSMOUSE, "busmouse", THIS_MODULE, open_mouse, close_mouse, 7 }; static int __init logi_busmouse_init(void) { if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse")) return -EIO; outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT); outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT); udelay(100L); /* wait for reply from mouse */ if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) { release_region(LOGIBM_BASE, LOGIBM_EXTENT); return -EIO; } outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT); MSE_INT_OFF(); msedev = register_busmouse(&busmouse); if (msedev < 0) { release_region(LOGIBM_BASE, LOGIBM_EXTENT); printk(KERN_WARNING "Unable to register busmouse driver.\n"); } else printk(KERN_INFO "Logitech busmouse installed.\n"); return msedev < 0 ? msedev : 0; } static void __exit logi_busmouse_cleanup (void) { unregister_busmouse(msedev); release_region(LOGIBM_BASE, LOGIBM_EXTENT); } module_init(logi_busmouse_init); module_exit(logi_busmouse_cleanup); MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; |