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

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/device.h>
#include <ddktl/protocol/platform/bus.h>
#include <fbl/alloc_checker.h>

namespace board_msm8x53 {

zx_status_t Msm8x53::Create(zx_device_t* parent) {
  pbus_protocol_t pbus;

  auto status = device_get_protocol(parent, ZX_PROTOCOL_PBUS, &pbus);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: device_get_protocol failed %d", __func__, status);
    return status;
  }

  pdev_board_info_t board_info;
  status = pbus_get_board_info(&pbus, &board_info);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: GetBoardInfo failed %d", __func__, status);
    return status;
  }

  fbl::AllocChecker ac;
  auto board = fbl::make_unique_checked<Msm8x53>(&ac, parent, &pbus, &board_info);
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  status = board->DdkAdd("msm8x53", DEVICE_ADD_NON_BINDABLE);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: DdkAdd failed %d", __func__, status);
    return status;
  }

  // Start up our protocol helpers and platform devices.
  status = board->Start();
  if (status == ZX_OK) {
    // devmgr is now in charge of the device.
    __UNUSED auto* dummy = board.release();
  }
  return status;
}

int Msm8x53::Thread() {
  if (GpioInit() != ZX_OK) {
    zxlogf(ERROR, "GpioInit() failed");
    return -1;
  }

  if (ClockInit() != ZX_OK) {
    zxlogf(ERROR, "ClockInit failed");
    return -1;
  }

  if (PowerInit() != ZX_OK) {
    zxlogf(ERROR, "PowerInit() failed");
    return -1;
  }

  if (PilInit() != ZX_OK) {
    zxlogf(ERROR, "PilInit() failed");
    return -1;
  }

  if (Sdc1Init() != ZX_OK) {
    zxlogf(ERROR, "Sdc1Init() failed");
    return -1;
  }
  return 0;
}

zx_status_t Msm8x53::Start() {
  auto cb = [](void* arg) -> int { return reinterpret_cast<Msm8x53*>(arg)->Thread(); };
  auto rc = thrd_create_with_name(&thread_, cb, this, "msm8x53-start-thread");
  if (rc != thrd_success) {
    return ZX_ERR_INTERNAL;
  }
  return ZX_OK;
}

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

zx_status_t msm8x53_bind(void* ctx, zx_device_t* parent) {
  return board_msm8x53::Msm8x53::Create(parent);
}

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

}  // namespace board_msm8x53

ZIRCON_DRIVER_BEGIN(msm8x53, board_msm8x53::driver_ops, "zircon", "0.1", 3)
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_QUALCOMM),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_QUALCOMM_MSM8X53), ZIRCON_DRIVER_END(msm8x53)
