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

#include <lib/device-protocol/platform-device.h>
#include <lib/sync/completion.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/process.h>

#include <memory>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/mmio-buffer.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/i2cimpl.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/platform/device.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <hw/reg.h>

namespace dw_i2c {

zx_status_t DwI2cBus::Dumpstate() {
  zxlogf(INFO, "DW_kI2cEnable_STATUS = \t0x%x",
         EnableStatusReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_kI2cEnable = \t0x%x", EnableReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_CON = \t0x%x", ControlReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_TAR = \t0x%x", TargetAddressReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_HS_MADDR = \t0x%x", HSMasterAddrReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_SS_SCL_HCNT = \t0x%x",
         StandardSpeedSclHighCountReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_SS_SCL_LCNT = \t0x%x",
         StandardSpeedSclLowCountReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_FS_SCL_HCNT = \t0x%x",
         FastSpeedSclHighCountReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_FS_SCL_LCNT = \t0x%x",
         FastSpeedSclLowCountReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_INTR_MASK = \t0x%x", InterruptMaskReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_RAW_INTR_STAT = \t0x%x",
         RawInterruptStatusReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_RX_TL = \t0x%x", RxFifoThresholdReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_TX_TL = \t0x%x", TxFifoThresholdReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_STATUS = \t0x%x", StatusReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_TXFLR = \t0x%x", TxFifoLevelReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_RXFLR = \t0x%x", RxFifoLevelReg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_COMP_PARAM_1 = \t0x%x", CompParam1Reg::Get().ReadFrom(&mmio_).reg_value());
  zxlogf(INFO, "DW_I2C_TX_ABRT_SOURCE = \t0x%x",
         TxAbrtSourceReg::Get().ReadFrom(&mmio_).reg_value());
  return ZX_OK;
}

zx_status_t DwI2cBus::EnableAndWait(bool enable) {
  uint32_t poll = 0;

  // Set enable bit.
  auto enable_reg = EnableReg::Get().ReadFrom(&mmio_);
  enable_reg.set_enable(enable).WriteTo(&mmio_);

  do {
    if (EnableStatusReg::Get().ReadFrom(&mmio_).enable() == enable) {
      // We are done. Exit.
      return ZX_OK;
    }
    // Sleep 10 times the signaling period for the highest i2c transfer speed (400K) ~25uS.
    zx_nanosleep(zx_deadline_after(kPollSleep));
  } while (poll++ < kMaxPoll);

  zxlogf(ERROR, "%s: Could not %s I2C contoller! DW_kI2cEnable_STATUS = 0x%x", __FUNCTION__,
         enable ? "enable" : "disable", EnableStatusReg::Get().ReadFrom(&mmio_).enable());
  Dumpstate();

  return ZX_ERR_TIMED_OUT;
}

zx_status_t DwI2cBus::Enable() { return EnableAndWait(kI2cEnable); }

void DwI2cBus::ClearInterrupts() {
  // Reading this register will clear all the interrupts.
  ClearInterruptReg::Get().ReadFrom(&mmio_);
}

void DwI2cBus::DisableInterrupts() { InterruptMaskReg::Get().FromValue(0).WriteTo(&mmio_); }

void DwI2cBus::EnableInterrupts(uint32_t flag) {
  InterruptMaskReg::Get().FromValue(flag).WriteTo(&mmio_);
}

zx_status_t DwI2cBus::Disable() { return EnableAndWait(kI2cDisable); }

zx_status_t DwI2cBus::WaitEvent(uint32_t sig_mask) {
  uint32_t observed = 0;
  auto deadline = zx::deadline_after(timeout_);
  sig_mask |= kErrorSignal;

  zx_status_t status = event_.wait_one(sig_mask, deadline, &observed);
  if (status != ZX_OK) {
    return status;
  }

  event_.signal(observed, 0);
  if (observed & kErrorSignal) {
    return ZX_ERR_TIMED_OUT;
  }

  return ZX_OK;
}

InterruptStatusReg DwI2cBus::ReadAndClearIrq() {
  auto irq = InterruptStatusReg::Get().ReadFrom(&mmio_);

  if (irq.tx_abrt()) {
    // ABRT_SOURCE should be read before clearing TX_ABRT.
    zxlogf(ERROR, "dw-i2c: error on bus - Abort source 0x%x",
           TxAbrtSourceReg::Get().ReadFrom(&mmio_).reg_value());
    ClearTxAbrtReg::Get().ReadFrom(&mmio_);
  }
  if (irq.start_det()) {
    ClearStartDetReg::Get().ReadFrom(&mmio_);
  }
  if (irq.activity()) {
    ClearActivityReg::Get().ReadFrom(&mmio_);
  }
  if (irq.stop_det()) {
    ClearStopDetReg::Get().ReadFrom(&mmio_);
  }
  return irq;
}

// Thread to handle interrupts.
int DwI2cBus::IrqThread() {
  zx_status_t status;

  while (1) {
    status = irq_.wait(nullptr);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: irq wait failed, retcode = %d", __FUNCTION__, status);
      return status;
    }

    fbl::AutoLock lock(&ops_lock_);
    if (ops_ == nullptr) {
      continue;
    }

    auto reg = ReadAndClearIrq();

    if (reg.tx_abrt()) {
      if (event_.signal(0, kErrorSignal) != ZX_OK) {
        zxlogf(ERROR, "Failure signaling I2C error - %d", status);
      }
      ops_ = nullptr;
    }

    if (reg.rx_full()) {
      if (Receive() != ZX_OK) {
        if (event_.signal(0, kErrorSignal) != ZX_OK) {
          zxlogf(ERROR, "Failure signaling I2C error - %d", status);
        }
        ops_ = nullptr;
      }
    }

    if (reg.tx_empty()) {
      if (Transmit() != ZX_OK) {
        if (event_.signal(0, kErrorSignal) != ZX_OK) {
          zxlogf(ERROR, "Failure signaling I2C error - %d", status);
        }
        ops_ = nullptr;
      }
    }

    if (reg.stop_det()) {
      // Signal complete when all tx/rx are complete.
      if (tx_op_idx_ == ops_count_ && rx_pending_ == 0) {
        if (event_.signal(0, kTransactionCompleteSignal) != ZX_OK) {
          zxlogf(ERROR, "Failure signaling I2C error - %d", status);
        }
        ops_ = nullptr;
      }
    }

  }  // while (1)

