/*
 * (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 <malloc.h>
#include <stdio_dev.h>
#include <asm/byteorder.h>

#include <usb.h>

/*
 * If overwrite_console returns 1, the stdin, stderr and stdout
 * are switched to the serial port, else the settings in the
 * environment are used
 */
#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
extern int overwrite_console(void);
#else
int overwrite_console(void)
{
	return 0;
}
#endif

/* Keyboard sampling rate */
#define REPEAT_RATE	(40 / 4)	/* 40msec -> 25cps */
#define REPEAT_DELAY	10		/* 10 x REPEAT_RATE = 400msec */

#define NUM_LOCK	0x53
#define CAPS_LOCK	0x39
#define SCROLL_LOCK	0x47

/* Modifier bits */
#define LEFT_CNTR	(1 << 0)
#define LEFT_SHIFT	(1 << 1)
#define LEFT_ALT	(1 << 2)
#define LEFT_GUI	(1 << 3)
#define RIGHT_CNTR	(1 << 4)
#define RIGHT_SHIFT	(1 << 5)
#define RIGHT_ALT	(1 << 6)
#define RIGHT_GUI	(1 << 7)

/* Size of the keyboard buffer */
#define USB_KBD_BUFFER_LEN	0x20

/* Device name */
#define DEVNAME			"usbkbd"

/* Keyboard maps */
static const unsigned char usb_kbd_numkey[] = {
	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
	'\r', 0x1b, '\b', '\t', ' ', '-', '=', '[', ']',
	'\\', '#', ';', '\'', '`', ',', '.', '/'
};
static const unsigned char usb_kbd_numkey_shifted[] = {
	'!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
	'\r', 0x1b, '\b', '\t', ' ', '_', '+', '{', '}',
	'|', '~', ':', '"', '~', '<', '>', '?'
};

static const unsigned char usb_kbd_num_keypad[] = {
	'/', '*', '-', '+', '\r',
	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
	'.', 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
};

/*
 * NOTE: It's important for the NUM, CAPS, SCROLL-lock bits to be in this
 *       order. See usb_kbd_setled() function!
 */
#define USB_KBD_NUMLOCK		(1 << 0)
#define USB_KBD_CAPSLOCK	(1 << 1)
#define USB_KBD_SCROLLLOCK	(1 << 2)
#define USB_KBD_CTRL		(1 << 3)

#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 {
	uint32_t	repeat_delay;

	uint32_t	usb_in_pointer;
	uint32_t	usb_out_pointer;
	uint8_t		usb_kbd_buffer[USB_KBD_BUFFER_LEN];

	uint8_t		*new;
	uint8_t		old[USB_KBD_BOOT_REPORT_SIZE];

	uint8_t		flags;
};

extern int __maybe_unused net_busy_flag;

/* The period of time between two calls of usb_kbd_testc(). */
static unsigned long __maybe_unused kbd_testc_tms;

/* Generic keyboard event polling. */
void usb_kbd_generic_poll(void)
{
	struct stdio_dev *dev;
	struct usb_device *usb_kbd_dev;
	struct usb_kbd_pdata *data;
	struct usb_interface *iface;
	struct usb_endpoint_descriptor *ep;
	int pipe;
	int maxp;

	/* Get the pointer to USB Keyboard device pointer */
	dev = stdio_get_by_name(DEVNAME);
	usb_kbd_dev = (struct usb_device *)dev->priv;
	data = usb_kbd_dev->privptr;
	iface = &usb_kbd_dev->config.if_desc[0];
	ep = &iface->ep_desc[0];
	pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress);

	/* Submit a interrupt transfer request */
	maxp = usb_maxpacket(usb_kbd_dev, pipe);
	usb_submit_int_msg(usb_kbd_dev, pipe, data->new,
		min(maxp, USB_KBD_BOOT_REPORT_SIZE),
		ep->bInterval);
}

