mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:37:46 +00: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_RESET 0xFF
|
||||||
|
|
||||||
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
||||||
|
#define PS2MOUSE_INTELLIMOUSE_EXPLORER_ID 0x04
|
||||||
|
|
||||||
//#define PS2MOUSE_DEBUG
|
//#define PS2MOUSE_DEBUG
|
||||||
|
|
||||||
|
@ -151,6 +152,14 @@ void PS2MouseDevice::parse_data_packet()
|
||||||
packet.y = y;
|
packet.y = y;
|
||||||
packet.z = z;
|
packet.z = z;
|
||||||
packet.buttons = m_data[0] & 0x07;
|
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;
|
packet.is_relative = true;
|
||||||
#ifdef PS2MOUSE_DEBUG
|
#ifdef PS2MOUSE_DEBUG
|
||||||
dbg() << "PS2 Relative Mouse: Buttons " << String::format("%x", packet.buttons);
|
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()
|
void PS2MouseDevice::initialize_device()
|
||||||
{
|
{
|
||||||
if (!m_device_present)
|
if (!m_device_present)
|
||||||
|
@ -223,28 +247,14 @@ void PS2MouseDevice::initialize_device()
|
||||||
mouse_write(PS2MOUSE_ENABLE_PACKET_STREAMING);
|
mouse_write(PS2MOUSE_ENABLE_PACKET_STREAMING);
|
||||||
expect_ack();
|
expect_ack();
|
||||||
|
|
||||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
u8 device_id = get_device_id();
|
||||||
expect_ack();
|
|
||||||
u8 device_id = mouse_read();
|
|
||||||
|
|
||||||
if (device_id != PS2MOUSE_INTELLIMOUSE_ID) {
|
if (device_id != PS2MOUSE_INTELLIMOUSE_ID) {
|
||||||
// Send magical wheel initiation sequence.
|
// Send magical wheel initiation sequence.
|
||||||
mouse_write(PS2MOUSE_SET_SAMPLE_RATE);
|
set_sample_rate(200);
|
||||||
expect_ack();
|
set_sample_rate(100);
|
||||||
mouse_write(200);
|
set_sample_rate(80);
|
||||||
expect_ack();
|
device_id = get_device_id();
|
||||||
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) {
|
if (device_id == PS2MOUSE_INTELLIMOUSE_ID) {
|
||||||
|
@ -254,6 +264,19 @@ void PS2MouseDevice::initialize_device()
|
||||||
klog() << "PS2MouseDevice: No mouse wheel detected!";
|
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();
|
enable_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,15 @@ private:
|
||||||
u8 wait_then_read(u8 port);
|
u8 wait_then_read(u8 port);
|
||||||
void parse_data_packet();
|
void parse_data_packet();
|
||||||
void expect_ack();
|
void expect_ack();
|
||||||
|
void set_sample_rate(u8);
|
||||||
|
u8 get_device_id();
|
||||||
|
|
||||||
bool m_device_present { false };
|
bool m_device_present { false };
|
||||||
CircularQueue<MousePacket, 100> m_queue;
|
CircularQueue<MousePacket, 100> m_queue;
|
||||||
u8 m_data_state { 0 };
|
u8 m_data_state { 0 };
|
||||||
u8 m_data[4];
|
u8 m_data[4];
|
||||||
bool m_has_wheel { false };
|
bool m_has_wheel { false };
|
||||||
|
bool m_has_five_buttons { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ struct MousePacket {
|
||||||
LeftButton = 0x01,
|
LeftButton = 0x01,
|
||||||
RightButton = 0x02,
|
RightButton = 0x02,
|
||||||
MiddleButton = 0x04,
|
MiddleButton = 0x04,
|
||||||
|
BackButton = 0x08,
|
||||||
|
ForwardButton = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char buttons { 0 };
|
unsigned char buttons { 0 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue