[acpi_multiply] Organize components into modules

Separate driver components and libraries into individual directories.
Add method comments, clean up imports, and include a README.

Change-Id: If992d4a66fc4678d8f58f5782dabce23f7b8757b
Reviewed-on: https://fuchsia-review.googlesource.com/c/sdk-samples/drivers/+/712342
Reviewed-by: Simon Shields <simonshields@google.com>
Commit-Queue: Dave Smith <smithdave@google.com>
Reviewed-by: Suraj Malhotra <surajmalhotra@google.com>
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 72e4ab0..8135d79 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -12,8 +12,8 @@
     testonly = True,
     repo_name = "fuchsiasamples.com",
     deps = [
-        "//src/acpi_multiply:test_implementation_pkg",
-        "//src/acpi_multiply:pkg",
+        "//src/acpi_multiply/controller:pkg",
+        "//src/acpi_multiply/driver:pkg",
         "//src/bind_library:child_pkg",
         "//src/bind_library:parent_pkg",
         "//src/composite_sample:pkg",
diff --git a/src/acpi_multiply/BUILD.bazel b/src/acpi_multiply/BUILD.bazel
deleted file mode 100644
index ef3c7c5..0000000
--- a/src/acpi_multiply/BUILD.bazel
+++ /dev/null
@@ -1,143 +0,0 @@
-# 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.
-
-load(
-    "@rules_fuchsia//fuchsia:defs.bzl",
-    "fuchsia_cc_binary",
-    "fuchsia_component_manifest",
-    "fuchsia_driver_bytecode_bind_rules",
-    "fuchsia_driver_component",
-    "fuchsia_fidl_library",
-    "fuchsia_fidl_llcpp_library",
-    "fuchsia_package",
-)
-
-fuchsia_fidl_library(
-    name = "sample.acpi.multiply",
-    srcs = [
-        "acpi_multiply.fidl",
-    ],
-    library = "sample.acpi.multiply",
-    visibility = ["//visibility:public"],
-    deps = [
-        "@fuchsia_sdk//fidl/zx",
-    ],
-)
-
-fuchsia_fidl_llcpp_library(
-    name = "sample.acpi.multiply_cc",
-    library = ":sample.acpi.multiply",
-    visibility = ["//visibility:public"],
-    deps = [
-        "@fuchsia_sdk//fidl/zx:zx_llcpp_cc",
-        "@fuchsia_sdk//pkg/fidl_cpp_wire",
-    ],
-)
-
-fuchsia_driver_bytecode_bind_rules(
-    name = "bind_bytecode",
-    output = "acpi_multiply.bindbc",
-    rules = "acpi_multiply.bind",
-    deps = [
-        "@fuchsia_sdk//bind/fuchsia.acpi",
-    ],
-)
-
-cc_binary(
-    name = "acpi_multiply",
-    srcs = [
-        "registers.h",
-        "acpi_multiply.cc",
-        "acpi_multiply.h",
-    ],
-    linkshared = True,
-    deps = [
-        ":sample.acpi.multiply_cc",
-        "@fuchsia_sdk//fidl/fuchsia.hardware.acpi:fuchsia.hardware.acpi_llcpp_cc",
-        "@fuchsia_sdk//fidl/zx:zx_cc",
-        "@fuchsia_sdk//pkg/async-cpp",
-        "@fuchsia_sdk//pkg/mmio",
-        "@fuchsia_sdk//pkg/hwreg",
-        "@fuchsia_sdk//pkg/driver2-llcpp",
-        "@fuchsia_sdk//pkg/fidl_cpp_wire",
-        "@fuchsia_sdk//pkg/sys_component_llcpp",
-        "@fuchsia_sdk//pkg/zx",
-    ],
-)
-
-fuchsia_component_manifest(
-    name = "manifest",
-    src = "meta/acpi_multiply.cml",
-)
-
-fuchsia_driver_component(
-    name = "component",
-    bind_bytecode = ":bind_bytecode",
-    driver_lib = ":acpi_multiply",
-    manifest = ":manifest",
-)
-
-fuchsia_package(
-    name = "pkg",
-    package_name = "acpi_multiply",
-    visibility = ["//visibility:public"],
-    deps = [
-        ":component",
-    ],
-)
-
-
-
-cc_binary(
-    name = "test_acpi_implementation",
-    srcs = [
-        "test_acpi_implementation.cc",
-        "test_acpi_implementation.h",
-        "registers.h",
-    ],
-    linkshared = True,
-    deps = [
-        "@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_llcpp_cc",
-        "@fuchsia_sdk//fidl/fuchsia.driver.compat:fuchsia.driver.compat_llcpp_cc",
-        "@fuchsia_sdk//fidl/fuchsia.hardware.acpi:fuchsia.hardware.acpi_llcpp_cc",
-        "@fuchsia_sdk//fidl/zx:zx_cc",
-        "@fuchsia_sdk//pkg/async-cpp",
-        "@fuchsia_sdk//pkg/driver2-llcpp",
-        "@fuchsia_sdk//pkg/hwreg",
-        "@fuchsia_sdk//pkg/mmio",
-        "@fuchsia_sdk//pkg/fidl_cpp_wire",
-        "@fuchsia_sdk//pkg/sys_component_llcpp",
-        "@fuchsia_sdk//pkg/zx",
-    ],
-)
-
-fuchsia_component_manifest(
-    name = "test_implementation_manifest",
-    src = "meta/test_acpi_implementation.cml",
-)
-
-fuchsia_driver_bytecode_bind_rules(
-    name = "test_implementation_bind_bytecode",
-    output = "test_implementation.bindbc",
-    rules = "test_acpi_implementation.bind",
-    deps = [
-        "@fuchsia_sdk//bind/fuchsia.acpi",
-    ],
-)
-
-fuchsia_driver_component(
-    name = "test_acpi_component",
-    bind_bytecode = ":test_implementation_bind_bytecode",
-    driver_lib = ":test_acpi_implementation",
-    manifest = ":test_implementation_manifest",
-)
-
-fuchsia_package(
-    name = "test_implementation_pkg",
-    package_name = "test_acpi_implementation",
-    visibility = ["//visibility:public"],
-    deps = [
-        ":test_acpi_component",
-    ],
-)
diff --git a/src/acpi_multiply/README.md b/src/acpi_multiply/README.md
new file mode 100644
index 0000000..0616101
--- /dev/null
+++ b/src/acpi_multiply/README.md
@@ -0,0 +1,58 @@
+# ACPI Multiply Sample
+
+This sample project contains a driver component name `acpi_multiply` for a virtual "multiplier"
+device described the ACPI hardware ID `FDFS0001`.
+The driver interacts with the device hardware using the `fuchsia.hardware.acpi` protocol,
+and exposes a custom FIDL protocol (`sample.acpi.multiply`) for other components to
+consume.
+
+The `acpi_controller` driver component emulates an ACPI controller, creating the child device
+nodes to the mutiply device and responding to requests for device resources such as MMIO and
+interrupts.
+
+## Building
+
+To build the `acpi_multiply` driver and related components, run the following commands:
+
+```
+tools/bazel build --config=fuchsia_x64 //src/acpi_multiply/controller:pkg
+tools/bazel build --config=fuchsia_x64 //src/acpi_multiply/driver:pkg
+```
+
+## Running
+
+Use the following commands to load the driver components on a target device:
+
+1.  Load the `acpi_controller` driver component to create a virtual ACPI device node:
+
+    ```
+    tools/bazel run --config=fuchsia_x64 //src/acpi_multiply/controller:pkg.component
+    ```
+
+1.  Load the `acpi_multiply` driver component to bind to the device node and begin
+    semding requests to perform multipy operations:
+
+    ```
+    tools/bazel run --config=fuchsia_x64 //src/acpi_multiply/driver:pkg.component
+    ```
+
+1.  Open the device log viewer:
+
+    ```
+    tools/ffx log --filter acpi_controller --filter acpi_multiply
+    ```
+
+You should see the `acpi_multiply` driver log multiplication operations it performs after the
+driver has successfully bound.
+
+```
+[acpi-multiply,driver][I]: [acpi_multiply.cc:93] UINT32_MAX*9: Got result overflowed=true result=4294967287
+[acpi-multiply,driver][I]: [acpi_multiply.cc:105] 2*9: Got result overflowed=false result=18
+```
+
+## Source layout
+
+*   `controller/` — Source code of the `acpi_controller` driver component.
+*   `driver/` — Source code of the `acpi_multiply` driver component.
+*   `fidl/` — FIDL library definition for `sample.acpi.multiply`.
+*   `lib/` — Common device registers shared between the controller and driver components.
diff --git a/src/acpi_multiply/controller/BUILD.bazel b/src/acpi_multiply/controller/BUILD.bazel
new file mode 100644
index 0000000..a639141
--- /dev/null
+++ b/src/acpi_multiply/controller/BUILD.bazel
@@ -0,0 +1,69 @@
+# 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.
+
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_cc_binary",
+    "fuchsia_component_manifest",
+    "fuchsia_driver_bytecode_bind_rules",
+    "fuchsia_driver_component",
+    "fuchsia_package",
+)
+
+fuchsia_driver_bytecode_bind_rules(
+    name = "bind_bytecode",
+    output = "acpi_controller.bindbc",
+    rules = "acpi_controller.bind",
+    deps = [
+        "@fuchsia_sdk//bind/fuchsia.acpi",
+    ],
+)
+
+cc_binary(
+    name = "acpi_controller",
+    srcs = [
+        "acpi_controller.cc",
+        "acpi_controller.h",
+    ],
+    linkshared = True,
+    deps = [
+        "//src/acpi_multiply/lib",
+        "@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_llcpp_cc",
+        "@fuchsia_sdk//fidl/fuchsia.driver.compat:fuchsia.driver.compat_llcpp_cc",
+        "@fuchsia_sdk//fidl/fuchsia.hardware.acpi:fuchsia.hardware.acpi_llcpp_cc",
+        "@fuchsia_sdk//fidl/zx:zx_cc",
+        "@fuchsia_sdk//pkg/async-cpp",
+        "@fuchsia_sdk//pkg/driver2-llcpp",
+        "@fuchsia_sdk//pkg/hwreg",
+        "@fuchsia_sdk//pkg/mmio",
+        "@fuchsia_sdk//pkg/fidl_cpp_wire",
+        "@fuchsia_sdk//pkg/sys_component_llcpp",
+        "@fuchsia_sdk//pkg/zx",
+    ],
+)
+
+fuchsia_component_manifest(
+    name = "manifest",
+    src = "meta/acpi_controller.cml",
+    includes = [
+        "@fuchsia_sdk//pkg/syslog:client",
+    ],
+)
+
+
+fuchsia_driver_component(
+    name = "component",
+    bind_bytecode = ":bind_bytecode",
+    driver_lib = ":acpi_controller",
+    manifest = ":manifest",
+)
+
+fuchsia_package(
+    name = "pkg",
+    package_name = "acpi_controller",
+    visibility = ["//visibility:public"],
+    deps = [
+        ":component",
+    ],
+)
diff --git a/src/acpi_multiply/test_acpi_implementation.bind b/src/acpi_multiply/controller/acpi_controller.bind
similarity index 100%
rename from src/acpi_multiply/test_acpi_implementation.bind
rename to src/acpi_multiply/controller/acpi_controller.bind
diff --git a/src/acpi_multiply/test_acpi_implementation.cc b/src/acpi_multiply/controller/acpi_controller.cc
similarity index 66%
rename from src/acpi_multiply/test_acpi_implementation.cc
rename to src/acpi_multiply/controller/acpi_controller.cc
index d70b8ab..161aba1 100644
--- a/src/acpi_multiply/test_acpi_implementation.cc
+++ b/src/acpi_multiply/controller/acpi_controller.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/acpi_multiply/test_acpi_implementation.h"
+#include "acpi_controller.h"
 
 #include <fidl/fuchsia.component.decl/cpp/wire_types.h>
 #include <fidl/fuchsia.driver.framework/cpp/wire.h>
