// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <ddktl/device.h>
#include <ddktl/mmio.h>
#include <ddktl/pdev.h>
#include <ddktl/protocol/usb-dci.h>
#include <fbl/macros.h>
#include <fbl/mutex.h>
#include <fbl/optional.h>
#include <fbl/unique_ptr.h>
#include <lib/zx/handle.h>
#include <lib/zx/interrupt.h>
#include <zircon/listnode.h>
#include <zircon/hw/usb.h>

#include <threads.h>

// DMA support is a work in progress.
// Does not actually work yet.
#define USE_DMA 1

namespace mt_usb {

class MtUsb;
using MtUsbType = ddk::Device<MtUsb, ddk::Unbindable>;

class MtUsb : public MtUsbType, public ddk::UsbDciProtocol<MtUsb> {
public:
    explicit MtUsb(zx_device_t* parent, pdev_protocol_t* pdev)
        : MtUsbType(parent), pdev_(pdev) {}

    static zx_status_t Create(zx_device_t* parent);

    // Device protocol implementation.
    void DdkUnbind();
    void DdkRelease();

    // USB DCI protocol implementation.
     void UsbDciRequestQueue(usb_request_t* req);
     zx_status_t UsbDciSetInterface(const usb_dci_interface_t* interface);
     zx_status_t UsbDciConfigEp(const usb_endpoint_descriptor_t* ep_desc, const
                                usb_ss_ep_comp_descriptor_t* ss_comp_desc);
     zx_status_t UsbDciDisableEp(uint8_t ep_address);
     zx_status_t UsbDciEpSetStall(uint8_t ep_address);
     zx_status_t UsbDciEpClearStall(uint8_t ep_address);
     zx_status_t UsbDciGetBti(zx_handle_t* out_bti);
     size_t UsbDciGetRequestSize();

private:
    DISALLOW_COPY_ASSIGN_AND_MOVE(MtUsb);

    enum Ep0State {
        // Waiting for next setup request.
        EP0_IDLE,
        // Reading data for setup request.
        EP0_READ,
        // Writing data for setup request.
        EP0_WRITE,
    };

    enum EpDirection {
        EP_OUT,
        EP_IN,
    };

    struct Endpoint {
        // Endpoint number to use when indexing into hardware registers.
        uint8_t ep_num;
        EpDirection direction;
        uint8_t address;

#ifdef USE_DMA
        // DMA channel number allocated to this endpoint.
        uint8_t dma_channel;
        // Physical address for current DMA transaction
        zx_paddr_t dma_phys;
#endif

        bool enabled  __TA_GUARDED(lock) = false;
        uint16_t max_packet_size;

        // Requests waiting to be processed.
        list_node_t queued_reqs __TA_GUARDED(lock);
        // request currently being processed.
        usb_request_t* current_req __TA_GUARDED(lock) = nullptr;
        list_node_t complete_reqs __TA_GUARDED(lock);

        // Offset into current_req during read and write.
        size_t cur_offset;

        fbl::Mutex lock;
    };

    zx_status_t Init();
    void InitEndpoints();
    void InitPhy();
    int IrqThread();

    void HandleSuspend();
    void HandleReset();
    void HandleEp0();
#ifdef USE_DMA
    void HandleDma();
#endif
    void HandleEndpointTxLocked(Endpoint* ep) __TA_REQUIRES(ep->lock);
    void HandleEndpointRxLocked(Endpoint* ep) __TA_REQUIRES(ep->lock);

    void FifoRead(uint8_t ep_index, void* buf, size_t buflen, size_t* actual);
    void FifoWrite(uint8_t ep_index, const void* buf, size_t length);
    void EpQueueNextLocked(Endpoint* ep) __TA_REQUIRES(ep->lock);
    void StartEndpoint(Endpoint* ep);
    void StartEndpoints();

    static uint8_t EpAddressToIndex(uint8_t addr);

#ifdef USE_DMA
    static constexpr uint8_t DMA_CHANNEL_COUNT = 8;
    static constexpr uint8_t DMA_CHANNEL_INVALID = 0xff;

    zx_status_t AllocDmaChannel(Endpoint* ep);
    void ReleaseDmaChannel(Endpoint* ep);
#endif

    inline ddk::MmioBuffer* usb_mmio() {
        return &*usb_mmio_;
    }
    inline ddk::MmioBuffer* phy_mmio() {
        return &*phy_mmio_;
    }

    ddk::PDev pdev_;
    fbl::optional<ddk::UsbDciInterfaceProxy> dci_intf_;
    zx::bti bti_;

    fbl::optional<ddk::MmioBuffer> usb_mmio_;
    fbl::optional<ddk::MmioBuffer> phy_mmio_;

    zx::interrupt irq_;
    thrd_t irq_thread_;

    // Number of endpoints we support, not counting ep0.
    // We are limited to 8 DMA channels so we will really allow a total of 8.
    // But we use 16 here since we keep IN and OUT endpoints separate in the "eps_" array.
    static constexpr size_t NUM_EPS = 16;

    // Endpoints are mapped 0x01 -> 0, 0x81 -> 1, 0x02 -> 2, 0x82 -> 3, ...
    // Even index: OUT, odd index: IN.
    Endpoint eps_[NUM_EPS];

#ifdef USE_DMA
   // Maps DMA channels to the endpoints that use them.
    Endpoint* dma_eps_[DMA_CHANNEL_COUNT] = {};
#endif

    // Address assigned to us by the host.
    uint8_t address_ = 0;
    bool set_address_ = false;

    // Current USB configuration. TODO this needs a lock.
    uint8_t configuration_ = 0;

    Ep0State ep0_state_ = EP0_IDLE;
    usb_setup_t cur_setup_;

    uint8_t ep0_data_[UINT16_MAX];
    // Current read/write location in ep0_buffer_
    size_t ep0_data_offset_ = 0;
    // Total length to read or write
    size_t ep0_data_length_ = 0;

    uint8_t ep0_max_packet_;
};

} // namespace mt_usb

__BEGIN_CDECLS
zx_status_t mt_usb_bind(void* ctx, zx_device_t* parent);
__END_CDECLS
