blob: 442fa18635777f81d7d623728d4e8aec43ea56d8 [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "keyboard_chardev.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static struct keyboard_state kb_state;
static keycode_state_t kc_state;
void
keyboard_cdev_handle_led_changed(void *cookie)
{
/* Update LED states. */
keyboard_set_led(&kb_state, kc_state.scroll_lock, kc_state.num_lock, kc_state.caps_lock);
kc_state.led_state_changed = false;
}
static int
keyboard_getchar(struct ps_chardevice *device)
{
keyboard_key_event_t ev = keyboard_poll_ps2_keyevent(&kb_state);
return keycode_process_vkey_event_to_char(&kc_state, ev.vkey, ev.pressed, NULL);
}
static ssize_t
keyboard_write(ps_chardevice_t* d, const void* vdata, size_t count, chardev_callback_t rcb UNUSED,
void* token UNUSED)
{
/* Keyboard has no write support. */
return 0;
}
static ssize_t
keyboard_read(ps_chardevice_t* d, void* vdata, size_t count, chardev_callback_t rcb UNUSED,
void* token UNUSED)
{
int ret;
int i;
char* data = (char*) vdata;
for (i = 0; i < count; i++) {
ret = keyboard_getchar(d);
if (ret != EOF) {
*data++ = ret;
} else {
return i;
}
}
return count;
}
static void
keyboard_handle_irq(ps_chardevice_t* device UNUSED)
{
/* No IRQ handling required here. */
}
int
keyboard_cdev_init(const struct dev_defn* defn, const ps_io_ops_t* ops, ps_chardevice_t* dev)
{
memset(dev, 0, sizeof(*dev));
/* Set up all the device properties. */
dev->id = defn->id;
dev->vaddr = (void*) NULL; /* Save the IO port base number. */
dev->read = &keyboard_read;
dev->write = &keyboard_write;
dev->handle_irq = &keyboard_handle_irq;
dev->irqs = defn->irqs;
dev->ioops = *ops;
/* Initialise keyboard drivers. */
if (keyboard_init(&kb_state, ops, NULL)) {
return -1;
}
/* Initialise keycode. */
keycode_init(&kc_state, NULL, NULL,
keyboard_cdev_handle_led_changed);
/* Set initial LED state. */
keyboard_cdev_handle_led_changed(NULL);
return 0;
}