blob: 3b4d5882799649563a806a6eefacefb66eda0bc4 [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.
#ifndef SRC_DEVICES_BLOCK_DRIVERS_SDMMC_HARDWARE_TEST_SDMMC_TEST_DEVICE_CONTROLLER_H_
#define SRC_DEVICES_BLOCK_DRIVERS_SDMMC_HARDWARE_TEST_SDMMC_TEST_DEVICE_CONTROLLER_H_
#include <fcntl.h>
#include <fidl/fuchsia.hardware.i2c/cpp/wire.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/status.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <array>
#include <fbl/unique_fd.h>
namespace sdmmc {
template <typename T>
fidl::WireSyncClient<T> GetFidlClient(fbl::unique_fd device) {
fidl::ClientEnd<T> client;
zx_status_t status =
fdio_get_service_handle(device.release(), client.channel().reset_and_get_address());
if (status != ZX_OK) {
return {};
}
return fidl::WireSyncClient<T>(std::move(client));
}
template <typename T>
fidl::WireSyncClient<T> GetFidlClient(const char* path) {
fbl::unique_fd device(open(path, O_RDWR));
if (!device.is_valid()) {
return {};
}
return GetFidlClient<T>(std::move(device));
}
class SdmmcTestDeviceController {
public:
SdmmcTestDeviceController() = default;
explicit SdmmcTestDeviceController(fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> i2c)
: i2c_(std::move(i2c)) {}
SdmmcTestDeviceController(SdmmcTestDeviceController&& other) noexcept
: i2c_(std::move(other.i2c_)) {}
SdmmcTestDeviceController& operator=(SdmmcTestDeviceController&& other) noexcept {
i2c_ = std::move(other.i2c_);
return *this;
}
bool is_valid() const { return i2c_.is_valid(); }
zx::status<std::vector<uint8_t>> ReadI2c(const std::vector<uint8_t>& address, uint8_t size);
zx::status<> WriteI2c(const std::vector<uint8_t>& address, const std::vector<uint8_t>& data);
zx::status<std::vector<uint8_t>> ReadReg(uint8_t reg, uint8_t size);
zx::status<uint8_t> ReadReg(uint8_t reg);
zx::status<> WriteReg(uint8_t reg, uint8_t value);
zx::status<std::vector<uint8_t>> ReadFunction(uint8_t function, uint32_t address, uint8_t size);
zx::status<uint8_t> ReadFunction(uint8_t function, uint32_t address);
zx::status<> WriteFunction(uint8_t function, uint32_t address, const std::vector<uint8_t>& data);
// TODO: Register address constant
zx::status<uint8_t> GetCoreVersion() { return ReadReg(0); }
zx::status<std::array<uint8_t, 4>> GetId();
private:
static constexpr uint32_t kMaxFunctionAddress = 0x1'ffff;
static std::vector<uint8_t> FunctionAddressToVector(uint8_t function, uint32_t address);
zx::status<std::vector<uint8_t>> RetryI2cRequest(
const fidl::WireRequest<fuchsia_hardware_i2c::Device2::Transfer>& request);
fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> i2c_;
};
} // namespace sdmmc
#endif // SRC_DEVICES_BLOCK_DRIVERS_SDMMC_HARDWARE_TEST_SDMMC_TEST_DEVICE_CONTROLLER_H_