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