  return ZX_OK;
}

zx_status_t DwI2cBus::WaitBusBusy() {
  uint32_t timeout = 0;
  auto status = StatusReg::Get();
  while (status.ReadFrom(&mmio_).activity()) {
    if (timeout > 100) {
      return ZX_ERR_TIMED_OUT;
    }
    zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    timeout++;
  }
  return ZX_OK;
}

void DwI2cBus::SetOpsHelper(const i2c_impl_op_t* ops, size_t count) {
  fbl::AutoLock lock(&ops_lock_);
  ops_ = ops;
  ops_count_ = count;
  rx_op_idx_ = 0;
  tx_op_idx_ = 0;
  rx_done_len_ = 0;
  tx_done_len_ = 0;
  send_restart_ = false;
  rx_pending_ = 0;
}

zx_status_t DwI2cBus::Transact(const i2c_impl_op_t* rws, size_t count) {
  fbl::AutoLock lock(&transact_lock_);

  auto status = WaitBusBusy();
  if (status != ZX_OK) {
    zxlogf(ERROR, "I2C bus wait failed %d", status);
    return status;
  }
  status = SetSlaveAddress(rws[0].address);
  if (status != ZX_OK) {
    zxlogf(ERROR, "I2C set address failed %d", status);
    return status;
  }

  DisableInterrupts();
  SetOpsHelper(rws, count);
  status = Enable();
  if (status != ZX_OK) {
    zxlogf(ERROR, "I2C device enable failed %d", status);
    return status;
  }
  event_.signal(kTransactionCompleteSignal | kErrorSignal, 0);
  ClearInterrupts();
  EnableInterrupts(kI2cInterruptDefaultMask);

  status = WaitEvent(kTransactionCompleteSignal);

  auto disable_ret = Disable();
  if (disable_ret != ZX_OK) {
    zxlogf(ERROR, "I2C device disable failed %d", disable_ret);
  }
  return status;
}

zx_status_t DwI2cBus::SetSlaveAddress(uint16_t addr) {
  if (addr & (~k7BitAddrMask)) {
    // support 7bit for now
    return ZX_ERR_NOT_SUPPORTED;
  }
  addr &= k7BitAddrMask;
  auto reg = TargetAddressReg::Get().ReadFrom(&mmio_);
  reg.set_target_address(addr).set_master_10bitaddr(0);
  reg.WriteTo(&mmio_);
  return ZX_OK;
}

zx_status_t DwI2cBus::Receive() {
  if (rx_pending_ == 0) {
    zxlogf(ERROR, "dw-i2c: Bytes received without being requested");
    return ZX_ERR_IO_OVERRUN;
  }

  uint32_t avail_read = RxFifoLevelReg::Get().ReadFrom(&mmio_).rx_fifo_level();

  while ((avail_read != 0) && (rx_op_idx_ < ops_count_)) {
    const i2c_impl_op_t* op = &ops_[rx_op_idx_];
    if (!op->is_read) {
      rx_op_idx_++;
      continue;
    }
    uint8_t* buff = static_cast<uint8_t*>(op->data_buffer) + rx_done_len_;
    *buff = static_cast<uint8_t>(DataCommandReg::Get().ReadFrom(&mmio_).data());
    rx_done_len_++;
    rx_pending_--;
    if (rx_done_len_ == op->data_size) {
      rx_op_idx_++;
      rx_done_len_ = 0;
    }
    avail_read--;
  }

  if (avail_read != 0) {
    zxlogf(ERROR, "dw-i2c: %d more bytes received than requested", avail_read);
    return ZX_ERR_IO_OVERRUN;
  }

  return ZX_OK;
}

zx_status_t DwI2cBus::Transmit() {
  uint32_t tx_limit;

  tx_limit = tx_fifo_depth_ - TxFifoLevelReg::Get().ReadFrom(&mmio_).tx_fifo_level();

  // TODO(ZX-4628)
  // If IC_EMPTYFIFO_HOLD_MASTER_EN = 0, then STOP is sent on TX_EMPTY. All commands should be
  // queued up as soon as possible to avoid this. Possible race leading to failed
  // transaction, if the irq thread is deschedule in the midst for tx command queuing.
  // This is the mode used in as370 and currently this issue is not addressed.
  // See bug ZX-4628 for details.
  // If IC_EMPTYFIFO_HOLD_MASTER_EN = 1, then STOP and RESTART must be sent explicitly, which is
  // handled by this code.
  while ((tx_limit != 0) && (tx_op_idx_ < ops_count_)) {
    const i2c_impl_op_t* op = &ops_[tx_op_idx_];
    uint8_t* buff = static_cast<uint8_t*>(op->data_buffer) + tx_done_len_;
    size_t len = op->data_size - tx_done_len_;
    ZX_DEBUG_ASSERT(len <= kMaxTransfer);

    auto cmd = DataCommandReg::Get().FromValue(0);
    // Send STOP cmd if last byte and stop set.
    if (len == 1 && op->stop) {
      cmd.set_stop(1);
    }
    // Send restart.
    if (send_restart_) {
      cmd.set_start(1);
      send_restart_ = false;
    }

    if (op->is_read) {
      // Read command should be queued for each byte.
      cmd.set_command(1);
      rx_pending_++;
      // Set receive threshold to 1 less than the expected size.
      // Do this only once.
      if (tx_done_len_ == 0) {
        RxFifoThresholdReg::Get()
            .FromValue(0)
            .set_rx_threshold_level(static_cast<uint32_t>(op->data_size - 1))
            .WriteTo(&mmio_);
      }
    } else {
      cmd.set_data(*buff++);
    }
    cmd.WriteTo(&mmio_);
    tx_done_len_++;

    if (tx_done_len_ == op->data_size) {
      tx_op_idx_++;
      tx_done_len_ = 0;
      send_restart_ = true;
    }
    tx_limit--;
  }

  if (tx_op_idx_ == ops_count_) {
    // All tx are complete. Remove TX_EMPTY from interrupt mask.
    EnableInterrupts(kI2cInterruptReadMask);
  }

  return ZX_OK;
}

void DwI2cBus::ShutDown() {
  irq_.destroy();
  if (irq_thread_.joinable()) {
    irq_thread_.join();
  }
}

zx_status_t DwI2cBus::HostInit() {
  // Make sure we are truly running on a DesignWire IP.
  auto dw_comp_type = CompTypeReg::Get().ReadFrom(&mmio_).reg_value();

  if (dw_comp_type != kDwCompTypeNum) {
    zxlogf(ERROR, "%s: Incompatible IP Block detected. Expected = 0x%x, Actual = 0x%x",
           __FUNCTION__, kDwCompTypeNum, dw_comp_type);

    return ZX_ERR_NOT_SUPPORTED;
  }

  // Read the various capabilities of the fragment.
  auto comp_reg = CompParam1Reg::Get().ReadFrom(&mmio_);
  tx_fifo_depth_ = comp_reg.tx_buffer_depth();
  rx_fifo_depth_ = comp_reg.rx_buffer_depth();

  // Minimum fifo depth would be max transfer limit.
  kMaxTransfer = tx_fifo_depth_ > rx_fifo_depth_ ? rx_fifo_depth_ : tx_fifo_depth_;

  /* I2C Block Initialization based on DW_apb_i2c_databook Section 7.3 */

  // Disable I2C Block.
  Disable();

  // Configure the controller:
  auto ctrl_reg = ControlReg::Get().FromValue(0);

  // - slave disable
  ctrl_reg.set_slave_disable(1);

  // - enable restart mode
  ctrl_reg.set_restart_en(1);

  // - set 7-bit address modeset
  ctrl_reg.set_master_10bitaddr(k7BitAddr);
  ctrl_reg.set_slave_10bitaddr(k7BitAddr);

  // - set speed to fast, master enable
  ctrl_reg.set_max_speed_mode(kFastMode);

  // - set master enable
  ctrl_reg.set_master_mode(1);

  // Write final mask.
  ctrl_reg.WriteTo(&mmio_);

  // Write SS/FS LCNT and HCNT.
  StandardSpeedSclHighCountReg::Get()
      .ReadFrom(&mmio_)
      .set_ss_scl_hcnt(kSclStandardSpeedHcnt)
      .WriteTo(&mmio_);
  StandardSpeedSclLowCountReg::Get()
      .ReadFrom(&mmio_)
      .set_ss_scl_lcnt(kSclStandardSpeedLcnt)
      .WriteTo(&mmio_);
  FastSpeedSclHighCountReg::Get()
      .ReadFrom(&mmio_)
      .set_fs_scl_hcnt(kSclFastSpeedHcnt)
      .WriteTo(&mmio_);
  FastSpeedSclLowCountReg::Get()
      .ReadFrom(&mmio_)
      .set_fs_scl_lcnt(kSclFastSpeedLcnt)
      .WriteTo(&mmio_);

  // Set SDA Hold time.
  // Enable SDA hold for RX as well.
  SdaHoldReg::Get()
      .FromValue(0)
      .set_sda_hold_time_tx(kSdaHoldValue)
      .set_sda_hold_time_rx(kSdaHoldValue)
      .WriteTo(&mmio_);

  // Setup TX and RX FIFO Thresholds.
  TxFifoThresholdReg::Get()
      .ReadFrom(&mmio_)
      .set_tx_threshold_level(tx_fifo_depth_ / 2)
      .WriteTo(&mmio_);
  RxFifoThresholdReg::Get().ReadFrom(&mmio_).set_rx_threshold_level(0).WriteTo(&mmio_);

  // Disable interrupts.
  DisableInterrupts();

  return ZX_OK;
}