/* 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)
{
	if (data->usb_in_pointer == USB_KBD_BUFFER_LEN - 1) {
		/* Check for buffer full. */
		if (data->usb_out_pointer == 0)
			return;

		data->usb_in_pointer = 0;
	} else {
		/* Check for buffer full. */
		if (data->usb_in_pointer == data->usb_out_pointer - 1)
			return;

		data->usb_in_pointer++;
	}

	data->usb_kbd_buffer[data->usb_in_pointer] = c;
}

/*
 * 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
 * waiting for job completion.
 */
static void usb_kbd_setled(struct usb_device *dev)
{
	struct usb_interface *iface = &dev->config.if_desc[0];
	struct usb_kbd_pdata *data = dev->privptr;
	uint32_t leds = data->flags & USB_KBD_LEDMASK;

	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
}

#define CAPITAL_MASK	0x20
/* Translate the scancode in ASCII */
static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
				unsigned char modifier, int pressed)
{
	uint8_t keycode = 0;

	/* Key released */
	if (pressed == 0) {
		data->repeat_delay = 0;
		return 0;
	}

	if (pressed == 2) {
		data->repeat_delay++;
		if (data->repeat_delay < REPEAT_DELAY)
			return 0;

		data->repeat_delay = REPEAT_DELAY;
	}

	/* Alphanumeric values */
	if ((scancode > 3) && (scancode <= 0x1d)) {
		keycode = scancode - 4 + 'a';

		if (data->flags & USB_KBD_CAPSLOCK)
			keycode &= ~CAPITAL_MASK;

		if (modifier & (LEFT_SHIFT | RIGHT_SHIFT)) {
			/* Handle CAPSLock + Shift pressed simultaneously */
			if (keycode & CAPITAL_MASK)
				keycode &= ~CAPITAL_MASK;
			else
				keycode |= CAPITAL_MASK;
		}
	}

	if ((scancode > 0x1d) && (scancode < 0x3a)) {
		/* Shift pressed */
		if (modifier & (LEFT_SHIFT | RIGHT_SHIFT))
			keycode = usb_kbd_numkey_shifted[scancode - 0x1e];
		else
			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];

	if (data->flags & USB_KBD_CTRL)
		keycode = scancode - 0x3;

	if (pressed == 1) {
		if (scancode == NUM_LOCK) {
			data->flags ^= USB_KBD_NUMLOCK;
			return 1;
		}

		if (scancode == CAPS_LOCK) {
			data->flags ^= USB_KBD_CAPSLOCK;
			return 1;
		}
		if (scancode == SCROLL_LOCK) {
			data->flags ^= USB_KBD_SCROLLLOCK;
			return 1;
		}
	}

	/* Report keycode if any */
	if (keycode) {
		debug("%c", keycode);
		usb_kbd_put_queue(data, keycode);
	}

	return 0;
}

static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up)
{
	uint32_t res = 0;
	struct usb_kbd_pdata *data = dev->privptr;
	uint8_t *new;
	uint8_t *old;

	if (up) {
		new = data->old;
		old = data->new;
	} else {
		new = data->new;
		old = data->old;
	}

	if ((old[i] > 3) &&
	    (memscan(new + 2, old[i], USB_KBD_BOOT_REPORT_SIZE - 2) ==
			new + USB_KBD_BOOT_REPORT_SIZE)) {
		res |= usb_kbd_translate(data, old[i], data->new[0], up);
	}

	return res;
}

/* Interrupt service routine */
static int usb_kbd_irq_worker(struct usb_device *dev)
{
	struct usb_kbd_pdata *data = dev->privptr;
	int i, res = 0;

	/* No combo key pressed */
	if (data->new[0] == 0x00)
		data->flags &= ~USB_KBD_CTRL;
	/* Left or Right Ctrl pressed */
	else if ((data->new[0] == LEFT_CNTR) || (data->new[0] == RIGHT_CNTR))
		data->flags |= USB_KBD_CTRL;

	for (i = 2; i < USB_KBD_BOOT_REPORT_SIZE; i++) {
		res |= usb_kbd_service_key(dev, i, 0);
		res |= usb_kbd_service_key(dev, i, 1);
	}

	/* Key is still pressed */
	if ((data->new[2] > 3) && (data->old[2] == data->new[2]))
		res |= usb_kbd_translate(data, data->new[2], data->new[0], 2);

	if (res == 1)
		usb_kbd_setled(dev);

	memcpy(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE);

	return 1;
}

