/*****************************************************************************
 * Copyright (c) 2013 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <termctrl.h>

#include "usb-core.h"
#include "usb-key.h"

/*
 * HID Spec Version 1.11
 */

#define HID_REQ_GET_REPORT              0x01
#define HID_REQ_GET_IDLE                0x02
#define HID_REQ_GET_PROTOCOL            0x03
#define HID_REQ_SET_REPORT              0x09
#define HID_REQ_SET_IDLE                0x0A
#define HID_REQ_SET_PROTOCOL            0x0B

//#define KEY_DEBUG

/* HID SPEC - 7.2.6 Set_Protocol Request */
static int usb_hid_set_protocol(struct usb_dev *dev, uint16_t value)
{
	struct usb_dev_req req;
	if (!dev)
		return false;
	req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
	req.bRequest = HID_REQ_SET_PROTOCOL;
	req.wValue = cpu_to_le16(value);
	req.wIndex = cpu_to_le16(dev->intf_num);
	req.wLength = 0;
	return usb_send_ctrl(dev->control, &req, NULL);
}

/* HID SPEC - 7.2.4 Set_Idle Request */
static int usb_hid_set_idle(struct usb_dev *dev, uint16_t ms_delay)
{
	struct usb_dev_req req;
	if (!dev)
		return false;
	req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
	req.bRequest = HID_REQ_SET_IDLE;
	req.wValue = cpu_to_le16((ms_delay/4) << 8);
	req.wIndex = cpu_to_le16(dev->intf_num);
	req.wLength = 0;
	return usb_send_ctrl(dev->control, &req, NULL);
}

/* HID SPEC - 7.2.1 Get Report Request */
static int usb_hid_get_report(struct usb_dev *dev, void *data, size_t size)
{
	struct usb_dev_req req;
	if (!dev)
		return false;
	req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_IN;
	req.bRequest = HID_REQ_GET_REPORT;
	req.wIndex = cpu_to_le16(dev->intf_num);

	req.wLength = cpu_to_le16((uint16_t)size);
	req.wValue = cpu_to_le16(1 << 8);
	return usb_send_ctrl(dev->control, &req, data);
}

/* ring buffer with RD/WR indices for key buffering */
static uint8_t keybuf[256];	/* size fixed to byte range !   */
uint8_t r_ptr = 0;		/* RD-index for Keyboard-Buffer */
uint8_t w_ptr = 0;		/* WR-index for Keyboard-Buffer */

/* variables for LED status */
uint8_t set_leds;
const uint8_t *key_std       = NULL;
const uint8_t *key_std_shift = NULL;

/**
 * read character from Keyboard-Buffer
 *
 * @param   -
 * @return  > 0  Keycode
 *          = 0  if no key available
 */
static int read_key(void)
{
	if (r_ptr != w_ptr)
		return (int)keybuf[r_ptr++];
	else
		return false;
}

/**
 * Store character into Keyboard-Buffer
 *
 * @param   Key = detected ASCII-Key (> 0)
 * @return  -
 */
static void write_key(uint8_t key)
{
	if ((w_ptr + 1) != r_ptr)
		keybuf[w_ptr++] = key;
}

/**
 * Convert keyboard usage-ID to ANSI-Code
 *
 * @param   Ctrl=Modifier Byte
 *          Key =Usage ID from USB Keyboard
 * @return  -
 */
static void get_char(uint8_t ctrl, uint8_t keypos)
{
	uint8_t ch;

#ifdef KEY_DEBUG
	printf("pos %02X\n", keypos);
#endif

	if (set_leds & LED_CAPS_LOCK)	                /* is CAPS Lock set ? */
		ctrl |= MODIFIER_SHIFT;	                    /* simulate shift */

	if (ctrl == 0) {
		ch = key_std[keypos];
		if (ch != 0)
			write_key(ch);
		return;
	}

	if (ctrl & MODIFIER_SHIFT) {
		ch = key_std_shift[keypos];
		if (ch != 0)
			write_key(ch);
		return;
	}

	if (ctrl & MODIFIER_CTRL) {
		ch = keycodes_ctrl[keypos];
		if (ch != 0)
			write_key(ch);
		return;
	}

	if (ctrl == MODIFIER_ALT_GR) {
		ch = keycodes_alt_GR[keypos];
		if (ch != 0)
			write_key(ch);
		return;
	}
}

static void check_key_code(uint8_t *buf)
{
	static uint8_t key_last[6];	            /* list of processed keys */
	uint8_t i, j, key_pos;

	/* set translation table to defaults */
	if ((key_std == NULL) || (key_std_shift == NULL)) {
		key_std       = keycodes_std_US;
		key_std_shift = keycodes_shift_US;
	}

	if (buf[0] & MODIFIER_SHIFT)	   /* any shift key pressed ? */
		set_leds &= ~LED_CAPS_LOCK;	  /* CAPS-LOCK-LED always off */

	i = 2;	/* skip modifier byte and reserved byte */
	while (i < 8) {
		key_pos = buf[i];
		if ((key_pos != 0) && (key_pos <= 100)) {    /* support for 101 keys */
			j = 0;
			/* search if already processed */
			while ((j < 6) && (key_pos != key_last[j]))
				j++;

			if (j >= 6) {	       /* not found (= not processed) */
				switch (key_pos) {
				case 0x39:	           /* caps-lock key ? */
				case 0x32:	           /* caps-lock key ? */
					set_leds ^= LED_CAPS_LOCK;
					break;

				case 0x3a:	                        /* F1 */
					write_key(0x1b);
					write_key(0x5b);
					write_key(0x31);
					write_key(0x31);
					write_key(0x7e);
					break;

				case 0x3b:		                /* F2 */
					write_key(0x1b);
					write_key(0x5b);
					write_key(0x31);
					write_key(0x32);
					write_key(0x7e);
					break;

				case 0x3c:
					write_key(0x1b);               /* F3 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x33);
					write_key(0x7e);
					break;

				case 0x3d:
					write_key(0x1b);		/* F4 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x34);
					write_key(0x7e);
					break;

				case 0x3e:
					write_key(0x1b);		/* F5 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x35);
					write_key(0x7e);
					break;

				case 0x3f:
					write_key(0x1b);		/* F6 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x37);
					write_key(0x7e);
					break;

				case 0x40:
					write_key(0x1b);		/* F7 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x38);
					write_key(0x7e);
					break;

				case 0x41:
					write_key(0x1b);		/* F8 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x39);
					write_key(0x7e);
					break;

				case 0x42:
					write_key(0x1b);		/* F9 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x30);
					write_key(0x7e);
					break;

				case 0x43:
					write_key(0x1b);	       /* F10 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x31);
					write_key(0x7e);
					break;

				case 0x44:
					write_key(0x1b);	       /* F11 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x33);
					write_key(0x7e);
					break;

				case 0x45:
					write_key(0x1b);	       /* F12 */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x34);
					write_key(0x7e);
					break;

				case 0x47:	         /* scroll-lock key ? */
					set_leds ^= LED_SCROLL_LOCK;
					break;

				case 0x49:
					write_key(0x1b);	       /* INS */
					write_key(0x5b);
					write_key(0x31);
					write_key(0x7e);
					break;

				case 0x4a:
					write_key(0x1b);	      /* HOME */
					write_key(0x5b);
					write_key(0x32);
					write_key(0x7e);
					break;

				case 0x4b:
					write_key(0x1b);	      /* PgUp */
					write_key(0x5b);
					write_key(0x33);
					write_key(0x7e);
					break;

				case 0x4c:
					write_key(0x1b);	       /* DEL */
					write_key(0x5b);
					write_key(0x34);
					write_key(0x7e);
					break;

				case 0x4d:
					write_key(0x1b);	       /* END */
					write_key(0x5b);
					write_key(0x35);
					write_key(0x7e);
					break;

				case 0x4e:
					write_key(0x1b);	      /* PgDn */
					write_key(0x5b);
					write_key(0x36);
					write_key(0x7e);
					break;

				case 0x4f:
					write_key(0x1b);	   /* R-Arrow */
					write_key(0x5b);
					write_key(0x43);
					break;

				case 0x50:
					write_key(0x1b);	   /* L-Arrow */
					write_key(0x5b);
					write_key(0x44);
					break;

				case 0x51:
					write_key(0x1b);	   /* D-Arrow */
					write_key(0x5b);
					write_key(0x42);
					break;

				case 0x52:
					write_key(0x1b);	   /* U-Arrow */
					write_key(0x5b);
					write_key(0x41);
					break;

				case 0x53:	            /* num-lock key ? */
					set_leds ^= LED_NUM_LOCK;
					break;

				default:
					/* convert key position to ASCII code */
					get_char(buf[0], key_pos);
					break;
				}
			}
		}
		i++;
	}
	/*****************************************/
	/* all keys are processed, create a copy */
	/* to flag them as processed             */
	/*****************************************/
	for (i = 2, j = 0; j < 6; i++, j++)
		key_last[j] = buf[i];      /* copy all actual keys to last */
}

#define USB_HID_SIZE 128
uint32_t *kbd_buffer;

int usb_hid_kbd_init(struct usb_dev *dev)
{
	int i;
	uint8_t key[8];

	usb_hid_set_protocol(dev, 0);
	usb_hid_set_idle(dev, 500);

	memset(key, 0, 8);
	if (usb_hid_get_report(dev, key, 8))
		check_key_code(key);

	kbd_buffer = SLOF_dma_alloc(USB_HID_SIZE);
	if (!kbd_buffer) {
		printf("%s: unable to allocate keyboard buffer\n", __func__);
		return false;
	}

#ifdef KEY_DEBUG
	printf("HID kbd init %d\n", dev->ep_cnt);
#endif
	for (i = 0; i < dev->ep_cnt; i++) {
		if ((dev->ep[i].bmAttributes & USB_EP_TYPE_MASK)
			== USB_EP_TYPE_INTR)
			usb_dev_populate_pipe(dev, &dev->ep[i], kbd_buffer, USB_HID_SIZE);
	}
	return true;
}

int usb_hid_kbd_exit(struct usb_dev *dev)
{
	if (dev->intr) {
		usb_put_pipe(dev->intr);
		dev->intr = NULL;
	}
	SLOF_dma_free(kbd_buffer, USB_HID_SIZE);
	return true;
}

unsigned char usb_key_available(void *dev)
{
	if (dev && r_ptr != w_ptr)
		return true;
	else
		return false;
}

unsigned char usb_read_keyb(void *vdev)
{
	struct usb_dev *dev = vdev;
	uint8_t key[8];

	if (!dev)
		return false;

	memset(key, 0, 8);
	while (usb_poll_intr(dev->intr, key)) {
		check_key_code(key);
		memset(key, 0, 8);
	}
	return read_key();
}
