Tom Rini | 10e4779 | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Keyboard input helper functions (too small to be called a layer) |
| 4 | * |
| 5 | * Copyright (c) 2011 The Chromium OS Authors. |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
| 8 | #ifndef _INPUT_H |
| 9 | #define _INPUT_H |
| 10 | |
| 11 | enum { |
| 12 | INPUT_MAX_MODIFIERS = 4, |
| 13 | INPUT_BUFFER_LEN = 16, |
| 14 | }; |
| 15 | |
| 16 | enum { |
| 17 | /* Keyboard LEDs */ |
| 18 | INPUT_LED_SCROLL = 1 << 0, |
Bin Meng | 07ab26e | 2015-11-12 05:33:03 -0800 | [diff] [blame] | 19 | INPUT_LED_NUM = 1 << 1, |
| 20 | INPUT_LED_CAPS = 1 << 2, |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 21 | }; |
| 22 | |
| 23 | /* |
| 24 | * This table translates key codes to ASCII. Most of the entries are ASCII |
| 25 | * codes, but entries after KEY_FIRST_MOD indicate that this key is a |
| 26 | * modifier key, like shift, ctrl. KEY_FIRST_MOD + MOD_SHIFT is the shift |
| 27 | * key, for example. |
| 28 | */ |
| 29 | struct input_key_xlate { |
| 30 | /* keycode of the modifiers which select this table, -1 if none */ |
| 31 | int left_keycode; |
| 32 | int right_keycode; |
| 33 | const uchar *xlate; /* keycode to ASCII table */ |
| 34 | int num_entries; /* number of entries in this table */ |
| 35 | }; |
| 36 | |
| 37 | struct input_config { |
Simon Glass | 244f589 | 2015-10-18 21:17:11 -0600 | [diff] [blame] | 38 | struct udevice *dev; |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 39 | uchar fifo[INPUT_BUFFER_LEN]; |
| 40 | int fifo_in, fifo_out; |
| 41 | |
| 42 | /* Which modifiers are active (1 bit for each MOD_... value) */ |
| 43 | uchar modifiers; |
| 44 | uchar flags; /* active state keys (FLAGS_...) */ |
Simon Glass | 03fef7e | 2015-11-11 10:05:40 -0700 | [diff] [blame] | 45 | uchar leds; /* active LEDs (INPUT_LED_...) */ |
| 46 | uchar leds_changed; /* LEDs that just changed */ |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 47 | uchar num_tables; /* number of modifier tables */ |
| 48 | int prev_keycodes[INPUT_BUFFER_LEN]; /* keys held last time */ |
| 49 | int num_prev_keycodes; /* number of prev keys */ |
| 50 | struct input_key_xlate table[INPUT_MAX_MODIFIERS]; |
| 51 | |
| 52 | /** |
| 53 | * Function the input helper calls to scan the keyboard |
| 54 | * |
| 55 | * @param config Input state |
| 56 | * @return 0 if no keys read, otherwise number of keys read, or 1 if |
| 57 | * unknown |
| 58 | */ |
| 59 | int (*read_keys)(struct input_config *config); |
Simon Glass | d64a8cb | 2015-10-18 21:17:25 -0600 | [diff] [blame] | 60 | bool allow_repeats; /* Don't filter out repeats */ |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 61 | unsigned int next_repeat_ms; /* Next time we repeat a key */ |
| 62 | unsigned int repeat_delay_ms; /* Time before autorepeat starts */ |
| 63 | unsigned int repeat_rate_ms; /* Autorepeat rate in ms */ |
| 64 | }; |
| 65 | |
| 66 | struct stdio_dev; |
| 67 | |
| 68 | /** |
| 69 | * Convert a list of key codes into ASCII and send them |
| 70 | * |
| 71 | * @param config Input state |
| 72 | * @param keycode List of key codes to examine |
| 73 | * @param num_keycodes Number of key codes |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 74 | * Return: number of ascii characters sent, or 0 if none, or -1 for an |
Hung-Te Lin | 47a65ad | 2012-10-11 15:15:53 +0000 | [diff] [blame] | 75 | * internal error |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 76 | */ |
| 77 | int input_send_keycodes(struct input_config *config, int keycode[], int count); |
| 78 | |
| 79 | /** |
Simon Glass | 2fed04b | 2015-10-18 21:17:24 -0600 | [diff] [blame] | 80 | * Add a new keycode to an existing list of keycodes |
| 81 | * |
| 82 | * This can be used to handle keyboards which do their own scanning. An |
| 83 | * internal list of depressed keys is maintained by the input library. Then |
| 84 | * this function is called to add a new key to the list (when a 'make code' is |
| 85 | * received), or remove a key (when a 'break code' is received). |
| 86 | * |
| 87 | * This function looks after maintenance of the list of active keys, and calls |
| 88 | * input_send_keycodes() with its updated list. |
| 89 | * |
| 90 | * @param config Input state |
| 91 | * @param new_keycode New keycode to add/remove |
| 92 | * @param release true if this key was released, false if depressed |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 93 | * Return: number of ascii characters sent, or 0 if none, or -1 for an |
Simon Glass | 2fed04b | 2015-10-18 21:17:24 -0600 | [diff] [blame] | 94 | * internal error |
| 95 | */ |
| 96 | int input_add_keycode(struct input_config *config, int new_keycode, |
| 97 | bool release); |
| 98 | |
| 99 | /** |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 100 | * Add a new key translation table to the input |
| 101 | * |
| 102 | * @param config Input state |
| 103 | * @param left_keycode Key to hold to get into this table |
| 104 | * @param right_keycode Another key to hold to get into this table |
| 105 | * @param xlate Conversion table from key codes to ASCII |
| 106 | * @param num_entries Number of entries in xlate table |
| 107 | */ |
| 108 | int input_add_table(struct input_config *config, int left_keycode, |
| 109 | int right_keycode, const uchar *xlate, int num_entries); |
| 110 | |
| 111 | /** |
| 112 | * Test if keys are available to be read |
| 113 | * |
| 114 | * @param config Input state |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 115 | * Return: 0 if no keys available, 1 if keys are available |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 116 | */ |
| 117 | int input_tstc(struct input_config *config); |
| 118 | |
| 119 | /** |
| 120 | * Read a key |
| 121 | * |
| 122 | * TODO: U-Boot wants 0 for no key, but Ctrl-@ is a valid key... |
| 123 | * |
| 124 | * @param config Input state |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 125 | * Return: key, or 0 if no key, or -1 if error |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 126 | */ |
| 127 | int input_getc(struct input_config *config); |
| 128 | |
| 129 | /** |
| 130 | * Register a new device with stdio and switch to it if wanted |
| 131 | * |
| 132 | * @param dev Pointer to device |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 133 | * Return: 0 if ok, -1 on error |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 134 | */ |
| 135 | int input_stdio_register(struct stdio_dev *dev); |
| 136 | |
| 137 | /** |
Simon Glass | 6bca4f4 | 2012-09-27 15:18:41 +0000 | [diff] [blame] | 138 | * Set up the keyboard autorepeat delays |
| 139 | * |
| 140 | * @param repeat_delay_ms Delay before key auto-repeat starts (in ms) |
| 141 | * @param repeat_rate_ms Delay between successive key repeats (in ms) |
| 142 | */ |
| 143 | void input_set_delays(struct input_config *config, int repeat_delay_ms, |
| 144 | int repeat_rate_ms); |
| 145 | |
| 146 | /** |
Simon Glass | d64a8cb | 2015-10-18 21:17:25 -0600 | [diff] [blame] | 147 | * Tell the input layer whether to allow the caller to determine repeats |
| 148 | * |
| 149 | * Generally the input library handles processing of a list of scanned keys. |
| 150 | * Repeated keys need to be generated based on a timer in this case, since all |
| 151 | * that is provided is a list of keys current depressed. |
| 152 | * |
| 153 | * Keyboards which do their own scanning will resend codes when they want to |
| 154 | * inject a repeating key. This function can be called at start-up to select |
| 155 | * this behaviour. |
| 156 | * |
| 157 | * @param config Input state |
| 158 | * @param allow_repeats true to repeat depressed keys every time |
| 159 | * input_send_keycodes() is called, false to do normal |
| 160 | * keyboard repeat processing with a timer. |
| 161 | */ |
| 162 | void input_allow_repeats(struct input_config *config, bool allow_repeats); |
| 163 | |
| 164 | /** |
Simon Glass | 03fef7e | 2015-11-11 10:05:40 -0700 | [diff] [blame] | 165 | * Check if keyboard LEDs need to be updated |
| 166 | * |
| 167 | * This can be called after input_tstc() to see if keyboard LEDs need |
| 168 | * updating. |
| 169 | * |
| 170 | * @param config Input state |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 171 | * Return: -1 if no LEDs need updating, other value if they do |
Simon Glass | 03fef7e | 2015-11-11 10:05:40 -0700 | [diff] [blame] | 172 | */ |
| 173 | int input_leds_changed(struct input_config *config); |
| 174 | |
| 175 | /** |
Simon Glass | e7817a9 | 2015-10-18 21:17:13 -0600 | [diff] [blame] | 176 | * Set up the key map tables |
| 177 | * |
| 178 | * This must be called after input_init() or keycode decoding will not work. |
| 179 | * |
| 180 | * @param config Input state |
Simon Glass | e6fa485 | 2015-11-11 10:05:37 -0700 | [diff] [blame] | 181 | * @param german true to use German keyboard layout, false for US |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 182 | * Return: 0 if ok, -1 on error |
Simon Glass | e7817a9 | 2015-10-18 21:17:13 -0600 | [diff] [blame] | 183 | */ |
Simon Glass | e6fa485 | 2015-11-11 10:05:37 -0700 | [diff] [blame] | 184 | int input_add_tables(struct input_config *config, bool german); |
Simon Glass | e7817a9 | 2015-10-18 21:17:13 -0600 | [diff] [blame] | 185 | |
| 186 | /** |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 187 | * Set up the input handler with basic key maps. |
| 188 | * |
| 189 | * @param config Input state |
| 190 | * @param leds Initial LED value (INPUT_LED_ mask), 0 suggested |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 191 | * Return: 0 if ok, -1 on error |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 192 | */ |
Simon Glass | 6bca4f4 | 2012-09-27 15:18:41 +0000 | [diff] [blame] | 193 | int input_init(struct input_config *config, int leds); |
Simon Glass | ec9fe92 | 2012-04-17 09:01:30 +0000 | [diff] [blame] | 194 | |
| 195 | #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE |
| 196 | extern int overwrite_console(void); |
| 197 | #define OVERWRITE_CONSOLE overwrite_console() |
| 198 | #else |
| 199 | #define OVERWRITE_CONSOLE 0 |
| 200 | #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */ |
| 201 | |
| 202 | #endif |