zx_status_t DwI2cBus::Init() {
  zx_status_t status;

  timeout_ = zx::duration(kDefaultTimeout);

  status = zx::event::create(0, &event_);
  if (status != ZX_OK) {
    return status;
  }

  // Initialize i2c host controller.
  status = HostInit();
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: failed to initialize i2c host controller %d", __FUNCTION__, status);
    return status;
  }

  irq_thread_ = std::thread(&DwI2cBus::IrqThread, this);

  return ZX_OK;
}

#define I2C_AS370_DW_TEST 0

#if I2C_AS370_DW_TEST
int DwI2c::TestThread() {
  zx_status_t status;
  bool pass = true;
  uint8_t addr = 0;            // PMIC device
  uint8_t valid_addr = 0x66;   // SY20212DAIC PMIC device
  uint8_t valid_value = 0x8B;  // Register 0x0 default value for PMIC
  uint8_t data_write = 0;
  uint8_t data_read;
#if 0
  zxlogf(INFO, "Finding I2c devices");
  // Find all available devices.
  for (uint32_t i = 0x0; i <= 0x7f; i++) {
    addr = static_cast<uint8_t>(i);
    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},
    };

    status = I2cImplTransact(0, ops, countof(ops));
    if (status == ZX_OK) {
      zxlogf(INFO, "I2C device found at address: 0x%02X", addr);
    }
  }
#endif
  zxlogf(INFO, "I2C: Testing PMIC ping");

  // Test multiple reads from a known device.
  for (uint32_t i = 0; i < 10; i++) {
    addr = valid_addr;
    data_read = 0;
    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},
    };

    status = I2cImplTransact(0, ops, countof(ops));
    if (status == ZX_OK) {
      // Check with reset value of PMIC registers.
      if (data_read != valid_value) {
        zxlogf(INFO, "I2C test: PMIC register value does not matched - %x", data_read);
        pass = false;
      }
    } else {
      zxlogf(INFO, "I2C test: PMIC ping failed : %d", status);
      pass = false;
    }
  }

  if (pass) {
    zxlogf(INFO, "DW I2C test for AS370 passed");
  } else {
    zxlogf(ERROR, "DW I2C test for AS370 failed");
  }
  return 0;
}
#endif

