1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15#include "../../chardev.h"
16
17#define KEYBOARD_PS2_IRQ 1
18#define PS2_IOPORT_CONTROL 0x64
19#define PS2_IOPORT_DATA 0x60
20
21/* ref: http://www.computer-engineering.org/ps2keyboard/ */
22#define PS2_CMD_DISABLE_MOUSE_INTERFACE         0xA7
23#define PS2_CMD_ENABLE_MOUSE_INTERFACE          0xA8
24#define PS2_CMD_CONTROLLER_SELF_TEST            0xAA
25#define PS2_CMD_KEYBOARD_INTERFACE_TEST         0xAB
26#define PS2_CMD_DISABLE_KEYBOARD_INTERFACE      0xAD
27#define PS2_CMD_ENABLE_KEYBOARD_INTERFACE       0xAE
28#define PS2_READ_CMD_BYTE                       0x20
29#define PS2_WRITE_CMD_BYTE                      0x60
30#define PS2_CONTROLLER_SELF_TEST_OK             0x55
31
32#define KEYBOARD_RESET                  0xFF
33#define KEYBOARD_RESEND                 0xFE
34#define KEYBOARD_ACK                    0xFA
35#define KEYBOARD_ERROR                  0xFC
36#define KEYBOARD_DISABLE_SCAN           0xF5
37#define KEYBOARD_ENABLE_SCAN            0xF4
38#define KEYBOARD_SET_SCANCODE_MODE      0xF0
39#define KEYBOARD_ECHO                   0xEE
40#define KEYBOARD_SET_LEDS               0xED
41#define KEYBOARD_BAT_SUCCESSFUL         0xAA
42
43#define KEYBOARD_PS2_STATE_NORMAL 0x1
44#define KEYBOARD_PS2_STATE_IGNORE 0x2
45#define KEYBOARD_PS2_STATE_EXTENDED_MODE 0x4
46#define KEYBOARD_PS2_STATE_RELEASE_KEY 0x8
47#define KEYBOARD_PS2_EVENTCODE_RELEASE 0xF0
48#define KEYBOARD_PS2_EVENTCODE_EXTENDED 0xE0
49#define KEYBOARD_PS2_EVENTCODE_EXTENDED_PAUSE 0xE1
50
51typedef struct keyboard_key_event {
52    int16_t vkey;
53    bool pressed;
54} keyboard_key_event_t;
55
56/* Internal state structure which stores the book-keeping to convert from PS2 keycodes to
57   vkey press / release events.
58
59   This only generated press / release events given in virtual key codes; it does NOT keep the
60   key state machine needed to generate a stream of typed bytes from these events. This is
61   done by keyboard_vkey.c/h.
62*/
63struct keyboard_state {
64    ps_io_ops_t ops;
65    int state;
66    int num_ignore;
67
68    /* Callback function which gets called when there is a keyboard key event. */
69    void (*handle_event_callback)(keyboard_key_event_t ev, void *cookie);
70};
71
72/* ---------------------------------------------------------------------------------------------- */
73
74/* Initialise keyboard driver state.
75   The handle_event_callback parameter is optional, and may be set to NULL. Events are be
76   returned by keyboard_poll_ps2_keyevents().
77*/
78int keyboard_init(struct keyboard_state *state, const ps_io_ops_t* ops,
79                  void (*handle_event_callback)(keyboard_key_event_t ev, void *cookie));
80
81void keyboard_set_scanmode(struct keyboard_state *state, uint8_t mode);
82
83void keyboard_set_led(struct keyboard_state *state, char scroll_lock, char num_lock, char caps_lock);
84
85int keyboard_reset(struct keyboard_state *state);
86
87/* This may be called in a loop on every IRQ, until no more character events reported.
88   Note that this polling will NOT call the handle_event_callback on key events. */
89keyboard_key_event_t keyboard_poll_ps2_keyevent(struct keyboard_state *state);
90
91/* This may be called on every IRQ, for driver to read any key events. This function continuously
92   calls keyboard_poll_ps2_keyevent in a loop and invokes handle_event_callback for every key
93   event detected. */
94void keyboard_poll_ps2_keyevents(struct keyboard_state *state, void *cookie);
95
96