blob: 71546cb086cd11d0ef37b1028a2c3bbbea74ef3d [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 Glass139309b2015-11-11 10:05:48 -070012#include <input.h>
wdenkb983fa22004-01-16 00:30:56 +000013#include <keyboard.h>
Simon Glass139309b2015-11-11 10:05:48 -070014#include <stdio_dev.h>
wdenkb983fa22004-01-16 00:30:56 +000015
Simon Glass139309b2015-11-11 10:05:48 -070016static struct input_config config;
wdenkb983fa22004-01-16 00:30:56 +000017
Simon Glass139309b2015-11-11 10:05:48 -070018static 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();
wdenkdc130442004-12-12 22:06:17 +000024#endif
25
Simon Glass139309b2015-11-11 10:05:48 -070026 return 1;
27}
wdenkb983fa22004-01-16 00:30:56 +000028
Simon Glass139309b2015-11-11 10:05:48 -070029static int check_leds(int ret)
30{
31 int leds;
wdenkb983fa22004-01-16 00:30:56 +000032
Simon Glass139309b2015-11-11 10:05:48 -070033 leds = input_leds_changed(&config);
34 if (leds >= 0)
35 pckbd_leds(leds);
wdenkb983fa22004-01-16 00:30:56 +000036
Simon Glass139309b2015-11-11 10:05:48 -070037 return ret;
wdenkb983fa22004-01-16 00:30:56 +000038}
39
40/* test if a character is in the queue */
Simon Glass0d1e1f72014-07-23 06:54:59 -060041static int kbd_testc(struct stdio_dev *dev)
wdenkb983fa22004-01-16 00:30:56 +000042{
Simon Glass139309b2015-11-11 10:05:48 -070043 return check_leds(input_tstc(&config));
wdenkb983fa22004-01-16 00:30:56 +000044}
45
46/* gets the character from the queue */
Simon Glass0d1e1f72014-07-23 06:54:59 -060047static int kbd_getc(struct stdio_dev *dev)
wdenkb983fa22004-01-16 00:30:56 +000048{
Simon Glass139309b2015-11-11 10:05:48 -070049 return check_leds(input_getc(&config));
wdenkb983fa22004-01-16 00:30:56 +000050}
51
Simon Glass139309b2015-11-11 10:05:48 -070052void handle_scancode(unsigned char scan_code)
wdenkb983fa22004-01-16 00:30:56 +000053{
Simon Glass139309b2015-11-11 10:05:48 -070054 bool release = false;
wdenkb983fa22004-01-16 00:30:56 +000055
Simon Glass139309b2015-11-11 10:05:48 -070056 /* 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;
wdenkb983fa22004-01-16 00:30:56 +000060 }
61
Simon Glass139309b2015-11-11 10:05:48 -070062 input_add_keycode(&config, scan_code, release);
wdenkb983fa22004-01-16 00:30:56 +000063}
64
Simon Glass139309b2015-11-11 10:05:48 -070065/* TODO: convert to driver model */
wdenkb983fa22004-01-16 00:30:56 +000066int kbd_init (void)
67{
Simon Glass139309b2015-11-11 10:05:48 -070068 struct stdio_dev kbddev;
69 struct input_config *input = &config;
wdenkb983fa22004-01-16 00:30:56 +000070
71 if(kbd_init_hw()==-1)
72 return -1;
Wolfgang Denka1be4762008-05-20 16:00:29 +020073 memset (&kbddev, 0, sizeof(kbddev));
Simon Glass139309b2015-11-11 10:05:48 -070074 strcpy(kbddev.name, "kbd");
Bin Meng6abe4b62015-11-03 23:23:37 -080075 kbddev.flags = DEV_FLAGS_INPUT;
Simon Glass139309b2015-11-11 10:05:48 -070076 kbddev.getc = kbd_getc;
77 kbddev.tstc = kbd_testc;
wdenkb983fa22004-01-16 00:30:56 +000078
Simon Glass139309b2015-11-11 10:05:48 -070079 input_init(input, 0);
80 input->read_keys = kbd_read_keys;
81 input_add_tables(input, true);
82
83 return input_stdio_register(&kbddev);
wdenkb983fa22004-01-16 00:30:56 +000084}