// 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 "sdio-controller-device.h"

#include <fidl/fuchsia.hardware.sdio/cpp/wire.h>
#include <fuchsia/hardware/sdio/c/banjo.h>
#include <fuchsia/hardware/sdmmc/c/banjo.h>
#include <inttypes.h>
#include <lib/async/cpp/task.h>
#include <lib/fdf/dispatcher.h>
#include <lib/fit/defer.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/sdio/hw.h>
#include <lib/zx/clock.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/process.h>
#include <zircon/threads.h>

#include <algorithm>

#include <fbl/algorithm.h>

#include "sdmmc-root-device.h"

namespace {

constexpr uint8_t kCccrVendorAddressMin = 0xf0;

constexpr uint32_t kBcmManufacturerId = 0x02d0;

uint32_t SdioReadTupleBody(const uint8_t* tuple_body, size_t start, size_t numbytes) {
  uint32_t res = 0;

  for (size_t i = start; i < (start + numbytes); i++) {
    res |= tuple_body[i] << ((i - start) * 8);
  }
  return res;
}

inline bool SdioFnIdxValid(uint8_t fn_idx) { return (fn_idx < SDIO_MAX_FUNCS); }

inline uint8_t GetBits(uint32_t x, uint32_t mask, uint32_t loc) {
  return static_cast<uint8_t>((x & mask) >> loc);
}

inline void UpdateBitsU8(uint8_t* x, uint8_t mask, uint8_t loc, uint8_t val) {
  *x = static_cast<uint8_t>(*x & ~mask);
  *x = static_cast<uint8_t>(*x | ((val << loc) & mask));
}

inline uint8_t GetBitsU8(uint8_t x, uint8_t mask, uint8_t loc) {
  return static_cast<uint8_t>((x & mask) >> loc);
}

}  // namespace

namespace sdmmc {

zx_status_t SdioControllerDevice::Create(SdmmcRootDevice* parent,
                                         std::unique_ptr<SdmmcDevice> sdmmc,
                                         std::unique_ptr<SdioControllerDevice>* out_dev) {
  fbl::AllocChecker ac;
  out_dev->reset(new (&ac) SdioControllerDevice(parent, std::move(sdmmc)));
  if (!ac.check()) {
    FDF_LOGL(ERROR, parent->logger(), "failed to allocate device memory");
    return ZX_ERR_NO_MEMORY;
  }

  return ZX_OK;
}

zx_status_t SdioControllerDevice::Probe(
    const fuchsia_hardware_sdmmc::wire::SdmmcMetadata& metadata) {
  std::lock_guard<std::mutex> lock(lock_);
  return ProbeLocked();
}

zx_status_t SdioControllerDevice::ProbeLocked() {
  zx_status_t st = SdioReset();

  if ((st = sdmmc_->SdmmcGoIdle()) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "SDMMC_GO_IDLE_STATE failed, retcode = %d", st);
    return st;
  }

  sdmmc_->SdSendIfCond();

