libpayload-x86: keyboard: Use i8042 driver
Make use of i8042 driver in keyboard.c. Required to add PS/2 mouse support. Tested on Lenovo T500. Change-Id: If60b5ed922b8fc4b552d0bfd9fe20c0fd6c776bf Signed-off-by: Patrick Rudolph <siro@das-labor.org> Reviewed-on: https://review.coreboot.org/18596 Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
717ba74836
commit
52165966f3
|
@ -331,6 +331,7 @@ config FONT_SCALE_FACTOR
|
||||||
|
|
||||||
config PC_I8042
|
config PC_I8042
|
||||||
bool "A common PC i8042 driver"
|
bool "A common PC i8042 driver"
|
||||||
|
default y if PC_KEYBOARD
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
To be used by PC_KEYBOARD and PC_MOUSE.
|
To be used by PC_KEYBOARD and PC_MOUSE.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* This file is part of the libpayload project.
|
* This file is part of the libpayload project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||||
|
* Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -162,31 +163,21 @@ static struct layout_maps keyboard_layouts[] = {
|
||||||
#define MOD_CAPSLOCK (1 << 2)
|
#define MOD_CAPSLOCK (1 << 2)
|
||||||
#define MOD_ALT (1 << 3)
|
#define MOD_ALT (1 << 3)
|
||||||
|
|
||||||
static void keyboard_cmd(unsigned char cmd, unsigned char val)
|
static unsigned char keyboard_cmd(unsigned char cmd)
|
||||||
{
|
{
|
||||||
while (inb(0x64) & 2);
|
i8042_write_data(cmd);
|
||||||
outb(cmd, 0x60);
|
|
||||||
mdelay(20);
|
|
||||||
|
|
||||||
while (inb(0x64) & 2);
|
return i8042_wait_read_ps2() == 0xfa;
|
||||||
outb(val, 0x60);
|
|
||||||
mdelay(20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int keyboard_havechar(void)
|
int keyboard_havechar(void)
|
||||||
{
|
{
|
||||||
unsigned char c = inb(0x64);
|
return i8042_data_ready_ps2();
|
||||||
return (c == 0xFF) ? 0 : c & 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char keyboard_get_scancode(void)
|
unsigned char keyboard_get_scancode(void)
|
||||||
{
|
{
|
||||||
unsigned char ch = 0;
|
return i8042_read_data_ps2();
|
||||||
|
|
||||||
if (keyboard_havechar())
|
|
||||||
ch = inb(0x60);
|
|
||||||
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int keyboard_getchar(void)
|
int keyboard_getchar(void)
|
||||||
|
@ -224,10 +215,12 @@ int keyboard_getchar(void)
|
||||||
case 0x3a:
|
case 0x3a:
|
||||||
if (modifier & MOD_CAPSLOCK) {
|
if (modifier & MOD_CAPSLOCK) {
|
||||||
modifier &= ~MOD_CAPSLOCK;
|
modifier &= ~MOD_CAPSLOCK;
|
||||||
keyboard_cmd(0xed, (0 << 2));
|
if (keyboard_cmd(0xed))
|
||||||
|
keyboard_cmd(0 << 2);
|
||||||
} else {
|
} else {
|
||||||
modifier |= MOD_CAPSLOCK;
|
modifier |= MOD_CAPSLOCK;
|
||||||
keyboard_cmd(0xed, (1 << 2));
|
if (keyboard_cmd(0xed))
|
||||||
|
keyboard_cmd(1 << 2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -262,16 +255,6 @@ int keyboard_getchar(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int keyboard_wait_write(void)
|
|
||||||
{
|
|
||||||
int retries = 10000;
|
|
||||||
|
|
||||||
while(retries-- && (inb(0x64) & 0x02))
|
|
||||||
udelay(50);
|
|
||||||
|
|
||||||
return (retries <= 0) ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set keyboard layout
|
* Set keyboard layout
|
||||||
* @param country string describing the keyboard layout language.
|
* @param country string describing the keyboard layout language.
|
||||||
|
@ -303,11 +286,32 @@ static struct console_input_driver cons = {
|
||||||
|
|
||||||
void keyboard_init(void)
|
void keyboard_init(void)
|
||||||
{
|
{
|
||||||
|
unsigned int ret;
|
||||||
map = &keyboard_layouts[0];
|
map = &keyboard_layouts[0];
|
||||||
|
|
||||||
/* If 0x64 returns 0xff, then we have no keyboard
|
/* Initialized keyboard controller. */
|
||||||
* controller */
|
if (!i8042_probe() || !i8042_has_ps2())
|
||||||
if (inb(0x64) == 0xFF)
|
return;
|
||||||
|
|
||||||
|
/* Empty keyboard buffer */
|
||||||
|
while (keyboard_havechar())
|
||||||
|
keyboard_getchar();
|
||||||
|
|
||||||
|
/* Enable first PS/2 port */
|
||||||
|
i8042_cmd(0xae);
|
||||||
|
|
||||||
|
/* Set scancode set 1 */
|
||||||
|
ret = keyboard_cmd(0xf0);
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = keyboard_cmd(0x01);
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Enable scanning */
|
||||||
|
ret = keyboard_cmd(0xf4);
|
||||||
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
console_add_input_driver(&cons);
|
console_add_input_driver(&cons);
|
||||||
|
@ -325,10 +329,12 @@ void keyboard_disconnect(void)
|
||||||
keyboard_getchar();
|
keyboard_getchar();
|
||||||
|
|
||||||
/* Send keyboard disconnect command */
|
/* Send keyboard disconnect command */
|
||||||
outb(I8042_CMD_DIS_KB, 0x64);
|
i8042_cmd(I8042_CMD_DIS_KB);
|
||||||
keyboard_wait_write();
|
|
||||||
|
|
||||||
/* Hand off with empty buffer */
|
/* Hand off with empty buffer */
|
||||||
while (keyboard_havechar())
|
while (keyboard_havechar())
|
||||||
keyboard_getchar();
|
keyboard_getchar();
|
||||||
|
|
||||||
|
/* Release keyboard controller driver */
|
||||||
|
i8042_close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue