// 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 "mt8167-i2c.h"

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/i2cimpl.h>
#include <ddk/protocol/platform-device-lib.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/platform/device.h>

#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/unique_ptr.h>

#include <zircon/syscalls/port.h>
#include <zircon/types.h>

//#define TEST_USB_REGS_READ

namespace mt8167_i2c {

constexpr size_t kMaxTransferSize = UINT16_MAX - 1; // More than enough.
constexpr size_t kHwFifoSize = 8;
constexpr uint32_t kEventCompletion = ZX_USER_SIGNAL_0;
constexpr zx::duration kTimeout = zx::msec(10);

uint32_t Mt8167I2c::I2cImplGetBusCount() {
    return bus_count_;
}

zx_status_t Mt8167I2c::I2cImplGetMaxTransferSize(uint32_t bus_id, size_t* out_size) {
    *out_size = kMaxTransferSize;
    return ZX_OK;
}

zx_status_t Mt8167I2c::I2cImplSetBitrate(uint32_t bus_id, uint32_t bitrate) {
    // TODO(andresoportus): Support changing frequencies.
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Mt8167I2c::I2cImplTransact(uint32_t id, const i2c_impl_op_t* ops, size_t count) {
    zx_status_t status = ZX_OK;
    if (id >= bus_count_) {
        return ZX_ERR_INVALID_ARGS;
    }

    auto control_reg = ControlReg::Get().ReadFrom(&keys_[id].mmio);
    control_reg.set_ackerr_det_en(1).set_clk_ext_en(1).WriteTo(&keys_[id].mmio);

    for (size_t i = 0; i < count; ++i) {
        if (ops[i].address > 0xFF) {
            return ZX_ERR_NOT_SUPPORTED;
        }
        uint8_t addr = static_cast<uint8_t>(ops[i].address);
        // TODO(andresoportus): Add support for HW transaction (write followed by read).
        status = Transact(ops[i].is_read, id, addr, ops[i].data_buffer, ops[i].data_size,
                          ops[i].stop);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s: error in bus id: %u  addr: 0x%X  size: %lu\n", __func__, id, addr,
                   ops[i].data_size);
            Reset(id);
            return status;
        }
    }

    return ZX_OK;
}

int Mt8167I2c::IrqThread() {
    zx_port_packet_t packet;
    while (1) {
        auto status = irq_port_.wait(zx::time::infinite(), &packet);
        zxlogf(TRACE, "Port key %lu triggered\n", packet.key);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s: irq_port_.wait failed %d \n", __func__, status);
            return status;
        }
        auto id = static_cast<uint32_t>(packet.key);
        ZX_ASSERT(id < keys_.size());
        keys_[id].irq.ack();
        keys_[id].event.signal(0, kEventCompletion);
    }
}

void Mt8167I2c::Reset(uint32_t id) {
    SoftResetReg::Get().ReadFrom(&keys_[id].mmio).set_soft_reset(1).WriteTo(&keys_[id].mmio);
    IntrStatReg::Get().FromValue(0xFFFFFFFF).WriteTo(&keys_[id].mmio); // Write to clear register.
}

void Mt8167I2c::DataMove(bool is_read, uint32_t id, void* buf, size_t len) {
    uint8_t* p = static_cast<uint8_t*>(buf);
    for (size_t i = 0; i < len; ++i) {
        if (is_read) {
            p[i] = DataPortReg::Get().ReadFrom(&keys_[id].mmio).reg_value();
        } else {
            DataPortReg::Get().FromValue(p[i]).WriteTo(&keys_[id].mmio);
        }
    }
}

zx_status_t Mt8167I2c::Transact(bool is_read, uint32_t id, uint8_t addr, void* buf,
                                size_t len, bool stop) {
    zx_status_t status;

    // TODO(andresoportus): Only stop when stop is set.
    // TODO(andresoportus): Add support for arbitrary sizes.
    if (len > kHwFifoSize) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint8_t addr_dir = static_cast<uint8_t>((addr << 1) | is_read);
    FifoAddrClrReg::Get().ReadFrom(&keys_[id].mmio).set_fifo_addr_clr(1).WriteTo(&keys_[id].mmio);
    SlaveAddrReg::Get().ReadFrom(&keys_[id].mmio).set_reg_value(addr_dir).WriteTo(&keys_[id].mmio);
    TransferLenReg::Get().FromValue(static_cast<uint8_t>(len)).WriteTo(&keys_[id].mmio);
    TransacLenReg::Get().FromValue(1).WriteTo(&keys_[id].mmio); // Single transaction of len bytes.

    IntrStatReg::Get().FromValue(0xFFFFFFFF).WriteTo(&keys_[id].mmio); // Write to clear register.

    if (!is_read) {
        DataMove(is_read, id, buf, len);
    }

    StartReg::Get().ReadFrom(&keys_[id].mmio).set_start(1).WriteTo(&keys_[id].mmio);
    status = keys_[id].event.wait_one(kEventCompletion, zx::deadline_after(kTimeout), nullptr);
    if (status != ZX_OK) {
        return status;
    }
    status = keys_[id].event.signal(kEventCompletion, 0);
    if (status != ZX_OK) {
        return status;
    }
    if (is_read) {
        DataMove(is_read, id, buf, len);
    }
    auto st = IntrStatReg::Get().ReadFrom(&keys_[id].mmio);
    if (st.arb_lost() || st.hs_nacker() || st.ackerr()) {
        zxlogf(ERROR, "%s: I2C error 0x%X\n", __func__,
               IntrStatReg::Get().ReadFrom(&keys_[id].mmio).reg_value());
        if (st.ackerr()) {
            zxlogf(ERROR, "%s: No I2C ack reply from peripheral\n", __func__);
        }
        return ZX_ERR_INTERNAL;
    }
    return ZX_OK;
}

void Mt8167I2c::ShutDown() {
    for (uint32_t id = 0; id < bus_count_; id++) {
        keys_[id].irq.destroy();
    }
    thrd_join(irq_thread_, NULL);
}

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

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

int Mt8167I2c::TestThread() {
#ifdef TEST_USB_REGS_READ
    constexpr uint32_t bus_id = 2;
    constexpr uint8_t addr = 0x48;
    Reset(bus_id);
    for (uint8_t data_write = 0; data_write < 0xF; ++data_write) {
        uint8_t data_read;
        i2c_impl_op_t ops[] = {
            {.address = addr,
             .data_buffer = &data_write,
             .data_size = 1,
             .is_read = false,
             .stop = false},
            {.address = addr,
             .data_buffer = &data_read,
             .data_size = 1,
             .is_read = true,
             .stop = true},
        };
        auto status = I2cImplTransact(bus_id, ops, countof(ops));
        if (status == ZX_OK) {
            zxlogf(INFO, "I2C Addr: 0x%02X Reg:0x%02X Value:0x%02X\n", addr, data_write, data_read);
        }
    }
#endif
    return 0;
}

zx_status_t Mt8167I2c::Bind() {
    zx_status_t status;

    status = zx::port::create(ZX_PORT_BIND_TO_INTERRUPT, &irq_port_);
    if (status != ZX_OK) {
        return status;
    }

    pdev_protocol_t pdev;
    status = device_get_protocol(parent(), ZX_PROTOCOL_PDEV, &pdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s ZX_PROTOCOL_PLATFORM_DEV failed %d\n", __FUNCTION__, status);
        return ZX_ERR_NOT_SUPPORTED;
    }

    pdev_device_info_t info;
    status = pdev_get_device_info(&pdev, &info);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pdev_get_device_info failed %d\n", __FUNCTION__, status);
        return ZX_ERR_NOT_SUPPORTED;
    }

    bus_count_ = info.mmio_count - 1; // Last MMIO is for XO clock.
    if (bus_count_ != MT8167_I2C_CNT) {
        zxlogf(ERROR, "%s wrong I2C count %d\n", __FUNCTION__, bus_count_);
        return ZX_ERR_INTERNAL;
    }

    mmio_buffer_t mmio;
    status = pdev_map_mmio_buffer(&pdev, bus_count_, ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pdev_map_mmio_buffer failed %d\n", __FUNCTION__, status);
        return status;
    }
    xo_regs_ = XoRegs(mmio); // Last MMIO is for XO clock.

    for (uint32_t id = 0; id < bus_count_; id++) {
        status = pdev_map_mmio_buffer(&pdev, id, ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s pdev_map_mmio_buffer failed %d\n", __FUNCTION__, status);
            return status;
        }

        zx::event event;
        status = zx::event::create(0, &event);
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s zx::event::create failed %d\n", __FUNCTION__, status);
            return status;
        }
        keys_.push_back({ddk::MmioBuffer(mmio), zx::interrupt(), std::move(event)});

        status = pdev_get_interrupt(&pdev, id, 0, keys_[id].irq.reset_and_get_address());
        if (status != ZX_OK) {
            return status;
        }
        status = keys_[id].irq.bind(irq_port_, id, 0); // id is the port key used.
        if (status != ZX_OK) {
            return status;
        }

        // TODO(andresoportus): Add support for turn on only during transactions?.
        xo_regs_.value().ClockEnable(id, true);

        // TODO(andresoportus): Add support for DMA mode.
    }

    auto thunk = [](void* arg) -> int { return reinterpret_cast<Mt8167I2c*>(arg)->IrqThread(); };
    int rc = thrd_create_with_name(&irq_thread_, thunk, this, "mt8167-i2c");
    if (rc != thrd_success) {
        return ZX_ERR_INTERNAL;
    }

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

zx_status_t Mt8167I2c::Init() {
    auto cleanup = fbl::MakeAutoCall([&]() { ShutDown(); });

    pbus_protocol_t pbus;
    if (device_get_protocol(parent(), ZX_PROTOCOL_PBUS, &pbus) != ZX_OK) {
        zxlogf(ERROR, "%s ZX_PROTOCOL_PLATFORM_BUS not available\n", __FUNCTION__);
        return ZX_ERR_NOT_SUPPORTED;
    }
    i2c_impl_protocol_t i2c_proto = {
        .ops = &i2c_impl_protocol_ops_,
        .ctx = this,
    };
    auto status = pbus_register_protocol(&pbus, ZX_PROTOCOL_I2C_IMPL, &i2c_proto, sizeof(i2c_proto));
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s pbus_register_protocol failed: %d\n", __FUNCTION__, status);
        return status;
    }

#ifdef TEST_USB_REGS_READ
    auto thunk =
        [](void* arg) -> int { return reinterpret_cast<Mt8167I2c*>(arg)->TestThread(); };
    int rc = thrd_create_with_name(&irq_thread_, thunk, this, "mt8167-i2c-test");
    if (rc != thrd_success) {
        return ZX_ERR_INTERNAL;
    }
#endif

    cleanup.cancel();
    return ZX_OK;
}

zx_status_t Mt8167I2c::Create(zx_device_t* parent) {
    fbl::AllocChecker ac;
    auto dev = fbl::make_unique_checked<Mt8167I2c>(&ac, parent);
    if (!ac.check()) {
        zxlogf(ERROR, "%s ZX_ERR_NO_MEMORY\n", __FUNCTION__);
        return ZX_ERR_NO_MEMORY;
    }

    auto 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();
}

} // namespace mt8167_i2c

extern "C" zx_status_t mt8167_i2c_bind(void* ctx, zx_device_t* parent) {
    return mt8167_i2c::Mt8167I2c::Create(parent);
}
