/*
 * usb_e1.c
 *
 * Copyright (C) 2019-2020  Sylvain Munaut <tnt@246tNt.com>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#include <no2usb/usb_hw.h>
#include <no2usb/usb_priv.h>

#include "console.h"
#include "e1.h"
#include "misc.h"
#include "usb_desc_ids.h"
#include "utils.h"

#include "ice1usb_proto.h"

struct usb_e1_state {
	bool running;		/* are we running (transceiving USB data)? */
	int out_bdi;		/* buffer descriptor index for OUT EP */
	int in_bdi;		/* buffer descriptor index for IN EP */
	struct ice1usb_tx_config tx_cfg;
	struct ice1usb_rx_config rx_cfg;
	struct e1_error_count last_err;
};

static struct usb_e1_state g_usb_e1[2];

/* default configuration at power-up */
static const struct ice1usb_tx_config tx_cfg_default = {
	.mode		= ICE1USB_TX_MODE_TS0_CRC4_E,
	.timing		= ICE1USB_TX_TIME_SRC_LOCAL,
	.ext_loopback	= ICE1USB_TX_EXT_LOOPBACK_OFF,
	.alarm		= 0,
};

static const struct ice1usb_rx_config rx_cfg_default = {
	.mode		= ICE1USB_RX_MODE_MULTIFRAME,
};


static volatile struct usb_ep *
_get_ep_regs(uint8_t ep)
{
	return (ep & 0x80) ? &usb_ep_regs[ep & 0x1f].in : &usb_ep_regs[ep & 0x1f].out;
}

static struct usb_e1_state *
_get_state(int port)
{
	if ((port < 0) || (port > 1))
		panic("_get_state invalid port %d", port);
	return &g_usb_e1[port];
}

static int
_ifnum2port(uint8_t bInterfaceNumber)
{
	switch (bInterfaceNumber) {
	case USB_INTF_E1(0): return 0;
	case USB_INTF_E1(1): return 1;
	default:
		/* Don't panic since this will be handled as USB STALL */
		return -1;
	}
}


