summaryrefslogtreecommitdiff
path: root/kernel/src/drivers/ps2ctrl.c
blob: 527435d91ca232f347d63228f6923e308214e2dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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;
}