This source file includes following definitions.
- bmouse_setup
- mouse_interrupt
- fasync_mouse
- close_mouse
- open_mouse
- write_mouse
- read_mouse
- mouse_select
- bus_mouse_init
- init_module
- cleanup_module
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 #include <linux/module.h>
37
38 #include <linux/kernel.h>
39 #include <linux/sched.h>
40 #include <linux/busmouse.h>
41 #include <linux/signal.h>
42 #include <linux/errno.h>
43 #include <linux/mm.h>
44 #include <linux/mouse.h>
45 #include <linux/random.h>
46 #include <linux/delay.h>
47 #include <linux/ioport.h>
48
49 #include <asm/io.h>
50 #include <asm/segment.h>
51 #include <asm/system.h>
52 #include <asm/irq.h>
53
54 static struct mouse_status mouse;
55 static int mouse_irq = MOUSE_IRQ;
56
57 void bmouse_setup(char *str, int *ints)
58 {
59 if (ints[0] > 0)
60 mouse_irq=ints[1];
61 }
62
63 static void mouse_interrupt(int irq, struct pt_regs *regs)
64 {
65 char dx, dy;
66 unsigned char buttons;
67
68 outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
69 dx = (inb(MSE_DATA_PORT) & 0xf);
70 outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
71 dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
72 outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
73 dy = (inb(MSE_DATA_PORT) & 0xf);
74 outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
75 buttons = inb(MSE_DATA_PORT);
76 dy |= (buttons & 0xf) << 4;
77 buttons = ((buttons >> 5) & 0x07);
78 if (dx != 0 || dy != 0 || buttons != mouse.buttons) {
79 add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
80 mouse.buttons = buttons;
81 mouse.dx += dx;
82 mouse.dy -= dy;
83 mouse.ready = 1;
84 wake_up_interruptible(&mouse.wait);
85
86
87
88
89
90
91 if (mouse.dx < -2048)
92 mouse.dx = -2048;
93 if (mouse.dx > 2048)
94 mouse.dx = 2048;
95
96 if (mouse.dy < -2048)
97 mouse.dy = -2048;
98 if (mouse.dy > 2048)
99 mouse.dy = 2048;
100
101 if (mouse.fasyncptr)
102 kill_fasync(mouse.fasyncptr, SIGIO);
103 }
104 MSE_INT_ON();
105 }
106
107 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
108 {
109 int retval;
110
111 retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
112 if (retval < 0)
113 return retval;
114 return 0;
115 }
116
117
118
119
120
121 static void close_mouse(struct inode * inode, struct file * file)
122 {
123 fasync_mouse(inode, file, 0);
124 if (--mouse.active)
125 return;
126 MSE_INT_OFF();
127 free_irq(mouse_irq);
128 MOD_DEC_USE_COUNT;
129 }
130
131
132
133
134
135 static int open_mouse(struct inode * inode, struct file * file)
136 {
137 if (!mouse.present)
138 return -EINVAL;
139 if (mouse.active++)
140 return 0;
141 if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse")) {
142 mouse.active--;
143 return -EBUSY;
144 }
145 mouse.ready = 0;
146 mouse.dx = 0;
147 mouse.dy = 0;
148 mouse.buttons = 0x87;
149 MOD_INC_USE_COUNT;
150 MSE_INT_ON();
151 return 0;
152 }
153
154
155
156
157
158 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
159 {
160 return -EINVAL;
161 }
162
163
164
165
166
167 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
168 {
169 int r;
170 int dx;
171 int dy;
172 unsigned char buttons;
173
174
175 if (count < 3)
176 return -EINVAL;
177 if ((r = verify_area(VERIFY_WRITE, buffer, count)))
178 return r;
179 if (!mouse.ready)
180 return -EAGAIN;
181
182
183
184
185
186
187
188
189
190 disable_irq(mouse_irq);
191 dx = mouse.dx;
192 dy = mouse.dy;
193 if (dx < -127)
194 dx = -127;
195 if (dx > 127)
196 dx = 127;
197 if (dy < -127)
198 dy = -127;
199 if (dy > 127)
200 dy = 127;
201 buttons = mouse.buttons;
202 mouse.dx -= dx;
203 mouse.dy -= dy;
204 mouse.ready = 0;
205 enable_irq(mouse_irq);
206
207
208 put_user(buttons | 0x80, buffer);
209 put_user((char)dx, buffer + 1);
210 put_user((char)dy, buffer + 2);
211 for (r = 3; r < count; r++)
212 put_user(0x00, buffer + r);
213 return r;
214 }
215
216
217
218
219 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
220 {
221 if (sel_type == SEL_IN) {
222 if (mouse.ready)
223 return 1;
224 select_wait(&mouse.wait, wait);
225 }
226 return 0;
227 }
228
229 struct file_operations bus_mouse_fops = {
230 NULL,
231 read_mouse,
232 write_mouse,
233 NULL,
234 mouse_select,
235 NULL,
236 NULL,
237 open_mouse,
238 close_mouse,
239 NULL,
240 fasync_mouse,
241 };
242
243 static struct mouse bus_mouse = {
244 LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops
245 };
246
247 int bus_mouse_init(void)
248 {
249 if (check_region(LOGIBM_BASE, LOGIBM_EXTENT)) {
250 mouse.present = 0;
251 return -EIO;
252 }
253
254 outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
255 outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
256 udelay(100L);
257 if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
258 mouse.present = 0;
259 return -EIO;
260 }
261 outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
262 MSE_INT_OFF();
263
264 request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse");
265
266 mouse.present = 1;
267 mouse.active = 0;
268 mouse.ready = 0;
269 mouse.buttons = 0x87;
270 mouse.dx = 0;
271 mouse.dy = 0;
272 mouse.wait = NULL;
273 printk("Logitech bus mouse detected, using IRQ %d.\n",
274 mouse_irq);
275 mouse_register(&bus_mouse);
276 return 0;
277 }
278
279 #ifdef MODULE
280
281 int init_module(void)
282 {
283 return bus_mouse_init();
284 }
285
286 void cleanup_module(void)
287 {
288 mouse_deregister(&bus_mouse);
289 release_region(LOGIBM_BASE, LOGIBM_EXTENT);
290 }
291 #endif