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