X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fusb_kbd.c;h=b316807844b17150c5070c70f6bc9e39502f4695;hb=7fc7d241169d26ec79a86bfcab0e966c778defe7;hp=d2d29cc98f5ed3e8cf7f91f13daa2d6619756df5;hpb=576a085c1d224b8a5a3ccf5c4114d07a1f695f20;p=oweals%2Fu-boot.git diff --git a/common/usb_kbd.c b/common/usb_kbd.c index d2d29cc98f..b316807844 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -1,19 +1,21 @@ +// 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 #include #include +#include #include +#include #include #include #include +#include #include #include @@ -74,13 +76,12 @@ static const unsigned char usb_kbd_num_keypad[] = { '.', 0, 0, 0, '=' }; -/* - * map arrow keys to ^F/^B ^N/^P, can't really use the proper - * ANSI sequence for arrow keys because the queuing code breaks - * when a single keypress expands to 3 queue elements - */ -static const unsigned char usb_kbd_arrow[] = { - 0x6, 0x2, 0xe, 0x10 +static const u8 usb_special_keys[] = { +#ifdef CONFIG_USB_KEYBOARD_FN_KEYS + '2', 'H', '5', '3', 'F', '6', 'C', 'D', 'B', 'A' +#else + 'C', 'D', 'B', 'A' +#endif }; /* @@ -95,12 +96,6 @@ static const unsigned char usb_kbd_arrow[] = { #define USB_KBD_LEDMASK \ (USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK) -/* - * USB Keyboard reports are 8 bytes in boot protocol. - * Appendix B of HID Device Class Definition 1.11 - */ -#define USB_KBD_BOOT_REPORT_SIZE 8 - struct usb_kbd_pdata { unsigned long intpipe; int intpktsize; @@ -126,7 +121,7 @@ extern int __maybe_unused net_busy_flag; static unsigned long __maybe_unused kbd_testc_tms; /* Puts character in the queue and sets up the in and out pointer. */ -static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c) +static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c) { if (data->usb_in_pointer == USB_KBD_BUFFER_LEN - 1) { /* Check for buffer full. */ @@ -207,10 +202,6 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, keycode = usb_kbd_numkey[scancode - 0x1e]; } - /* Arrow keys */ - if ((scancode >= 0x4f) && (scancode <= 0x52)) - keycode = usb_kbd_arrow[scancode - 0x4f]; - /* Numeric keypad */ if ((scancode >= 0x54) && (scancode <= 0x67)) keycode = usb_kbd_num_keypad[scancode - 0x54]; @@ -238,9 +229,55 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, if (keycode) { debug("%c", keycode); usb_kbd_put_queue(data, keycode); + return 0; } +#ifdef CONFIG_USB_KEYBOARD_FN_KEYS + if (scancode < 0x3a || scancode > 0x52 || + scancode == 0x46 || scancode == 0x47) + return 1; + + usb_kbd_put_queue(data, 0x1b); + if (scancode < 0x3e) { + /* F1 - F4 */ + usb_kbd_put_queue(data, 0x4f); + usb_kbd_put_queue(data, scancode - 0x3a + 'P'); + return 0; + } + usb_kbd_put_queue(data, '['); + if (scancode < 0x42) { + /* F5 - F8 */ + usb_kbd_put_queue(data, '1'); + if (scancode == 0x3e) + --scancode; + keycode = scancode - 0x3f + '7'; + } else if (scancode < 0x49) { + /* F9 - F12 */ + usb_kbd_put_queue(data, '2'); + if (scancode > 0x43) + ++scancode; + keycode = scancode - 0x42 + '0'; + } else { + /* + * INSERT, HOME, PAGE UP, DELETE, END, PAGE DOWN, + * RIGHT, LEFT, DOWN, UP + */ + keycode = usb_special_keys[scancode - 0x49]; + } + usb_kbd_put_queue(data, keycode); + if (scancode < 0x4f && scancode != 0x4a && scancode != 0x4d) + usb_kbd_put_queue(data, '~'); return 0; +#else + /* Left, Right, Up, Down */ + if (scancode > 0x4e && scancode < 0x53) { + usb_kbd_put_queue(data, 0x1b); + usb_kbd_put_queue(data, '['); + usb_kbd_put_queue(data, usb_special_keys[scancode - 0x4f]); + return 0; + } + return 1; +#endif /* CONFIG_USB_KEYBOARD_FN_KEYS */ } static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up) @@ -316,11 +353,10 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) #if defined(CONFIG_SYS_USB_EVENT_POLL) struct usb_kbd_pdata *data = dev->privptr; - /* Submit a interrupt transfer request */ - usb_submit_int_msg(dev, data->intpipe, &data->new[0], data->intpktsize, - data->intinterval); - - usb_kbd_irq_worker(dev); + /* Submit an interrupt transfer request */ + if (usb_int_msg(dev, data->intpipe, &data->new[0], + data->intpktsize, data->intinterval, true) >= 0) + usb_kbd_irq_worker(dev); #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \ defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) #if defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) @@ -368,7 +404,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 +420,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; @@ -480,8 +518,8 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum) 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 (usb_int_msg(dev, data->intpipe, data->new, data->intpktsize, + data->intinterval, false) < 0) { #endif printf("Failed to get keyboard state from device %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); @@ -515,7 +553,7 @@ static int probe_usb_keyboard(struct usb_device *dev) if (error) return error; - stdinname = getenv("stdin"); + stdinname = env_get("stdin"); #if CONFIG_IS_ENABLED(CONSOLE_MUX) error = iomux_doenv(stdin, stdinname); if (error) @@ -537,7 +575,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) { @@ -582,7 +620,7 @@ int usb_kbd_deregister(int force) if (stdio_deregister_dev(dev, force) != 0) return 1; #if CONFIG_IS_ENABLED(CONSOLE_MUX) - if (iomux_doenv(stdin, getenv("stdin")) != 0) + if (iomux_doenv(stdin, env_get("stdin")) != 0) return 1; #endif #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE @@ -600,7 +638,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) { @@ -627,7 +665,7 @@ static int usb_kbd_remove(struct udevice *dev) goto err; } #if CONFIG_IS_ENABLED(CONSOLE_MUX) - if (iomux_doenv(stdin, getenv("stdin"))) { + if (iomux_doenv(stdin, env_get("stdin"))) { ret = -ENOLINK; goto err; }