// Copyright 2020 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 "dai.h"

#include <lib/ddk/binding_driver.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/metadata.h>
#include <lib/ddk/platform-defs.h>
#include <lib/fpromise/result.h>
#include <lib/zx/clock.h>
#include <math.h>
#include <string.h>

#include <numeric>
#include <optional>
#include <utility>

#include <fbl/algorithm.h>

namespace audio::aml_g12 {

enum {
  FRAGMENT_PDEV,
  FRAGMENT_COUNT,
};

AmlG12TdmDai::AmlG12TdmDai(zx_device_t* parent, ddk::PDevFidl pdev)
    : AmlG12TdmDaiDeviceType(parent),
      loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
      pdev_(std::move(pdev)) {
  ddk_proto_id_ = ZX_PROTOCOL_DAI;
  loop_.StartThread("aml-g12-tdm-dai");
}

void AmlG12TdmDai::InitDaiFormats() {
  // Only the PCM signed sample format is supported.
  dai_format_.sample_format = ::fuchsia::hardware::audio::DaiSampleFormat::PCM_SIGNED;
  dai_format_.frame_rate = AmlTdmConfigDevice::GetSupportedFrameRates()[0];
  dai_format_.bits_per_sample = metadata_.dai.bits_per_sample;
  dai_format_.bits_per_slot = metadata_.dai.bits_per_slot;
  dai_format_.number_of_channels = metadata_.dai.number_of_channels;
  dai_format_.channels_to_use_bitmask = std::numeric_limits<uint64_t>::max();  // Enable all.
  switch (metadata_.dai.type) {
    case metadata::DaiType::I2s:
      dai_format_.frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::I2S);
      break;
    case metadata::DaiType::StereoLeftJustified:
      dai_format_.frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::STEREO_LEFT);
      break;
    case metadata::DaiType::Tdm1:
      dai_format_.frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::TDM1);
      break;
    case metadata::DaiType::Tdm2:
      dai_format_.frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::TDM2);
      break;
    case metadata::DaiType::Tdm3:
      dai_format_.frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::TDM3);
      break;
  }
}

void AmlG12TdmDai::Connect(ConnectRequestView request, ConnectCompleter::Sync& completer) {
  ::fidl::InterfaceRequest<::fuchsia::hardware::audio::Dai> dai;
  dai.set_channel(request->dai_protocol.TakeChannel());
  dai_binding_.emplace(this, std::move(dai), loop_.dispatcher());
  dai_binding_->set_error_handler([this](zx_status_t status) -> void {
    zxlogf(INFO, "DAI protocol %s", zx_status_get_string(status));
    Stop([]() {});
    delay_info_sent_ = false;
  });
}

zx_status_t AmlG12TdmDai::DaiConnect(zx::channel channel) {
  dai_binding_.emplace(this, std::move(channel), loop_.dispatcher());
  return ZX_OK;
}

void AmlG12TdmDai::Reset(ResetCallback callback) {
  auto status =
      aml_audio_->InitHW(metadata_, dai_format_.channels_to_use_bitmask, dai_format_.frame_rate);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to init tdm hardware %d", status);
  }
  callback();
}

zx_status_t AmlG12TdmDai::InitPDev() {
  size_t actual = 0;
  auto status = device_get_fragment_metadata(parent(), "pdev", DEVICE_METADATA_PRIVATE, &metadata_,
                                             sizeof(metadata::AmlConfig), &actual);
  if (status != ZX_OK || sizeof(metadata::AmlConfig) != actual) {
    zxlogf(ERROR, "device_get_fragment_metadata failed %d", status);
    return status;
  }
  status = AmlTdmConfigDevice::Normalize(metadata_);
  if (status != ZX_OK) {
    return status;
  }
  InitDaiFormats();

  status = pdev_.GetBti(0, &bti_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "could not obtain bti %d", status);
    return status;
  }
  std::optional<fdf::MmioBuffer> mmio;
  status = pdev_.MapMmio(0, &mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "could not get mmio %d", status);
    return status;
  }
  aml_audio_ = std::make_unique<AmlTdmConfigDevice>(metadata_, *std::move(mmio));
  if (aml_audio_ == nullptr) {
    zxlogf(ERROR, "failed to create TDM device with config");
    return ZX_ERR_NO_MEMORY;
  }

  Reset([]() {});

  return ZX_OK;
}

void AmlG12TdmDai::DdkRelease() {
  loop_.Shutdown();
  Shutdown();
  delete this;
}

void AmlG12TdmDai::Shutdown() {
  if (rb_started_) {
    Stop([]() {});
  }
  aml_audio_->Shutdown();
  pinned_ring_buffer_.Unpin();
}

void AmlG12TdmDai::GetVmo(uint32_t min_frames, uint32_t clock_recovery_notifications_per_ring,
                          GetVmoCallback callback) {
  if (rb_started_) {
    zxlogf(ERROR, "GetVmo failed, ring buffer started");
    ringbuffer_binding_->Unbind();
    return;
  }
  frame_size_ = metadata_.ring_buffer.number_of_channels * metadata_.ring_buffer.bytes_per_sample;
  size_t ring_buffer_size =
      fbl::round_up<size_t, size_t>(min_frames * frame_size_ + aml_audio_->fifo_depth(),
                                    std::lcm(frame_size_, aml_audio_->GetBufferAlignment()));
  size_t out_frames = ring_buffer_size / frame_size_;
  if (out_frames > std::numeric_limits<uint32_t>::max()) {
    zxlogf(ERROR, "out frames too big %zu", out_frames);
    ringbuffer_binding_->Unbind();
    return;
  }
  auto status = InitBuffer(ring_buffer_size);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to init buffer %d", status);
    ringbuffer_binding_->Unbind();
    return;
  }

  constexpr uint32_t rights = ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_MAP | ZX_RIGHT_TRANSFER;
  zx::vmo buffer;
  status = ring_buffer_vmo_.duplicate(rights, &buffer);
  if (status != ZX_OK) {
    zxlogf(ERROR, "GetVmo failed, could not duplicate VMO");
    ringbuffer_binding_->Unbind();
    return;
  }

  status = aml_audio_->SetBuffer(pinned_ring_buffer_.region(0).phys_addr, ring_buffer_size);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to set buffer %d", status);
    ringbuffer_binding_->Unbind();
    return;
  }

  expected_notifications_per_ring_.store(clock_recovery_notifications_per_ring);
  rb_fetched_ = true;
  // This is safe because of the overflow check we made above.
  auto out_num_rb_frames = static_cast<uint32_t>(out_frames);
  callback(fpromise::ok(std::make_tuple(out_num_rb_frames, std::move(buffer))));
}

void AmlG12TdmDai::Start(StartCallback callback) {
  uint64_t start_time = 0;
  if (rb_started_) {
    zxlogf(ERROR, "Could not start: already started");
    ringbuffer_binding_->Close(ZX_ERR_BAD_STATE);
    return;
  }
  if (!rb_fetched_) {
    zxlogf(ERROR, "Could not start: first, GetVmo must successfully complete");
    ringbuffer_binding_->Close(ZX_ERR_BAD_STATE);
    return;
  }

  start_time = aml_audio_->Start();
  rb_started_ = true;

  uint32_t notifs = expected_notifications_per_ring_.load();
  if (notifs) {
    us_per_notification_ =
        static_cast<uint32_t>(1000 * pinned_ring_buffer_.region(0).size /
                              (frame_size_ * dai_format_.frame_rate / 1000 * notifs));
    notify_timer_.PostDelayed(loop_.dispatcher(), zx::usec(us_per_notification_));
  } else {
    us_per_notification_ = 0;
  }

  callback(start_time);
}

void AmlG12TdmDai::Stop(StopCallback callback) {
  if (!rb_fetched_) {
    zxlogf(ERROR, "GetVmo must successfully complete before calling Start or Stop");
    ringbuffer_binding_->Close(ZX_ERR_BAD_STATE);
    return;
  }
  if (!rb_started_) {
    zxlogf(INFO, "Stop called while stopped; this is allowed");
  }
  notify_timer_.Cancel();
  us_per_notification_ = 0;
  aml_audio_->Stop();
  rb_started_ = false;
  callback();
}

zx_status_t AmlG12TdmDai::InitBuffer(size_t size) {
  // Make sure the DMA is stopped before releasing quarantine.
  aml_audio_->Stop();
  // Make sure that all reads/writes have gone through.
#if defined(__aarch64__)
  __asm__ volatile("dsb sy" : : : "memory");
#endif
  auto status = bti_.release_quarantine();
  if (status != ZX_OK) {
    zxlogf(ERROR, "could not release quarantine bti - %d", status);
    return status;
  }
  pinned_ring_buffer_.Unpin();
  status = zx_vmo_create_contiguous(bti_.get(), size, 0, ring_buffer_vmo_.reset_and_get_address());
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to allocate ring buffer vmo - %d", status);
    return status;
  }

  status = pinned_ring_buffer_.Pin(ring_buffer_vmo_, bti_, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to pin ring buffer vmo - %d", status);
    return status;
  }
  if (pinned_ring_buffer_.region_count() != 1) {
    if (!AllowNonContiguousRingBuffer()) {
      zxlogf(ERROR, "buffer is not contiguous");
      return ZX_ERR_NO_MEMORY;
    }
  }
  return ZX_OK;
}

