// 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 <fidl/fuchsia.hardware.platform.bus/cpp/driver/fidl.h>
#include <fidl/fuchsia.hardware.platform.bus/cpp/fidl.h>
#include <fidl/fuchsia.scheduler/cpp/fidl.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/ddk/metadata.h>
#include <lib/ddk/platform-defs.h>

#include <ddk/metadata/gpio.h>
#include <soc/aml-s905d3/s905d3-gpio.h>
#include <soc/aml-s905d3/s905d3-hw.h>

#include "nelson-gpios.h"
#include "nelson.h"

// uncomment to disable LED blinky test
// #define GPIO_TEST

namespace {

constexpr char kGpioHSchedulerRole[] = "fuchsia.devices.gpio.drivers.aml-gpio.gpioh";

}  // namespace

namespace nelson {
namespace fpbus = fuchsia_hardware_platform_bus;

static const std::vector<fpbus::Mmio> gpio_mmios{
    {{
        .base = S905D3_GPIO_BASE,
        .length = S905D3_GPIO_LENGTH,
    }},
    {{
        .base = S905D3_GPIO_AO_BASE,
        .length = S905D3_GPIO_AO_LENGTH,
    }},
    {{
        .base = S905D3_GPIO_INTERRUPT_BASE,
        .length = S905D3_GPIO_INTERRUPT_LENGTH,
    }},
};

static const std::vector<fpbus::Irq> gpio_irqs{
    {{
        .irq = S905D3_GPIO_IRQ_0,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_1,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_2,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_3,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_4,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_5,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_6,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
    {{
        .irq = S905D3_GPIO_IRQ_7,
        .mode = ZX_INTERRUPT_MODE_DEFAULT,
    }},
};

// GPIOs to expose from generic GPIO driver. Do not expose C bank or H bank GPIOs here, as they are
// managed by separate devices below. The three GPIO devices are not capable of synchronizing
// accesses to the interrupt registers, so C and H bank GPIOs that are used for interrupts must be
// exposed by the main device (only GPIO_SOC_SELINA_IRQ_OUT and GPIO_TH_SOC_INT). All pins can be
// used in calls from the board driver, regardless of bank.
static const gpio_pin_t gpio_pins[] = {
    DECL_GPIO_PIN(GPIO_INRUSH_EN_SOC),
    DECL_GPIO_PIN(GPIO_SOC_I2S_SCLK),
    DECL_GPIO_PIN(GPIO_SOC_I2S_FS),
    DECL_GPIO_PIN(GPIO_SOC_I2S_DO0),
    DECL_GPIO_PIN(GPIO_SOC_I2S_DIN0),
    DECL_GPIO_PIN(GPIO_SOC_AUDIO_EN),
    DECL_GPIO_PIN(GPIO_SOC_MIC_DCLK),
    DECL_GPIO_PIN(GPIO_SOC_MICLR_DIN0),
    DECL_GPIO_PIN(GPIO_SOC_MICLR_DIN1),
    DECL_GPIO_PIN(GPIO_SOC_BKL_EN),
    DECL_GPIO_PIN(GPIO_AUDIO_SOC_FAULT_L),
    DECL_GPIO_PIN(GPIO_SOC_TH_RST_L),
    DECL_GPIO_PIN(GPIO_SOC_AV_I2C_SDA),
    DECL_GPIO_PIN(GPIO_SOC_AV_I2C_SCL),
    DECL_GPIO_PIN(GPIO_HW_ID_3),
    DECL_GPIO_PIN(GPIO_SOC_TH_BOOT_MODE_L),
    DECL_GPIO_PIN(GPIO_MUTE_SOC),
    DECL_GPIO_PIN(GPIO_HW_ID_2),
    DECL_GPIO_PIN(GPIO_TOUCH_SOC_INT_L),
    DECL_GPIO_PIN(GPIO_VOL_UP_L),
    DECL_GPIO_PIN(GPIO_VOL_DN_L),
    DECL_GPIO_PIN(GPIO_HW_ID_0),
    DECL_GPIO_PIN(GPIO_HW_ID_1),
    DECL_GPIO_PIN(GPIO_SOC_TOUCH_RST_L),
    DECL_GPIO_PIN(GPIO_ALERT_PWR_L),
    DECL_GPIO_PIN(GPIO_DISP_SOC_ID0),
    DECL_GPIO_PIN(GPIO_DISP_SOC_ID1),
    DECL_GPIO_PIN(GPIO_SOC_DISP_RST_L),
    DECL_GPIO_PIN(GPIO_SOC_TOUCH_I2C_SDA),
    DECL_GPIO_PIN(GPIO_SOC_TOUCH_I2C_SCL),
    // ot-radio is responsible for not making concurrent calls to this GPIO and the GPIO C device
    // (or other clients of that device, namely SPI0). Calls may be made on the interrupt object
    // (and interrupts may be received) at any time, as there is no GPIO driver involvement in that
    // case.
    DECL_GPIO_PIN(GPIO_TH_SOC_INT),
    DECL_GPIO_PIN(GPIO_SOC_TH_INT),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_D0),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_D1),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_D2),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_D3),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_CLK),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_SDIO_CMD),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_REG_ON),
    DECL_GPIO_PIN(GPIO_WIFI_SOC_WAKE),
    DECL_GPIO_PIN(GPIO_SOC_BT_PCM_IN),
    DECL_GPIO_PIN(GPIO_SOC_BT_PCM_OUT),
    DECL_GPIO_PIN(GPIO_SOC_BT_PCM_SYNC),
    DECL_GPIO_PIN(GPIO_SOC_BT_PCM_CLK),
    DECL_GPIO_PIN(GPIO_SOC_BT_UART_TX),
    DECL_GPIO_PIN(GPIO_SOC_BT_UART_RX),
    DECL_GPIO_PIN(GPIO_SOC_BT_UART_CTS),
    DECL_GPIO_PIN(GPIO_SOC_BT_UART_RTS),
    DECL_GPIO_PIN(GPIO_SOC_WIFI_LPO_32K768),
    DECL_GPIO_PIN(GPIO_SOC_BT_REG_ON),
    DECL_GPIO_PIN(GPIO_BT_SOC_WAKE),
    DECL_GPIO_PIN(GPIO_SOC_BT_WAKE),
    // Like above -- Selina is responsible for not making current calls to this GPIO and the GPIO H
    // device (or SPI1, which is a client of the GPIO H device).
    DECL_GPIO_PIN(GPIO_SOC_SELINA_IRQ_OUT),
    DECL_GPIO_PIN(GPIO_SOC_DEBUG_UARTAO_TX),
    DECL_GPIO_PIN(GPIO_SOC_DEBUG_UARTAO_RX),
    DECL_GPIO_PIN(GPIO_SOC_SENSORS_I2C_SCL),
    DECL_GPIO_PIN(GPIO_SOC_SENSORS_I2C_SDA),
    DECL_GPIO_PIN(GPIO_HW_ID_4),
    DECL_GPIO_PIN(GPIO_RGB_SOC_INT_L),
    DECL_GPIO_PIN(GPIO_SOC_JTAG_TCK),
    DECL_GPIO_PIN(GPIO_SOC_JTAG_TMS),
    DECL_GPIO_PIN(GPIO_SOC_JTAG_TDI),
    DECL_GPIO_PIN(GPIO_SOC_JTAG_TDO),
    DECL_GPIO_PIN(GPIO_FDR_L),
    DECL_GPIO_PIN(GPIO_AMBER_LED_PWM),
    DECL_GPIO_PIN(GPIO_SOC_VDDEE_PWM),
    DECL_GPIO_PIN(GPIO_SOC_VDDCPU_PWM),
    DECL_GPIO_PIN(SOC_EMMC_D0),
    DECL_GPIO_PIN(SOC_EMMC_D1),
    DECL_GPIO_PIN(SOC_EMMC_D2),
    DECL_GPIO_PIN(SOC_EMMC_D3),
    DECL_GPIO_PIN(SOC_EMMC_D4),
    DECL_GPIO_PIN(SOC_EMMC_D5),
    DECL_GPIO_PIN(SOC_EMMC_D6),
    DECL_GPIO_PIN(SOC_EMMC_D7),
    DECL_GPIO_PIN(SOC_EMMC_CLK),
    DECL_GPIO_PIN(SOC_EMMC_CMD),
    DECL_GPIO_PIN(SOC_EMMC_RST_L),
    DECL_GPIO_PIN(SOC_EMMC_DS),
};

// The GPIO H device won't be able to provide interrupts for the pins it exposes, so
// GPIO_SOC_SELINA_IRQ_OUT must be be exposed by the main GPIO device (see the list of pins above)
// instead of this one.
static const gpio_pin_t gpio_h_pins[] = {
    DECL_GPIO_PIN(GPIO_SOC_SELINA_RESET), DECL_GPIO_PIN(GPIO_SOC_SPI_B_MOSI),
    DECL_GPIO_PIN(GPIO_SOC_SPI_B_MISO),   DECL_GPIO_PIN(GPIO_SOC_SPI_B_SS0),
    DECL_GPIO_PIN(GPIO_SOC_SPI_B_SCLK),   DECL_GPIO_PIN(GPIO_SOC_SELINA_OSC_EN)};

static const gpio_pin_t gpio_c_pins[] = {
    DECL_GPIO_PIN(GPIO_SOC_SPI_A_MISO),
    DECL_GPIO_PIN(GPIO_SOC_SPI_A_MOSI),
    DECL_GPIO_PIN(GPIO_SOC_SPI_A_SCLK),
    DECL_GPIO_PIN(GPIO_SOC_SPI_A_SS0),
};

static const std::vector<fpbus::Metadata> gpio_c_metadata{
    {{
        .type = DEVICE_METADATA_GPIO_PINS,
        .data = std::vector<uint8_t>(
            reinterpret_cast<const uint8_t*>(&gpio_c_pins),
            reinterpret_cast<const uint8_t*>(&gpio_c_pins) + sizeof(gpio_c_pins)),
    }},
};

static const fpbus::Node gpio_c_dev = []() {
  fpbus::Node dev = {};
  dev.name() = "gpio-c";
  dev.vid() = PDEV_VID_AMLOGIC;
  dev.pid() = PDEV_PID_AMLOGIC_S905D3;
  dev.did() = PDEV_DID_AMLOGIC_GPIO;
  dev.instance_id() = 2;
  dev.mmio() = gpio_mmios;
  dev.metadata() = gpio_c_metadata;
  return dev;
}();

zx_status_t Nelson::GpioInit() {
  // Enable mute LED so it will be controlled by mute switch.
  gpio_init_steps_.push_back({GPIO_AMBER_LED_PWM, GpioConfigOut(1)});

  fuchsia_hardware_gpioimpl::wire::InitMetadata metadata;
  metadata.steps = fidl::VectorView<fuchsia_hardware_gpioimpl::wire::InitStep>::FromExternal(
      gpio_init_steps_.data(), gpio_init_steps_.size());

  const fit::result encoded_metadata = fidl::Persist(metadata);
  if (!encoded_metadata.is_ok()) {
    zxlogf(ERROR, "Failed to encode GPIO init metadata: %s",
           encoded_metadata.error_value().FormatDescription().c_str());
    return encoded_metadata.error_value().status();
  }

  const std::vector<fpbus::Metadata> gpio_metadata{
      {{
          .type = DEVICE_METADATA_GPIO_PINS,
          .data = std::vector<uint8_t>(
              reinterpret_cast<const uint8_t*>(&gpio_pins),
              reinterpret_cast<const uint8_t*>(&gpio_pins) + sizeof(gpio_pins)),
      }},
      {{
          .type = DEVICE_METADATA_GPIO_INIT,
          .data = encoded_metadata.value(),
      }},
  };

  fpbus::Node gpio_dev;
  gpio_dev.name() = "gpio";
  gpio_dev.vid() = PDEV_VID_AMLOGIC;
  gpio_dev.pid() = PDEV_PID_AMLOGIC_S905D3;
  gpio_dev.did() = PDEV_DID_AMLOGIC_GPIO;
  gpio_dev.mmio() = gpio_mmios;
  gpio_dev.irq() = gpio_irqs;
  gpio_dev.metadata() = gpio_metadata;

  fidl::Arena<> fidl_arena;
  fdf::Arena arena('GPIO');
  auto result = pbus_.buffer(arena)->NodeAdd(fidl::ToWire(fidl_arena, gpio_dev));
  if (!result.ok()) {
    zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_dev) request failed: %s", __func__,
           result.FormatDescription().data());
    return result.status();
  }
  if (result->is_error()) {
    zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_dev) failed: %s", __func__,
           zx_status_get_string(result->error_value()));
    return result->error_value();
  }

  const fuchsia_scheduler::RoleName role(kGpioHSchedulerRole);

  fit::result role_metadata = fidl::Persist(role);
  if (role_metadata.is_error()) {
    zxlogf(ERROR, "Failed to persist scheduler role: %s",
           role_metadata.error_value().FormatDescription().c_str());
    return role_metadata.error_value().status();
  }

  const std::vector<fpbus::Metadata> gpio_h_metadata{
      {{
          .type = DEVICE_METADATA_GPIO_PINS,
          .data = std::vector<uint8_t>(
              reinterpret_cast<const uint8_t*>(&gpio_h_pins),
              reinterpret_cast<const uint8_t*>(&gpio_h_pins) + sizeof(gpio_h_pins)),
      }},
      {{
          .type = DEVICE_METADATA_SCHEDULER_ROLE_NAME,
          .data = role_metadata.value(),
      }},
  };

  const fpbus::Node gpio_h_dev = [&gpio_h_metadata]() {
    fpbus::Node dev = {};
    dev.name() = "gpio-h";
    dev.vid() = PDEV_VID_AMLOGIC;
    dev.pid() = PDEV_PID_AMLOGIC_S905D3;
    dev.did() = PDEV_DID_AMLOGIC_GPIO;
    dev.instance_id() = 1;
    dev.mmio() = gpio_mmios;
    dev.metadata() = gpio_h_metadata;
    return dev;
  }();

  {
    auto result = pbus_.buffer(arena)->NodeAdd(fidl::ToWire(fidl_arena, gpio_h_dev));
    if (!result.ok()) {
      zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_h_dev) request failed: %s", __func__,
             result.FormatDescription().data());
      return result.status();
    }
    if (result->is_error()) {
      zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_h_dev) failed: %s", __func__,
             zx_status_get_string(result->error_value()));
      return result->error_value();
    }
  }

  {
    auto result = pbus_.buffer(arena)->NodeAdd(fidl::ToWire(fidl_arena, gpio_c_dev));
    if (!result.ok()) {
      zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_c_dev) request failed: %s", __func__,
             result.FormatDescription().data());
      return result.status();
    }
    if (result->is_error()) {
      zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_c_dev) failed: %s", __func__,
             zx_status_get_string(result->error_value()));
      return result->error_value();
    }
  }

#ifdef GPIO_TEST
  static const std::vector<fpbus::Gpio> gpio_test_gpios{
      {{
          // SYS_LED
          .gpio = GPIO_AMBER_LED_PWM,
      }},
      {{
          // JTAG Adapter Pin
          .gpio = GPIO_SOC_JTAG_TCK,
      }},
  };

  fpbus::Node gpio_test_dev;
  gpio_test_dev.name() = "nelson-gpio-test";
  gpio_test_dev.vid() = PDEV_VID_GENERIC;
  gpio_test_dev.pid() = PDEV_PID_GENERIC;
  gpio_test_dev.did() = PDEV_DID_GPIO_TEST;
  gpio_test_dev.gpio() = gpio_test_gpios;

  result = pbus_.buffer(arena)->NodeAdd(fidl::ToWire(fidl_arena, gpio_test_dev));
  if (!result.ok()) {
    zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_test_dev) request failed: %s", __func__,
           result.FormatDescription().data());
    return result.status();
  }
  if (result->is_error()) {
    zxlogf(ERROR, "%s: NodeAdd Gpio(gpio_test_dev) failed: %s", __func__,
           zx_status_get_string(result->error_value()));
    return result->error_value();
  }
#endif

  return ZX_OK;
}

}  // namespace nelson
