Signed-off-by: Andrey Danin <danind...@mail.ru>
CC: Stephen Warren <swar...@nvidia.com>
CC: Marc Dietrich <marvi...@gmx.de>
CC: Julian Andres Klode <j...@jak-linux.org>
CC: ac...@lists.launchpad.net
---
 Changes for v2:
        - fixed incorrect keys handling in nvec-keyboard driver

 .../include/asm/arch-tegra/tegra_nvec_keyboard.h   |  304 ++++++++++++++++++++
 drivers/input/Makefile                             |    3 +
 drivers/input/tegra-nvec-kbc.c                     |  215 ++++++++++++++
 include/configs/tegra-common-post.h                |    2 +
 4 files changed, 524 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h
 create mode 100644 drivers/input/tegra-nvec-kbc.c

diff --git a/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h 
b/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h
new file mode 100644
index 0000000..5f789f4
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin <danind...@mail.ru>
+ * (C) Copyright 2009
+ * NVIDIA Corporation.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _TEGRA_NVEC_KEYBOARD_H_
+#define _TEGRA_NVEC_KEYBOARD_H_
+
+#include <linux/input.h>
+
+
+/* Keytables */
+
+static unsigned short code_tab_102us[] = {
+       /* 0x00 */
+       KEY_GRAVE,
+       KEY_ESC,
+       KEY_1,
+       KEY_2,
+       KEY_3,
+       KEY_4,
+       KEY_5,
+       KEY_6,
+       KEY_7,
+       KEY_8,
+       KEY_9,
+       KEY_0,
+       KEY_MINUS,
+       KEY_EQUAL,
+       KEY_BACKSPACE,
+       KEY_TAB,
+       /* 0x10 */
+       KEY_Q,
+       KEY_W,
+       KEY_E,
+       KEY_R,
+       KEY_T,
+       KEY_Y,
+       KEY_U,
+       KEY_I,
+       KEY_O,
+       KEY_P,
+       KEY_LEFTBRACE,
+       KEY_RIGHTBRACE,
+       KEY_ENTER,
+       KEY_LEFTCTRL,
+       KEY_A,
+       KEY_S,
+       /* 0x20 */
+       KEY_D,
+       KEY_F,
+       KEY_G,
+       KEY_H,
+       KEY_J,
+       KEY_K,
+       KEY_L,
+       KEY_SEMICOLON,
+       KEY_APOSTROPHE,
+       KEY_GRAVE,
+       KEY_LEFTSHIFT,
+       KEY_BACKSLASH,
+       KEY_Z,
+       KEY_X,
+       KEY_C,
+       KEY_V,
+       /* 0x30 */
+       KEY_B,
+       KEY_N,
+       KEY_M,
+       KEY_COMMA,
+       KEY_DOT,
+       KEY_SLASH,
+       KEY_RIGHTSHIFT,
+       KEY_KPASTERISK,
+       KEY_LEFTALT,
+       KEY_SPACE,
+       KEY_CAPSLOCK,
+       KEY_F1,
+       KEY_F2,
+       KEY_F3,
+       KEY_F4,
+       KEY_F5,
+       /* 0x40 */
+       KEY_F6,
+       KEY_F7,
+       KEY_F8,
+       KEY_F9,
+       KEY_F10,
+       KEY_FN,
+       /* VK_SCROLL */
+       0,
+       KEY_KP7,
+       KEY_KP8,
+       KEY_KP9,
+       KEY_KPMINUS,
+       KEY_KP4,
+       KEY_KP5,
+       KEY_KP6,
+       KEY_KPPLUS,
+       KEY_KP1,
+       /* 0x50 */
+       KEY_KP2,
+       KEY_KP3,
+       KEY_KP0,
+       KEY_KPDOT,
+       /* VK_SNAPSHOT */
+       0, /* KEY_MENU, */
+       KEY_POWER,
+       /* VK_OEM_102 */
+       KEY_102ND,
+       KEY_F11,
+       KEY_F12,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* 0x60 */
+       0,
+       0,
+       0,
+       0, /* KEY_SEARCH, */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* 0x70 */
+       0,
+       0,
+       0,
+       KEY_KP5,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       KEY_KP9,
+};
+
+static unsigned short extcode_tab_us102[] = {
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* 0x10 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* VK_MEDIA_NEXT_TRACK */
+       0,
+       0,
+       0,
+       /* VK_RETURN */
+       0,
+       KEY_RIGHTCTRL,
+       0,
+       0,
+       /* 0x20 */
+       KEY_MUTE,
+       /* VK_LAUNCH_APP1 */
+       0,
+       /* VK_MEDIA_PLAY_PAUSE */
+       0,
+       0,
+       /* VK_MEDIA_STOP */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* 0x30 */
+       KEY_VOLUMEUP,
+       0,
+       /* VK_BROWSER_HOME */
+       0,
+       0,
+       0,
+       /* VK_DIVIDE */
+       KEY_KPSLASH,
+       0,
+       /* VK_SNAPSHOT */
+       KEY_SYSRQ,
+       /* VK_RMENU */
+       KEY_RIGHTALT,
+       /* VK_OEM_NV_BACKLIGHT_UP */
+       0,
+       /* VK_OEM_NV_BACKLIGHT_DN */
+       0,
+       /* VK_OEM_NV_BACKLIGHT_AUTOTOGGLE */
+       0,
+       /* VK_OEM_NV_POWER_INFO */
+       0,
+       /* VK_OEM_NV_WIFI_TOGGLE */
+       0,
+       /* VK_OEM_NV_DISPLAY_SELECT */
+       0,
+       /* VK_OEM_NV_AIRPLANE_TOGGLE */
+       0,
+       /* 0x40 */
+       0,
+       KEY_LEFT,
+       0,
+       0,
+       0,
+       0,
+       0, /* KEY_CANCEL, */
+       KEY_HOME,
+       KEY_UP,
+       KEY_PAGEUP,
+       0,
+       KEY_LEFT,
+       0,
+       KEY_RIGHT,
+       0,
+       KEY_END,
+       /* 0x50 */
+       KEY_DOWN,
+       KEY_PAGEDOWN,
+       KEY_INSERT,
+       KEY_DELETE,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       KEY_LEFTMETA,
+       0,
+       KEY_ESC,
+       KEY_KPMINUS,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       /* VK_BROWSER_SEARCH */
+       0,
+       /* VK_BROWSER_FAVORITES */
+       0,
+       /* VK_BROWSER_REFRESH */
+       0,
+       /* VK_BROWSER_STOP */
+       0,
+       /* VK_BROWSER_FORWARD */
+       0,
+       /* VK_BROWSER_BACK */
+       0,
+       /* VK_LAUNCH_APP2 */
+       0,
+       /* VK_LAUNCH_MAIL */
+       0,
+       /* VK_LAUNCH_MEDIA_SELECT */
+       0,
+};
+
+static unsigned short *code_tabs[] = { code_tab_102us, extcode_tab_us102 };
+
+
+#endif /* _TEGRA_NVEC_KEYBOARD_H_ */
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index a8e9be2..38c576f 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -7,6 +7,9 @@
 
 obj-$(CONFIG_I8042_KBD) += i8042.o
 obj-$(CONFIG_TEGRA_KEYBOARD) += tegra-kbc.o
