Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ HelenOS.config	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -486,5 +486,5 @@
 
 % PC keyboard support
-! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_PC_KBD (y/n)
+! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_AT_KBD (y/n)
 
 % Support for msim keyboard
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ boot/arch/arm32/Makefile.inc	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -74,5 +74,5 @@
 	RD_DRVS_ESSENTIAL += \
 		char/pl050 \
-		char/xtkbd \
+		char/atkbd \
 		char/ps2mouse \
 		platform/icp
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ kernel/genarch/Makefile.inc	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -141,4 +141,10 @@
 endif
 
+ifeq ($(CONFIG_AT_KBD),y)
+GENARCH_SOURCES += \
+	genarch/src/kbrd/kbrd_at.c \
+	genarch/src/kbrd/scanc_at.c
+endif
+
 ifeq ($(CONFIG_SUN_KBD),y)
 GENARCH_SOURCES += \
Index: kernel/genarch/include/genarch/kbrd/scanc_at.h
===================================================================
--- kernel/genarch/include/genarch/kbrd/scanc_at.h	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ kernel/genarch/include/genarch/kbrd/scanc_at.h	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Scan codes for PC/AT keyboards.
+ */
+
+#ifndef KERN_SCANC_AT_H_
+#define KERN_SCANC_AT_H_
+
+#define SC_SCAN_ESCAPE	0xE0
+#define SC_ESC		0x76
+#define SC_BACKSPACE	0x66
+#define SC_LSHIFT       0x12
+#define SC_RSHIFT       0x59
+#define SC_CAPSLOCK     0x58
+#define SC_SPEC_ESCAPE  0xe0
+#define SC_LEFTARR      0x6b
+#define SC_RIGHTARR     0x74
+#define SC_UPARR        0x75
+#define SC_DOWNARR      0x72
+#define SC_DELETE       0x70
+#define SC_HOME         0x6C
+#define SC_END          0x69
+
+#endif
+
+/** @}
+ */
Index: rnel/genarch/include/genarch/kbrd/scanc_pl050.h
===================================================================
--- kernel/genarch/include/genarch/kbrd/scanc_pl050.h	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2009 Vineeth Pillai
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch	
- * @{
- */
-/**
- * @file
- * @brief	Scan codes for pl050 keyboards.
- */
-
-#ifndef KERN_SCANC_PL050_H_
-#define KERN_SCANC_PL050_H_
-
-#define SC_SCAN_ESCAPE	0xE0
-#define SC_ESC		0x76
-#define SC_BACKSPACE	0x66
-#define SC_LSHIFT       0x12
-#define SC_RSHIFT       0x59
-#define SC_CAPSLOCK     0x58
-#define SC_SPEC_ESCAPE  0xe0
-#define SC_LEFTARR      0x6b
-#define SC_RIGHTARR     0x74
-#define SC_UPARR        0x75
-#define SC_DOWNARR      0x72
-#define SC_DELETE       0x70
-#define SC_HOME         0x6C
-#define SC_END          0x69
-
-#endif
-
-/** @}
- */
Index: kernel/genarch/src/kbrd/kbrd_at.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_at.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ kernel/genarch/src/kbrd/kbrd_at.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief PC/AT Keyboard processing.
+ */
+
+#include <genarch/kbrd/kbrd.h>
+#include <genarch/kbrd/scanc.h>
+
+#include <genarch/kbrd/scanc_at.h>
+
+#include <synch/spinlock.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <proc/thread.h>
+#include <arch.h>
+#include <macros.h>
+
+#define PRESSED_SHIFT     (1 << 0)
+#define PRESSED_CAPSLOCK  (1 << 1)
+#define LOCKED_CAPSLOCK   (1 << 0)
+
+#define AT_KEY_RELEASE		0xF0
+#define AT_ESC_KEY		0xE0
+#define AT_CAPS_SCAN_CODE	0x58
+#define AT_NUM_SCAN_CODE	0x77
+#define AT_SCROLL_SCAN_CODE	0x7E
+
+static bool is_lock_key(wchar_t);
+
+static indev_operations_t kbrd_raw_ops = {
+	.poll = NULL
+};
+
+/** Process release of key.
+ *
+ * @param sc Scancode of the key being released.
+ */
+static void key_released(kbrd_instance_t *instance, wchar_t sc)
+{
+	spinlock_lock(&instance->keylock);
+	
+	switch (sc) {
+	case SC_LSHIFT:
+	case SC_RSHIFT:
+		instance->keyflags &= ~PRESSED_SHIFT;
+		break;
+	case SC_CAPSLOCK:
+		instance->keyflags &= ~PRESSED_CAPSLOCK;
+		if (instance->lockflags & LOCKED_CAPSLOCK)
+			instance->lockflags &= ~LOCKED_CAPSLOCK;
+		else
+			instance->lockflags |= LOCKED_CAPSLOCK;
+		break;
+	default:
+		break;
+	}
+	
+	spinlock_unlock(&instance->keylock);
+}
+
+/** Process keypress.
+ *
+ * @param sc Scancode of the key being pressed.
+ */
+static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+{
+	bool letter;
+	bool shift;
+	bool capslock;
+	
+	spinlock_lock(&instance->keylock);
+	
+	switch (sc) {
+	case SC_LSHIFT:
+	case SC_RSHIFT:
+		instance->keyflags |= PRESSED_SHIFT;
+		break;
+	case SC_CAPSLOCK:
+		instance->keyflags |= PRESSED_CAPSLOCK;
+		break;
+	case SC_SCAN_ESCAPE:
+		break;
+	default:
+		letter = islower(sc_primary_map[sc]);
+		shift = instance->keyflags & PRESSED_SHIFT;
+		capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
+		    (instance->lockflags & LOCKED_CAPSLOCK);
+		
+		if ((letter) && (capslock))
+			shift = !shift;
+		
+		if (shift)
+			indev_push_character(instance->sink, sc_secondary_map[sc]);
+		else
+			indev_push_character(instance->sink, sc_primary_map[sc]);
+		break;
+	}
+	
+	spinlock_unlock(&instance->keylock);
+}
+
+static void kkbrd(void *arg)
+{
+	static int key_released_flag = 0;
+	static int is_locked = 0;
+	kbrd_instance_t *instance = (kbrd_instance_t *) arg;
+	
+	while (true) {
+		wchar_t sc = indev_pop_character(&instance->raw);
+
+		if (sc == AT_KEY_RELEASE) {
+			key_released_flag = 1;
+		} else {
+			if (key_released_flag) {
+				key_released_flag = 0;
+				if (is_lock_key(sc)) {
+					if (!is_locked) {
+						is_locked = 1;
+					} else {
+						is_locked = 0;
+						continue;
+					}
+				}
+				key_released(instance, sc);
+
+			} else {
+				if (is_lock_key(sc) && is_locked)
+					continue;
+				key_pressed(instance, sc);
+			}
+		}
+		
+	}
+}
+
+kbrd_instance_t *kbrd_init(void)
+{
+	kbrd_instance_t *instance;
+
+	instance = malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
+	if (instance) {
+		instance->thread = thread_create(kkbrd, (void *) instance, TASK, 0,
+		    "kkbrd");
+		
+		if (!instance->thread) {
+			free(instance);
+			return NULL;
+		}
+		
+		instance->sink = NULL;
+		indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
+		
+		spinlock_initialize(&instance->keylock, "kbrd_at.instance.keylock");
+		instance->keyflags = 0;
+		instance->lockflags = 0;
+	}
+	
+	return instance;
+}
+
+indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
+{
+	ASSERT(instance);
+	ASSERT(sink);
+	
+	instance->sink = sink;
+	thread_ready(instance->thread);
+	
+	return &instance->raw;
+}
+
+static bool is_lock_key(wchar_t sc)
+{
+	return ((sc == AT_CAPS_SCAN_CODE) || (sc == AT_NUM_SCAN_CODE) ||
+	    (sc == AT_SCROLL_SCAN_CODE));
+}
+
+/** @}
+ */
Index: kernel/genarch/src/kbrd/scanc_at.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_at.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ kernel/genarch/src/kbrd/scanc_at.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, U_SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Scan codes for PC/AT keyboards (set 2).
+ */
+#include <genarch/kbrd/scanc.h>
+#include <typedefs.h>
+#include <str.h>
+
+
+/** Primary meaning of scancodes. */
+wchar_t sc_primary_map[] = {
+	U_NULL, /* 0x00 */
+	U_SPECIAL, /* 0x01 - F9 */
+	U_SPECIAL, /* 0x02 - F7 */
+	U_SPECIAL, /* 0x03 - F5 */
+	U_SPECIAL, /* 0x04 - F3 */
+	U_SPECIAL, /* 0x05 - F1 */
+	U_SPECIAL, /* 0x06 - F2 */
+	U_SPECIAL, /* 0x07 - F12 */
+	U_SPECIAL, /* 0x08 -  */
+	U_SPECIAL, /* 0x09 - F10 */
+	U_SPECIAL, /* 0x0A - F8 */
+	U_SPECIAL, /* 0x0B - F10 */
+	U_SPECIAL, /* 0x0C - F4 */
+	'\t', /* 0x0D - Tab */
+	'`',
+	U_SPECIAL, /* 0x0F */
+	U_SPECIAL, /* 0x10 */
+	U_SPECIAL, /* 0x11 - LAlt */
+	U_SPECIAL, /* 0x12 - LShift */
+	U_SPECIAL, /* ox13 */
+	U_SPECIAL, /* 0x14 Ctrl */
+	'q', '1',
+	U_SPECIAL, /* 0x17 */
+	U_SPECIAL, /* 0x18 */
+	U_SPECIAL, /* 0x19 */
+	'z', 's', 'a', 'w', '2',
+	U_SPECIAL, /* 0x1F */
+	U_SPECIAL, /* 0x20 */
+	'c', 'x', 'd', 'e', '4', '3',
+	U_SPECIAL, /* 0x27 */
+	U_SPECIAL, /* 0x28 */
+	' ', 'v', 'f', 't', 'r', '5',
+	U_SPECIAL, /* 0x2F */
+	U_SPECIAL, /* 0x30 */
+	'n', 'b', 'h', 'g', 'y', '6',
+	U_SPECIAL, /* 0x37 */
+	U_SPECIAL, /* 0x38 */
+	U_SPECIAL, /* 0x39 */
+	'm', 'j', 'u', '7', '8',
+	U_SPECIAL, /* 0x3F */
+	U_SPECIAL, /* 0x40 */
+	',', 'k', 'i', 'o', '0', '9',
+	U_SPECIAL, /* 0x47 */
+	U_SPECIAL, /* 0x48 */
+	'.', '/', 'l', ';', 'p', '-',
+	U_SPECIAL, /* 0x4F */
+	U_SPECIAL, /* 0x50 */
+	U_SPECIAL, /* 0x51 */
+	'\'',
+	U_SPECIAL, /* 0x53 */
+	'[', '=',
+	U_SPECIAL, /* 0x56 */
+	U_SPECIAL, /* 0x57 */
+	U_SPECIAL, /* 0x58 - Caps Lock */
+	U_SPECIAL, /* 0x59 - RShift */
+	'\n', ']',
+	U_SPECIAL, /* 0x5C */
+	'\\',
+	U_SPECIAL, /* 0x5E */
+	U_SPECIAL, /* 0x5F */
+	U_SPECIAL, /* 0x60 */
+	U_SPECIAL, /* 0x61 */
+	U_SPECIAL, /* 0x62 */
+	U_SPECIAL, /* 0x63 */
+	U_SPECIAL, /* 0x64 */
+	U_SPECIAL, /* 0x65 */
+	'\b', /* 0x66  - backspace*/
+	U_SPECIAL, /* 0x67 */
+	U_SPECIAL, /* 0x68 */
+	U_END_ARROW, /* 0x69 */
+	U_SPECIAL, /* 0x6a */
+	U_LEFT_ARROW, /* 0x6b - Left Arrow */
+	U_SPECIAL, /* 0x6c */
+	U_SPECIAL, /* 0x6d */
+	U_SPECIAL, /* 0x6e */
+	U_SPECIAL, /* 0x6f */
+	U_SPECIAL, /* 0x70 */
+	U_DELETE, /* 0x71 - Del*/
+	U_DOWN_ARROW, /* 0x72 Down Arrow */
+	U_SPECIAL, /* 0x73 */
+	U_RIGHT_ARROW, /* 0x74  - Right Arrow */
+	U_UP_ARROW, /* 0x75  Up Arrow */
+	U_ESCAPE, /* 0x76 Esc */
+	U_SPECIAL, /* 0x77 - NumLock*/
+	U_SPECIAL, /* 0x78  F11*/
+	U_SPECIAL, /* 0x79 */
+	U_PAGE_DOWN, /* 0x7a */
+	U_SPECIAL, /* 0x7b */
+	U_SPECIAL, /* 0x7c */
+	U_PAGE_UP, /* 0x7d */
+	U_SPECIAL, /* 0x7e */
+	U_SPECIAL /* 0x7f */
+};
+
+/** Secondary meaning of scancodes. */
+wchar_t sc_secondary_map[] = {
+	U_NULL, /* 0x00 */
+	U_SPECIAL, /* 0x01 - F9 */
+	U_SPECIAL, /* 0x02 - F7 */
+	U_SPECIAL, /* 0x03 - F5 */
+	U_SPECIAL, /* 0x04 - F3 */
+	U_SPECIAL, /* 0x05 - F1 */
+	U_SPECIAL, /* 0x06 - F2 */
+	U_SPECIAL, /* 0x07 - F12 */
+	U_SPECIAL, /* 0x08 -  */
+	U_SPECIAL, /* 0x09 - F10 */
+	U_SPECIAL, /* 0x0A - F8 */
+	U_SPECIAL, /* 0x0B - F10 */
+	U_SPECIAL, /* 0x0C - F4 */
+	'\t', /* 0x0D - Tab */
+	'~',
+	U_SPECIAL, /* 0x0F */
+	U_SPECIAL, /* 0x10 */
+	U_SPECIAL, /* 0x11 - LAlt */
+	U_SPECIAL, /* 0x12 - LShift */
+	U_SPECIAL, /* ox13 */
+	U_SPECIAL, /* 0x14 Ctrl */
+	'Q', '!',
+	U_SPECIAL, /* 0x17 */
+	U_SPECIAL, /* 0x18 */
+	U_SPECIAL, /* 0x19 */
+	'Z', 'S', 'A', 'W', '@',
+	U_SPECIAL, /* 0x1F */
+	U_SPECIAL, /* 0x20 */
+	'C', 'X', 'D', 'E', '$', '#',
+	U_SPECIAL, /* 0x27 */
+	U_SPECIAL, /* 0x28 */
+	' ', 'V', 'F', 'T', 'R', '%',
+	U_SPECIAL, /* 0x2F */
+	U_SPECIAL, /* 0x30 */
+	'N', 'B', 'H', 'G', 'Y', '^',
+	U_SPECIAL, /* 0x37 */
+	U_SPECIAL, /* 0x38 */
+	U_SPECIAL, /* 0x39 */
+	'M', 'J', 'U', '&', '*',
+	U_SPECIAL, /* 0x3F */
+	U_SPECIAL, /* 0x40 */
+	'<', 'K', 'I', 'O', ')', '(',
+	U_SPECIAL, /* 0x47 */
+	U_SPECIAL, /* 0x48 */
+	'>', '?', 'L', ':', 'P', '_',
+	U_SPECIAL, /* 0x4F */
+	U_SPECIAL, /* 0x50 */
+	U_SPECIAL, /* 0x51 */
+	'"',
+	U_SPECIAL, /* 0x53 */
+	'{', '+',
+	U_SPECIAL, /* 0x56 */
+	U_SPECIAL, /* 0x57 */
+	U_SPECIAL, /* 0x58 - Caps Lock */
+	U_SPECIAL, /* 0x59 - RShift */
+	'\n', '}',
+	U_SPECIAL, /* 0x5C */
+	'|',
+	U_SPECIAL, /* 0x5E */
+	U_SPECIAL, /* 0x5F */
+	U_SPECIAL, /* 0x60 */
+	U_SPECIAL, /* 0x61 */
+	U_SPECIAL, /* 0x62 */
+	U_SPECIAL, /* 0x63 */
+	U_SPECIAL, /* 0x64 */
+	U_SPECIAL, /* 0x65 */
+	'\b', /* 0x66  - backspace*/
+	U_SPECIAL, /* 0x67 */
+	U_SPECIAL, /* 0x68 */
+	U_END_ARROW, /* 0x69 */
+	U_SPECIAL, /* 0x6a */
+	U_LEFT_ARROW, /* 0x6b - Left Arrow */
+	U_SPECIAL, /* 0x6c */
+	U_SPECIAL, /* 0x6d */
+	U_SPECIAL, /* 0x6e */
+	U_SPECIAL, /* 0x6f */
+	U_SPECIAL, /* 0x70 */
+	U_DELETE, /* 0x71 - Del*/
+	U_DOWN_ARROW, /* 0x72 Down Arrow */
+	U_SPECIAL, /* 0x73 */
+	U_RIGHT_ARROW, /* 0x74  - Right Arrow */
+	U_UP_ARROW, /* 0x75  Up Arrow */
+	U_ESCAPE, /* 0x76 Esc */
+	U_SPECIAL, /* 0x77 - NumLock*/
+	U_SPECIAL, /* 0x78  F11*/
+	U_SPECIAL, /* 0x79 */
+	U_PAGE_DOWN, /* 0x7a */
+	U_SPECIAL, /* 0x7b */
+	U_SPECIAL, /* 0x7c */
+	U_PAGE_UP, /* 0x7d */
+	U_SPECIAL, /* 0x7e */
+	U_SPECIAL /* 0x7f */
+};
+
+/** @}
+ */
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ uspace/Makefile	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -144,4 +144,5 @@
 	drv/char/pl050 \
 	drv/char/ps2mouse \
+	drv/char/atkbd \
 	drv/char/xtkbd \
 	drv/test/test1 \
Index: uspace/drv/char/atkbd/Makefile
===================================================================
--- uspace/drv/char/atkbd/Makefile	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ uspace/drv/char/atkbd/Makefile	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2011 Jan Vesely
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = atkbd
+
+SOURCES = \
+	main.c \
+	atkbd.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/atkbd/atkbd.c
===================================================================
--- uspace/drv/char/atkbd/atkbd.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ uspace/drv/char/atkbd/atkbd.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvkbd
+ * @{
+ */
+/** @file
+ * @brief AT keyboard driver
+ */
+
+#include <errno.h>
+#include <ddf/log.h>
+#include <io/keycode.h>
+#include <io/chardev.h>
+#include <io/console.h>
+#include <ipc/kbdev.h>
+#include <abi/ipc/methods.h>
+#include "atkbd.h"
+
+#define AT_CAPS_SCAN_CODE 0x58
+#define AT_NUM_SCAN_CODE 0x77
+#define AT_SCROLL_SCAN_CODE 0x7E
+
+/* Set 2 scan codes (AT keyboard) */
+static const unsigned int scanmap_simple[] = {
+	[0x0e] = KC_BACKTICK,
+
+	[0x16] = KC_1,
+	[0x1e] = KC_2,
+	[0x26] = KC_3,
+	[0x25] = KC_4,
+	[0x2e] = KC_5,
+	[0x36] = KC_6,
+	[0x3d] = KC_7,
+	[0x3e] = KC_8,
+	[0x46] = KC_9,
+	[0x45] = KC_0,
+
+	[0x4e] = KC_MINUS,
+	[0x55] = KC_EQUALS,
+	[0x66] = KC_BACKSPACE,
+
+	[0x0d] = KC_TAB,
+
+	[0x15] = KC_Q,
+	[0x1d] = KC_W,
+	[0x24] = KC_E,
+	[0x2d] = KC_R,
+	[0x2c] = KC_T,
+	[0x35] = KC_Y,
+	[0x3c] = KC_U,
+	[0x43] = KC_I,
+	[0x44] = KC_O,
+	[0x4d] = KC_P,
+
+	[0x54] = KC_LBRACKET,
+	[0x5b] = KC_RBRACKET,
+
+	[0x58] = KC_CAPS_LOCK,
+
+	[0x1c] = KC_A,
+	[0x1b] = KC_S,
+	[0x23] = KC_D,
+	[0x2b] = KC_F,
+	[0x34] = KC_G,
+	[0x33] = KC_H,
+	[0x3b] = KC_J,
+	[0x42] = KC_K,
+	[0x4b] = KC_L,
+
+	[0x4c] = KC_SEMICOLON,
+	[0x52] = KC_QUOTE,
+	[0x5d] = KC_BACKSLASH,
+
+	[0x12] = KC_LSHIFT,
+
+	[0x1a] = KC_Z,
+	[0x22] = KC_X,
+	[0x21] = KC_C,
+	[0x2a] = KC_V,
+	[0x32] = KC_B,
+	[0x31] = KC_N,
+	[0x3a] = KC_M,
+
+	[0x41] = KC_COMMA,
+	[0x49] = KC_PERIOD,
+	[0x4a] = KC_SLASH,
+
+	[0x59] = KC_RSHIFT,
+
+	[0x14] = KC_LCTRL,
+	[0x11] = KC_LALT,
+	[0x29] = KC_SPACE,
+
+	[0x76] = KC_ESCAPE,
+
+	[0x05] = KC_F1,
+	[0x06] = KC_F2,
+	[0x04] = KC_F3,
+	[0x0c] = KC_F4,
+	[0x03] = KC_F5,
+	[0x0b] = KC_F6,
+	[0x02] = KC_F7,
+
+	[0x0a] = KC_F8,
+	[0x01] = KC_F9,
+	[0x09] = KC_F10,
+
+	[0x78] = KC_F11,
+	[0x07] = KC_F12,
+
+	[0x7e] = KC_SCROLL_LOCK,
+
+	[0x5a] = KC_ENTER,
+
+	[0x77] = KC_NUM_LOCK,
+	[0x7c] = KC_NTIMES,
+	[0x7b] = KC_NMINUS,
+	[0x79] = KC_NPLUS,
+	[0x6c] = KC_N7,
+	[0x75] = KC_N8,
+	[0x7d] = KC_N9,
+	[0x6b] = KC_N4,
+	[0x73] = KC_N5,
+	[0x74] = KC_N6,
+	[0x69] = KC_N1,
+	[0x72] = KC_N2,
+	[0x7a] = KC_N3,
+	[0x70] = KC_N0,
+	[0x71] = KC_NPERIOD,
+};
+
+#define KBD_SCANCODE_SET_EXTENDED		0xe0
+#define KBD_SCANCODE_SET_EXTENDED_SPECIAL	0xe1
+#define KBD_SCANCODE_KEY_RELEASE		0xf0
+
+static const unsigned int scanmap_e0[] = {
+	[0x65] = KC_RALT,
+	[0x59] = KC_RSHIFT,
+
+	[0x64] = KC_PRTSCR,
+
+	[0x70] = KC_INSERT,
+	[0x6c] = KC_HOME,
+	[0x7d] = KC_PAGE_UP,
+
+	[0x71] = KC_DELETE,
+	[0x69] = KC_END,
+	[0x7a] = KC_PAGE_DOWN,
+
+	[0x75] = KC_UP,
+	[0x6b] = KC_LEFT,
+	[0x72] = KC_DOWN,
+	[0x74] = KC_RIGHT,
+
+	[0x4a] = KC_NSLASH,
+	[0x5a] = KC_NENTER
+};
+
+static void push_event(async_sess_t *sess, kbd_event_type_t type,
+    unsigned int key)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_4(exch, KBDEV_EVENT, type, key, 0, 0);
+	async_exchange_end(exch);
+}
+
+/** Get data and parse scancodes.
+ *
+ * @param arg Pointer to at_kbd_t structure.
+ *
+ * @return EIO on error.
+ *
+ */
+static int polling(void *arg)
+{
+	const at_kbd_t *kbd = arg;
+	
+	assert(kbd);
+	assert(kbd->parent_sess);
+	
+	async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess);
+	
+	while (true) {
+		if (!parent_exch)
+			parent_exch = async_exchange_begin(kbd->parent_sess);
+
+		uint8_t code = 0;
+		ssize_t size = chardev_read(parent_exch, &code, 1);
+		if (size != 1)
+			return EIO;
+		
+		const unsigned int *map;
+		size_t map_size;
+		
+		if (code == KBD_SCANCODE_SET_EXTENDED) {
+			map = scanmap_e0;
+			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
+			
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+		} else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0x14)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0x77)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0xe1)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0xf0)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0x14)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code != 0xf0)
+				continue;
+
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+			if (code == 0x77)
+				push_event(kbd->client_sess, KEY_PRESS, KC_BREAK);
+
+			continue;
+		} else {
+			map = scanmap_simple;
+			map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
+		}
+		
+		kbd_event_type_t type;
+		if (code == KBD_SCANCODE_KEY_RELEASE) {
+			type = KEY_RELEASE;
+			size = chardev_read(parent_exch, &code, 1);
+			if (size != 1)
+				return EIO;
+		} else {
+			type = KEY_PRESS;
+		}
+		
+		const unsigned int key = (code < map_size) ? map[code] : 0;
+		
+		if (key != 0)
+			push_event(kbd->client_sess, type, key);
+		else
+			ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
+	}
+}
+
+/** Default handler for IPC methods not handled by DDF.
+ *
+ * @param fun     Device function handling the call.
+ * @param icallid Call id.
+ * @param icall   Call data.
+ *
+ */
+static void default_connection_handler(ddf_fun_t *fun,
+    ipc_callid_t icallid, ipc_call_t *icall)
+{
+	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	at_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
+
+	switch (method) {
+	case KBDEV_SET_IND: {
+		async_answer_0(icallid, ENOTSUP);
+		break;
+	}
+	/*
+	 * This might be ugly but async_callback_receive_start makes no
+	 * difference for incorrect call and malloc failure.
+	 */
+	case IPC_M_CONNECT_TO_ME: {
+		async_sess_t *sess =
+		    async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
+		
+		/* Probably ENOMEM error, try again. */
+		if (sess == NULL) {
+			ddf_msg(LVL_WARN,
+			    "Failed creating callback session");
+			async_answer_0(icallid, EAGAIN);
+			break;
+		}
+		
+		if (kbd->client_sess == NULL) {
+			kbd->client_sess = sess;
+			ddf_msg(LVL_DEBUG, "Set client session");
+			async_answer_0(icallid, EOK);
+		} else {
+			ddf_msg(LVL_ERROR, "Client session already set");
+			async_answer_0(icallid, ELIMIT);
+		}
+		
+		break;
+	}
+	default:
+		ddf_msg(LVL_ERROR, "Unknown method: %d.", (int)method);
+		async_answer_0(icallid, EINVAL);
+		break;
+	}
+}
+
+/** Keyboard function ops. */
+static ddf_dev_ops_t kbd_ops = {
+	.default_handler = default_connection_handler
+};
+
+/** Initialize keyboard driver structure.
+ *
+ * @param kbd Keyboard driver structure to initialize.
+ * @param dev DDF device structure.
+ *
+ * Connects to parent, creates keyboard function, starts polling fibril.
+ *
+ */
+int at_kbd_init(at_kbd_t *kbd, ddf_dev_t *dev)
+{
+	assert(kbd);
+	assert(dev);
+	
+	kbd->client_sess = NULL;
+	kbd->parent_sess = ddf_dev_parent_sess_create(dev);
+	
+	if (!kbd->parent_sess) {
+		ddf_msg(LVL_ERROR, "Failed creating parent session.");
+		return EIO;
+	}
+	
+	kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd");
+	if (!kbd->kbd_fun) {
+		ddf_msg(LVL_ERROR, "Failed creating function 'kbd'.");
+		return ENOMEM;
+	}
+	
+	ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops);
+	
+	int ret = ddf_fun_bind(kbd->kbd_fun);
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function 'kbd'.");
+		ddf_fun_destroy(kbd->kbd_fun);
+		return EEXIST;
+	}
+	
+	ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function 'kbd' to category "
+		    "'keyboard'.");
+		ddf_fun_unbind(kbd->kbd_fun);
+		ddf_fun_destroy(kbd->kbd_fun);
+		return ENOMEM;
+	}
+	
+	kbd->polling_fibril = fibril_create(polling, kbd);
+	if (!kbd->polling_fibril) {
+		ddf_msg(LVL_ERROR, "Failed creating polling fibril.");
+		ddf_fun_unbind(kbd->kbd_fun);
+		ddf_fun_destroy(kbd->kbd_fun);
+		return ENOMEM;
+	}
+	
+	fibril_add_ready(kbd->polling_fibril);
+	return EOK;
+}
Index: uspace/drv/char/atkbd/atkbd.h
===================================================================
--- uspace/drv/char/atkbd/atkbd.h	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ uspace/drv/char/atkbd/atkbd.h	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvkbd
+ * @{
+ */
+/** @file
+ * @brief AT keyboard driver
+ */
+
+#ifndef _AT_KBD_H_
+#define _AT_KBD_H_
+
+#include <ddf/driver.h>
+#include <fibril.h>
+
+/** PC/AT keyboard driver structure. */
+typedef struct {
+	ddf_fun_t *kbd_fun;        /**< Keyboard function. */
+	async_sess_t *parent_sess; /**< Connection to device providing data. */
+	async_sess_t *client_sess; /**< Callback connection to client. */
+	fid_t polling_fibril;      /**< Fibril retrieving an parsing data. */
+} at_kbd_t;
+
+extern int at_kbd_init(at_kbd_t *, ddf_dev_t *);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/char/atkbd/atkbd.ma
===================================================================
--- uspace/drv/char/atkbd/atkbd.ma	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ uspace/drv/char/atkbd/atkbd.ma	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,1 @@
+100 char/atkbd
Index: uspace/drv/char/atkbd/main.c
===================================================================
--- uspace/drv/char/atkbd/main.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
+++ uspace/drv/char/atkbd/main.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvkbd
+ * @{
+ */
+/** @file
+ * @brief AT keyboard driver
+ */
+
+#include <libarch/inttypes.h>
+#include <ddf/driver.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <str_error.h>
+#include <ddf/log.h>
+#include <stdio.h>
+
+#include "atkbd.h"
+
+#define NAME "atkbd"
+
+static int at_kbd_add(ddf_dev_t *device);
+
+/** DDF driver ops. */
+static driver_ops_t kbd_driver_ops = {
+	.dev_add = at_kbd_add,
+};
+
+/** DDF driver structure. */
+static driver_t kbd_driver = {
+	.name = NAME,
+	.driver_ops = &kbd_driver_ops
+};
+
+/** Initialize global driver structures (NONE).
+ *
+ * Driver debug level is set here.
+ *
+ * @param[in] argc Nmber of arguments in argv vector (ignored).
+ * @param[in] argv Cmdline argument vector (ignored).
+ *
+ * @return Error code.
+ *
+ */
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS AT keyboard driver.\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&kbd_driver);
+}
+
+/** Initialize a new ddf driver instance of the driver
+ *
+ * @param[in] device DDF instance of the device to initialize.
+ *
+ * @return Error code.
+ *
+ */
+static int at_kbd_add(ddf_dev_t *device)
+{
+	int rc;
+
+	if (!device)
+		return EINVAL;
+
+	at_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(at_kbd_t));
+	if (kbd == NULL) {
+		ddf_msg(LVL_ERROR, "Failed to allocate AT_KBD driver instance.");
+		return ENOMEM;
+	}
+
+	rc = at_kbd_init(kbd, device);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to initialize AT_KBD driver: %s.",
+		    str_error(rc));
+    		return rc;
+	}
+
+	ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision 1afd9ee9738e27e900797a1c4687fd1b40996c62)
+++ uspace/drv/char/pl050/pl050.c	(revision 50122036bedeb4c4ffe03dda0b6696bc78c598e4)
@@ -323,5 +323,5 @@
 
 	if (str_cmp(pl050->name, "kbd") == 0)
-		mname = "char/xtkbd";
+		mname = "char/atkbd";
 	else
 		mname = "char/ps2mouse";
