blob: c533a3b6f8d3582e07326120a9208110c77da32a [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "../../chardev.h"
#define KEYBOARD_PS2_IRQ 1
#define PS2_IOPORT_CONTROL 0x64
#define PS2_IOPORT_DATA 0x60
/* ref: http://www.computer-engineering.org/ps2keyboard/ */
#define PS2_CMD_DISABLE_MOUSE_INTERFACE 0xA7
#define PS2_CMD_ENABLE_MOUSE_INTERFACE 0xA8
#define PS2_CMD_CONTROLLER_SELF_TEST 0xAA
#define PS2_CMD_KEYBOARD_INTERFACE_TEST 0xAB
#define PS2_CMD_DISABLE_KEYBOARD_INTERFACE 0xAD
#define PS2_CMD_ENABLE_KEYBOARD_INTERFACE 0xAE
#define PS2_READ_CMD_BYTE 0x20
#define PS2_WRITE_CMD_BYTE 0x60
#define PS2_CONTROLLER_SELF_TEST_OK 0x55
#define KEYBOARD_RESET 0xFF
#define KEYBOARD_RESEND 0xFE
#define KEYBOARD_ACK 0xFA
#define KEYBOARD_ERROR 0xFC
#define KEYBOARD_DISABLE_SCAN 0xF5
#define KEYBOARD_ENABLE_SCAN 0xF4
#define KEYBOARD_SET_SCANCODE_MODE 0xF0
#define KEYBOARD_ECHO 0xEE
#define KEYBOARD_SET_LEDS 0xED
#define KEYBOARD_BAT_SUCCESSFUL 0xAA
#define KEYBOARD_PS2_STATE_NORMAL 0x1
#define KEYBOARD_PS2_STATE_IGNORE 0x2
#define KEYBOARD_PS2_STATE_EXTENDED_MODE 0x4
#define KEYBOARD_PS2_STATE_RELEASE_KEY 0x8
#define KEYBOARD_PS2_EVENTCODE_RELEASE 0xF0
#define KEYBOARD_PS2_EVENTCODE_EXTENDED 0xE0
#define KEYBOARD_PS2_EVENTCODE_EXTENDED_PAUSE 0xE1
typedef struct keyboard_key_event {
int16_t vkey;
bool pressed;
} keyboard_key_event_t;
/* Internal state structure which stores the book-keeping to convert from PS2 keycodes to
vkey press / release events.
This only generated press / release events given in virtual key codes; it does NOT keep the
key state machine needed to generate a stream of typed bytes from these events. This is
done by keyboard_vkey.c/h.
*/
struct keyboard_state {
ps_io_ops_t ops;
int state;
int num_ignore;
/* Callback function which gets called when there is a keyboard key event. */
void (*handle_event_callback)(keyboard_key_event_t ev, void *cookie);
};
/* ---------------------------------------------------------------------------------------------- */
/* Initialise keyboard driver state.
The handle_event_callback parameter is optional, and may be set to NULL. Events are be
returned by keyboard_poll_ps2_keyevents().
*/
int keyboard_init(struct keyboard_state *state, const ps_io_ops_t* ops,
void (*handle_event_callback)(keyboard_key_event_t ev, void *cookie));
void keyboard_set_scanmode(struct keyboard_state *state, uint8_t mode);
void keyboard_set_led(struct keyboard_state *state, char scroll_lock, char num_lock, char caps_lock);
int keyboard_reset(struct keyboard_state *state);
/* This may be called in a loop on every IRQ, until no more character events reported.
Note that this polling will NOT call the handle_event_callback on key events. */
keyboard_key_event_t keyboard_poll_ps2_keyevent(struct keyboard_state *state);
/* This may be called on every IRQ, for driver to read any key events. This function continuously
calls keyboard_poll_ps2_keyevent in a loop and invokes handle_event_callback for every key
event detected. */
void keyboard_poll_ps2_keyevents(struct keyboard_state *state, void *cookie);