  uint32_t ocr;
  if ((st = sdmmc_->SdioSendOpCond(0, &ocr)) != ZX_OK) {
    FDF_LOGL(DEBUG, logger(), "SDIO_SEND_OP_COND failed, retcode = %d", st);
    return st;
  }
  // Select voltage 3.3 V. Also request for 1.8V. Section 3.2 SDIO spec
  if (ocr & SDIO_SEND_OP_COND_IO_OCR_33V) {
    uint32_t new_ocr = SDIO_SEND_OP_COND_IO_OCR_33V | SDIO_SEND_OP_COND_CMD_S18R;
    if ((st = sdmmc_->SdioSendOpCond(new_ocr, &ocr)) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "SDIO_SEND_OP_COND failed, retcode = %d", st);
      return st;
    }
  }
  if (ocr & SDIO_SEND_OP_COND_RESP_MEM_PRESENT) {
    // Combo cards not supported
    FDF_LOGL(ERROR, logger(), "Combo card not supported");
    return ZX_ERR_NOT_SUPPORTED;
  }
  if (!(ocr & SDIO_SEND_OP_COND_RESP_IORDY)) {
    FDF_LOGL(WARNING, logger(), "IO not ready after SDIO_SEND_OP_COND");
    return ZX_ERR_IO;
  }
  if (ocr & SDIO_SEND_OP_COND_RESP_S18A) {
    if ((st = sdmmc_->SdSwitchUhsVoltage(ocr)) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Failed to switch voltage to 1.8V");
      return st;
    }
  }
  hw_info_.num_funcs =
      GetBits(ocr, SDIO_SEND_OP_COND_RESP_NUM_FUNC_MASK, SDIO_SEND_OP_COND_RESP_NUM_FUNC_LOC);
  if ((st = sdmmc_->SdSendRelativeAddr(nullptr)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "SD_SEND_RELATIVE_ADDR failed, retcode = %d", st);
    return st;
  }

  if ((st = sdmmc_->MmcSelectCard()) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "MMC_SELECT_CARD failed, retcode = %d", st);
    return st;
  }

  sdmmc_->SetRequestRetries(10);

  if ((st = ProcessCccr()) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Read CCCR failed, retcode = %d", st);
    return st;
  }

  // Read CIS to get max block size
  if ((st = ProcessCis(0)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Read CIS failed, retcode = %d", st);
    return st;
  }

  // BCM43458 includes function 0 in its OCR register. This violates the SDIO specification and
  // the assumptions made here. Check the manufacturer ID to account for this quirk.
  if (funcs_[0].hw_info.manufacturer_id != kBcmManufacturerId) {
    hw_info_.num_funcs++;
  }

  if ((st = TrySwitchUhs()) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Switching to ultra high speed failed, retcode = %d", st);
    if ((st = TrySwitchHs()) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Switching to high speed failed, retcode = %d", st);
      if ((st = SwitchFreq(SDIO_DEFAULT_FREQ)) != ZX_OK) {
        FDF_LOGL(ERROR, logger(), "Switch freq retcode = %d", st);
        return st;
      }
    }
  }

  // This effectively excludes cards that don't report the mandatory FUNCE tuple, as the max block
  // size would still be set to zero.
  if ((st = SdioUpdateBlockSizeLocked(0, 0, true)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Failed to update function 0 block size, retcode = %d", st);
    return st;
  }

  const bool sdio_irq_supported =
      sdmmc_->RegisterInBandInterrupt(this, &in_band_interrupt_protocol_ops_) == ZX_OK;

  // 0 is the common function. Already initialized
  for (size_t i = 1; i < hw_info_.num_funcs; i++) {
    if ((st = InitFunc(static_cast<uint8_t>(i))) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Failed to initialize function %zu, retcode = %d", i, st);
      return st;
    }

    if (sdio_irq_supported &&
        (st = zx::interrupt::create({}, 0, ZX_INTERRUPT_VIRTUAL, &sdio_irqs_[i])) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Failed to create virtual interrupt for function %zu: %d", i, st);
      return st;
    }
  }

  sdmmc_->SetRequestRetries(0);

  FDF_LOGL(INFO, logger(), "sdio device initialized successfully");
  FDF_LOGL(INFO, logger(), "          Manufacturer: 0x%x", funcs_[0].hw_info.manufacturer_id);
  FDF_LOGL(INFO, logger(), "          Product: 0x%x", funcs_[0].hw_info.product_id);
  FDF_LOGL(INFO, logger(), "          cccr vsn: 0x%x", hw_info_.cccr_vsn);
  FDF_LOGL(INFO, logger(), "          SDIO vsn: 0x%x", hw_info_.sdio_vsn);
  FDF_LOGL(INFO, logger(), "          num funcs: %d", hw_info_.num_funcs);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::StartSdioIrqDispatcherIfNeeded() {
  std::lock_guard<std::mutex> lock(irq_dispatcher_lock_);

  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }
  if (irq_dispatcher_.get()) {
    return ZX_OK;
  }

  auto dispatcher = fdf::SynchronizedDispatcher::Create(
      fdf::SynchronizedDispatcher::Options::kAllowSyncCalls, "sdio-irq-thread",
      [&](fdf_dispatcher_t*) { irq_shutdown_completion_.Signal(); });
  if (dispatcher.is_error()) {
    FDF_LOGL(ERROR, logger(), "Failed to create dispatcher: %s",
             zx_status_get_string(dispatcher.status_value()));
    return dispatcher.status_value();
  }
  irq_dispatcher_ = *std::move(dispatcher);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::AddDevice() {
  std::lock_guard<std::mutex> lock(lock_);

  dispatcher_ = fdf_dispatcher_get_async_dispatcher(fdf_dispatcher_get_current_dispatcher());

  auto inspect_sink = parent_->driver_incoming()->Connect<fuchsia_inspect::InspectSink>();
  if (inspect_sink.is_error() || !inspect_sink->is_valid()) {
    FDF_LOGL(ERROR, logger(), "Failed to connect to inspect sink: %s",
             inspect_sink.status_string());
    return inspect_sink.status_value();
  }
  exposed_inspector_.emplace(inspect::ComponentInspector(
      dispatcher_, {.inspector = inspector_, .client_end = std::move(inspect_sink.value())}));

  auto [controller_client_end, controller_server_end] =
      fidl::Endpoints<fuchsia_driver_framework::NodeController>::Create();
  auto [node_client_end, node_server_end] =
      fidl::Endpoints<fuchsia_driver_framework::Node>::Create();

  controller_.Bind(std::move(controller_client_end));
  sdio_controller_node_.Bind(std::move(node_client_end));

  fidl::Arena arena;

  const auto args =
      fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena).name(arena, kDeviceName).Build();

  auto result = parent_->root_node()->AddChild(args, std::move(controller_server_end),
                                               std::move(node_server_end));
  if (!result.ok()) {
    FDF_LOGL(ERROR, logger(), "Failed to add child sdio controller device: %s",
             result.status_string());
    return result.status();
  }

  auto remove_device_on_error =
      fit::defer([&]() { [[maybe_unused]] auto result = controller_->Remove(); });

  zx_status_t st;
  for (uint32_t i = 0; i < hw_info_.num_funcs - 1; i++) {
    if ((st = SdioFunctionDevice::Create(this, i + 1, &child_sdio_function_devices_[i])) != ZX_OK) {
      return st;
    }
  }

  for (uint32_t i = 0; i < hw_info_.num_funcs - 1; i++) {
    if ((st = child_sdio_function_devices_[i]->AddDevice(funcs_[i + 1].hw_info)) != ZX_OK) {
      return st;
    }
  }

  root_ = inspector_.GetRoot().CreateChild("sdio_core");
  tx_errors_ = root_.CreateUint("tx_errors", 0);
  rx_errors_ = root_.CreateUint("rx_errors", 0);

  remove_device_on_error.cancel();
  return ZX_OK;
}

void SdioControllerDevice::StopSdioIrqDispatcher(
    std::optional<fdf::PrepareStopCompleter> completer) {
  shutdown_ = true;

  {
    std::lock_guard<std::mutex> lock(irq_dispatcher_lock_);
    if (irq_dispatcher_.get()) {
      irq_dispatcher_.ShutdownAsync();
      irq_shutdown_completion_.Wait();
    }
  }

  for (const zx::interrupt& irq : sdio_irqs_) {
    if (irq.is_valid()) {
      // Return an error to any waiters.
      irq.destroy();
    }
  }

  if (completer.has_value()) {
    completer.value()(zx::ok());
  }
}

zx_status_t SdioControllerDevice::SdioGetDevHwInfo(uint8_t fn_idx, sdio_hw_info_t* out_hw_info) {
  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }

  std::lock_guard<std::mutex> lock(lock_);

  memcpy(&out_hw_info->dev_hw_info, &hw_info_, sizeof(sdio_device_hw_info_t));
  memcpy(&out_hw_info->func_hw_info, &funcs_[fn_idx].hw_info, sizeof(sdio_func_hw_info_t));
  out_hw_info->host_max_transfer_size =
      static_cast<uint32_t>(sdmmc_->host_info().max_transfer_size);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioEnableFn(uint8_t fn_idx) {
  std::lock_guard<std::mutex> lock(lock_);
  return SdioEnableFnLocked(fn_idx);
}

zx_status_t SdioControllerDevice::SdioEnableFnLocked(uint8_t fn_idx) {
  uint8_t ioex_reg = 0;
  zx_status_t st = ZX_OK;

  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }

  SdioFunction& func = funcs_[fn_idx];
  if (func.enabled) {
    return ZX_OK;
  }
  if ((st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, &ioex_reg)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error enabling func:%d status:%d", fn_idx, st);
    return st;
  }

  ioex_reg = static_cast<uint8_t>(ioex_reg | (1 << fn_idx));
  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, ioex_reg, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error enabling func:%d status:%d", fn_idx, st);
    return st;
  }
  // wait for the device to enable the func.
  zx::nanosleep(zx::deadline_after(zx::msec(10)));
  if ((st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, &ioex_reg)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error enabling func:%d status:%d", fn_idx, st);
    return st;
  }

  if (!(ioex_reg & (1 << fn_idx))) {
    st = ZX_ERR_IO;
    FDF_LOGL(ERROR, logger(), "Failed to enable func %d", fn_idx);
    return st;
  }

  func.enabled = true;
  FDF_LOGL(DEBUG, logger(), "Func %d is enabled", fn_idx);
  return st;
}

zx_status_t SdioControllerDevice::SdioDisableFn(uint8_t fn_idx) {
  uint8_t ioex_reg = 0;
  zx_status_t st = ZX_OK;

  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }

  std::lock_guard<std::mutex> lock(lock_);

  SdioFunction* func = &funcs_[fn_idx];
  if (!func->enabled) {
    FDF_LOGL(ERROR, logger(), "Func %d is not enabled", fn_idx);
    return ZX_ERR_IO;
  }

  if ((st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, &ioex_reg)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading IOEx reg. func: %d status: %d", fn_idx, st);
    return st;
  }

  ioex_reg = static_cast<uint8_t>(ioex_reg & ~(1 << fn_idx));
  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, ioex_reg, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error writing IOEx reg. func: %d status:%d", fn_idx, st);
    return st;
  }

  func->enabled = false;
  FDF_LOGL(DEBUG, logger(), "Function %d is disabled", fn_idx);
  return st;
}

zx_status_t SdioControllerDevice::SdioEnableFnIntr(uint8_t fn_idx) {
  zx_status_t st = ZX_OK;

  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }

  std::lock_guard<std::mutex> lock(lock_);

  SdioFunction* func = &funcs_[fn_idx];
  if (func->intr_enabled) {
    return ZX_OK;
  }

  uint8_t intr_byte;
  st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, 0, &intr_byte);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Failed to enable interrupt for fn: %d status: %d", fn_idx, st);
    return st;
  }

  // Enable fn intr
  intr_byte = static_cast<uint8_t>(intr_byte | 1 << fn_idx);
  // Enable master intr
  intr_byte = static_cast<uint8_t>(intr_byte | 1);

  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, intr_byte, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Failed to enable interrupt for fn: %d status: %d", fn_idx, st);
    return st;
  }

  func->intr_enabled = true;
  FDF_LOGL(DEBUG, logger(), "Interrupt enabled for fn %d", fn_idx);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioDisableFnIntr(uint8_t fn_idx) {
  zx_status_t st = ZX_OK;

  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }

  std::lock_guard<std::mutex> lock(lock_);

  SdioFunction* func = &funcs_[fn_idx];
  if (!func->intr_enabled) {
    FDF_LOGL(ERROR, logger(), "Interrupt is not enabled for %d", fn_idx);
    return ZX_ERR_BAD_STATE;
  }

  uint8_t intr_byte;
  st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, 0, &intr_byte);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Failed reading intr enable reg. func: %d status: %d", fn_idx, st);
    return st;
  }

  intr_byte = static_cast<uint8_t>(intr_byte & ~(1 << fn_idx));
  if (!(intr_byte & SDIO_ALL_INTR_ENABLED_MASK)) {
    // disable master as well
    intr_byte = 0;
  }

  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_IEN_INTR_EN_ADDR, intr_byte, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error writing to intr enable reg. func: %d status: %d", fn_idx, st);
    return st;
  }

  func->intr_enabled = false;
  FDF_LOGL(DEBUG, logger(), "Interrupt disabled for fn %d", fn_idx);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioUpdateBlockSize(uint8_t fn_idx, uint16_t blk_sz, bool deflt) {
  std::lock_guard<std::mutex> lock(lock_);
  return SdioUpdateBlockSizeLocked(fn_idx, blk_sz, deflt);
}

zx_status_t SdioControllerDevice::SdioUpdateBlockSizeLocked(uint8_t fn_idx, uint16_t blk_sz,
                                                            bool deflt) {
  SdioFunction* func = &funcs_[fn_idx];
  if (deflt) {
    blk_sz = static_cast<uint16_t>(func->hw_info.max_blk_size);
  }

  // The minimum block size is 1 for all functions, as per the CCCR and FBR sections of the spec.
  if (blk_sz > func->hw_info.max_blk_size || blk_sz == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (func->cur_blk_size == blk_sz) {
    return ZX_OK;
  }

  // This register is read-only if SMB is not set. DoRwTxn will use byte mode instead of block mode
  // in that case, so the register write can be skipped.
  if (hw_info_.caps & SDIO_CARD_MULTI_BLOCK) {
    zx_status_t st =
        WriteData16(0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_BLK_SIZE_ADDR, blk_sz);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Error setting blk size.fn: %d blk_sz: %d ret: %d", fn_idx, blk_sz,
               st);
      return st;
    }
  }

  func->cur_blk_size = blk_sz;
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioGetBlockSize(uint8_t fn_idx, uint16_t* out_cur_blk_size) {
  std::lock_guard<std::mutex> lock(lock_);

  if (hw_info_.caps & SDIO_CARD_MULTI_BLOCK) {
    zx_status_t st = ReadData16(0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_BLK_SIZE_ADDR,
                                out_cur_blk_size);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Failed to get block size for fn: %d ret: %d", fn_idx, st);
    }
    return st;
  }

  *out_cur_blk_size = funcs_[fn_idx].cur_blk_size;
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioDoRwByte(bool write, uint8_t fn_idx, uint32_t addr,
                                               uint8_t write_byte, uint8_t* out_read_byte) {
  std::lock_guard<std::mutex> lock(lock_);
  return SdioDoRwByteLocked(write, fn_idx, addr, write_byte, out_read_byte);
}

