mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:38:10 +00:00
Kernel: Add support for the PS/2 mouse wheel if detected.
This commit is contained in:
parent
852d648912
commit
dae8eb6454
3 changed files with 78 additions and 17 deletions
|
@ -10,6 +10,11 @@
|
|||
#define I8042_MOUSE_BUFFER 0x20
|
||||
#define I8042_KEYBOARD_BUFFER 0x00
|
||||
|
||||
#define PS2MOUSE_GET_DEVICE_ID 0xF2
|
||||
#define PS2MOUSE_SET_SAMPLE_RATE 0xF3
|
||||
|
||||
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
||||
|
||||
//#define PS2MOUSE_DEBUG
|
||||
|
||||
static PS2MouseDevice* s_the;
|
||||
|
@ -40,6 +45,21 @@ void PS2MouseDevice::handle_irq()
|
|||
|
||||
byte data = IO::in8(I8042_BUFFER);
|
||||
m_data[m_data_state] = data;
|
||||
|
||||
auto commit_packet = [&] {
|
||||
m_data_state = 0;
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("PS2Mouse: %d, %d %s %s (buffered: %u)\n",
|
||||
m_data[1],
|
||||
m_data[2],
|
||||
(m_data[0] & 1) ? "Left" : "",
|
||||
(m_data[0] & 2) ? "Right" : "",
|
||||
m_queue.size()
|
||||
);
|
||||
#endif
|
||||
parse_data_packet();
|
||||
};
|
||||
|
||||
switch (m_data_state) {
|
||||
case 0:
|
||||
if (!(data & 0x08)) {
|
||||
|
@ -52,17 +72,15 @@ void PS2MouseDevice::handle_irq()
|
|||
++m_data_state;
|
||||
break;
|
||||
case 2:
|
||||
m_data_state = 0;
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("PS2Mouse: %d, %d %s %s (buffered: %u)\n",
|
||||
m_data[1],
|
||||
m_data[2],
|
||||
(m_data[0] & 1) ? "Left" : "",
|
||||
(m_data[0] & 2) ? "Right" : "",
|
||||
m_queue.size()
|
||||
);
|
||||
#endif
|
||||
parse_data_packet();
|
||||
if (m_has_wheel) {
|
||||
++m_data_state;
|
||||
break;
|
||||
}
|
||||
commit_packet();
|
||||
break;
|
||||
case 3:
|
||||
ASSERT(m_has_wheel);
|
||||
commit_packet();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +90,9 @@ void PS2MouseDevice::parse_data_packet()
|
|||
{
|
||||
int x = m_data[1];
|
||||
int y = m_data[2];
|
||||
int z = 0;
|
||||
if (m_has_wheel)
|
||||
z = (char)m_data[3];
|
||||
bool x_overflow = m_data[0] & 0x40;
|
||||
bool y_overflow = m_data[0] & 0x80;
|
||||
bool x_sign = m_data[0] & 0x10;
|
||||
|
@ -87,7 +108,9 @@ void PS2MouseDevice::parse_data_packet()
|
|||
MousePacket packet;
|
||||
packet.dx = x;
|
||||
packet.dy = y;
|
||||
packet.dz = z;
|
||||
packet.buttons = m_data[0] & 0x07;
|
||||
|
||||
m_queue.enqueue(packet);
|
||||
}
|
||||
|
||||
|
@ -119,17 +142,52 @@ void PS2MouseDevice::initialize()
|
|||
|
||||
// Set default settings.
|
||||
mouse_write(0xf6);
|
||||
byte ack1 = mouse_read();
|
||||
ASSERT(ack1 == 0xfa);
|
||||
expect_ack();
|
||||
|
||||
// Enable.
|
||||
mouse_write(0xf4);
|
||||
byte ack2 = mouse_read();
|
||||
ASSERT(ack2 == 0xfa);
|
||||
expect_ack();
|
||||
|
||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
||||
expect_ack();
|
||||
byte device_id = mouse_read();
|
||||
|
||||
if (device_id != PS2MOUSE_INTELLIMOUSE_ID) {
|
||||
// Send magical wheel initiation sequence.
|
||||
mouse_write(PS2MOUSE_SET_SAMPLE_RATE);
|
||||
expect_ack();
|
||||
mouse_write(200);
|
||||
expect_ack();
|
||||
mouse_write(PS2MOUSE_SET_SAMPLE_RATE);
|
||||
expect_ack();
|
||||
mouse_write(100);
|
||||
expect_ack();
|
||||
mouse_write(PS2MOUSE_SET_SAMPLE_RATE);
|
||||
expect_ack();
|
||||
mouse_write(80);
|
||||
expect_ack();
|
||||
|
||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
||||
expect_ack();
|
||||
device_id = mouse_read();
|
||||
}
|
||||
|
||||
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||
m_has_wheel = true;
|
||||
kprintf("PS2MouseDevice: Mouse wheel enabled!\n");
|
||||
} else {
|
||||
kprintf("PS2MouseDevice: No mouse wheel detected!\n");
|
||||
}
|
||||
|
||||
enable_irq();
|
||||
}
|
||||
|
||||
void PS2MouseDevice::expect_ack()
|
||||
{
|
||||
byte data = mouse_read();
|
||||
ASSERT(data == I8042_ACK);
|
||||
}
|
||||
|
||||
void PS2MouseDevice::prepare_for_input()
|
||||
{
|
||||
for (;;) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue