blob: 48255bd87b4857670e4dc20c838a2c49eade8f78 [file] [log] [blame]
wdenkb983fa22004-01-16 00:30:56 +00001/***********************************************************************
2 *
3 * (C) Copyright 2004
4 * DENX Software Engineering
5 * Wolfgang Denk, wd@denx.de
wdenkb983fa22004-01-16 00:30:56 +00006 *
7 * Keyboard driver
8 *
9 ***********************************************************************/
10
11#include <common.h>
Simon Glassa73bda42015-11-08 23:47:45 -070012#include <console.h>
Simon Glass139309b2015-11-11 10:05:48 -070013#include <input.h>
Simon Glassa73bda42015-11-08 23:47:45 -070014
15#include <stdio_dev.h>
wdenkb983fa22004-01-16 00:30:56 +000016#include <keyboard.h>
Simon Glass139309b2015-11-11 10:05:48 -070017#include <stdio_dev.h>
wdenkb983fa22004-01-16 00:30:56 +000018
Simon Glass139309b2015-11-11 10:05:48 -070019static struct input_config config;
wdenkb983fa22004-01-16 00:30:56 +000020
Simon Glass139309b2015-11-11 10:05:48 -070021static int kbd_read_keys(struct input_config *config)
22{
23#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || \
24 defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
25 /* no ISR is used, so received chars must be polled */
26 ps2ser_check();
wdenkdc130442004-12-12 22:06:17 +000027#endif
28
Simon Glass139309b2015-11-11 10:05:48 -070029 return 1;
30}
wdenkb983fa22004-01-16 00:30:56 +000031
Simon Glass139309b2015-11-11 10:05:48 -070032static int check_leds(int ret)
33{
34 int leds;
wdenkb983fa22004-01-16 00:30:56 +000035
Simon Glass139309b2015-11-11 10:05:48 -070036 leds = input_leds_changed(&config);
37 if (leds >= 0)
38 pckbd_leds(leds);
wdenkb983fa22004-01-16 00:30:56 +000039
Simon Glass139309b2015-11-11 10:05:48 -070040 return ret;
wdenkb983fa22004-01-16 00:30:56 +000041}
42
43/* test if a character is in the queue */
Simon Glass0d1e1f72014-07-23 06:54:59 -060044static int kbd_testc(struct stdio_dev *dev)
wdenkb983fa22004-01-16 00:30:56 +000045{
Simon Glass139309b2015-11-11 10:05:48 -070046 return check_leds(input_tstc(&config));
wdenkb983fa22004-01-16 00:30:56 +000047}
48
49/* gets the character from the queue */
Simon Glass0d1e1f72014-07-23 06:54:59 -060050static int kbd_getc(struct stdio_dev *dev)
wdenkb983fa22004-01-16 00:30:56 +000051{
Simon Glass139309b2015-11-11 10:05:48 -070052 return check_leds(input_getc(&config));
wdenkb983fa22004-01-16 00:30:56 +000053}
54
Simon Glass139309b2015-11-11 10:05:48 -070055void handle_scancode(unsigned char scan_code)
wdenkb983fa22004-01-16 00:30:56 +000056{
Simon Glass139309b2015-11-11 10:05:48 -070057 bool release = false;
wdenkb983fa22004-01-16 00:30:56 +000058
Simon Glass139309b2015-11-11 10:05:48 -070059 /* 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;
wdenkb983fa22004-01-16 00:30:56 +000063 }
64
Simon Glass139309b2015-11-11 10:05:48 -070065 input_add_keycode(&config, scan_code, release);
wdenkb983fa22004-01-16 00:30:56 +000066}
67
Simon Glass139309b2015-11-11 10:05:48 -070068/* TODO: convert to driver model */
wdenkb983fa22004-01-16 00:30:56 +000069int kbd_init (void)
70{
Simon Glass139309b2015-11-11 10:05:48 -070071 struct stdio_dev kbddev;
72 struct input_config *input = &config;
wdenkb983fa22004-01-16 00:30:56 +000073
74 if(kbd_init_hw()==-1)
75 return -1;
Wolfgang Denka1be4762008-05-20 16:00:29 +020076 memset (&kbddev, 0, sizeof(kbddev));
Simon Glass139309b2015-11-11 10:05:48 -070077 strcpy(kbddev.name, "kbd");
Bin Meng6abe4b62015-11-03 23:23:37 -080078 kbddev.flags = DEV_FLAGS_INPUT;
Simon Glass139309b2015-11-11 10:05:48 -070079 kbddev.getc = kbd_getc;
80 kbddev.tstc = kbd_testc;
wdenkb983fa22004-01-16 00:30:56 +000081
Simon Glass139309b2015-11-11 10:05:48 -070082 input_init(input, 0);
83 input->read_keys = kbd_read_keys;
84 input_add_tables(input, true);
85
86 return input_stdio_register(&kbddev);
wdenkb983fa22004-01-16 00:30:56 +000087}