zx_status_t SdioControllerDevice::SdioDoRwByteLocked(bool write, uint8_t fn_idx, uint32_t addr,
                                                     uint8_t write_byte, uint8_t* out_read_byte) {
  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  out_read_byte = write ? nullptr : out_read_byte;
  write_byte = write ? write_byte : 0;
  return sdmmc_->SdioIoRwDirect(write, fn_idx, addr, write_byte, out_read_byte);
}

zx_status_t SdioControllerDevice::SdioGetInBandIntr(uint8_t fn_idx, zx::interrupt* out_irq) {
  if (!SdioFnIdxValid(fn_idx) || fn_idx == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (!sdio_irqs_[fn_idx].is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (const zx_status_t st = StartSdioIrqDispatcherIfNeeded(); st != ZX_OK) {
    return st;
  }

  return sdio_irqs_[fn_idx].duplicate(ZX_RIGHT_SAME_RIGHTS, out_irq);
}

void SdioControllerDevice::SdioAckInBandIntr(uint8_t fn_idx) {
  // Don't ack for function 0 interrupts. This should not be possible given the child devices we've
  // added, but check for it just in case.
  if (SdioFnIdxValid(fn_idx) && fn_idx != 0) {
    std::lock_guard<std::mutex> lock(lock_);
    interrupt_enabled_mask_ |= 1 << fn_idx;
    sdmmc_->AckInBandInterrupt();
  }
}

void SdioControllerDevice::InBandInterruptCallback() {
  async::PostTask(irq_dispatcher_.async_dispatcher(), [this] { SdioIrqHandler(); });
}

void SdioControllerDevice::SdioIrqHandler() {
  const zx::time irq_time = zx::clock::get_monotonic();

  if (shutdown_) {
    return;
  }

  uint8_t intr_byte;
  {
    std::lock_guard<std::mutex> lock(lock_);

    zx_status_t st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_INTx_INTR_PEN_ADDR, 0, &intr_byte);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Failed reading intr pending reg. status: %d", st);
      return;
    }

    // Only trigger interrupts for functions that have ack'd the previous interrupt. Clear the
    // enabled bits for these functions.
    intr_byte &= interrupt_enabled_mask_;
    interrupt_enabled_mask_ &= ~intr_byte;
  }

  for (uint8_t i = 1; SdioFnIdxValid(i); i++) {
    if (intr_byte & (1 << i)) {
      sdio_irqs_[i].trigger(0, irq_time);
    }
  }
}

