123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /*
- * Copyright (c) 2020, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/RefCounted.h>
- #include <Kernel/Devices/HID/KeyboardDevice.h>
- #include <Kernel/Devices/HID/MouseDevice.h>
- #include <Kernel/Locking/Spinlock.h>
- namespace Kernel {
- #define I8042_BUFFER 0x60
- #define I8042_STATUS 0x64
- #define I8042_ACK 0xFA
- #define I8042_RESEND 0xFE
- #define I8042_BUFFER_FULL 0x01
- #define I8042_WHICH_BUFFER 0x20
- #define I8042_KEYBOARD_BUFFER 0x00
- #define I8042_MOUSE_BUFFER 0x20
- class I8042Controller;
- class I8042Device {
- public:
- virtual ~I8042Device() = default;
- virtual void irq_handle_byte_read(u8 byte) = 0;
- protected:
- explicit I8042Device(const I8042Controller& ps2_controller)
- : m_i8042_controller(ps2_controller)
- {
- }
- NonnullRefPtr<I8042Controller> m_i8042_controller;
- };
- class PS2KeyboardDevice;
- class PS2MouseDevice;
- class I8042Controller : public RefCounted<I8042Controller> {
- friend class PS2KeyboardDevice;
- friend class PS2MouseDevice;
- public:
- static NonnullRefPtr<I8042Controller> initialize();
- void detect_devices();
- bool reset_device(HIDDevice::Type device)
- {
- SpinlockLocker lock(m_lock);
- return do_reset_device(device);
- }
- u8 send_command(HIDDevice::Type device, u8 command)
- {
- SpinlockLocker lock(m_lock);
- return do_send_command(device, command);
- }
- u8 send_command(HIDDevice::Type device, u8 command, u8 data)
- {
- SpinlockLocker lock(m_lock);
- return do_send_command(device, command, data);
- }
- u8 read_from_device(HIDDevice::Type device)
- {
- SpinlockLocker lock(m_lock);
- return do_read_from_device(device);
- }
- void wait_then_write(u8 port, u8 data)
- {
- SpinlockLocker lock(m_lock);
- do_wait_then_write(port, data);
- }
- u8 wait_then_read(u8 port)
- {
- SpinlockLocker lock(m_lock);
- return do_wait_then_read(port);
- }
- void prepare_for_output();
- void prepare_for_input(HIDDevice::Type);
- bool irq_process_input_buffer(HIDDevice::Type);
- RefPtr<MouseDevice> mouse() const;
- RefPtr<KeyboardDevice> keyboard() const;
- private:
- I8042Controller();
- void do_drain();
- bool do_reset_device(HIDDevice::Type);
- u8 do_send_command(HIDDevice::Type type, u8 data);
- u8 do_send_command(HIDDevice::Type device, u8 command, u8 data);
- u8 do_write_to_device(HIDDevice::Type device, u8 data);
- u8 do_read_from_device(HIDDevice::Type device);
- void do_wait_then_write(u8 port, u8 data);
- u8 do_wait_then_read(u8 port);
- Spinlock<u8> m_lock;
- bool m_first_port_available { false };
- bool m_second_port_available { false };
- bool m_is_dual_channel { false };
- RefPtr<MouseDevice> m_mouse_device;
- RefPtr<KeyboardDevice> m_keyboard_device;
- };
- }
|