/* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021-2023, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include #include #include #include namespace Kernel { void PS2KeyboardDevice::handle_byte_read_from_serial_input(u8 byte) { u8 ch = byte & 0x7f; bool pressed = !(byte & 0x80); if (byte == 0xe0) { m_has_e0_prefix = true; return; } ScanCodeEvent event {}; event.pressed = pressed; event.e0_prefix = m_has_e0_prefix; m_has_e0_prefix = false; dbgln_if(KEYBOARD_DEBUG, "Keyboard::handle_byte_read_from_serial_input: {:#02x} {}", ch, (pressed ? "down" : "up")); event.scan_code_value = ch; m_keyboard_device->handle_scan_code_input_event(event); } UNMAP_AFTER_INIT ErrorOr> PS2KeyboardDevice::try_to_initialize(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, KeyboardDevice const& keyboard_device) { auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) PS2KeyboardDevice(serial_io_controller, port_index, keyboard_device))); TRY(device->initialize()); return device; } UNMAP_AFTER_INIT ErrorOr PS2KeyboardDevice::initialize() { ErrorOr err = attached_controller().reset_device(attached_port_index()); if (err.is_error()) { TRY(attached_controller().send_command(attached_port_index(), SerialIOController::DeviceCommand::GetDeviceID)); ErrorOr res = attached_controller().read_from_device(attached_port_index()); if (res.is_error()) { return err; } switch (res.value()) { // Regular and NCD Sun keyboards. case 0xab: case 0xac: // Trust keyboard, raw and translated case 0x2b: case 0x5d: // NMB SGI keyboard, raw and translated case 0x60: case 0x47: return {}; } } return err; } // FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices // are hot pluggable. UNMAP_AFTER_INIT PS2KeyboardDevice::PS2KeyboardDevice(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, KeyboardDevice const& keyboard_device) : SerialIODevice(serial_io_controller, port_index) , m_keyboard_device(keyboard_device) { } // FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices // are hot pluggable. UNMAP_AFTER_INIT PS2KeyboardDevice::~PS2KeyboardDevice() = default; }