// 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 "qcom-gpio.h"

#include <algorithm>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <fbl/alloc_checker.h>
#include <fbl/array.h>

namespace {

uint64_t kPortKeyIrqMsg = 0x00;
uint64_t kPortKeyTerminate = 0x01;

}  // namespace

namespace gpio {

int QcomGpioDevice::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", __func__, status);
      return thrd_error;
    }
    zxlogf(DEBUG, "%s msg on port key %lu", __func__, packet.key);
    if (packet.key == kPortKeyTerminate) {
      zxlogf(INFO, "QCOM GPIO thread terminating");
      return 0;
    }
    size_t index = 0;
    status = enabled_ints_cache_.Find(true, 0, kGpioMax, 1, &index);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s no interrupt found in cache %d", __func__, status);
    }
    while (status == ZX_OK) {
      zxlogf(DEBUG, "%s msg on port INT %lu", __func__, index);
      if (status_int_.Status(index)) {
        status = interrupts_[index].trigger(0, zx::time(packet.interrupt.timestamp));
        if (status != ZX_OK) {
          zxlogf(ERROR, "%s zx_interrupt_trigger failed %d", __func__, status);
        }
        status_int_.Clear(index);
      } else {
        zxlogf(ERROR, "%s interrupt %lu not enabled in reg", __func__, index);
      }
      status = enabled_ints_cache_.Find(true, index + 1, kGpioMax, 1, &index);
      if (status != ZX_ERR_NO_RESOURCES) {  // not just not-found in cache.
        zxlogf(ERROR, "%s error in reading from cache %d", __func__, status);
      }
    }
    combined_int_.ack();
  }
}

zx_status_t QcomGpioDevice::GpioImplConfigIn(uint32_t index, uint32_t flags) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  GpioCfgReg::SetMode(&gpio_mmio_, index, GpioCfgReg::kModeGpio);
  GpioCfgReg::SetOut(&gpio_mmio_, index, false);
  const uint32_t pull_mode = flags & GPIO_PULL_MASK;

  // clang-format off
    switch (pull_mode) {
    case GPIO_NO_PULL:   GpioCfgReg::SetPullNone(&gpio_mmio_, index); break;
    case GPIO_PULL_DOWN: GpioCfgReg::SetPullDown(&gpio_mmio_, index); break;
    case GPIO_PULL_UP:   GpioCfgReg::SetPullUp  (&gpio_mmio_, index); break;
    default: return ZX_ERR_NOT_SUPPORTED;
    }
  // clang-format on
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplConfigOut(uint32_t index, uint8_t initial_value) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  GpioCfgReg::SetMode(&gpio_mmio_, index, GpioCfgReg::kModeGpio);
  GpioCfgReg::SetOut(&gpio_mmio_, index, true);
  return GpioImplWrite(index, initial_value);
}

zx_status_t QcomGpioDevice::GpioImplSetAltFunction(uint32_t index, uint64_t function) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (function >= GpioCfgReg::kModeMax) {
    return ZX_ERR_OUT_OF_RANGE;
  }
  GpioCfgReg::SetMode(&gpio_mmio_, index, static_cast<uint32_t>(function));
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplSetDriveStrength(uint32_t index, uint64_t ua,
                                                     uint64_t* out_actual_ua) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  uint64_t supported_uas[] = {2000, 4000, 6000, 8000, 10000, 12000, 14000, 16000};
  if (std::find(std::begin(supported_uas), std::end(supported_uas), ua) ==
      std::end(supported_uas)) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  GpioCfgReg::SetStrength(&gpio_mmio_, index, static_cast<uint8_t>(ua / 1000));
  if (out_actual_ua) {
    *out_actual_ua = ua;
  }
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplRead(uint32_t index, uint8_t* out_value) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  *out_value = static_cast<uint8_t>(in_out_.GetVal(index));
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplWrite(uint32_t index, uint8_t value) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  in_out_.SetVal(index, value);
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplGetInterrupt(uint32_t index, uint32_t flags,
                                                 zx::interrupt* out_irq) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx::interrupt irq;
  auto status = zx::interrupt::create(zx::resource(), index, ZX_INTERRUPT_VIRTUAL, &irq);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s zx::interrupt::create failed %d", __func__, status);
    return status;
  }
  status = irq.duplicate(ZX_RIGHT_SAME_RIGHTS, out_irq);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s interrupt.duplicate failed %d", __func__, status);
    return status;
  }

  // clang-format off
    switch (flags & ZX_INTERRUPT_MODE_MASK) {
    case ZX_INTERRUPT_MODE_EDGE_LOW:   int_cfg_.SetMode(index, Mode::EdgeLow);   break;
    case ZX_INTERRUPT_MODE_EDGE_HIGH:  int_cfg_.SetMode(index, Mode::EdgeHigh);  break;
    case ZX_INTERRUPT_MODE_LEVEL_LOW:  int_cfg_.SetMode(index, Mode::LevelLow);  break;
    case ZX_INTERRUPT_MODE_LEVEL_HIGH: int_cfg_.SetMode(index, Mode::LevelHigh); break;
    case ZX_INTERRUPT_MODE_EDGE_BOTH:  int_cfg_.SetMode(index, Mode::EdgeDual);  break;
    default: return ZX_ERR_INVALID_ARGS;
    }
  // clang-format on

  interrupts_[index] = std::move(irq);
  // TODO(andresoportus): Once we define which cases would use them, enable direct interrupts
  // (via TlmmDirConnIntReg).
  status_int_.Clear(index);
  int_cfg_.EnableCombined(index, true);
  enabled_ints_cache_.SetOne(index);
  zxlogf(DEBUG, "%s INT %u enabled", __func__, index);
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplReleaseInterrupt(uint32_t index) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  interrupts_[index].destroy();
  interrupts_[index].reset();
  int_cfg_.EnableCombined(index, false);
  enabled_ints_cache_.ClearOne(index);
  zxlogf(DEBUG, "%s INT %u disabled", __func__, index);
  return ZX_OK;
}

zx_status_t QcomGpioDevice::GpioImplSetPolarity(uint32_t index, uint32_t polarity) {
  if (index >= kGpioMax) {
    return ZX_ERR_INVALID_ARGS;
  }
  int_cfg_.SetPolarity(index, static_cast<bool>(polarity));
  return ZX_OK;
}

void QcomGpioDevice::ShutDown() {
  combined_int_.destroy();
  zx_port_packet packet = {kPortKeyTerminate, ZX_PKT_TYPE_USER, ZX_OK, {}};
  auto status = port_.queue(&packet);
  ZX_ASSERT(status == ZX_OK);
  thrd_join(thread_, NULL);
}

void QcomGpioDevice::DdkUnbind(ddk::UnbindTxn txn) {
  ShutDown();
  txn.Reply();
}

void QcomGpioDevice::DdkRelease() { delete this; }

zx_status_t QcomGpioDevice::Bind() {
  auto status = pdev_.GetInterrupt(0, &combined_int_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s GetInterrupt failed %d", __func__, status);
    return status;
  }

  status = zx::port::create(ZX_PORT_BIND_TO_INTERRUPT, &port_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s port create failed %d", __func__, status);
    return status;
  }

  status = combined_int_.bind(port_, kPortKeyIrqMsg, 0 /*options*/);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s interrupt bind failed %d", __func__, status);
    return status;
  }

  fbl::AllocChecker ac;
  interrupts_ = fbl::Array(new (&ac) zx::interrupt[kGpioMax], kGpioMax);
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

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

  status = DdkAdd("qcom-gpio");
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s DdkAdd failed %d", __func__, status);
    ShutDown();
    return status;
  }
  return ZX_OK;
}

zx_status_t QcomGpioDevice::Init() {
  pbus_protocol_t pbus;
  auto status = device_get_protocol(parent(), ZX_PROTOCOL_PBUS, &pbus);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: ZX_PROTOCOL_PBUS not available %d", __func__, status);
    return status;
  }
  gpio_impl_protocol_t gpio_proto = {
      .ops = &gpio_impl_protocol_ops_,
      .ctx = this,
  };
  status = pbus_register_protocol(&pbus, ZX_PROTOCOL_GPIO_IMPL,
                                  reinterpret_cast<uint8_t*>(&gpio_proto), sizeof(gpio_proto));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s pbus_register_protocol failed %d", __func__, status);
    ShutDown();
    return status;
  }
  return enabled_ints_cache_.Reset(kGpioMax);  // Clear and resize.
}

zx_status_t QcomGpioDevice::Create(zx_device_t* parent) {
  pdev_protocol_t pdev;
  zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s ZX_PROTOCOL_PDEV not available %d", __func__, status);
    return status;
  }

  mmio_buffer_t gpio_mmio;
  status = pdev_map_mmio_buffer(&pdev, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &gpio_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s gpio pdev_map_mmio_buffer failed %d", __func__, status);
    return status;
  }

  fbl::AllocChecker ac;
  auto dev =
      fbl::make_unique_checked<gpio::QcomGpioDevice>(&ac, parent, ddk::MmioBuffer(gpio_mmio));
  if (!ac.check()) {
    zxlogf(ERROR, "qcom_gpio_bind: ZX_ERR_NO_MEMORY");
    return ZX_ERR_NO_MEMORY;
  }
  status = dev->Bind();
  if (status != ZX_OK) {
    return status;
  }

  // devmgr is now in charge of the memory for dev
  auto ptr = dev.release();
  return ptr->Init();
}

zx_status_t qcom_gpio_bind(void* ctx, zx_device_t* parent) {
  return gpio::QcomGpioDevice::Create(parent);
}

}  // namespace gpio
