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