This source file includes following definitions.
- mouse_interrupt
- fasync_mouse
- release_mouse
- open_mouse
- write_mouse
- read_mouse
- mouse_select
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifdef MODULE
14 #include <linux/module.h>
15 #include <linux/version.h>
16 #else
17 #define MOD_INC_USE_COUNT
18 #define MOD_DEC_USE_COUNT
19 #endif
20
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/signal.h>
24 #include <linux/errno.h>
25 #include <linux/mouse.h>
26
27 #include <asm/io.h>
28 #include <asm/segment.h>
29 #include <asm/system.h>
30 #include <asm/irq.h>
31
32 #define ATIXL_MOUSE_IRQ 5
33 #define ATIXL_BUSMOUSE 3
34
35
36
37 #define ATIXL_MSE_DATA_PORT 0x23d
38 #define ATIXL_MSE_SIGNATURE_PORT 0x23e
39 #define ATIXL_MSE_CONTROL_PORT 0x23c
40
41 #define ATIXL_MSE_READ_BUTTONS 0x00
42 #define ATIXL_MSE_READ_X 0x01
43 #define ATIXL_MSE_READ_Y 0x02
44
45
46
47
48 #define ATIXL_MSE_DISABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
49 outb( (0x20 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
50
51
52 #define ATIXL_MSE_ENABLE_UPDATE() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
53 outb( (0xdf & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
54
55
56 #define ATIXL_MSE_INT_OFF() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
57 outb( (0xe7 & inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
58
59
60 #define ATIXL_MSE_INT_ON() { outb( 0x07, ATIXL_MSE_CONTROL_PORT ); \
61 outb( (0x08 | inb( ATIXL_MSE_DATA_PORT )), ATIXL_MSE_DATA_PORT ); }
62
63
64
65 static struct mouse_status {
66 char buttons;
67 char latch_buttons;
68 int dx;
69 int dy;
70 int present;
71 int ready;
72 int active;
73 struct wait_queue *wait;
74 struct fasync_struct *fasync;
75 } mouse;
76
77 void mouse_interrupt(int irq, struct pt_regs * regs)
78 {
79 char dx, dy, buttons;
80
81 ATIXL_MSE_DISABLE_UPDATE();
82 outb(ATIXL_MSE_READ_X, ATIXL_MSE_CONTROL_PORT);
83 dx = inb( ATIXL_MSE_DATA_PORT);
84 outb(ATIXL_MSE_READ_Y, ATIXL_MSE_CONTROL_PORT);
85 dy = inb( ATIXL_MSE_DATA_PORT);
86 outb(ATIXL_MSE_READ_BUTTONS, ATIXL_MSE_CONTROL_PORT);
87 buttons = inb( ATIXL_MSE_DATA_PORT);
88 if (dx != 0 || dy != 0 || buttons != mouse.latch_buttons) {
89 mouse.latch_buttons |= buttons;
90 mouse.dx += dx;
91 mouse.dy += dy;
92 mouse.ready = 1;
93 wake_up_interruptible(&mouse.wait);
94 if (mouse.fasync)
95 kill_fasync(mouse.fasync, SIGIO);
96 }
97 ATIXL_MSE_ENABLE_UPDATE();
98 }
99
100 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
101 {
102 int retval;
103
104 retval = fasync_helper(inode, filp, on, &mouse.fasync);
105 if (retval < 0)
106 return retval;
107 return 0;
108 }
109
110 static void release_mouse(struct inode * inode, struct file * file)
111 {
112 ATIXL_MSE_INT_OFF();
113 mouse.active = 0;
114 mouse.ready = 0;
115 free_irq(ATIXL_MOUSE_IRQ);
116 fasync_mouse(inode, file, 0);
117 }
118
119 static int open_mouse(struct inode * inode, struct file * file)
120 {
121 if (!mouse.present)
122 return -EINVAL;
123 if (mouse.active)
124 return -EBUSY;
125 mouse.active = 1;
126 mouse.ready = 0;
127 mouse.dx = 0;
128 mouse.dy = 0;
129 mouse.buttons = mouse.latch_buttons = 0;
130 if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse")) {
131 mouse.active = 0;
132 return -EBUSY;
133 }
134 ATIXL_MSE_INT_ON();
135 return 0;
136 }
137
138
139 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
140 {
141 return -EINVAL;
142 }
143
144 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
145 {
146 int i;
147
148 if (count < 3)
149 return -EINVAL;
150 if (!mouse.ready)
151 return -EAGAIN;
152 ATIXL_MSE_DISABLE_UPDATE();
153
154 put_user((char)(~mouse.latch_buttons&7) | 0x80 , buffer);
155 if (mouse.dx < -127)
156 mouse.dx = -127;
157 if (mouse.dx > 127)
158 mouse.dx = 127;
159 put_user((char)mouse.dx, buffer + 1);
160 if (mouse.dy < -127)
161 mouse.dy = -127;
162 if (mouse.dy > 127)
163 mouse.dy = 127;
164 put_user((char)-mouse.dy, buffer + 2);
165 for(i = 3; i < count; i++)
166 put_user(0x00, buffer + i);
167 mouse.dx = 0;
168 mouse.dy = 0;
169 mouse.latch_buttons = mouse.buttons;
170 mouse.ready = 0;
171 ATIXL_MSE_ENABLE_UPDATE();
172 return i;
173 }
174
175 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
176 {
177 if (sel_type != SEL_IN)
178 return 0;
179 if (mouse.ready)
180 return 1;
181 select_wait(&mouse.wait,wait);
182 return 0;
183 }
184
185 struct file_operations atixl_busmouse_fops = {
186 NULL,
187 read_mouse,
188 write_mouse,
189 NULL,
190 mouse_select,
191 NULL,
192 NULL,
193 open_mouse,
194 release_mouse,
195 NULL,
196 fasync_mouse,
197 };
198
199 static struct mouse atixl_mouse = {
200 ATIXL_BUSMOUSE, "atixl", &atixl_busmouse_fops
201 };
202
203 #ifdef MODULE
204 char kernel_version[] = UTS_RELEASE;
205
206 int init_module(void)
207 #else
208 unsigned long atixl_busmouse_init(unsigned long kmem_start)
209 #endif
210 {
211 unsigned char a,b,c;
212
213 a = inb( ATIXL_MSE_SIGNATURE_PORT );
214 b = inb( ATIXL_MSE_SIGNATURE_PORT );
215 c = inb( ATIXL_MSE_SIGNATURE_PORT );
216 if (( a != b ) && ( a == c ))
217 printk("\nATI Inport ");
218 else{
219 mouse.present = 0;
220 #ifdef MODULE
221 return -EIO;
222 #else
223 return kmem_start;
224 #endif
225 }
226 outb(0x80, ATIXL_MSE_CONTROL_PORT);
227 outb(0x07, ATIXL_MSE_CONTROL_PORT);
228 outb(0x0a, ATIXL_MSE_DATA_PORT);
229 mouse.present = 1;
230 mouse.active = 0;
231 mouse.ready = 0;
232 mouse.buttons = mouse.latch_buttons = 0;
233 mouse.dx = mouse.dy = 0;
234 mouse.wait = NULL;
235 printk("Bus mouse detected and installed.\n");
236 mouse_register(&atixl_mouse);
237 #ifdef MODULE
238 return 0;
239 #else
240 return kmem_start;
241 #endif
242 }
243
244 #ifdef MODULE
245 void cleanup_module(void)
246 {
247 if (MOD_IN_USE)
248 printk("atixlmouse: in use, remove delayed\n");
249 mouse_deregister(&atixl_mouse);
250 }
251 #endif