mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Kernel: Detect 5-button PS/2 mouse if present :^)
The detection works very similarly to how we detect a mouse wheel, just another magical sequence of "set sample rate" requests to the mouse followed by an ID check.
This commit is contained in:
parent
c00ff4ba62
commit
c5882d3a18
3 changed files with 47 additions and 19 deletions
|
@ -52,6 +52,7 @@ namespace Kernel {
|
|||
#define PS2MOUSE_RESET 0xFF
|
||||
|
||||
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
||||
#define PS2MOUSE_INTELLIMOUSE_EXPLORER_ID 0x04
|
||||
|
||||
//#define PS2MOUSE_DEBUG
|
||||
|
||||
|
@ -151,6 +152,14 @@ void PS2MouseDevice::parse_data_packet()
|
|||
packet.y = y;
|
||||
packet.z = z;
|
||||
packet.buttons = m_data[0] & 0x07;
|
||||
|
||||
if (m_has_five_buttons) {
|
||||
if (m_data[3] & 0x10)
|
||||
packet.buttons |= MousePacket::BackButton;
|
||||
if (m_data[3] & 0x20)
|
||||
packet.buttons |= MousePacket::ForwardButton;
|
||||
}
|
||||
|
||||
packet.is_relative = true;
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbg() << "PS2 Relative Mouse: Buttons " << String::format("%x", packet.buttons);
|
||||
|
@ -201,6 +210,21 @@ void PS2MouseDevice::check_device_presence()
|
|||
}
|
||||
}
|
||||
|
||||
u8 PS2MouseDevice::get_device_id()
|
||||
{
|
||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
||||
expect_ack();
|
||||
return mouse_read();
|
||||
}
|
||||
|
||||
void PS2MouseDevice::set_sample_rate(u8 rate)
|
||||
{
|
||||
mouse_write(PS2MOUSE_SET_SAMPLE_RATE);
|
||||
expect_ack();
|
||||
mouse_write(rate);
|
||||
expect_ack();
|
||||
}
|
||||
|
||||
void PS2MouseDevice::initialize_device()
|
||||
{
|
||||
if (!m_device_present)
|
||||
|
@ -223,28 +247,14 @@ void PS2MouseDevice::initialize_device()
|
|||
mouse_write(PS2MOUSE_ENABLE_PACKET_STREAMING);
|
||||
expect_ack();
|
||||
|
||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
||||
expect_ack();
|
||||
u8 device_id = mouse_read();
|
||||
u8 device_id = get_device_id();
|
||||
|
||||
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();
|
||||
set_sample_rate(200);
|
||||
set_sample_rate(100);
|
||||
set_sample_rate(80);
|
||||
device_id = get_device_id();
|
||||
}
|
||||
|
||||
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||
|
@ -254,6 +264,19 @@ void PS2MouseDevice::initialize_device()
|
|||
klog() << "PS2MouseDevice: No mouse wheel detected!";
|
||||
}
|
||||
|
||||
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||
// Try to enable 5 buttons as well!
|
||||
set_sample_rate(200);
|
||||
set_sample_rate(200);
|
||||
set_sample_rate(80);
|
||||
device_id = get_device_id();
|
||||
}
|
||||
|
||||
if (device_id == PS2MOUSE_INTELLIMOUSE_EXPLORER_ID) {
|
||||
m_has_five_buttons = true;
|
||||
klog() << "PS2MouseDevice: 5 buttons enabled!";
|
||||
}
|
||||
|
||||
enable_irq();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,12 +68,15 @@ private:
|
|||
u8 wait_then_read(u8 port);
|
||||
void parse_data_packet();
|
||||
void expect_ack();
|
||||
void set_sample_rate(u8);
|
||||
u8 get_device_id();
|
||||
|
||||
bool m_device_present { false };
|
||||
CircularQueue<MousePacket, 100> m_queue;
|
||||
u8 m_data_state { 0 };
|
||||
u8 m_data[4];
|
||||
bool m_has_wheel { false };
|
||||
bool m_has_five_buttons { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ struct MousePacket {
|
|||
LeftButton = 0x01,
|
||||
RightButton = 0x02,
|
||||
MiddleButton = 0x04,
|
||||
BackButton = 0x08,
|
||||
ForwardButton = 0x10,
|
||||
};
|
||||
|
||||
unsigned char buttons { 0 };
|
||||
|
|
Loading…
Add table
Reference in a new issue