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

#include <fbl/alloc_checker.h>
#include <fbl/array.h>
#include <mock-mmio-reg/mock-mmio-reg.h>

namespace {

constexpr size_t kRegSize = 0x00001000 / sizeof(uint32_t);  // in 32 bits chunks.

}  // namespace

namespace spi {

class FakeMtkSpi : public MtkSpi {
 public:
  static std::unique_ptr<FakeMtkSpi> Create(ddk::MmioBuffer mmio) {
    fbl::AllocChecker ac;
    auto device = fbl::make_unique_checked<FakeMtkSpi>(&ac, std::move(mmio));
    if (!ac.check()) {
      zxlogf(ERROR, "%s: device object alloc failed", __func__);
      return nullptr;
    }
    EXPECT_OK(device->Init());

    return device;
  }

  explicit FakeMtkSpi(ddk::MmioBuffer mmio) : MtkSpi(nullptr, std::move(mmio)) {}
};

class MtkSpiTest : public zxtest::Test {
 public:
  void SetUp() override {
    fbl::AllocChecker ac;

    regs_ = fbl::Array(new (&ac) ddk_mock::MockMmioReg[kRegSize], kRegSize);
    if (!ac.check()) {
      zxlogf(ERROR, "%s: regs_ alloc failed", __func__);
      return;
    }
    mock_mmio_ = fbl::make_unique_checked<ddk_mock::MockMmioRegRegion>(&ac, regs_.get(),
                                                                       sizeof(uint32_t), kRegSize);
    if (!ac.check()) {
      zxlogf(ERROR, "%s: mock_mmio_ alloc failed", __func__);
      return;
    }

    (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000004);  // Reset
    (*mock_mmio_)[6 * 4].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFB);
    (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00003000);   // MSB
    (*mock_mmio_)[0 * 4].ExpectRead(0x00000000).ExpectWrite(0x00210021);   // CS
    (*mock_mmio_)[10 * 4].ExpectRead(0x00000000).ExpectWrite(0x00100010);  // SCK
    (*mock_mmio_)[1 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000021);   // Idle
    ddk::MmioBuffer mmio(mock_mmio_->GetMmioBuffer());
    spi_ = FakeMtkSpi::Create(std::move(mmio));
    ASSERT_NOT_NULL(spi_);
  }

  void TearDown() override { mock_mmio_->VerifyAll(); }

 protected:
  std::unique_ptr<FakeMtkSpi> spi_;

  // Mmio Regs and Regions
  fbl::Array<ddk_mock::MockMmioReg> regs_;
  std::unique_ptr<ddk_mock::MockMmioRegRegion> mock_mmio_;
};

TEST_F(MtkSpiTest, Exchange1) {
  uint8_t txdata[8];
  memset(txdata, 0x01, sizeof(txdata));
  uint8_t rxdata[8] = {0};
  size_t actual = 0;

  (*mock_mmio_)[6 * 4].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFF3FF);  // DMA
  (*mock_mmio_)[1 * 4].ExpectRead(0x00000000).ExpectWrite(0x00070000);  // Packet
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);                         // TX Data
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // Activate
  (*mock_mmio_)[8 * 4].ExpectRead(0x00000001);                          // Wait
  (*mock_mmio_)[5 * 4].ExpectRead(0x04030201);                          // RX Data
  (*mock_mmio_)[5 * 4].ExpectRead(0x08070605);
  EXPECT_OK(spi_->SpiImplExchange(0, txdata, sizeof(txdata), rxdata, sizeof(rxdata), &actual));
  EXPECT_EQ(actual, 8);
  uint8_t expected[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  EXPECT_BYTES_EQ(rxdata, expected, sizeof(expected));
}

TEST_F(MtkSpiTest, Exchange2) {
  uint8_t txdata[48];
  memset(txdata, 0x01, sizeof(txdata));
  uint8_t rxdata[48] = {0};
  size_t actual = 0;

  (*mock_mmio_)[6 * 4].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFF3FF);  // DMA
  (*mock_mmio_)[1 * 4].ExpectRead(0x00000000).ExpectWrite(0x001F0000);  // Packet
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);                         // TX Data
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // Activate
  (*mock_mmio_)[8 * 4].ExpectRead(0x00000000);                          // Wait Fail
  (*mock_mmio_)[8 * 4].ExpectRead(0x00000001);                          // Wait Success
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);                          // RX Data
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);

  (*mock_mmio_)[6 * 4].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFF3FF);  // DMA
  (*mock_mmio_)[1 * 4].ExpectRead(0x00000000).ExpectWrite(0x000F0000);  // Packet
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);                         // TX Data
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);
  (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // Activate
  (*mock_mmio_)[8 * 4].ExpectRead(0x00000001);                          // Wait Success
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);                          // RX Data
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);
  EXPECT_OK(spi_->SpiImplExchange(0, txdata, sizeof(txdata), rxdata, sizeof(rxdata), &actual));
  EXPECT_EQ(actual, 48);
  uint8_t expected[48];
  memset(expected, 0x0A, sizeof(expected));
  EXPECT_BYTES_EQ(rxdata, expected, sizeof(expected));
}

TEST_F(MtkSpiTest, Exchange3) {
  uint8_t txdata[7];
  memset(txdata, 0x01, sizeof(txdata));
  uint8_t rxdata[7] = {0};
  size_t actual = 0;

  (*mock_mmio_)[6 * 4].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFF3FF);  // DMA
  (*mock_mmio_)[1 * 4].ExpectRead(0x00000000).ExpectWrite(0x00060000);  // Packet
  (*mock_mmio_)[4 * 4].ExpectWrite(0x01010101);                         // TX Data
  (*mock_mmio_)[4 * 4].ExpectWrite(0x00010101);
  (*mock_mmio_)[6 * 4].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // Activate
  (*mock_mmio_)[8 * 4].ExpectRead(0x00000001);                          // Wait Success
  (*mock_mmio_)[5 * 4].ExpectRead(0x0A0A0A0A);                          // RX Data
  (*mock_mmio_)[5 * 4].ExpectRead(0x0B0A0A0A);

  EXPECT_OK(spi_->SpiImplExchange(0, txdata, sizeof(txdata), rxdata, sizeof(rxdata), &actual));
  EXPECT_EQ(actual, 7);
  uint8_t expected[7];
  memset(expected, 0x0A, sizeof(expected));
  EXPECT_BYTES_EQ(rxdata, expected, sizeof(expected));
}

}  // namespace spi
