2 * Amiga Mouse Driver for Linux 68k by Michael Rausch
5 * Logitech Bus Mouse Driver for Linux
8 * Mods by Matthew Dillon
10 * tracks better when X is busy or paging
12 * Heavily modified by David Giller
13 * changed from queue- to counter- driven
14 * hacked out a (probably incorrect) mouse_poll
16 * Modified again by Nathan Laredo to interface with
17 * 0.96c-pl1 IRQ handling changes (13JUL92)
18 * didn't bother touching poll code.
20 * Modified the poll() code blindly to conform to the VFS
21 * requirements. 92.07.14 - Linus. Somebody should test it out.
23 * Modified by Johan Myreen to make room for other mice (9AUG92)
24 * removed assignment chr_fops[10] = &mouse_fops; see mouse.c
25 * renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
26 * renamed this file mouse.c => busmouse.c
28 * Modified for use in the 1.3 kernels by Jes Sorensen.
30 * Moved the isr-allocation to the mouse_{open,close} calls, as there
31 * is no reason to service the mouse in the vertical blank isr if
32 * the mouse is not in use. Jes Sorensen
35 #include <linux/module.h>
37 #include <linux/types.h>
38 #include <linux/kernel.h>
39 #include <linux/sched.h>
41 #include <linux/signal.h>
42 #include <linux/errno.h>
43 #include <linux/miscdevice.h>
44 #include <linux/random.h>
45 #include <linux/poll.h>
46 #include <linux/init.h>
47 #include <linux/busmouse.h>
49 #include <asm/setup.h>
50 #include <asm/system.h>
51 #include <asm/uaccess.h>
53 #include <asm/amigahw.h>
54 #include <asm/amigaints.h>
56 #define AMI_MSE_INT_ON() mouseint_allowed = 1
57 #define AMI_MSE_INT_OFF() mouseint_allowed = 0
60 static struct mouse_status mouse
;
62 static int mouseint_allowed
;
64 static void mouse_interrupt(int irq
, void *dummy
, struct pt_regs
*fp
)
66 static int lastx
=0, lasty
=0;
69 unsigned char buttons
;
71 unsigned short joy0dat
, potgor
;
78 * This routine assumes, just like Kickstart, that the mouse
79 * has not moved more than 127 ticks since last VBL.
82 joy0dat
= custom
.joy0dat
;
89 dx
= (256 + nx
) - lastx
;
92 dx
= (nx
- 256) - lastx
;
96 dy
= (256 + ny
) - lasty
;
99 dy
= (ny
- 256) - lasty
;
106 dx
+= (lastdx
= joy0dat
& 0xff);
108 dx
= -255-dx
; /* underrun */
111 dx
= 255-dx
; /* overflow */
114 dy
+= (lastdy
= joy0dat
>> 8);
123 potgor
= custom
.potgor
;
124 buttons
= (ciaa
.pra
& 0x40 ? 4 : 0) | /* left button; note that the bits are low-active, as are the expected results -> double negation */
126 (potgor
& 0x0100 ? 2 : 0) | /* middle button; emulation goes here */
128 (potgor
& 0x0400 ? 1 : 0); /* right button */
131 if (dx
!= 0 || dy
!= 0 || buttons
!= mouse
.buttons
) {
132 add_mouse_randomness((buttons
<< 16) + (dy
<< 8) + dx
);
133 mouse
.buttons
= buttons
;
137 wake_up_interruptible(&mouse
.wait
);
140 * keep dx/dy reasonable, but still able to track when X (or
141 * whatever) must page or is busy (i.e. long waits between
144 if (mouse
.dx
< -2048)
150 if (mouse
.dy
< -2048)
157 kill_fasync(mouse
.fasyncptr
, SIGIO
);
162 static int fasync_mouse(int fd
, struct file
*filp
, int on
)
165 retval
= fasync_helper(fd
, filp
, on
, &mouse
.fasyncptr
);
172 * close access to the mouse
175 static int release_mouse(struct inode
* inode
, struct file
* file
)
177 fasync_mouse(-1, file
, 0);
180 free_irq(IRQ_AMIGA_VERTB
, mouse_interrupt
);
187 * open access to the mouse, currently only one open is
191 static int open_mouse(struct inode
* inode
, struct file
* file
)
198 * use VBL to poll mouse deltas
201 if(request_irq(IRQ_AMIGA_VERTB
, mouse_interrupt
, 0,
202 "Amiga mouse", mouse_interrupt
)) {
204 printk(KERN_INFO
"Installing Amiga mouse failed.\n");
211 mouse
.buttons
= 0x87;
219 * writes are disallowed
222 static ssize_t
write_mouse(struct file
* file
, const char * buffer
,
223 size_t count
, loff_t
*ppos
)
229 * read mouse data. Currently never blocks.
232 static ssize_t
read_mouse(struct file
* file
, char * buffer
,
233 size_t count
, loff_t
*ppos
)
237 unsigned char buttons
;
245 * Obtain the current mouse parameters and limit as appropriate for
246 * the return data format. Interrupts are only disabled while
247 * obtaining the parameters, NOT during the puts_user() calls,
248 * so paging in put_user() does not effect mouse tracking.
264 buttons
= mouse
.buttons
;
270 if (put_user(buttons
| 0x80, buffer
++) ||
271 put_user((char)dx
, buffer
++) ||
272 put_user((char)dy
, buffer
++))
276 if (clear_user(buffer
, count
- 3))
282 * poll for mouse input
285 static unsigned int mouse_poll(struct file
*file
, poll_table
* wait
)
287 poll_wait(file
, &mouse
.wait
, wait
);
289 return POLLIN
| POLLRDNORM
;
293 struct file_operations amiga_mouse_fops
= {
294 NULL
, /* mouse_seek */
297 NULL
, /* mouse_readdir */
298 mouse_poll
, /* mouse_poll */
299 NULL
, /* mouse_ioctl */
300 NULL
, /* mouse_mmap */
308 static struct miscdevice amiga_mouse
= {
309 AMIGAMOUSE_MINOR
, "amigamouse", &amiga_mouse_fops
312 __initfunc(int amiga_mouse_init(void))
314 if (!MACH_IS_AMIGA
|| !AMIGAHW_PRESENT(AMI_MOUSE
))
317 custom
.joytest
= 0; /* reset counters */
323 mouse
.buttons
= 0x87;
330 printk(KERN_INFO
"Amiga mouse installed.\n");
331 misc_register(&amiga_mouse
);
336 #include <asm/setup.h>
338 int init_module(void)
340 return amiga_mouse_init();
343 void cleanup_module(void)
345 misc_deregister(&amiga_mouse
);