2
* Copyright (c) 2009 Vineeth Pillai
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
/** @addtogroup genarch
34
* @brief pl050 Keyboard processing.
37
#include <genarch/kbrd/kbrd.h>
38
#include <genarch/kbrd/scanc.h>
40
#include <genarch/kbrd/scanc_pl050.h>
42
#include <synch/spinlock.h>
43
#include <console/chardev.h>
44
#include <console/console.h>
45
#include <proc/thread.h>
49
#define PRESSED_SHIFT (1 << 0)
50
#define PRESSED_CAPSLOCK (1 << 1)
51
#define LOCKED_CAPSLOCK (1 << 0)
53
#define PL050_KEY_RELEASE 0xF0
54
#define PL050_ESC_KEY 0xE0
55
#define PL050_CAPS_SCAN_CODE 0x58
56
#define PL050_NUM_SCAN_CODE 0x77
57
#define PL050_SCROLL_SCAN_CODE 0x7E
59
static bool is_lock_key(wchar_t);
61
static indev_operations_t kbrd_raw_ops = {
65
/** Process release of key.
67
* @param sc Scancode of the key being released.
69
static void key_released(kbrd_instance_t *instance, wchar_t sc)
71
spinlock_lock(&instance->keylock);
76
instance->keyflags &= ~PRESSED_SHIFT;
79
instance->keyflags &= ~PRESSED_CAPSLOCK;
80
if (instance->lockflags & LOCKED_CAPSLOCK)
81
instance->lockflags &= ~LOCKED_CAPSLOCK;
83
instance->lockflags |= LOCKED_CAPSLOCK;
89
spinlock_unlock(&instance->keylock);
94
* @param sc Scancode of the key being pressed.
96
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
102
spinlock_lock(&instance->keylock);
107
instance->keyflags |= PRESSED_SHIFT;
110
instance->keyflags |= PRESSED_CAPSLOCK;
115
letter = islower(sc_primary_map[sc]);
116
shift = instance->keyflags & PRESSED_SHIFT;
117
capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
118
(instance->lockflags & LOCKED_CAPSLOCK);
120
if ((letter) && (capslock))
124
indev_push_character(instance->sink, sc_secondary_map[sc]);
126
indev_push_character(instance->sink, sc_primary_map[sc]);
130
spinlock_unlock(&instance->keylock);
133
static void kkbrd(void *arg)
135
static int key_released_flag = 0;
136
static int is_locked = 0;
137
kbrd_instance_t *instance = (kbrd_instance_t *) arg;
140
wchar_t sc = indev_pop_character(&instance->raw);
142
if (sc == PL050_KEY_RELEASE) {
143
key_released_flag = 1;
145
if (key_released_flag) {
146
key_released_flag = 0;
147
if (is_lock_key(sc)) {
155
key_released(instance, sc);
158
if (is_lock_key(sc) && is_locked)
160
key_pressed(instance, sc);
167
kbrd_instance_t *kbrd_init(void)
169
kbrd_instance_t *instance
170
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
173
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
175
if (!instance->thread) {
180
instance->sink = NULL;
181
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
183
spinlock_initialize(&instance->keylock, "instance_keylock");
184
instance->keyflags = 0;
185
instance->lockflags = 0;
191
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
196
instance->sink = sink;
197
thread_ready(instance->thread);
199
return &instance->raw;
202
static bool is_lock_key(wchar_t sc)
204
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
205
(sc == PL050_SCROLL_SCAN_CODE));