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