blob: a9a5af283f3002bed16eb8db82a4bca5f7667132 [file] [log] [blame]
// Copyright 2022 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 "i2c_controller.h"
#include <bind/fuchsia/hardware/i2c/cpp/bind.h>
namespace test_i2c_controller {
zx::result<> TestDa7219I2cController::Start() {
node_.Bind(std::move(node()), dispatcher());
i2c_server_ = std::make_shared<I2cDeviceServer>(&logger());
// Serve the fuchsia.hardware.i2c/Device protocol to clients through the
// fuchsia.hardware.i2c/Service wrapper.
fuchsia_hardware_i2c::Service::InstanceHandler handler(
{.device = [this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> request)
-> void {
I2cDeviceServer::BindDeviceClient(i2c_server_, dispatcher(),
std::move(request));
}});
auto result = context().outgoing()->AddService<fuchsia_hardware_i2c::Service>(
std::move(handler));
if (result.is_error()) {
FDF_SLOG(ERROR, "Failed to add service",
KV("status", result.status_string()));
return result.take_error();
}
auto status = AddChild();
if (status.status_value() != ZX_OK) {
return status;
}
return zx::ok();
}
zx::result<> TestDa7219I2cController::AddChild() {
fidl::Arena arena;
// Offer `fuchsia.hardware.i2c.Service` to the driver that binds to the node.
auto offers = fidl::VectorView<fuchsia_component_decl::wire::Offer>(arena, 1);
offers[0] = fdf::MakeOffer<fuchsia_hardware_i2c::Service>(arena, "default");
// Set the properties of the node that a driver will bind to.
auto properties =
fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
properties[0] =
fdf::MakeProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
properties[1] =
fdf::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */,
0x1a /* I2C address used by the DA7219 codec */);
auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
.name(arena, "i2c-child")
.offers(offers)
.properties(properties)
.Build();
// Create endpoints of the `NodeController` for the node.
auto endpoints =
fidl::CreateEndpoints<fuchsia_driver_framework::NodeController>();
if (endpoints.is_error()) {
FDF_SLOG(ERROR, "Failed to create endpoint",
KV("status", endpoints.status_string()));
return zx::error(endpoints.status_value());
}
auto result = node_.sync()->AddChild(args, std::move(endpoints->server), {});
if (!result.ok()) {
FDF_SLOG(ERROR, "Failed to add child",
KV("status", result.status_string()));
return zx::error(result.status());
}
controller_.Bind(std::move(endpoints->client), dispatcher());
return zx::ok();
}
} // namespace test_i2c_controller
FUCHSIA_DRIVER_RECORD_CPP_V2(
fdf::Record<test_i2c_controller::TestDa7219I2cController>);