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