// SPDX-License-Identifier: MPL-2.0 #ifndef SH_LIB_PS2_H #define SH_LIB_PS2_H #include "std/stdlib.h" #include "devs/input/event.h" #include "devs/input/kbd.h" // Port macros #define SH_PS2_PORT_DATA 0x60 #define SH_PS2_PORT_COMMAND 0x64 // Status byte bits #define SH_PS2_STATUS_OBF 0b1 #define SH_PS2_STATUS_IBF 0b10 #define SH_PS2_STATUS_MOUSE_DATA 0b100000 #define SH_PS2_STATUS_TIMEOUT 0b1000000 #define SH_PS2_STATUS_PARITY 0b10000000 // Config byte bits #define SH_PS2_CONFIG_PORT1_IRQ 0b1 #define SH_PS2_CONFIG_PORT2_IRQ 0b10 #define SH_PS2_CONFIG_PORT1_CLOCK_DISABLED 0b10000 #define SH_PS2_CONFIG_PORT2_CLOCK_DISABLED 0b100000 #define SH_PS2_CONFIG_TRANSLATION 0b1000000 // PS2 controller commands macros #define SH_PS2_COMMAND_READ_CONFIG 0x20 #define SH_PS2_COMMAND_WRITE_CONFIG 0x60 #define SH_PS2_COMMAND_PS2_SELF_TEST 0xAA #define SH_PS2_COMMAND_PORT1_TEST 0xAB #define SH_PS2_COMMAND_PORT2_DISABLE 0xA7 #define SH_PS2_COMMAND_PORT2_ENABLE 0xA8 #define SH_PS2_COMMAND_PORT2_TEST 0xA9 #define SH_PS2_COMMAND_PORT1_DISABLE 0xAD #define SH_PS2_COMMAND_PORT1_ENABLE 0xAE #define SH_PS2_COMMAND_READ_OUTPUT 0xD0 #define SH_PS2_COMMAND_WRITE_OUTPUT 0xD1 #define SH_PS2_COMMAND_WRITE_PORT2 0xD4 // Self test results macros #define SH_PS2_SELF_TEST_SUCCESS 0x55 #define SH_PS2_SELF_TEST_FAIL 0xFC #define SH_PS2_PORTS_SELF_TEST_SUCCESS 0x00 // PS2 keyboard commands macros #define SH_PS2_KBD_COMMAND_SET_LEDS 0xED #define SH_PS2_KBD_COMMAND_ECHO 0xEE #define SH_PS2_KBD_COMMAND_SC_SET 0xF0 #define SH_PS2_KBD_COMMAND_IDENTIFY 0xF2 #define SH_PS2_KBD_COMMAND_ENABLE_SCANNING 0xF4 #define SH_PS2_KBD_COMMAND_DISABLE_SCANNING 0xF5 #define SH_PS2_KBD_COMMAND_DEFAULTS 0xF6 #define SH_PS2_KBD_COMMAND_RESET 0xFF // Leds bits #define SH_PS2_KBD_LEDS_SCROLL_LOCK 0b1 #define SH_PS2_KBD_LEDS_NUM_LOCK 0b10 #define SH_PS2_KBD_LEDS_CAPS_LOCK 0b100 // Scancodes (SC) sets #define SH_PS2_KBD_SC_SET_CURRENT 0 #define SH_PS2_KBD_SC_SET_1 1 #define SH_PS2_KBD_SC_SET_2 2 #define SH_PS2_KBD_SC_SET_3 3 // Keyboard response macros #define SH_PS2_KBD_ACK 0xFA #define SH_PS2_KBD_RESEND 0xFE #define SH_PS2_KBD_BAT_SUCCESS 0xAA #define SH_PS2_KBD_BAT_FAIL 0xFC #define SH_PS2_KBD_ECHO_REPLY 0xEE // Return SH_TRUE if data port contain useful datas to read inline sh_bool sh_ps2_output_ready() { return sh_asm_inb(SH_PS2_PORT_COMMAND) & SH_PS2_STATUS_OBF; } // Return SH_TRUE if controller isn't ready for any output inline sh_bool sh_ps2_cant_write() { return sh_asm_inb(SH_PS2_PORT_COMMAND) & SH_PS2_STATUS_IBF; } // Keyboard command struct typedef struct { sh_uint8 command; sh_uint8 data; sh_bool has_data; } sh_ps2_KBD_COMMAND; // Read status byte inline sh_uint8 sh_ps2_read_status() { return sh_asm_inb(SH_PS2_PORT_COMMAND); } // Read config byte inline sh_uint8 sh_ps2_read_config() { while (sh_ps2_cant_write()); sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_READ_CONFIG); while (!sh_ps2_output_ready()); return sh_asm_inb(SH_PS2_PORT_DATA); } // Write config byte inline void sh_ps2_write_config(sh_uint8 config) { while (sh_ps2_cant_write()); sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_WRITE_CONFIG); while (sh_ps2_cant_write()); sh_asm_outb(SH_PS2_PORT_DATA,config); } // PS2 IRQ1 handler void sh_ps2_irq1_handler(); // Send a keyboard command and wait for it to finish SH_STATUS sh_ps2_send_keyboard_command_wait(sh_uint8 cmd,sh_uint8 data,sh_bool has_data); // Initialize the PS2 driver SH_STATUS sh_ps2_driver_init(); // Disable scanning SH_STATUS sh_ps2_disable_scanning(); // Enable scanning SH_STATUS sh_ps2_enable_scanning(); #endif