zx_status_t SdioControllerDevice::SdioIoAbort(uint8_t fn_idx) {
  if (!SdioFnIdxValid(fn_idx) || fn_idx == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  return SdioDoRwByte(true, 0, SDIO_CIA_CCCR_ASx_ABORT_SEL_CR_ADDR, fn_idx, nullptr);
}

zx_status_t SdioControllerDevice::SdioIntrPending(uint8_t fn_idx, bool* out_pending) {
  if (!SdioFnIdxValid(fn_idx) || fn_idx == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  uint8_t intr_byte;
  zx_status_t st = SdioDoRwByte(false, 0, SDIO_CIA_CCCR_INTx_INTR_PEN_ADDR, 0, &intr_byte);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Failed reading intr pending reg. status: %d", st);
    return st;
  }

  *out_pending = intr_byte & (1 << fn_idx);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioDoVendorControlRwByte(bool write, uint8_t addr,
                                                            uint8_t write_byte,
                                                            uint8_t* out_read_byte) {
  // The vendor area of the CCCR is 0xf0 - 0xff.
  if (addr < kCccrVendorAddressMin) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  return SdioDoRwByte(write, 0, addr, write_byte, out_read_byte);
}

zx_status_t SdioControllerDevice::SdioRegisterVmo(uint8_t fn_idx, uint32_t vmo_id, zx::vmo vmo,
                                                  uint64_t offset, uint64_t size,
                                                  uint32_t vmo_rights) {
  if (!SdioFnIdxValid(fn_idx) || fn_idx == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  std::lock_guard<std::mutex> lock(lock_);
  return sdmmc_->RegisterVmo(vmo_id, fn_idx, std::move(vmo), offset, size, vmo_rights);
}

zx_status_t SdioControllerDevice::SdioUnregisterVmo(uint8_t fn_idx, uint32_t vmo_id,
                                                    zx::vmo* out_vmo) {
  if (!SdioFnIdxValid(fn_idx) || fn_idx == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  std::lock_guard<std::mutex> lock(lock_);
  return sdmmc_->UnregisterVmo(vmo_id, fn_idx, out_vmo);
}

zx_status_t SdioControllerDevice::SdioRequestCardReset() {
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  std::lock_guard<std::mutex> lock(lock_);

  tuned_ = false;
  funcs_ = {};
  hw_info_ = {};

  sdmmc_->HwReset();

  zx_status_t status = ProbeLocked();
  if (status == ZX_OK) {
    FDF_LOGL(INFO, logger(), "Reset card successfully");
  } else {
    FDF_LOGL(ERROR, logger(), "Card reset failed: %s", zx_status_get_string(status));
  }

  return status;
}

zx_status_t SdioControllerDevice::SdioPerformTuning() {
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  if (!tuned_) {
    // Tuning was not performed during initialization, so there is no need to do it now.
    return ZX_OK;
  }

  if (tuning_in_progress_.exchange(true)) {
    return ZX_ERR_ALREADY_BOUND;
  }

  zx_status_t status = sdmmc_->PerformTuning(SD_SEND_TUNING_BLOCK);
  tuning_in_progress_.store(false);
  return status;
}

zx::result<uint8_t> SdioControllerDevice::ReadCccrByte(uint32_t addr) {
  uint8_t byte = 0;
  zx_status_t status = SdioDoRwByteLocked(false, 0, addr, 0, &byte);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  return zx::ok(byte);
}

// Use function overloads to convert the buffer depending on whether this is a Banjo or a FIDL call.
// We use Banjo for tracking buffer positions, so there is no conversion necessary in that case.

sdmmc_buffer_region_t GetBuffer(const fuchsia_hardware_sdmmc::wire::SdmmcBufferRegion& buffer) {
  sdmmc_buffer_region_t out{};
  if (buffer.buffer.is_vmo_id()) {
    out.type = SDMMC_BUFFER_TYPE_VMO_ID;
    out.buffer.vmo_id = buffer.buffer.vmo_id();
  } else if (buffer.buffer.is_vmo()) {
    out.type = SDMMC_BUFFER_TYPE_VMO_HANDLE;
    out.buffer.vmo = buffer.buffer.vmo().get();
  } else {
    out.type = 0;
  }

  out.offset = buffer.offset;
  out.size = buffer.size;
  return out;
}

sdmmc_buffer_region_t GetBuffer(const sdmmc_buffer_region_t& buffer) { return buffer; }

template <typename T>
zx::result<SdioControllerDevice::SdioTxnPosition<T>> SdioControllerDevice::DoOneRwTxnRequest(
    uint8_t fn_idx, const SdioRwTxn<T>& txn, SdioTxnPosition<T> current_position) {
  const uint32_t func_blk_size = funcs_[fn_idx].cur_blk_size;
  const bool mbs = hw_info_.caps & SDIO_CARD_MULTI_BLOCK;
  const size_t max_transfer_size = func_blk_size * (mbs ? SDIO_IO_RW_EXTD_MAX_BLKS_PER_CMD : 1);

  size_t block_count = 0;  // The number of full blocks that are in the buffers processed so far.
  size_t total_size = 0;   // The total number of bytes that are in the buffers processed so far.
  size_t last_block_buffer_index = 0;  // The index of the last buffer to cross a block boundary.
  size_t last_block_buffer_size = 0;   // The offset where the new block starts in this buffer.

  sdmmc_buffer_region_t buffers[SDIO_IO_RW_EXTD_MAX_BLKS_PER_CMD];
  for (size_t i = 0; i < std::size(buffers) && i < current_position.buffers.size(); i++) {
    buffers[i] = GetBuffer(current_position.buffers[i]);
    if (buffers[i].type == 0) {
      return zx::error(ZX_ERR_INVALID_ARGS);
    }

    if (i == 0) {
      ZX_ASSERT(current_position.first_buffer_offset < buffers[i].size);
      buffers[i].offset += current_position.first_buffer_offset;
      buffers[i].size -= current_position.first_buffer_offset;
    }

    // Trim the buffer to the max transfer size so that block boundaries can be checked.
    const size_t buffer_size = std::min(buffers[i].size, max_transfer_size - total_size);

    if ((total_size + buffer_size) / func_blk_size != block_count) {
      // This buffer crosses a block boundary, record the index and the offset at which the next
      // block begins.
      last_block_buffer_index = i;
      last_block_buffer_size = buffer_size - ((total_size + buffer_size) % func_blk_size);
      block_count = (total_size + buffer_size) / func_blk_size;
    }

    total_size += buffer_size;

    ZX_ASSERT(total_size <= max_transfer_size);
    if (total_size == max_transfer_size) {
      break;
    }
  }

  zx_status_t status;
  uint32_t txn_size = 0;
  if (block_count == 0) {
    // The collection of buffers didn't make up a full block.
    txn_size = static_cast<uint32_t>(total_size);

    // We know the entire buffers list is being used because the max transfer size is always at
    // least the block size. The first buffer may have had the size adjusted, so use the local
    // buffers array.
    cpp20::span txn_buffers(buffers, current_position.buffers.size());
    status = sdmmc_->SdioIoRwExtended(hw_info_.caps, txn.write, fn_idx, current_position.address,
                                      txn.incr, 1, static_cast<uint32_t>(total_size), txn_buffers);
    last_block_buffer_index = current_position.buffers.size();
  } else {
    txn_size = static_cast<uint32_t>(block_count * func_blk_size);

    cpp20::span txn_buffers(buffers, last_block_buffer_index + 1);
    txn_buffers[last_block_buffer_index].size = last_block_buffer_size;
    status = sdmmc_->SdioIoRwExtended(hw_info_.caps, txn.write, fn_idx, current_position.address,
                                      txn.incr, static_cast<uint32_t>(block_count), func_blk_size,
                                      txn_buffers);

    if (last_block_buffer_index == 0) {
      last_block_buffer_size += current_position.first_buffer_offset;
    }

    ZX_ASSERT(last_block_buffer_size <= current_position.buffers[last_block_buffer_index].size);

    if (current_position.buffers[last_block_buffer_index].size == last_block_buffer_size) {
      last_block_buffer_index++;
      last_block_buffer_size = 0;
    }
  }

  if (status != ZX_OK) {
    (txn.write ? tx_errors_ : rx_errors_).Add(1);
    return zx::error(status);
  }

  return zx::ok(SdioTxnPosition<T>{
      .buffers = current_position.buffers.subspan(last_block_buffer_index),
      .first_buffer_offset = last_block_buffer_size,
      .address = current_position.address + (txn.incr ? txn_size : 0),
  });
}

// Explicit instantiation to ensure both methods are available to SdioFunctionDevice.
template zx_status_t SdioControllerDevice::SdioDoRwTxn<>(uint8_t,
                                                         const SdioRwTxn<sdmmc_buffer_region_t>&);
template zx_status_t SdioControllerDevice::SdioDoRwTxn<>(
    uint8_t, const SdioRwTxn<fuchsia_hardware_sdmmc::wire::SdmmcBufferRegion>&);

template <typename T>
zx_status_t SdioControllerDevice::SdioDoRwTxn(uint8_t fn_idx, const SdioRwTxn<T>& txn) {
  if (!SdioFnIdxValid(fn_idx)) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (shutdown_) {
    return ZX_ERR_CANCELED;
  }

  std::lock_guard<std::mutex> lock(lock_);
  SdioTxnPosition<T> current_position = {
      .buffers = txn.buffers,
      .first_buffer_offset = 0,
      .address = txn.addr,
  };

  while (!current_position.buffers.empty()) {
    zx::result<SdioTxnPosition<T>> status = DoOneRwTxnRequest<T>(fn_idx, txn, current_position);
    if (status.is_error()) {
      return status.error_value();
    }
    current_position = status.value();
  }

  return ZX_OK;
}

zx_status_t SdioControllerDevice::SdioReset() {
  zx_status_t st = ZX_OK;
  uint8_t abort_byte;

  st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_ASx_ABORT_SEL_CR_ADDR, 0, &abort_byte);
  if (st != ZX_OK) {
    abort_byte = SDIO_CIA_CCCR_ASx_ABORT_SOFT_RESET;
  } else {
    abort_byte |= SDIO_CIA_CCCR_ASx_ABORT_SOFT_RESET;
  }
  return SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_ASx_ABORT_SEL_CR_ADDR, abort_byte, nullptr);
}

zx_status_t SdioControllerDevice::ProcessCccr() {
  uint8_t cccr_vsn, sdio_vsn, vsn_info, bus_speed, card_caps, uhs_caps, drv_strength;

  // version info
  zx_status_t status = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_CCCR_SDIO_VER_ADDR, 0, &vsn_info);
  if (status != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading CCCR reg: %d", status);
    return status;
  }
  cccr_vsn = GetBits(vsn_info, SDIO_CIA_CCCR_CCCR_VER_MASK, SDIO_CIA_CCCR_CCCR_VER_LOC);
  sdio_vsn = GetBits(vsn_info, SDIO_CIA_CCCR_SDIO_VER_MASK, SDIO_CIA_CCCR_SDIO_VER_LOC);
  if ((cccr_vsn < SDIO_CCCR_FORMAT_VER_3) || (sdio_vsn < SDIO_SDIO_VER_3)) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  hw_info_.cccr_vsn = cccr_vsn;
  hw_info_.sdio_vsn = sdio_vsn;

  // card capabilities
  status = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_CARD_CAPS_ADDR, 0, &card_caps);
  if (status != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading CAPS reg: %d", status);
    return status;
  }
  hw_info_.caps = 0;
  if (card_caps & SDIO_CIA_CCCR_CARD_CAP_SMB) {
    hw_info_.caps |= SDIO_CARD_MULTI_BLOCK;
  }
  if (card_caps & SDIO_CIA_CCCR_CARD_CAP_LSC) {
    hw_info_.caps |= SDIO_CARD_LOW_SPEED;
  }
  if (card_caps & SDIO_CIA_CCCR_CARD_CAP_4BLS) {
    hw_info_.caps |= SDIO_CARD_FOUR_BIT_BUS;
  }

  // speed
  status = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &bus_speed);
  if (status != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading SPEED reg: %d", status);
    return status;
  }
  if (bus_speed & SDIO_CIA_CCCR_BUS_SPEED_SEL_SHS) {
    hw_info_.caps |= SDIO_CARD_HIGH_SPEED;
  }

  // Is UHS supported?
  status = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_UHS_SUPPORT_ADDR, 0, &uhs_caps);
  if (status != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading SPEED reg: %d", status);
    return status;
  }
  if (uhs_caps & SDIO_CIA_CCCR_UHS_SDR50) {
    hw_info_.caps |= SDIO_CARD_UHS_SDR50;
  }
  if (uhs_caps & SDIO_CIA_CCCR_UHS_SDR104) {
    hw_info_.caps |= SDIO_CARD_UHS_SDR104;
  }
  if (uhs_caps & SDIO_CIA_CCCR_UHS_DDR50) {
    hw_info_.caps |= SDIO_CARD_UHS_DDR50;
  }

  // drv_strength
  status = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_DRV_STRENGTH_ADDR, 0, &drv_strength);
  if (status != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading SPEED reg: %d", status);
    return status;
  }
  if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTA) {
    hw_info_.caps |= SDIO_CARD_TYPE_A;
  }
  if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTB) {
    hw_info_.caps |= SDIO_CARD_TYPE_B;
  }
  if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTD) {
    hw_info_.caps |= SDIO_CARD_TYPE_D;
  }
  return status;
}

