mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 22:27:35 +00:00
Kernel+Userland: Implement support for PS2 scan code set 2
This scan code set is more advanced than the basic scan code set 1, and is required to be supported for some bare metal hardware that might not properly enable the PS2 first port translation in the i8042 controller. LibWeb can now also generate bindings for keyboard events like the Pause key, as well as other function keys (such as Right Alt, etc). The logic for handling scan code sets is implemented by the PS2 keyboard driver and is abstracted from the main HID KeyboardDevice code which only handles "standard" KeyEvent(s).
This commit is contained in:
parent
60a96b3786
commit
61a385fc01
12 changed files with 982 additions and 440 deletions
|
@ -120,7 +120,7 @@ UNMAP_AFTER_INIT bool I8042Controller::check_existence_via_probing(Badge<HIDMana
|
|||
}
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<void> I8042Controller::detect_devices()
|
||||
UNMAP_AFTER_INIT ErrorOr<void> I8042Controller::detect_devices(EnableKeyboardFirstPortTranslation enable_first_port_translation)
|
||||
{
|
||||
u8 configuration;
|
||||
{
|
||||
|
@ -135,7 +135,13 @@ UNMAP_AFTER_INIT ErrorOr<void> I8042Controller::detect_devices()
|
|||
configuration = TRY(do_wait_then_read_any_input(I8042Port::Buffer));
|
||||
configuration &= ~I8042ConfigurationFlag::FirstPS2PortInterrupt;
|
||||
configuration &= ~I8042ConfigurationFlag::SecondPS2PortInterrupt;
|
||||
configuration |= I8042ConfigurationFlag::FirstPS2PortTranslation;
|
||||
|
||||
// FIXME: Don't enable translation for the first i8042 port if nothing is connected
|
||||
// or even worse - a mouse device, because we will get garbage data.
|
||||
if (enable_first_port_translation == EnableKeyboardFirstPortTranslation::Yes)
|
||||
configuration |= I8042ConfigurationFlag::FirstPS2PortTranslation;
|
||||
else
|
||||
configuration &= ~I8042ConfigurationFlag::FirstPS2PortTranslation;
|
||||
|
||||
TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration));
|
||||
TRY(do_wait_then_write(I8042Port::Buffer, configuration));
|
||||
|
@ -197,7 +203,9 @@ UNMAP_AFTER_INIT ErrorOr<void> I8042Controller::detect_devices()
|
|||
// FIXME: Actually figure out the connected PS2 device type
|
||||
m_first_ps2_port.device_type = PS2DeviceType::StandardKeyboard;
|
||||
auto keyboard_device = TRY(KeyboardDevice::try_to_initialize());
|
||||
auto error_or_device = PS2KeyboardDevice::try_to_initialize(*this, I8042PortIndex::FirstPort, *keyboard_device);
|
||||
// FIXME: Determine if the user wants to operate in scan code set 3.
|
||||
auto keyboard_device_scan_code_set = enable_first_port_translation == EnableKeyboardFirstPortTranslation::Yes ? ScanCodeSet::Set1 : ScanCodeSet::Set2;
|
||||
auto error_or_device = PS2KeyboardDevice::try_to_initialize(*this, I8042PortIndex::FirstPort, keyboard_device_scan_code_set, *keyboard_device);
|
||||
if (error_or_device.is_error()) {
|
||||
dbgln("I8042: Keyboard device failed to initialize, disable");
|
||||
m_first_port_available = false;
|
||||
|
|
|
@ -94,7 +94,12 @@ class I8042Controller final : public SerialIOController {
|
|||
public:
|
||||
static ErrorOr<NonnullRefPtr<I8042Controller>> create();
|
||||
|
||||
ErrorOr<void> detect_devices();
|
||||
enum class EnableKeyboardFirstPortTranslation {
|
||||
Yes,
|
||||
No
|
||||
};
|
||||
ErrorOr<void> detect_devices(EnableKeyboardFirstPortTranslation);
|
||||
|
||||
virtual ErrorOr<void> send_command(PortIndex, DeviceCommand command) override;
|
||||
virtual ErrorOr<void> send_command(PortIndex, DeviceCommand command, u8 data) override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue