/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */
#include "otgusbtty.h"
#include <usb/usb.h>
#include "../services.h"

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

struct otg_usbtty {
    usb_otg_t otg;
    ps_dma_man_t* dman;
    void* desc;
    uintptr_t pdesc;
};

struct free_token {
    void* vaddr;
    size_t size;
    ps_dma_man_t* dman;
};

static struct device_desc otg_usbtty_device_desc = {
    .bLength                = 0x12,
    .bDescriptorType        = 0x1,
    .bcdUSB                 = 0x110,
    .bDeviceClass           = 0x0,
    .bDeviceSubClass        = 0x0,
    .bDeviceProtocol        = 0x0,
    .bMaxPacketSize0        = 0x40,
    .idVendor               = 0x067b,
    .idProduct              = 0x2303,
    .bcdDevice              = 0x300,
    .iManufacturer          = 0x0 /* 0x1 */,
    .iProduct               = 0x0 /* 0x2 */,
    .iSerialNumber          = 0x0,
    .bNumConfigurations     = 0x1
};

static struct config_desc otg_usbtty_config_desc = {
    .bLength                = 0x9,
    .bDescriptorType        = 0x2,
    .wTotalLength           = 0x27,
    .bNumInterfaces         = 0x1,
    .bConfigurationValue    = 0x1,
    .iConfigurationIndex    = 0x0,
    .bmAttributes           = 0x80,
    .bMaxPower              = 0x32
};

static struct iface_desc otg_usbtty_iface_desc = {
    .bLength                = 0x9,
    .bDescriptorType        = 0x4,
    .bInterfaceNumber       = 0x0,
    .bAlternateSetting      = 0x0,
    .bNumEndpoints          = 0x3,
    .bInterfaceClass        = 0xff,
    .bInterfaceSubClass     = 0x0,
    .bInterfaceProtocol     = 0x0,
    .iInterface             = 0x0
};

static struct endpoint_desc otg_usbtty_ep1_desc = {
    .bLength                = 0x7,
    .bDescriptorType        = 0x5,
    .bEndpointAddress       = 0x81,
    .bmAttributes           = 0x3,
    .wMaxPacketSize         = 0xa,
    .bInterval              = 0x1
};

static struct endpoint_desc otg_usbtty_ep2_desc = {
    .bLength                = 0x7,
    .bDescriptorType        = 0x5,
    .bEndpointAddress       = 0x2,
    .bmAttributes           = 0x2,
    .wMaxPacketSize         = 0x40,
    .bInterval              = 0x0
};

static struct endpoint_desc otg_usbtty_ep3_desc = {
    .bLength                = 0x7,
    .bDescriptorType        = 0x5,
    .bEndpointAddress       = 0x83,
    .bmAttributes           = 0x2,
    .wMaxPacketSize         = 0x40,
    .bInterval              = 0x0
};


static void
freebuf_cb(usb_otg_t otg, void* token,
           enum usb_xact_status stat)
{
    struct free_token* t;

    if (stat != XACTSTAT_SUCCESS) {
	    ZF_LOGF("Transaction failed\n");
    }
    t = (struct free_token*)token;
    ps_dma_free_pinned(t->dman, t->vaddr, t->size);
    usb_free(t);
}

