wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 1 | /*********************************************************************** |
2 | * | ||||
3 | * (C) Copyright 2004 | ||||
4 | * DENX Software Engineering | ||||
5 | * Wolfgang Denk, wd@denx.de | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 6 | * |
7 | * Keyboard driver | ||||
8 | * | ||||
9 | ***********************************************************************/ | ||||
10 | |||||
11 | #include <common.h> | ||||
Simon Glass | 24b852a | 2015-11-08 23:47:45 -0700 | [diff] [blame] | 12 | #include <console.h> |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 13 | #include <input.h> |
Simon Glass | 24b852a | 2015-11-08 23:47:45 -0700 | [diff] [blame] | 14 | |
15 | #include <stdio_dev.h> | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 16 | #include <keyboard.h> |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 17 | #include <stdio_dev.h> |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 18 | |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 19 | static struct input_config config; |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 20 | |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 21 | static int kbd_read_keys(struct input_config *config) |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 22 | { |
Heiko Schocher | 064b55c | 2017-06-14 05:49:40 +0200 | [diff] [blame] | 23 | #if defined(CONFIG_ARCH_MPC8540) || \ |
York Sun | 3c3d8ab | 2016-11-16 11:23:23 -0800 | [diff] [blame] | 24 | defined(CONFIG_ARCH_MPC8541) || defined(CONFIG_ARCH_MPC8555) |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 25 | /* no ISR is used, so received chars must be polled */ |
26 | ps2ser_check(); | ||||
27 | #endif | ||||
28 | |||||
29 | return 1; | ||||
30 | } | ||||
31 | |||||
32 | static int check_leds(int ret) | ||||
33 | { | ||||
34 | int leds; | ||||
35 | |||||
36 | leds = input_leds_changed(&config); | ||||
37 | if (leds >= 0) | ||||
38 | pckbd_leds(leds); | ||||
39 | |||||
40 | return ret; | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 41 | } |
42 | |||||
43 | /* test if a character is in the queue */ | ||||
Simon Glass | 709ea54 | 2014-07-23 06:54:59 -0600 | [diff] [blame] | 44 | static int kbd_testc(struct stdio_dev *dev) |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 45 | { |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 46 | return check_leds(input_tstc(&config)); |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 47 | } |
48 | |||||
49 | /* gets the character from the queue */ | ||||
Simon Glass | 709ea54 | 2014-07-23 06:54:59 -0600 | [diff] [blame] | 50 | static int kbd_getc(struct stdio_dev *dev) |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 51 | { |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 52 | return check_leds(input_getc(&config)); |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 53 | } |
54 | |||||
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 55 | void handle_scancode(unsigned char scan_code) |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 56 | { |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 57 | bool release = false; |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 58 | |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 59 | /* Compare with i8042_kbd_check() in i8042.c if some logic is missing */ |
60 | if (scan_code & 0x80) { | ||||
61 | scan_code &= 0x7f; | ||||
62 | release = true; | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 63 | } |
64 | |||||
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 65 | input_add_keycode(&config, scan_code, release); |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 66 | } |
67 | |||||
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 68 | /* TODO: convert to driver model */ |
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 69 | int kbd_init (void) |
70 | { | ||||
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 71 | struct stdio_dev kbddev; |
72 | struct input_config *input = &config; | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 73 | |
74 | if(kbd_init_hw()==-1) | ||||
75 | return -1; | ||||
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 76 | memset (&kbddev, 0, sizeof(kbddev)); |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 77 | strcpy(kbddev.name, "kbd"); |
Bin Meng | 1caf934 | 2015-11-03 23:23:37 -0800 | [diff] [blame] | 78 | kbddev.flags = DEV_FLAGS_INPUT; |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 79 | kbddev.getc = kbd_getc; |
80 | kbddev.tstc = kbd_testc; | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 81 | |
Simon Glass | 91f8154 | 2015-11-11 10:05:48 -0700 | [diff] [blame] | 82 | input_init(input, 0); |
83 | input->read_keys = kbd_read_keys; | ||||
84 | input_add_tables(input, true); | ||||
85 | |||||
86 | return input_stdio_register(&kbddev); | ||||
wdenk | 1c43771 | 2004-01-16 00:30:56 +0000 | [diff] [blame] | 87 | } |