void AmlG12TdmDai::GetProperties(::fuchsia::hardware::audio::Dai::GetPropertiesCallback callback) {
  ::fuchsia::hardware::audio::DaiProperties props;
  props.set_is_input(metadata_.is_input);
  props.set_manufacturer(metadata_.manufacturer);
  props.set_product_name(metadata_.product_name);
  props.set_clock_domain(::fuchsia::hardware::audio::CLOCK_DOMAIN_MONOTONIC);
  callback(std::move(props));
}

void AmlG12TdmDai::GetRingBufferFormats(GetRingBufferFormatsCallback callback) {
  ::fuchsia::hardware::audio::Dai_GetRingBufferFormats_Result result;
  ::fuchsia::hardware::audio::Dai_GetRingBufferFormats_Response response;
  ::fuchsia::hardware::audio::PcmSupportedFormats pcm_formats;
  ::fuchsia::hardware::audio::ChannelSet channel_set;
  std::vector<::fuchsia::hardware::audio::ChannelAttributes> attributes(
      metadata_.ring_buffer.number_of_channels);
  channel_set.set_attributes(std::move(attributes));
  pcm_formats.mutable_channel_sets()->push_back(std::move(channel_set));
  pcm_formats.mutable_sample_formats()->push_back(
      ::fuchsia::hardware::audio::SampleFormat::PCM_SIGNED);
  pcm_formats.mutable_bytes_per_sample()->push_back(metadata_.ring_buffer.bytes_per_sample);
  pcm_formats.mutable_valid_bits_per_sample()->push_back(metadata_.ring_buffer.bytes_per_sample *
                                                         8);
  pcm_formats.set_frame_rates(AmlTdmConfigDevice::GetSupportedFrameRates());
  ::fuchsia::hardware::audio::SupportedFormats formats;
  formats.set_pcm_supported_formats(std::move(pcm_formats));
  response.ring_buffer_formats.push_back(std::move(formats));
  result.set_response(std::move(response));
  callback(std::move(result));
}

void AmlG12TdmDai::GetDaiFormats(GetDaiFormatsCallback callback) {
  ::fuchsia::hardware::audio::Dai_GetDaiFormats_Result result;
  ::fuchsia::hardware::audio::Dai_GetDaiFormats_Response response;
  ::fuchsia::hardware::audio::DaiSupportedFormats formats;
  formats.number_of_channels.push_back(metadata_.dai.number_of_channels);
  formats.sample_formats.push_back(::fuchsia::hardware::audio::DaiSampleFormat::PCM_SIGNED);
  ::fuchsia::hardware::audio::DaiFrameFormat frame_format;
  switch (metadata_.dai.type) {
    case metadata::DaiType::I2s:
      frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::I2S);
      break;
    case metadata::DaiType::StereoLeftJustified:
      frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::STEREO_LEFT);
      break;
    case metadata::DaiType::Tdm1:
      frame_format.set_frame_format_standard(
          ::fuchsia::hardware::audio::DaiFrameFormatStandard::TDM1);
      break;
    default:
      ZX_ASSERT(0);  // Not supported.
  }
  formats.frame_formats.push_back(std::move(frame_format));
  formats.frame_rates = AmlTdmConfigDevice::GetSupportedFrameRates();
  formats.bits_per_slot.push_back(metadata_.dai.bits_per_slot);
  formats.bits_per_sample.push_back(metadata_.dai.bits_per_sample);
  response.dai_formats.push_back(std::move(formats));
  result.set_response(std::move(response));
  callback(std::move(result));
}

void AmlG12TdmDai::CreateRingBuffer(
    ::fuchsia::hardware::audio::DaiFormat dai_format,
    ::fuchsia::hardware::audio::Format ring_buffer_format,
    ::fidl::InterfaceRequest<::fuchsia::hardware::audio::RingBuffer> ring_buffer) {
  if (ring_buffer_format.pcm_format().frame_rate == 0) {
    zxlogf(ERROR, "Bad (zero) frame rate");
    ring_buffer.Close(ZX_ERR_INVALID_ARGS);
    return;
  }

  uint32_t bytes_per_frame = ring_buffer_format.pcm_format().bytes_per_sample *
                             ring_buffer_format.pcm_format().number_of_channels;
  if (bytes_per_frame == 0) {
    zxlogf(ERROR, "Bad (zero) bytes per frame");
    ring_buffer.Close(ZX_ERR_INVALID_ARGS);
    return;
  }

  // Stop and terminate a previous ring buffer.
  if (rb_started_) {
    Stop([]() {});
    ringbuffer_binding_->Unbind();
  }

  ringbuffer_binding_.emplace(this, std::move(ring_buffer), loop_.dispatcher());
  // Clear delay info sent state such that a call to WatchDelayInfo after CreateRingBuffer will be
  // replied to the first time. Doing it here instead of in the error handler guarantees that once
  // CreateRingBuffer is called, a WatchDelayInfo will be replied to even before the error handler
  // is called for any previous ring buffer in use.
  delay_info_sent_ = false;
  ringbuffer_binding_->set_error_handler([this](zx_status_t status) -> void {
    zxlogf(INFO, "RingBuffer protocol %s", zx_status_get_string(status));
    ResetRingBuffer();
  });
  dai_format_ = std::move(dai_format);

  internal_delay_nsec_ = 0;  // No internal delay known, so we report 0.

  Reset([]() {});
}

