// 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 <lib/zx/clock.h>
#include <lib/zx/vmar.h>
#include <unistd.h>

#include <limits>
#include <optional>
#include <utility>

#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <soc/as370/as370-audio-regs.h>
#include <soc/as370/as370-clk-regs.h>
#include <soc/as370/as370-dma.h>
#include <soc/as370/syn-audio-in.h>

namespace {
constexpr uint64_t kPortDmaNotification = 0x00;
}  // namespace

std::unique_ptr<SynAudioInDevice> SynAudioInDevice::Create(ddk::MmioBuffer mmio_global,
                                                           ddk::MmioBuffer mmio_avio_global,
                                                           ddk::MmioBuffer mmio_i2s,
                                                           ddk::SharedDmaProtocolClient dma) {
  fbl::AllocChecker ac;
  auto dev = std::unique_ptr<SynAudioInDevice>(new (&ac) SynAudioInDevice(
      std::move(mmio_global), std::move(mmio_avio_global), std::move(mmio_i2s), dma));
  if (!ac.check()) {
    return nullptr;
  }

  auto status = dev->Init();
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s could not init %d", __FILE__, status);
    return nullptr;
  }
  return dev;
}

SynAudioInDevice::SynAudioInDevice(ddk::MmioBuffer mmio_global, ddk::MmioBuffer mmio_avio_global,
                                   ddk::MmioBuffer mmio_i2s, ddk::SharedDmaProtocolClient dma)
    : global_(std::move(mmio_global)),
      avio_global_(std::move(mmio_avio_global)),
      i2s_(std::move(mmio_i2s)),
      dma_(dma) {
  cic_filter_ = std::make_unique<CicFilter>();
}

uint32_t SynAudioInDevice::PcmAmountPerTransfer() const {
  constexpr uint32_t kChannelsPerDma = 2;
  const uint32_t kTransferSize = dma_.GetTransferSize(DmaId::kDmaIdPdmW0);
  ZX_DEBUG_ASSERT(kTransferSize % (kChannelsPerDma * cic_filter_->GetInputToOutputRatio()) == 0);
  const uint32_t kPcmDataForOneChannel =
      kTransferSize / (kChannelsPerDma * cic_filter_->GetInputToOutputRatio());
  return static_cast<uint32_t>(kNumberOfChannels) * kPcmDataForOneChannel;
}

uint32_t SynAudioInDevice::FifoDepth() const {
  constexpr uint32_t kNumberOfTransfersForFifoDepth = 2;
  return kNumberOfTransfersForFifoDepth * PcmAmountPerTransfer();
}

void SynAudioInDevice::ProcessDma(uint32_t index) {
  const uint32_t dma_transfer_size = dma_.GetTransferSize(DmaId::kDmaIdPdmW0);
  while (1) {
    static uint32_t run_count = 0;
    auto before = zx::clock::get_monotonic();
    auto dhub_pos = dma_.GetBufferPosition(index == 0 ? DmaId::kDmaIdPdmW0 : DmaId::kDmaIdPdmW1);
    auto amount_pdm = dhub_pos - dma_buffer_current_[index];
    auto distance = dma_buffer_size_[index] - amount_pdm;

    // Check for usual case, wrap around, or no work to do.
    if (dhub_pos > dma_buffer_current_[index]) {
      zxlogf(DEBUG,
             "audio: %u  usual  run %u  distance 0x%08X  dhub 0x%08X  curr 0x%08X  pdm 0x%08X\n",
             index, run_count, distance, dhub_pos, dma_buffer_current_[index], amount_pdm);
    } else if (dhub_pos < dma_buffer_current_[index]) {
      distance = dma_buffer_current_[index] - dhub_pos;
      amount_pdm = dma_buffer_size_[index] - distance;
      zxlogf(DEBUG,
             "audio: %u  wrap   run %u  distance 0x%08X  dhub 0x%08X  curr 0x%08X  pdm 0x%08X\n",
             index, run_count, distance, dhub_pos, dma_buffer_current_[index], amount_pdm);
    } else {
      zxlogf(DEBUG,
             "audio: %u  empty  run %u  distance 0x%08X  dhub 0x%08X  curr 0x%08X  pdm 0x%08X\n",
             index, run_count, distance, dhub_pos, dma_buffer_current_[index], amount_pdm);
      return;
    }

    run_count++;

    // Check for overflowing.
    if (distance <= dma_transfer_size) {
      overflows_++;
      zxlogf(ERROR, "audio: %u  overflows %u", index, overflows_);
      return;  // We can't keep up.
    }

    const uint32_t max_dma_to_process = dma_transfer_size;
    if (amount_pdm > max_dma_to_process) {
      zxlogf(DEBUG, "audio: %u  PDM data (%u) from dhub is too big (>%u),  overflows %u", index,
             amount_pdm, max_dma_to_process, overflows_);
      amount_pdm = max_dma_to_process;
    }

    constexpr uint32_t multiplier_shift = 5;
    struct Parameter {
      uint32_t filter_index;
      uint32_t input_channel;
      uint32_t output_channel;
    };

    std::optional<Parameter> parameters[][2] = {
        {std::optional<Parameter>({0, 0, 0}), std::optional<Parameter>({1, 1, 1})},  // index 0.
        {std::optional<Parameter>({2, 0, 2}), std::optional<Parameter>()},           // index 1.
    };
    uint32_t amount_pcm = 0;
    // Either input channel (rising or falled edge PDM capture), unless it is only one channel.
    for (uint32_t i = 0; i < (kNumberOfChannels > 1 ? 2 : 1); ++i) {
      if (parameters[index][i].has_value()) {
        zxlogf(DEBUG, "audio: %u  decoding from 0x%08X  amount 0x%08X  into 0x%08X", index,
               dma_buffer_current_[index], amount_pdm, ring_buffer_current_);
        amount_pcm = cic_filter_->Filter(
            parameters[index][i]->filter_index,
            reinterpret_cast<void*>(dma_base_[index] + dma_buffer_current_[index]), amount_pdm,
            reinterpret_cast<void*>(ring_buffer_base_ + ring_buffer_current_), 2,
            parameters[index][i]->input_channel, kNumberOfChannels,
            parameters[index][i]->output_channel, multiplier_shift);
      }
    }

    // Increment output (ring buffer) pointer and check for wraparound on the last DMA.
    if (index == kNumberOfDmas - 1) {
      ring_buffer_current_ += amount_pcm;
      if (ring_buffer_current_ >= ring_buffer_size_) {
        ring_buffer_current_ = 0;
      }
    }

    // Increment input (DMA buffer) pointer and check for wraparound.
    dma_buffer_current_[index] += amount_pdm;
    if (dma_buffer_current_[index] >= dma_buffer_size_[index]) {
      dma_buffer_current_[index] -= dma_buffer_size_[index];
    }

    // Clean cache for the next input (DMA buffer).
    auto buffer_to_clean = max_dma_to_process;
    ZX_ASSERT(dma_buffer_current_[index] + buffer_to_clean <= dma_buffer_size_[index]);
    dma_buffer_[index].op_range(ZX_VMO_OP_CACHE_CLEAN_INVALIDATE, dma_buffer_current_[index],
                                buffer_to_clean, nullptr, 0);
    auto after = zx::clock::get_monotonic();
    zxlogf(DEBUG, "audio: %u  decoded 0x%X bytes in %lumsecs  into 0x%X bytes  distance 0x%X",
           index, amount_pdm, (after - before).to_msecs(), amount_pcm, distance);
  }
}

int SynAudioInDevice::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", __FILE__, status);
      return thrd_error;
    }
    zxlogf(DEBUG, "audio: msg on port key %lu", packet.key);
    if (packet.key == kPortDmaNotification) {
      if (enabled_) {
        for (uint32_t i = 0; i < kNumberOfDmas; ++i) {
          ProcessDma(i);
        }
      } else {
        zxlogf(DEBUG, "audio: DMA already stopped");
      }
    }
  }
}

