1
2
3
4
5
6
7
8
9#include <common.h>
10#include <console.h>
11#include <dm.h>
12#include <errno.h>
13#include <stdio_dev.h>
14#include <input.h>
15#ifdef CONFIG_DM_KEYBOARD
16#include <keyboard.h>
17#endif
18#include <linux/input.h>
19
20enum {
21
22 FLAG_SCROLL_LOCK = 1 << 0,
23 FLAG_NUM_LOCK = 1 << 1,
24 FLAG_CAPS_LOCK = 1 << 2,
25
26
27 KEY_RELEASE = 1 << 15,
28 KEY_MASK = 0xfff,
29};
30
31
32
33
34
35
36
37static const uchar kbd_plain_xlate[] = {
38 0xff, 0x1b, '1', '2', '3', '4', '5', '6',
39 '7', '8', '9', '0', '-', '=', '\b', '\t',
40 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
41 'o', 'p', '[', ']', '\r', 0xff, 'a', 's',
42 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
43 '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v',
44 'b', 'n', 'm', ',' , '.', '/', 0xff, 0xff, 0xff,
45 ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
47 '8', '9', '-', '4', '5', '6', '+', '1',
48 '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 '\r', 0xff, '/', '*',
51};
52
53static unsigned char kbd_shift_xlate[] = {
54 0xff, 0x1b, '!', '@', '#', '$', '%', '^',
55 '&', '*', '(', ')', '_', '+', '\b', '\t',
56 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
57 'O', 'P', '{', '}', '\r', 0xff, 'A', 'S',
58 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
59 '"', '~', 0xff, '|', 'Z', 'X', 'C', 'V',
60 'B', 'N', 'M', '<', '>', '?', 0xff, 0xff, 0xff,
61 ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
62 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
63 '8', '9', '-', '4', '5', '6', '+', '1',
64 '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff, 0xff,
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66 '\r', 0xff, '/', '*',
67};
68
69static unsigned char kbd_ctrl_xlate[] = {
70 0xff, 0x1b, '1', 0x00, '3', '4', '5', 0x1E,
71 '7', '8', '9', '0', 0x1F, '=', '\b', '\t',
72 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09,
73 0x0f, 0x10, 0x1b, 0x1d, '\n', 0xff, 0x01, 0x13,
74 0x04, 0x06, 0x08, 0x09, 0x0a, 0x0b, 0x0c, ';',
75 '\'', '~', 0x00, 0x1c, 0x1a, 0x18, 0x03, 0x16,
76 0x02, 0x0e, 0x0d, '<', '>', '?', 0xff, 0xff,
77 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
79 '8', '9', '-', '4', '5', '6', '+', '1',
80 '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff,
81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82 '\r', 0xff, '/', '*',
83};
84
85
86
87
88static const uchar kbd_plain_xlate_german[] = {
89 0xff, 0x1b, '1', '2', '3', '4', '5', '6',
90 '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t',
91 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i',
92 'o', 'p', 0x81, '+', '\r', 0xff, 'a', 's',
93 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94,
94 0x84, '^', 0xff, '#', 'y', 'x', 'c', 'v',
95 'b', 'n', 'm', ',', '.', '-', 0xff, '*',
96 ' ', ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
98 '8', '9', '-', '4', '5', '6', '+', '1',
99 '2', '3', '0', ',', 0xff, 0xff, '<', 0xff,
100 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
102 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
104 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
105 '\r', 0xff, '/', '*',
106};
107
108static unsigned char kbd_shift_xlate_german[] = {
109 0xff, 0x1b, '!', '"', 0x15, '$', '%', '&',
110 '/', '(', ')', '=', '?', '`', 0x08, '\t',
111 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I',
112 'O', 'P', 0x9a, '*', '\r', 0xff, 'A', 'S',
113 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99,
114 0x8e, 0xf8, 0xff, '\'', 'Y', 'X', 'C', 'V',
115 'B', 'N', 'M', ';', ':', '_', 0xff, '*',
116 ' ', ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
118 '8', '9', '-', '4', '5', '6', '+', '1',
119 '2', '3', '0', ',', 0xff, 0xff, '>', 0xff,
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
123 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
124 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
125 '\r', 0xff, '/', '*',
126};
127
128static unsigned char kbd_right_alt_xlate_german[] = {
129 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
130 '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff,
131 '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
132 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff,
133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
136 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
137 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
138 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
139 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff,
140};
141
142enum kbd_mask {
143 KBD_ENGLISH = 1 << 0,
144 KBD_GERMAN = 1 << 1,
145};
146
147static struct kbd_entry {
148 int kbd_mask;
149 int left_keycode;
150 int right_keycode;
151 const uchar *xlate;
152 int num_entries;
153} kbd_entry[] = {
154 { KBD_ENGLISH, -1, -1,
155 kbd_plain_xlate, ARRAY_SIZE(kbd_plain_xlate) },
156 { KBD_GERMAN, -1, -1,
157 kbd_plain_xlate_german, ARRAY_SIZE(kbd_plain_xlate_german) },
158 { KBD_ENGLISH, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
159 kbd_shift_xlate, ARRAY_SIZE(kbd_shift_xlate) },
160 { KBD_GERMAN, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
161 kbd_shift_xlate_german, ARRAY_SIZE(kbd_shift_xlate_german) },
162 { KBD_ENGLISH | KBD_GERMAN, KEY_LEFTCTRL, KEY_RIGHTCTRL,
163 kbd_ctrl_xlate, ARRAY_SIZE(kbd_ctrl_xlate) },
164 { KBD_GERMAN, -1, KEY_RIGHTALT,
165 kbd_right_alt_xlate_german,
166 ARRAY_SIZE(kbd_right_alt_xlate_german) },
167 {},
168};
169
170
171
172
173
174static struct {
175 int kbd_scan_code;
176 char *escape;
177} kbd_to_ansi364[] = {
178 { KEY_UP, "\033[A"},
179 { KEY_DOWN, "\033[B"},
180 { KEY_RIGHT, "\033[C"},
181 { KEY_LEFT, "\033[D"},
182};
183
184
185#define ANSI_CHAR_MAX 3
186
187static int input_queue_ascii(struct input_config *config, int ch)
188{
189 if (config->fifo_in + 1 == INPUT_BUFFER_LEN) {
190 if (!config->fifo_out)
191 return -1;
192 else
193 config->fifo_in = 0;
194 } else {
195 if (config->fifo_in + 1 == config->fifo_out)
196 return -1;
197 config->fifo_in++;
198 }
199 debug(" {%02x} ", ch);
200 config->fifo[config->fifo_in] = (uchar)ch;
201
202 return 0;
203}
204
205int input_tstc(struct input_config *config)
206{
207 if (config->fifo_in == config->fifo_out && config->read_keys) {
208 if (!(*config->read_keys)(config))
209 return 0;
210 }
211 return config->fifo_in != config->fifo_out;
212}
213
214int input_getc(struct input_config *config)
215{
216 int err = 0;
217
218 while (config->fifo_in == config->fifo_out) {
219 if (config->read_keys)
220 err = (*config->read_keys)(config);
221 if (err)
222 return -1;
223 }
224
225 if (++config->fifo_out == INPUT_BUFFER_LEN)
226 config->fifo_out = 0;
227
228 return config->fifo[config->fifo_out];
229}
230
231
232
233
234
235
236
237
238
239
240
241
242static struct input_key_xlate *process_modifier(struct input_config *config,
243 int key, int release)
244{
245#ifdef CONFIG_DM_KEYBOARD
246 struct udevice *dev = config->dev;
247 struct keyboard_ops *ops = keyboard_get_ops(dev);
248#endif
249 struct input_key_xlate *table;
250 int i;
251
252
253 assert(config->num_tables > 0);
254 table = &config->table[0];
255 for (i = 1; i < config->num_tables; i++) {
256 struct input_key_xlate *tab = &config->table[i];
257
258 if (key == tab->left_keycode || key == tab->right_keycode)
259 table = tab;
260 }
261
262
263 if (!release) {
264 int flip = -1;
265
266 switch (key) {
267 case KEY_SCROLLLOCK:
268 flip = FLAG_SCROLL_LOCK;
269 break;
270 case KEY_NUMLOCK:
271 flip = FLAG_NUM_LOCK;
272 break;
273 case KEY_CAPSLOCK:
274 flip = FLAG_CAPS_LOCK;
275 break;
276 }
277
278 if (flip != -1) {
279 int leds = 0;
280
281 config->flags ^= flip;
282 if (config->flags & FLAG_NUM_LOCK)
283 leds |= INPUT_LED_NUM;
284 if (config->flags & FLAG_CAPS_LOCK)
285 leds |= INPUT_LED_CAPS;
286 if (config->flags & FLAG_SCROLL_LOCK)
287 leds |= INPUT_LED_SCROLL;
288 config->leds = leds;
289 config->leds_changed = flip;
290
291#ifdef CONFIG_DM_KEYBOARD
292 if (ops->update_leds) {
293 if (ops->update_leds(dev, config->leds))
294 debug("Update keyboard's LED failed\n");
295 }
296#endif
297 }
298 }
299
300 return table;
301}
302
303
304
305
306
307
308
309
310
311static int array_search(int *array, int count, int key)
312{
313 int i;
314
315 for (i = 0; i < count; i++) {
316 if (array[i] == key)
317 return i;
318 }
319
320 return -1;
321}
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337static int sort_array_by_ordering(int *dest, int count, int *order,
338 int ocount)
339{
340 int temp[count];
341 int dest_count;
342 int same;
343 int i;
344
345
346 memcpy(temp, dest, count * sizeof(*dest));
347 dest_count = 0;
348
349
350 for (i = 0; i < ocount; i++) {
351 if (array_search(temp, count, order[i]) != -1)
352 dest[dest_count++] = order[i];
353 }
354 same = dest_count;
355
356
357 for (i = 0; i < count; i++) {
358 if (array_search(order, ocount, temp[i]) == -1)
359 dest[dest_count++] = temp[i];
360 }
361 assert(dest_count == count);
362 return same;
363}
364
365
366
367
368
369
370
371
372
373
374
375
376static int input_check_keycodes(struct input_config *config,
377 int keycode[], int num_keycodes, int *same)
378{
379
380 if (!config->num_tables) {
381 debug("%s: No xlate tables: cannot decode keys\n", __func__);
382 return -1;
383 }
384
385
386 *same = sort_array_by_ordering(keycode, num_keycodes,
387 config->prev_keycodes, config->num_prev_keycodes);
388
389 memcpy(config->prev_keycodes, keycode, num_keycodes * sizeof(int));
390 config->num_prev_keycodes = num_keycodes;
391
392 return *same != num_keycodes;
393}
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408static int input_keycode_to_ansi364(struct input_config *config,
409 int keycode, char output_ch[], int max_chars)
410{
411 const char *escape;
412 int ch_count;
413 int i;
414
415 for (i = ch_count = 0; i < ARRAY_SIZE(kbd_to_ansi364); i++) {
416 if (keycode != kbd_to_ansi364[i].kbd_scan_code)
417 continue;
418 for (escape = kbd_to_ansi364[i].escape; *escape; escape++) {
419 if (ch_count < max_chars)
420 output_ch[ch_count] = *escape;
421 ch_count++;
422 }
423 return ch_count;
424 }
425
426 return 0;
427}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451static int input_keycodes_to_ascii(struct input_config *config,
452 int keycode[], int num_keycodes, char output_ch[],
453 int max_chars, int same)
454{
455 struct input_key_xlate *table;
456 int ch_count = 0;
457 int i;
458
459 table = &config->table[0];
460
461
462 for (i = 0; i < num_keycodes; i++) {
463 int key = keycode[i] & KEY_MASK;
464
465 if (key >= table->num_entries || table->xlate[key] == 0xff) {
466 table = process_modifier(config, key,
467 keycode[i] & KEY_RELEASE);
468 }
469 }
470
471
472 for (i = same; i < num_keycodes; i++) {
473 int key = keycode[i];
474 int ch;
475
476
477
478
479
480 if (key < table->num_entries) {
481 ch = table->xlate[key];
482 if ((config->flags & FLAG_CAPS_LOCK) &&
483 ch >= 'a' && ch <= 'z')
484 ch -= 'a' - 'A';
485
486 if (!(config->flags & FLAG_NUM_LOCK)) {
487 if (key >= KEY_KP7 && key <= KEY_KPDOT &&
488 key != KEY_KPMINUS && key != KEY_KPPLUS)
489 ch = 0xff;
490 }
491 if (ch_count < max_chars && ch != 0xff)
492 output_ch[ch_count++] = (uchar)ch;
493 } else {
494 ch_count += input_keycode_to_ansi364(config, key,
495 output_ch, max_chars);
496 }
497 }
498
499 if (ch_count > max_chars) {
500 debug("%s: Output char buffer overflow size=%d, need=%d\n",
501 __func__, max_chars, ch_count);
502 return -1;
503 }
504
505
506 return ch_count;
507}
508
509static int _input_send_keycodes(struct input_config *config, int keycode[],
510 int num_keycodes, bool do_send)
511{
512 char ch[num_keycodes * ANSI_CHAR_MAX];
513 int count, i, same = 0;
514 int is_repeat = 0;
515 unsigned delay_ms;
516
517 config->modifiers = 0;
518 if (!input_check_keycodes(config, keycode, num_keycodes, &same)) {
519
520
521
522
523
524
525
526
527 is_repeat = config->allow_repeats || (config->repeat_rate_ms &&
528 (int)get_timer(config->next_repeat_ms) >= 0);
529 if (!is_repeat)
530 return 0;
531 }
532
533 count = input_keycodes_to_ascii(config, keycode, num_keycodes,
534 ch, sizeof(ch), is_repeat ? 0 : same);
535 if (do_send) {
536 for (i = 0; i < count; i++)
537 input_queue_ascii(config, ch[i]);
538 }
539 delay_ms = is_repeat ?
540 config->repeat_rate_ms :
541 config->repeat_delay_ms;
542
543 config->next_repeat_ms = get_timer(0) + delay_ms;
544
545 return count;
546}
547
548int input_send_keycodes(struct input_config *config, int keycode[],
549 int num_keycodes)
550{
551 return _input_send_keycodes(config, keycode, num_keycodes, true);
552}
553
554int input_add_keycode(struct input_config *config, int new_keycode,
555 bool release)
556{
557 int keycode[INPUT_MAX_MODIFIERS + 1];
558 int count, i;
559
560
561 for (i = 0, count = 0; i < config->num_prev_keycodes; i++) {
562 int code = config->prev_keycodes[i];
563
564 if (new_keycode == code) {
565 if (release)
566 continue;
567 new_keycode = -1;
568 }
569 keycode[count++] = code;
570 }
571
572 if (!release && new_keycode != -1)
573 keycode[count++] = new_keycode;
574 debug("\ncodes for %02x/%d: ", new_keycode, release);
575 for (i = 0; i < count; i++)
576 debug("%02x ", keycode[i]);
577 debug("\n");
578
579
580 return _input_send_keycodes(config, keycode, count, !release);
581}
582
583int input_add_table(struct input_config *config, int left_keycode,
584 int right_keycode, const uchar *xlate, int num_entries)
585{
586 struct input_key_xlate *table;
587
588 if (config->num_tables == INPUT_MAX_MODIFIERS) {
589 debug("%s: Too many modifier tables\n", __func__);
590 return -1;
591 }
592
593 table = &config->table[config->num_tables++];
594 table->left_keycode = left_keycode;
595 table->right_keycode = right_keycode;
596 table->xlate = xlate;
597 table->num_entries = num_entries;
598
599 return 0;
600}
601
602void input_set_delays(struct input_config *config, int repeat_delay_ms,
603 int repeat_rate_ms)
604{
605 config->repeat_delay_ms = repeat_delay_ms;
606 config->repeat_rate_ms = repeat_rate_ms;
607}
608
609void input_allow_repeats(struct input_config *config, bool allow_repeats)
610{
611 config->allow_repeats = allow_repeats;
612}
613
614int input_leds_changed(struct input_config *config)
615{
616 if (config->leds_changed)
617 return config->leds;
618
619 return -1;
620}
621
622int input_add_tables(struct input_config *config, bool german)
623{
624 struct kbd_entry *entry;
625 int mask;
626 int ret;
627
628 mask = german ? KBD_GERMAN : KBD_ENGLISH;
629 for (entry = kbd_entry; entry->kbd_mask; entry++) {
630 if (!(mask & entry->kbd_mask))
631 continue;
632 ret = input_add_table(config, entry->left_keycode,
633 entry->right_keycode, entry->xlate,
634 entry->num_entries);
635 if (ret)
636 return ret;
637 }
638
639 return 0;
640}
641
642int input_init(struct input_config *config, int leds)
643{
644 memset(config, '\0', sizeof(*config));
645 config->leds = leds;
646
647 return 0;
648}
649
650int input_stdio_register(struct stdio_dev *dev)
651{
652 int error;
653
654 error = stdio_register(dev);
655#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(ENV_SUPPORT)
656
657 if (!error && strcmp(env_get("stdin"), dev->name) == 0) {
658
659 if (OVERWRITE_CONSOLE ||
660 console_assign(stdin, dev->name))
661 return -1;
662 }
663#else
664 error = error;
665#endif
666
667 return 0;
668}
669