summaryrefslogtreecommitdiff
path: root/kernel/src/drivers/ps2ctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/drivers/ps2ctrl.c')
-rw-r--r--kernel/src/drivers/ps2ctrl.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/kernel/src/drivers/ps2ctrl.c b/kernel/src/drivers/ps2ctrl.c
new file mode 100644
index 0000000..527435d
--- /dev/null
+++ b/kernel/src/drivers/ps2ctrl.c
@@ -0,0 +1,99 @@
+#include <panic.h>
+#include <sys.h>
+
+#include "print.h"
+#include "ps2ctrl.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)
+
+static bool is_init = false;
+
+uint8_t ps2ctrl_in(void) {
+ while((ps2ctrl_in_status() & STATUS_OUT_BUF) == 0) {
+ io_wait();
+ }
+ return inb(0x60);
+}
+
+uint8_t ps2ctrl_in_status(void) {
+ return inb(0x64);
+}
+
+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);
+}
+
+void ps2ctrl_set_port2(void) {
+ outb(0x64, 0xD4);
+}
+
+void ps2ctrl_init(void) {
+
+ debugk("Loading PS/2 Controller");
+
+ is_init = false;
+
+ pic_mask(1); // keyboard
+ pic_mask(12); // mouse
+
+ inb(0x60);
+
+ // self-test
+ ps2ctrl_out_cmd(0xAA);
+ uint8_t response = ps2ctrl_in();
+ if(response != 0x55) {
+ errork("PS/2 controller failed to initialize");
+ return;
+ }
+
+ // set config
+ ps2ctrl_out_cmd(0x20);
+ uint8_t config = ps2ctrl_in();
+ config = (config | CONFIG_INT_0 | CONFIG_INT_1) & ~CONFIG_TRANS;
+ // config = 0xFF;
+ ps2ctrl_out_cmd(0x60);
+ ps2ctrl_out_data(config);
+
+ // enable port 0
+ ps2ctrl_out_cmd(0xAE);
+
+ // enable port 2
+ ps2ctrl_out_cmd(0xA9);
+ response = ps2ctrl_in();
+ if (response == 0x01) {
+ errork("PS/2 port 2 not supported");
+ return;
+ }
+
+ ps2ctrl_out_cmd(0xA8);
+
+ is_init = true;
+
+ pic_unmask(1);
+ pic_unmask(12);
+
+ succek("Loaded PS/2 Controller");
+}
+
+bool ps2ctrl_is_init(void) {
+ return is_init;
+}