// Copyright 2019 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 <algorithm>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <fbl/alloc_checker.h>
#include <fbl/array.h>
#include <fbl/unique_ptr.h>

#include "qcom-gpio.h"

namespace {

uint64_t kPortKeyIrqMsg = 0x00;
uint64_t kPortKeyTerminate = 0x01;

} // namespace

namespace gpio {

int QcomGpioDevice::Thread() {
    while (1) {
        zx_port_packet_t packet;
        auto status = port_.wait(zx::time::infinite(), &packet);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s port wait failed: %d\n", __func__, status);
            return thrd_error;
        }
        zxlogf(TRACE, "%s msg on port key %lu\n", __func__, packet.key);
        if (packet.key == kPortKeyTerminate) {
            zxlogf(INFO, "QCOM GPIO thread terminating\n");
            return 0;
        }
        size_t index = 0;
        status = enabled_ints_cache_.Find(true, 0, kGpioMax, 1, &index);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s no interrupt found in cache %d\n", __func__, status);
        }
        while (status == ZX_OK) {
            zxlogf(TRACE, "%s msg on port INT %lu\n", __func__, index);
            if (status_int_.Status(index)) {
                status = interrupts_[index].trigger(0, zx::time(packet.interrupt.timestamp));
                if (status != ZX_OK) {
                    zxlogf(ERROR, "%s zx_interrupt_trigger failed %d\n", __func__, status);
                }
                status_int_.Clear(index);
            } else {
                zxlogf(ERROR, "%s interrupt %lu not enabled in reg\n", __func__, index);
            }
            status = enabled_ints_cache_.Find(true, index + 1, kGpioMax, 1, &index);
            if (status != ZX_ERR_NO_RESOURCES) { // not just not-found in cache.
                zxlogf(ERROR, "%s error in reading from cache %d\n", __func__, status);
            }
        }
        combined_int_.ack();
    }
}

zx_status_t QcomGpioDevice::GpioImplConfigIn(uint32_t index, uint32_t flags) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    GpioCfgReg::SetMode(&gpio_mmio_, index, GpioCfgReg::kModeGpio);
    GpioCfgReg::SetOut(&gpio_mmio_, index, false);
    const uint32_t pull_mode = flags & GPIO_PULL_MASK;

    // clang-format off
    switch (pull_mode) {
    case GPIO_NO_PULL:   GpioCfgReg::SetPullNone(&gpio_mmio_, index); break;
    case GPIO_PULL_DOWN: GpioCfgReg::SetPullDown(&gpio_mmio_, index); break;
    case GPIO_PULL_UP:   GpioCfgReg::SetPullUp  (&gpio_mmio_, index); break;
    default: return ZX_ERR_NOT_SUPPORTED;
    }
    // clang-format on
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplConfigOut(uint32_t index, uint8_t initial_value) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    GpioCfgReg::SetMode(&gpio_mmio_, index, GpioCfgReg::kModeGpio);
    GpioCfgReg::SetOut(&gpio_mmio_, index, true);
    return GpioImplWrite(index, initial_value);
}

zx_status_t QcomGpioDevice::GpioImplSetAltFunction(uint32_t index, uint64_t function) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (function >= GpioCfgReg::kModeMax) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    GpioCfgReg::SetMode(&gpio_mmio_, index, static_cast<uint32_t>(function));
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplSetDriveStrength(uint32_t index, uint8_t mA) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    uint8_t supported_mAs[] = {2, 4, 6, 8, 10, 12, 14, 16};
    if (std::find(std::begin(supported_mAs), std::end(supported_mAs), mA) ==
        std::end(supported_mAs)) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    GpioCfgReg::SetStrength(&gpio_mmio_, index, mA);
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplRead(uint32_t index, uint8_t* out_value) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    *out_value = static_cast<uint8_t>(in_out_.GetVal(index));
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplWrite(uint32_t index, uint8_t value) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    in_out_.SetVal(index, value);
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplGetInterrupt(uint32_t index, uint32_t flags,
                                                 zx::interrupt* out_irq) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }

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

    // clang-format off
    switch (flags & ZX_INTERRUPT_MODE_MASK) {
    case ZX_INTERRUPT_MODE_EDGE_LOW:   int_cfg_.SetMode(index, Mode::EdgeLow);   break;
    case ZX_INTERRUPT_MODE_EDGE_HIGH:  int_cfg_.SetMode(index, Mode::EdgeHigh);  break;
    case ZX_INTERRUPT_MODE_LEVEL_LOW:  int_cfg_.SetMode(index, Mode::LevelLow);  break;
    case ZX_INTERRUPT_MODE_LEVEL_HIGH: int_cfg_.SetMode(index, Mode::LevelHigh); break;
    case ZX_INTERRUPT_MODE_EDGE_BOTH:  int_cfg_.SetMode(index, Mode::EdgeDual);  break;
    default: return ZX_ERR_INVALID_ARGS;
    }
    // clang-format on

    interrupts_[index] = std::move(irq);
    // TODO(andresoportus): Once we define which cases would use them, enable direct interrupts
    // (via TlmmDirConnIntReg).
    status_int_.Clear(index);
    int_cfg_.EnableCombined(index, true);
    enabled_ints_cache_.SetOne(index);
    zxlogf(TRACE, "%s INT %u enabled\n", __func__, index);
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplReleaseInterrupt(uint32_t index) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    interrupts_[index].destroy();
    interrupts_[index].reset();
    int_cfg_.EnableCombined(index, false);
    enabled_ints_cache_.ClearOne(index);
    zxlogf(TRACE, "%s INT %u disabled\n", __func__, index);
    return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplSetPolarity(uint32_t index, uint32_t polarity) {
    if (index >= kGpioMax) {
        return ZX_ERR_INVALID_ARGS;
    }
    int_cfg_.SetPolarity(index, static_cast<bool>(polarity));
    return ZX_OK;
}

void QcomGpioDevice::ShutDown() {
    combined_int_.destroy();
    zx_port_packet packet = {kPortKeyTerminate, ZX_PKT_TYPE_USER, ZX_OK, {}};
    auto status = port_.queue(&packet);
    ZX_ASSERT(status == ZX_OK);
    thrd_join(thread_, NULL);
}

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

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

zx_status_t QcomGpioDevice::Bind() {
    auto status = pdev_.GetInterrupt(0, &combined_int_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s GetInterrupt failed %d\n", __func__, status);
        return status;
    }

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

    status = combined_int_.bind(port_, kPortKeyIrqMsg, 0 /*options*/);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s interrupt bind failed %d\n", __func__, status);
        return status;
    }

    fbl::AllocChecker ac;
    interrupts_ = fbl::Array(new (&ac) zx::interrupt[kGpioMax], kGpioMax);
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

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

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

zx_status_t QcomGpioDevice::Init() {
    pbus_protocol_t pbus;
    auto status = device_get_protocol(parent(), ZX_PROTOCOL_PBUS, &pbus);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: ZX_PROTOCOL_PBUS not available %d\n", __func__, status);
        return status;
    }
    gpio_impl_protocol_t gpio_proto = {
        .ops = &gpio_impl_protocol_ops_,
        .ctx = this,
    };
    status = pbus_register_protocol(&pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_proto, sizeof(gpio_proto));
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pbus_register_protocol failed %d\n", __func__, status);
        ShutDown();
        return status;
    }
    return enabled_ints_cache_.Reset(kGpioMax); // Clear and resize.
}

zx_status_t QcomGpioDevice::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", __func__, 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", __func__, status);
        return status;
    }

    fbl::AllocChecker ac;
    auto dev = fbl::make_unique_checked<gpio::QcomGpioDevice>(&ac, parent, gpio_mmio);
    if (!ac.check()) {
        zxlogf(ERROR, "qcom_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 qcom_gpio_bind(void* ctx, zx_device_t* parent) {
    return gpio::QcomGpioDevice::Create(parent);
}

} // namespace gpio
