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