blob: 06466cde07194e9acf9c0607ff1b8390521fcd25 [file] [log] [blame]
// Copyright 2021 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 "ft_device.h"
#include <fuchsia/hardware/gpio/cpp/banjo-mock.h>
#include <lib/ddk/metadata.h>
#include <lib/fake-i2c/fake-i2c.h>
#include <lib/fake_ddk/fake_ddk.h>
#include <lib/focaltech/focaltech.h>
#include <hid/ft3x27.h>
#include <hid/ft5726.h>
#include <hid/ft6336.h>
#include <zxtest/zxtest.h>
#include "ft_firmware.h"
namespace {
constexpr uint8_t kFirmware0[] = {0x00, 0xd2, 0xc8, 0x53, 0xd5, 0x6b, 0xc0, 0x60, 0x73, 0xd8};
constexpr uint8_t kFirmware1[] = {0x10, 0x58, 0xb2, 0x12, 0xc8, 0xea, 0x5a, 0xca};
constexpr uint8_t kFirmware2[] = {0xb7, 0xf9, 0xd1, 0x12, 0xb0, 0x10, 0x2c, 0xef, 0x98, 0x65};
constexpr uint8_t kFirmware3[] = {0x02, 0x69, 0x96, 0x71, 0x61};
} // namespace
namespace ft {
const FirmwareEntry kFirmwareEntries[] = {
{
.display_vendor = 0,
.ddic_version = 0,
.firmware_data = kFirmware0,
.firmware_size = sizeof(kFirmware0),
},
{
.display_vendor = 1,
.ddic_version = 0,
.firmware_data = kFirmware1,
.firmware_size = sizeof(kFirmware1),
},
{
.display_vendor = 0,
.ddic_version = 1,
.firmware_data = kFirmware2,
.firmware_size = sizeof(kFirmware2),
},
{
.display_vendor = 1,
.ddic_version = 1,
.firmware_data = kFirmware3,
.firmware_size = sizeof(kFirmware3),
},
};
const size_t kNumFirmwareEntries = countof(kFirmwareEntries);
class FakeFtDevice : public fake_i2c::FakeI2c {
protected:
zx_status_t Transact(const uint8_t* write_buffer, size_t write_buffer_size, uint8_t* read_buffer,
size_t* read_buffer_size) override {
return ZX_ERR_NOT_SUPPORTED;
}
};
class FocaltechTest : public zxtest::Test {
public:
void SetUp() override {
fbl::Array<fake_ddk::FragmentEntry> fragments(new fake_ddk::FragmentEntry[3], 3);
fragments[0].name = "i2c";
fragments[0].protocols.push_back(fake_ddk::ProtocolEntry{
.id = ZX_PROTOCOL_I2C,
.proto =
{
.ops = i2c_.GetProto()->ops,
.ctx = i2c_.GetProto()->ctx,
},
});
fragments[1].name = "gpio-int";
fragments[1].protocols.push_back(fake_ddk::ProtocolEntry{
.id = ZX_PROTOCOL_GPIO,
.proto =
{
.ops = interrupt_gpio_.GetProto()->ops,
.ctx = interrupt_gpio_.GetProto()->ctx,
},
});
fragments[2].name = "gpio-reset";
fragments[2].protocols.push_back(fake_ddk::ProtocolEntry{
.id = ZX_PROTOCOL_GPIO,
.proto =
{
.ops = reset_gpio_.GetProto()->ops,
.ctx = reset_gpio_.GetProto()->ctx,
},
});
ddk_.SetFragments(std::move(fragments));
zx::interrupt interrupt;
ASSERT_OK(zx::interrupt::create(zx::resource(), 0, ZX_INTERRUPT_VIRTUAL, &interrupt));
interrupt_gpio_.ExpectConfigIn(ZX_OK, GPIO_NO_PULL)
.ExpectGetInterrupt(ZX_OK, ZX_INTERRUPT_MODE_EDGE_LOW, std::move(interrupt));
reset_gpio_.ExpectConfigOut(ZX_OK, 0).ExpectWrite(ZX_OK, 1);
}
protected:
fake_ddk::Bind ddk_;
private:
FakeFtDevice i2c_;
ddk::MockGpio interrupt_gpio_;
ddk::MockGpio reset_gpio_;
};
TEST_F(FocaltechTest, Metadata3x27) {
constexpr FocaltechMetadata kFt3x27Metadata = {
.device_id = FOCALTECH_DEVICE_FT3X27,
.needs_firmware = false,
};
ddk_.SetMetadata(DEVICE_METADATA_PRIVATE, &kFt3x27Metadata, sizeof(kFt3x27Metadata));
FtDevice dut(nullptr);
EXPECT_OK(dut.Init());
uint8_t actual_descriptor[1024];
size_t actual_size = 0;
EXPECT_OK(dut.HidbusGetDescriptor(0, actual_descriptor, sizeof(actual_descriptor), &actual_size));
const uint8_t* expected_descriptor;
const size_t expected_size = get_ft3x27_report_desc(&expected_descriptor);
ASSERT_EQ(actual_size, expected_size);
EXPECT_BYTES_EQ(actual_descriptor, expected_descriptor, expected_size);
}
TEST_F(FocaltechTest, Metadata5726) {
constexpr FocaltechMetadata kFt5726Metadata = {
.device_id = FOCALTECH_DEVICE_FT5726,
.needs_firmware = false,
};
ddk_.SetMetadata(DEVICE_METADATA_PRIVATE, &kFt5726Metadata, sizeof(kFt5726Metadata));
FtDevice dut(nullptr);
EXPECT_OK(dut.Init());
uint8_t actual_descriptor[1024];
size_t actual_size = 0;
EXPECT_OK(dut.HidbusGetDescriptor(0, actual_descriptor, sizeof(actual_descriptor), &actual_size));
const uint8_t* expected_descriptor;
const size_t expected_size = get_ft5726_report_desc(&expected_descriptor);
ASSERT_EQ(actual_size, expected_size);
EXPECT_BYTES_EQ(actual_descriptor, expected_descriptor, expected_size);
}
TEST_F(FocaltechTest, Metadata6336) {
constexpr FocaltechMetadata kFt6336Metadata = {
.device_id = FOCALTECH_DEVICE_FT6336,
.needs_firmware = false,
};
ddk_.SetMetadata(DEVICE_METADATA_PRIVATE, &kFt6336Metadata, sizeof(kFt6336Metadata));
FtDevice dut(nullptr);
EXPECT_OK(dut.Init());
uint8_t actual_descriptor[1024];
size_t actual_size = 0;
EXPECT_OK(dut.HidbusGetDescriptor(0, actual_descriptor, sizeof(actual_descriptor), &actual_size));
const uint8_t* expected_descriptor;
const size_t expected_size = get_ft6336_report_desc(&expected_descriptor);
ASSERT_EQ(actual_size, expected_size);
EXPECT_BYTES_EQ(actual_descriptor, expected_descriptor, expected_size);
}
TEST_F(FocaltechTest, Firmware5726) {
constexpr FocaltechMetadata kFt5726Metadata = {
.device_id = FOCALTECH_DEVICE_FT5726,
.needs_firmware = true,
.display_vendor = 1,
.ddic_version = 1,
};
ddk_.SetMetadata(DEVICE_METADATA_PRIVATE, &kFt5726Metadata, sizeof(kFt5726Metadata));
FtDevice dut(nullptr);
EXPECT_OK(dut.Init());
}
} // namespace ft