zx_status_t SdioControllerDevice::ProcessCis(uint8_t fn_idx) {
  zx_status_t st = ZX_OK;

  if (fn_idx >= SDIO_MAX_FUNCS) {
    return ZX_ERR_INVALID_ARGS;
  }
  uint32_t cis_ptr = 0;
  for (size_t i = 0; i < SDIO_CIS_ADDRESS_SIZE; i++) {
    uint8_t addr;
    st = SdioDoRwByteLocked(
        false, 0, static_cast<uint32_t>(SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_CIS_ADDR + i),
        0, &addr);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Error reading CIS of CCCR reg: %d", st);
      return st;
    }
    cis_ptr |= addr << (i * 8);
  }
  if (!cis_ptr) {
    FDF_LOGL(ERROR, logger(), "CIS address is invalid");
    return ZX_ERR_IO;
  }

  while (true) {
    uint8_t tuple_code, tuple_link;
    SdioFuncTuple cur_tup;
    st = SdioDoRwByteLocked(false, 0, cis_ptr + SDIO_CIS_TPL_FRMT_TCODE_OFF, 0, &tuple_code);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Error reading tuple code for fn %d", fn_idx);
      break;
    }
    // Ignore null tuples
    if (tuple_code == SDIO_CIS_TPL_CODE_NULL) {
      cis_ptr++;
      continue;
    }
    if (tuple_code == SDIO_CIS_TPL_CODE_END) {
      break;
    }
    st = SdioDoRwByteLocked(false, 0, cis_ptr + SDIO_CIS_TPL_FRMT_TLINK_OFF, 0, &tuple_link);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Error reading tuple size for fn %d", fn_idx);
      break;
    }
    if (tuple_link == SDIO_CIS_TPL_LINK_END) {
      break;
    }

    cur_tup.tuple_code = tuple_code;
    cur_tup.tuple_body_size = tuple_link;

    cis_ptr += SDIO_CIS_TPL_FRMT_TBODY_OFF;
    for (size_t i = 0; i < tuple_link; i++, cis_ptr++) {
      st = SdioDoRwByteLocked(false, 0, cis_ptr, 0, &cur_tup.tuple_body[i]);
      if (st != ZX_OK) {
        FDF_LOGL(ERROR, logger(), "Error reading tuple body for fn %d", fn_idx);
        return st;
      }
    }

    if ((st = ParseFnTuple(fn_idx, cur_tup)) != ZX_OK) {
      break;
    }
  }
  return st;
}

zx_status_t SdioControllerDevice::ParseFnTuple(uint8_t fn_idx, const SdioFuncTuple& tup) {
  zx_status_t st = ZX_OK;
  switch (tup.tuple_code) {
    case SDIO_CIS_TPL_CODE_MANFID:
      st = ParseMfidTuple(fn_idx, tup);
      break;
    case SDIO_CIS_TPL_CODE_FUNCE:
      st = ParseFuncExtTuple(fn_idx, tup);
      break;
    default:
      break;
  }
  return st;
}

