[coreboot-gerrit] New patch to review for coreboot: 6616d9c libpayload: Add PS/2 keyboard mode setting code back

Andrew Wu (arw@dmp.com.tw) gerrit at coreboot.org
Tue Oct 8 12:08:08 CEST 2013


Andrew Wu (arw at dmp.com.tw) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3956

-gerrit

commit 6616d9c9a93506e4a9177037e05a254ef901e7aa
Author: Andrew Wu <arw at dmp.com.tw>
Date:   Tue Oct 8 17:58:14 2013 +0800

    libpayload: Add PS/2 keyboard mode setting code back
    
    PS/2 keyboard controller may not set the 'XLATE' bit on boot by
    default.
    
    Revert keyboard.c to earlier version (commit a2d78), which sets
    the 'XLATE' bit. Add keyboard disabling/enabling during setting
    mode register to avoid scancode data interference, so the problem
    mentioned in commit dd6c4 is still fixed.
    
    Tested on Vortex86EX hardware with PS/2 keyboard.
    
    Change-Id: I42cedfdff2db5cfba39de8811284a72a9793f294
    Signed-off-by: Andrew Wu <arw at dmp.com.tw>
---
 payloads/libpayload/drivers/keyboard.c | 74 ++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/payloads/libpayload/drivers/keyboard.c b/payloads/libpayload/drivers/keyboard.c
index e65f085..5fa90dd 100644
--- a/payloads/libpayload/drivers/keyboard.c
+++ b/payloads/libpayload/drivers/keyboard.c
@@ -31,6 +31,13 @@
 #include <libpayload-config.h>
 #include <libpayload.h>
 
+#define I8042_CMD_READ_MODE  0x20
+#define I8042_CMD_WRITE_MODE 0x60
+#define I8042_CMD_DISABLE_KB 0xad
+#define I8042_CMD_ENABLE_KB  0xae
+
+#define I8042_MODE_XLATE     0x40
+
 struct layout_maps {
 	const char *country;
 	const unsigned short map[4][0x57];
@@ -256,6 +263,54 @@ int keyboard_getchar(void)
 	return ret;
 }
 
+static int keyboard_wait_read(void)
+{
+	int retries = 10000;
+
+	while(retries-- && !(inb(0x64) & 0x01))
+		udelay(50);
+
+	return (retries <= 0) ? -1 : 0;
+}
+
+static int keyboard_wait_write(void)
+{
+	int retries = 10000;
+
+	while(retries-- && (inb(0x64) & 0x02))
+		udelay(50);
+
+	return (retries <= 0) ? -1 : 0;
+}
+
+static unsigned char keyboard_get_mode(void)
+{
+	keyboard_wait_write();
+	outb(I8042_CMD_READ_MODE, 0x64);
+	keyboard_wait_read();
+	return inb(0x60);
+}
+
+static void keyboard_set_mode(unsigned char mode)
+{
+	keyboard_wait_write();
+	outb(I8042_CMD_WRITE_MODE, 0x64);
+	keyboard_wait_write();
+	outb(mode, 0x60);
+}
+
+static void keyboard_disable(void)
+{
+	keyboard_wait_write();
+	outb(I8042_CMD_DISABLE_KB, 0x64);
+}
+
+static void keyboard_enable(void)
+{
+	keyboard_wait_write();
+	outb(I8042_CMD_ENABLE_KB, 0x64);
+}
+
 /**
  * Set keyboard layout
  * @param country string describing the keyboard layout language.
@@ -287,16 +342,35 @@ static struct console_input_driver cons = {
 
 void keyboard_init(void)
 {
+	u8 mode;
 	map = &keyboard_layouts[0];
 
 	/* If 0x64 returns 0xff, then we have no keyboard
 	 * controller */
+
 	if (inb(0x64) == 0xFF)
 		return;
 
 	/* Empty keyboard buffer */
 	while (keyboard_havechar()) keyboard_getchar();
 
+	/* Before setup keyboard, lock keyboard input first */
+	keyboard_disable();
+
+	/* Read the current mode */
+	mode = keyboard_get_mode();
+
+	/* Turn on scancode translate mode so that we can
+	   use the scancode set 1 tables */
+
+	mode |= I8042_MODE_XLATE;
+
+	/* Write the new mode */
+	keyboard_set_mode(mode);
+
+	/* Now it is safe to enable keyboard input */
+	keyboard_enable();
+
 	console_add_input_driver(&cons);
 }
 



More information about the coreboot-gerrit mailing list