// 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 <fuchsia/hardware/clockimpl/cpp/banjo.h>
#include <fuchsia/hardware/gpio/c/banjo.h>
#include <lib/mmio/mmio.h>
#include <limits.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddktl/metadata/audio.h>
#include <fbl/algorithm.h>
#include <hwreg/bitfields.h>
#include <soc/mt8167/mt8167-clk.h>
#include <soc/mt8167/mt8167-gpio.h>
#include <soc/mt8167/mt8167-hw.h>

#include "mt8167.h"

namespace board_mt8167 {

class WACS2_CMD : public hwreg::RegisterBase<WACS2_CMD, uint32_t> {
 public:
  static auto Get() { return hwreg::RegisterAddr<WACS2_CMD>(0x00A0); }

  DEF_BIT(31, WACS2_WRITE);
  DEF_FIELD(30, 16, WACS2_ADR);
  DEF_FIELD(15, 0, WACS2_WDATA);
};

class WACS2_RDATA : public hwreg::RegisterBase<WACS2_RDATA, uint32_t> {
 public:
  static constexpr uint32_t kStateIdle = 0;

  static auto Get() { return hwreg::RegisterAddr<WACS2_RDATA>(0x00A4); }

  DEF_FIELD(18, 16, status);
};

constexpr zx_bind_inst_t root_match[] = {
    BI_MATCH(),
};
static const zx_bind_inst_t in_i2c_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
    BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 1),
    BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x1B),
};
static const zx_bind_inst_t mt8167s_out_i2c_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
    BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 2),
    BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x48),
};
static const zx_bind_inst_t cleo_out_i2c_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
    BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 2),
    BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x2C),
};
static const zx_bind_inst_t mt8167s_out_codec_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_CODEC),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TI),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TI_TAS5782),
};
static const zx_bind_inst_t cleo_out_codec_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_CODEC),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TI),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TI_TAS58xx),
};
static const device_fragment_part_t in_i2c_fragment[] = {
    {std::size(root_match), root_match},
    {std::size(in_i2c_match), in_i2c_match},
};
static const device_fragment_part_t mt8167s_out_i2c_fragment[] = {
    {std::size(root_match), root_match},
    {std::size(mt8167s_out_i2c_match), mt8167s_out_i2c_match},
};
static const device_fragment_part_t cleo_out_i2c_fragment[] = {
    {std::size(root_match), root_match},
    {std::size(cleo_out_i2c_match), cleo_out_i2c_match},
};
static const device_fragment_part_t cleo_out_codec_fragment[] = {
    {std::size(root_match), root_match},
    {std::size(cleo_out_codec_match), cleo_out_codec_match},
};
static const device_fragment_part_t mt8167s_out_codec_fragment[] = {
    {std::size(root_match), root_match},
    {std::size(mt8167s_out_codec_match), mt8167s_out_codec_match},
};

static const zx_bind_inst_t in_gpio_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO24_EINT24),
};
static const zx_bind_inst_t mt8167s_out_reset_gpio_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO107_MSDC1_DAT1),
};
static const zx_bind_inst_t mt8167s_out_mute_gpio_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO108_MSDC1_DAT2),
};
static const device_fragment_part_t in_gpio_fragment[] = {
    {countof(root_match), root_match},
    {countof(in_gpio_match), in_gpio_match},
};
static const device_fragment_part_t mt8167s_out_reset_gpio_fragment[] = {
    {countof(root_match), root_match},
    {countof(mt8167s_out_reset_gpio_match), mt8167s_out_reset_gpio_match},
};
static const device_fragment_part_t mt8167s_out_mute_gpio_fragment[] = {
    {countof(root_match), root_match},
    {countof(mt8167s_out_mute_gpio_match), mt8167s_out_mute_gpio_match},
};

static const device_fragment_t in_fragments[] = {
    {"i2c", countof(in_i2c_fragment), in_i2c_fragment},
    {"gpio", countof(in_gpio_fragment), in_gpio_fragment},
};
static const device_fragment_t mt8167s_codec_fragments[] = {
    {"i2c", countof(mt8167s_out_i2c_fragment), mt8167s_out_i2c_fragment},
    {"gpio-reset", countof(mt8167s_out_reset_gpio_fragment), mt8167s_out_reset_gpio_fragment},
    {"gpio-mute", countof(mt8167s_out_mute_gpio_fragment), mt8167s_out_mute_gpio_fragment},
};
static const device_fragment_t mt8167s_controller_fragments[] = {
    {"codec", countof(mt8167s_out_codec_fragment), mt8167s_out_codec_fragment},
};
static const device_fragment_t cleo_codec_fragments[] = {
    {"i2c", countof(cleo_out_i2c_fragment), cleo_out_i2c_fragment},
};
static const device_fragment_t cleo_controller_fragments[] = {
    {"codec", countof(cleo_out_codec_fragment), cleo_out_codec_fragment},
};

zx_status_t Mt8167::AudioInit() {
  if (board_info_.pid != PDEV_PID_MEDIATEK_8167S_REF && board_info_.pid != PDEV_PID_CLEO) {
    // We only support the boards listed above.
    return ZX_ERR_NOT_SUPPORTED;
  }
  constexpr pbus_mmio_t mmios[] = {
      {
          .base = MT8167_AUDIO_BASE,
          .length = MT8167_AUDIO_SIZE,
      },
      // MMIO for clocks.
      // TODO(andresoportus): Move this to a clock driver.
      {
          .base = MT8167_XO_BASE,
          .length = MT8167_XO_SIZE,
      },
      {
          .base = MT8167_PLL_BASE,
          .length = MT8167_PLL_SIZE,
      },
  };

  static constexpr pbus_bti_t btis_out[] = {
      {
          .iommu_index = 0,
          .bti_id = BTI_AUDIO_OUT,
      },
  };

  static constexpr pbus_bti_t btis_in[] = {
      {
          .iommu_index = 0,
          .bti_id = BTI_AUDIO_IN,
      },
  };

  metadata::CodecType out_codec =
      metadata::CodecType::Tas5782;  // Default to PDEV_PID_MEDIATEK_8167S_REF.
  if (board_info_.pid == PDEV_PID_CLEO) {
    out_codec = metadata::CodecType::Tas58xx;
  }
  pbus_metadata_t out_metadata[] = {
      {
          .type = DEVICE_METADATA_PRIVATE,
          .data_buffer = &out_codec,
          .data_size = sizeof(out_codec),
      },
  };

  pbus_dev_t controller_out = {};
  controller_out.name = "mt8167-audio-out";
  controller_out.vid = PDEV_VID_MEDIATEK;
  controller_out.pid = PDEV_PID_MEDIATEK_8167S_REF;
  controller_out.did = PDEV_DID_MEDIATEK_AUDIO_OUT;
  controller_out.mmio_list = mmios;
  controller_out.mmio_count = countof(mmios);
  controller_out.bti_list = btis_out;
  controller_out.bti_count = countof(btis_out);
  controller_out.metadata_list = out_metadata;
  controller_out.metadata_count = countof(out_metadata);

  pbus_dev_t dev_in = {};
  dev_in.name = "mt8167-audio-in";
  dev_in.vid = PDEV_VID_MEDIATEK;
  dev_in.pid = PDEV_PID_MEDIATEK_8167S_REF;
  dev_in.did = PDEV_DID_MEDIATEK_AUDIO_IN;
  dev_in.mmio_list = mmios;
  dev_in.mmio_count = countof(mmios);
  dev_in.bti_list = btis_in;
  dev_in.bti_count = countof(btis_in);

  // Output pin assignments.
  // Datasheet has 2 numberings for I2S engines: I2S[0-3] (used in GPIOs) and I2S[1-4] (other
  // registers). 8CH corresponds to I2S2 in the 1-4 range (MtAudioOutDevice::I2S2).
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO25_EINT25, MT8167_GPIO25_I2S2_MCK_FN);
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO55_I2S_DATA_IN, MT8167_GPIO55_I2S_8CH_DO1_FN);
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO56_I2S_LRCK, MT8167_GPIO56_I2S_8CH_LRCK_FN);
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO25_I2S_BCK, MT8167_GPIO57_I2S_8CH_BCK_FN);

  if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
    // ~AMP_RESET.
    gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO107_MSDC1_DAT1, MT8167_GPIO_GPIO_FN);
    gpio_impl_config_out(&gpio_impl_, MT8167_GPIO107_MSDC1_DAT1, 1);  // Set to "not reset".

    // ~AMP_MUTE.
    gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO108_MSDC1_DAT2, MT8167_GPIO_GPIO_FN);
    gpio_impl_config_out(&gpio_impl_, MT8167_GPIO108_MSDC1_DAT2, 1);  // Set to "not mute".
  } else {                                                            // Cleo.
    // From the TAS5805m codec reference manual:
    // "9.5.3.1 Startup Procedures
    // 1. Configure ADR/FAULT pin with proper settings for I2C device address.
    // 2. Bring up power supplies (it does not matter if PVDD or DVDD comes up first).
    // 3. Once power supplies are stable, bring up PDN to High and wait 5ms at least, then
    // start SCLK, LRCLK.
    // 4. Once I2S clocks are stable, set the device into HiZ state and enable DSP via the I2C
    // control port.
    // 5. Wait 5ms at least. Then initialize the DSP Coefficient, then set the device to Play
    // state.
    // 6. The device is now in normal operation."
    // ADR/FAULT is hardwired to VIO18_PMU (always on).
    // PVDD is hardwired to DC_IN.
    // DVDD is hardwired to VIO18_PMU (always on).
    // Step 3 PDN setup and 5ms delay is executed below.
    gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO107_MSDC1_DAT1, MT8167_GPIO_GPIO_FN);
    gpio_impl_config_out(&gpio_impl_, MT8167_GPIO107_MSDC1_DAT1, 1);  // Set PDN to High.
    zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));
    // I2S clocks are configured by the controller and the rest of the initialization is done
    // in the codec itself.
  }

  // Input pin assignments.
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO100_CMDAT0, MT8167_GPIO100_TDM_RX_MCK_FN);
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO101_CMDAT1, MT8167_GPIO101_TDM_RX_BCK_FN);
  if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
    gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO16_EINT16, MT8167_GPIO16_TDM_RX_LRCK_FN);
  } else {
    gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO102_CMMCLK, MT8167_GPIO102_TDM_RX_LRCK_FN);
  }
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO103_CMPCLK, MT8167_GPIO103_TDM_RX_DI_FN);

  // ~ADC_RESET.
  gpio_impl_set_alt_function(&gpio_impl_, MT8167_GPIO24_EINT24, MT8167_GPIO_GPIO_FN);
  gpio_impl_config_out(&gpio_impl_, MT8167_GPIO24_EINT24, 1);  // Set to "not reset".

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_resource(get_root_resource());
  std::optional<ddk::MmioBuffer> pmic_mmio;
  auto status =
      ddk::MmioBuffer::Create(MT8167_PMIC_WRAP_BASE, MT8167_PMIC_WRAP_SIZE, *root_resource,
                              ZX_CACHE_POLICY_UNCACHED_DEVICE, &pmic_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: PMIC MmioBuffer::Create failed %d", __FUNCTION__, status);
    return status;
  }

  // Wait for the PMIC to be IDLE.
  while (WACS2_RDATA::Get().ReadFrom(&(*pmic_mmio)).status() != WACS2_RDATA::kStateIdle) {
  }

  // Set the VCN 1.8 Volts by sending a command to the PMIC via the SOC's PMIC WRAP interface.
  constexpr uint32_t kDigLdoCon11 = 0x0512;
  constexpr uint16_t kVcn18Enable = 0x4001;
  auto pmic = WACS2_CMD::Get().ReadFrom(&(*pmic_mmio));
  // From the documentation "Wrapper access: Address[15:1]" hence the >> 1.
  pmic.set_WACS2_WRITE(1).set_WACS2_ADR(kDigLdoCon11 >> 1).set_WACS2_WDATA(kVcn18Enable);
  pmic.WriteTo(&(*pmic_mmio));

  // Enable clocks. These are needed by both the input and output drivers, so enable them here
  // instead of in those drivers.
  ddk::ClockImplProtocolClient clock = parent();
  if (!clock.is_valid()) {
    zxlogf(ERROR, "%s: could not get CLOCK_IMPL protocol", __func__);
    return ZX_ERR_INTERNAL;
  }
  clock.Enable(kClkRgAud1);
  clock.Enable(kClkRgAud2);

  if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
    constexpr zx_device_prop_t props[] = {{BIND_PLATFORM_DEV_VID, 0, PDEV_VID_TI},
                                          {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_TI_TAS5782}};

    const composite_device_desc_t comp_desc = {
        .props = props,
        .props_count = std::size(props),
        .fragments = mt8167s_codec_fragments,
        .fragments_count = countof(mt8167s_codec_fragments),
        .coresident_device_index = UINT32_MAX,
        .metadata_list = nullptr,
        .metadata_count = 0,
    };

    status = DdkAddComposite("audio-tas5782", &comp_desc);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: DdkAddComposite failed %d", __FUNCTION__, status);
      return status;
    }

    status = pbus_.CompositeDeviceAdd(&controller_out, mt8167s_controller_fragments,
                                      countof(mt8167s_controller_fragments), UINT32_MAX);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: pbus_.CompositeDeviceAdd failed %d", __FUNCTION__, status);
      return status;
    }
  } else {
    bool btl_mode = true;
    const device_metadata_t codec_metadata[] = {
        {
            .type = DEVICE_METADATA_PRIVATE,
            .data = &btl_mode,
            .length = sizeof(btl_mode),
        },
    };
    constexpr zx_device_prop_t props[] = {{BIND_PLATFORM_DEV_VID, 0, PDEV_VID_TI},
                                          {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_TI_TAS58xx}};

    const composite_device_desc_t comp_desc = {
        .props = props,
        .props_count = std::size(props),
        .fragments = cleo_codec_fragments,
        .fragments_count = countof(cleo_codec_fragments),
        .coresident_device_index = UINT32_MAX,
        .metadata_list = codec_metadata,
        .metadata_count = countof(codec_metadata),
    };

    status = DdkAddComposite("audio-tas58xx", &comp_desc);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: DdkAddComposite failed %d", __FUNCTION__, status);
      return status;
    }

    status = pbus_.CompositeDeviceAdd(&controller_out, cleo_controller_fragments,
                                      countof(cleo_controller_fragments), UINT32_MAX);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: pbus_.CompositeDeviceAdd failed %d", __FUNCTION__, status);
      return status;
    }
  }
  status = pbus_.CompositeDeviceAdd(&dev_in, in_fragments, countof(in_fragments), UINT32_MAX);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pbus_.CompositeDeviceAdd failed %d", __FUNCTION__, status);
    return status;
  }
  return ZX_OK;
}

}  // namespace board_mt8167
