From 05a505ad83637e66304ba9d9dbb2f068ca978d5d Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 8 Nov 2019 12:43:28 -0700 Subject: [PATCH] Add key translation --- .../system76/galp3-c/include/board/kbc.h | 3 + .../system76/galp3-c/include/board/keymap.h | 2 + src/board/system76/galp3-c/kbc.c | 35 ++++++ src/board/system76/galp3-c/kbscan.c | 16 +-- src/board/system76/galp3-c/keymap.c | 105 ++++++++++++++++++ 5 files changed, 146 insertions(+), 15 deletions(-) diff --git a/src/board/system76/galp3-c/include/board/kbc.h b/src/board/system76/galp3-c/include/board/kbc.h index 6f9f960..2f0d734 100644 --- a/src/board/system76/galp3-c/include/board/kbc.h +++ b/src/board/system76/galp3-c/include/board/kbc.h @@ -1,9 +1,12 @@ #ifndef _BOARD_KBC_H #define _BOARD_KBC_H +#include + #include void kbc_init(void); +void kbc_key(struct Kbc * kbc, uint16_t key, bool pressed); void kbc_event(struct Kbc * kbc); #endif // _BOARD_KBC_H diff --git a/src/board/system76/galp3-c/include/board/keymap.h b/src/board/system76/galp3-c/include/board/keymap.h index 0f92dc2..fdc5e25 100644 --- a/src/board/system76/galp3-c/include/board/keymap.h +++ b/src/board/system76/galp3-c/include/board/keymap.h @@ -12,6 +12,8 @@ uint16_t keymap(int output, int input, int layer); +uint16_t keymap_translate(uint16_t key); + // See http://www.techtoys.com.hk/Downloads/Download/Microchip/PS2_driver/ScanCode.pdf // Should send 0xE0 before scancode bytes diff --git a/src/board/system76/galp3-c/kbc.c b/src/board/system76/galp3-c/kbc.c index eab616c..5e62073 100644 --- a/src/board/system76/galp3-c/kbc.c +++ b/src/board/system76/galp3-c/kbc.c @@ -2,6 +2,7 @@ #include #include +#include void kbc_init(void) { // Disable interrupts @@ -9,6 +10,35 @@ void kbc_init(void) { *(KBC.control) = 0; } +// Translate from scancode set 2 to scancode set 1 +// for basically no good reason +static bool kbc_translate = true; + +void kbc_key(struct Kbc * kbc, uint16_t key, bool pressed) { + if (kbc_translate) { + key = keymap_translate(key); + } + switch (key & 0xFF00) { + case K_E0: + printf(" E0\n"); + kbc_keyboard(kbc, 0xE0); + key &= 0xFF; + // Fall through + case 0x00: + if (!pressed) { + if (kbc_translate) { + key |= 0x80; + } else { + printf(" F0\n"); + kbc_keyboard(kbc, 0xF0); + } + } + printf(" %02X\n", key); + kbc_keyboard(kbc, (uint8_t)key); + break; + } +} + enum KbcState { KBC_STATE_NORMAL, KBC_STATE_WRITE_CONFIG, @@ -109,6 +139,11 @@ void kbc_event(struct Kbc * kbc) { } else { control &= ~(1 << 1); } + if (data & (1 << 6)) { + kbc_translate = true; + } else { + kbc_translate = false; + } *kbc->control = control; break; case KBC_STATE_SET_LEDS: diff --git a/src/board/system76/galp3-c/kbscan.c b/src/board/system76/galp3-c/kbscan.c index c6d69ee..576a4af 100644 --- a/src/board/system76/galp3-c/kbscan.c +++ b/src/board/system76/galp3-c/kbscan.c @@ -51,21 +51,7 @@ void kbscan_event(void) { uint16_t key = keymap(i, j, kbscan_layer); printf("KB %d, %d, %d = 0x%04X, %d\n", i, j, kbscan_layer, key, new_b); if (kbscan_enabled && key) { - switch (key & 0xFF00) { - case K_E0: - printf(" E0\n"); - kbc_keyboard(&KBC, 0xE0); - // Fall through - case 0x00: - if (!new_b) { - printf(" F0\n"); - kbc_keyboard(&KBC, 0xF0); - } - uint8_t key_byte = (uint8_t)(key & 0xFF); - printf(" %02X\n", key_byte); - kbc_keyboard(&KBC, key_byte); - break; - } + kbc_key(&KBC, key, new_b); } } } diff --git a/src/board/system76/galp3-c/keymap.c b/src/board/system76/galp3-c/keymap.c index 2163905..2355601 100644 --- a/src/board/system76/galp3-c/keymap.c +++ b/src/board/system76/galp3-c/keymap.c @@ -170,3 +170,108 @@ uint16_t keymap(int output, int input, int layer) { return 0; } } + +// This is terrible, from http://www.vetra.com/scancodes.html +uint16_t keymap_translate(uint16_t key) { + switch (key) { + // Function keys + + case K_F1: return 0x3B; + case K_F2: return 0x3C; + case K_F3: return 0x3D; + case K_F4: return 0x3E; + case K_F5: return 0x3F; + case K_F6: return 0x40; + case K_F7: return 0x41; + case K_F8: return 0x42; + case K_F9: return 0x43; + case K_F10: return 0x44; + case K_F11: return 0x57; + case K_F12: return 0x58; + + // Number keys + + case K_0: return 0x0B; + case K_1: return 0x02; + case K_2: return 0x03; + case K_3: return 0x04; + case K_4: return 0x05; + case K_5: return 0x06; + case K_6: return 0x07; + case K_7: return 0x08; + case K_8: return 0x09; + case K_9: return 0x0A; + + // Letter keys + + case K_A: return 0x1E; + case K_B: return 0x30; + case K_C: return 0x2E; + case K_D: return 0x20; + case K_E: return 0x12; + case K_F: return 0x21; + case K_G: return 0x22; + case K_H: return 0x23; + case K_I: return 0x17; + case K_J: return 0x24; + case K_K: return 0x25; + case K_L: return 0x26; + case K_M: return 0x32; + case K_N: return 0x31; + case K_O: return 0x18; + case K_P: return 0x19; + case K_Q: return 0x10; + case K_R: return 0x13; + case K_S: return 0x1F; + case K_T: return 0x14; + case K_U: return 0x16; + case K_V: return 0x2F; + case K_W: return 0x11; + case K_X: return 0x2D; + case K_Y: return 0x15; + case K_Z: return 0x2C; + + // Special keys + + case K_ESC: return 0x01; + + case K_TICK: return 0x29; + case K_MINUS: return 0x0C; + case K_EQUALS: return 0x0D; + case K_BKSP: return 0x0E; + + case K_TAB: return 0x0F; + case K_BRACE_OPEN: return 0x1A; + case K_BRACE_CLOSE: return 0x1B; + case K_BACKSLASH: return 0x2B; + + case K_CAPS: return 0x3A; + case K_SEMICOLON: return 0x27; + case K_QUOTE: return 0x28; + case K_ENTER: return 0x1C; + + case K_LEFT_SHIFT: return 0x2A; + case K_COMMA: return 0x33; + case K_PERIOD: return 0x34; + case K_SLASH: return 0x35; + case K_RIGHT_SHIFT: return 0x36; + + case K_LEFT_CTRL: return 0x1D; + case K_LEFT_ALT: return 0x38; + case K_SPACE: return 0x39; + case K_RIGHT_ALT: return (K_E0 | 0x38); + case K_RIGHT_CTRL: return (K_E0 | 0x1D); + + case K_INSERT: return (K_E0 | 0x52); + case K_DEL: return (K_E0 | 0x53); + case K_HOME: return (K_E0 | 0x47); + case K_END: return (K_E0 | 0x4F); + case K_PGUP: return (K_E0 | 0x49); + case K_PGDN: return (K_E0 | 0x51); + + case K_UP: return (K_E0 | 0x48); + case K_LEFT: return (K_E0 | 0x4B); + case K_DOWN: return (K_E0 | 0x50); + case K_RIGHT: return (K_E0 | 0x4D); + } +}