blob: fd47d537afaa4fd8c1f138ed9c1f2404b0482b4c [file] [log] [blame]
// Copyright 2024 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.
use fdf_component::{Driver, DriverContext, Node, NodeBuilder, ServiceInstance, driver_register};
use fidl_next_fuchsia_hardware_i2cimpl as i2cimpl;
use log::{error, info};
use zx::Status;
/// The implementation of our driver will live in this object, which implements [`Driver`].
#[allow(unused)]
struct DriverTransportChild {
/// The [`Node`] is our handle to the node we bound to. We need to keep this handle
/// open to keep the node around.
node: Node,
}
// This creates the exported driver registration structures that allow the driver host to
// find and run the start and stop methods on our `DriverTransportChild`.
driver_register!(DriverTransportChild);
impl Driver for DriverTransportChild {
const NAME: &str = "driver_child_rust_next_driver";
async fn start(mut context: DriverContext) -> Result<Self, Status> {
info!(
"Binding node client. Every driver needs to do this for the driver to be considered loaded."
);
let node = context.take_node()?;
let device = get_i2cimpl_device(&context).unwrap().spawn();
let transfer_size = device.get_max_transfer_size().await.unwrap().unwrap().size;
info!("i2cimpl max transfer size: {transfer_size}");
info!("Adding child node with i2cimpl max transfer size as a property value");
let child_node = NodeBuilder::new("transport-child")
.add_property(bind_fuchsia_test::TEST_CHILD, u64::from(transfer_size) as u32)
.build();
node.add_child(child_node).await?;
device.set_bitrate(0x5u32).await.unwrap().unwrap();
Ok(Self { node })
}
async fn stop(&self) {
info!(
"DriverTransportChild::stop() was invoked. Use this function to do any cleanup needed."
);
}
}
fn get_i2cimpl_device(
context: &DriverContext,
) -> Result<fidl_next::ClientEnd<i2cimpl::Device, fdf_fidl::DriverChannel>, Status> {
let service_proxy: ServiceInstance<i2cimpl::Service> =
context.incoming.service().connect_next()?;
let (client_end, server_end) = fdf_fidl::create_channel();
service_proxy.device(server_end).map_err(|err| {
error!("Error connecting to i2cimpl device proxy at driver startup: {err}");
Status::INTERNAL
})?;
Ok(client_end)
}