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