diff --git a/src/board/system76/common/include/board/options.h b/src/board/system76/common/include/board/options.h index bc136450a..b8920ceb7 100644 --- a/src/board/system76/common/include/board/options.h +++ b/src/board/system76/common/include/board/options.h @@ -24,6 +24,8 @@ enum { OPT_ALLOW_BAT_BOOST, OPT_ALWAYS_ON_USB, OPT_GPU_MUX_CTRL, + OPT_KB_PRIVACY, + OPT_KB_PRIVACY_MAX_DELAY, NUM_OPTIONS }; diff --git a/src/board/system76/common/kbscan.c b/src/board/system76/common/kbscan.c index b4bd4d379..caf367b6b 100644 --- a/src/board/system76/common/kbscan.c +++ b/src/board/system76/common/kbscan.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,17 @@ bool kbscan_fn_held = false; bool kbscan_esc_held = false; +bool kb_privacy_enabled = false; +static uint16_t kb_privacy_lfsr; + +static uint8_t kb_privacy_rand(uint8_t max) { + if (!kb_privacy_lfsr) + kb_privacy_lfsr = (uint16_t)(time_get() | 1u); + uint16_t bit = kb_privacy_lfsr & 1u; + kb_privacy_lfsr = (kb_privacy_lfsr >> 1) ^ (uint16_t)(bit ? 0xB400u : 0u); + return (uint8_t)(kb_privacy_lfsr % max); +} + bool kbscan_enabled = false; uint16_t kbscan_repeat_period = 91; uint16_t kbscan_repeat_delay = 500; @@ -58,6 +70,8 @@ void kbscan_init(void) { KSIGCTRL = 0; KSIGOEN = 0; KSIGDAT = 0; + + kb_privacy_enabled = (bool)options_get(OPT_KB_PRIVACY); } // Debounce time in milliseconds @@ -208,9 +222,21 @@ bool kbscan_press(uint16_t key, bool pressed, uint8_t *layer) { return true; } + if (key == K_KB_PRIVACY && pressed) { + DEBUG("Toggling KB privacy\n"); + kb_privacy_enabled ^= 1; + options_set(OPT_KB_PRIVACY, (uint8_t)kb_privacy_enabled); + return true; + } + switch (key & KT_MASK) { case (KT_NORMAL): if (kbscan_enabled) { + if (kb_privacy_enabled) { + uint8_t max_delay = options_get(OPT_KB_PRIVACY_MAX_DELAY); + if (max_delay) + delay_ms(kb_privacy_rand(max_delay)); + } kbc_scancode(key, pressed); } break; diff --git a/src/board/system76/common/options.c b/src/board/system76/common/options.c index 5d7b3d842..b07f1328a 100644 --- a/src/board/system76/common/options.c +++ b/src/board/system76/common/options.c @@ -17,6 +17,8 @@ uint8_t DEFAULT_OPTIONS[NUM_OPTIONS] = { [OPT_ALLOW_BAT_BOOST] = 0, [OPT_ALWAYS_ON_USB] = 0, [OPT_GPU_MUX_CTRL] = 0, + [OPT_KB_PRIVACY] = 0, + [OPT_KB_PRIVACY_MAX_DELAY] = 100, }; // clang-format on diff --git a/src/common/include/common/keymap.h b/src/common/include/common/keymap.h index 10a1a5d07..05fb8aa67 100644 --- a/src/common/include/common/keymap.h +++ b/src/common/include/common/keymap.h @@ -284,5 +284,6 @@ uint16_t keymap_translate(uint16_t key); #define KF_CUSTOM (0x0200) #define K_FNLOCK (KF_CUSTOM | 0x01) +#define K_KB_PRIVACY (KF_CUSTOM | 0x02) #endif // _COMMON_KEYMAP_H diff --git a/src/keyboard/system76/14in_83/keymap/default.c b/src/keyboard/system76/14in_83/keymap/default.c index ea1c8beea..58b0cfe76 100644 --- a/src/keyboard/system76/14in_83/keymap/default.c +++ b/src/keyboard/system76/14in_83/keymap/default.c @@ -19,7 +19,7 @@ LAYOUT( K_ESC, K_TOUCHPAD, K_DISPLAY_TOGGLE, K_MUTE, K_KBD_BKL, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, K_BRIGHTNESS_DOWN, K_BRIGHTNESS_UP, K_CAMERA_TOGGLE, K_AIRPLANE_MODE, K_SUSPEND, K_HOME, K_END, K_PRINT_SCREEN, K_DEL, K_PLAY_PAUSE, K_FAN_TOGGLE, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, - K_FNLOCK, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, + K_FNLOCK, K_A, K_KB_PRIVACY, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_PGUP, K_UP, K_PGDN, K_LEFT, K_DOWN, K_RIGHT