| // 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. |
| driver::ServiceInstanceHandler handler; |
| fuchsia_hardware_i2c::Service::Handler service(&handler); |
| auto result = |
| service.add_device([this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> request) -> void { |
| I2cDeviceServer::BindDeviceClient(i2c_server_, dispatcher(), std::move(request)); |
| }); |
| if (result.is_error()) { |
| return result.take_error(); |
| } |
| 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] = driver::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] = driver::MakeEnumProperty(arena, bind_fuchsia_hardware_i2c::SERVICE, |
| bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT); |
| properties[1] = driver::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(driver::Record<test_i2c_controller::TestDa7219I2cController>); |