static void
_usb_fill_feedback_ep(int port)
{
	volatile struct usb_ep *ep_regs = _get_ep_regs(USB_EP_E1_FB(port));

	/* Always ensure we're ready to send */
	if ((ep_regs->bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA)
	{
		uint32_t val = 8192;

		/* Add instant bias depending on TX fifo level */
		unsigned int level = e1_tx_level(port);

		if (level < (4 * 16))
			val += 256;
		else if (level > (6 * 16))
			val -= 256;

		/* Fill buffer and submit it */
		usb_data_write(ep_regs->bd[0].ptr, &val, 4);
		ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(3);
	}
}


void
usb_e1_run(int port)
{
	struct usb_e1_state *usb_e1 = _get_state(port);
	volatile struct usb_ep *ep_regs;
	int bdi;

	if (!usb_e1->running)
		return;

	/* Interrupt endpoint */
	ep_regs = _get_ep_regs(USB_EP_E1_INT(port));

	if ((ep_regs->bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA) {
		const struct e1_error_count *cur_err = e1_get_error_count(port);
		if (memcmp(cur_err, &usb_e1->last_err, sizeof(*cur_err))) {
			struct ice1usb_irq errmsg = {
				.type = ICE1USB_IRQ_T_ERRCNT,
				.u = {
					.errors = {
						.crc = cur_err->crc,
						.align = cur_err->align,
						.ovfl = cur_err->ovfl,
						.unfl = cur_err->unfl,
						.flags = cur_err->flags,
					}
				}
			};
			printf("E");
			usb_data_write(ep_regs->bd[0].ptr, &errmsg, sizeof(errmsg));
			ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(sizeof(errmsg));
			usb_e1->last_err = *cur_err;
		}
	}

	/* Data IN endpoint */
	ep_regs = _get_ep_regs(USB_EP_E1_IN(port));
	bdi = usb_e1->in_bdi;

	while ((ep_regs->bd[bdi].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA)
	{
		uint32_t ptr = ep_regs->bd[bdi].ptr;
		uint32_t hdr;
		unsigned int pos;

		/* Error check */
		if ((ep_regs->bd[bdi].csr & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_ERR)
			puts("Err EP IN\n");

		/* Get some data from E1 */
		int n = e1_rx_level(port);

		if (n > 32)
			n = 9;
		else if (n > 8)
			n = 8;
		else if (!n)
			break;

		n = e1_rx_need_data(port, (ptr >> 2) + 1, n, &pos);

		/* Write header: currently version and pos (mfr/fr number) */
		hdr = (0 << 28) | (pos & 0xff);
		usb_data_write(ptr, &hdr, 4);

		/* Resubmit */
		ep_regs->bd[bdi].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN((n * 32) + 4);

		/* Next BDI */
		bdi ^= 1;
		usb_e1->in_bdi = bdi;
	}

	/* Data OUT endpoint */
	ep_regs = _get_ep_regs(USB_EP_E1_OUT(port));
	bdi = usb_e1->out_bdi;

	while ((ep_regs->bd[bdi].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA)
	{
		uint32_t ptr = ep_regs->bd[bdi].ptr;
		uint32_t csr = ep_regs->bd[bdi].csr;
		uint32_t hdr;

		/* Error check */
		if ((csr & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_ERR) {
			puts("Err EP OUT\n");
			goto refill;
		}

		/* Grab header */
		usb_data_read(&hdr, ptr, 4);

		/* Empty data into the FIFO */
		int n = ((int)(csr & USB_BD_LEN_MSK) - 6) / 32;
		if (n > 0)
			e1_tx_feed_data(port, (ptr >> 2) + 1, n);

refill:
		/* Refill it */
		ep_regs->bd[bdi].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(292);

		/* Next BDI */
		bdi ^= 1;
		usb_e1->out_bdi = bdi;

		static int x = 0;
		if ((x++ & 0xff) == 0xff)
			puts(".");
	}

	/* Feedback endpoint */
	_usb_fill_feedback_ep(port);
}

static enum usb_fnd_resp
_e1_set_conf(const struct usb_conf_desc *conf)
{
	const struct usb_intf_desc *intf;

	printf("e1 set_conf %08x\n", conf);
	if (!conf)
		return USB_FND_SUCCESS;

	for (int port=0; port<2; port++)
	{
		intf = usb_desc_find_intf(conf, USB_INTF_E1(port), 0, NULL);
		if (!intf)
			return USB_FND_ERROR;

		printf("e1 set_conf[%d] %08x\n", port, intf);

		usb_ep_boot(intf, USB_EP_E1_IN(port),  true);
		usb_ep_boot(intf, USB_EP_E1_OUT(port), true);
		usb_ep_boot(intf, USB_EP_E1_FB(port),  false);
		usb_ep_boot(intf, USB_EP_E1_INT(port), false);
	}

	return USB_FND_SUCCESS;
}

static void _perform_tx_config(int port)
{
	struct usb_e1_state *usb_e1 = _get_state(port);
	const struct ice1usb_tx_config *cfg = &usb_e1->tx_cfg;
	e1_tx_config(port,
		((cfg->mode & 3) << 1) |
		((cfg->timing & 1) << 3) |
		((cfg->alarm & 1) << 4) |
		((cfg->ext_loopback & 3) << 5)
	);
}

static void _perform_rx_config(int port)
{
	struct usb_e1_state *usb_e1 = _get_state(port);
	const struct ice1usb_rx_config *cfg = &usb_e1->rx_cfg;
	e1_rx_config(port,
		(cfg->mode << 1)
	);
}

static enum usb_fnd_resp
_e1_set_intf(const struct usb_intf_desc *base, const struct usb_intf_desc *sel)
{
	volatile struct usb_ep *ep_regs;
	struct usb_e1_state *usb_e1;
	int port;

	/* Is it for E1 interface ? */
	if ((base->bInterfaceClass != 0xff) || (base->bInterfaceSubClass != 0xe1))
		return USB_FND_CONTINUE;

	/* Get matching port (if any) */
	port = _ifnum2port(base->bInterfaceNumber);
	if (port < 0)
		return USB_FND_ERROR;

	usb_e1 = _get_state(port);

	/* Valid setting ? */
	if (sel->bAlternateSetting > 1)
		return USB_FND_ERROR;

	/* Don't do anything if no change */
	if (usb_e1->running == (sel->bAlternateSetting != 0))
		return USB_FND_SUCCESS;

	usb_e1->running = (sel->bAlternateSetting != 0);

	/* Reconfigure the endpoints */
	usb_ep_reconf(sel, USB_EP_E1_IN(port));
	usb_ep_reconf(sel, USB_EP_E1_OUT(port));
	usb_ep_reconf(sel, USB_EP_E1_FB(port));
	usb_ep_reconf(sel, USB_EP_E1_INT(port));

	/* Update E1 and USB state */
	switch (usb_e1->running) {
	case false:
		/* Disable E1 rx/tx */
		e1_init(port, 0, 0);
		break;

	case true:
		/* Reset and Re-Enable E1 */
		e1_init(port, 0, 0);
		_perform_rx_config(port);
		_perform_tx_config(port);

		/* Reset BDI */
		usb_e1->in_bdi = 0;
		usb_e1->out_bdi = 0;

		/* EP OUT: Queue two buffers */
		ep_regs = _get_ep_regs(USB_EP_E1_OUT(port));
		ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(292);
		ep_regs->bd[1].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(292);

		break;
	}

	return USB_FND_SUCCESS;
}

static enum usb_fnd_resp
_e1_get_intf(const struct usb_intf_desc *base, uint8_t *alt)
{
	struct usb_e1_state *usb_e1;
	int port;

	/* Is it for E1 interface ? */
	if ((base->bInterfaceClass != 0xff) || (base->bInterfaceSubClass != 0xe1))
		return USB_FND_CONTINUE;

	/* Get matching port (if any) */
	port = _ifnum2port(base->bInterfaceNumber);
	if (port < 0)
		return USB_FND_ERROR;

	usb_e1 = _get_state(port);

	/* Return current alt-setting */
	*alt = usb_e1->running ? 1 : 0;

	return USB_FND_SUCCESS;
}

static bool
_set_tx_mode_done(struct usb_xfer *xfer)
{
	const struct ice1usb_tx_config *cfg = (const struct ice1usb_tx_config *) xfer->data;
	struct usb_ctrl_req *req = xfer->cb_ctx;
	int port = _ifnum2port(req->wIndex);
	struct usb_e1_state *usb_e1 = _get_state(port);
	printf("set_tx_mode[%d] %02x%02x%02x%02x\r\n", port,
		xfer->data[0], xfer->data[1], xfer->data[2], xfer->data[3]);
	usb_e1->tx_cfg = *cfg;
	_perform_tx_config(port);
	return true;
}

static bool
_set_rx_mode_done(struct usb_xfer *xfer)
{
	const struct ice1usb_rx_config *cfg = (const struct ice1usb_rx_config *) xfer->data;
	struct usb_ctrl_req *req = xfer->cb_ctx;
	int port = _ifnum2port(req->wIndex);
	struct usb_e1_state *usb_e1 = _get_state(port);
	printf("set_rx_mode[%d] %02x\r\n", port, xfer->data[0]);
	usb_e1->rx_cfg = *cfg;
	_perform_rx_config(port);
	return true;
}

/* per-interface requests */
static enum usb_fnd_resp
_e1_ctrl_req_intf(struct usb_ctrl_req *req, struct usb_xfer *xfer)
{
	struct usb_e1_state *usb_e1;
	int port;

	/* Get matching port (if any) */
	port = _ifnum2port(req->wIndex);
	if (port < 0)
		return USB_FND_CONTINUE;

	usb_e1 = _get_state(port);

	/* Process request */
	switch (req->bRequest) {
	case ICE1USB_INTF_GET_CAPABILITIES:
		/* no optional capabilities yet */
		xfer->len = 0;
		break;
	case ICE1USB_INTF_SET_TX_CFG:
		if (req->wLength < sizeof(struct ice1usb_tx_config))
			return USB_FND_ERROR;
		xfer->cb_done = _set_tx_mode_done;
		xfer->cb_ctx = req;
		xfer->len = sizeof(struct ice1usb_tx_config);
		break;
	case ICE1USB_INTF_GET_TX_CFG:
		if (req->wLength < sizeof(struct ice1usb_tx_config))
			return USB_FND_ERROR;
		memcpy(xfer->data, &usb_e1->tx_cfg, sizeof(struct ice1usb_tx_config));
		xfer->len = sizeof(struct ice1usb_tx_config);
		break;
	case ICE1USB_INTF_SET_RX_CFG:
		if (req->wLength < sizeof(struct ice1usb_rx_config))
			return USB_FND_ERROR;
		xfer->cb_done = _set_rx_mode_done;
		xfer->cb_ctx = req;
		xfer->len = sizeof(struct ice1usb_rx_config);
		break;
	case ICE1USB_INTF_GET_RX_CFG:
		if (req->wLength < sizeof(struct ice1usb_rx_config))
			return USB_FND_ERROR;
		memcpy(xfer->data, &usb_e1->rx_cfg, sizeof(struct ice1usb_rx_config));
		xfer->len = sizeof(struct ice1usb_rx_config);
		break;
	default:
		return USB_FND_ERROR;
	}

	return USB_FND_SUCCESS;
}

/* device-global requests */
static enum usb_fnd_resp
_e1_ctrl_req_dev(struct usb_ctrl_req *req, struct usb_xfer *xfer)
{
	switch (req->bRequest) {
	case ICE1USB_DEV_GET_CAPABILITIES:
		xfer->data[0] = (1 << ICE1USB_DEV_CAP_GPSDO);
		xfer->len = 1;
		break;
	default:
		return USB_FND_ERROR;
	}

	return USB_FND_SUCCESS;
}


/* USB host issues a control request to us */
static enum usb_fnd_resp
_e1_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
{
	if (USB_REQ_TYPE(req) != USB_REQ_TYPE_VENDOR)
		return USB_FND_CONTINUE;

	switch (USB_REQ_RCPT(req)) {
	case USB_REQ_RCPT_DEV:
		return _e1_ctrl_req_dev(req, xfer);
	case USB_REQ_RCPT_INTF:
		return _e1_ctrl_req_intf(req, xfer);
	case USB_REQ_RCPT_EP:
	case USB_REQ_RCPT_OTHER:
	default:
		return USB_FND_ERROR;
	}
}


static struct usb_fn_drv _e1_drv = {
	.set_conf	= _e1_set_conf,
        .set_intf       = _e1_set_intf,
        .get_intf       = _e1_get_intf,
	.ctrl_req	= _e1_ctrl_req,
};

void
usb_e1_init(void)
{
	for (int i=0; i<2; i++) {
		struct usb_e1_state *usb_e1 = _get_state(i);
		memset(usb_e1, 0x00, sizeof(struct usb_e1_state));
		usb_e1->tx_cfg = tx_cfg_default;
		usb_e1->rx_cfg = rx_cfg_default;
	}

	usb_register_function_driver(&_e1_drv);
}