/* Keyboard interrupt handler */
static int usb_kbd_irq(struct usb_device *dev)
{
	if ((dev->irq_status != 0) ||
	    (dev->irq_act_len != USB_KBD_BOOT_REPORT_SIZE)) {
		debug("USB KBD: Error %lX, len %d\n",
		      dev->irq_status, dev->irq_act_len);
		return 1;
	}

	return usb_kbd_irq_worker(dev);
}

/* Interrupt polling */
static inline void usb_kbd_poll_for_event(struct usb_device *dev)
{
#if	defined(CONFIG_SYS_USB_EVENT_POLL)
	struct usb_interface *iface;
	struct usb_endpoint_descriptor *ep;
	struct usb_kbd_pdata *data;
	int pipe;
	int maxp;

	/* Get the pointer to USB Keyboard device pointer */
	data = dev->privptr;
	iface = &dev->config.if_desc[0];
	ep = &iface->ep_desc[0];
	pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);

	/* Submit a interrupt transfer request */
	maxp = usb_maxpacket(dev, pipe);
	usb_submit_int_msg(dev, pipe, &data->new[0],
		min(maxp, USB_KBD_BOOT_REPORT_SIZE),
		ep->bInterval);

	usb_kbd_irq_worker(dev);
#elif	defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
	struct usb_interface *iface;
	struct usb_kbd_pdata *data = dev->privptr;
	iface = &dev->config.if_desc[0];
	usb_get_report(dev, iface->desc.bInterfaceNumber,
		       1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE);
	if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE))
		usb_kbd_irq_worker(dev);
#endif
}

/* test if a character is in the queue */
static int usb_kbd_testc(struct stdio_dev *sdev)
{
	struct stdio_dev *dev;
	struct usb_device *usb_kbd_dev;
	struct usb_kbd_pdata *data;

#ifdef CONFIG_CMD_NET
	/*
	 * If net_busy_flag is 1, NET transfer is running,
	 * then we check key-pressed every second (first check may be
	 * less than 1 second) to improve TFTP booting performance.
	 */
	if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ))
		return 0;
	kbd_testc_tms = get_timer(0);
#endif
	dev = stdio_get_by_name(DEVNAME);
	usb_kbd_dev = (struct usb_device *)dev->priv;
	data = usb_kbd_dev->privptr;

	usb_kbd_poll_for_event(usb_kbd_dev);

	return !(data->usb_in_pointer == data->usb_out_pointer);
}

/* gets the character from the queue */
static int usb_kbd_getc(struct stdio_dev *sdev)
{
	struct stdio_dev *dev;
	struct usb_device *usb_kbd_dev;
	struct usb_kbd_pdata *data;

	dev = stdio_get_by_name(DEVNAME);
	usb_kbd_dev = (struct usb_device *)dev->priv;
	data = usb_kbd_dev->privptr;

	while (data->usb_in_pointer == data->usb_out_pointer)
		usb_kbd_poll_for_event(usb_kbd_dev);

	if (data->usb_out_pointer == USB_KBD_BUFFER_LEN - 1)
		data->usb_out_pointer = 0;
	else
		data->usb_out_pointer++;

	return data->usb_kbd_buffer[data->usb_out_pointer];
}

