/*
 * 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)
 */
/*
 * These functions need to be implemented by platform
 * specific code.
 */

#ifndef __USB_USB_HOST_H_
#define __USB_USB_HOST_H_

#include <platsupport/io.h>
#include <platsupport/sync/sync.h>
#include <usb/plat/usb.h>

enum usb_speed {
/// 1.5Mbps connection
    USBSPEED_LOW  = 0,
/// 12Mbps connection
    USBSPEED_FULL = 1,
/// 480Mbps connection
    USBSPEED_HIGH = 2
};

/*
 * Endpoint types
 * NOTE: do not change the defined order, see USB 2.0 spec(9.6.6)
 */
enum usb_endpoint_type {
    EP_CONTROL = 0,
    EP_ISOCHRONOUS,
    EP_BULK,
    EP_INTERRUPT
};

/* NOTE: do not change the defined order, see USB 2.0 spec(9.6.6) */
enum usb_endpoint_dir {
    EP_DIR_OUT = 0,
    EP_DIR_IN
};

struct endpoint {
    enum usb_endpoint_type type;
    uint8_t   num;               // Endpoint number
    enum usb_endpoint_dir  dir;  // Endpoint direction
    uint16_t  max_pkt;   // Maximum packet size
    uint8_t   interval;  // Interval for polling or NAK rate for Bulk/Control

    /* For host controller driver only, actually holds queue head. */
    void      *hcpriv;
};

enum usb_xact_type {
/// Input PID
    PID_IN,
/// Output PID
    PID_OUT,
/// Setup PID
    PID_SETUP
};

enum usb_xact_status {
/// The transaction completed successfully
    XACTSTAT_SUCCESS,
/// The transaction has not been processed
    XACTSTAT_PENDING,
/// The transaction was cancelled due to disconnect, etc
    XACTSTAT_CANCELLED,
/// There was an error in processing the transaction
    XACTSTAT_ERROR,
/// The host exhibited a failure during the transaction.
    XACTSTAT_HOSTERROR
};

/*
 * XXX: The xact size has to meet the QTD limitation. We only allocate one QTD
 * for each xact.
 */
#define MAX_XACT_SIZE  (5 * PAGE_SIZE_4K)
struct xact {
/// Transfer type
    enum usb_xact_type type;
/// DMA buffer to exchange
    void* vaddr;
    uintptr_t paddr;
/// The length of @ref{buf}
    int len;
};

static inline void* xact_get_vaddr(struct xact* xact)
{
    return xact->vaddr;
}

static inline uintptr_t xact_get_paddr(struct xact* xact)
{
    return xact->paddr;
}

/** Callback type for asynchronous USB transactions
 * @param[in] token  An unmodified opaque token as passed to
 *                   the associated transaction request.
 * @param[in] stat   The status of the transaction.
 * @param[in] rbytes The number of bytes remaining in the transaction.
 *                   This value is generally 0 on successful transmission
 *                   unless a short read or write occurs.
 * @return           1 if the transaction should be rescheduled,
 *                   otherwise, 0.
 */
typedef int (*usb_cb_t)(void* token, enum usb_xact_status stat, int rbytes);

struct usb_host;
typedef struct usb_host usb_host_t;

struct usb_host {
    /// Device ID
    enum usb_host_id id;
    /// Number of ports provided by this host controller
    int nports;

    /// DMA allocator
    ps_dma_man_t* dman;

    /// Synchronization operations
    ps_mutex_ops_t* sync;

    /// Submit a transaction for transfer.
    int (*schedule_xact)(usb_host_t* hdev, uint8_t addr, int8_t hub_addr, uint8_t hub_port,
                         enum usb_speed speed, struct endpoint *ep,
                         struct xact* xact, int nxact, usb_cb_t cb, void* t);
    /// Cancel all transactions for a given device endpoint
    int (*cancel_xact)(usb_host_t* hdev, struct endpoint *ep);
    /// Handle an IRQ
    void (*handle_irq)(usb_host_t* hdev);

    /// IRQ numbers tied to this device
    const int* irqs;
    /// Host private data
    struct usb_hc_data* pdata;
};


/**
 * Schedules a USB transaction
 * @param[in] hdev     The host controller that should be used for the transfer
 * @param[in] addr     The destination USB device address
 * @param[in] hub_addr The USB device address of the hub at which the destination
 *                     device is connected. -1 must be used if the device is not
 *                     connected to a hub (i.e. when it is the root hub).
 *                     0 may be used if the device is a SPEED_FULL device.
 * @param[in] hub_port The port at which the destination device is connected to
 *                     its parent hub.
 *                     0 may be used if the device is a SPEED_FULL device.
 * @param[in] speed    The USB speed of the device.
 * @param[in] ep       The destination endpoint of the destination device.
 * @param[in] xact     An array of packet descriptors.
 * @param[in] nxact    The number of packet descriptors in the array.
 * @param[in] cb       A callback function to call on completion.
 *                     NULL will result in blocking operation.
 * @param[in] t        A token to pass, unmodified, to the provided callback
 *                     function on completion.
 * @return             Negative values represent failure, otherwise, the
 *                     number of bytes remaining to be transferred is returned.
 */
static inline int
usb_hcd_schedule(usb_host_t* hdev, uint8_t addr, uint8_t hub_addr, uint8_t hub_port,
                 enum usb_speed speed, struct endpoint *ep,
                 struct xact* xact, int nxact, usb_cb_t cb, void* t)
{
    return hdev->schedule_xact(hdev, addr, hub_addr, hub_port, speed, ep,
                               xact, nxact, cb, t);
}

static inline void
usb_hcd_handle_irq(usb_host_t* hdev)
{
    hdev->handle_irq(hdev);
}

static inline int
usb_hcd_count_ports(usb_host_t* hdev)
{
    return hdev->nports;
}

/**
 * Initialise USB host controller.
 * This function should only be called if you wish to use a raw API for the usb host controller, otherwise,
 * this function will be called by usb_init and the appropriate book keeping for device management
 * will be created and maintained.
 * @param[in]  id     The id of the host controller to initialise
 * @param[in]  ioops  a list of io operation functions.
 *                    of the initialised host controller
 * @param[in]  sync   a list of mutex operation functions.
 * @param[out] hdev   A host structure to populate. This must
 *                    already be filled with a DMA allocator.
 *                    and the device ID.
 * @return            0 on success
 */
int usb_host_init(enum usb_host_id id, ps_io_ops_t* ioops, ps_mutex_ops_t *sync, usb_host_t* hdev);

/** Return a list of IRQ numbers handled by the provided host
 * @param[in]  host   A handle to the USB host device in question
 * @param[out] nirqs  The number of IRQs handled by this host.
 * @return            A NULL terminated list of IRQs
 */
const int* usb_host_irqs(usb_host_t* host, int* nirqs);


#endif /* __USB_USB_HOST_H_ */

