// 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 <lib/mmio/mmio.h>

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

namespace {
constexpr size_t kGpioRegSize = 0x00300000 / sizeof(uint32_t);  // in 32 bits chunks.
}  // namespace

namespace gpio {

class QcomGpioDeviceTest : public QcomGpioDevice {
 public:
  explicit QcomGpioDeviceTest(ddk_mock::MockMmioRegRegion& gpio_regs)
      : QcomGpioDevice(nullptr, gpio_regs.GetMmioBuffer()) {
    // Fake interrupts.
    interrupts_ = fbl::Array(new zx::interrupt[kGpioMax], kGpioMax);
  }
};

TEST(GpioTest, AltMode) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x22000].ExpectRead(0x00000000).ExpectWrite(0x0000003C);  // 4 GpioCfg bits for mode.
  EXPECT_OK(gpio.GpioImplSetAltFunction(0x22, 15));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, NoPull0) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x00000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x00000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 1 GpioCfg bits for OE.
  gpios_mock[0x00000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFC);  // bits 0 to disable pull.
  EXPECT_OK(gpio.GpioImplConfigIn(0, GPIO_NO_PULL));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, NoPullMid) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x43000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x43000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 1 GpioCfg bits for OE.
  gpios_mock[0x43000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFC);  // bits 0 to disable pull.
  EXPECT_OK(gpio.GpioImplConfigIn(0x43, GPIO_NO_PULL));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, NoPullHigh) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x7C000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x7C000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 1 GpioCfg bits for OE.
  gpios_mock[0x7C000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFC);  // bits 0 to disable pull.
  EXPECT_OK(gpio.GpioImplConfigIn(0x7C, GPIO_NO_PULL));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, OutOfRange) {
  ddk_mock::MockMmioRegRegion unused(nullptr, sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(unused);

  EXPECT_EQ(gpio.GpioImplConfigIn(kGpioRegSize, GPIO_NO_PULL), ZX_ERR_INVALID_ARGS);
}

TEST(GpioTest, PullUp) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x21000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x21000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 1 GpioCfg bits for OE.
  gpios_mock[0x21000].ExpectRead(0x00000000).ExpectWrite(0x00000003);  // bits to enable pull up.
  EXPECT_OK(gpio.GpioImplConfigIn(0x21, GPIO_PULL_UP));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, PullDown) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x20000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x20000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 1 GpioCfg bits for OE.
  gpios_mock[0x20000].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // bits to enable pull down.
  EXPECT_OK(gpio.GpioImplConfigIn(0x20, GPIO_PULL_DOWN));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, Out) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x19000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x19000].ExpectRead(0x00000000).ExpectWrite(0x00000200);  // 1 GpioCfg bits for OE.
  gpios_mock[0x19004].ExpectRead(0x00000000).ExpectWrite(0x00000002);  // write 1 to out.
  EXPECT_OK(gpio.GpioImplConfigOut(0x19, 1));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, In) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x44000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFC3);  // 4 GpioCfg bits for mode.
  gpios_mock[0x44000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFDFF);  // 0 GpioCfg bits for OE.
  gpios_mock[0x44000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFC);  // bits 0 to disable pull.
  gpios_mock[0x44004].ExpectRead(0x00000001);                          // read 0x01.
  gpios_mock[0x44004].ExpectRead(0x00000000);                          // read 0x00.
  gpios_mock[0x44004].ExpectRead(0x00000001);                          // read 0x01.
  EXPECT_OK(gpio.GpioImplConfigIn(0x44, GPIO_NO_PULL));
  uint8_t out_value = 0;
  EXPECT_OK(gpio.GpioImplRead(0x44, &out_value));
  EXPECT_EQ(out_value, 0x01);
  EXPECT_OK(gpio.GpioImplRead(0x44, &out_value));
  EXPECT_EQ(out_value, 0x00);
  EXPECT_OK(gpio.GpioImplRead(0x44, &out_value));
  EXPECT_EQ(out_value, 0x01);
  gpios_mock.VerifyAll();
}

