]>
git.dujemihanovic.xyz Git - nameless-os.git/blob - kernel/drivers/input/ps2.c
5 #include <irq/interrupt.h>
7 static int was_released
= 0, is_caps
= 0;
10 int ps2_keyb_handler()
12 uint8_t scancode
= inb(PS2_DATA_PORT
);
18 if (scancode
== 0xf0) {
20 uint8_t scancode
= inb(PS2_DATA_PORT
);
21 if (scancode
== 0x12) {
26 if (scancode
== 0x12) {
31 buffer
= scancodes
[scancode
];
33 buffer
= scancodes
[scancode
] - ('a'-'A');
39 char ps2_get_keystroke()
48 uint8_t ccb
, is_2channel
, port_1_test
, port_2_test
;
50 kprint("ps2: Begin initializing PS/2 controller\n", 0);
51 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_DISABLE
);
53 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_1_DISABLE
);
57 outb(PS2_CMD_STS_PORT
, PS2_CMD_READ_CCB
);
59 ccb
= inb(PS2_DATA_PORT
);
66 outb(PS2_CMD_STS_PORT
, PS2_CMD_WRITE_CCB
);
68 outb(PS2_DATA_PORT
, ccb
);
71 outb(PS2_CMD_STS_PORT
, PS2_CMD_CONTROLLER_TEST
);
73 if (inb(PS2_DATA_PORT
) != PS2_CONTROLLER_GOOD
) {
74 kprint("ps2: Controller self test failed, exiting!\n", 0);
79 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_ENABLE
);
81 outb(PS2_CMD_STS_PORT
, PS2_CMD_READ_CCB
);
83 ccb
= inb(PS2_DATA_PORT
);
85 if (ccb
& PORT_2_CLK
!= PORT_2_CLK
) {
87 kprint("ps2: Controller is single-channel\n", 0);
90 kprint("ps2: Controller is dual-channel\n", 0);
92 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_DISABLE
);
96 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_1_TEST
);
99 if (inb(PS2_DATA_PORT
) != 0) {
101 kprint("ps2: Port 1 test failed!\n", 0);
103 kprint("ps2: No functional port, exiting!\n", 0);
106 } else port_1_test
= 1;
110 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_TEST
);
113 if (inb(PS2_DATA_PORT
) != 0) {
115 kprint("ps2: Port 2 test failed!", 0);
117 kprint("ps2: No functional port, exiting!\n", 0);
120 } else port_2_test
= 1;
123 if (port_1_test
) { ps2_input_wait(); outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_1_ENABLE
); }
124 if (port_2_test
) { ps2_input_wait(); outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_ENABLE
); }
126 int dev_1_test
, dev_2_test
;
133 outb(PS2_DATA_PORT
, PS2_DEV_RESET
);
135 resp
= inb(PS2_DATA_PORT
);
136 } while (resp
== RESEND
);
138 if (resp
== SELF_TEST_BAD
|| resp
== SELF_TEST_BAD_2
) {
140 kprint("ps2: Port 1 device self test failed!\n", 0);
142 kprint("ps2: No functioning devices, exiting!\n", 0);
145 } else { dev_1_test
= 1; kprint("ps2: Port 1 device test successful\n", 0); }
156 outb(PS2_CMD_STS_PORT
, PS2_CMD_PORT_2_WRITE
);
158 outb(PS2_DATA_PORT
, PS2_DEV_RESET
);
160 resp
= inb(PS2_DATA_PORT
);
161 } while (resp
== RESEND
);
163 if (resp
== SELF_TEST_BAD
|| resp
== SELF_TEST_BAD_2
) {
165 kprint("ps2: Port 2 device self test failed!\n", 0);
167 kprint("ps2: No functioning devices, exiting!\n", 0);
170 } else { dev_2_test
= 1; kprint("ps2: Port 2 device test successful\n", 0); }
176 outb(PS2_CMD_STS_PORT
, PS2_CMD_READ_CCB
);
178 ccb
= inb(PS2_DATA_PORT
);
180 SET(ccb
, PORT_1_IRQ
);
183 outb(PS2_CMD_STS_PORT
, PS2_CMD_WRITE_CCB
);
185 outb(PS2_DATA_PORT
, ccb
);
187 if (dev_1_test
) register_interrupt(33, &ps2_keyb_handler
);
189 if (dev_2_test
&& dev_1_test
) return 1;
193 void ps2_output_wait()
196 status
= inb(PS2_CMD_STS_PORT
);
198 while (!IS_SET(status
, OUT_STATUS
)) status
= inb(PS2_CMD_STS_PORT
);
202 void ps2_input_wait()
205 status
= inb(PS2_CMD_STS_PORT
);
207 while (IS_SET(status
, IN_STATUS
)) status
= inb(PS2_CMD_STS_PORT
);