@@ -19,20 +19,13 @@
 
 #include "registers.h"
 
-namespace fdf {
-using namespace fuchsia_driver_framework;
-}  // namespace fdf
+namespace acpi_multiply {
 
-namespace test_acpi_implementation {
-
-namespace fcd = fuchsia_component_decl::wire;
-namespace facpi = fuchsia_hardware_acpi::wire;
-
-zx::status<std::unique_ptr<TestAcpiImplementation>> TestAcpiImplementation::Start(
+zx::status<std::unique_ptr<AcpiMultiplyController>> AcpiMultiplyController::Start(
     fuchsia_driver_framework::wire::DriverStartArgs &start_args, fdf::UnownedDispatcher dispatcher,
     fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
     driver::Logger logger) {
-  auto driver = std::make_unique<TestAcpiImplementation>(
+  auto driver = std::make_unique<AcpiMultiplyController>(
       dispatcher->async_dispatcher(), std::move(node), std::move(ns), std::move(logger));
 
   auto result = driver->Run(std::move(start_args.outgoing_dir()));
@@ -43,7 +36,8 @@
   return zx::ok(std::move(driver));
 }
 
-zx::status<> TestAcpiImplementation::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
+zx::status<> AcpiMultiplyController::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
+  // Allocate an MMIO buffer representing the ACPI multiply device
   zx::vmo vmo;
   zx_status_t raw_status = zx::vmo::create(zx_system_get_page_size(), 0, &vmo);
   if (raw_status != ZX_OK) {
@@ -57,11 +51,13 @@
   }
   buffer_ = std::move(buffer.value());
 
+  // Create an IRQ resource for the ACPI multiply device
   raw_status = zx::interrupt::create(zx::resource(), 0, ZX_INTERRUPT_VIRTUAL, &irq_);
   if (raw_status != ZX_OK) {
     return zx::error(raw_status);
   }
 
+  // Serve `fuchsia.hardware.acpi/Device` to child device nodes
   auto service = [this](fidl::ServerEnd<fuchsia_hardware_acpi::Device> server_end) {
     fidl::BindServer(dispatcher_, std::move(server_end), this);
   };
@@ -80,40 +76,44 @@
   return outgoing_.Serve(std::move(outgoing_dir));
 }
 
-zx::status<> TestAcpiImplementation::AddChild() {
+zx::status<> AcpiMultiplyController::AddChild() {
   fidl::Arena arena;
 
   // Offer fuchsia.hardware.acpi.Device to the driver that binds to the node.
   auto protocol_offer =
-      fcd::OfferProtocol::Builder(arena)
+      fuchsia_component_decl::wire::OfferProtocol::Builder(arena)
           .source_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_acpi::Device>)
           .target_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_acpi::Device>)
-          .dependency_type(fcd::DependencyType::kStrong)
+          .dependency_type(fuchsia_component_decl::wire::DependencyType::kStrong)
           .Build();
-  fcd::Offer offer = fcd::Offer::WithProtocol(arena, protocol_offer);
+  fuchsia_component_decl::wire::Offer offer =
+      fuchsia_component_decl::wire::Offer::WithProtocol(arena, protocol_offer);
 
-  // Set the properties of the node that a driver will bind to.
-  auto properties = fidl::VectorView<fdf::wire::NodeProperty>(arena, 2);
-  properties[0] = fdf::wire::NodeProperty::Builder(arena)
-                      .key(fdf::wire::NodePropertyKey::WithIntValue(1 /* BIND_PROTOCOL */))
-                      .value(fdf::wire::NodePropertyValue::WithIntValue(30 /* ZX_PROTOCOL_ACPI */))
-                      .Build();
+  // Set the properties of the node that a driver binds to.
+  auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
+  properties[0] =
+      fuchsia_driver_framework::wire::NodeProperty::Builder(arena)
+          .key(fuchsia_driver_framework::wire::NodePropertyKey::WithIntValue(1 /* BIND_PROTOCOL */))
+          .value(fuchsia_driver_framework::wire::NodePropertyValue::WithIntValue(
+              30 /* ZX_PROTOCOL_ACPI */))
+          .Build();
 
-  properties[1] = fdf::wire::NodeProperty::Builder(arena)
-                      .key(fdf::wire::NodePropertyKey::WithStringValue(
+  properties[1] = fuchsia_driver_framework::wire::NodeProperty::Builder(arena)
+                      .key(fuchsia_driver_framework::wire::NodePropertyKey::WithStringValue(
                           arena, fidl::StringView::FromExternal("fuchsia.acpi.hid")))
-                      .value(fdf::wire::NodePropertyValue::WithStringValue(
+                      .value(fuchsia_driver_framework::wire::NodePropertyValue::WithStringValue(
                           arena, fidl::StringView::FromExternal("FDFS0001")))
                       .Build();
 
-  auto args = fdf::wire::NodeAddArgs::Builder(arena)
-                  .name(arena, "acpi-child")
-                  .offers(fidl::VectorView<fcd::Offer>::FromExternal(&offer, 1))
-                  .properties(properties)
-                  .Build();
+  auto args =
+      fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
+          .name(arena, "acpi-child")
+          .offers(fidl::VectorView<fuchsia_component_decl::wire::Offer>::FromExternal(&offer, 1))
+          .properties(properties)
+          .Build();
 
   // Create endpoints of the `NodeController` for the node.
-  auto endpoints = fidl::CreateEndpoints<fdf::NodeController>();
+  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());
@@ -128,7 +128,8 @@
   return zx::ok();
 }
 
-void TestAcpiImplementation::GetMmio(GetMmioRequestView request,
+// Protocol method for `fuchsia.hardware.acpi/Device` to return a requested MMIO region.
+void AcpiMultiplyController::GetMmio(GetMmioRequestView request,
                                      GetMmioCompleter::Sync &completer) {
   if (request->index != 0) {
     completer.ReplyError(ZX_ERR_OUT_OF_RANGE);
@@ -149,7 +150,8 @@
   });
 }
 
-void TestAcpiImplementation::MapInterrupt(MapInterruptRequestView request,
+// Protocol method for `fuchsia.hardware.acpi/Device` to return the requested IRQ.
+void AcpiMultiplyController::MapInterrupt(MapInterruptRequestView request,
                                           MapInterruptCompleter::Sync &completer) {
   if (request->index != 0) {
     completer.ReplyError(ZX_ERR_OUT_OF_RANGE);
@@ -166,20 +168,22 @@
   completer.ReplySuccess(std::move(clone));
 }
 
-void TestAcpiImplementation::EvaluateObject(EvaluateObjectRequestView request,
+// Protocol method for `fuchsia.hardware.acpi/Device` to interpret an invoke the control method
+// associated with the provided object path.
+void AcpiMultiplyController::EvaluateObject(EvaluateObjectRequestView request,
                                             EvaluateObjectCompleter::Sync &completer) {
-  if (request->mode != facpi::EvaluateObjectMode::kPlainObject) {
-    completer.ReplyError(facpi::Status::kNotSupported);
+  if (request->mode != fuchsia_hardware_acpi::wire::EvaluateObjectMode::kPlainObject) {
+    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotSupported);
     return;
   }
 
   if (request->path.get() != "_MUL") {
-    completer.ReplyError(facpi::Status::kNotFound);
+    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotFound);
     return;
   }
 
   fidl::Arena arena;
-  completer.ReplySuccess(facpi::EncodedObject());
+  completer.ReplySuccess(fuchsia_hardware_acpi::wire::EncodedObject());
   // To simulate asynchronous hardware, we post a delayed task and trigger an interrupt when the
   // task is complete.
   async::PostDelayedTask(
@@ -207,6 +211,6 @@
       zx::msec(10));
 }
 
-}  // namespace test_acpi_implementation
+}  // namespace acpi_multiply
 
-FUCHSIA_DRIVER_RECORD_CPP_V1(test_acpi_implementation::TestAcpiImplementation);
+FUCHSIA_DRIVER_RECORD_CPP_V1(acpi_multiply::AcpiMultiplyController);
diff --git a/src/acpi_multiply/test_acpi_implementation.h b/src/acpi_multiply/controller/acpi_controller.h
similarity index 81%
rename from src/acpi_multiply/test_acpi_implementation.h
rename to src/acpi_multiply/controller/acpi_controller.h
index 3941ea8..899d68e 100644
--- a/src/acpi_multiply/test_acpi_implementation.h
+++ b/src/acpi_multiply/controller/acpi_controller.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SRC_ACPI_MULTIPLY_TEST_ACPI_IMPLEMENTATION_H_
-#define SRC_ACPI_MULTIPLY_TEST_ACPI_IMPLEMENTATION_H_
+#ifndef SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_
+#define SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_
 
 #include <fidl/fuchsia.driver.framework/cpp/markers.h>
 #include <fidl/fuchsia.driver.framework/cpp/wire_types.h>
@@ -15,18 +15,18 @@
 #include <lib/sys/component/llcpp/outgoing_directory.h>
 #include <lib/zx/status.h>
 
-namespace test_acpi_implementation {
+namespace acpi_multiply {
 
-// Test driver that interacts with the ACPI multiply driver. It implements the ACPI protocol
-// and behaves as follows:
+// Sample driver that implements a `fuchsia.hardware.acpi` bus controller and emulates the
+// following ACPI protocol behaviors for the ACPI multiple driver:
 // 1. Child driver writes two values to multiply to register offsets 0x0 and 0x04
 // 2. Child driver calls EvaluateObject("_MUL") to perform the multiplication, and waits
 // for an interrupt.
 // 3. This driver performs the multiplication, writes the result (64-bit) to 0x08
 // and triggers an interrupt.
-class TestAcpiImplementation : public fidl::WireServer<fuchsia_hardware_acpi::Device> {
+class AcpiMultiplyController : public fidl::WireServer<fuchsia_hardware_acpi::Device> {
  public:
-  TestAcpiImplementation(async_dispatcher_t* dispatcher,
+  AcpiMultiplyController(async_dispatcher_t* dispatcher,
                          fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
                          driver::Namespace ns, driver::Logger logger)
       : dispatcher_(dispatcher),
@@ -35,15 +35,16 @@
         logger_(std::move(logger)),
         node_(std::move(node)) {}
 
-  virtual ~TestAcpiImplementation() = default;
+  virtual ~AcpiMultiplyController() = default;
 
-  static constexpr const char* Name() { return "test-acpi-implementation"; }
-  static zx::status<std::unique_ptr<TestAcpiImplementation>> Start(
+  static constexpr const char* Name() { return "sample-acpi-controller"; }
+  static zx::status<std::unique_ptr<AcpiMultiplyController>> Start(
       fuchsia_driver_framework::wire::DriverStartArgs& start_args,
       fdf::UnownedDispatcher dispatcher,
       fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
       driver::Logger logger);
 
+  // fuchsia.hardware.acpi/Device:
   void MapInterrupt(MapInterruptRequestView request, MapInterruptCompleter::Sync& completer);
   void GetMmio(GetMmioRequestView request, GetMmioCompleter::Sync& completer);
   void EvaluateObject(EvaluateObjectRequestView request, EvaluateObjectCompleter::Sync& completer);
@@ -79,8 +80,7 @@
     completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
   }
 
-  void SetWakeDevice(SetWakeDeviceRequestView request,
-                     SetWakeDeviceCompleter::Sync& completer) {
+  void SetWakeDevice(SetWakeDeviceRequestView request, SetWakeDeviceCompleter::Sync& completer) {
     completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
   }
 
@@ -101,6 +101,6 @@
   fidl::WireSharedClient<fuchsia_driver_framework::NodeController> controller_;
 };
 
-}  // namespace test_acpi_implementation
+}  // namespace acpi_multiply
 
-#endif  // SRC_ACPI_MULTIPLY_TEST_ACPI_IMPLEMENTATION_H_
+#endif  // SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_
diff --git a/src/acpi_multiply/controller/meta/acpi_controller.cml b/src/acpi_multiply/controller/meta/acpi_controller.cml
new file mode 100644
index 0000000..12d2c24
--- /dev/null
+++ b/src/acpi_multiply/controller/meta/acpi_controller.cml
@@ -0,0 +1,26 @@
+// 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: [
+        'syslog/client.shard.cml',
+    ],
+    program: {
+        runner: 'driver',
+        binary: 'lib/libacpi_controller.so',
+        bind: 'meta/bind/acpi_controller.bindbc'
+    },
+    use: [
+        { service: 'fuchsia.driver.compat.Service' },
+    ],
+    // Provide the ACPI device capability to other components
+    capabilities: [
+        { protocol: 'fuchsia.hardware.acpi.Device' },
+    ],
+    expose: [
+        {
+            protocol: 'fuchsia.hardware.acpi.Device',
+            from: 'self',
+        },
+    ],
+}
diff --git a/src/acpi_multiply/driver/BUILD.bazel b/src/acpi_multiply/driver/BUILD.bazel
new file mode 100644
index 0000000..a1e0df0
--- /dev/null
+++ b/src/acpi_multiply/driver/BUILD.bazel
@@ -0,0 +1,67 @@
+# 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.
+
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_cc_binary",
+    "fuchsia_component_manifest",
+    "fuchsia_driver_bytecode_bind_rules",
+    "fuchsia_driver_component",
+    "fuchsia_package",
+)
+
+fuchsia_driver_bytecode_bind_rules(
+    name = "bind_bytecode",
+    output = "acpi_multiply.bindbc",
+    rules = "acpi_multiply.bind",
+    deps = [
+        "@fuchsia_sdk//bind/fuchsia.acpi",
+    ],
+)
+
+cc_binary(
+    name = "acpi_multiply",
+    srcs = [
+        "acpi_multiply.cc",
+        "acpi_multiply.h",
+    ],
+    linkshared = True,
+    deps = [
+        "//src/acpi_multiply/fidl:sample.acpi.multiply_cc",
+        "//src/acpi_multiply/lib",
+        "@fuchsia_sdk//fidl/fuchsia.hardware.acpi:fuchsia.hardware.acpi_llcpp_cc",
+        "@fuchsia_sdk//fidl/zx:zx_cc",
+        "@fuchsia_sdk//pkg/async-cpp",
+        "@fuchsia_sdk//pkg/mmio",
+        "@fuchsia_sdk//pkg/hwreg",
+        "@fuchsia_sdk//pkg/driver2-llcpp",
+        "@fuchsia_sdk//pkg/fidl_cpp_wire",
+        "@fuchsia_sdk//pkg/sys_component_llcpp",
+        "@fuchsia_sdk//pkg/zx",
+    ],
+)
+
+fuchsia_component_manifest(
+    name = "manifest",
+    src = "meta/acpi_multiply.cml",
+    includes = [
+        "@fuchsia_sdk//pkg/syslog:client",
+    ],
+)
+
+fuchsia_driver_component(
+    name = "component",
+    bind_bytecode = ":bind_bytecode",
+    driver_lib = ":acpi_multiply",
+    manifest = ":manifest",
+)
+
+fuchsia_package(
+    name = "pkg",
+    package_name = "acpi_multiply",
+    visibility = ["//visibility:public"],
+    deps = [
+        ":component",
+    ],
+)
diff --git a/src/acpi_multiply/acpi_multiply.bind b/src/acpi_multiply/driver/acpi_multiply.bind
similarity index 100%
rename from src/acpi_multiply/acpi_multiply.bind
rename to src/acpi_multiply/driver/acpi_multiply.bind
diff --git a/src/acpi_multiply/acpi_multiply.cc b/src/acpi_multiply/driver/acpi_multiply.cc
similarity index 90%
rename from src/acpi_multiply/acpi_multiply.cc
rename to src/acpi_multiply/driver/acpi_multiply.cc
index 4005d4c..74f53b0 100644
--- a/src/acpi_multiply/acpi_multiply.cc
+++ b/src/acpi_multiply/driver/acpi_multiply.cc
@@ -19,9 +19,6 @@
 
 namespace acpi_multiply {
 
-namespace fio = fuchsia_io;
-namespace facpi = fuchsia_hardware_acpi;
-
 zx::status<std::unique_ptr<AcpiMultiplyDriver>> AcpiMultiplyDriver::Start(
     fuchsia_driver_framework::wire::DriverStartArgs& start_args, fdf::UnownedDispatcher dispatcher,
     fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
@@ -36,7 +33,7 @@
   return zx::ok(std::move(driver));
 }
 
-zx::status<> AcpiMultiplyDriver::Run(fidl::ServerEnd<fio::Directory> outgoing_dir) {
+zx::status<> AcpiMultiplyDriver::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
   auto status = outgoing_.AddProtocol<sample_acpi_multiply::Device>(this, Name());
   if (status.is_error()) {
     FDF_SLOG(ERROR, "Failed to add protocol", KV("status", status.status_string()));
@@ -44,7 +41,7 @@
   }
 
   // Connect to the ACPI protocol exposed by the parent driver.
-  auto client = ns_.Connect<facpi::Device>();
+  auto client = ns_.Connect<fuchsia_hardware_acpi::Device>();
   if (client.is_error()) {
     FDF_SLOG(ERROR, "Failed to connect to ACPI", KV("status", client.status_string()));
     return client.take_error();
@@ -117,6 +114,7 @@
   return zx::ok();
 }
 
+// Protocol method in `sample.acpi.multiply` to execute a multiply operation
 void AcpiMultiplyDriver::Multiply(MultiplyRequestView request, MultiplyCompleter::Sync& completer) {
   std::scoped_lock lock(completer_lock_);
   // Queue operations if there is already one in-flight.
@@ -136,6 +134,7 @@
   });
 }
 
+// Call the underlying hardware resources (MMIO, Interrupt) to perform a multiply operation.
 void AcpiMultiplyDriver::DoMultiply(Operation operation) {
   // Write the operands to the two MMIO registers.
   MultiplyArgumentReg::Get(true).FromValue(0).set_operand(operation.a).WriteTo(&mmio_.value());
@@ -144,9 +143,10 @@
   cur_completer_ = std::move(operation.completer);
   fidl::Arena arena;
   // Call the ACPI method that will trigger the multiply operation.
-  auto result = acpi_->EvaluateObject(fidl::StringView::FromExternal("_MUL"),
-                                      facpi::wire::EvaluateObjectMode::kPlainObject,
-                                      fidl::VectorView<facpi::wire::Object>(arena, 0));
+  auto result =
+      acpi_->EvaluateObject(fidl::StringView::FromExternal("_MUL"),
+                            fuchsia_hardware_acpi::wire::EvaluateObjectMode::kPlainObject,
+                            fidl::VectorView<fuchsia_hardware_acpi::wire::Object>(arena, 0));
   if (!result.ok() || result->is_error()) {
     FDF_SLOG(ERROR, "Failed to send EvaluateObject",
              KV("error", (const char*)(result.ok() ? std::to_string(result->error_value()).data()
@@ -159,6 +159,7 @@
   // We will receive an interrupt when the operation is done.
 }
 
+// Callback when the ACPI device raises an interrupt, signaling the multiply operation is complete.
 void AcpiMultiplyDriver::HandleIrq(async_dispatcher_t* dispatcher, async::IrqBase* irq,
                                    zx_status_t status, const zx_packet_interrupt_t* interrupt) {
   irq_.ack();
diff --git a/src/acpi_multiply/acpi_multiply.h b/src/acpi_multiply/driver/acpi_multiply.h
similarity index 96%
rename from src/acpi_multiply/acpi_multiply.h
rename to src/acpi_multiply/driver/acpi_multiply.h
index bc1a174..2b6833c 100644
--- a/src/acpi_multiply/acpi_multiply.h
+++ b/src/acpi_multiply/driver/acpi_multiply.h
@@ -21,6 +21,7 @@
 
 namespace acpi_multiply {
 
+// Sample driver for a virtual "multiplier" device described using ACPI.
 class AcpiMultiplyDriver : public fidl::WireServer<sample_acpi_multiply::Device> {
  public:
   AcpiMultiplyDriver(async_dispatcher_t* dispatcher,
@@ -42,6 +43,7 @@
       fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
       driver::Logger logger);
 
+  // sample.acpi.multiply/Device:
   void Multiply(MultiplyRequestView request, MultiplyCompleter::Sync& completer);
 
  private:
diff --git a/src/acpi_multiply/driver/meta/acpi_multiply.cml b/src/acpi_multiply/driver/meta/acpi_multiply.cml
new file mode 100644
index 0000000..5fda9de
--- /dev/null
+++ b/src/acpi_multiply/driver/meta/acpi_multiply.cml
@@ -0,0 +1,28 @@
+// 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: [
+        'syslog/client.shard.cml',
+    ],
+    program: {
+        runner: 'driver',
+        binary: 'lib/libacpi_multiply.so',
+        bind: 'meta/bind/acpi_multiply.bindbc'
+    },
+    // Consume the ACPI device capability from the parent
+    use: [
+        { protocol: 'fuchsia.hardware.acpi.Device' },
+        { service: 'fuchsia.driver.compat.Service' },
+    ],
+    // Provide the multiply device capability to other components
+    capabilities: [
+        { protocol: 'sample.acpi.multiply.Device' },
+    ],
+    expose: [
+        {
+            protocol: 'sample.acpi.multiply.Device',
+            from: 'self',
+        },
+    ],
+}
diff --git a/src/acpi_multiply/fidl/BUILD.bazel b/src/acpi_multiply/fidl/BUILD.bazel
new file mode 100644
index 0000000..f71167c
--- /dev/null
+++ b/src/acpi_multiply/fidl/BUILD.bazel
@@ -0,0 +1,31 @@
+# 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.
+
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_fidl_library",
+    "fuchsia_fidl_llcpp_library",
+)
+
+fuchsia_fidl_library(
+    name = "sample.acpi.multiply",
+    srcs = [
+        "acpi_multiply.fidl",
+    ],
+    library = "sample.acpi.multiply",
+    visibility = ["//visibility:public"],
+    deps = [
+        "@fuchsia_sdk//fidl/zx",
+    ],
+)
+
+fuchsia_fidl_llcpp_library(
+    name = "sample.acpi.multiply_cc",
+    library = ":sample.acpi.multiply",
+    visibility = ["//visibility:public"],
+    deps = [
+        "@fuchsia_sdk//fidl/zx:zx_llcpp_cc",
+        "@fuchsia_sdk//pkg/fidl_cpp_wire",
+    ],
+)
diff --git a/src/acpi_multiply/acpi_multiply.fidl b/src/acpi_multiply/fidl/acpi_multiply.fidl
similarity index 100%
rename from src/acpi_multiply/acpi_multiply.fidl
rename to src/acpi_multiply/fidl/acpi_multiply.fidl
diff --git a/src/acpi_multiply/lib/BUILD.bazel b/src/acpi_multiply/lib/BUILD.bazel
new file mode 100644
index 0000000..65726c0
--- /dev/null
+++ b/src/acpi_multiply/lib/BUILD.bazel
@@ -0,0 +1,10 @@
+# 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.
+
+cc_library(
+    name = "lib",
+    hdrs = ["include/registers.h"],
+    includes = ["include"],
+    visibility = ["//visibility:public"],
+)
diff --git a/src/acpi_multiply/registers.h b/src/acpi_multiply/lib/include/registers.h
similarity index 100%
rename from src/acpi_multiply/registers.h
rename to src/acpi_multiply/lib/include/registers.h
diff --git a/src/acpi_multiply/meta/acpi_multiply.cml b/src/acpi_multiply/meta/acpi_multiply.cml
deleted file mode 100644
index 630ee40..0000000
--- a/src/acpi_multiply/meta/acpi_multiply.cml
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    program: {
-        runner: 'driver',
-        binary: 'lib/libacpi_multiply.so',
-        bind: 'meta/bind/acpi_multiply.bindbc'
-    },
-    use: [
-        {
-            protocol: [
-              'fuchsia.logger.LogSink',
-              'fuchsia.hardware.acpi.Device',
-            ],
-        },
-        { service: "fuchsia.driver.compat.Service" },
-    ],
-}
diff --git a/src/acpi_multiply/meta/test_acpi_implementation.cml b/src/acpi_multiply/meta/test_acpi_implementation.cml
deleted file mode 100644
index c86ada6..0000000
--- a/src/acpi_multiply/meta/test_acpi_implementation.cml
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    program: {
-        runner: 'driver',
-        binary: 'lib/libtest_acpi_implementation.so',
-        bind: 'meta/bind/test_implementation.bindbc'
-    },
-    use: [
-        {
-            protocol: [
-              'fuchsia.logger.LogSink',
-            ],
-        },
-        { service: "fuchsia.driver.compat.Service" },
-    ],
-    capabilities: [
-        { protocol: 'fuchsia.hardware.acpi.Device' },
-    ],
-    expose: [
-        {
-            protocol: 'fuchsia.hardware.acpi.Device',
-            from: 'self',
-        },
-    ],
-}