3 * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #define PS2MOUSE_SAMPLES 0x64 // Samples in second - 0x50 for 80, 0x64 for 100, 0xC8 for 200
28 #define PS2MOUSE_RESOLUTION 2
30 #define PS2MOUSE_TIMEOUT 500000
31 #define PS2MOUSE_ACK 0xFA
32 #define PS2MOUSE_PORT 0x60
33 #define PS2MOUSE_CTRL 0x64
34 #define PS2MOUSE_COMMAND 0xD4
35 #define PS2MOUSE_COMMAND_RESET 0xFF
36 #define PS2MOUSE_COMMAND_GET_MOUSE_ID 0xF2
37 #define PS2MOUSE_COMMAND_GET_PACKET 0xEB
38 #define PS2MOUSE_COMMAND_ENABLE_PACKETS 0xF4
39 #define PS2MOUSE_COMMAND_SET_SAMPLERATE 0xF3
40 #define PS2MOUSE_COMMAND_SET_RESOLUTION 0xE8
41 #define PS2MOUSE_COMMAND_SET_REMOTE 0xF0
42 #define PS2MOUSE_RESET_ACK 0xAA
43 #define PS2MOUSE_IRQ 12
45 #define PS2MOUSE_SAMPLERATE_80 0x50
46 #define PS2MOUSE_SAMPLERATE_100 0x64
47 #define PS2MOUSE_SAMPLERATE_200 0xC8
49 #define PS2MOUSE_SAMPLERATE PS2MOUSE_SAMPLERATE_100
52 bool ps2mouse_extwheel
= 0;
53 bool ps2mouse_extbuttons
= 0;
57 dev_mouse_t ps2mouse_state
;
59 bool ps2mouse_reset ();
60 bool ps2mouse_write (unsigned char command
);
61 short ps2mouse_read ();
63 /* ps2mouse_reset - reset mouse */
65 bool ps2mouse_reset ()
69 for (timeout
= 0; timeout
< PS2MOUSE_TIMEOUT
; timeout
++)
71 if((inb (PS2MOUSE_CTRL
) && 0x02) != 0x02)
76 outb (PS2MOUSE_CTRL
, PS2MOUSE_COMMAND
);
77 outb (PS2MOUSE_PORT
, PS2MOUSE_COMMAND_RESET
);
79 for (timeout
= 0; timeout
< PS2MOUSE_TIMEOUT
; timeout
++)
81 int read
= ps2mouse_read ();
82 if (read
== PS2MOUSE_RESET_ACK
)
94 /* ps2mouse_write - send a command to mouse */
96 bool ps2mouse_write (unsigned char command
)
100 for (timeout
= 0; timeout
< PS2MOUSE_TIMEOUT
; timeout
++)
102 if((inb (PS2MOUSE_CTRL
) && 0x02) != 0x02)
107 outb (PS2MOUSE_CTRL
, PS2MOUSE_COMMAND
);
108 outb (PS2MOUSE_PORT
, command
);
110 short read
= ps2mouse_read ();
112 if (read
== PS2MOUSE_ACK
)
121 /* ps2mouse_read - read a value from mouse */
123 short ps2mouse_read()
127 for (timeout
= 0; timeout
< PS2MOUSE_TIMEOUT
; timeout
++)
129 if ((inb (PS2MOUSE_CTRL
) && 0x01) == 0x01)
130 return inb (PS2MOUSE_PORT
);
137 /* ps2mouse_get_state - get a mouse state */
139 bool ps2mouse_get_state ()
141 unsigned char b1
, b2
, b3
, b4
= 0;
143 if (ps2mouse_write (PS2MOUSE_COMMAND_GET_PACKET
) == -1)
146 b1
= ps2mouse_read ();
147 b2
= ps2mouse_read ();
148 b3
= ps2mouse_read ();
150 if (ps2mouse_extwheel
|| ps2mouse_extbuttons
)
151 b4
= ps2mouse_read ();
153 ps2mouse_state
.flags
= 0;
154 ps2mouse_state
.flags
|= ((b1
& 1) ? MOUSE_FLAG_BUTTON1
: 0);
155 ps2mouse_state
.flags
|= ((b1
& 2) ? MOUSE_FLAG_BUTTON2
: 0);
156 ps2mouse_state
.flags
|= ((b1
& 3) ? MOUSE_FLAG_BUTTON3
: 0);
157 ps2mouse_state
.flags
|= ((b1
& 4) ? MOUSE_FLAG_BUTTON4
: 0);
158 ps2mouse_state
.flags
|= ((b1
& 5) ? MOUSE_FLAG_BUTTON5
: 0);
162 dx
= (b1
& 0x10) ? b2
- 256 : b2
;
163 dy
= (b1
& 0x20) ? -(b3
- 256) : -b3
;
164 dz
= (b4
& 0x08) ? (b4
& 7) - 8 : b4
& 7;
166 if (dx
> 5 || dx
< -5)
168 if (dy
> 5 || dy
< -5)
171 ps2mouse_state
.pos_x
= dx
;
172 ps2mouse_state
.pos_y
= dy
;
175 ps2mouse_state
.flags
= ps2mouse_state
.flags
| MOUSE_FLAG_SCROLLUP
;
177 ps2mouse_state
.flags
= ps2mouse_state
.flags
| MOUSE_FLAG_SCROLLDOWN
;
182 void ps2mouse_get_mouseid ()
184 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
185 ps2mouse_write (PS2MOUSE_SAMPLERATE_200
);
187 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
188 ps2mouse_write (PS2MOUSE_SAMPLERATE_100
);
190 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
191 ps2mouse_write (PS2MOUSE_SAMPLERATE_80
);
193 ps2mouse_write (PS2MOUSE_COMMAND_GET_MOUSE_ID
);
194 mouse_id
= ps2mouse_read ();
199 ps2mouse_extwheel
= true;
201 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
202 ps2mouse_write (PS2MOUSE_SAMPLERATE_200
);
204 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
205 ps2mouse_write (PS2MOUSE_SAMPLERATE_200
);
207 ps2mouse_write (PS2MOUSE_COMMAND_SET_SAMPLERATE
);
208 ps2mouse_write (PS2MOUSE_SAMPLERATE_80
);
210 ps2mouse_write (PS2MOUSE_COMMAND_GET_MOUSE_ID
);
211 mouse_id
= ps2mouse_read ();
214 ps2mouse_extbuttons
= true;
217 unsigned ps2mouse_init ()
221 ps2mouse_extbuttons
= false;
222 ps2mouse_extwheel
= false;
224 if(ps2mouse_reset () == 0)
227 ps2mouse_read (); // Mouse send her ID
229 ps2mouse_get_mouseid ();
234 ps2mouse_write (PS2MOUSE_COMMAND_SET_REMOTE
);
235 ps2mouse_write (PS2MOUSE_COMMAND_ENABLE_PACKETS
);
240 bool ps2mouse_acthandler (unsigned act
, char *block
, unsigned block_len
)
245 return ps2mouse_init ();
250 if(!ps2mouse_get_state ())
252 memcpy (block
, &ps2mouse_state
, sizeof (dev_mouse_t
));