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