blob: 84ee015cb33e88ffc4656f8a158224f70da31c0e [file] [log] [blame]
wdenk1c437712004-01-16 00:30:56 +00001/***********************************************************************
2 *
3 * (C) Copyright 2004
4 * DENX Software Engineering
5 * Wolfgang Denk, wd@denx.de
wdenk1c437712004-01-16 00:30:56 +00006 *
7 * Keyboard driver
8 *
9 ***********************************************************************/
10
11#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -070012#include <console.h>
Simon Glass91f81542015-11-11 10:05:48 -070013#include <input.h>
Simon Glass24b852a2015-11-08 23:47:45 -070014
15#include <stdio_dev.h>
wdenk1c437712004-01-16 00:30:56 +000016#include <keyboard.h>
Simon Glass91f81542015-11-11 10:05:48 -070017#include <stdio_dev.h>
wdenk1c437712004-01-16 00:30:56 +000018
Simon Glass91f81542015-11-11 10:05:48 -070019static struct input_config config;
wdenk1c437712004-01-16 00:30:56 +000020
Simon Glass91f81542015-11-11 10:05:48 -070021static int kbd_read_keys(struct input_config *config)
wdenk1c437712004-01-16 00:30:56 +000022{
Heiko Schocher064b55c2017-06-14 05:49:40 +020023#if defined(CONFIG_ARCH_MPC8540) || \
York Sun3c3d8ab2016-11-16 11:23:23 -080024 defined(CONFIG_ARCH_MPC8541) || defined(CONFIG_ARCH_MPC8555)
Simon Glass91f81542015-11-11 10:05:48 -070025 /* no ISR is used, so received chars must be polled */
26 ps2ser_check();
27#endif
28
29 return 1;
30}
31
32static 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;
wdenk1c437712004-01-16 00:30:56 +000041}
42
43/* test if a character is in the queue */
Simon Glass709ea542014-07-23 06:54:59 -060044static int kbd_testc(struct stdio_dev *dev)
wdenk1c437712004-01-16 00:30:56 +000045{
Simon Glass91f81542015-11-11 10:05:48 -070046 return check_leds(input_tstc(&config));
wdenk1c437712004-01-16 00:30:56 +000047}
48
49/* gets the character from the queue */
Simon Glass709ea542014-07-23 06:54:59 -060050static int kbd_getc(struct stdio_dev *dev)
wdenk1c437712004-01-16 00:30:56 +000051{
Simon Glass91f81542015-11-11 10:05:48 -070052 return check_leds(input_getc(&config));
wdenk1c437712004-01-16 00:30:56 +000053}
54
Simon Glass91f81542015-11-11 10:05:48 -070055void handle_scancode(unsigned char scan_code)
wdenk1c437712004-01-16 00:30:56 +000056{
Simon Glass91f81542015-11-11 10:05:48 -070057 bool release = false;
wdenk1c437712004-01-16 00:30:56 +000058
Simon Glass91f81542015-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;
wdenk1c437712004-01-16 00:30:56 +000063 }
64
Simon Glass91f81542015-11-11 10:05:48 -070065 input_add_keycode(&config, scan_code, release);
wdenk1c437712004-01-16 00:30:56 +000066}
67
Simon Glass91f81542015-11-11 10:05:48 -070068/* TODO: convert to driver model */
wdenk1c437712004-01-16 00:30:56 +000069int kbd_init (void)
70{
Simon Glass91f81542015-11-11 10:05:48 -070071 struct stdio_dev kbddev;
72 struct input_config *input = &config;
wdenk1c437712004-01-16 00:30:56 +000073
74 if(kbd_init_hw()==-1)
75 return -1;
Wolfgang Denk53677ef2008-05-20 16:00:29 +020076 memset (&kbddev, 0, sizeof(kbddev));
Simon Glass91f81542015-11-11 10:05:48 -070077 strcpy(kbddev.name, "kbd");
Bin Meng1caf9342015-11-03 23:23:37 -080078 kbddev.flags = DEV_FLAGS_INPUT;
Simon Glass91f81542015-11-11 10:05:48 -070079 kbddev.getc = kbd_getc;
80 kbddev.tstc = kbd_testc;
wdenk1c437712004-01-16 00:30:56 +000081
Simon Glass91f81542015-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);
wdenk1c437712004-01-16 00:30:56 +000087}