zx_status_t SynAudioInDevice::Init() {
  auto status = zx::port::create(0, &port_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s port create failed %d", __FILE__, status);
    return status;
  }

  dma_notify_t notify = {};
  auto notify_cb = [](void* ctx, dma_state_t state) -> void {
    SynAudioInDevice* thiz = static_cast<SynAudioInDevice*>(ctx);
    zx_port_packet packet = {kPortDmaNotification, ZX_PKT_TYPE_USER, ZX_OK, {}};
    zxlogf(DEBUG, "audio: notification callback with state %d", static_cast<int>(state));
    // No need to notify if we already stopped the DMA.
    if (thiz->enabled_) {
      auto status = thiz->port_.queue(&packet);
      ZX_ASSERT(status == ZX_OK);
    }
  };
  notify.callback = notify_cb;
  notify.ctx = this;
  dma_.SetNotifyCallback(DmaId::kDmaIdPdmW0, &notify);
  // Only need notification for PDM0, PDM1 piggybacks onto it.

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

uint32_t SynAudioInDevice::GetRingPosition() { return ring_buffer_current_; }

zx_status_t SynAudioInDevice::GetBuffer(size_t size, zx::vmo* buffer) {
  // dma_buffer_size (ask here is a buffer of size 8 x 16KB) allows for this driver not getting CPU
  // time to perform the PDM decoding even when behind.  Higher numbers allow for more resiliance,
  // although if we get behind on decoding there is more latency added to the created ringbuffer.
  // Note though that it is expected for the driver to decode one transfer within the time it takes
  // to receive the next as reported on fifo_depth() (kNumberOfTransfersForFifoDepth == 2).
  ZX_ASSERT(dma_.GetTransferSize(DmaId::kDmaIdPdmW0) == dma_.GetTransferSize(DmaId::kDmaIdPdmW1));
  ZX_ASSERT(kNumberOfDmas <= 2);

  auto root = zx::vmar::root_self();
  size_t buffer_size = 0;
  for (uint32_t i = 0; i < kNumberOfDmas; ++i) {
    dma_.InitializeAndGetBuffer(i == 0 ? DmaId::kDmaIdPdmW0 : DmaId::kDmaIdPdmW1, DMA_TYPE_CYCLIC,
                                8 * 16 * 1024, &dma_buffer_[i]);
    dma_buffer_[i].get_size(&buffer_size);
    dma_buffer_size_[i] = static_cast<uint32_t>(buffer_size);

    constexpr uint32_t flags = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
    auto status = root->map(flags, 0, dma_buffer_[i], 0, dma_buffer_size_[i], &dma_base_[i]);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s vmar mapping failed %d", __FILE__, status);
      return status;
    }
    dma_buffer_[i].op_range(ZX_VMO_OP_CACHE_CLEAN_INVALIDATE, 0, dma_buffer_size_[i], nullptr, 0);
  }

  // We simplify buffer management by having decoded PCM data for all channels to not wrap at the
  // end of ring buffer, rounding up to the decoded PCM data amount per transfer.
  size = fbl::round_up<size_t, uint32_t>(size, PcmAmountPerTransfer());

  auto status = zx::vmo::create(size, 0, &ring_buffer_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s failed to allocate ring buffer vmo %d", __FILE__, status);
    return status;
  }
  ring_buffer_.get_size(&buffer_size);
  ring_buffer_size_ = static_cast<uint32_t>(buffer_size);
  constexpr uint32_t flags = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
  status = root->map(flags, 0, ring_buffer_, 0, ring_buffer_size_, &ring_buffer_base_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s vmar mapping failed %d", __FILE__, status);
    return status;
  }
  constexpr uint32_t rights =
      ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_MAP | ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE;
  return ring_buffer_.duplicate(rights, buffer);
}

uint64_t SynAudioInDevice::Start() {
  AIO_IRQENABLE::Get().ReadFrom(&i2s_).set_PDMIRQ(1).WriteTo(&i2s_);
  AIO_MCLKPDM_ACLK_CTRL::Get().FromValue(0x189).WriteTo(&i2s_);
  constexpr uint32_t divider = 3;  // divide by 8.
  AIO_PDM_CTRL1::Get()
      .FromValue(0)
      .set_RDM(4)
      .set_RSLB(1)
      .set_INVCLK_INT(1)
      .set_CLKDIV(divider)
      .WriteTo(&i2s_);

  AIO_PDM_PDM0_CTRL::Get().FromValue(0).set_MUTE(1).set_ENABLE(0).WriteTo(&i2s_);
  AIO_PDM_PDM1_CTRL::Get().FromValue(0).set_MUTE(1).set_ENABLE(0).WriteTo(&i2s_);

  AIO_PDM_PDM0_CTRL::Get().FromValue(0).set_MUTE(1).set_ENABLE(1).WriteTo(&i2s_);
  AIO_PDM_PDM1_CTRL::Get().FromValue(0).set_MUTE(1).set_ENABLE(1).WriteTo(&i2s_);

  AIO_PDM_MIC_SEL::Get().FromValue(0).set_CTRL(0x4).WriteTo(&i2s_);
  AIO_PDM_MIC_SEL::Get().FromValue(0).set_CTRL(0xc).WriteTo(&i2s_);

  AIO_PDM_PDM0_CTRL2::Get().FromValue(0).set_FDLT(3).set_RDLT(3).WriteTo(&i2s_);
  AIO_PDM_PDM1_CTRL2::Get().FromValue(0).set_FDLT(3).set_RDLT(3).WriteTo(&i2s_);

  // Playback.
  enabled_ = true;
  for (uint32_t i = 0; i < kNumberOfDmas; ++i) {
    dma_.Start(i == 0 ? DmaId::kDmaIdPdmW0 : DmaId::kDmaIdPdmW1);
  }

  // Unmute.
  AIO_PDM_PDM0_CTRL::Get().FromValue(0).set_MUTE(0).set_ENABLE(1).WriteTo(&i2s_);
  AIO_PDM_PDM1_CTRL::Get().FromValue(0).set_MUTE(0).set_ENABLE(1).WriteTo(&i2s_);

  // Enable.
  AIO_IOSEL_PDM::Get().FromValue(0).set_GENABLE(1).WriteTo(&i2s_);
  return 0;
}

void SynAudioInDevice::Stop() {
  AIO_IOSEL_PDM::Get().FromValue(0).set_GENABLE(0).WriteTo(&i2s_);
  enabled_ = false;
  for (uint32_t i = 0; i < kNumberOfDmas; ++i) {
    dma_.Stop(i == 0 ? DmaId::kDmaIdPdmW0 : DmaId::kDmaIdPdmW1);
  }
}

void SynAudioInDevice::Shutdown() { Stop(); }