zx_status_t SdioControllerDevice::ParseFuncExtTuple(uint8_t fn_idx, const SdioFuncTuple& tup) {
  SdioFunction* func = &funcs_[fn_idx];
  if (fn_idx == 0) {
    if (tup.tuple_body_size < SDIO_CIS_TPL_FUNC0_FUNCE_MIN_BDY_SZ) {
      return ZX_ERR_IO;
    }
    func->hw_info.max_blk_size =
        SdioReadTupleBody(tup.tuple_body, SDIO_CIS_TPL_FUNCE_FUNC0_MAX_BLK_SIZE_LOC, 2);
    func->hw_info.max_blk_size = static_cast<uint32_t>(
        std::min<uint64_t>(sdmmc_->host_info().max_transfer_size, func->hw_info.max_blk_size));

    if (func->hw_info.max_blk_size == 0) {
      FDF_LOGL(ERROR, logger(), "Invalid max block size for function 0");
      return ZX_ERR_IO_INVALID;
    }

    uint8_t speed_val = GetBitsU8(tup.tuple_body[3], SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_VAL_MASK,
                                  SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_VAL_LOC);
    uint8_t speed_unit = GetBitsU8(tup.tuple_body[3], SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_UNIT_MASK,
                                   SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_UNIT_LOC);
    // MAX_TRAN_SPEED is set in the function 0 CIS tuple but applies to all functions on the card.
    hw_info_.max_tran_speed = sdio_cis_tpl_funce_tran_speed_val[speed_val] *
                              sdio_cis_tpl_funce_tran_speed_unit[speed_unit];
    return ZX_OK;
  }

  if (tup.tuple_body_size < SDIO_CIS_TPL_FUNCx_FUNCE_MIN_BDY_SZ) {
    FDF_LOGL(ERROR, logger(), "Invalid body size: %d for func_ext tuple", tup.tuple_body_size);
    return ZX_ERR_IO;
  }

  func->hw_info.max_blk_size =
      SdioReadTupleBody(tup.tuple_body, SDIO_CIS_TPL_FUNCE_FUNCx_MAX_BLK_SIZE_LOC, 2);
  if (func->hw_info.max_blk_size == 0) {
    FDF_LOGL(ERROR, logger(), "Invalid max block size for function %u", fn_idx);
    return ZX_ERR_IO_INVALID;
  }

  return ZX_OK;
}

zx_status_t SdioControllerDevice::ParseMfidTuple(uint8_t fn_idx, const SdioFuncTuple& tup) {
  if (tup.tuple_body_size < SDIO_CIS_TPL_MANFID_MIN_BDY_SZ) {
    return ZX_ERR_IO;
  }
  SdioFunction* func = &funcs_[fn_idx];
  func->hw_info.manufacturer_id = SdioReadTupleBody(tup.tuple_body, 0, 2);
  func->hw_info.product_id = SdioReadTupleBody(tup.tuple_body, 2, 2);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::ProcessFbr(uint8_t fn_idx) {
  zx_status_t st = ZX_OK;
  uint8_t fbr, fn_intf_code;

  SdioFunction* func = &funcs_[fn_idx];
  if ((st = SdioDoRwByteLocked(
           false, 0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_STD_IF_CODE_ADDR, 0, &fbr)) !=
      ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading intf code: %d", st);
    return st;
  }
  fn_intf_code = GetBitsU8(fbr, SDIO_CIA_FBR_STD_IF_CODE_MASK, SDIO_CIA_FBR_STD_IF_CODE_LOC);
  if (fn_intf_code == SDIO_CIA_FBR_STD_IF_CODE_MASK) {
    // fn_code > 0Eh
    if ((st = SdioDoRwByteLocked(false, 0,
                                 SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_STD_IF_CODE_EXT_ADDR,
                                 0, &fn_intf_code)) != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "Error while reading the extended intf code %d", st);
      return st;
    }
  }
  func->hw_info.fn_intf_code = fn_intf_code;
  return ZX_OK;
}

zx_status_t SdioControllerDevice::InitFunc(uint8_t fn_idx) {
  zx_status_t st = ZX_OK;

  if ((st = ProcessFbr(fn_idx)) != ZX_OK) {
    return st;
  }

  if ((st = ProcessCis(fn_idx)) != ZX_OK) {
    return st;
  }

  // Enable all func for now. Should move to wifi driver ?
  if ((st = SdioEnableFnLocked(fn_idx)) != ZX_OK) {
    return st;
  }

  // Set default block size
  if ((st = SdioUpdateBlockSizeLocked(fn_idx, 0, true)) != ZX_OK) {
    return st;
  }

  return st;
}

zx_status_t SdioControllerDevice::SwitchFreq(uint32_t new_freq) {
  zx_status_t st;
  if ((st = sdmmc_->SetBusFreq(new_freq)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while switching host bus frequency, retcode = %d", st);
    return st;
  }
  return ZX_OK;
}

zx_status_t SdioControllerDevice::TrySwitchHs() {
  zx_status_t st = ZX_OK;
  uint8_t speed = 0;

  if (!(hw_info_.caps & SDIO_CARD_HIGH_SPEED)) {
    FDF_LOGL(ERROR, logger(), "High speed not supported, retcode = %d", st);
    return ZX_ERR_NOT_SUPPORTED;
  }
  st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &speed);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while reading CCCR reg, retcode = %d", st);
    return st;
  }
  UpdateBitsU8(&speed, SDIO_CIA_CCCR_BUS_SPEED_BSS_MASK, SDIO_CIA_CCCR_BUS_SPEED_BSS_LOC,
               SDIO_BUS_SPEED_EN_HS);
  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, speed, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while writing to CCCR reg, retcode = %d", st);
    return st;
  }
  // Switch the host timing
  if ((st = sdmmc_->SetTiming(SDMMC_TIMING_HS)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "failed to switch to hs timing on host : %d", st);
    return st;
  }

  if ((st = SwitchFreq(SDIO_HS_MAX_FREQ)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "failed to switch to hs timing on host : %d", st);
    return st;
  }

  if ((st = SwitchBusWidth(SDIO_BW_4BIT)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Swtiching to 4-bit bus width failed, retcode = %d", st);
    return st;
  }
  return ZX_OK;
}

