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 MSE_INT_OFF();
69 outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
70 dx = (inb(MSE_DATA_PORT) & 0xf);
71 outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
72 dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
73 outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
74 dy = (inb(MSE_DATA_PORT) & 0xf);
75 outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
76 buttons = inb(MSE_DATA_PORT);
77 dy |= (buttons & 0xf) << 4;
78 buttons = ((buttons >> 5) & 0x07);
79 if (dx != 0 || dy != 0 || buttons != mouse.buttons) {
80 add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
81 mouse.buttons = buttons;
82 mouse.dx += dx;
83 mouse.dy -= dy;
84 mouse.ready = 1;
85 wake_up_interruptible(&mouse.wait);
86
87
88
89
90
91
92 if (mouse.dx < -2048)
93 mouse.dx = -2048;
94 if (mouse.dx > 2048)
95 mouse.dx = 2048;
96
97 if (mouse.dy < -2048)
98 mouse.dy = -2048;
99 if (mouse.dy > 2048)
100 mouse.dy = 2048;
101
102 if (mouse.fasyncptr)
103 kill_fasync(mouse.fasyncptr, SIGIO);
104 }
105 MSE_INT_ON();
106 }
107
108 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
109 {
110 int retval;
111
112 retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
113 if (retval < 0)
114 return retval;
115 return 0;
116 }
117
118
119
120
121
122 static void close_mouse(struct inode * inode, struct file * file)
123 {
124 fasync_mouse(inode, file, 0);
125 if (--mouse.active)
126 return;
127 MSE_INT_OFF();
128 free_irq(mouse_irq);
129 MOD_DEC_USE_COUNT;
130 }
131
132
133
134
135
136 static int open_mouse(struct inode * inode, struct file * file)
137 {
138 if (!mouse.present)
139 return -EINVAL;
140 if (mouse.active++)
141 return 0;
142 if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse")) {
143 mouse.active--;
144 return -EBUSY;
145 }
146 mouse.ready = 0;
147 mouse.dx = 0;
148 mouse.dy = 0;
149 mouse.buttons = 0x87;
150 MOD_INC_USE_COUNT;
151 MSE_INT_ON();
152 return 0;
153 }
154
155
156
157
158
159 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
160 {
161 return -EINVAL;
162 }
163
164
165
166
167
168 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
169 {
170 int r;
171 int dx;
172 int dy;
173 unsigned char buttons;
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 MSE_INT_OFF();
190 dx = mouse.dx;
191 dy = mouse.dy;
192 if (dx < -127)
193 dx = -127;
194 if (dx > 127)
195 dx = 127;
196 if (dy < -127)
197 dy = -127;
198 if (dy > 127)
199 dy = 127;
200 buttons = mouse.buttons;
201 mouse.dx -= dx;
202 mouse.dy -= dy;
203 mouse.ready = 0;
204 MSE_INT_ON();
205
206 put_user(buttons | 0x80, buffer);
207 put_user((char)dx, buffer + 1);
208 put_user((char)dy, buffer + 2);
209 for (r = 3; r < count; r++)
210 put_user(0x00, buffer + r);
211 return r;
212 }
213
214
215
216
217 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
218 {
219 if (sel_type == SEL_IN) {
220 if (mouse.ready)
221 return 1;
222 select_wait(&mouse.wait, wait);
223 }
224 return 0;
225 }
226
227 struct file_operations bus_mouse_fops = {
228 NULL,
229 read_mouse,
230 write_mouse,
231 NULL,
232 mouse_select,
233 NULL,
234 NULL,
235 open_mouse,
236 close_mouse,
237 NULL,
238 fasync_mouse,
239 };
240
241 static struct mouse bus_mouse = {
242 LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops
243 };
244
245 int bus_mouse_init(void)
246 {
247 if (check_region(LOGIBM_BASE, LOGIBM_EXTENT)) {
248 mouse.present = 0;
249 return -EIO;
250 }
251
252 outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
253 outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
254 udelay(100L);
255 if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
256 mouse.present = 0;
257 return -EIO;
258 }
259 outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
260 MSE_INT_OFF();
261
262 request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse");
263
264 mouse.present = 1;
265 mouse.active = 0;
266 mouse.ready = 0;
267 mouse.buttons = 0x87;
268 mouse.dx = 0;
269 mouse.dy = 0;
270 mouse.wait = NULL;
271 printk("Logitech bus mouse detected, using IRQ %d.\n",
272 mouse_irq);
273 mouse_register(&bus_mouse);
274 return 0;
275 }
276
277 #ifdef MODULE
278
279 int init_module(void)
280 {
281 return bus_mouse_init();
282 }
283
284 void cleanup_module(void)
285 {
286 mouse_deregister(&bus_mouse);
287 release_region(LOGIBM_BASE, LOGIBM_EXTENT);
288 }
289 #endif