mirror of
https://github.com/drasko/codezero.git
synced 2026-02-23 07:13:15 +01:00
KMI patch for devel branch on bahadir's repo.
Important points: ---------------- 1. Works fine for pb926 + qemu. 2. Scan code logic for kryboard is not complete. We just have generic keys and shift working. 3. Mouse scancodes are collected but not decoded. 4. Right now we are doing enable_irq(), just before we go for waiting again for new irqs. This is not correct but we had latency issues. This needs to be fixed immediately. 5. Also it seems like the notify_clot count should be an atomic variable. Needs to be discussed.
This commit is contained in:
@@ -36,6 +36,8 @@ objects += SConscript('uart/pl011/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('timer/sp804/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('kmi/pl050/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
|
||||
objects += SConscript('uart/omap/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
|
||||
26
conts/libdev/include/libdev/kmi.h
Executable file
26
conts/libdev/include/libdev/kmi.h
Executable file
@@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef __KMI_H__
|
||||
#define __KMI_H__
|
||||
|
||||
/*
|
||||
* Current keyboard state
|
||||
*/
|
||||
struct keyboard_state{
|
||||
int keyup;
|
||||
int shift;
|
||||
int caps_lock;
|
||||
};
|
||||
|
||||
/* Common functions */
|
||||
void kmi_irq_handler(unsigned long base);
|
||||
int kmi_data_read(unsigned long base);
|
||||
|
||||
/* Keyboard specific calls */
|
||||
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state);
|
||||
void kmi_keyboard_init(unsigned long base, unsigned int div);
|
||||
|
||||
/* Mouse specific calls */
|
||||
void kmi_mouse_enable(unsigned long base);
|
||||
void kmi_mouse_init(unsigned long base, unsigned int div);
|
||||
|
||||
#endif /* __KMI_H__ */
|
||||
14
conts/libdev/kmi/pl050/SConscript
Normal file
14
conts/libdev/kmi/pl050/SConscript
Normal file
@@ -0,0 +1,14 @@
|
||||
Import('env', 'platform')
|
||||
|
||||
#Platforms using pl050
|
||||
plat_list = ('eb', 'pba8', 'pba9', 'pb11mpcore', 'pb926')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = []
|
||||
|
||||
for plat_supported in plat_list:
|
||||
if plat_supported == platform:
|
||||
src_local += Glob('*.c')
|
||||
|
||||
obj = env.StaticObject(src_local)
|
||||
Return('obj')
|
||||
280
conts/libdev/kmi/pl050/keymap.h
Executable file
280
conts/libdev/kmi/pl050/keymap.h
Executable file
@@ -0,0 +1,280 @@
|
||||
|
||||
#ifndef __KEYMAP_H__
|
||||
#define __KEYMAP_H__
|
||||
|
||||
/* Special meaning keys */
|
||||
#define KEYCODE_LSHIFT 0x101
|
||||
#define KEYCODE_RSHIFT 0x102
|
||||
#define KEYCODE_LCTRL 0x103
|
||||
#define KEYCODE_RCTRL 0x104
|
||||
#define KEYCODE_ALT 0x105
|
||||
#define KEYCODE_ALTGR 0x106
|
||||
|
||||
#define KEYCODE_CAPSLK 0x201
|
||||
#define KEYCODE_SCRLK 0x202
|
||||
#define KEYCODE_NUMLK 0x203
|
||||
|
||||
#define KEYCODE_TAB 0x301
|
||||
#define KEYCODE_BACKSP 0x302
|
||||
#define KEYCODE_RETURN 0x303
|
||||
#define KEYCODE_ESCAPE 0x304
|
||||
#define KEYCODE_ENTER 0x305
|
||||
|
||||
#define KEYCODE_PRTSCR 0x401
|
||||
#define KEYCODE_BREAK 0x402
|
||||
#define KEYCODE_INSERT 0x403
|
||||
#define KEYCODE_HOME 0x404
|
||||
#define KEYCODE_PAGEUP 0x405
|
||||
#define KEYCODE_DELETE 0x406
|
||||
#define KEYCODE_END 0x407
|
||||
#define KEYCODE_PAGEDN 0x408
|
||||
|
||||
#define KEYCODE_UP 0x501
|
||||
#define KEYCODE_DOWN 0x502
|
||||
#define KEYCODE_LEFT 0x503
|
||||
#define KEYCODE_RIGHT 0x504
|
||||
#define KEYCODE_CENTER 0x505
|
||||
|
||||
#define KEYCODE_F1 0x601
|
||||
#define KEYCODE_F2 0x602
|
||||
#define KEYCODE_F3 0x603
|
||||
#define KEYCODE_F4 0x604
|
||||
#define KEYCODE_F5 0x605
|
||||
#define KEYCODE_F6 0x606
|
||||
#define KEYCODE_F7 0x607
|
||||
#define KEYCODE_F8 0x608
|
||||
#define KEYCODE_F9 0x609
|
||||
#define KEYCODE_F10 0x60A
|
||||
#define KEYCODE_F11 0x60B
|
||||
#define KEYCODE_F12 0x60C
|
||||
|
||||
#define KEYCODE_WINL 0x701
|
||||
#define KEYCODE_WINR 0x702
|
||||
#define KEYCODE_MENU 0x703
|
||||
|
||||
#define MODIFIER_EXTENDED 0x00100000
|
||||
#define MODIFIER_EXTENDED2 0x00200000
|
||||
#define MODIFIER_RCTRL 0x00400000
|
||||
#define MODIFIER_RSHIFT 0x00800000
|
||||
#define MODIFIER_LSHIFT 0x01000000
|
||||
#define MODIFIER_LCTRL 0x02000000
|
||||
#define MODIFIER_ALT 0x04000000
|
||||
#define MODIFIER_ALTGR 0x08000000
|
||||
#define MODIFIER_SCRLK 0x10000000
|
||||
#define MODIFIER_NUMLK 0x20000000
|
||||
#define MODIFIER_CAPSLK 0x40000000
|
||||
#define MODIFIER_RELEASE 0x80000000
|
||||
#define MODIFIER_SHIFT (MODIFIER_LSHIFT | MODIFIER_RSHIFT)
|
||||
#define MODIFIER_CTRL (MODIFIER_LCTRL | MODIFIER_RCTRL)
|
||||
|
||||
struct keyboard_key {
|
||||
int nomods;
|
||||
int shift;
|
||||
int ext_nomods;
|
||||
int ext_shift;
|
||||
};
|
||||
|
||||
/*
|
||||
* Keymap for a UK keyboard
|
||||
* maps key numbers->key codes
|
||||
*
|
||||
* We will use scan code index to get the key
|
||||
*
|
||||
* FIXME: element 1 and 4 gives, muticharacter
|
||||
* character constant error, fix this.
|
||||
*/
|
||||
struct keyboard_key keymap_uk2[256] = {
|
||||
/* 0 */ {0,0,0,0},
|
||||
#if 0
|
||||
/* 1 */ {'`','¬',0,0},
|
||||
#else
|
||||
/* 1 */ {'`',0,0,0},
|
||||
#endif
|
||||
/* 2 */ {'1','!',0,0},
|
||||
/* 3 */ {'2','"',0,0},
|
||||
#if 0
|
||||
/* 4 */ {'3','£',0,0},
|
||||
#else
|
||||
/* 4 */ {'3',0,0,0},
|
||||
#endif
|
||||
/* 5 */ {'4','$',0,0},
|
||||
/* 6 */ {'5','%',0,0},
|
||||
/* 7 */ {'6','^',0,0},
|
||||
/* 8 */ {'7','&',0,0},
|
||||
/* 9 */ {'8','*',0,0},
|
||||
/* 10 */ {'9','(',0,0},
|
||||
/* 11 */ {'0',')',0,0},
|
||||
/* 12 */ {'-','_',0,0},
|
||||
/* 13 */ {'=','+',0,0},
|
||||
/* 14 */ {0,0,0,0},
|
||||
/* 15 */ {KEYCODE_BACKSP,0,0,0},
|
||||
/* 16 */ {KEYCODE_TAB,0,0,0},
|
||||
/* 17 */ {'q','Q',0,0},
|
||||
/* 18 */ {'w','W',0,0},
|
||||
/* 19 */ {'e','E',0,0},
|
||||
/* 20 */ {'r','R',0,0},
|
||||
/* 21 */ {'t','T',0,0},
|
||||
/* 22 */ {'y','Y',0,0},
|
||||
/* 23 */ {'u','U',0,0},
|
||||
/* 24 */ {'i','I',0,0},
|
||||
/* 25 */ {'o','O',0,0},
|
||||
/* 26 */ {'p','P',0,0},
|
||||
/* 27 */ {'[','{',0,0},
|
||||
/* 28 */ {']','}',0,0},
|
||||
/* 29 */ {'#','~',0,0},
|
||||
/* 30 */ {KEYCODE_CAPSLK,0,0,0},
|
||||
/* 31 */ {'a','A',0,0},
|
||||
/* 32 */ {'s','S',0,0},
|
||||
/* 33 */ {'d','D',0,0},
|
||||
/* 34 */ {'f','F',0,0},
|
||||
/* 35 */ {'g','G',0,0},
|
||||
/* 36 */ {'h','H',0,0},
|
||||
/* 37 */ {'j','J',0,0},
|
||||
/* 38 */ {'k','K',0,0},
|
||||
/* 39 */ {'l','L',0,0},
|
||||
/* 40 */ {';',':',0,0},
|
||||
/* 41 */ {'\'','@',0,0},
|
||||
/* 42 */ {0,0,0,0},
|
||||
/* 43 */ {KEYCODE_RETURN,0,KEYCODE_ENTER,0},
|
||||
/* 44 */ {KEYCODE_LSHIFT,0,0,0},
|
||||
/* 45 */ {'\\','|',0,0},
|
||||
/* 46 */ {'z','Z',0,0},
|
||||
/* 47 */ {'x','X',0,0},
|
||||
/* 48 */ {'c','C',0,0},
|
||||
/* 49 */ {'v','V',0,0},
|
||||
/* 50 */ {'b','B',0,0},
|
||||
/* 51 */ {'n','N',0,0},
|
||||
/* 52 */ {'m','M',0,0},
|
||||
/* 53 */ {',','<',0,0},
|
||||
/* 54 */ {'.','>',0,0},
|
||||
/* 55 */ {'/','?','/' | MODIFIER_NUMLK,0},
|
||||
/* 56 */ {0,0,0,0},
|
||||
/* 57 */ {KEYCODE_RSHIFT,0,0,0},
|
||||
/* 58 */ {KEYCODE_LCTRL,0,KEYCODE_RCTRL,0},
|
||||
/* 59 */ {0,0,0,0},
|
||||
/* 60 */ {KEYCODE_ALT,0,KEYCODE_ALTGR,0},
|
||||
/* 61 */ {' ',0,0,0},
|
||||
/* 62 */ {KEYCODE_ALTGR,0,0,0},
|
||||
/* 63 */ {0,0,0,0},
|
||||
/* 64 */ {KEYCODE_RCTRL,0,0,0},
|
||||
/* 65 */ {0,0,0,0},
|
||||
/* 66 */ {0,0,0,0},
|
||||
/* 67 */ {0,0,0,0},
|
||||
/* 68 */ {0,0,0,0},
|
||||
/* 69 */ {0,0,0,0},
|
||||
/* 70 */ {0,0,0,0},
|
||||
/* 71 */ {0,0,0,0},
|
||||
/* 72 */ {0,0,0,0},
|
||||
/* 73 */ {0,0,0,0},
|
||||
/* 74 */ {0,0,0,0},
|
||||
/* 75 */ {KEYCODE_INSERT,0,0,0},
|
||||
/* 76 */ {KEYCODE_DELETE,0,0,0},
|
||||
/* 77 */ {0,0,0,0},
|
||||
/* 78 */ {0,0,0,0},
|
||||
/* 79 */ {KEYCODE_LEFT,0,0,0},
|
||||
/* 80 */ {KEYCODE_HOME,0,0,0},
|
||||
/* 81 */ {KEYCODE_END,0,0,0},
|
||||
/* 82 */ {0,0,0,0},
|
||||
/* 83 */ {KEYCODE_UP,0,0,0},
|
||||
/* 84 */ {KEYCODE_DOWN,0,0,0},
|
||||
/* 85 */ {KEYCODE_PAGEUP,0,0,0},
|
||||
/* 86 */ {KEYCODE_PAGEDN,0,0,0},
|
||||
/* 87 */ {0,0,0,0},
|
||||
/* 88 */ {0,0,0,0},
|
||||
/* 89 */ {KEYCODE_RIGHT,0,0,0},
|
||||
/* 90 */ {KEYCODE_NUMLK,0,KEYCODE_BREAK,0},
|
||||
/* 91 */ {KEYCODE_HOME | MODIFIER_NUMLK,0,KEYCODE_HOME,0},
|
||||
/* 92 */ {KEYCODE_LEFT | MODIFIER_NUMLK,0,KEYCODE_LEFT,0},
|
||||
/* 93 */ {KEYCODE_END | MODIFIER_NUMLK,0,KEYCODE_END,0},
|
||||
/* 94 */ {0,0,0,0},
|
||||
/* 95 */ {'/' | MODIFIER_NUMLK,0,0},
|
||||
/* 96 */ {KEYCODE_UP | MODIFIER_NUMLK,0,KEYCODE_UP,0},
|
||||
/* 97 */ {KEYCODE_CENTER | MODIFIER_NUMLK,0,KEYCODE_CENTER,0},
|
||||
/* 98 */ {KEYCODE_DOWN | MODIFIER_NUMLK,0,KEYCODE_DOWN,0},
|
||||
/* 99 */ {KEYCODE_INSERT | MODIFIER_NUMLK,0,KEYCODE_INSERT,0},
|
||||
/* 100 */ {'*' | MODIFIER_NUMLK,0,KEYCODE_PRTSCR,0},
|
||||
/* 101 */ {KEYCODE_PAGEUP | MODIFIER_NUMLK,0,KEYCODE_PAGEUP,0},
|
||||
/* 102 */ {KEYCODE_RIGHT | MODIFIER_NUMLK,0,KEYCODE_RIGHT,0},
|
||||
/* 103 */ {KEYCODE_PAGEDN | MODIFIER_NUMLK,0,KEYCODE_PAGEDN,0},
|
||||
/* 104 */ {KEYCODE_DELETE | MODIFIER_NUMLK,0,KEYCODE_DELETE,0},
|
||||
/* 105 */ {'-' | MODIFIER_NUMLK,0,0,0},
|
||||
/* 106 */ {'+' | MODIFIER_NUMLK,0,0,0},
|
||||
/* 107 */ {KEYCODE_ENTER,0,0,0},
|
||||
/* 108 */ {0,0,0,0},
|
||||
/* 109 */ {0,0,0,0},
|
||||
/* 110 */ {KEYCODE_ESCAPE,0,0,0},
|
||||
/* 111 */ {0,0,0,0},
|
||||
/* 112 */ {KEYCODE_F1,0,0,7},
|
||||
/* 113 */ {KEYCODE_F2,0,0,0},
|
||||
/* 114 */ {KEYCODE_F3,0,0,0},
|
||||
/* 115 */ {KEYCODE_F4,0,0,0},
|
||||
/* 116 */ {KEYCODE_F5,0,0,0},
|
||||
/* 117 */ {KEYCODE_F6,0,0,0},
|
||||
/* 118 */ {KEYCODE_F7,0,0,0},
|
||||
/* 119 */ {KEYCODE_F8,0,0,0},
|
||||
/* 120 */ {KEYCODE_F9,0,0,0},
|
||||
/* 121 */ {KEYCODE_F10,0,0,0},
|
||||
/* 122 */ {KEYCODE_F11,0,0,0},
|
||||
/* 123 */ {KEYCODE_F12,0,0,0},
|
||||
/* 124 */ {KEYCODE_PRTSCR,0,0,0},
|
||||
/* 125 */ {KEYCODE_SCRLK,0,KEYCODE_BREAK,0},
|
||||
/* 126 */ {KEYCODE_BREAK,0,0,0},
|
||||
/* 127 */ {0,0,0,0},
|
||||
/* 128 */ {KEYCODE_WINL,0,KEYCODE_WINL,0},
|
||||
/* 129 */ {KEYCODE_WINR,0,KEYCODE_WINR,0},
|
||||
/* 130 */ {KEYCODE_MENU,0,KEYCODE_MENU,0},
|
||||
/* currently no keys with numbers > 130 */
|
||||
/* 131 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 140 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 150 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 160 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 170 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 180 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 190 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 200 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 210 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 220 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 230 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 240 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
/* 250 */ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Scan code to key number conversion table for
|
||||
* an extended AT keyboard in mode 2
|
||||
*
|
||||
* This will give us the key index for keyboard
|
||||
*/
|
||||
int scancode_mode2_extended[256] = {
|
||||
0, 120, 0, 116, 114, 112, 113,
|
||||
123, 0, 121, 119, 117, 115, 16,
|
||||
1, 0, 0, 60, 44, 0, 58,
|
||||
17, 2, 0, 0, 0, 46, 32,
|
||||
31, 18, 3, 128, 0, 48, 47,
|
||||
33, 19, 5, 4, 129, 0, 61,
|
||||
49, 34, 21, 20, 6, 130, 0,
|
||||
51, 50, 36, 35, 22, 7, 0,
|
||||
0, 0, 52, 37, 23, 8, 9,
|
||||
0, 0, 53, 38, 24, 25, 11,
|
||||
10, 0, 0, 54, 55, 39, 40,
|
||||
26, 12, 0, 0, 0, 41, 0,
|
||||
27, 13, 0, 0, 30, 57, 43,
|
||||
28, 0, 29, 0, 0, 0, 45,
|
||||
0, 0, 0, 0, 15, 0, 0,
|
||||
93, 0, 92, 91, 0, 0, 0,
|
||||
99, 104, 98, 97, 102, 96, 110,
|
||||
90, 122, 106, 103, 105, 100, 101,
|
||||
125, 0, 0, 0, 0, 118, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
/* no keys with codes > 0x8F */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#endif /* __KEYMAP_H__ */
|
||||
387
conts/libdev/kmi/pl050/kmi.c
Executable file
387
conts/libdev/kmi/pl050/kmi.c
Executable file
@@ -0,0 +1,387 @@
|
||||
|
||||
/*
|
||||
* PL050 Primecell Keyboard, Mouse driver
|
||||
*
|
||||
* Copyright (C) 2010 Amit Mahajan
|
||||
*/
|
||||
|
||||
#include <libdev/kmi.h>
|
||||
#include "kmi.h"
|
||||
#include "keymap.h"
|
||||
|
||||
/*
|
||||
* Reading Rx data automatically clears the RXITR
|
||||
*/
|
||||
void kmi_irq_handler(unsigned long base)
|
||||
{
|
||||
}
|
||||
|
||||
int kmi_data_read(unsigned long base)
|
||||
{
|
||||
/* Check and return if data present */
|
||||
if (*(volatile unsigned long *)(base + PL050_KMISTAT) & KMI_RXFULL)
|
||||
return *(volatile unsigned long *)(base + PL050_KMIDATA);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char kmi_keyboard_read(int c, struct keyboard_state *state)
|
||||
{
|
||||
int keycode, shkeycode;
|
||||
int keynum;
|
||||
int extflag;
|
||||
int modmask;
|
||||
|
||||
/* Special codes */
|
||||
switch (c) {
|
||||
case 0xF0:
|
||||
/* release */
|
||||
state->modifiers |= MODIFIER_RELEASE;
|
||||
return 0;
|
||||
case 0xE0:
|
||||
/* extended */
|
||||
state->modifiers |= MODIFIER_EXTENDED;
|
||||
return 0;
|
||||
case 0xE1:
|
||||
/* extended for 2 characters - only used for Break in mode 2 */
|
||||
state->modifiers |= MODIFIER_EXTENDED;
|
||||
state->modifiers |= MODIFIER_EXTENDED2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extflag = 1;
|
||||
modmask = 0xFFFFFFFF;
|
||||
|
||||
/* Is this a scan code? */
|
||||
if (c > 0 && c <= 0x9F)
|
||||
{
|
||||
keynum = scancode_mode2_extended[c];
|
||||
|
||||
/* ignore unrecognised codes */
|
||||
if (!keynum)
|
||||
{
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* is this an extended code? */
|
||||
if (state->modifiers & MODIFIER_EXTENDED)
|
||||
{
|
||||
keycode = keymap_uk2[keynum].ext_nomods;
|
||||
extflag = 0;
|
||||
state->modifiers &= ~MODIFIER_EXTENDED;
|
||||
if (!keycode)
|
||||
{
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (state->modifiers & MODIFIER_EXTENDED2)
|
||||
{
|
||||
keycode = keymap_uk2[keynum].ext_nomods;
|
||||
extflag = 0;
|
||||
state->modifiers &= ~MODIFIER_EXTENDED2;
|
||||
if (!keycode)
|
||||
{
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keycode = keymap_uk2[keynum].nomods;
|
||||
if (!keycode)
|
||||
{
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle shift */
|
||||
if (state->modifiers & MODIFIER_CAPSLK)
|
||||
{
|
||||
if (keycode >= 'a' && keycode <= 'z')
|
||||
{
|
||||
if (!(state->modifiers & MODIFIER_SHIFT))
|
||||
{
|
||||
shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
|
||||
if (shkeycode)
|
||||
keycode = shkeycode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state->modifiers & MODIFIER_SHIFT)
|
||||
{
|
||||
shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
|
||||
if (shkeycode)
|
||||
keycode = shkeycode;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state->modifiers & MODIFIER_SHIFT)
|
||||
{
|
||||
shkeycode = extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
|
||||
if (shkeycode)
|
||||
keycode = shkeycode;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle the numeric keypad */
|
||||
if (keycode & MODIFIER_NUMLK)
|
||||
{
|
||||
keycode &= ~MODIFIER_NUMLK;
|
||||
|
||||
if (state->modifiers & MODIFIER_NUMLK)
|
||||
{
|
||||
if (!(state->modifiers & MODIFIER_SHIFT))
|
||||
{
|
||||
switch (keycode)
|
||||
{
|
||||
case KEYCODE_HOME:
|
||||
keycode = '7';
|
||||
break;
|
||||
case KEYCODE_UP:
|
||||
keycode = '8';
|
||||
break;
|
||||
case KEYCODE_PAGEUP:
|
||||
keycode = '9';
|
||||
break;
|
||||
case KEYCODE_LEFT:
|
||||
keycode = '4';
|
||||
break;
|
||||
case KEYCODE_CENTER:
|
||||
keycode = '5';
|
||||
break;
|
||||
case KEYCODE_RIGHT:
|
||||
keycode = '6';
|
||||
break;
|
||||
case KEYCODE_END:
|
||||
keycode = '1';
|
||||
break;
|
||||
case KEYCODE_DOWN:
|
||||
keycode = '2';
|
||||
break;
|
||||
case KEYCODE_PAGEDN:
|
||||
keycode = '3';
|
||||
break;
|
||||
case KEYCODE_INSERT:
|
||||
keycode = '0';
|
||||
break;
|
||||
case KEYCODE_DELETE:
|
||||
keycode = '.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
modmask = ~MODIFIER_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* modifier keys */
|
||||
switch (keycode)
|
||||
{
|
||||
case KEYCODE_LSHIFT:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_LSHIFT | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_LSHIFT;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_RSHIFT:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_RSHIFT | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_RSHIFT;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_LCTRL:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_LCTRL | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_LCTRL;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_RCTRL:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_RCTRL | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_RCTRL;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_ALT:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_ALT | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_ALT;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_ALTGR:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~(MODIFIER_ALTGR | MODIFIER_RELEASE);
|
||||
else
|
||||
state->modifiers |= MODIFIER_ALTGR;
|
||||
return 0;
|
||||
|
||||
case KEYCODE_CAPSLK:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
else
|
||||
{
|
||||
state->modifiers ^= MODIFIER_CAPSLK;
|
||||
//__keyb_update_locks (state);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case KEYCODE_SCRLK:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
else
|
||||
{
|
||||
state->modifiers ^= MODIFIER_SCRLK;
|
||||
//__keyb_update_locks (state);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case KEYCODE_NUMLK:
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
else
|
||||
{
|
||||
state->modifiers ^= MODIFIER_NUMLK;
|
||||
//__keyb_update_locks (state);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (state->modifiers & MODIFIER_RELEASE)
|
||||
{
|
||||
/* clear release condition */
|
||||
state->modifiers &= ~MODIFIER_RELEASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* write code into the buffer */
|
||||
return keycode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simple logic to interpret keyboard keys and shift keys
|
||||
* TODO: Add support for all the modifier keys
|
||||
*
|
||||
* Keyevents work in 3 phase manner, if you press 'A':
|
||||
* 1. scan code for 'A' is generated
|
||||
* 2. Key release event i.e KYBD_DATA_KEYUP
|
||||
* 3. scan code for 'A' again is generated
|
||||
*/
|
||||
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state)
|
||||
{
|
||||
int keynum, keycode = 0;
|
||||
|
||||
/* Read Keyboard RX buffer */
|
||||
unsigned char data = kmi_data_read(base);
|
||||
|
||||
/* if a key up occurred (key released) occured */
|
||||
if (data == KYBD_DATA_KEYUP) {
|
||||
state->keyup = 1;
|
||||
return 0;
|
||||
}
|
||||
else if (state->keyup){
|
||||
state->keyup = 0;
|
||||
|
||||
/* Check if shift was lifted */
|
||||
if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
|
||||
state->shift = 0;
|
||||
}
|
||||
else {
|
||||
/* Find key number */
|
||||
keynum = scancode_mode2_extended[data];
|
||||
if(state->shift)
|
||||
keycode = keymap_uk2[keynum].shift;
|
||||
else
|
||||
keycode = keymap_uk2[keynum].nomods;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
|
||||
state->shift = 1;
|
||||
}
|
||||
|
||||
return (unsigned char)keycode;
|
||||
}
|
||||
|
||||
void kmi_keyboard_init(unsigned long base, unsigned int div)
|
||||
{
|
||||
/* STOP KMI */
|
||||
*(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
|
||||
|
||||
/*
|
||||
* For versatile, KMI refernce clock = 24MHz
|
||||
* KMI manual says we need 8MHz clock,
|
||||
* so divide by 3
|
||||
*/
|
||||
*(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
|
||||
|
||||
/* Enable KMI and TX/RX interrupts */
|
||||
*(volatile unsigned long *)(base + PL050_KMICR) =
|
||||
KMI_RXINTR | KMI_EN;
|
||||
|
||||
/* Reset and wait for reset to complete */
|
||||
*(volatile unsigned long *)(base + PL050_KMIDATA) =
|
||||
KYBD_DATA_RESET;
|
||||
while(kmi_data_read(base) != KYBD_DATA_RTR);
|
||||
}
|
||||
|
||||
void kmi_mouse_enable(unsigned long base)
|
||||
{
|
||||
unsigned long *datareg = (unsigned long *)(base + PL050_KMIDATA);
|
||||
|
||||
*datareg = MOUSE_DATA_ENABLE;
|
||||
|
||||
/*sleep for sometime here */
|
||||
|
||||
while (*datareg != MOUSE_DATA_ACK);
|
||||
}
|
||||
|
||||
void kmi_mouse_init(unsigned long base, unsigned int div)
|
||||
{
|
||||
int data[2];
|
||||
|
||||
/* STOP KMI */
|
||||
*(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
|
||||
|
||||
/*
|
||||
* For versatile, KMI refernce clock = 24MHz
|
||||
* KMI manual says we need 8MHz clock,
|
||||
* so divide by 3
|
||||
*/
|
||||
*(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
|
||||
|
||||
/* Enable KMI and TX/RX interrupts */
|
||||
*(volatile unsigned long *)(base + PL050_KMICR) =
|
||||
KMI_RXINTR | KMI_EN;
|
||||
|
||||
/* Reset and wait for reset to complete */
|
||||
*(volatile unsigned long *)(base + PL050_KMIDATA) =
|
||||
MOUSE_DATA_RESET;
|
||||
|
||||
do {
|
||||
data[0] = kmi_data_read(base);
|
||||
/* Some sleep here */
|
||||
data[1] = kmi_data_read(base);
|
||||
}while((data[0] != MOUSE_DATA_ACK) && (data[1] != MOUSE_DATA_RTR));
|
||||
|
||||
/* Set enable data code to mouse */
|
||||
kmi_mouse_enable(base);
|
||||
}
|
||||
|
||||
59
conts/libdev/kmi/pl050/kmi.h
Executable file
59
conts/libdev/kmi/pl050/kmi.h
Executable file
@@ -0,0 +1,59 @@
|
||||
|
||||
#ifndef __PL050_KMI_H__
|
||||
#define __PL050_KMI_H__
|
||||
|
||||
/* Register offsets */
|
||||
#define PL050_KMICR 0x00
|
||||
#define PL050_KMISTAT 0x04
|
||||
#define PL050_KMIDATA 0x08
|
||||
#define PL050_KMICLKDIV 0x0C
|
||||
#define PL050_KMIIR 0x10
|
||||
|
||||
/* Bit definitions for KMI control register */
|
||||
#define KMI_TYPE (1 << 0x5)
|
||||
#define KMI_RXINTR (1 << 0x4)
|
||||
#define KMI_TXINTR (1 << 0x3)
|
||||
#define KMI_EN (1 << 0x2)
|
||||
#define KMI_FD (1 << 0x1)
|
||||
#define KMI_FC (1 << 0x0)
|
||||
|
||||
/* KMI generic defines */
|
||||
#define KMI_DATA_RESET 0xFF
|
||||
#define KMI_DATA_RTR 0xAA
|
||||
|
||||
/* Keyboard special defines */
|
||||
#define KYBD_DATA_RESET KMI_DATA_RESET // Keyboard reset
|
||||
#define KYBD_DATA_RTR KMI_DATA_RTR // Keyboard response to reset
|
||||
|
||||
#define KYBD_DATA_KEYUP 0xF0 // Key up control code
|
||||
#define KYBD_DATA_SHIFTL 18 // Shift key left
|
||||
#define KYBD_DATA_SHIFTR 89 // Shift key right
|
||||
|
||||
/* Bit definitions for KMI STAT register */
|
||||
#define KMI_TXEMPTY (1 << 0x6)
|
||||
#define KMI_TXBUSY (1 << 0x5)
|
||||
#define KMI_RXFULL (1 << 0x4)
|
||||
#define KMI_RXBUSY (1 << 0x3)
|
||||
#define KMI_RXPARITY (1 << 0x2)
|
||||
#define KMI_CLKIN (1 << 0x1)
|
||||
#define KMI_DATAIN (1 << 0x0)
|
||||
|
||||
/* Mouse special defines */
|
||||
#define MOUSE_DATA_RESET KMI_DATA_RESET // Mouse reset
|
||||
#define MOUSE_DATA_RTR KMI_DATA_RTR // Mouse response to reset
|
||||
#define MOUSE_DATA_ACK 0xFA
|
||||
#define MOUSE_DATA_ENABLE 0xF4 // Mouse enable
|
||||
|
||||
/* Common functions */
|
||||
void kmi_irq_handler(unsigned long base);
|
||||
int kmi_data_read(unsigned long base);
|
||||
|
||||
/* Keyboard specific calls */
|
||||
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state);
|
||||
void kmi_keyboard_init(unsigned long base, unsigned int div);
|
||||
|
||||
/* Mouse specific calls */
|
||||
void kmi_mouse_enable(unsigned long base);
|
||||
void kmi_mouse_init(unsigned long base, unsigned int div);
|
||||
|
||||
#endif /* __PL050_KMI_H__ */
|
||||
Reference in New Issue
Block a user