zx_status_t SdioControllerDevice::TrySwitchUhs() {
  zx_status_t st = ZX_OK;
  if ((st = SwitchBusWidth(SDIO_BW_4BIT)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Swtiching to 4-bit bus width failed, retcode = %d", st);
    return st;
  }

  uint8_t speed = 0;

  uint32_t new_freq = SDIO_DEFAULT_FREQ;
  uint8_t select_speed = SDIO_BUS_SPEED_SDR50;
  sdmmc_timing_t timing = SDMMC_TIMING_SDR50;

  st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &speed);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while reading CCCR reg, retcode = %d", st);
    return st;
  }

  if ((sdmmc_->host_info().caps & SDMMC_HOST_CAP_SDR104) &&
      (hw_info_.caps & SDIO_CARD_UHS_SDR104)) {
    select_speed = SDIO_BUS_SPEED_SDR104;
    timing = SDMMC_TIMING_SDR104;
    new_freq = SDIO_UHS_SDR104_MAX_FREQ;
  } else if ((sdmmc_->host_info().caps & SDMMC_HOST_CAP_SDR50) &&
             (hw_info_.caps & SDIO_CARD_UHS_SDR50)) {
    select_speed = SDIO_BUS_SPEED_SDR50;
    timing = SDMMC_TIMING_SDR50;
    new_freq = SDIO_UHS_SDR50_MAX_FREQ;
  } else if ((sdmmc_->host_info().caps & SDMMC_HOST_CAP_DDR50) &&
             (hw_info_.caps & SDIO_CARD_UHS_DDR50)) {
    select_speed = SDIO_BUS_SPEED_DDR50;
    timing = SDMMC_TIMING_DDR50;
    new_freq = SDIO_UHS_DDR50_MAX_FREQ;
  } else {
    select_speed = SDIO_BUS_SPEED_SDR25;
    timing = SDMMC_TIMING_SDR25;
    new_freq = SDIO_UHS_SDR25_MAX_FREQ;
  }

  UpdateBitsU8(&speed, SDIO_CIA_CCCR_BUS_SPEED_BSS_MASK, SDIO_CIA_CCCR_BUS_SPEED_BSS_LOC,
               select_speed);

  st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, speed, nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while writing to CCCR reg, retcode = %d", st);
    return st;
  }
  // Switch the host timing
  if ((st = sdmmc_->SetTiming(timing)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "failed to switch to uhs timing on host : %d", st);
    return st;
  }

  if ((st = SwitchFreq(new_freq)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "failed to switch to uhs timing on host : %d", st);
    return st;
  }

  // Only tune for SDR50 if the host requires it.
  if (timing == SDMMC_TIMING_SDR104 ||
      (timing == SDMMC_TIMING_SDR50 &&
       !(sdmmc_->host_info().caps & SDMMC_HOST_CAP_NO_TUNING_SDR50))) {
    st = sdmmc_->PerformTuning(SD_SEND_TUNING_BLOCK);
    if (st != ZX_OK) {
      FDF_LOGL(ERROR, logger(), "tuning failed %d", st);
      return st;
    }
    tuned_ = true;
  }
  return ZX_OK;
}

zx_status_t SdioControllerDevice::Enable4BitBus() {
  zx_status_t st = ZX_OK;
  if ((hw_info_.caps & SDIO_CARD_LOW_SPEED) && !(hw_info_.caps & SDIO_CARD_FOUR_BIT_BUS)) {
    FDF_LOGL(ERROR, logger(), "Switching to 4-bit bus unsupported");
    return ZX_ERR_NOT_SUPPORTED;
  }
  uint8_t bus_ctrl_reg;
  if ((st = SdioDoRwByteLocked(false, 0, SDIO_CIA_CCCR_BUS_INTF_CTRL_ADDR, 0, &bus_ctrl_reg)) !=
      ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading the current bus width");
    return st;
  }
  UpdateBitsU8(&bus_ctrl_reg, SDIO_CIA_CCCR_INTF_CTRL_BW_MASK, SDIO_CIA_CCCR_INTF_CTRL_BW_LOC,
               SDIO_BW_4BIT);
  if ((st = SdioDoRwByteLocked(true, 0, SDIO_CIA_CCCR_BUS_INTF_CTRL_ADDR, bus_ctrl_reg, nullptr)) !=
      ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error while switching the bus width");
    return st;
  }
  if ((st = sdmmc_->SetBusWidth(SDMMC_BUS_WIDTH_FOUR)) != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "failed to switch the host bus width to %d, retcode = %d",
             SDMMC_BUS_WIDTH_FOUR, st);
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}

zx_status_t SdioControllerDevice::SwitchBusWidth(uint32_t bw) {
  zx_status_t st = ZX_OK;
  if (bw != SDIO_BW_1BIT && bw != SDIO_BW_4BIT) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  if (bw == SDIO_BW_4BIT) {
    if ((st = Enable4BitBus()) != ZX_OK) {
      return st;
    }
  }
  return ZX_OK;
}

zx_status_t SdioControllerDevice::ReadData16(uint8_t fn_idx, uint32_t addr, uint16_t* word) {
  uint8_t byte1 = 0, byte2 = 0;
  zx_status_t st = SdioDoRwByteLocked(false, 0, addr, 0, &byte1);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading from addr:0x%x, retcode: %d", addr, st);
    return st;
  }

  st = SdioDoRwByteLocked(false, 0, addr + 1, 0, &byte2);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error reading from addr:0x%x, retcode: %d", addr + 1, st);
    return st;
  }

  *word = static_cast<uint16_t>(byte2 << 8 | byte1);
  return ZX_OK;
}

zx_status_t SdioControllerDevice::WriteData16(uint8_t fn_idx, uint32_t addr, uint16_t word) {
  zx_status_t st = SdioDoRwByteLocked(true, 0, addr, static_cast<uint8_t>(word & 0xff), nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error writing to addr:0x%x, retcode: %d", addr, st);
    return st;
  }

  st = SdioDoRwByteLocked(true, 0, addr + 1, static_cast<uint8_t>((word >> 8) & 0xff), nullptr);
  if (st != ZX_OK) {
    FDF_LOGL(ERROR, logger(), "Error writing to addr:0x%x, retcode: %d", addr + 1, st);
    return st;
  }

  return ZX_OK;
}

fdf::Logger& SdioControllerDevice::logger() { return parent_->logger(); }

}  // namespace sdmmc
