74 lines
1.4 KiB
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;
|
||
|
}
|