common: Implement A/B metadata
[oweals/u-boot.git] / common / usb_kbd.c
index 8cbdba6ac2984fd667e6e7130311249126ca6c78..cc99c6be072044bde788380cfbf231d92a20a277 100644 (file)
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
  * Part of this source has been derived from the Linux USB
  * project.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
 #include <console.h>
@@ -14,6 +13,7 @@
 #include <malloc.h>
 #include <memalign.h>
 #include <stdio_dev.h>
+#include <watchdog.h>
 #include <asm/byteorder.h>
 
 #include <usb.h>
@@ -145,6 +145,12 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c)
        data->usb_kbd_buffer[data->usb_in_pointer] = c;
 }
 
+static void usb_kbd_put_sequence(struct usb_kbd_pdata *data, char *s)
+{
+       for (; *s; s++)
+               usb_kbd_put_queue(data, *s);
+}
+
 /*
  * Set the LEDs. Since this is used in the irq routine, the control job is
  * issued with a timeout of 0. This means, that the job is queued without
@@ -235,9 +241,25 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
        }
 
        /* Report keycode if any */
-       if (keycode) {
+       if (keycode)
                debug("%c", keycode);
+
+       switch (keycode) {
+       case 0x0e:                                      /* Down arrow key */
+               usb_kbd_put_sequence(data, "\e[B");
+               break;
+       case 0x10:                                      /* Up arrow key */
+               usb_kbd_put_sequence(data, "\e[A");
+               break;
+       case 0x06:                                      /* Right arrow key */
+               usb_kbd_put_sequence(data, "\e[C");
+               break;
+       case 0x02:                                      /* Left arrow key */
+               usb_kbd_put_sequence(data, "\e[D");
+               break;
+       default:
                usb_kbd_put_queue(data, keycode);
+               break;
        }
 
        return 0;
@@ -368,7 +390,7 @@ static int usb_kbd_testc(struct stdio_dev *sdev)
                return 0;
        kbd_testc_tms = get_timer(0);
 #endif
-       dev = stdio_get_by_name(DEVNAME);
+       dev = stdio_get_by_name(sdev->name);
        usb_kbd_dev = (struct usb_device *)dev->priv;
        data = usb_kbd_dev->privptr;
 
@@ -384,12 +406,14 @@ static int usb_kbd_getc(struct stdio_dev *sdev)
        struct usb_device *usb_kbd_dev;
        struct usb_kbd_pdata *data;
 
-       dev = stdio_get_by_name(DEVNAME);
+       dev = stdio_get_by_name(sdev->name);
        usb_kbd_dev = (struct usb_device *)dev->priv;
        data = usb_kbd_dev->privptr;
 
-       while (data->usb_in_pointer == data->usb_out_pointer)
+       while (data->usb_in_pointer == data->usb_out_pointer) {
+               WATCHDOG_RESET();
                usb_kbd_poll_for_event(usb_kbd_dev);
+       }
 
        if (data->usb_out_pointer == USB_KBD_BUFFER_LEN - 1)
                data->usb_out_pointer = 0;
@@ -537,7 +561,7 @@ static int probe_usb_keyboard(struct usb_device *dev)
        return 0;
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 /* Search for keyboard and register it if found. */
 int drv_usb_kbd_init(void)
 {
@@ -600,7 +624,7 @@ int usb_kbd_deregister(int force)
 
 #endif
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 
 static int usb_kbd_probe(struct udevice *dev)
 {