aboutsummaryrefslogtreecommitdiff
path: root/devices/i8042.c
diff options
context:
space:
mode:
Diffstat (limited to 'devices/i8042.c')
-rw-r--r--devices/i8042.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/devices/i8042.c b/devices/i8042.c
new file mode 100644
index 0000000..cf8c6ec
--- /dev/null
+++ b/devices/i8042.c
@@ -0,0 +1,53 @@
+/*
+ * https://wiki.osdev.org/%228042%22_PS/2_Controller
+ */
+
+#include "keyboard.h"
+#include "ps2_controller.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/io.h>
+
+// r status register
+// w command register
+#define comm_port 0x64
+#define comm_enable_first_ps2 0xae
+#define comm_read_ctrl_config 0x20
+#define comm_write_ctrl_config 0x60
+
+#define data_port 0x60
+#define data_enable_scanning 0xf4
+
+void
+ps2_ctrl_init()
+{
+ // eat all previous keystrikes
+ while (inb(comm_port) & 0x1) inb(data_port);
+
+ uint8_t test;
+ outb(0xaa, comm_port);
+ test = inb(data_port);
+ printf("i8042: self test 0xaa:%x %s\n", test, test == 0x55 ? "ok" : "failed");
+ outb(0xab, comm_port);
+ test = inb(data_port);
+ printf("i8042: port1 test 0xab:%x %s\n", test, test == 0x00 ? "ok" : "failed");
+ outb(0xa9, comm_port);
+ test = inb(data_port);
+ printf("i8042: port2 test 0xa9:%x %s\n", test, test == 0x00 ? "ok" : "failed");
+
+ // printf("8042: init keyboard\n");
+
+ outb(comm_enable_first_ps2, comm_port);
+ outb(comm_read_ctrl_config, comm_port);
+ const uint8_t conf = (inb(data_port) | 1) & ~0x10;
+ outb(comm_write_ctrl_config, comm_port);
+
+ outb(conf, data_port);
+ outb(data_enable_scanning, data_port);
+}
+
+unsigned char
+kbd_read_next()
+{
+ return inb(data_port);
+}