trios/kernel/drivers/ps2ctrl.c

74 lines
1.4 KiB
C

#include <stdint.h>
#include <sys.h>
#include "ps2ctrl.h"
#include "../panic.h"
#include "../interrupt/pic.h"
#define STATUS_OUT_BUF ((uint8_t)0x01)
#define STATUS_IN_BUF ((uint8_t)0x02)
#define CONFIG_INT_0 ((uint8_t)0x01)
#define CONFIG_INT_1 ((uint8_t)0x02)
#define CONFIG_SYS ((uint8_t)0x04)
#define CONFIG_CLOCK_0 ((uint8_t)0x10)
#define CONFIG_CLOCK_1 ((uint8_t)0x20)
#define CONFIG_TRANS ((uint8_t)0x40)
uint8_t ps2ctrl_in_status(void) {
return inb(0x64);
}
uint8_t ps2ctrl_in(void) {
while((ps2ctrl_in_status() & STATUS_OUT_BUF) == 0) {
io_wait();
}
return inb(0x60);
}
void ps2ctrl_out_cmd(uint8_t cmd) {
while((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) {
io_wait();
}
outb(0x64, cmd);
}
void ps2ctrl_out_data(uint8_t data) {
while((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) {
io_wait();
}
outb(0x60, data);
}
static bool is_init = false;
void ps2ctrl_init(void) {
is_init = false;
pic_mask(1);
// clear buffer
inb(0x60);
// self-test
ps2ctrl_out_cmd(0xAA);
uint8_t response = ps2ctrl_in();
if(response != 0x55) {
panic("PS/2 controller failed to initialize");
}
// set config
ps2ctrl_out_cmd(0x20);
uint8_t config = ps2ctrl_in();
config = (config | CONFIG_INT_0) & ~CONFIG_TRANS & ~CONFIG_INT_1;
ps2ctrl_out_cmd(0x60);
ps2ctrl_out_data(config);
// enable port 0
ps2ctrl_out_cmd(0xAE);
pic_unmask(1);
is_init = true;
}
bool ps2ctrl_is_init(void) {
return is_init;
}