zx_status_t DwI2c::I2cImplTransact(uint32_t bus_id, const i2c_impl_op_t* rws, size_t count) {
  if (bus_id >= bus_count_) {
    return ZX_ERR_INVALID_ARGS;
  }

  for (uint32_t i = 0; i < count; ++i) {
    if (rws[i].data_size > buses_[bus_id]->kMaxTransfer) {
      return ZX_ERR_OUT_OF_RANGE;
    }
  }

  if (count == 0) {
    return ZX_OK;
  }

  for (uint32_t i = 1; i < count; ++i) {
    if (rws[i].address != rws[0].address) {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }

  return buses_[bus_id]->Transact(rws, count);
}

zx_status_t DwI2c::I2cImplSetBitrate(uint32_t bus_id, uint32_t bitrate) {
  // TODO: currently supports FAST_MODE - 400kHz
  return ZX_ERR_NOT_SUPPORTED;
}

uint32_t DwI2c::I2cImplGetBusCount() { return static_cast<uint32_t>(bus_count_); }

zx_status_t DwI2c::I2cImplGetMaxTransferSize(uint32_t bus_id, size_t* out_size) {
  if (bus_id >= bus_count_) {
    return ZX_ERR_INVALID_ARGS;
  }
  *out_size = buses_[bus_id]->kMaxTransfer;
  return ZX_OK;
}

void DwI2c::ShutDown() {
  for (uint32_t id = 0; id < bus_count_; id++) {
    buses_[id]->ShutDown();
  }
}

void DwI2c::DdkUnbindNew(ddk::UnbindTxn txn) {
  ShutDown();
  txn.Reply();
}

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

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

#if I2C_AS370_DW_TEST
  thrd_t test_thread;
  auto thunk = [](void* arg) -> int { return reinterpret_cast<DwI2c*>(arg)->TestThread(); };
  int rc = thrd_create_with_name(&test_thread, thunk, this, "dw-i2c-test");
  if (rc != thrd_success) {
    return ZX_ERR_INTERNAL;
  }
#endif

  cleanup.cancel();
  return ZX_OK;
}

zx_status_t DwI2c::Create(void* ctx, zx_device_t* parent) {
  zx_status_t status;
  fbl::AllocChecker ac;

  ddk::PDev pdev(parent);
  if (!pdev.is_valid()) {
    zxlogf(ERROR, "%s: Failed to get ZX_PROTOCOL_PDEV", __FILE__);
    return ZX_ERR_NO_RESOURCES;
  }

  pdev_device_info_t info;
  if ((status = pdev.GetDeviceInfo(&info)) != ZX_OK) {
    zxlogf(ERROR, "dw_i2c: pdev_get_device_info failed");
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (info.mmio_count != info.irq_count) {
    zxlogf(ERROR, "dw_i2c: mmio_count %u does not matchirq_count %u", info.mmio_count,
           info.irq_count);
    return ZX_ERR_INVALID_ARGS;
  }

  fbl::Vector<std::unique_ptr<DwI2cBus>> bus_list;

  for (uint32_t i = 0; i < info.mmio_count; i++) {
    std::optional<ddk::MmioBuffer> mmio;
    if ((status = pdev.MapMmio(i, &mmio)) != ZX_OK) {
      zxlogf(ERROR, "%s: pdev_map_mmio_buffer failed %d", __FUNCTION__, status);
      return status;
    }

    zx::interrupt irq;
    if ((status = pdev.GetInterrupt(i, &irq)) != ZX_OK) {
      return status;
    }

    auto i2c_bus = fbl::make_unique_checked<DwI2cBus>(&ac, *std::move(mmio), irq);
    if (!ac.check()) {
      return ZX_ERR_NO_MEMORY;
    }

    if ((status = i2c_bus->Init()) != ZX_OK) {
      zxlogf(ERROR, "dw_i2c: dw_i2c bus init failed: %d", status);
      return ZX_ERR_INTERNAL;
    }

    bus_list.push_back(std::move(i2c_bus), &ac);
    if (!ac.check()) {
      return ZX_ERR_NO_MEMORY;
    }
  }

  auto dev = fbl::make_unique_checked<DwI2c>(&ac, parent, std::move(bus_list));
  if (!ac.check()) {
    zxlogf(ERROR, "%s ZX_ERR_NO_MEMORY", __FUNCTION__);
    return ZX_ERR_NO_MEMORY;
  }

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

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

static zx_driver_ops_t dw_i2c_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .init = nullptr,
    .bind = DwI2c::Create,
    .create = nullptr,
    .release = nullptr,
    .run_unit_tests = nullptr,
};

}  // namespace dw_i2c

// clang-format off
ZIRCON_DRIVER_BEGIN(dw_i2c, dw_i2c::dw_i2c_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PDEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_GENERIC),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_GENERIC),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_DW_I2C)
ZIRCON_DRIVER_END(dw_i2c)
//clang-format on
