2 * Microsoft busmouse driver based on Logitech driver (see busmouse.c)
4 * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
6 * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
9 * Microsoft Bus Mouse support folded into 0.97pl4 code
10 * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
11 * Changes: Logitech and Microsoft support in the same kernel.
12 * Defined new constants in busmouse.h for MS mice.
13 * Added int mse_busmouse_type to distinguish busmouse types
14 * Added a couple of new functions to handle differences in using
15 * MS vs. Logitech (where the int variable wasn't appropriate).
17 * Modified by Peter Cervasio (address above) (26SEP92)
18 * Changes: Included code to (properly?) detect when a Microsoft mouse is
19 * really attached to the machine. Don't know what this does to
20 * Logitech bus mice, but all it does is read ports.
22 * Modified by Christoph Niemann (niemann@rubdv15.etdv.ruhr-uni-bochum.de)
23 * Changes: Better interrupt-handler (like in busmouse.c).
24 * Some changes to reduce code-size.
25 * Changed dectection code to use inb_p() instead of doing empty
31 #include <linux/kernel.h>
32 #include <linux/sched.h>
33 #include <linux/busmouse.h>
34 #include <linux/signal.h>
35 #include <linux/errno.h>
38 #include <asm/segment.h>
39 #include <asm/system.h>
42 static struct mouse_status mouse
;
44 static void ms_mouse_interrupt(int unused
)
47 unsigned char buttons
;
49 outb(MS_MSE_COMMAND_MODE
, MS_MSE_CONTROL_PORT
);
50 outb((inb(MS_MSE_DATA_PORT
) | 0x20), MS_MSE_DATA_PORT
);
52 outb(MS_MSE_READ_X
, MS_MSE_CONTROL_PORT
);
53 dx
= inb(MS_MSE_DATA_PORT
);
55 outb(MS_MSE_READ_Y
, MS_MSE_CONTROL_PORT
);
56 dy
= inb(MS_MSE_DATA_PORT
);
58 outb(MS_MSE_READ_BUTTONS
, MS_MSE_CONTROL_PORT
);
59 buttons
= ~(inb(MS_MSE_DATA_PORT
)) & 0x07;
61 outb(MS_MSE_COMMAND_MODE
, MS_MSE_CONTROL_PORT
);
62 outb((inb(MS_MSE_DATA_PORT
) & 0xdf), MS_MSE_DATA_PORT
);
64 if (dx
!= 0 || dy
!= 0 || buttons
!= mouse
.buttons
|| ((~buttons
) & 0x07)) {
65 mouse
.buttons
= buttons
;
69 wake_up_interruptible(&mouse
.wait
);
73 static void release_mouse(struct inode
* inode
, struct file
* file
)
76 mouse
.active
= mouse
.ready
= 0;
80 static int open_mouse(struct inode
* inode
, struct file
* file
)
87 mouse
.ready
= mouse
.dx
= mouse
.dy
= 0;
89 if (request_irq(MOUSE_IRQ
, ms_mouse_interrupt
)) {
93 outb(MS_MSE_START
, MS_MSE_CONTROL_PORT
);
99 static int write_mouse(struct inode
* inode
, struct file
* file
, char * buffer
, int count
)
104 static int read_mouse(struct inode
* inode
, struct file
* file
, char * buffer
, int count
)
112 put_fs_byte(mouse
.buttons
| 0x80, buffer
);
113 dx
= mouse
.dx
< -127 ? -127 : mouse
.dx
> 127 ? 127 : mouse
.dx
;
114 dy
= mouse
.dy
< -127 ? 127 : mouse
.dy
> 127 ? -127 : -mouse
.dy
;
115 put_fs_byte((char)dx
, buffer
+ 1);
116 put_fs_byte((char)dy
, buffer
+ 2);
117 for (i
= 3; i
< count
; i
++)
118 put_fs_byte(0x00, buffer
+ i
);
125 static int mouse_select(struct inode
*inode
, struct file
*file
, int sel_type
, select_table
* wait
)
127 if (sel_type
!= SEL_IN
)
131 select_wait(&mouse
.wait
,wait
);
135 struct file_operations ms_bus_mouse_fops
= {
136 NULL
, /* mouse_seek */
139 NULL
, /* mouse_readdir */
140 mouse_select
, /* mouse_select */
141 NULL
, /* mouse_ioctl */
142 NULL
, /* mouse_mmap */
147 unsigned long ms_bus_mouse_init(unsigned long kmem_start
)
151 mouse
.present
= mouse
.active
= mouse
.ready
= 0;
152 mouse
.buttons
= 0x80;
153 mouse
.dx
= mouse
.dy
= 0;
155 if (inb_p(MS_MSE_SIGNATURE_PORT
) == 0xde) {
157 mse_byte
= inb_p(MS_MSE_SIGNATURE_PORT
);
159 for (i
= 0; i
< 4; i
++) {
160 if (inb_p(MS_MSE_SIGNATURE_PORT
) == 0xde) {
161 if (inb_p(MS_MSE_SIGNATURE_PORT
) == mse_byte
)
169 if (mouse
.present
== 0) {
173 printk("Microsoft BusMouse detected and installed.\n");