// 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 <lib/device-protocol/pdev.h>
#include <lib/device-protocol/platform-device.h>
#include <zircon/syscalls/port.h>
#include <zircon/types.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.h>
#include <ddktl/protocol/composite.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.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);
constexpr uint32_t kAltFunctionGpio = 0;
constexpr uint32_t kAltFunctionI2c = 1;

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 && bind_finished_) {
      zxlogf(ERROR, "%s: error in bus id: %u  addr: 0x%X  size: %lu", __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", packet.key);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: irq_port_.wait failed %d ", __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()) {
    if (bind_finished_) {
      zxlogf(ERROR, "%s: I2C error 0x%X", __func__,
             IntrStatReg::Get().ReadFrom(&keys_[id].mmio).reg_value());
      if (st.ackerr()) {
        zxlogf(ERROR, "%s: No I2C ack reply from peripheral", __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::DdkUnbindNew(ddk::UnbindTxn txn) {
  ShutDown();
  txn.Reply();
}

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", addr, data_write, data_read);
    }
  }
#endif
  return 0;
}

zx_status_t Mt8167I2c::GetI2cGpios(fbl::Array<ddk::GpioProtocolClient>* gpios) {
  ddk::CompositeProtocolClient composite(parent());
  if (!composite.is_valid()) {
    zxlogf(ERROR, "%s: Could not get composite protocol", __FILE__);
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto fragment_count = composite.GetFragmentCount();
  if (fragment_count != kMaxFragments) {
    zxlogf(ERROR, "%s Wrong number of fragments %u", __func__, fragment_count);
    return ZX_ERR_INTERNAL;
  }
  size_t actual = 0;
  zx_device_t* fragments[kMaxFragments];
  composite.GetFragments(fragments, fragment_count, &actual);
  if (actual != fragment_count) {
    return ZX_ERR_INTERNAL;
  }

  size_t gpio_count = kMaxFragments - 1;  // kMaxFragments is 1 pdev + 6 GPIOs for 3 I2C busses.

  fbl::AllocChecker ac;
  gpios->reset(new (&ac) ddk::GpioProtocolClient[gpio_count], gpio_count);
  if (!ac.check()) {
    zxlogf(ERROR, "%s ZX_ERR_NO_MEMORY", __FUNCTION__);
    return ZX_ERR_NO_MEMORY;
  }

  for (uint32_t i = 0; i < gpio_count; i++) {
    auto status = device_get_protocol(fragments[i + 1], ZX_PROTOCOL_GPIO, &((*gpios)[i]));
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s ZX_PROTOCOL_GPIO failed", __FUNCTION__);
      return status;
    }
  }

  return ZX_OK;
}

zx_status_t Mt8167I2c::DoDummyTransactions() {
  fbl::Array<ddk::GpioProtocolClient> gpios;
  zx_status_t status = GetI2cGpios(&gpios);
  if (status != ZX_OK || gpios.size() == 0) {
    return status;
  }

  for (const ddk::GpioProtocolClient& gpio : gpios) {
    gpio.SetAltFunction(kAltFunctionGpio);
  }

  // Do one dummy write on each bus. This works around an issue where the first transaction after
  // enabling the VGP1 regulator gets a NACK error.
  // TODO(ZX-3486): Figure out a fix for this instead of working around it.
  for (uint32_t id = 0; id < bus_count_; id++) {
    uint8_t byte = 0;
    i2c_impl_op_t ops = {.address = 0x00,
                         .data_buffer = &byte,
                         .data_size = sizeof(byte),
                         .is_read = false,
                         .stop = true};

    I2cImplTransact(id, &ops, 1);
    Reset(id);
  }

  for (const ddk::GpioProtocolClient& gpio : gpios) {
    gpio.SetAltFunction(kAltFunctionI2c);
  }

  return ZX_OK;
}

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;
  }

  ddk::CompositeProtocolClient composite(parent());
  if (!composite.is_valid()) {
    zxlogf(ERROR, "%s: Could not get composite protocol", __FILE__);
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto fragment_count = composite.GetFragmentCount();
  if (fragment_count != kMaxFragments) {
    zxlogf(ERROR, "%s Wrong number of fragments %u", __func__, fragment_count);
    return ZX_ERR_INTERNAL;
  }
  size_t actual = 0;
  zx_device_t* fragments[kMaxFragments];
  composite.GetFragments(fragments, fragment_count, &actual);
  if (actual != fragment_count) {
    return ZX_ERR_INTERNAL;
  }

  ddk::PDev pdev = fragments[0];
  pdev_device_info_t info;
  status = pdev.GetDeviceInfo(&info);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s pdev_get_device_info failed %d", __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", __FUNCTION__, bus_count_);
    return ZX_ERR_INTERNAL;
  }

  std::optional<ddk::MmioBuffer> mmio;
  status = pdev.MapMmio(bus_count_, &mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s MapMmio %u failed %d", __FUNCTION__, bus_count_, status);
    return status;
  }
  xo_regs_ = XoRegs(std::move(*mmio));  // Last MMIO is for XO clock.

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

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

    status = pdev.GetInterrupt(id, &keys_[id].irq);
    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 = DoDummyTransactions();
  if (status != ZX_OK) {
    return status;
  }

  bind_finished_ = true;

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

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

#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(void* ctx, 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", __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();
}

static constexpr zx_driver_ops_t driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = Mt8167I2c::Create;
  return ops;
}();

}  // namespace mt8167_i2c

// clang-format off
ZIRCON_DRIVER_BEGIN(mt8167_i2c, mt8167_i2c::driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_COMPOSITE),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_MEDIATEK),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_MEDIATEK_I2C),
ZIRCON_DRIVER_END(mt8167_i2c)
    // clang-format on
