// 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.

#include <stdint.h>
#include <threads.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <fbl/alloc_checker.h>
#include <fbl/unique_ptr.h>
#include <hw/reg.h>
#include <soc/mt8167/mt8167-hw.h>
#include <zircon/syscalls/port.h>
#include <zircon/types.h>

#include "mt8167-gpio.h"

namespace gpio {

int Mt8167GpioDevice::Thread() {
    while (1) {
        zx_port_packet_t packet;
        zx_status_t status = port_.wait(zx::time::infinite(), &packet);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s port wait failed: %d\n", __FUNCTION__, status);
            return thrd_error;
        }
        uint32_t index = eint_.GetNextInterrupt(0);
        while (index != ExtendedInterruptReg::kInvalidInterruptIdx &&
               index < interrupts_.size() &&
               interrupts_[index].is_valid()) {
            zxlogf(TRACE, "%s msg on port key %lu  EINT %u\n", __FUNCTION__, packet.key, index);
            if (eint_.IsEnabled(index)) {
                zxlogf(TRACE, "%s zx_interrupt_trigger for %u\n", __FUNCTION__, index);
                status = interrupts_[index].trigger(0, zx::time(packet.interrupt.timestamp));
                if (status != ZX_OK) {
                    zxlogf(ERROR, "%s zx_interrupt_trigger failed %d \n", __FUNCTION__, status);
                }
            }
            eint_.AckInterrupt(index);
            index = eint_.GetNextInterrupt(index + 1);
        }
        int_.ack();
    }
}

zx_status_t Mt8167GpioDevice::GpioImplConfigIn(uint32_t index, uint32_t flags) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    GpioModeReg::SetMode(&gpio_mmio_, index, GpioModeReg::kModeGpio);
    dir_.SetDir(index, false);
    const uint32_t pull_mode = flags & GPIO_PULL_MASK;

    switch (pull_mode) {
    case GPIO_NO_PULL:
        if (pull_en_.PullDisable(index)) {
            return ZX_OK;
        }
        break;
    case GPIO_PULL_UP:
        if (pull_en_.PullEnable(index) && pull_sel_.SetPullUp(index)) {
            return ZX_OK;
        }
        break;
    case GPIO_PULL_DOWN:
        if (pull_en_.PullEnable(index) && pull_sel_.SetPullDown(index)) {
            return ZX_OK;
        }
        break;
    }

    // If not supported above, try IO Config.
    // TODO(andresoportus): We only support enable/disable pull through the GPIO protocol, so
    // until we allow passing particular pull amounts we can specify here different pull amounts
    // for particular GPIOs.
    PullAmount pull_amount = kPull10K;
    if (index >= 40 && index <= 43) {
        pull_amount = kPull75K;
    }
    switch (pull_mode) {
    case GPIO_NO_PULL:
        if (iocfg_.PullDisable(index)) {
            return ZX_OK;
        }
        break;
    case GPIO_PULL_UP:
        if (iocfg_.PullEnable(index, pull_amount) && iocfg_.SetPullUp(index)) {
            return ZX_OK;
        }
        break;
    case GPIO_PULL_DOWN:
        if (iocfg_.PullEnable(index, pull_amount) && iocfg_.SetPullDown(index)) {
            return ZX_OK;
        }
        break;
    }

    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Mt8167GpioDevice::GpioImplConfigOut(uint32_t index, uint8_t initial_value) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    GpioModeReg::SetMode(&gpio_mmio_, index, GpioModeReg::kModeGpio);
    dir_.SetDir(index, true);
    return GpioImplWrite(index, initial_value);
}

