+// 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>
#include <malloc.h>
#include <memalign.h>
#include <stdio_dev.h>
+#include <watchdog.h>
#include <asm/byteorder.h>
#include <usb.h>
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
}
}
- if ((scancode > 0x1d) && (scancode < 0x3a)) {
+ if ((scancode > 0x1d) && (scancode < 0x39)) {
/* Shift pressed */
if (modifier & (LEFT_SHIFT | RIGHT_SHIFT))
keycode = usb_kbd_numkey_shifted[scancode - 0x1e];
}
/* 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;
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;
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;
USB_KBD_BOOT_REPORT_SIZE, data->new,
data->intinterval);
if (!data->intq) {
+#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
+ if (usb_get_report(dev, iface->desc.bInterfaceNumber,
+ 1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) {
#else
if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize,
data->intinterval) < 0) {
if (error)
return error;
- stdinname = getenv("stdin");
-#ifdef CONFIG_CONSOLE_MUX
+ stdinname = env_get("stdin");
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
error = iomux_doenv(stdin, stdinname);
if (error)
return error;
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)
{
/* No USB Keyboard found */
return -1;
}
-#endif
/* Deregister the keyboard. */
int usb_kbd_deregister(int force)
{
-#ifdef CONFIG_SYS_STDIO_DEREGISTER
+#if CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER)
struct stdio_dev *dev;
struct usb_device *usb_kbd_dev;
struct usb_kbd_pdata *data;
data = usb_kbd_dev->privptr;
if (stdio_deregister_dev(dev, force) != 0)
return 1;
-#ifdef CONFIG_CONSOLE_MUX
- if (iomux_doenv(stdin, getenv("stdin")) != 0)
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
+ if (iomux_doenv(stdin, env_get("stdin")) != 0)
return 1;
#endif
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
#endif
}
-#ifdef CONFIG_DM_USB
+#endif
+
+#if CONFIG_IS_ENABLED(DM_USB)
static int usb_kbd_probe(struct udevice *dev)
{
struct usb_device *udev = dev_get_parent_priv(dev);
+
+ return probe_usb_keyboard(udev);
+}
+
+static int usb_kbd_remove(struct udevice *dev)
+{
+ struct usb_device *udev = dev_get_parent_priv(dev);
+ struct usb_kbd_pdata *data;
+ struct stdio_dev *sdev;
int ret;
- ret = probe_usb_keyboard(udev);
+ sdev = stdio_get_by_name(DEVNAME);
+ if (!sdev) {
+ ret = -ENXIO;
+ goto err;
+ }
+ data = udev->privptr;
+ if (stdio_deregister_dev(sdev, true)) {
+ ret = -EPERM;
+ goto err;
+ }
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
+ if (iomux_doenv(stdin, env_get("stdin"))) {
+ ret = -ENOLINK;
+ goto err;
+ }
+#endif
+#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
+ destroy_int_queue(udev, data->intq);
+#endif
+ free(data->new);
+ free(data);
+ return 0;
+err:
+ printf("%s: warning, ret=%d", __func__, ret);
return ret;
}
.id = UCLASS_KEYBOARD,
.of_match = usb_kbd_ids,
.probe = usb_kbd_probe,
+ .remove = usb_kbd_remove,
};
static const struct usb_device_id kbd_id_table[] = {