static void
send_desc(otg_usbtty_t tty, enum DescriptorType type, int index,
          int maxlen)
{
    struct anon_desc* d = NULL;
    /* Not handling index yet... */
    if (index != 0) {
	    ZF_LOGF("Index not implemented\n");
    }
    /* Find the descriptor */
    switch (type) {
    case DEVICE:
        d = (struct anon_desc*)&otg_usbtty_device_desc;
        printf("device descriptor read/");
        if (maxlen >= d->bLength) {
            printf("all\n");
        } else {
            printf("%d\n", maxlen);
        }
        break;
    case CONFIGURATION:
        printf("config\n");
        break;
    case STRING:
        printf("string\n");
        break;
    case INTERFACE:
        printf("interface\n");
        break;
    case ENDPOINT:
        printf("endpoint\n");
        break;
    case DEVICE_QUALIFIER:
        printf("device qualifier\n");
        break;
    case OTHER_SPEED_CONFIGURATION:
        printf("other speed\n");
        break;
    case INTERFACE_POWER:
        printf("interface power\n");
        break;
    case HID:
        printf("hid\n");
        break;
    case HUB:
        printf("Hub\n");
        break;
    default:
        printf("Unhandled descriptor request\n");
    }
    /* Send the descriptor */
    if (d != NULL) {
        struct free_token* t;
        uintptr_t pbuf;
        int err;

        t = usb_malloc(sizeof(*t));
	if (!t) {
		ZF_LOGF("Out of memory\n");
	}
        t->dman = tty->dman;

        /* limit size to prevent babble */
        t->size = d->bLength;
        if (maxlen < t->size) {
            t->size = maxlen;
        }
        /* Copy in */
        t->vaddr = ps_dma_alloc_pinned(tty->dman, t->size, 32, 0, PS_MEM_NORMAL, &pbuf);
        if (t->vaddr == NULL) {
            ZF_LOGF("Out of DMA memory\n");
        }
        memcpy(t->vaddr, d, t->size);

        /* Send the packet */
        err = otg_prime(tty->otg, 0, PID_IN, t->vaddr, pbuf, t->size, freebuf_cb, t);
        if (err) {
            ps_dma_free_pinned(tty->dman, t->vaddr, t->size);
            ZF_LOGF("OTG device error\n");
        }
        /* Status phase */
        err = otg_prime(tty->otg, 0, PID_OUT, NULL, 0, 0, freebuf_cb, t);
        if (err) {
            ps_dma_free_pinned(tty->dman, t->vaddr, t->size);
            ZF_LOGF("OTG device error\n");
        }
    }
}

static void
usbtty_setup_cb(usb_otg_t otg, void* token, struct usbreq* req)
{
    otg_usbtty_t tty = (otg_usbtty_t)token;
    (void)otg_usbtty_config_desc;
    (void)otg_usbtty_iface_desc;
    (void)otg_usbtty_ep1_desc;
    (void)otg_usbtty_ep2_desc;
    (void)otg_usbtty_ep3_desc;
    switch (req->bRequest) {
    case GET_DESCRIPTOR:
        send_desc(tty, req->wValue >> 8, req->wValue & 0xff,
                  req->wLength);
        break;
    case GET_CONFIGURATION:
        printf("get conf\n");
        break;
    case GET_STATUS:
        printf("get stat\n");
        break;
    case CLR_FEATURE:
        printf("Clear feat\n");
        break;
    case SET_FEATURE:
        printf("Set feature\n");
        break;
    case SET_ADDRESS:
        printf("Set address\n");
        break;
    case SET_DESCRIPTOR:
        printf("Set descriptor\n");
        break;
    case SET_CONFIGURATION:
        printf("Set config\n");
        break;
    case GET_INTERFACE:
        printf("Get interface\n");
        break;
    case SET_INTERFACE:
        printf("Set interface\n");
        break;
    default:
        printf("Unhandled request %d\n", req->bRequest);
    }
}

int
otg_usbtty_init(usb_otg_t otg, ps_dma_man_t* dman,
                otg_usbtty_t* usbtty)
{
    otg_usbtty_t tty;
    int err;

    if (!dman || !usbtty || !otg) {
        ZF_LOGF("Invalid arguments\n");
    }

    /* Allocate memory */
    tty = usb_malloc(sizeof(*tty));
    if (tty == NULL) {
        return -1;
    }
    tty->dman = dman;
    tty->otg = otg;
    /* Initialise the control endpoint */
    err = otg_ep0_setup(otg, usbtty_setup_cb, tty);
    if (err) {
        usb_free(tty);
        return -1;
    }
    *usbtty = tty;
    return 0;
}

