diff --git a/src/board/system76/galp3-c/include/board/keymap.h b/src/board/system76/galp3-c/include/board/keymap.h index d1fc6ac..f390d07 100644 --- a/src/board/system76/galp3-c/include/board/keymap.h +++ b/src/board/system76/galp3-c/include/board/keymap.h @@ -14,14 +14,27 @@ uint16_t keymap(int output, int input, int layer); uint16_t keymap_translate(uint16_t key); +// Key types +#define KT_MASK (0xF000) + +// Normal keys +#define KT_NORMAL (0x0000) + +// Layer selection +#define KT_FN (0x1000) + +// SCI +#define KT_SCI (0x2000) + +#define SCI_BRIGHTNESS_DOWN (0x11) +#define SCI_BRIGHTNESS_UP (0x12) +#define SCI_AIRPLANE_MODE (0x14) + // See http://www.techtoys.com.hk/Downloads/Download/Microchip/PS2_driver/ScanCode.pdf // Should send 0xE0 before scancode bytes -#define K_E0 0x0100 +#define K_E0 (0x0100) -// Layer selection - -#define K_FN (0x8000) // Hotkeys diff --git a/src/board/system76/galp3-c/include/board/pmc.h b/src/board/system76/galp3-c/include/board/pmc.h index 77f3ef8..65ea613 100644 --- a/src/board/system76/galp3-c/include/board/pmc.h +++ b/src/board/system76/galp3-c/include/board/pmc.h @@ -4,6 +4,7 @@ #include void pmc_init(void); +bool pmc_sci(struct Pmc * pmc, uint8_t sci); void pmc_event(struct Pmc * pmc); #endif // _BOARD_PMC_H diff --git a/src/board/system76/galp3-c/kbscan.c b/src/board/system76/galp3-c/kbscan.c index b172ac2..57e3889 100644 --- a/src/board/system76/galp3-c/kbscan.c +++ b/src/board/system76/galp3-c/kbscan.c @@ -2,6 +2,7 @@ #include #include #include +#include #include bool kbscan_enabled = false; @@ -48,11 +49,25 @@ void kbscan_event(void) { if (new_b != last_b) { uint16_t key = keymap(i, j, kbscan_layer); DEBUG("KB %d, %d, %d = 0x%04X, %d\n", i, j, kbscan_layer, key, new_b); - if (key == K_FN) { - if (new_b) layer = 1; - else layer = 0; - } else if (kbscan_enabled && key) { - kbc_scancode(&KBC, key, new_b); + switch (key & KT_MASK) { + case (KT_FN): + if (new_b) layer = 1; + else layer = 0; + break; + case (KT_SCI): + if (new_b) { + uint8_t sci = (uint8_t)(key & 0xFF); + if (!pmc_sci(&PMC_1, sci)) { + // In the case of ignored SCI, reset bit + new &= ~(1 << j); + } + } + break; + case (KT_NORMAL): + if (kbscan_enabled && key) { + kbc_scancode(&KBC, key, new_b); + } + break; } } } @@ -76,10 +91,12 @@ void kbscan_event(void) { if (new_b != last_b) { uint16_t key = keymap(i, j, kbscan_layer); DEBUG("KB %d, %d, %d = 0x%04X, %d\n", i, j, kbscan_layer, key, new_b); - if (key == K_FN) { - // N/A - } else if (kbscan_enabled && key) { - kbc_scancode(&KBC, key, new_b); + switch (key & KT_MASK) { + case (KT_NORMAL): + if (kbscan_enabled && key) { + kbc_scancode(&KBC, key, new_b); + } + break; } } } diff --git a/src/board/system76/galp3-c/keymap/default.h b/src/board/system76/galp3-c/keymap/default.h index 690bb0d..3d2889b 100644 --- a/src/board/system76/galp3-c/keymap/default.h +++ b/src/board/system76/galp3-c/keymap/default.h @@ -64,7 +64,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_E), // 7 }, { // 6 - K(K_FN), // 0 + K(KT_FN), // 0 K(K_B), // 1 K(K_F), // 2 K(K_G), // 3 @@ -120,7 +120,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_SEMICOLON), // 3 K(K_P), // 4 K(K_0), // 5 - K(K_F8), // 6 + {K_F8, KT_SCI | SCI_BRIGHTNESS_DOWN}, // 6 K(K_F7), // 7 }, { // 12 @@ -131,7 +131,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_BRACE_OPEN), // 4 K(K_MINUS), // 5 K(K_F10), // 6 - K(K_F9), // 7 + {K_F9, KT_SCI | SCI_BRIGHTNESS_UP}, // 7 }, { // 13 K(0), // 0 @@ -141,7 +141,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_EQUALS), // 4 K(K_RIGHT), // 5 K(0 /* TODO: Pause/Break */), // 6 - K(K_F11), // 7 + {K_F11, KT_SCI | SCI_AIRPLANE_MODE}, // 7 }, { // 14 K(0), // 0 diff --git a/src/board/system76/galp3-c/keymap/jeremy.h b/src/board/system76/galp3-c/keymap/jeremy.h index 3df3508..a73583f 100644 --- a/src/board/system76/galp3-c/keymap/jeremy.h +++ b/src/board/system76/galp3-c/keymap/jeremy.h @@ -31,7 +31,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(0), // 4 K(0), // 5 K(K_LEFT_SUPER), // 6 - K(K_FN), // 7 + K(KT_FN), // 7 }, { // 3 K(0), // 0 @@ -46,7 +46,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { { // 4 K(K_X), // 0 K(K_Z), // 1 - K(K_FN), // 2 + K(KT_FN), // 2 K(K_A), // 3 K(K_TAB), // 4 K(0), // 5 @@ -64,7 +64,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_E), // 7 }, { // 6 - K(K_FN), // 0 + K(KT_FN), // 0 K(K_B), // 1 K(K_F), // 2 K(K_G), // 3 @@ -120,7 +120,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { {K_SEMICOLON, K_INSERT}, // 3 K(K_P), // 4 K(K_0), // 5 - K(K_F8), // 6 + {K_F8, KT_SCI | SCI_BRIGHTNESS_DOWN}, // 6 K(K_F7), // 7 }, { // 12 @@ -131,7 +131,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_BRACE_OPEN), // 4 K(K_MINUS), // 5 K(K_F10), // 6 - K(K_F9), // 7 + {K_F9, KT_SCI | SCI_BRIGHTNESS_UP}, // 7 }, { // 13 K(0), // 0 @@ -141,7 +141,7 @@ uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { K(K_EQUALS), // 4 K(K_RIGHT), // 5 K(0 /* TODO: Pause/Break */), // 6 - K(K_F11), // 7 + {K_F11, KT_SCI | SCI_AIRPLANE_MODE}, // 7 }, { // 14 K(0), // 0 diff --git a/src/board/system76/galp3-c/main.c b/src/board/system76/galp3-c/main.c index 61c32b2..89afebb 100644 --- a/src/board/system76/galp3-c/main.c +++ b/src/board/system76/galp3-c/main.c @@ -62,6 +62,7 @@ void ac_adapter() { static struct Gpio __code ACIN_N = GPIO(B, 6); static struct Gpio __code LED_ACIN = GPIO(C, 7); + static bool send_sci = true; static bool last = true; // Check if the adapter line goes low @@ -83,6 +84,16 @@ void ac_adapter() { // Reset main loop cycle to force reading PECI and battery main_cycle = 0; + + // Send SCI to update AC and battery information + send_sci = true; + } + + if (send_sci) { + // Send SCI 0x16 for AC detect event + if (pmc_sci(&PMC_1, 0x16)) { + send_sci = false; + } } last = new; diff --git a/src/board/system76/galp3-c/pmc.c b/src/board/system76/galp3-c/pmc.c index 80f4c59..b6497fc 100644 --- a/src/board/system76/galp3-c/pmc.c +++ b/src/board/system76/galp3-c/pmc.c @@ -2,8 +2,7 @@ #include #include #include - -uint8_t pmc_sci_queue = 0; +#include void pmc_init(void) { *(PMC_1.control) = 0x41; @@ -19,6 +18,22 @@ enum PmcState { PMC_STATE_ACPI_WRITE_ADDR, }; +static uint8_t pmc_sci_queue = 0; +static struct Gpio __code SCI_N = GPIO(D, 4); + +bool pmc_sci(struct Pmc * pmc, uint8_t sci) { + bool update = pmc_sci_queue == 0; + // Set SCI queue if possible + if (update) pmc_sci_queue = sci; + // Set SCI pending bit + uint8_t sts = pmc_status(pmc); + pmc_set_status(pmc, sts | (1 << 5)); + // Start SCI interrupt + gpio_set(&SCI_N, false); + *(SCI_N.control) = 0x40; + return update; +} + void pmc_event(struct Pmc * pmc) { static enum PmcState state = PMC_STATE_DEFAULT; static uint8_t state_data[2] = {0, 0}; @@ -51,10 +66,13 @@ void pmc_event(struct Pmc * pmc) { break; case 0x84: DEBUG(" SCI queue\n"); - // Clear SCI event pending bit + // Clear SCI pending bit pmc_set_status(pmc, sts & ~(1 << 5)); - // Send SCI event + // Send SCI queue pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT); + // Stop SCI interrupt + *(SCI_N.control) = 0x80; + gpio_set(&SCI_N, true); // Clear SCI queue pmc_sci_queue = 0; break;