/* probes the USB device dev for keyboard type. */
static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
{
	struct usb_interface *iface;
	struct usb_endpoint_descriptor *ep;
	struct usb_kbd_pdata *data;
	int pipe, maxp;

	if (dev->descriptor.bNumConfigurations != 1)
		return 0;

	iface = &dev->config.if_desc[ifnum];

	if (iface->desc.bInterfaceClass != 3)
		return 0;

	if (iface->desc.bInterfaceSubClass != 1)
		return 0;

	if (iface->desc.bInterfaceProtocol != 1)
		return 0;

	if (iface->desc.bNumEndpoints != 1)
		return 0;

	ep = &iface->ep_desc[0];

	/* Check if endpoint 1 is interrupt endpoint */
	if (!(ep->bEndpointAddress & 0x80))
		return 0;

	if ((ep->bmAttributes & 3) != 3)
		return 0;

	debug("USB KBD: found set protocol...\n");

	data = malloc(sizeof(struct usb_kbd_pdata));
	if (!data) {
		printf("USB KBD: Error allocating private data\n");
		return 0;
	}

	/* Clear private data */
	memset(data, 0, sizeof(struct usb_kbd_pdata));

	/* allocate input buffer aligned and sized to USB DMA alignment */
	data->new = memalign(USB_DMA_MINALIGN,
		roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN));

	/* Insert private data into USB device structure */
	dev->privptr = data;

	/* Set IRQ handler */
	dev->irq_handle = usb_kbd_irq;

	pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
	maxp = usb_maxpacket(dev, pipe);

	/* We found a USB Keyboard, install it. */
	usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);

	debug("USB KBD: found set idle...\n");
	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);

	debug("USB KBD: enable interrupt pipe...\n");
	if (usb_submit_int_msg(dev, pipe, data->new,
			       min(maxp, USB_KBD_BOOT_REPORT_SIZE),
			       ep->bInterval) < 0) {
		printf("Failed to get keyboard state from device %04x:%04x\n",
		       dev->descriptor.idVendor, dev->descriptor.idProduct);
		/* Abort, we don't want to use that non-functional keyboard. */
		return 0;
	}

	/* Success. */
	return 1;
}

/* Search for keyboard and register it if found. */
int drv_usb_kbd_init(void)
{
	struct stdio_dev usb_kbd_dev, *old_dev;
	struct usb_device *dev;
	char *stdinname = getenv("stdin");
	int error, i;

	/* Scan all USB Devices */
	for (i = 0; i < USB_MAX_DEVICE; i++) {
		/* Get USB device. */
		dev = usb_get_dev_index(i);
		if (!dev)
			return -1;

		if (dev->devnum == -1)
			continue;

		/* Try probing the keyboard */
		if (usb_kbd_probe(dev, 0) != 1)
			continue;

		/* We found a keyboard, check if it is already registered. */
		debug("USB KBD: found set up device.\n");
		old_dev = stdio_get_by_name(DEVNAME);
		if (old_dev) {
			/* Already registered, just return ok. */
			debug("USB KBD: is already registered.\n");
			usb_kbd_deregister();
			return 1;
		}

		/* Register the keyboard */
		debug("USB KBD: register.\n");
		memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
		strcpy(usb_kbd_dev.name, DEVNAME);
		usb_kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
		usb_kbd_dev.getc = usb_kbd_getc;
		usb_kbd_dev.tstc = usb_kbd_testc;
		usb_kbd_dev.priv = (void *)dev;
		error = stdio_register(&usb_kbd_dev);
		if (error)
			return error;

#ifdef CONFIG_CONSOLE_MUX
		error = iomux_doenv(stdin, stdinname);
		if (error)
			return error;
#else
		/* Check if this is the standard input device. */
		if (strcmp(stdinname, DEVNAME))
			return 1;

		/* Reassign the console */
		if (overwrite_console())
			return 1;

		error = console_assign(stdin, DEVNAME);
		if (error)
			return error;
#endif

		return 1;
	}

	/* No USB Keyboard found */
	return -1;
}

/* Deregister the keyboard. */
int usb_kbd_deregister(void)
{
#ifdef CONFIG_SYS_STDIO_DEREGISTER
	return stdio_deregister(DEVNAME);
#else
	return 1;
#endif
}