+ifdef CONFIG_SYS_I2C_TEGRA_NVEC
+obj-$(CONFIG_TEGRA_NVEC_KEYBOARD) += tegra-nvec-kbc.o
+endif
 obj-$(CONFIG_CROS_EC_KEYB) += cros_ec_keyb.o
 ifdef CONFIG_PS2KBD
 obj-y += keyboard.o pc_keyb.o
diff --git a/drivers/input/tegra-nvec-kbc.c b/drivers/input/tegra-nvec-kbc.c
new file mode 100644
index 0000000..f5832b1
--- /dev/null
+++ b/drivers/input/tegra-nvec-kbc.c
@@ -0,0 +1,215 @@
+/*
+ *  (C) Copyright 2014
+ *  Andrey Danin <danind...@mail.ru>
+ *  (C) Copyright 2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <input.h>
+#include <asm/arch-tegra/tegra_nvec.h>
+#include <asm/arch-tegra/tegra_nvec_keyboard.h>
+
+
+enum {
+       KBC_MAX_KPENT = 8,
+       KBC_REPEAT_RATE_MS      = 30,
+       KBC_REPEAT_DELAY_MS     = 240,
+};
+
+/* keyboard config/state */
+static struct keyb {
+       int registered;
+       struct input_config input;      /* The input layer */
+       int pressed_keys[KBC_MAX_KPENT];
+       int pressed_keys_cnt;
+} config;
+
+
+/* 0 - pressed, other - released */
+char keys[256];
+
+
+/* nvec commands */
+static char enable_kbd[] = { NVEC_KBD, ENABLE_KBD };
+static char reset_kbd[] = { NVEC_PS2, MOUSE_SEND_CMD, MOUSE_RESET, 3 };
+static char clear_leds[] = { NVEC_KBD, SET_LEDS, 0 };
+
+
+/**
+ * Check the tegra nvec keyboard, and send any keys that are pressed.
+ *
+ * This is called by input_tstc() and input_getc() when they need more
+ * characters
+ *
+ * @param input                Input configuration
+ * @return 1, to indicate that we have something to look at
+ */
+int tegra_nvec_kbc_check(struct input_config *input)
+{
+       int i;
+
+       nvec_read_events();
+
+       config.pressed_keys_cnt = 0;
+       /* TODO Optimization required */
+       for (i = 0; i < sizeof(keys); ++i) {
+               if (keys[i] == 0 && config.pressed_keys_cnt < KBC_MAX_KPENT) {
+                       config.pressed_keys[config.pressed_keys_cnt] = i;
+                       ++config.pressed_keys_cnt;
+               }
+       }
+
+       input_send_keycodes(input,
+                           config.pressed_keys,
+                           config.pressed_keys_cnt);
+
+       return config.pressed_keys_cnt;
+}
+
+
+/**
+ * Test if keys are available to be read
+ *
+ * @return 0 if no keys available, 1 if keys are available
+ */
+static int kbd_tstc(void)
+{
+       /* Just get input to do this for us */
+       return input_tstc(&config.input);
+}
+
+
+/**
+ * Read a key
+ *
+ * TODO: U-Boot wants 0 for no key, but Ctrl-@ is a valid key...
+ *
+ * @return ASCII key code, or 0 if no key, or -1 if error
+ */
+static int kbd_getc(void)
+{
+       /* Just get input to do this for us */
+       return input_getc(&config.input);
+}
+
+
+int tegra_nvec_process_keyboard_msg(const unsigned char *msg)
+{
+       int code, state;
+       int event_type;
+       int _size;
+       int key;
+
+
+       event_type = nvec_msg_event_type(msg);
+       if (event_type != NVEC_KEYBOARD)
+               return -1;
+
+       _size = (msg[0] & (3 << 5)) >> 5;
+
+       if (_size == NVEC_VAR_SIZE) {
+               debug("Skip unsupported msg (size: %d)\n", _size);
+               return -1;
+       }
+
+       if (_size == NVEC_3BYTES)
+               msg++;
+
+       code = msg[1] & 0x7f;
+       state = msg[1] & 0x80;
+
+       key = code_tabs[_size][code];
+       keys[key] = state;
+
+       return 0;
+}
+
+
+int tegra_nvec_enable_kbd_events(void)
+{
+       if (nvec_do_request(reset_kbd, 4)) {
+               error("NVEC: failed to reset keyboard\n");
+               return -1;
+       }
+       if (nvec_do_request(clear_leds, 3)) {
+               error("NVEC: failed to clear leds\n");
+               return -1;
+       }
+       if (nvec_do_request(enable_kbd, 2)) {
+               error("NVEC: failed to enable keyboard\n");
+               return -1;
+       }
+
+       debug("NVEC: keyboard initialization finished\n");
+
+       return 0;
+}
+
+
+static int tegra_nvec_kbc_start(void)
+{
+       if (config.registered)
+               return 0;
+
+       struct nvec_periph nvec_keyboard;
+       memset(&nvec_keyboard, 0, sizeof(nvec_keyboard));
+       nvec_keyboard.start = tegra_nvec_enable_kbd_events;
+       nvec_keyboard.process_msg = tegra_nvec_process_keyboard_msg;
+
+       if (nvec_register_periph(NVEC_KEYBOARD, &nvec_keyboard)) {
+               error("NVEC: failed to register keyboard perephirial device");
+               return -1;
+       }
+
+       config.registered = 1;
+
+       return 0;
+}
+
+
+int drv_keyboard_init(void)
+{
+       struct stdio_dev dev;
+       int error;
+#ifdef CONFIG_CONSOLE_MUX
+       char *stdinname = getenv("stdin");
+#endif
+
+       memset(keys, 1, sizeof(keys));
+
+       config.registered = 0;
+
+       if (input_init(&config.input, 0)) {
+               printf("nvec kbc: cannot set up input\n");
+               return -1;
+       }
+       input_set_delays(&config.input, KBC_REPEAT_DELAY_MS,
+                        KBC_REPEAT_RATE_MS);
+       config.input.read_keys = tegra_nvec_kbc_check;
+
+       memset(&dev, '\0', sizeof(dev));
+       strcpy(dev.name, "tegra-nvec-kbc");
+       dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+       dev.getc = kbd_getc;
+       dev.tstc = kbd_tstc;
+       dev.start = tegra_nvec_kbc_start;
+
+       /* Register the device. tegra_nvec_kbc_start() will be called soon */
+       error = input_stdio_register(&dev);
+       if (error) {
+               printf("nvec kbc: failed to register stdio device, %d\n",
+                      error);
+               return error;
+       }
+#ifdef CONFIG_CONSOLE_MUX
+       error = iomux_doenv(stdin, stdinname);
+       if (error) {
+               printf("nvec kbc: iomux_doenv failed, %d\n", error);
+               return error;
+       }
+#endif
+       return 0;
+}
diff --git a/include/configs/tegra-common-post.h 
b/include/configs/tegra-common-post.h
index e1a3bbc..efc0ef9 100644
--- a/include/configs/tegra-common-post.h
+++ b/include/configs/tegra-common-post.h
@@ -106,6 +106,8 @@
 
 #ifdef CONFIG_TEGRA_KEYBOARD
 #define STDIN_KBD_KBC ",tegra-kbc"
+#elif defined(CONFIG_TEGRA_NVEC_KEYBOARD)
+#define STDIN_KBD_KBC ",tegra-nvec-kbc"
 #else
 #define STDIN_KBD_KBC ""
 #endif
-- 
1.7.9.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to