blob: 8603f9e6d9bdcbb848d45646086fef15557fdb9e [file] [log] [blame]
// 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 "gpio.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl-async/cpp/bind.h>
#include <ddk/debug.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <mock/ddktl/protocol/gpioimpl.h>
namespace gpio {
class FakeGpio : public GpioDevice {
public:
static std::unique_ptr<FakeGpio> Create(const gpio_impl_protocol_t* proto) {
fbl::AllocChecker ac;
auto device = fbl::make_unique_checked<FakeGpio>(&ac, proto);
if (!ac.check()) {
zxlogf(ERROR, "FakeGpio::Create: device object alloc failed\n");
return nullptr;
}
return device;
}
zx_status_t Connect(async_dispatcher_t* dispatcher, zx::channel request) {
return fidl::BindSingleInFlightOnly(dispatcher, std::move(request), this);
}
explicit FakeGpio(const gpio_impl_protocol_t* gpio_impl)
: GpioDevice(nullptr, const_cast<gpio_impl_protocol_t*>(gpio_impl), 0) {}
};
class GpioTest : public zxtest::Test {
public:
void SetUp() override {
gpio_ = FakeGpio::Create(gpio_impl_.GetProto());
ASSERT_NOT_NULL(gpio_);
loop_ = std::make_unique<async::Loop>(&kAsyncLoopConfigAttachToCurrentThread);
zx::channel server;
ASSERT_OK(zx::channel::create(0, &client_, &server));
ASSERT_OK(loop_->StartThread("gpio-test-loop"));
ASSERT_OK(gpio_->Connect(loop_->dispatcher(), std::move(server)));
}
void TearDown() override {
gpio_impl_.VerifyAndClear();
loop_->Shutdown();
}
protected:
std::unique_ptr<FakeGpio> gpio_;
ddk::MockGpioImpl gpio_impl_;
std::unique_ptr<async::Loop> loop_;
zx::channel client_;
};
TEST_F(GpioTest, TestFidlAll) {
::llcpp::fuchsia::hardware::gpio::Gpio::SyncClient client(std::move(client_));
gpio_impl_.ExpectRead(ZX_OK, 0, 20);
auto result_read = client.Read();
EXPECT_OK(result_read.status());
EXPECT_EQ(result_read->result.response().value, 20);
gpio_impl_.ExpectWrite(ZX_OK, 0, 11);
auto result_write = client.Write(11);
EXPECT_OK(result_write.status());
gpio_impl_.ExpectConfigIn(ZX_OK, 0, 0);
auto result_in = client.ConfigIn(GpioFlags::PULL_DOWN);
EXPECT_OK(result_in.status());
gpio_impl_.ExpectConfigOut(ZX_OK, 0, 5);
auto result_out = client.ConfigOut(5);
EXPECT_OK(result_out.status());
gpio_impl_.ExpectSetDriveStrength(ZX_OK, 0, 2000, 2000);
auto result_drivestrength = client.SetDriveStrength(2000);
EXPECT_OK(result_drivestrength.status());
EXPECT_EQ(result_drivestrength->result.response().actual_ds_ua, 2000);
}
TEST_F(GpioTest, TestBanjoSetDriveStrength) {
uint64_t actual = 0;
gpio_impl_.ExpectSetDriveStrength(ZX_OK, 0, 3000, 3000);
EXPECT_OK(gpio_->GpioSetDriveStrength(3000, &actual));
EXPECT_EQ(actual, 3000);
}
} // namespace gpio