From 52165966f308a66aa1ec31a6dd9e3b61c17ec496 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 4 Feb 2017 17:44:17 +0100 Subject: 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 Reviewed-on: https://review.coreboot.org/18596 Reviewed-by: Philipp Deppenwiese Tested-by: build bot (Jenkins) --- payloads/libpayload/Kconfig | 1 + payloads/libpayload/drivers/i8042/keyboard.c | 70 +++++++++++++++------------- 2 files changed, 39 insertions(+), 32 deletions(-) (limited to 'payloads/libpayload') diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index e0aa26d1a7..d4d76bbdeb 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -331,6 +331,7 @@ config FONT_SCALE_FACTOR config PC_I8042 bool "A common PC i8042 driver" + default y if PC_KEYBOARD default n help To be used by PC_KEYBOARD and PC_MOUSE. diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index 056aa24957..a4f91b047a 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -2,6 +2,7 @@ * This file is part of the libpayload project. * * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2017 Patrick Rudolph * * Redistribution and use in source and binary forms, with or without * 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_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); - outb(cmd, 0x60); - mdelay(20); + i8042_write_data(cmd); - while (inb(0x64) & 2); - outb(val, 0x60); - mdelay(20); + return i8042_wait_read_ps2() == 0xfa; } int keyboard_havechar(void) { - unsigned char c = inb(0x64); - return (c == 0xFF) ? 0 : c & 1; + return i8042_data_ready_ps2(); } unsigned char keyboard_get_scancode(void) { - unsigned char ch = 0; - - if (keyboard_havechar()) - ch = inb(0x60); - - return ch; + return i8042_read_data_ps2(); } int keyboard_getchar(void) @@ -224,10 +215,12 @@ int keyboard_getchar(void) case 0x3a: if (modifier & MOD_CAPSLOCK) { modifier &= ~MOD_CAPSLOCK; - keyboard_cmd(0xed, (0 << 2)); + if (keyboard_cmd(0xed)) + keyboard_cmd(0 << 2); } else { modifier |= MOD_CAPSLOCK; - keyboard_cmd(0xed, (1 << 2)); + if (keyboard_cmd(0xed)) + keyboard_cmd(1 << 2); } break; } @@ -262,16 +255,6 @@ int keyboard_getchar(void) 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 * @param country string describing the keyboard layout language. @@ -303,11 +286,32 @@ static struct console_input_driver cons = { void keyboard_init(void) { + unsigned int ret; map = &keyboard_layouts[0]; - /* If 0x64 returns 0xff, then we have no keyboard - * controller */ - if (inb(0x64) == 0xFF) + /* Initialized keyboard controller. */ + if (!i8042_probe() || !i8042_has_ps2()) + 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; console_add_input_driver(&cons); @@ -325,10 +329,12 @@ void keyboard_disconnect(void) keyboard_getchar(); /* Send keyboard disconnect command */ - outb(I8042_CMD_DIS_KB, 0x64); - keyboard_wait_write(); + i8042_cmd(I8042_CMD_DIS_KB); /* Hand off with empty buffer */ while (keyboard_havechar()) keyboard_getchar(); + + /* Release keyboard controller driver */ + i8042_close(); } -- cgit v1.2.3