TEST(GpioTest, GetInterrupt) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x55008].ExpectRead(0x00000000).ExpectWrite(0x00000008);  // int detect to edge low.
  gpios_mock[0x55008].ExpectRead(0x00000000).ExpectWrite(0x00000002);  // polarity + for any edge.
  gpios_mock[0x55008].ExpectRead(0x00000000).ExpectWrite(0x00000010);  // enable raw status.
  gpios_mock[0x55008].ExpectRead(0x00000000).ExpectWrite(0x00000080);  // route to APPS.
  gpios_mock[0x55008].ExpectRead(0x00000000).ExpectWrite(0x00000001);  // enable.
  zx::interrupt out_int;
  EXPECT_OK(gpio.GpioImplGetInterrupt(0x55, ZX_INTERRUPT_MODE_EDGE_LOW, &out_int));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, ReleaseInterrupt) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x66008].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFEF);  // disable raw status.
  gpios_mock[0x66008].ExpectRead(0x00000000).ExpectWrite(0x000000E0);  // don't route.
  gpios_mock[0x66008].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFE);  // disable.
  EXPECT_OK(gpio.GpioImplReleaseInterrupt(0x66));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, InterruptSetPolarityEdge) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x77008].ExpectRead(0x00000008);                          // edge low.
  gpios_mock[0x77008].ExpectRead(0x00000002);                          // polarity +;
  gpios_mock[0x77008].ExpectRead(0x00000000).ExpectWrite(0x00000004);  // int detect to edge high.
  gpios_mock[0x77008].ExpectRead(0x00000000).ExpectWrite(0x00000002);  // polarity + for any edge.
  gpios_mock[0x77008].ExpectRead(0x00000004);                          // edge high.
  gpios_mock[0x77008].ExpectRead(0x00000002);                          // polarity +;
  gpios_mock[0x77008].ExpectRead(0x00000000).ExpectWrite(0x00000008);  // int detect to edge low.
  gpios_mock[0x77008].ExpectRead(0x00000000).ExpectWrite(0x00000002);  // polarity + for any edge.
  zx::interrupt out_int;
  EXPECT_OK(gpio.GpioImplSetPolarity(0x77, true));
  EXPECT_OK(gpio.GpioImplSetPolarity(0x77, false));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, InterruptSetPolarityLevel) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  gpios_mock[0x88008].ExpectRead(0x00000000);                          // level.
  gpios_mock[0x88008].ExpectRead(0x00000002);                          // polarity +;
  gpios_mock[0x88008].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFF3);  // int detect to level.
  gpios_mock[0x88008].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFFD);  // polarity -.
  gpios_mock[0x88008].ExpectRead(0x00000000);                          // level.
  gpios_mock[0x88008].ExpectRead(0x00000000);                          // polarity -;
  gpios_mock[0x88008].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFFF3);  // int detect to level.
  gpios_mock[0x88008].ExpectRead(0x00000000).ExpectWrite(0x00000002);  // polarity +.
  zx::interrupt out_int;
  EXPECT_OK(gpio.GpioImplSetPolarity(0x88, false));
  EXPECT_OK(gpio.GpioImplSetPolarity(0x88, true));
  gpios_mock.VerifyAll();
}

TEST(GpioTest, SetDriveStrength2) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  uint64_t actual = 0;
  gpios_mock[0x87000].ExpectRead(0xFFFFFFFF).ExpectWrite(0xFFFFFE3F);  // strength to 0x0.
  EXPECT_OK(gpio.GpioImplSetDriveStrength(0x87, 2000, &actual));
  EXPECT_EQ(actual, 2000);
  gpios_mock.VerifyAll();
}

TEST(GpioTest, SetDriveStrength16) {
  fbl::Array<ddk_mock::MockMmioReg> gpio_regs =
      fbl::Array(new ddk_mock::MockMmioReg[kGpioRegSize], kGpioRegSize);
  ddk_mock::MockMmioRegRegion gpios_mock(gpio_regs.data(), sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(gpios_mock);

  uint64_t actual = 0;
  gpios_mock[0x86000].ExpectRead(0x00000000).ExpectWrite(0x000001C0);  // strength to 0x7.
  EXPECT_OK(gpio.GpioImplSetDriveStrength(0x86, 16000, &actual));
  EXPECT_EQ(actual, 16000);
  gpios_mock.VerifyAll();
}

TEST(GpioTest, SetDriveStrengthOdd) {
  ddk_mock::MockMmioRegRegion unused(nullptr, sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(unused);
  EXPECT_NOT_OK(gpio.GpioImplSetDriveStrength(0x85, 1, nullptr));
}

TEST(GpioTest, SetDriveStrengthLarge) {
  ddk_mock::MockMmioRegRegion unused(nullptr, sizeof(uint32_t), kGpioRegSize);
  QcomGpioDeviceTest gpio(unused);
  EXPECT_NOT_OK(gpio.GpioImplSetDriveStrength(0x84, 17, nullptr));
}

}  // namespace gpio

int main(int argc, char** argv) { return RUN_ALL_TESTS(argc, argv); }
