PatchworkOS  3984a1d
A non-POSIX operating system.
Loading...
Searching...
No Matches
ps2.h
Go to the documentation of this file.
1#pragma once
2
3#include <kernel/cpu/io.h>
4
5#include <kernel/cpu/irq.h>
6#include <stdbool.h>
7#include <stdint.h>
8
9/**
10 * @brief IBM Personal Computer/2 ports.
11 * @defgroup modules_drivers_ps2 PS/2
12 * @ingroup modules_drivers
13 *
14 * @see https://wiki.osdev.org/I8042_PS/2_Controller
15 * @see https://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm
16 * @{
17 */
18
19/**
20 * @brief Wait timeout for PS/2 controller
21 */
22#define PS2_WAIT_TIMEOUT (CLOCKS_PER_SEC / 2)
23
24/**
25 * @brief Small delay for various operations
26 */
27#define PS2_SMALL_DELAY (CLOCKS_PER_SEC / 100)
28
29/**
30 * @brief Large delay for various operations
31 */
32#define PS2_LARGE_DELAY (CLOCKS_PER_SEC / 5)
33
34/**
35 * @brief Number of retries for commands
36 */
37#define PS2_COMMAND_RETRIES 10
38
39/**
40 * @brief All known PS/2 keyboard PNP IDs.
41 *
42 * @see https://uefi.org/sites/default/files/resources/devids%20%285%29.txt
43 */
44#define PS2_KEYBOARD_PNP_IDS \
45 "PNP0300;PNP0301;PNP0302;PNP0303;PNP0304;PNP0305;PNP0306;PNP0307;PNP0308;PNP0309;PNP030A;PNP030B;PNP0320;PNP0321;" \
46 "PNP0322;PNP0323;PNP0324;PNP0325;PNP0326;PNP0327;PNP0340;PNP0341;PNP0342;PNP0343;PNP0344"
47
48/**
49 * @brief All known PS/2 mouse PNP IDs.
50 *
51 * @see https://uefi.org/sites/default/files/resources/devids%20%285%29.txt
52 */
53#define PS2_MOUSE_PNP_IDS \
54 "PNP0F00;PNP0F01;PNP0F02;PNP0F03;PNP0F04;PNP0F05;PNP0F06;PNP0F07;PNP0F08;PNP0F09;PNP0F0A;PNP0F0B;PNP0F0C;PNP0F0D;" \
55 "PNP0F0E;PNP0F0F;PNP0F10;PNP0F11;PNP0F12;PNP0F13;PNP0F14;PNP0F15;PNP0F16;PNP0F17;PNP0F18;PNP0F19;PNP0F1A;PNP0F1B;" \
56 "PNP0F1C;PNP0F1D;PNP0F1E;PNP0F1F;PNP0F20;PNP0F21;PNP0F22;PNP0F23;PNP0FFC;PNP0FFF"
57
58/**
59 * @brief PS/2 controller commands.
60 * @enum ps2_cmd_t
61 */
76
77/**
78 * @brief PS/2 controller status register bits.
79 * @enum ps2_status_bits_t
80 */
81typedef enum
82{
83 PS2_STATUS_OUT_FULL = (1 << 0), ///< Output buffer status (0 = empty, 1 = full)
84 PS2_STATUS_IN_FULL = (1 << 1), ///< Input buffer status (0 = empty, 1 = full)
86 PS2_STATUS_CMD_DATA = (1 << 3), ///< Command(1) or Data(0)
87
91
92/**
93 * @brief PS/2 controller configuration bits.
94 * @enum ps2_config_bits_t
95 */
96typedef enum
97{
98 PS2_CFG_FIRST_IRQ = (1 << 0), ///< First PS/2 port interrupt enable
99 PS2_CFG_SECOND_IRQ = (1 << 1), ///< Second PS/2 port interrupt enable
100 PS2_CFG_SYSTEM_FLAG = (1 << 2), ///< System flag (POST passed)
101 PS2_CFG_RESERVED_3 = (1 << 3), ///< Should be zero
102 PS2_CFG_FIRST_CLOCK_DISABLE = (1 << 4), ///< First PS/2 port clock disable
103 PS2_CFG_SECOND_CLOCK_DISABLE = (1 << 5), ///< Second PS/2 port clock disable
104 PS2_CFG_FIRST_TRANSLATION = (1 << 6), ///< First PS/2 port translation enable
105 PS2_CFG_RESERVED_7 = (1 << 7) ///< Should be zero
107
108/**
109 * @brief PS/2 device commands.
110 * @enum ps2_device_cmd_t
111 */
125
126/**
127 * @brief PS/2 device identifiers.
128 * @enum ps2_device_t
129 */
137
138/**
139 * @brief PS/2 device types.
140 * @enum ps2_device_type_t
141 */
150
151/**
152 * @brief PS/2 controller self-test responses.
153 * @enum ps2_self_test_response_t
154 */
160
161/**
162 * @brief PS/2 device test responses.
163 * @enum ps2_device_test_response_t
164 */
173
174/**
175 * @brief PS/2 device command responses.
176 * @enum ps2_device_response_t
177 */
178typedef enum
179{
183 PS2_DEV_RESPONSE_KBD_EXTENDED = 0xE0, ///< Indicates that the following byte is an extended scancode.
184 PS2_DEV_RESPONSE_KBD_RELEASE = 0xF0, ///< Indicates that the following byte is a key release code.
186
187/**
188 * @brief Known PS/2 device structure.
189 * @struct ps2_known_device_t
190 */
191typedef struct
192{
193 const char* pnpId;
194 const char* name;
196
197/**
198 * @brief PS/2 device information structure.
199 * @struct ps2_device_info_t
200 */
201typedef struct
202{
203 ps2_device_t device; ///< Device port.
204 const char* pnpId; ///< PNP ID of the device.
205 const char* name; ///< Human-readable name of the device.
206 irq_virt_t irq; ///< IRQ assigned to the device by ACPI.
207 bool attached; ///< The device has been attached from ACPI.
208 bool initialized; ///< The device has been initialized.
209 void* private; ///< Driver-specific private data.
211
212/**
213 * @brief Drain the PS/2 output buffer.
214 *
215 * Reads and discards any data in the PS/2 output buffer.
216 */
217void ps2_drain(void);
218
219/**
220 * @brief Wait until status bit(s) are set.
221 *
222 * @param status Status bit(s) to wait for.
223 * @return On success, `0`. On timeout, `ERR`.
224 */
226
227/**
228 * @brief Wait until status bit(s) are clear.
229 *
230 * @param status Status bit(s) to wait for.
231 * @return On success, `0`. On timeout, `ERR`.
232 */
234
235/**
236 * @brief Read from the PS/2 controllers data port.
237 *
238 * Waits for the output buffer to be full, then reads a byte from the data port.
239 *
240 * @return On success, the response byte. On failure, `ERR` and `errno` is set to:
241 * - `ETIMEOUT`: Timeout occurred while waiting for data.
242 */
243uint64_t ps2_read(void);
244
245/**
246 * @brief Read from the PS/2 controllers data port without waiting.
247 *
248 * @return On success, the response byte. On failure, `ERR` and `errno` is set to:
249 * - `EAGAIN`: No data available to read.
250 */
252
253/**
254 * @brief Write to the PS/2 controllers data port.
255 *
256 * Waits for the input buffer to be empty, then writes a byte to the data port.
257 *
258 * @param data Byte to write.
259 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
260 * - `ETIMEOUT`: Timeout occurred while waiting to write.
261 */
263
264/**
265 * @brief Send a command to the PS/2 controller without reading response.
266 *
267 * @param command Command to send.
268 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
269 * - `ETIMEOUT`: Timeout occurred while waiting to send command.
270 */
271uint64_t ps2_cmd(ps2_cmd_t command);
272
273/**
274 * @brief Send a command to the PS/2 controller and read response.
275 *
276 * @param command Command to send.
277 * @return On success, the response byte. On failure, `ERR` and `errno` is set to:
278 * - `ETIMEOUT`: Timeout occurred while waiting to send command or read data.
279 */
281
282/**
283 * @brief Send a command to the PS/2 controller and write data
284 *
285 * @param command Command to send.
286 * @param data Data to write.
287 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
288 * - `ETIMEOUT`: Timeout occurred while waiting to send command or write data.
289 */
291
292/**
293 * @brief Send a command to a PS/2 device without reading response.
294 *
295 * @param device Device to send command to.
296 * @param command Command to send.
297 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
298 * - `ETIMEOUT`: Timeout occurred while waiting to send command.
299 */
301
302/**
303 * @brief Send a command to a PS/2 device and read response.
304 *
305 * @param device Device to send command to, specified by its port.
306 * @param command Command to send.
307 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
308 * - `ETIMEOUT`: Timeout occurred while waiting to send command or read data.
309 */
311
312/**
313 * @brief Send a command and a subcommand to a PS/2 device.
314 *
315 * @param device Device to send command to, specified by its port.
316 * @param command Command to send.
317 * @param subCommand Subcommand to send.
318 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
319 * - `ETIMEOUT`: Timeout occurred while waiting to send command or subcommand.
320 */
322
323/** @} */
int64_t y
Definition main.c:153
static fd_t data
Definition dwm.c:21
uint8_t irq_virt_t
Virtual IRQ numbers.
Definition irq.h:57
uint64_t ps2_cmd(ps2_cmd_t command)
Send a command to the PS/2 controller without reading response.
Definition ps2.c:397
ps2_device_t
PS/2 device identifiers.
Definition ps2.h:131
uint64_t ps2_read(void)
Read from the PS/2 controllers data port.
Definition ps2.c:365
ps2_status_bits_t
PS/2 controller status register bits.
Definition ps2.h:82
ps2_device_test_response_t
PS/2 device test responses.
Definition ps2.h:166
ps2_cmd_t
PS/2 controller commands.
Definition ps2.h:63
ps2_config_bits_t
PS/2 controller configuration bits.
Definition ps2.h:97
uint64_t ps2_wait_until_set(ps2_status_bits_t status)
Wait until status bit(s) are set.
Definition ps2.c:335
uint64_t ps2_write(uint8_t data)
Write to the PS/2 controllers data port.
Definition ps2.c:386
uint64_t ps2_device_cmd_and_read(ps2_device_t device, ps2_device_cmd_t command)
Send a command to a PS/2 device and read response.
Definition ps2.c:530
ps2_self_test_response_t
PS/2 controller self-test responses.
Definition ps2.h:156
ps2_device_type_t
PS/2 device types.
Definition ps2.h:143
uint64_t ps2_cmd_and_read(ps2_cmd_t command)
Send a command to the PS/2 controller and read response.
Definition ps2.c:408
void ps2_drain(void)
Drain the PS/2 output buffer.
Definition ps2.c:325
uint64_t ps2_read_no_wait(void)
Read from the PS/2 controllers data port without waiting.
Definition ps2.c:375
uint64_t ps2_wait_until_clear(ps2_status_bits_t status)
Wait until status bit(s) are clear.
Definition ps2.c:350
ps2_device_cmd_t
PS/2 device commands.
Definition ps2.h:113
ps2_device_response_t
PS/2 device command responses.
Definition ps2.h:179
uint64_t ps2_device_cmd(ps2_device_t device, ps2_device_cmd_t command)
Send a command to a PS/2 device without reading response.
Definition ps2.c:488
uint64_t ps2_cmd_and_write(ps2_cmd_t command, uint8_t data)
Send a command to the PS/2 controller and write data.
Definition ps2.c:417
uint64_t ps2_device_sub_cmd(ps2_device_t device, ps2_device_cmd_t command, uint8_t subCommand)
Send a command and a subcommand to a PS/2 device.
Definition ps2.c:539
@ PS2_DEV_COUNT
Definition ps2.h:135
@ PS2_DEV_NONE
Definition ps2.h:132
@ PS2_DEV_SECOND
Definition ps2.h:134
@ PS2_DEV_FIRST
Definition ps2.h:133
@ PS2_STATUS_SYSTEM_FLAG
Definition ps2.h:85
@ PS2_STATUS_TIMEOUT_ERROR
Definition ps2.h:88
@ PS2_STATUS_PARITY_ERROR
Definition ps2.h:89
@ PS2_STATUS_IN_FULL
Input buffer status (0 = empty, 1 = full)
Definition ps2.h:84
@ PS2_STATUS_OUT_FULL
Output buffer status (0 = empty, 1 = full)
Definition ps2.h:83
@ PS2_STATUS_CMD_DATA
Command(1) or Data(0)
Definition ps2.h:86
@ PS2_DEV_TEST_DATA_STUCK_LOW
Definition ps2.h:170
@ PS2_DEV_TEST_PASS
Definition ps2.h:167
@ PS2_DEV_TEST_DATA_STUCK_HIGH
Definition ps2.h:171
@ PS2_DEV_TEST_CLOCK_STUCK_HIGH
Definition ps2.h:169
@ PS2_DEV_TEST_CLOCK_STUCK_LOW
Definition ps2.h:168
@ PS2_CMD_SECOND_TEST
Definition ps2.h:70
@ PS2_CMD_DUMP
Definition ps2.h:73
@ PS2_CMD_SECOND_WRITE
Definition ps2.h:74
@ PS2_CMD_SELF_TEST
Definition ps2.h:71
@ PS2_CMD_FIRST_ENABLE
Definition ps2.h:69
@ PS2_CMD_FIRST_DISABLE
Definition ps2.h:68
@ PS2_CMD_CFG_READ
Definition ps2.h:64
@ PS2_CMD_SECOND_ENABLE
Definition ps2.h:67
@ PS2_CMD_SECOND_DISABLE
Definition ps2.h:66
@ PS2_CMD_FIRST_TEST
Definition ps2.h:72
@ PS2_CMD_CFG_WRITE
Definition ps2.h:65
@ PS2_CFG_SECOND_IRQ
Second PS/2 port interrupt enable.
Definition ps2.h:99
@ PS2_CFG_FIRST_IRQ
First PS/2 port interrupt enable.
Definition ps2.h:98
@ PS2_CFG_RESERVED_7
Should be zero.
Definition ps2.h:105
@ PS2_CFG_SYSTEM_FLAG
System flag (POST passed)
Definition ps2.h:100
@ PS2_CFG_RESERVED_3
Should be zero.
Definition ps2.h:101
@ PS2_CFG_SECOND_CLOCK_DISABLE
Second PS/2 port clock disable.
Definition ps2.h:103
@ PS2_CFG_FIRST_CLOCK_DISABLE
First PS/2 port clock disable.
Definition ps2.h:102
@ PS2_CFG_FIRST_TRANSLATION
First PS/2 port translation enable.
Definition ps2.h:104
@ PS2_SELF_TEST_FAIL
Definition ps2.h:158
@ PS2_SELF_TEST_PASS
Definition ps2.h:157
@ PS2_DEV_TYPE_NONE
Definition ps2.h:144
@ PS2_DEV_TYPE_MOUSE_5BUTTON
Definition ps2.h:148
@ PS2_DEV_TYPE_KEYBOARD
Definition ps2.h:145
@ PS2_DEV_TYPE_MOUSE_STANDARD
Definition ps2.h:146
@ PS2_DEV_TYPE_MOUSE_SCROLL
Definition ps2.h:147
@ PS2_DEV_CMD_SET_DEFAULTS
Definition ps2.h:121
@ PS2_DEV_CMD_RESET
Definition ps2.h:123
@ PS2_DEV_CMD_IDENTIFY
Definition ps2.h:117
@ PS2_DEV_CMD_DISABLE_SCANNING
Definition ps2.h:120
@ PS2_DEV_CMD_ECHO
Definition ps2.h:114
@ PS2_DEV_CMD_SET_TYPEMATIC
Definition ps2.h:118
@ PS2_DEV_CMD_ENABLE_SCANNING
Definition ps2.h:119
@ PS2_DEV_CMD_SET_LEDS
Definition ps2.h:115
@ PS2_DEV_CMD_SET_SCANCODE_SET
Definition ps2.h:116
@ PS2_DEV_CMD_RESEND
Definition ps2.h:122
@ PS2_DEV_RESPONSE_RESEND
Definition ps2.h:181
@ PS2_DEV_RESPONSE_ACK
Definition ps2.h:180
@ PS2_DEV_RESPONSE_BAT_OK
Definition ps2.h:182
@ PS2_DEV_RESPONSE_KBD_EXTENDED
Indicates that the following byte is an extended scancode.
Definition ps2.h:183
@ PS2_DEV_RESPONSE_KBD_RELEASE
Indicates that the following byte is a key release code.
Definition ps2.h:184
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
PS/2 device information structure.
Definition ps2.h:202
bool attached
The device has been attached from ACPI.
Definition ps2.h:207
irq_virt_t irq
IRQ assigned to the device by ACPI.
Definition ps2.h:206
ps2_device_t device
Device port.
Definition ps2.h:203
bool initialized
The device has been initialized.
Definition ps2.h:208
const char * name
Human-readable name of the device.
Definition ps2.h:205
const char * pnpId
PNP ID of the device.
Definition ps2.h:204
Known PS/2 device structure.
Definition ps2.h:192
const char * pnpId
Definition ps2.h:193
const char * name
Definition ps2.h:194