zx_status_t Mt8167GpioDevice::GpioImplSetAltFunction(uint32_t index, uint64_t function) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (function >= GpioModeReg::kModeMax) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    GpioModeReg::SetMode(&gpio_mmio_, index, static_cast<uint16_t>(function));
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::GpioImplRead(uint32_t index, uint8_t* out_value) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    *out_value = static_cast<uint8_t>(in_.GetVal(index));
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::GpioImplWrite(uint32_t index, uint8_t value) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    out_.SetVal(index, value);
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::GpioImplGetInterrupt(uint32_t index, uint32_t flags,
                                                   zx::interrupt* out_irq) {
    zx_status_t status;
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }

    if (eint_.IsEnabled(index)) {
        zxlogf(ERROR, "%s interrupt %u already exists\n", __FUNCTION__, index);
        return ZX_ERR_ALREADY_EXISTS;
    }

    zx::interrupt irq;
    status = zx::interrupt::create(zx::resource(), index, ZX_INTERRUPT_VIRTUAL, &irq);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s zx::interrupt::create failed %d \n", __FUNCTION__, status);
        return status;
    }
    status = irq.duplicate(ZX_RIGHT_SAME_RIGHTS, out_irq);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s interrupt.duplicate failed %d \n", __FUNCTION__, status);
        return status;
    }

    switch (flags & ZX_INTERRUPT_MODE_MASK) {
    case ZX_INTERRUPT_MODE_EDGE_LOW:
        eint_.SetPolarity(index, false);
        eint_.SetEdge(index, true);
        break;
    case ZX_INTERRUPT_MODE_EDGE_HIGH:
        eint_.SetPolarity(index, true);
        eint_.SetEdge(index, true);
        break;
    case ZX_INTERRUPT_MODE_LEVEL_LOW:
        eint_.SetPolarity(index, false);
        eint_.SetEdge(index, false);
        break;
    case ZX_INTERRUPT_MODE_LEVEL_HIGH:
        eint_.SetPolarity(index, true);
        eint_.SetEdge(index, false);
        break;
    case ZX_INTERRUPT_MODE_EDGE_BOTH:
        return ZX_ERR_NOT_SUPPORTED;
    default:
        return ZX_ERR_INVALID_ARGS;
    }
    interrupts_[index] = std::move(irq);
    eint_.Enable(index);
    zxlogf(TRACE, "%s EINT %u enabled\n", __FUNCTION__, index);
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::GpioImplReleaseInterrupt(uint32_t index) {
    if (index >= interrupts_.size() || !eint_.IsEnabled(index)) {
        return ZX_ERR_INVALID_ARGS;
    }
    eint_.Disable(index);
    interrupts_[index].destroy();
    interrupts_[index].reset();
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::GpioImplSetPolarity(uint32_t index, uint32_t polarity) {
    if (index >= interrupts_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (polarity == GPIO_POLARITY_LOW) {
        eint_.SetPolarity(index, false);
        return ZX_OK;
    } else if (polarity == GPIO_POLARITY_HIGH) {
        eint_.SetPolarity(index, true);
        return ZX_OK;
    }
    return ZX_ERR_INVALID_ARGS;
}

void Mt8167GpioDevice::ShutDown() {
    int_.destroy();
    thrd_join(thread_, NULL);
}

void Mt8167GpioDevice::DdkUnbind() {
    ShutDown();
    DdkRemove();
}

void Mt8167GpioDevice::DdkRelease() {
    delete this;
}

zx_status_t Mt8167GpioDevice::Bind() {
    pdev_protocol_t pdev;
    zx_status_t status = device_get_protocol(parent(), ZX_PROTOCOL_PDEV, &pdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s ZX_PROTOCOL_PDEV not available %d \n", __FUNCTION__, status);
        return status;
    }

    status = pdev_map_interrupt(&pdev, 0, int_.reset_and_get_address());
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pdev_map_interrupt failed %d\n", __FUNCTION__, status);
        return status;
    }

    status = zx::port::create(ZX_PORT_BIND_TO_INTERRUPT, &port_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s zx_port_create failed %d\n", __FUNCTION__, status);
        return status;
    }

    status = int_.bind(port_, 0, 0 /*options*/);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s zx_interrupt_bind failed %d\n", __FUNCTION__, status);
        return status;
    }
    fbl::AllocChecker ac;
    interrupts_ = fbl::Array(new (&ac) zx::interrupt[MT8167_GPIO_EINT_MAX], MT8167_GPIO_EINT_MAX);
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    for (uint32_t i = 0; i < interrupts_.size(); ++i) {
        eint_.SetDomain0(i);
        eint_.Disable(i);
    }

    auto cb = [](void* arg) -> int { return reinterpret_cast<Mt8167GpioDevice*>(arg)->Thread(); };
    int rc = thrd_create_with_name(&thread_, cb, this, "mt8167-gpio-thread");
    if (rc != thrd_success) {
        return ZX_ERR_INTERNAL;
    }

    status = DdkAdd("mt8167-gpio");
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s DdkAdd failed %d\n", __FUNCTION__, status);
        ShutDown();
        return status;
    }
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::Init() {
    zx_status_t status;
    pbus_protocol_t pbus;
    status = device_get_protocol(parent(), ZX_PROTOCOL_PBUS, &pbus);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: ZX_PROTOCOL_PBUS not available %d\n", __FUNCTION__, status);
        return status;
    }
    gpio_impl_protocol_t gpio_proto = {
        .ops = &gpio_impl_protocol_ops_,
        .ctx = this,
    };
    const platform_proxy_cb_t kCallback = {nullptr, nullptr};
    status = pbus_register_protocol(&pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_proto, sizeof(gpio_proto),
                                    &kCallback);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pbus_register_protocol failed %d\n", __FUNCTION__, status);
        ShutDown();
        return status;
    }
    return ZX_OK;
}

zx_status_t Mt8167GpioDevice::Create(zx_device_t* parent) {
    pdev_protocol_t pdev;
    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s ZX_PROTOCOL_PDEV not available %d \n", __FUNCTION__, status);
        return status;
    }

    mmio_buffer_t gpio_mmio;
    status = pdev_map_mmio_buffer(&pdev, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &gpio_mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s gpio pdev_map_mmio_buffer failed %d\n", __FUNCTION__, status);
        return status;
    }

    mmio_buffer_t iocfg_mmio;
    status = pdev_map_mmio_buffer(&pdev, 1, ZX_CACHE_POLICY_UNCACHED_DEVICE, &iocfg_mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s iocfg pdev_map_mmio_buffer failed %d\n", __FUNCTION__, status);
        return status;
    }

    mmio_buffer_t eint_mmio;
    status = pdev_map_mmio_buffer(&pdev, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &eint_mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: pdev_map_mmio_buffer gpio failed %d\n", __FUNCTION__, status);
        return status;
    }

    fbl::AllocChecker ac;
    auto dev = fbl::make_unique_checked<gpio::Mt8167GpioDevice>(&ac, parent, gpio_mmio, iocfg_mmio,
                                                                eint_mmio);
    if (!ac.check()) {
        zxlogf(ERROR, "mt8167_gpio_bind: ZX_ERR_NO_MEMORY\n");
        return ZX_ERR_NO_MEMORY;
    }
    status = dev->Bind();
    if (status != ZX_OK) {
        return status;
    }

    // devmgr is now in charge of the memory for dev
    auto ptr = dev.release();
    return ptr->Init();
}

zx_status_t mt8167_gpio_bind(void* ctx, zx_device_t* parent) {
    return gpio::Mt8167GpioDevice::Create(parent);
}

} // namespace gpio