void AmlG12TdmDai::ResetRingBuffer() {
  rb_fetched_ = false;
  rb_started_ = false;
  expected_notifications_per_ring_ = 0;
  position_callback_.reset();
  dai_format_ = {};
  Stop([]() {});
}

void AmlG12TdmDai::GetProperties(
    ::fuchsia::hardware::audio::RingBuffer::GetPropertiesCallback callback) {
  ::fuchsia::hardware::audio::RingBufferProperties prop;
  prop.set_driver_transfer_bytes(aml_audio_->fifo_depth())
      .set_needs_cache_flush_or_invalidate(true);
  callback(std::move(prop));
}

void AmlG12TdmDai::ProcessRingNotification() {
  if (us_per_notification_) {
    notify_timer_.PostDelayed(loop_.dispatcher(), zx::usec(us_per_notification_));
  } else {
    notify_timer_.Cancel();
    return;
  }
  ::fuchsia::hardware::audio::RingBufferPositionInfo info;
  info.position = aml_audio_->GetRingPosition();
  info.timestamp = zx::clock::get_monotonic().get();
  if (position_callback_) {
    (*position_callback_)(std::move(info));
    position_callback_.reset();
  }
}

void AmlG12TdmDai::WatchClockRecoveryPositionInfo(WatchClockRecoveryPositionInfoCallback callback) {
  if (!expected_notifications_per_ring_.load()) {
    zxlogf(ERROR, "no notifications per ring");
  }
  position_callback_ = std::move(callback);
}

void AmlG12TdmDai::WatchDelayInfo(WatchDelayInfoCallback callback) {
  if (delay_info_sent_) {
    return;  // Only send delay state once, as if it never changed.
  }
  delay_info_sent_ = true;
  fuchsia::hardware::audio::DelayInfo delay_info = {};
  // No external delay information is provided by this driver.
  delay_info.set_internal_delay(internal_delay_nsec_);
  callback(std::move(delay_info));
}

static zx_status_t dai_bind(void* ctx, zx_device_t* device) {
  size_t actual = 0;
  metadata::AmlConfig metadata = {};
  auto status = device_get_fragment_metadata(device, "pdev", DEVICE_METADATA_PRIVATE, &metadata,
                                             sizeof(metadata::AmlConfig), &actual);
  if (status != ZX_OK || sizeof(metadata::AmlConfig) != actual) {
    zxlogf(ERROR, "device_get_fragment_metadata failed %d", status);
    return status;
  }
  ddk::PDevFidl pdev = ddk::PDevFidl::FromFragment(device);
  if (!pdev.is_valid()) {
    zxlogf(ERROR, "could not get pdev");
    return ZX_ERR_NO_RESOURCES;
  }
  auto dai = std::make_unique<audio::aml_g12::AmlG12TdmDai>(device, std::move(pdev));
  if (dai == nullptr) {
    zxlogf(ERROR, "Could not create DAI driver");
    return ZX_ERR_NO_MEMORY;
  }

  status = dai->InitPDev();
  if (status != ZX_OK) {
    zxlogf(ERROR, "Could not init device");
    return status;
  }
  zx_device_prop_t props[] = {
      {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_AMLOGIC},
      {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_AMLOGIC_DAI_OUT},
  };
  const char* name = "aml-g12-tdm-dai-out";
  if (metadata.is_input) {
    props[1].value = PDEV_DID_AMLOGIC_DAI_IN;
    name = "aml-g12-tdm-dai-in";
  }
  status = dai->DdkAdd(ddk::DeviceAddArgs(name).set_props(props));
  if (status != ZX_OK) {
    zxlogf(ERROR, "Could not add DAI driver to the DDK");
    return status;
  }
  [[maybe_unused]] auto unused = dai.release();
  return ZX_OK;
}

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

}  // namespace audio::aml_g12

// clang-format off
ZIRCON_DRIVER(aml_g12_tdm_dai, audio::aml_g12::driver_ops, "aml-g12-tdm-dai", "0.1");
