[board][vim] Convert to c++

Test: Tested on Frank with vim2, confirmed same behavior before and
after changes. All USB peripherals enumerated, touch and OKG working

ZX-3177 #done

Change-Id: I6bee8f66c3e9ce9c93eae67875f64d7c1a9812bf
diff --git a/system/dev/board/vim/rules.mk b/system/dev/board/vim/rules.mk
index 2649de3..931477f 100644
--- a/system/dev/board/vim/rules.mk
+++ b/system/dev/board/vim/rules.mk
@@ -9,28 +9,32 @@
 MODULE_TYPE := driver
 
 MODULE_SRCS += \
-    $(LOCAL_DIR)/vim.c \
-    $(LOCAL_DIR)/vim-gpio.c \
-    $(LOCAL_DIR)/vim-i2c.c \
-    $(LOCAL_DIR)/vim-mali.c \
-    $(LOCAL_DIR)/vim-uart.c \
-    $(LOCAL_DIR)/vim-usb.c \
-    $(LOCAL_DIR)/vim-sd-emmc.c \
-    $(LOCAL_DIR)/vim-sdio.c \
-    $(LOCAL_DIR)/vim-eth.c \
-    $(LOCAL_DIR)/vim-thermal.c \
-    $(LOCAL_DIR)/vim-display.c \
-    $(LOCAL_DIR)/vim-video.c \
-    $(LOCAL_DIR)/vim-led2472g.c \
-    $(LOCAL_DIR)/vim-rtc.c \
-    $(LOCAL_DIR)/vim-canvas.c \
-    $(LOCAL_DIR)/vim-clk.c \
-    $(LOCAL_DIR)/vim-sysmem.c \
+    $(LOCAL_DIR)/vim.cpp \
+    $(LOCAL_DIR)/vim-gpio.cpp\
+    $(LOCAL_DIR)/vim-i2c.cpp \
+    $(LOCAL_DIR)/vim-mali.cpp \
+    $(LOCAL_DIR)/vim-uart.cpp \
+    $(LOCAL_DIR)/vim-usb.cpp \
+    $(LOCAL_DIR)/vim-sd-emmc.cpp \
+    $(LOCAL_DIR)/vim-sdio.cpp \
+    $(LOCAL_DIR)/vim-eth.cpp \
+    $(LOCAL_DIR)/vim-thermal.cpp \
+    $(LOCAL_DIR)/vim-display.cpp \
+    $(LOCAL_DIR)/vim-video.cpp \
+    $(LOCAL_DIR)/vim-led2472g.cpp \
+    $(LOCAL_DIR)/vim-rtc.cpp \
+    $(LOCAL_DIR)/vim-canvas.cpp \
+    $(LOCAL_DIR)/vim-clk.cpp \
+    $(LOCAL_DIR)/vim-sysmem.cpp \
 
 MODULE_STATIC_LIBS := \
     system/ulib/ddk \
     system/ulib/sync \
     system/dev/lib/broadcom \
+    system/ulib/ddktl \
+    system/ulib/fbl \
+    system/ulib/zx \
+    system/ulib/zxcpp \
 
 MODULE_LIBS := \
     system/ulib/driver \
diff --git a/system/dev/board/vim/vim-canvas.c b/system/dev/board/vim/vim-canvas.c
deleted file mode 100644
index 163b648..0000000
--- a/system/dev/board/vim/vim-canvas.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-hw.h>
-#include "vim.h"
-
-static const pbus_mmio_t vim_canvas_mmios[] = {
-    {
-        .base =     S912_DMC_REG_BASE,
-        .length =   S912_DMC_REG_LENGTH,
-    },
-};
-
-static const pbus_bti_t vim_canvas_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_CANVAS,
-    },
-};
-
-static const pbus_dev_t canvas_dev = {
-    .name = "canvas",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_CANVAS,
-    .mmio_list = vim_canvas_mmios,
-    .mmio_count = countof(vim_canvas_mmios),
-    .bti_list = vim_canvas_btis,
-    .bti_count = countof(vim_canvas_btis),
-};
-
-zx_status_t vim2_canvas_init(vim_bus_t* bus) {
-    zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_AMLOGIC_CANVAS,
-                                                  &canvas_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim2_canvas_init: pbus_protocol_device_add Canvas failed: %d\n", status);
-        return status;
-    }
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-canvas.cpp b/system/dev/board/vim/vim-canvas.cpp
new file mode 100644
index 0000000..b936e2e
--- /dev/null
+++ b/system/dev/board/vim/vim-canvas.cpp
@@ -0,0 +1,48 @@
+// Copyright 2018 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 "vim.h"
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-s912/s912-hw.h>
+
+namespace vim {
+static const pbus_mmio_t vim_canvas_mmios[] = {
+    {
+        .base = S912_DMC_REG_BASE,
+        .length = S912_DMC_REG_LENGTH,
+    },
+};
+
+static const pbus_bti_t vim_canvas_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_CANVAS,
+    },
+};
+
+zx_status_t Vim::CanvasInit() {
+
+    pbus_dev_t canvas_dev = {};
+    canvas_dev.name = "canvas";
+    canvas_dev.vid = PDEV_VID_AMLOGIC;
+    canvas_dev.pid = PDEV_PID_GENERIC;
+    canvas_dev.did = PDEV_DID_AMLOGIC_CANVAS;
+    canvas_dev.mmio_list = vim_canvas_mmios;
+    canvas_dev.mmio_count = countof(vim_canvas_mmios);
+    canvas_dev.bti_list = vim_canvas_btis;
+    canvas_dev.bti_count = countof(vim_canvas_btis);
+
+    zx_status_t status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_AMLOGIC_CANVAS,
+                                                 &canvas_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "CanvasInit: pbus_protocol_device_add Canvas failed: %d\n", status);
+        return status;
+    }
+    return ZX_OK;
+}
+
+} //namespace vim
diff --git a/system/dev/board/vim/vim-clk.c b/system/dev/board/vim/vim-clk.c
deleted file mode 100644
index b3cc297..0000000
--- a/system/dev/board/vim/vim-clk.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include "vim.h"
-
-static const pbus_mmio_t clk_mmios[] = {
-    {
-        .base = S912_HIU_BASE,
-        .length = S912_HIU_LENGTH,
-    },
-};
-
-static const pbus_dev_t clk_dev = {
-    .name = "vim-clk",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_AMLOGIC_S912,
-    .did = PDEV_DID_AMLOGIC_AXG_CLK,
-    .mmio_list = clk_mmios,
-    .mmio_count = countof(clk_mmios),
-};
-
-zx_status_t vim_clk_init(vim_bus_t* bus) {
-    zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_CLK, &clk_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_clk_init: pbus_protocol_device_add failed, st = %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-clk.cpp b/system/dev/board/vim/vim-clk.cpp
new file mode 100644
index 0000000..9624a68
--- /dev/null
+++ b/system/dev/board/vim/vim-clk.cpp
@@ -0,0 +1,39 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include "vim.h"
+
+namespace vim {
+static const pbus_mmio_t clk_mmios[] = {
+    {
+        .base = S912_HIU_BASE,
+        .length = S912_HIU_LENGTH,
+    },
+};
+
+zx_status_t Vim::ClkInit() {
+
+    pbus_dev_t clk_dev = {};
+    clk_dev.name = "vim-clk";
+    clk_dev.vid = PDEV_VID_AMLOGIC;
+    clk_dev.pid = PDEV_PID_AMLOGIC_S912;
+    clk_dev.did = PDEV_DID_AMLOGIC_AXG_CLK;
+    clk_dev.mmio_list = clk_mmios;
+    clk_dev.mmio_count = countof(clk_mmios);
+
+    zx_status_t status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_CLK, &clk_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "ClkInit: pbus_protocol_device_add failed, st = %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-display.c b/system/dev/board/vim/vim-display.c
deleted file mode 100644
index 1510a7b..0000000
--- a/system/dev/board/vim/vim-display.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-hw.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include "vim.h"
-
-// DMC MMIO for display driver
-static pbus_mmio_t vim_display_mmios[] = {
-    {
-        .base =     S912_PRESET_BASE,
-        .length =   S912_PRESET_LENGTH,
-    },
-    {
-        .base =     S912_HDMITX_BASE,
-        .length =   S912_HDMITX_LENGTH,
-    },
-    {
-        .base =     S912_HIU_BASE,
-        .length =   S912_HIU_LENGTH,
-    },
-    {
-        .base =     S912_VPU_BASE,
-        .length =   S912_VPU_LENGTH,
-    },
-    {
-        .base =     S912_HDMITX_SEC_BASE,
-        .length =   S912_HDMITX_SEC_LENGTH,
-    },
-    {
-        .base =     S912_DMC_REG_BASE,
-        .length =   S912_DMC_REG_LENGTH,
-    },
-    {
-        .base =     S912_CBUS_REG_BASE,
-        .length =   S912_CBUS_REG_LENGTH,
-    },
-    {
-        .base =     S912_AUDOUT_BASE,
-        .length =   S912_AUDOUT_LEN,
-    },
-};
-
-const pbus_gpio_t vim_display_gpios[] = {
-    {
-        // HPD
-        .gpio = S912_GPIOH(0),
-    },
-};
-
-static const pbus_irq_t vim_display_irqs[] = {
-    {
-        .irq = S912_VIU1_VSYNC_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_RDMA_DONE_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-};
-
-static const pbus_bti_t vim_display_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_DISPLAY,
-    },
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_AUDIO,
-    },
-};
-
-static const uint32_t vim_display_protocols[] = {
-    ZX_PROTOCOL_AMLOGIC_CANVAS,
-};
-
-static const pbus_dev_t display_dev = {
-    .name = "display",
-    .vid = PDEV_VID_KHADAS,
-    .pid = PDEV_PID_VIM2,
-    .did = PDEV_DID_VIM_DISPLAY,
-    .mmio_list = vim_display_mmios,
-    .mmio_count = countof(vim_display_mmios),
-    .gpio_list = vim_display_gpios,
-    .gpio_count = countof(vim_display_gpios),
-    .irq_list = vim_display_irqs,
-    .irq_count = countof(vim_display_irqs),
-    .bti_list = vim_display_btis,
-    .bti_count = countof(vim_display_btis),
-    .protocol_list = vim_display_protocols,
-    .protocol_count = countof(vim_display_protocols),
-};
-
-zx_status_t vim_display_init(vim_bus_t* bus) {
-    zx_status_t status;
-
-    // enable this #if 0 in order to enable the SPDIF out pin for VIM2 (GPIO H4, pad M22)
-#if 0
-    gpio_set_alt_function(&bus->gpio, S912_SPDIF_H4, S912_SPDIF_H4_OUT_FN);
-#endif
-
-    if ((status = pbus_device_add(&bus->pbus, &display_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_display_init: pbus_device_add() failed for display: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-display.cpp b/system/dev/board/vim/vim-display.cpp
new file mode 100644
index 0000000..7a1cf89
--- /dev/null
+++ b/system/dev/board/vim/vim-display.cpp
@@ -0,0 +1,113 @@
+// Copyright 2018 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 "vim.h"
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+namespace vim {
+// DMC MMIO for display driver
+static pbus_mmio_t vim_display_mmios[] = {
+    {
+        .base = S912_PRESET_BASE,
+        .length = S912_PRESET_LENGTH,
+    },
+    {
+        .base = S912_HDMITX_BASE,
+        .length = S912_HDMITX_LENGTH,
+    },
+    {
+        .base = S912_HIU_BASE,
+        .length = S912_HIU_LENGTH,
+    },
+    {
+        .base = S912_VPU_BASE,
+        .length = S912_VPU_LENGTH,
+    },
+    {
+        .base = S912_HDMITX_SEC_BASE,
+        .length = S912_HDMITX_SEC_LENGTH,
+    },
+    {
+        .base = S912_DMC_REG_BASE,
+        .length = S912_DMC_REG_LENGTH,
+    },
+    {
+        .base = S912_CBUS_REG_BASE,
+        .length = S912_CBUS_REG_LENGTH,
+    },
+    {
+        .base = S912_AUDOUT_BASE,
+        .length = S912_AUDOUT_LEN,
+    },
+};
+
+const pbus_gpio_t vim_display_gpios[] = {
+    {
+        // HPD
+        .gpio = S912_GPIOH(0),
+    },
+};
+
+static const pbus_irq_t vim_display_irqs[] = {
+    {
+        .irq = S912_VIU1_VSYNC_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_RDMA_DONE_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static const pbus_bti_t vim_display_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_DISPLAY,
+    },
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_AUDIO,
+    },
+};
+
+static const uint32_t vim_display_protocols[] = {
+    ZX_PROTOCOL_AMLOGIC_CANVAS,
+};
+
+zx_status_t Vim::DisplayInit() {
+    zx_status_t status;
+    pbus_dev_t display_dev = {};
+    display_dev.name = "display";
+    display_dev.vid = PDEV_VID_KHADAS;
+    display_dev.pid = PDEV_PID_VIM2;
+    display_dev.did = PDEV_DID_VIM_DISPLAY;
+    display_dev.mmio_list = vim_display_mmios;
+    display_dev.mmio_count = countof(vim_display_mmios);
+    display_dev.irq_list = vim_display_irqs;
+    display_dev.irq_count = countof(vim_display_irqs);
+    display_dev.gpio_list = vim_display_gpios;
+    display_dev.gpio_count = countof(vim_display_gpios);
+    display_dev.bti_list = vim_display_btis;
+    display_dev.bti_count = countof(vim_display_btis);
+    display_dev.protocol_list = vim_display_protocols;
+    display_dev.protocol_count = countof(vim_display_protocols);
+
+    // enable this #if 0 in order to enable the SPDIF out pin for VIM2 (GPIO H4, pad M22)
+#if 0
+    gpio_set_alt_function(&bus->gpio, S912_SPDIF_H4, S912_SPDIF_H4_OUT_FN);
+#endif
+
+    if ((status = pbus_.DeviceAdd(&display_dev)) != ZX_OK) {
+        zxlogf(ERROR, "DisplayInit: pbus_device_add() failed for display: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-eth.c b/system/dev/board/vim/vim-eth.c
deleted file mode 100644
index 7e58e21..0000000
--- a/system/dev/board/vim/vim-eth.c
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/metadata.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/ethernet.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include <limits.h>
-
-#include "vim.h"
-
-static const pbus_gpio_t eth_board_gpios[] = {
-    {
-        // MAC_RST
-        .gpio = S912_GPIOZ(14),
-    },
-    {
-        // MAC_INTR (need to wire up interrupt?)
-        .gpio = S912_GPIOZ(15),
-    },
-};
-
-static const pbus_irq_t eth_mac_irqs[] = {
-    {
-        .irq = S912_ETH_GMAC_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-};
-
-static const pbus_mmio_t eth_board_mmios[] = {
-    {
-        .base = PERIPHS_REG_BASE,
-        .length = PERIPHS_REG_SIZE,
-    },
-    {
-        .base = HHI_REG_BASE,
-        .length = HHI_REG_SIZE,
-    },
-};
-
-static const pbus_mmio_t eth_mac_mmios[] = {
-    {
-        .base = ETH_MAC_REG_BASE,
-        .length = ETH_MAC_REG_SIZE,
-    },
-};
-
-static const pbus_bti_t eth_mac_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = 0,
-    },
-};
-
-static const pbus_boot_metadata_t eth_mac_metadata[] = {
-    {
-        .zbi_type = DEVICE_METADATA_MAC_ADDRESS,
-        .zbi_extra = 0,
-    },
-};
-
-static const eth_dev_metadata_t eth_phy_device = {
-    .vid = PDEV_VID_REALTEK,
-    .pid = PDEV_PID_RTL8211F,
-    .did = PDEV_DID_ETH_PHY,
-};
-
-static const pbus_metadata_t eth_mac_device_metadata[] = {
-    {
-        .type = DEVICE_METADATA_PRIVATE,
-        .data_buffer = &eth_phy_device,
-        .data_size = sizeof(eth_dev_metadata_t),
-    },
-};
-
-static const eth_dev_metadata_t eth_mac_device = {
-    .vid = PDEV_VID_DESIGNWARE,
-    .did = PDEV_DID_ETH_MAC,
-};
-
-static const pbus_metadata_t eth_board_metadata[] = {
-    {
-        .type = DEVICE_METADATA_PRIVATE,
-        .data_buffer = &eth_mac_device,
-        .data_size = sizeof(eth_dev_metadata_t),
-    },
-};
-
-static const pbus_i2c_channel_t vim2_mcu_i2c[] = {
-    {
-        .bus_id = 1,
-        .address = 0x18,
-    },
-};
-
-static const pbus_dev_t eth_board_children[] = {
-    // Designware MAC.
-    {
-        .name = "dwmac",
-        .mmio_list = eth_mac_mmios,
-        .mmio_count = countof(eth_mac_mmios),
-        .bti_list = eth_mac_btis,
-        .bti_count = countof(eth_mac_btis),
-        .irq_list = eth_mac_irqs,
-        .irq_count = countof(eth_mac_irqs),
-        .metadata_list = eth_mac_device_metadata,
-        .metadata_count = countof(eth_mac_device_metadata),
-        .boot_metadata_list = eth_mac_metadata,
-        .boot_metadata_count = countof(eth_mac_metadata),
-    },
-};
-
-static pbus_dev_t eth_board_dev = {
-    .name = "ethernet_mac",
-    .vid = PDEV_VID_KHADAS,
-    .pid = PDEV_PID_VIM2,
-    .did = PDEV_DID_AMLOGIC_ETH,
-    .mmio_list = eth_board_mmios,
-    .mmio_count = countof(eth_board_mmios),
-    .gpio_list = eth_board_gpios,
-    .gpio_count = countof(eth_board_gpios),
-    .i2c_channel_list = vim2_mcu_i2c,
-    .i2c_channel_count = countof(vim2_mcu_i2c),
-    .metadata_list = eth_board_metadata,
-    .metadata_count = countof(eth_board_metadata),
-    .child_list = eth_board_children,
-    .child_count = countof(eth_board_children),
-};
-
-zx_status_t vim_eth_init(vim_bus_t* bus) {
-
-    // setup pinmux for RGMII connections
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_MDIO, S912_ETH_MDIO_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_MDC, S912_ETH_MDC_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RGMII_RX_CLK,
-                               S912_ETH_RGMII_RX_CLK_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RX_DV, S912_ETH_RX_DV_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RXD0, S912_ETH_RXD0_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RXD1, S912_ETH_RXD1_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RXD2, S912_ETH_RXD2_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RXD3, S912_ETH_RXD3_FN);
-
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_RGMII_TX_CLK,
-                               S912_ETH_RGMII_TX_CLK_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_TX_EN, S912_ETH_TX_EN_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_TXD0, S912_ETH_TXD0_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_TXD1, S912_ETH_TXD1_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_TXD2, S912_ETH_TXD2_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_ETH_TXD3, S912_ETH_TXD3_FN);
-
-    zx_status_t status = pbus_device_add(&bus->pbus, &eth_board_dev);
-
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_eth_init: pbus_device_add failed: %d\n", status);
-    }
-    return status;
-}
diff --git a/system/dev/board/vim/vim-eth.cpp b/system/dev/board/vim/vim-eth.cpp
new file mode 100644
index 0000000..ace1800
--- /dev/null
+++ b/system/dev/board/vim/vim-eth.cpp
@@ -0,0 +1,167 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/metadata.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/ethernet.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include <limits.h>
+
+#include "vim.h"
+namespace vim {
+static const pbus_gpio_t eth_board_gpios[] = {
+    {
+        // MAC_RST
+        .gpio = S912_GPIOZ(14),
+    },
+    {
+        // MAC_INTR (need to wire up interrupt?)
+        .gpio = S912_GPIOZ(15),
+    },
+};
+
+static const pbus_irq_t eth_mac_irqs[] = {
+    {
+        .irq = S912_ETH_GMAC_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static const pbus_mmio_t eth_board_mmios[] = {
+    {
+        .base = PERIPHS_REG_BASE,
+        .length = PERIPHS_REG_SIZE,
+    },
+    {
+        .base = HHI_REG_BASE,
+        .length = HHI_REG_SIZE,
+    },
+};
+
+static const pbus_mmio_t eth_mac_mmios[] = {
+    {
+        .base = ETH_MAC_REG_BASE,
+        .length = ETH_MAC_REG_SIZE,
+    },
+};
+
+static const pbus_bti_t eth_mac_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = 0,
+    },
+};
+
+static const pbus_boot_metadata_t eth_mac_metadata[] = {
+    {
+        .zbi_type = DEVICE_METADATA_MAC_ADDRESS,
+        .zbi_extra = 0,
+    },
+};
+
+static const eth_dev_metadata_t eth_phy_device = {
+    .vid = PDEV_VID_REALTEK,
+    .pid = PDEV_PID_RTL8211F,
+    .did = PDEV_DID_ETH_PHY,
+};
+
+static const pbus_metadata_t eth_mac_device_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &eth_phy_device,
+        .data_size = sizeof(eth_dev_metadata_t),
+    },
+};
+
+static const eth_dev_metadata_t eth_mac_device = {
+    .vid = PDEV_VID_DESIGNWARE,
+    //c++ init error
+    .pid = 0,
+    //c++ init error
+    .did = PDEV_DID_ETH_MAC,
+};
+
+static const pbus_metadata_t eth_board_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &eth_mac_device,
+        .data_size = sizeof(eth_dev_metadata_t),
+    },
+};
+
+static const pbus_i2c_channel_t vim2_mcu_i2c[] = {
+    {
+        .bus_id = 1,
+        .address = 0x18,
+    },
+};
+
+static const pbus_dev_t eth_board_children[] = {
+    // Designware MAC.
+    []() {
+        pbus_dev_t dev;
+        dev.name = "dwmac";
+        dev.mmio_list = eth_mac_mmios;
+        dev.mmio_count = countof(eth_mac_mmios);
+        dev.irq_list = eth_mac_irqs;
+        dev.irq_count = countof(eth_mac_irqs);
+        dev.bti_list = eth_mac_btis;
+        dev.bti_count = countof(eth_mac_btis);
+        dev.metadata_list = eth_mac_device_metadata;
+        dev.metadata_count = countof(eth_mac_device_metadata);
+        dev.boot_metadata_list = eth_mac_metadata;
+        dev.boot_metadata_count = countof(eth_mac_metadata);
+        return dev;
+    }(),
+};
+
+zx_status_t Vim::EthInit() {
+
+    pbus_dev_t eth_board_dev = {};
+    eth_board_dev.name = "ethernet_mac";
+    eth_board_dev.vid = PDEV_VID_KHADAS;
+    eth_board_dev.pid = PDEV_PID_VIM2;
+    eth_board_dev.did = PDEV_DID_AMLOGIC_ETH;
+    eth_board_dev.mmio_list = eth_board_mmios;
+    eth_board_dev.mmio_count = countof(eth_board_mmios);
+    eth_board_dev.gpio_list = eth_board_gpios;
+    eth_board_dev.gpio_count = countof(eth_board_gpios);
+    eth_board_dev.i2c_channel_list = vim2_mcu_i2c;
+    eth_board_dev.i2c_channel_count = countof(vim2_mcu_i2c);
+    eth_board_dev.metadata_list = eth_board_metadata;
+    eth_board_dev.metadata_count = countof(eth_board_metadata);
+    eth_board_dev.child_list = eth_board_children;
+    eth_board_dev.child_count = countof(eth_board_children);
+
+    // setup pinmux for RGMII connections
+    gpio_impl_.SetAltFunction(S912_ETH_MDIO, S912_ETH_MDIO_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_MDC, S912_ETH_MDC_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RGMII_RX_CLK,
+                              S912_ETH_RGMII_RX_CLK_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RX_DV, S912_ETH_RX_DV_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RXD0, S912_ETH_RXD0_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RXD1, S912_ETH_RXD1_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RXD2, S912_ETH_RXD2_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_RXD3, S912_ETH_RXD3_FN);
+
+    gpio_impl_.SetAltFunction(S912_ETH_RGMII_TX_CLK,
+                              S912_ETH_RGMII_TX_CLK_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_TX_EN, S912_ETH_TX_EN_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_TXD0, S912_ETH_TXD0_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_TXD1, S912_ETH_TXD1_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_TXD2, S912_ETH_TXD2_FN);
+    gpio_impl_.SetAltFunction(S912_ETH_TXD3, S912_ETH_TXD3_FN);
+
+    zx_status_t status = pbus_.DeviceAdd(&eth_board_dev);
+
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "EthInit: pbus_device_add failed: %d\n", status);
+    }
+    return status;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-gpio.c b/system/dev/board/vim/vim-gpio.c
deleted file mode 100644
index 2991ed2..0000000
--- a/system/dev/board/vim/vim-gpio.c
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2017 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-
-#include <soc/aml-s905x/s905x-gpio.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include <limits.h>
-
-#include "vim.h"
-
-// S905X and S912 have same MMIO addresses
-static const pbus_mmio_t gpio_mmios[] = {
-    {
-        .base = S912_GPIO_BASE,
-        .length = S912_GPIO_LENGTH,
-    },
-    {
-        .base = S912_GPIO_AO_BASE,
-        .length = S912_GPIO_AO_LENGTH,
-    },
-    {
-        .base = S912_GPIO_INTERRUPT_BASE,
-        .length = S912_GPIO_INTERRUPT_LENGTH,
-    },
-};
-
-// S905X and S912 have same GPIO IRQ numbers
-static const pbus_irq_t gpio_irqs[] = {
-    {
-        .irq = S912_GPIO_IRQ_0,
-    },
-    {
-        .irq = S912_GPIO_IRQ_1,
-    },
-    {
-        .irq = S912_GPIO_IRQ_2,
-    },
-    {
-        .irq = S912_GPIO_IRQ_3,
-    },
-    {
-        .irq = S912_GPIO_IRQ_4,
-    },
-    {
-        .irq = S912_GPIO_IRQ_5,
-    },
-    {
-        .irq = S912_GPIO_IRQ_6,
-    },
-    {
-        .irq = S912_GPIO_IRQ_7,
-    },
-    {
-        .irq = S912_AO_GPIO_IRQ_0,
-    },
-    {
-        .irq = S912_AO_GPIO_IRQ_1,
-    },
-};
-
-static const pbus_dev_t gpio_dev = {
-    .name = "gpio",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_AMLOGIC_S912,
-    .did = PDEV_DID_AMLOGIC_GPIO,
-    .mmio_list = gpio_mmios,
-    .mmio_count = countof(gpio_mmios),
-    .irq_list = gpio_irqs,
-    .irq_count = countof(gpio_irqs),
-};
-
-zx_status_t vim_gpio_init(vim_bus_t* bus) {
-    zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init: pbus_protocol_device_add failed: %d\n", status);
-        return status;
-    }
-
-    status = device_get_protocol(bus->parent, ZX_PROTOCOL_GPIO_IMPL, &bus->gpio);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init: device_get_protocol failed: %d\n", status);
-        return status;
-    }
-
-    const pbus_gpio_t gpio_test_gpios[] = {
-        {
-            // SYS_LED
-            .gpio = S912_GPIOAO(9),
-        },
-        {
-            // GPIO PIN
-            .gpio = S912_GPIOAO(2),
-        },
-    };
-
-    const pbus_dev_t gpio_test_dev = {
-        .name = "vim-gpio-test",
-        .vid = PDEV_VID_GENERIC,
-        .pid = PDEV_PID_GENERIC,
-        .did = PDEV_DID_GPIO_TEST,
-        .gpio_list = gpio_test_gpios,
-        .gpio_count = countof(gpio_test_gpios),
-    };
-
-    status = pbus_device_add(&bus->pbus, &gpio_test_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init could not add gpio_test_dev: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-gpio.cpp b/system/dev/board/vim/vim-gpio.cpp
new file mode 100644
index 0000000..1df14cc
--- /dev/null
+++ b/system/dev/board/vim/vim-gpio.cpp
@@ -0,0 +1,132 @@
+// Copyright 2017 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+
+#include <soc/aml-s905x/s905x-gpio.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include <limits.h>
+
+#include "vim.h"
+
+namespace vim {
+// S905X and S912 have same MMIO addresses
+static const pbus_mmio_t gpio_mmios[] = {
+    {
+        .base = S912_GPIO_BASE,
+        .length = S912_GPIO_LENGTH,
+    },
+    {
+        .base = S912_GPIO_AO_BASE,
+        .length = S912_GPIO_AO_LENGTH,
+    },
+    {
+        .base = S912_GPIO_INTERRUPT_BASE,
+        .length = S912_GPIO_INTERRUPT_LENGTH,
+    },
+};
+
+// S905X and S912 have same GPIO IRQ numbers
+static const pbus_irq_t gpio_irqs[] = {
+    {
+        .irq = S912_GPIO_IRQ_0,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_1,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_2,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_3,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_4,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_5,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_6,
+        .mode = 0,
+    },
+    {
+        .irq = S912_GPIO_IRQ_7,
+        .mode = 0,
+    },
+    {
+        .irq = S912_AO_GPIO_IRQ_0,
+        .mode = 0,
+    },
+    {
+        .irq = S912_AO_GPIO_IRQ_1,
+        .mode = 0,
+    },
+};
+
+zx_status_t Vim::GpioInit() {
+
+    pbus_dev_t gpio_dev = {};
+    gpio_dev.name = "gpio";
+    gpio_dev.vid = PDEV_VID_AMLOGIC;
+    gpio_dev.pid = PDEV_PID_AMLOGIC_S912;
+    gpio_dev.did = PDEV_DID_AMLOGIC_GPIO;
+    gpio_dev.mmio_list = gpio_mmios;
+    gpio_dev.mmio_count = countof(gpio_mmios);
+    gpio_dev.irq_list = gpio_irqs;
+    gpio_dev.irq_count = countof(gpio_irqs);
+
+    zx_status_t status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_GPIO_IMPL, &gpio_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "GpioInit: pbus_protocol_device_add failed: %d\n", status);
+        return status;
+    }
+
+    gpio_impl_ = ddk::GpioImplProtocolClient(parent());
+    if (!gpio_impl_.is_valid()) {
+        zxlogf(ERROR, "%s: device_get_protocol failed\n", __func__);
+        return ZX_ERR_INTERNAL;
+    }
+
+    if (enable_gpio_test_) {
+        const pbus_gpio_t gpio_test_gpios[] = {
+            {
+                // SYS_LED
+                .gpio = S912_GPIOAO(9),
+            },
+            {
+                // GPIO PIN
+                .gpio = S912_GPIOAO(2),
+            },
+        };
+
+        pbus_dev_t gpio_test_dev = {};
+        gpio_test_dev.name = "vim-gpio-test";
+        gpio_test_dev.vid = PDEV_VID_GENERIC;
+        gpio_test_dev.pid = PDEV_PID_GENERIC;
+        gpio_test_dev.did = PDEV_DID_GPIO_TEST;
+        gpio_test_dev.gpio_list = gpio_test_gpios;
+        gpio_test_dev.gpio_count = countof(gpio_test_gpios);
+
+        status = pbus_.DeviceAdd(&gpio_test_dev);
+        if (status != ZX_OK) {
+            zxlogf(ERROR, "GpioInit could not add gpio_test_dev: %d\n", status);
+            return status;
+        }
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-i2c.c b/system/dev/board/vim/vim-i2c.c
deleted file mode 100644
index 3f64524..0000000
--- a/system/dev/board/vim/vim-i2c.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include <limits.h>
-
-#include "vim.h"
-
-static const pbus_mmio_t i2c_mmios[] = {
-    {
-        .base = S912_I2C_A_BASE,
-        .length = S912_I2C_A_LENGTH,
-    },
-    {
-        .base = S912_I2C_B_BASE,
-        .length = S912_I2C_B_LENGTH,
-    },
-    {
-        .base = S912_I2C_C_BASE,
-        .length = S912_I2C_C_LENGTH,
-    },
-/*
-    {
-        .base = S912_I2C_D_BASE,
-        .length = S912_I2C_D_LENGTH,
-    },
-*/
-};
-
-static const pbus_irq_t i2c_irqs[] = {
-    {
-        .irq = S912_M_I2C_0_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_M_I2C_1_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_M_I2C_2_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-/*
-    {
-        .irq = S912_M_I2C_3_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-*/
-};
-
-static const pbus_dev_t i2c_dev = {
-    .name = "i2c",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_I2C,
-    .mmio_list = i2c_mmios,
-    .mmio_count = countof(i2c_mmios),
-    .irq_list = i2c_irqs,
-    .irq_count = countof(i2c_irqs),
-};
-
-zx_status_t vim_i2c_init(vim_bus_t* bus) {
-    // setup pinmux for our I2C busses
-    // I2C_A and I2C_B are exposed on the 40 pin header and I2C_C on the FPC connector
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_A, S912_I2C_SDA_A_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_A, S912_I2C_SCK_A_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_B, S912_I2C_SDA_B_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_B, S912_I2C_SCK_B_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_C, S912_I2C_SDA_C_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_C, S912_I2C_SCK_C_FN);
-
-    zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_I2C_IMPL, &i2c_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_i2c_init: pbus_protocol_device_add failed: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-i2c.cpp b/system/dev/board/vim/vim-i2c.cpp
new file mode 100644
index 0000000..fe6ece5
--- /dev/null
+++ b/system/dev/board/vim/vim-i2c.cpp
@@ -0,0 +1,88 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include <limits.h>
+
+#include "vim.h"
+
+namespace vim {
+
+static const pbus_mmio_t i2c_mmios[] = {
+    {
+        .base = S912_I2C_A_BASE,
+        .length = S912_I2C_A_LENGTH,
+    },
+    {
+        .base = S912_I2C_B_BASE,
+        .length = S912_I2C_B_LENGTH,
+    },
+    {
+        .base = S912_I2C_C_BASE,
+        .length = S912_I2C_C_LENGTH,
+    },
+    /*
+    {
+        .base = S912_I2C_D_BASE,
+        .length = S912_I2C_D_LENGTH,
+    },
+*/
+};
+
+static const pbus_irq_t i2c_irqs[] = {
+    {
+        .irq = S912_M_I2C_0_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_M_I2C_1_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_M_I2C_2_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    /*
+    {
+        .irq = S912_M_I2C_3_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+*/
+};
+
+zx_status_t Vim::I2cInit() {
+
+    pbus_dev_t i2c_dev = {};
+    i2c_dev.name = "i2c";
+    i2c_dev.vid = PDEV_VID_AMLOGIC;
+    i2c_dev.pid = PDEV_PID_GENERIC;
+    i2c_dev.did = PDEV_DID_AMLOGIC_I2C;
+    i2c_dev.mmio_list = i2c_mmios;
+    i2c_dev.mmio_count = countof(i2c_mmios);
+    i2c_dev.irq_list = i2c_irqs;
+    i2c_dev.irq_count = countof(i2c_irqs);
+
+    // setup pinmux for our I2C busses
+    // I2C_A and I2C_B are exposed on the 40 pin header and I2C_C on the FPC connector
+    gpio_impl_.SetAltFunction(S912_I2C_SDA_A, S912_I2C_SDA_A_FN);
+    gpio_impl_.SetAltFunction(S912_I2C_SCK_A, S912_I2C_SCK_A_FN);
+    gpio_impl_.SetAltFunction(S912_I2C_SDA_B, S912_I2C_SDA_B_FN);
+    gpio_impl_.SetAltFunction(S912_I2C_SCK_B, S912_I2C_SCK_B_FN);
+    gpio_impl_.SetAltFunction(S912_I2C_SDA_C, S912_I2C_SDA_C_FN);
+    gpio_impl_.SetAltFunction(S912_I2C_SCK_C, S912_I2C_SCK_C_FN);
+
+    zx_status_t status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_I2C_IMPL, &i2c_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "I2cInit: pbus_protocol_device_add failed: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-led2472g.c b/system/dev/board/vim/vim-led2472g.c
deleted file mode 100644
index a30e666..0000000
--- a/system/dev/board/vim/vim-led2472g.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include "vim.h"
-
-static const pbus_i2c_channel_t led2472g_channels[] = {
-    {
-        .bus_id = 0,
-        .address = 0x46,
-    },
-};
-
-static const pbus_dev_t led2472g_dev = {
-    .name = "led2472g",
-    .vid = PDEV_VID_GENERIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_LED2472G,
-    .i2c_channel_list = led2472g_channels,
-    .i2c_channel_count = countof(led2472g_channels),
-};
-
-zx_status_t vim_led2472g_init(vim_bus_t* bus) {
-    zx_status_t status;
-    if ((status = pbus_device_add(&bus->pbus, &led2472g_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_led2472g_init: pbus_device_add() failed for led2472g: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-led2472g.cpp b/system/dev/board/vim/vim-led2472g.cpp
new file mode 100644
index 0000000..63b679e
--- /dev/null
+++ b/system/dev/board/vim/vim-led2472g.cpp
@@ -0,0 +1,38 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include "vim.h"
+
+namespace vim {
+static const pbus_i2c_channel_t led2472g_channels[] = {
+    {
+        .bus_id = 0,
+        .address = 0x46,
+    },
+};
+
+zx_status_t Vim::Led2472gInit() {
+    zx_status_t status;
+    pbus_dev_t led2472g_dev = {};
+    led2472g_dev.name = "led2472g";
+    led2472g_dev.vid = PDEV_VID_GENERIC;
+    led2472g_dev.pid = PDEV_PID_GENERIC;
+    led2472g_dev.did = PDEV_DID_LED2472G;
+    led2472g_dev.i2c_channel_list = led2472g_channels;
+    led2472g_dev.i2c_channel_count = countof(led2472g_channels);
+
+    if ((status = pbus_.DeviceAdd(&led2472g_dev)) != ZX_OK) {
+        zxlogf(ERROR, "Led2472gInit: pbus_device_add() failed for led2472g: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-mali.c b/system/dev/board/vim/vim-mali.cpp
similarity index 63%
rename from system/dev/board/vim/vim-mali.c
rename to system/dev/board/vim/vim-mali.cpp
index 5c53bbe..fec71cf 100644
--- a/system/dev/board/vim/vim-mali.c
+++ b/system/dev/board/vim/vim-mali.cpp
@@ -9,6 +9,7 @@
 
 #include "vim.h"
 
+namespace vim {
 static const pbus_mmio_t mali_mmios[] = {
     {
         .base = S912_MALI_BASE,
@@ -46,29 +47,28 @@
     },
 };
 
-static const pbus_dev_t mali_dev = {
-    .name = "mali",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_AMLOGIC_S912,
-    .did = PDEV_DID_ARM_MALI_INIT,
-    .mmio_list = mali_mmios,
-    .mmio_count = countof(mali_mmios),
-    .irq_list = mali_irqs,
-    .irq_count = countof(mali_irqs),
-    .bti_list = mali_btis,
-    .bti_count = countof(mali_btis),
-};
-
-zx_status_t vim_mali_init(vim_bus_t* bus, uint32_t bti_index) {
+zx_status_t Vim::MaliInit() {
+    pbus_dev_t mali_dev = {};
+    mali_dev.name = "mali";
+    mali_dev.vid = PDEV_VID_AMLOGIC;
+    mali_dev.pid = PDEV_PID_AMLOGIC_S912;
+    mali_dev.did = PDEV_DID_ARM_MALI_INIT;
+    mali_dev.mmio_list = mali_mmios;
+    mali_dev.mmio_count = countof(mali_mmios);
+    mali_dev.irq_list = mali_irqs;
+    mali_dev.irq_count = countof(mali_irqs);
+    mali_dev.bti_list = mali_btis;
+    mali_dev.bti_count = countof(mali_btis);
 
     // Populate the BTI information
     mali_btis[0].iommu_index = 0;
-    mali_btis[0].bti_id      = bti_index;
+    mali_btis[0].bti_id = BTI_MALI;
 
-    zx_status_t status = pbus_device_add(&bus->pbus, &mali_dev);
+    zx_status_t status = pbus_.DeviceAdd(&mali_dev);
     if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_mali_init: pbus_device_add failed: %d\n", status);
+        zxlogf(ERROR, "MaliInit: pbus_device_add failed: %d\n", status);
         return status;
     }
     return status;
 }
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-rtc.c b/system/dev/board/vim/vim-rtc.c
deleted file mode 100644
index 9835741..0000000
--- a/system/dev/board/vim/vim-rtc.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-
-#include <limits.h>
-
-#include "vim.h"
-
-static const pbus_i2c_channel_t pcf8563_rtc_i2c[] = {
-    {
-        .bus_id = 1,
-        .address = 0x51,
-    },
-};
-
-static pbus_dev_t pcf8563_rtc_dev = {
-    .name = "pcf8563-rtc",
-    .vid = PDEV_VID_NXP,
-    .did = PDEV_DID_PCF8563_RTC,
-    .i2c_channel_list = pcf8563_rtc_i2c,
-    .i2c_channel_count = countof(pcf8563_rtc_i2c),
-};
-
-zx_status_t vim_rtc_init(vim_bus_t* bus) {
-
-    zx_status_t status = pbus_device_add(&bus->pbus, &pcf8563_rtc_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "%s(pcf8563): pbus_device_add failed: %d\n", __FUNCTION__, status);
-    }
-
-    return status;
-}
diff --git a/system/dev/board/vim/vim-rtc.cpp b/system/dev/board/vim/vim-rtc.cpp
new file mode 100644
index 0000000..1dcbc14
--- /dev/null
+++ b/system/dev/board/vim/vim-rtc.cpp
@@ -0,0 +1,40 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+
+#include <limits.h>
+
+#include "vim.h"
+
+namespace vim {
+
+static const pbus_i2c_channel_t pcf8563_rtc_i2c[] = {
+    {
+        .bus_id = 1,
+        .address = 0x51,
+    },
+};
+
+zx_status_t Vim::RtcInit() {
+    pbus_dev_t pcf8563_rtc_dev = {};
+
+    pcf8563_rtc_dev.name = "pcf8563-rtc";
+    pcf8563_rtc_dev.vid = PDEV_VID_NXP;
+    pcf8563_rtc_dev.pid = PDEV_PID_GENERIC;
+    pcf8563_rtc_dev.did = PDEV_DID_PCF8563_RTC;
+    pcf8563_rtc_dev.i2c_channel_list = pcf8563_rtc_i2c;
+    pcf8563_rtc_dev.i2c_channel_count = countof(pcf8563_rtc_i2c);
+
+    zx_status_t status = pbus_.DeviceAdd(&pcf8563_rtc_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "RtcInit: pbus_device_add failed: %d\n", status);
+    }
+
+    return status;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-sd-emmc.c b/system/dev/board/vim/vim-sd-emmc.c
deleted file mode 100644
index c5fd7ab..0000000
--- a/system/dev/board/vim/vim-sd-emmc.c
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/metadata.h>
-#include <ddk/platform-defs.h>
-#include <hw/reg.h>
-#include <soc/aml-s912/s912-hw.h>
-#include <soc/aml-a113/a113-hw.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-common/aml-sd-emmc.h>
-
-#include "vim.h"
-
-#define BIT_MASK(start, count) (((1 << (count)) - 1) << (start))
-#define SET_BITS(dest, start, count, value) \
-        ((dest & ~BIT_MASK(start, count)) | (((value) << (start)) & BIT_MASK(start, count)))
-
-/*static const pbus_mmio_t sdio_mmios[] = {
-    {
-        .base = 0xD0070000,
-        .length = 0x2000,
-    }
-};
-
-static const pbus_mmio_t sd_mmios[] = {
-    {
-        .base = 0xD0072000,
-        .length = 0x2000,
-    }
-};*/
-
-/*static const pbus_irq_t sdio_irqs[] = {
-    {
-        .irq = 248,
-    },
-};
-
-static const pbus_irq_t sd_irqs[] = {
-    {
-        .irq = 249,
-    },
-};*/
-
-static const pbus_mmio_t emmc_mmios[] = {
-    {
-        .base = 0xD0074000,
-        .length = 0x2000,
-    }
-};
-
-static const pbus_irq_t emmc_irqs[] = {
-    {
-        .irq = 250,
-    },
-};
-
-static const pbus_bti_t emmc_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_EMMC,
-    },
-};
-
-static const pbus_gpio_t emmc_gpios[] = {
-    {
-        .gpio = S912_EMMC_RST,
-    },
-};
-
-static aml_sd_emmc_config_t config = {
-    //As per AMlogic, on S912 chipset, HS400 mode can be operated at 125MHZ or low.
-    .supports_dma = true,
-    .min_freq = 400000,
-    .max_freq = 120000000,
-};
-
-static const pbus_metadata_t emmc_metadata[] = {
-    {
-        .type       = DEVICE_METADATA_PRIVATE,
-        .data_buffer       = &config,
-        .data_size        = sizeof(config),
-    },
-};
-
-static const pbus_boot_metadata_t emmc_boot_metadata[] = {
-    {
-        .zbi_type = DEVICE_METADATA_PARTITION_MAP,
-        .zbi_extra = 0,
-    },
-};
-
-static const pbus_dev_t emmc_dev = {
-    .name = "aml_emmc",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_SD_EMMC,
-    .mmio_list = emmc_mmios,
-    .mmio_count = countof(emmc_mmios),
-    .irq_list = emmc_irqs,
-    .irq_count = countof(emmc_irqs),
-    .bti_list = emmc_btis,
-    .bti_count = countof(emmc_btis),
-    .gpio_list = emmc_gpios,
-    .gpio_count = countof(emmc_gpios),
-    .metadata_list = emmc_metadata,
-    .metadata_count = countof(emmc_metadata),
-    .boot_metadata_list = emmc_boot_metadata,
-    .boot_metadata_count = countof(emmc_boot_metadata),
-};
-
-zx_status_t vim_sd_emmc_init(vim_bus_t* bus) {
-    zx_status_t status;
-
-    // set alternate functions to enable EMMC
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D0, S912_EMMC_NAND_D0_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D1, S912_EMMC_NAND_D1_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D2, S912_EMMC_NAND_D2_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D3, S912_EMMC_NAND_D3_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D4, S912_EMMC_NAND_D4_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D5, S912_EMMC_NAND_D5_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D6, S912_EMMC_NAND_D6_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D7, S912_EMMC_NAND_D7_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_CLK, S912_EMMC_CLK_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_RST, S912_EMMC_RST_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_CMD, S912_EMMC_CMD_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_DS, S912_EMMC_DS_FN);
-
-    if ((status = pbus_device_add(&bus->pbus, &emmc_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sd_emmc_init could not add emmc_dev: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-sd-emmc.cpp b/system/dev/board/vim/vim-sd-emmc.cpp
new file mode 100644
index 0000000..d99c981
--- /dev/null
+++ b/system/dev/board/vim/vim-sd-emmc.cpp
@@ -0,0 +1,113 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/metadata.h>
+#include <ddk/platform-defs.h>
+#include <hw/reg.h>
+#include <soc/aml-a113/a113-hw.h>
+#include <soc/aml-common/aml-sd-emmc.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include "vim.h"
+
+namespace vim {
+#define BIT_MASK(start, count) (((1 << (count)) - 1) << (start))
+#define SET_BITS(dest, start, count, value) \
+    ((dest & ~BIT_MASK(start, count)) | (((value) << (start)) & BIT_MASK(start, count)))
+
+static const pbus_mmio_t emmc_mmios[] = {
+    {
+        .base = 0xD0074000,
+        .length = 0x2000,
+    }};
+
+static const pbus_irq_t emmc_irqs[] = {
+    {
+        .irq = 250,
+        //c++ initialization error
+        .mode = 0
+        //c++ initialization error
+    },
+};
+
+static const pbus_bti_t emmc_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_EMMC,
+    },
+};
+
+static const pbus_gpio_t emmc_gpios[] = {
+    {
+        .gpio = S912_EMMC_RST,
+    },
+};
+
+static aml_sd_emmc_config_t config = {
+    //As per AMlogic, on S912 chipset, HS400 mode can be operated at 125MHZ or low.
+    .supports_dma = true,
+    .min_freq = 400000,
+    .max_freq = 120000000,
+};
+
+static const pbus_metadata_t emmc_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &config,
+        .data_size = sizeof(config),
+    },
+};
+
+static const pbus_boot_metadata_t emmc_boot_metadata[] = {
+    {
+        .zbi_type = DEVICE_METADATA_PARTITION_MAP,
+        .zbi_extra = 0,
+    },
+};
+
+zx_status_t Vim::SdEmmcInit() {
+    zx_status_t status;
+
+    pbus_dev_t emmc_dev = {};
+    emmc_dev.name = "aml_emmc";
+    emmc_dev.vid = PDEV_VID_AMLOGIC;
+    emmc_dev.pid = PDEV_PID_GENERIC;
+    emmc_dev.did = PDEV_DID_AMLOGIC_SD_EMMC;
+    emmc_dev.mmio_list = emmc_mmios;
+    emmc_dev.mmio_count = countof(emmc_mmios);
+    emmc_dev.irq_list = emmc_irqs;
+    emmc_dev.irq_count = countof(emmc_irqs);
+    emmc_dev.gpio_list = emmc_gpios;
+    emmc_dev.gpio_count = countof(emmc_gpios);
+    emmc_dev.bti_list = emmc_btis;
+    emmc_dev.bti_count = countof(emmc_btis);
+    emmc_dev.metadata_list = emmc_metadata;
+    emmc_dev.metadata_count = countof(emmc_metadata);
+    emmc_dev.boot_metadata_list = emmc_boot_metadata;
+    emmc_dev.boot_metadata_count = countof(emmc_boot_metadata);
+
+    // set alternate functions to enable EMMC
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D0, S912_EMMC_NAND_D0_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D1, S912_EMMC_NAND_D1_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D2, S912_EMMC_NAND_D2_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D3, S912_EMMC_NAND_D3_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D4, S912_EMMC_NAND_D4_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D5, S912_EMMC_NAND_D5_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D6, S912_EMMC_NAND_D6_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_NAND_D7, S912_EMMC_NAND_D7_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_CLK, S912_EMMC_CLK_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_RST, S912_EMMC_RST_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_CMD, S912_EMMC_CMD_FN);
+    gpio_impl_.SetAltFunction(S912_EMMC_DS, S912_EMMC_DS_FN);
+
+    if ((status = pbus_.DeviceAdd(&emmc_dev)) != ZX_OK) {
+        zxlogf(ERROR, "SdEmmcInit could not add emmc_dev: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-sdio.c b/system/dev/board/vim/vim-sdio.c
deleted file mode 100644
index e358e0c..0000000
--- a/system/dev/board/vim/vim-sdio.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/metadata.h>
-#include <ddk/platform-defs.h>
-#include <hw/reg.h>
-#include <soc/aml-s912/s912-hw.h>
-#include <soc/aml-a113/a113-hw.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-common/aml-sd-emmc.h>
-#include <wifi/wifi-config.h>
-
-#include "vim.h"
-
-static const pbus_gpio_t wifi_gpios[] = {
-    {
-        .gpio = S912_WIFI_SDIO_WAKE_HOST,
-    },
-    {
-        // For debugging purposes.
-        .gpio = S912_GPIODV(13),
-    },
-};
-
-static const wifi_config_t wifi_config = {
-    .oob_irq_mode = ZX_INTERRUPT_MODE_LEVEL_HIGH,
-};
-
-static const pbus_metadata_t wifi_metadata[] = {
-    {
-        .type       = DEVICE_METADATA_PRIVATE,
-        .data_buffer       = &wifi_config,
-        .data_size        = sizeof(wifi_config),
-    }
-};
-
-static const pbus_dev_t sdio_children[] = {
-    {
-        // Wifi driver.
-        .name = "vim2-wifi",
-        .gpio_list = wifi_gpios,
-        .gpio_count = countof(wifi_gpios),
-        .metadata_list = wifi_metadata,
-        .metadata_count = countof(wifi_metadata),
-    },
-};
-
-static const pbus_dev_t aml_sd_emmc_children[] = {
-    {
-        // Generic SDIO driver.
-        .name = "sdio",
-        .child_list = sdio_children,
-        .child_count = countof(sdio_children),
-    },
-};
-
-static const pbus_mmio_t aml_sd_emmc_mmios[] = {
-    {
-        .base = 0xD0070000,
-        .length = 0x2000,
-    }
-};
-
-static const pbus_irq_t aml_sd_emmc_irqs[] = {
-    {
-        .irq = 248,
-    },
-};
-
-static const pbus_bti_t aml_sd_emmc_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_SDIO,
-    },
-};
-
-static const pbus_gpio_t aml_sd_emmc_gpios[] = {
-    {
-        .gpio = S912_GPIOX(6),
-    },
-};
-
-static aml_sd_emmc_config_t config = {
-    .min_freq = 400000,
-    .max_freq = 125000000,
-    .supports_dma = true,
-};
-
-static const pbus_metadata_t aml_sd_emmc_metadata[] = {
-    {
-        .type       = DEVICE_METADATA_PRIVATE,
-        .data_buffer       = &config,
-        .data_size        = sizeof(config),
-    }
-};
-
-static const pbus_dev_t aml_sd_emmc_dev = {
-    .name = "aml-sdio",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_SD_EMMC,
-    .mmio_list = aml_sd_emmc_mmios,
-    .mmio_count = countof(aml_sd_emmc_mmios),
-    .irq_list = aml_sd_emmc_irqs,
-    .irq_count = countof(aml_sd_emmc_irqs),
-    .bti_list = aml_sd_emmc_btis,
-    .bti_count = countof(aml_sd_emmc_btis),
-    .gpio_list = aml_sd_emmc_gpios,
-    .gpio_count = countof(aml_sd_emmc_gpios),
-    .metadata_list = aml_sd_emmc_metadata,
-    .metadata_count = countof(aml_sd_emmc_metadata),
-    .child_list = aml_sd_emmc_children,
-    .child_count = countof(aml_sd_emmc_children),
-};
-
-zx_status_t vim_sdio_init(vim_bus_t* bus) {
-    zx_status_t status;
-
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D0, S912_WIFI_SDIO_D0_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D1, S912_WIFI_SDIO_D1_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D2, S912_WIFI_SDIO_D2_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D3, S912_WIFI_SDIO_D3_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_CLK, S912_WIFI_SDIO_CLK_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_CMD, S912_WIFI_SDIO_CMD_FN);
-    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_WAKE_HOST, S912_WIFI_SDIO_WAKE_HOST_FN);
-
-    if ((status = pbus_device_add(&bus->pbus, &aml_sd_emmc_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sdio_init could not add aml_sd_emmc_dev: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-sdio.cpp b/system/dev/board/vim/vim-sdio.cpp
new file mode 100644
index 0000000..66f78d7
--- /dev/null
+++ b/system/dev/board/vim/vim-sdio.cpp
@@ -0,0 +1,144 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/metadata.h>
+#include <ddk/platform-defs.h>
+#include <hw/reg.h>
+#include <soc/aml-a113/a113-hw.h>
+#include <soc/aml-common/aml-sd-emmc.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+#include <wifi/wifi-config.h>
+
+#include "vim.h"
+
+namespace vim {
+static const pbus_gpio_t wifi_gpios[] = {
+    {
+        .gpio = S912_WIFI_SDIO_WAKE_HOST,
+    },
+    {
+        // For debugging purposes.
+        .gpio = S912_GPIODV(13),
+    },
+};
+
+static const wifi_config_t wifi_config = {
+    .oob_irq_mode = ZX_INTERRUPT_MODE_LEVEL_HIGH,
+};
+
+static const pbus_metadata_t wifi_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &wifi_config,
+        .data_size = sizeof(wifi_config),
+    }};
+
+static const pbus_dev_t sdio_children[] = {
+    []() {
+        // Wifi driver.
+        pbus_dev_t dev;
+        dev.name = "vim2-wifi";
+        dev.gpio_list = wifi_gpios;
+        dev.gpio_count = countof(wifi_gpios);
+        dev.metadata_list = wifi_metadata;
+        dev.metadata_count = countof(wifi_metadata);
+        return dev;
+    }(),
+};
+
+static const pbus_dev_t aml_sd_emmc_children[] = {
+    []() {
+        // Generic SDIO driver.
+        pbus_dev_t dev;
+        dev.name = "sdio";
+        dev.child_list = sdio_children;
+        dev.child_count = countof(sdio_children);
+        return dev;
+    }(),
+};
+
+static const pbus_mmio_t aml_sd_emmc_mmios[] = {
+    {
+        .base = 0xD0070000,
+        .length = 0x2000,
+    }};
+
+static const pbus_irq_t aml_sd_emmc_irqs[] = {
+    {
+        .irq = 248,
+        //c++ initialization error
+        .mode = 0,
+        //c++ initialization error
+    },
+};
+
+static const pbus_bti_t aml_sd_emmc_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_SDIO,
+    },
+};
+
+static const pbus_gpio_t aml_sd_emmc_gpios[] = {
+    {
+        .gpio = S912_GPIOX(6),
+    },
+};
+
+static aml_sd_emmc_config_t config = {
+    .supports_dma = true,
+    .min_freq = 400000,
+    .max_freq = 125000000,
+};
+
+static const pbus_metadata_t aml_sd_emmc_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &config,
+        .data_size = sizeof(config),
+    }};
+
+static const pbus_dev_t aml_sd_emmc_dev = []() {
+    pbus_dev_t dev;
+
+    dev.name = "aml-sdio";
+    dev.vid = PDEV_VID_AMLOGIC;
+    dev.pid = PDEV_PID_GENERIC;
+    dev.did = PDEV_DID_AMLOGIC_SD_EMMC;
+    dev.mmio_list = aml_sd_emmc_mmios;
+    dev.mmio_count = countof(aml_sd_emmc_mmios);
+    dev.irq_list = aml_sd_emmc_irqs;
+    dev.irq_count = countof(aml_sd_emmc_irqs);
+    dev.gpio_list = aml_sd_emmc_gpios;
+    dev.gpio_count = countof(aml_sd_emmc_gpios);
+    dev.bti_list = aml_sd_emmc_btis;
+    dev.bti_count = countof(aml_sd_emmc_btis);
+    dev.metadata_list = aml_sd_emmc_metadata;
+    dev.metadata_count = countof(aml_sd_emmc_metadata);
+    dev.child_list = aml_sd_emmc_children;
+    dev.child_count = countof(aml_sd_emmc_children);
+    return dev;
+}();
+
+zx_status_t Vim::SdioInit() {
+    zx_status_t status;
+
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_D0, S912_WIFI_SDIO_D0_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_D1, S912_WIFI_SDIO_D1_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_D2, S912_WIFI_SDIO_D2_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_D3, S912_WIFI_SDIO_D3_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_CLK, S912_WIFI_SDIO_CLK_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_CMD, S912_WIFI_SDIO_CMD_FN);
+    gpio_impl_.SetAltFunction(S912_WIFI_SDIO_WAKE_HOST, S912_WIFI_SDIO_WAKE_HOST_FN);
+
+    if ((status = pbus_.DeviceAdd(&aml_sd_emmc_dev)) != ZX_OK) {
+        zxlogf(ERROR, "SdioInit could not add aml_sd_emmc_dev: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-sysmem.c b/system/dev/board/vim/vim-sysmem.c
deleted file mode 100644
index 85a8ecd..0000000
--- a/system/dev/board/vim/vim-sysmem.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include "vim.h"
-
-static const pbus_bti_t sysmem_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_SYSMEM,
-    },
-};
-
-static const pbus_dev_t sysmem_dev = {
-    .name = "sysmem",
-    .vid = PDEV_VID_GENERIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_SYSMEM,
-    .bti_list = sysmem_btis,
-    .bti_count = countof(sysmem_btis),
-};
-
-zx_status_t vim_sysmem_init(vim_bus_t* bus) {
-    zx_status_t status;
-
-    if ((status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_SYSMEM, &sysmem_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sysmem_init: pbus_protocol_device_add() failed for sysmem: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-sysmem.cpp b/system/dev/board/vim/vim-sysmem.cpp
new file mode 100644
index 0000000..a09a115
--- /dev/null
+++ b/system/dev/board/vim/vim-sysmem.cpp
@@ -0,0 +1,40 @@
+// Copyright 2019 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 "vim.h"
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+
+namespace vim {
+static const pbus_bti_t sysmem_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_SYSMEM,
+    },
+};
+
+static const pbus_dev_t sysmem_dev = []() {
+    pbus_dev_t dev;
+    dev.name = "sysmem";
+    dev.vid = PDEV_VID_GENERIC;
+    dev.pid = PDEV_PID_GENERIC;
+    dev.did = PDEV_DID_SYSMEM;
+    dev.bti_list = sysmem_btis;
+    dev.bti_count = countof(sysmem_btis);
+    return dev;
+}();
+
+zx_status_t Vim::SysmemInit() {
+    zx_status_t status;
+
+    if ((status = pbus_.ProtocolDeviceAdd(ZX_PROTOCOL_SYSMEM, &sysmem_dev)) != ZX_OK) {
+        zxlogf(ERROR, "SysmemInit: pbus_protocol_device_add() failed for sysmem: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
diff --git a/system/dev/board/vim/vim-thermal.c b/system/dev/board/vim/vim-thermal.c
deleted file mode 100644
index a441ac8..0000000
--- a/system/dev/board/vim/vim-thermal.c
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/metadata.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-s912/s912-hw.h>
-#include <soc/aml-common/aml-thermal.h>
-#include "vim.h"
-
-static const pbus_mmio_t mailbox_mmios[] = {
-    // Mailbox
-    {
-        .base = S912_HIU_MAILBOX_BASE,
-        .length = S912_HIU_MAILBOX_LENGTH,
-    },
-    // Mailbox Payload
-    {
-        .base = S912_MAILBOX_PAYLOAD_BASE,
-        .length = S912_MAILBOX_PAYLOAD_LENGTH,
-    },
-};
-
-// IRQ for Mailbox
-static const pbus_irq_t mailbox_irqs[] = {
-    {
-        .irq = S912_MBOX_IRQ_RECEIV0,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-    {
-        .irq = S912_MBOX_IRQ_RECEIV1,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-    {
-        .irq = S912_MBOX_IRQ_RECEIV2,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-    {
-        .irq = S912_MBOX_IRQ_SEND3,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-    {
-        .irq = S912_MBOX_IRQ_SEND4,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-    {
-        .irq = S912_MBOX_IRQ_SEND5,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
-    },
-};
-
-static const pbus_gpio_t fanctl_gpios[] = {
-    {
-        .gpio = S912_GPIODV(14),
-    },
-    {
-        .gpio = S912_GPIODV(15),
-    }
-};
-
-/* ACTIVE COOLING - For VIM2, we assume that all devices
- * are connected with a GPIO-controlled fan.
- * The GPIO controlled fan has 3 levels of speed (1-3)
- *
- * PASSIVE COOLING - For VIM2, we have DVFS support added
- * Below is the operating point information for Big cluster
- * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
- * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
- * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
- * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
- * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
- * Operating point 5 - Freq 1.2000 Ghz Voltage 1.0700 V
- * Operating point 6 - Freq 1.2960 Ghz Voltage 1.1000 V
- *
- * Below is the operating point information for Little cluster
- * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
- * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
- * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
- * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
- * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
- *
- * GPU_CLK_FREQUENCY_SOURCE - For VIM2, we support GPU
- * throttling. Currently we have pre-defined frequencies
- * we can set the GPU clock to, but we can always add more
- * One's we support now are below
- * Operating point  0 - 285.7 MHz
- * Operating point  1 - 400.0 MHz
- * Operating point  2 - 500.0 MHz
- * Operating point  3 - 666.0 MHz
- * Operating point -1 - INVALID/No throttling needed
- */
-
-static thermal_device_info_t aml_vim2_config = {
-    .active_cooling                 = true,
-    .passive_cooling                = true,
-    .gpu_throttling                 = true,
-    .big_little                     = true,
-    .num_trip_points                = 8,
-    .critical_temp                  = 81,
-    .trip_point_info = {
-        {
-            // This is the initial thermal setup of the device
-            // Fan set to OFF
-            // CPU freq set to a known stable MAX
-            .fan_level                  = 0,
-            .big_cluster_dvfs_opp       = 6,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 3,
-        },
-        {
-            .fan_level                  = 1,
-            .up_temp                    = 65,
-            .down_temp                  = 63,
-            .big_cluster_dvfs_opp       = 6,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 3,
-        },
-        {
-            .fan_level                  = 2,
-            .up_temp                    = 70,
-            .down_temp                  = 68,
-            .big_cluster_dvfs_opp       = 6,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 3,
-        },
-        {
-            .fan_level                  = 3,
-            .up_temp                    = 75,
-            .down_temp                  = 73,
-            .big_cluster_dvfs_opp       = 6,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 3,
-        },
-        {
-            .fan_level                  = 3,
-            .up_temp                    = 82,
-            .down_temp                  = 79,
-            .big_cluster_dvfs_opp       = 5,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 2,
-        },
-        {
-            .fan_level                  = 3,
-            .up_temp                    = 87,
-            .down_temp                  = 84,
-            .big_cluster_dvfs_opp       = 4,
-            .little_cluster_dvfs_opp    = 4,
-            .gpu_clk_freq_source        = 2,
-        },
-        {
-            .fan_level                  = 3,
-            .up_temp                    = 92,
-            .down_temp                  = 89,
-            .big_cluster_dvfs_opp       = 3,
-            .little_cluster_dvfs_opp    = 3,
-            .gpu_clk_freq_source        = 1,
-        },
-        {
-            .fan_level                  = 3,
-            .up_temp                    = 96,
-            .down_temp                  = 93,
-            .big_cluster_dvfs_opp       = 2,
-            .little_cluster_dvfs_opp    = 2,
-            .gpu_clk_freq_source        = 0,
-        }
-    }
-};
-
-static const pbus_metadata_t vim_thermal_metadata[] = {
-    {
-        .type       = DEVICE_METADATA_PRIVATE,
-        .data_buffer       = &aml_vim2_config,
-        .data_size        = sizeof(aml_vim2_config),
-    }
-};
-
-static const pbus_dev_t scpi_children[] = {
-    // VIM2 thermal driver
-    {
-        .gpio_list = fanctl_gpios,
-        .gpio_count = countof(fanctl_gpios),
-        .metadata_list = vim_thermal_metadata,
-        .metadata_count = countof(vim_thermal_metadata),
-    },
-};
-
-static const pbus_dev_t mailbox_children[] = {
-    // Amlogic SCPI driver
-    {
-        .child_list = scpi_children,
-        .child_count = countof(scpi_children),
-    },
-};
-
-static const pbus_dev_t mailbox_dev = {
-    .name = "mailbox",
-    .vid = PDEV_VID_KHADAS,
-    .pid = PDEV_PID_VIM2,
-    .did = PDEV_DID_AMLOGIC_MAILBOX,
-    .mmio_list = mailbox_mmios,
-    .mmio_count = countof(mailbox_mmios),
-    .irq_list = mailbox_irqs,
-    .irq_count = countof(mailbox_irqs),
-    .child_list = mailbox_children,
-    .child_count = countof(mailbox_children),
-};
-
-zx_status_t vim2_thermal_init(vim_bus_t* bus) {
-    zx_status_t status = pbus_device_add(&bus->pbus, &mailbox_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim2_thermal_init: pbus_device_add failed: %d\n", status);
-        return status;
-    }
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-thermal.cpp b/system/dev/board/vim/vim-thermal.cpp
new file mode 100644
index 0000000..dc6919f
--- /dev/null
+++ b/system/dev/board/vim/vim-thermal.cpp
@@ -0,0 +1,218 @@
+// Copyright 2018 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 "vim.h"
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/metadata.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-common/aml-thermal.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+
+namespace vim {
+
+static const pbus_mmio_t mailbox_mmios[] = {
+    // Mailbox
+    {
+        .base = S912_HIU_MAILBOX_BASE,
+        .length = S912_HIU_MAILBOX_LENGTH,
+    },
+    // Mailbox Payload
+    {
+        .base = S912_MAILBOX_PAYLOAD_BASE,
+        .length = S912_MAILBOX_PAYLOAD_LENGTH,
+    },
+};
+
+// IRQ for Mailbox
+static const pbus_irq_t mailbox_irqs[] = {
+    {.irq = S912_MBOX_IRQ_RECEIV0,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+    {.irq = S912_MBOX_IRQ_RECEIV1,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+    {.irq = S912_MBOX_IRQ_RECEIV2,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+    {.irq = S912_MBOX_IRQ_SEND3,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+    {.irq = S912_MBOX_IRQ_SEND4,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+    {.irq = S912_MBOX_IRQ_SEND5,
+     .mode = ZX_INTERRUPT_MODE_EDGE_HIGH},
+};
+
+static const pbus_gpio_t fanctl_gpios[] = {
+    {
+        .gpio = S912_GPIODV(14),
+    },
+    {
+        .gpio = S912_GPIODV(15),
+    }};
+
+/* ACTIVE COOLING - For VIM2, we assume that all devices
+ * are connected with a GPIO-controlled fan.
+ * The GPIO controlled fan has 3 levels of speed (1-3)
+ *
+ * PASSIVE COOLING - For VIM2, we have DVFS support added
+ * Below is the operating point information for Big cluster
+ * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
+ * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
+ * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
+ * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
+ * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
+ * Operating point 5 - Freq 1.2000 Ghz Voltage 1.0700 V
+ * Operating point 6 - Freq 1.2960 Ghz Voltage 1.1000 V
+ *
+ * Below is the operating point information for Little cluster
+ * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
+ * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
+ * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
+ * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
+ * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
+ *
+ * GPU_CLK_FREQUENCY_SOURCE - For VIM2, we support GPU
+ * throttling. Currently we have pre-defined frequencies
+ * we can set the GPU clock to, but we can always add more
+ * One's we support now are below
+ * Operating point  0 - 285.7 MHz
+ * Operating point  1 - 400.0 MHz
+ * Operating point  2 - 500.0 MHz
+ * Operating point  3 - 666.0 MHz
+ * Operating point -1 - INVALID/No throttling needed
+ */
+
+static thermal_device_info_t aml_vim2_config = {
+    .active_cooling = true,
+    .passive_cooling = true,
+    .gpu_throttling = true,
+    .num_trip_points = 8,
+    .big_little = true,
+    .critical_temp = 81,
+    .trip_point_info = {
+        {
+            // This is the initial thermal setup of the device
+            // Fan set to OFF
+            // CPU freq set to a known stable MAX
+
+            //c++ initialization error
+            .up_temp = 2,
+            .down_temp = 0,
+            //c++ initialization error
+            .fan_level = 0,
+            .big_cluster_dvfs_opp = 6,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 3,
+        },
+        {
+            .up_temp = 65,
+            .down_temp = 63,
+            .fan_level = 1,
+            .big_cluster_dvfs_opp = 6,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 3,
+        },
+        {
+            .up_temp = 70,
+            .down_temp = 68,
+            .fan_level = 2,
+            .big_cluster_dvfs_opp = 6,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 3,
+        },
+        {
+            .up_temp = 75,
+            .down_temp = 73,
+            .fan_level = 3,
+            .big_cluster_dvfs_opp = 6,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 3,
+        },
+        {
+            .up_temp = 82,
+            .down_temp = 79,
+            .fan_level = 3,
+            .big_cluster_dvfs_opp = 5,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 2,
+        },
+        {
+            .up_temp = 87,
+            .down_temp = 84,
+            .fan_level = 3,
+            .big_cluster_dvfs_opp = 4,
+            .little_cluster_dvfs_opp = 4,
+            .gpu_clk_freq_source = 2,
+        },
+        {
+            .up_temp = 92,
+            .down_temp = 89,
+            .fan_level = 3,
+            .big_cluster_dvfs_opp = 3,
+            .little_cluster_dvfs_opp = 3,
+            .gpu_clk_freq_source = 1,
+        },
+        {
+            .up_temp = 96,
+            .down_temp = 93,
+            .fan_level = 3,
+            .big_cluster_dvfs_opp = 2,
+            .little_cluster_dvfs_opp = 2,
+            .gpu_clk_freq_source = 0,
+        },
+    },
+    .opps = {},
+};
+
+static const pbus_metadata_t vim_thermal_metadata[] = {
+    {
+        .type = DEVICE_METADATA_PRIVATE,
+        .data_buffer = &aml_vim2_config,
+        .data_size = sizeof(aml_vim2_config),
+    }};
+
+static const pbus_dev_t scpi_children[] = {
+    // VIM2 thermal driver
+    []() {
+        pbus_dev_t dev;
+        dev.gpio_list = fanctl_gpios;
+        dev.gpio_count = countof(fanctl_gpios);
+        dev.metadata_list = vim_thermal_metadata;
+        dev.metadata_count = countof(vim_thermal_metadata);
+        return dev;
+    }(),
+};
+
+static const pbus_dev_t mailbox_children[] = {
+    // Amlogic SCPI driver
+    []() {
+        pbus_dev_t dev;
+        dev.child_list = scpi_children;
+        dev.child_count = countof(scpi_children);
+        return dev;
+    }(),
+};
+
+zx_status_t Vim::ThermalInit() {
+    pbus_dev_t mailbox_dev = {};
+    mailbox_dev.name = "mailbox";
+    mailbox_dev.vid = PDEV_VID_KHADAS;
+    mailbox_dev.pid = PDEV_PID_VIM2;
+    mailbox_dev.did = PDEV_DID_AMLOGIC_MAILBOX;
+    mailbox_dev.mmio_list = mailbox_mmios;
+    mailbox_dev.mmio_count = countof(mailbox_mmios);
+    mailbox_dev.irq_list = mailbox_irqs;
+    mailbox_dev.irq_count = countof(mailbox_irqs);
+    mailbox_dev.child_list = mailbox_children;
+    mailbox_dev.child_count = countof(mailbox_children);
+
+    zx_status_t status = pbus_.DeviceAdd(&mailbox_dev);
+
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "ThermalInit: pbus_device_add failed: %d\n", status);
+        return status;
+    }
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-uart.c b/system/dev/board/vim/vim-uart.c
deleted file mode 100644
index 18a5fce..0000000
--- a/system/dev/board/vim/vim-uart.c
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/mmio-buffer.h>
-#include <ddk/metadata.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/gpio.h>
-#include <ddk/protocol/platform/bus.h>
-#include <ddk/protocol/serial.h>
-#include <hw/reg.h>
-#include <soc/aml-s912/s912-gpio.h>
-#include <soc/aml-s912/s912-hw.h>
-#include <unistd.h>
-#include <zircon/device/serial.h>
-
-#include "vim.h"
-
-// set this to enable UART test driver, which uses the second UART
-// on the 40 pin header
-#define UART_TEST 1
-
-#define WIFI_32K    S912_GPIOX(16)
-#define BT_EN       S912_GPIOX(17)
-
-
-static const pbus_mmio_t bt_uart_mmios[] = {
-    // UART_A, for BT HCI
-    {
-        .base = S912_UART_A_BASE,
-        .length = S912_UART_A_LENGTH,
-    },
-};
-
-static const pbus_irq_t bt_uart_irqs[] = {
-    // UART_A, for BT HCI
-    {
-        .irq = S912_UART_A_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-};
-
-static const serial_port_info_t bt_uart_serial_info = {
-    .serial_class = SERIAL_CLASS_BLUETOOTH_HCI,
-    .serial_vid = PDEV_VID_BROADCOM,
-    .serial_pid = PDEV_PID_BCM4356,
-};
-
-static const pbus_metadata_t bt_uart_metadata[] = {
-    {
-        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
-        .data_buffer = &bt_uart_serial_info,
-        .data_size = sizeof(bt_uart_serial_info),
-    },
-};
-
-static pbus_dev_t bt_uart_dev = {
-    .name = "bt-uart",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_UART,
-    .mmio_list = bt_uart_mmios,
-    .mmio_count = countof(bt_uart_mmios),
-    .irq_list = bt_uart_irqs,
-    .irq_count = countof(bt_uart_irqs),
-    .metadata_list = bt_uart_metadata,
-    .metadata_count = countof(bt_uart_metadata),
-};
-
-#if UART_TEST
-static const pbus_mmio_t header_uart_mmios[] = {
-    // UART_AO_B, on 40 pin header
-    {
-        .base = S912_UART_AO_B_BASE,
-        .length = S912_UART_AO_B_LENGTH,
-    },
-};
-
-static const pbus_irq_t header_uart_irqs[] = {
-    // UART_AO_B, on 40 pin header
-    {
-        .irq = S912_UART_AO_B_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-};
-
-static const serial_port_info_t header_serial_info = {
-    .serial_class = SERIAL_CLASS_GENERIC,
-};
-
-static const pbus_metadata_t header_metadata[] = {
-    {
-        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
-        .data_buffer = &header_serial_info,
-        .data_size = sizeof(header_serial_info),
-    },
-};
-
-static pbus_dev_t header_uart_dev = {
-    .name = "header-uart",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_AMLOGIC_UART,
-    .mmio_list = header_uart_mmios,
-    .mmio_count = countof(header_uart_mmios),
-    .irq_list = header_uart_irqs,
-    .irq_count = countof(header_uart_irqs),
-    .metadata_list = header_metadata,
-    .metadata_count = countof(header_metadata),
-};
-#endif
-
-// Enables and configures PWM_E on the WIFI_32K line for the Wifi/Bluetooth module
-static zx_status_t vim_enable_wifi_32K(vim_bus_t* bus) {
-    // Configure WIFI_32K pin for PWM_E
-    zx_status_t status = gpio_impl_set_alt_function(&bus->gpio, WIFI_32K, 1);
-    if (status != ZX_OK) return status;
-
-    mmio_buffer_t buffer;
-    status = mmio_buffer_init_physical(&buffer, S912_PWM_BASE, 0x10000, get_root_resource(),
-                                       ZX_CACHE_POLICY_UNCACHED_DEVICE);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_enable_wifi_32K: io_buffer_init_physical failed: %d\n", status);
-        return status;
-    }
-    uint32_t* regs = buffer.vaddr;
-
-    // these magic numbers were gleaned by instrumenting drivers/amlogic/pwm/pwm_meson.c
-    // TODO(voydanoff) write a proper PWM driver
-    writel(0x016d016e, regs + S912_PWM_PWM_E);
-    writel(0x016d016d, regs + S912_PWM_E2);
-    writel(0x0a0a0609, regs + S912_PWM_TIME_EF);
-    writel(0x02808003, regs + S912_PWM_MISC_REG_EF);
-
-    mmio_buffer_release(&buffer);
-
-    return ZX_OK;
-}
-
-zx_status_t vim_uart_init(vim_bus_t* bus) {
-    zx_status_t status;
-
-    // set alternate functions to enable UART_A and UART_AO_B
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_TX_A, S912_UART_TX_A_FN);
-    if (status != ZX_OK) return status;
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_RX_A, S912_UART_RX_A_FN);
-    if (status != ZX_OK) return status;
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_CTS_A, S912_UART_CTS_A_FN);
-    if (status != ZX_OK) return status;
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_RTS_A, S912_UART_RTS_A_FN);
-    if (status != ZX_OK) return status;
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_TX_AO_B, S912_UART_TX_AO_B_FN);
-    if (status != ZX_OK) return status;
-    status = gpio_impl_set_alt_function(&bus->gpio, S912_UART_RX_AO_B, S912_UART_RX_AO_B_FN);
-    if (status != ZX_OK) return status;
-
-    // Configure the WIFI_32K PWM, which is needed for the Bluetooth module to work properly
-    status = vim_enable_wifi_32K(bus);
-     if (status != ZX_OK) {
-        return status;
-    }
-
-    // set GPIO to reset Bluetooth module
-    gpio_impl_config_out(&bus->gpio, BT_EN, 0);
-    usleep(10 * 1000);
-    gpio_impl_write(&bus->gpio, BT_EN, 1);
-
-    // Bind UART for Bluetooth HCI
-    status = pbus_device_add(&bus->pbus, &bt_uart_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init: pbus_device_add failed: %d\n", status);
-        return status;
-    }
-
-#if UART_TEST
-    // Bind UART for 40-pin header
-    status = pbus_device_add(&bus->pbus, &header_uart_dev);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init: pbus_device_add failed: %d\n", status);
-        return status;
-    }
-#endif
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-uart.cpp b/system/dev/board/vim/vim-uart.cpp
new file mode 100644
index 0000000..9b365dd
--- /dev/null
+++ b/system/dev/board/vim/vim-uart.cpp
@@ -0,0 +1,201 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/metadata.h>
+#include <ddk/mmio-buffer.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/gpio.h>
+#include <ddk/protocol/platform/bus.h>
+#include <ddk/protocol/serial.h>
+#include <hw/reg.h>
+#include <soc/aml-s912/s912-gpio.h>
+#include <soc/aml-s912/s912-hw.h>
+#include <unistd.h>
+#include <zircon/device/serial.h>
+
+#include "vim.h"
+
+namespace vim {
+// set this to enable UART test driver, which uses the second UART
+// on the 40 pin header
+#define UART_TEST 1
+
+#define WIFI_32K S912_GPIOX(16)
+#define BT_EN S912_GPIOX(17)
+
+static const pbus_mmio_t bt_uart_mmios[] = {
+    // UART_A, for BT HCI
+    {
+        .base = S912_UART_A_BASE,
+        .length = S912_UART_A_LENGTH,
+    },
+};
+
+static const pbus_irq_t bt_uart_irqs[] = {
+    // UART_A, for BT HCI
+    {
+        .irq = S912_UART_A_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static const serial_port_info_t bt_uart_serial_info = {
+    .serial_class = SERIAL_CLASS_BLUETOOTH_HCI,
+    .serial_vid = PDEV_VID_BROADCOM,
+    .serial_pid = PDEV_PID_BCM4356,
+};
+
+static const pbus_metadata_t bt_uart_metadata[] = {
+    {
+        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
+        .data_buffer = &bt_uart_serial_info,
+        .data_size = sizeof(bt_uart_serial_info),
+    },
+};
+
+static pbus_dev_t bt_uart_dev = [] {
+    pbus_dev_t dev;
+    dev.name = "bt-uart";
+    dev.vid = PDEV_VID_AMLOGIC;
+    dev.pid = PDEV_PID_GENERIC;
+    dev.did = PDEV_DID_AMLOGIC_UART;
+    dev.mmio_list = bt_uart_mmios;
+    dev.mmio_count = countof(bt_uart_mmios);
+    dev.irq_list = bt_uart_irqs;
+    dev.irq_count = countof(bt_uart_irqs);
+    dev.metadata_list = bt_uart_metadata;
+    dev.metadata_count = countof(bt_uart_metadata);
+    return dev;
+}();
+
+#if UART_TEST
+static const pbus_mmio_t header_uart_mmios[] = {
+    // UART_AO_B, on 40 pin header
+    {
+        .base = S912_UART_AO_B_BASE,
+        .length = S912_UART_AO_B_LENGTH,
+    },
+};
+
+static const pbus_irq_t header_uart_irqs[] = {
+    // UART_AO_B, on 40 pin header
+    {
+        .irq = S912_UART_AO_B_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static const serial_port_info_t header_serial_info = []() {
+    serial_port_info_t serial_port_info;
+    serial_port_info.serial_class = SERIAL_CLASS_GENERIC;
+    return serial_port_info;
+}();
+
+static const pbus_metadata_t header_metadata[] = {
+    {
+        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
+        .data_buffer = &header_serial_info,
+        .data_size = sizeof(header_serial_info),
+    },
+};
+
+static pbus_dev_t header_uart_dev = []() {
+    pbus_dev_t dev;
+    dev.name = "header-uart";
+    dev.vid = PDEV_VID_AMLOGIC;
+    dev.pid = PDEV_PID_GENERIC;
+    dev.did = PDEV_DID_AMLOGIC_UART;
+    dev.mmio_list = header_uart_mmios;
+    dev.mmio_count = countof(header_uart_mmios);
+    dev.irq_list = header_uart_irqs;
+    dev.irq_count = countof(header_uart_irqs);
+    dev.metadata_list = header_metadata;
+    dev.metadata_count = countof(header_metadata);
+    return dev;
+}();
+#endif
+
+// Enables and configures PWM_E on the WIFI_32K line for the Wifi/Bluetooth module
+zx_status_t Vim::EnableWifi32K() {
+    // Configure WIFI_32K pin for PWM_E
+    zx_status_t status = gpio_impl_.SetAltFunction(WIFI_32K, 1);
+    if (status != ZX_OK)
+        return status;
+
+    mmio_buffer_t buffer;
+    status = mmio_buffer_init_physical(&buffer, S912_PWM_BASE, 0x10000, get_root_resource(),
+                                       ZX_CACHE_POLICY_UNCACHED_DEVICE);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "vim_enable_wifi_32K: io_buffer_init_physical failed: %d\n", status);
+        return status;
+    }
+    uint32_t* regs = (uint32_t*)buffer.vaddr;
+
+    // these magic numbers were gleaned by instrumenting drivers/amlogic/pwm/pwm_meson.c
+    // TODO(voydanoff) write a proper PWM driver
+    writel(0x016d016e, regs + S912_PWM_PWM_E);
+    writel(0x016d016d, regs + S912_PWM_E2);
+    writel(0x0a0a0609, regs + S912_PWM_TIME_EF);
+    writel(0x02808003, regs + S912_PWM_MISC_REG_EF);
+
+    mmio_buffer_release(&buffer);
+
+    return ZX_OK;
+}
+
+zx_status_t Vim::UartInit() {
+    zx_status_t status;
+
+    // set alternate functions to enable UART_A and UART_AO_B
+    status = gpio_impl_.SetAltFunction(S912_UART_TX_A, S912_UART_TX_A_FN);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_impl_.SetAltFunction(S912_UART_RX_A, S912_UART_RX_A_FN);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_impl_.SetAltFunction(S912_UART_CTS_A, S912_UART_CTS_A_FN);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_impl_.SetAltFunction(S912_UART_RTS_A, S912_UART_RTS_A_FN);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_impl_.SetAltFunction(S912_UART_TX_AO_B, S912_UART_TX_AO_B_FN);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_impl_.SetAltFunction(S912_UART_RX_AO_B, S912_UART_RX_AO_B_FN);
+    if (status != ZX_OK)
+        return status;
+
+    // Configure the WIFI_32K PWM, which is needed for the Bluetooth module to work properly
+    status = EnableWifi32K();
+    if (status != ZX_OK) {
+        return status;
+    }
+
+    // set GPIO to reset Bluetooth module
+    gpio_impl_.ConfigOut(BT_EN, 0);
+    usleep(10 * 1000);
+    gpio_impl_.Write(BT_EN, 1);
+
+    // Bind UART for Bluetooth HCI
+    status = pbus_.DeviceAdd(&bt_uart_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "UartInit: pbus_device_add failed: %d\n", status);
+        return status;
+    }
+
+#if UART_TEST
+    // Bind UART for 40-pin header
+    status = pbus_.DeviceAdd(&header_uart_dev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "UartInit: pbus_device_add failed: %d\n", status);
+        return status;
+    }
+#endif
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-usb.c b/system/dev/board/vim/vim-usb.cpp
similarity index 62%
rename from system/dev/board/vim/vim-usb.c
rename to system/dev/board/vim/vim-usb.cpp
index 30bb61c..583cb53 100644
--- a/system/dev/board/vim/vim-usb.c
+++ b/system/dev/board/vim/vim-usb.cpp
@@ -11,9 +11,10 @@
 
 #include "vim.h"
 
+namespace vim {
 #define BIT_MASK(start, count) (((1 << (count)) - 1) << (start))
 #define SET_BITS(dest, start, count, value) \
-        ((dest & ~BIT_MASK(start, count)) | (((value) << (start)) & BIT_MASK(start, count)))
+    ((dest & ~BIT_MASK(start, count)) | (((value) << (start)) & BIT_MASK(start, count)))
 
 static const pbus_mmio_t xhci_mmios[] = {
     {
@@ -36,43 +37,43 @@
     },
 };
 
-static const pbus_dev_t xhci_dev = {
-    .name = "xhci",
-    .vid = PDEV_VID_GENERIC,
-    .pid = PDEV_PID_GENERIC,
-    .did = PDEV_DID_USB_XHCI,
-    .mmio_list = xhci_mmios,
-    .mmio_count = countof(xhci_mmios),
-    .irq_list = xhci_irqs,
-    .irq_count = countof(xhci_irqs),
-    .bti_list = xhci_btis,
-    .bti_count = countof(xhci_btis),
-};
-
-zx_status_t vim_usb_init(vim_bus_t* bus) {
+zx_status_t Vim::UsbInit() {
     zx_status_t status;
+    pbus_dev_t xhci_dev = {};
 
-    zx_handle_t bti;
-    status = iommu_get_bti(&bus->iommu, 0, BTI_BOARD, &bti);
+    xhci_dev.name = "xhci";
+    xhci_dev.vid = PDEV_VID_GENERIC;
+    xhci_dev.pid = PDEV_PID_GENERIC;
+    xhci_dev.did = PDEV_DID_USB_XHCI;
+    xhci_dev.mmio_list = xhci_mmios;
+    xhci_dev.mmio_count = countof(xhci_mmios);
+    xhci_dev.irq_list = xhci_irqs;
+    xhci_dev.irq_count = countof(xhci_irqs);
+    xhci_dev.bti_list = xhci_btis;
+    xhci_dev.bti_count = countof(xhci_btis);
+
+    zx::bti bti;
+
+    status = iommu_.GetBti(0, BTI_BOARD, &bti);
     if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_bus_bind: iommu_get_bti failed: %d\n", status);
+        zxlogf(ERROR, "UsbInit: iommu_get_bti failed: %d\n", status);
         return status;
     }
     io_buffer_t usb_phy;
-    status = io_buffer_init_physical(&usb_phy, bti, S912_USB_PHY_BASE, S912_USB_PHY_LENGTH,
+    status = io_buffer_init_physical(&usb_phy, bti.get(), S912_USB_PHY_BASE, S912_USB_PHY_LENGTH,
                                      get_root_resource(),
                                      ZX_CACHE_POLICY_UNCACHED_DEVICE);
     if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_usb_init io_buffer_init_physical failed %d\n", status);
-        zx_handle_close(bti);
+        zxlogf(ERROR, "UsbInit io_buffer_init_physical failed %d\n", status);
         return status;
     }
 
-    volatile void* regs = io_buffer_virt(&usb_phy);
+    volatile uint8_t* regs = static_cast<uint8_t*>(io_buffer_virt(&usb_phy));
 
     // amlogic_new_usb2_init
     for (int i = 0; i < 4; i++) {
-        volatile void* addr = regs + (i * PHY_REGISTER_SIZE) + U2P_R0_OFFSET;
+        volatile uint8_t* addr = regs + (i * PHY_REGISTER_SIZE) + U2P_R0_OFFSET;
+
         uint32_t temp = readl(addr);
         temp |= U2P_R0_POR;
         temp |= U2P_R0_DMPULLDOWN;
@@ -88,7 +89,7 @@
     }
 
     // amlogic_new_usb3_init
-    volatile void* addr = regs + (4 * PHY_REGISTER_SIZE);
+    volatile uint8_t* addr = regs + (4 * PHY_REGISTER_SIZE);
 
     uint32_t temp = readl(addr + USB_R1_OFFSET);
     temp = SET_BITS(temp, USB_R1_U3H_FLADJ_30MHZ_REG_START, USB_R1_U3H_FLADJ_30MHZ_REG_BITS, 0x20);
@@ -101,12 +102,12 @@
     writel(temp, addr + USB_R5_OFFSET);
 
     io_buffer_release(&usb_phy);
-    zx_handle_close(bti);
 
-    if ((status = pbus_device_add(&bus->pbus, &xhci_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_usb_init could not add xhci_dev: %d\n", status);
+    if ((status = pbus_.DeviceAdd(&xhci_dev)) != ZX_OK) {
+        zxlogf(ERROR, "UsbInit could not add xhci_dev: %d\n", status);
         return status;
     }
 
     return ZX_OK;
 }
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim-video.c b/system/dev/board/vim/vim-video.c
deleted file mode 100644
index 62fe3b6..0000000
--- a/system/dev/board/vim/vim-video.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 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 <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/platform/bus.h>
-#include <soc/aml-s912/s912-hw.h>
-
-#include "vim.h"
-
-static pbus_mmio_t vim_video_mmios[] = {
-    {
-        .base =     S912_FULL_CBUS_BASE,
-        .length =   S912_FULL_CBUS_LENGTH,
-    },
-    {
-        .base =     S912_DOS_BASE,
-        .length =   S912_DOS_LENGTH,
-    },
-    {
-        .base =     S912_HIU_BASE,
-        .length =   S912_HIU_LENGTH,
-    },
-    {
-        .base =     S912_AOBUS_BASE,
-        .length =   S912_AOBUS_LENGTH,
-    },
-    {
-        .base =     S912_DMC_REG_BASE,
-        .length =   S912_DMC_REG_LENGTH,
-    },
-};
-
-static const pbus_bti_t vim_video_btis[] = {
-    {
-        .iommu_index = 0,
-        .bti_id = BTI_VIDEO,
-    },
-};
-
-static const pbus_irq_t vim_video_irqs[] = {
-    {
-        .irq = S912_DEMUX_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_PARSER_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_DOS_MBOX_0_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_DOS_MBOX_1_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-    {
-        .irq = S912_DOS_MBOX_2_IRQ,
-        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
-    },
-};
-
-static const uint32_t vim_video_protocols[] = {
-    ZX_PROTOCOL_AMLOGIC_CANVAS,
-};
-
-static const pbus_dev_t video_dev = {
-    .name = "video",
-    .vid = PDEV_VID_AMLOGIC,
-    .pid = PDEV_PID_AMLOGIC_S912,
-    .did = PDEV_DID_AMLOGIC_VIDEO,
-    .mmio_list = vim_video_mmios,
-    .mmio_count = countof(vim_video_mmios),
-    .bti_list = vim_video_btis,
-    .bti_count = countof(vim_video_btis),
-    .irq_list = vim_video_irqs,
-    .irq_count = countof(vim_video_irqs),
-    .protocol_list = vim_video_protocols,
-    .protocol_count = countof(vim_video_protocols),
-};
-
-
-zx_status_t vim_video_init(vim_bus_t* bus) {
-    zx_status_t status;
-    if ((status = pbus_device_add(&bus->pbus, &video_dev)) != ZX_OK) {
-        zxlogf(ERROR, "vim_video_init: pbus_device_add() failed for video: %d\n", status);
-        return status;
-    }
-
-    return ZX_OK;
-}
diff --git a/system/dev/board/vim/vim-video.cpp b/system/dev/board/vim/vim-video.cpp
new file mode 100644
index 0000000..cbf9de9
--- /dev/null
+++ b/system/dev/board/vim/vim-video.cpp
@@ -0,0 +1,95 @@
+// Copyright 2018 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 <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/platform/bus.h>
+#include <soc/aml-s912/s912-hw.h>
+
+#include "vim.h"
+
+namespace vim {
+static pbus_mmio_t vim_video_mmios[] = {
+    {
+        .base = S912_FULL_CBUS_BASE,
+        .length = S912_FULL_CBUS_LENGTH,
+    },
+    {
+        .base = S912_DOS_BASE,
+        .length = S912_DOS_LENGTH,
+    },
+    {
+        .base = S912_HIU_BASE,
+        .length = S912_HIU_LENGTH,
+    },
+    {
+        .base = S912_AOBUS_BASE,
+        .length = S912_AOBUS_LENGTH,
+    },
+    {
+        .base = S912_DMC_REG_BASE,
+        .length = S912_DMC_REG_LENGTH,
+    },
+};
+
+static const pbus_bti_t vim_video_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_VIDEO,
+    },
+};
+
+static const pbus_irq_t vim_video_irqs[] = {
+    {
+        .irq = S912_DEMUX_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_PARSER_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_DOS_MBOX_0_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_DOS_MBOX_1_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = S912_DOS_MBOX_2_IRQ,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static const uint32_t vim_video_protocols[] = {
+    ZX_PROTOCOL_AMLOGIC_CANVAS,
+};
+
+zx_status_t Vim::VideoInit() {
+    pbus_dev_t video_dev = {};
+    video_dev.name = "video";
+    video_dev.vid = PDEV_VID_AMLOGIC;
+    video_dev.pid = PDEV_PID_AMLOGIC_S912;
+    video_dev.did = PDEV_DID_AMLOGIC_VIDEO;
+    video_dev.mmio_list = vim_video_mmios;
+    video_dev.mmio_count = countof(vim_video_mmios);
+    video_dev.irq_list = vim_video_irqs;
+    video_dev.irq_count = countof(vim_video_irqs);
+    video_dev.bti_list = vim_video_btis;
+    video_dev.bti_count = countof(vim_video_btis);
+    video_dev.protocol_list = vim_video_protocols;
+    video_dev.protocol_count = countof(vim_video_protocols);
+
+    zx_status_t status;
+
+    if ((status = pbus_.DeviceAdd(&video_dev)) != ZX_OK) {
+        zxlogf(ERROR, "VideoInit: pbus_device_add() failed for video: %d\n", status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+} //namespace vim
\ No newline at end of file
diff --git a/system/dev/board/vim/vim.c b/system/dev/board/vim/vim.c
deleted file mode 100644
index 9585d2a..0000000
--- a/system/dev/board/vim/vim.c
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2017 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 <assert.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <threads.h>
-#include <unistd.h>
-
-#include <ddk/binding.h>
-#include <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/driver.h>
-#include <ddk/platform-defs.h>
-#include <ddk/protocol/scpi.h>
-#include <hw/reg.h>
-
-#include <soc/aml-s912/s912-hw.h>
-
-#include <zircon/assert.h>
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
-#include <zircon/threads.h>
-
-#include "vim.h"
-
-static void vim_bus_release(void* ctx) {
-    vim_bus_t* bus = ctx;
-    free(bus);
-}
-
-static zx_protocol_device_t vim_bus_device_protocol = {
-    .version = DEVICE_OPS_VERSION,
-    .release = vim_bus_release,
-};
-
-static int vim_start_thread(void* arg) {
-    vim_bus_t* bus = arg;
-    zx_status_t status;
-    pdev_board_info_t info;
-
-    // Fetch the board info so that we can distinguish between the "vim2" and
-    // "vim2-machina" boards. The latter of which does not initialize devices.
-    if ((status = pbus_get_board_info(&bus->pbus, &info)) != ZX_OK) {
-        zxlogf(ERROR, "pbus_get_board_info failed: %d\n", status);
-        goto fail;
-    }
-    if (info.pid == PDEV_PID_VIM2_MACHINA) {
-        return ZX_OK;
-    }
-
-    // Start protocol drivers before adding platform devices.
-    //
-    // Sysmem is started early so zx_vmo_create_contiguous() works.
-    if ((status = vim_sysmem_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sysmem_init failed: %d\n", status);
-        goto fail;
-    }
-    if ((status = vim_gpio_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_gpio_init failed: %d\n", status);
-        goto fail;
-    }
-    if ((status = vim_i2c_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_i2c_init failed: %d\n", status);
-        goto fail;
-    }
-    if ((status = vim_clk_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_clk_init failed: %d\n", status);
-        goto fail;
-    }
-    if ((status = vim2_canvas_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim2_canvas_init failed: %d\n", status);
-    }
-
-    // Start platform devices.
-    if ((status = vim_uart_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_uart_init failed: %d\n", status);
-    }
-    if ((status = vim_sd_emmc_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sd_emmc_init failed: %d\n", status);
-    }
-    if ((status = vim_sdio_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_sdio_init failed: %d\n", status);
-    }
-    if ((status = vim_eth_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_eth_init failed: %d\n", status);
-    }
-    if ((status = vim_usb_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_usb_init failed: %d\n", status);
-    }
-    if ((status = vim_mali_init(bus, BTI_MALI)) != ZX_OK) {
-        zxlogf(ERROR, "vim_mali_init failed: %d\n", status);
-    }
-    if ((status = vim2_thermal_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim2_thermal_init failed: %d\n", status);
-    }
-    if ((status = vim_display_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_display_init failed: %d\n", status);
-    }
-    if ((status = vim_video_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_video_init failed: %d\n", status);
-    }
-    if ((status = vim_led2472g_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_led2472g_init failed: %d\n", status);
-    }
-    if ((status = vim_rtc_init(bus)) != ZX_OK) {
-        zxlogf(ERROR, "vim_rtc_init failed: %d\n", status);
-    }
-
-    return ZX_OK;
-fail:
-    zxlogf(ERROR, "vim_start_thread failed, not all devices have been initialized\n");
-    return status;
-}
-
-static zx_status_t vim_bus_bind(void* ctx, zx_device_t* parent) {
-    vim_bus_t* bus = calloc(1, sizeof(vim_bus_t));
-    if (!bus) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    bus->parent = parent;
-
-    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PBUS, &bus->pbus);
-    if (status != ZX_OK) {
-        goto fail;
-    }
-
-    // Set dummy board revision to facilitate testing of platform device get_board_info support.
-    pbus_board_info_t info;
-    info.board_revision = 1234;
-    pbus_set_board_info(&bus->pbus, &info);
-
-    // Get default BTI from the dummy IOMMU implementation in the platform bus.
-    status = device_get_protocol(parent, ZX_PROTOCOL_IOMMU, &bus->iommu);
-    if (status != ZX_OK) {
-        zxlogf(ERROR, "vim_bus_bind: could not get ZX_PROTOCOL_IOMMU\n");
-        goto fail;
-    }
-
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .name = "vim-bus",
-        .ctx = bus,
-        .ops = &vim_bus_device_protocol,
-        .flags = DEVICE_ADD_NON_BINDABLE,
-    };
-
-    status = device_add(parent, &args, NULL);
-    if (status != ZX_OK) {
-        goto fail;
-    }
-
-    thrd_t t;
-    int thrd_rc = thrd_create_with_name(&t, vim_start_thread, bus, "vim_start_thread");
-    if (thrd_rc != thrd_success) {
-        status = thrd_status_to_zx_status(thrd_rc);
-        goto fail;
-    }
-
-    return ZX_OK;
-
-fail:
-    zxlogf(ERROR, "vim_bus_bind failed %d\n", status);
-    vim_bus_release(bus);
-    return status;
-}
-
-static zx_driver_ops_t vim_bus_driver_ops = {
-    .version = DRIVER_OPS_VERSION,
-    .bind = vim_bus_bind,
-};
-
-ZIRCON_DRIVER_BEGIN(vim_bus, vim_bus_driver_ops, "zircon", "0.1", 4)
-    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
-    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_KHADAS),
-    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2),
-    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2_MACHINA),
-ZIRCON_DRIVER_END(vim_bus)
diff --git a/system/dev/board/vim/vim.cpp b/system/dev/board/vim/vim.cpp
new file mode 100644
index 0000000..68bbc6a
--- /dev/null
+++ b/system/dev/board/vim/vim.cpp
@@ -0,0 +1,227 @@
+// Copyright 2017 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 <memory>
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <threads.h>
+#include <unistd.h>
+
+#include <ddk/binding.h>
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/driver.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/scpi.h>
+#include <hw/reg.h>
+
+#include <soc/aml-s912/s912-hw.h>
+
+#include <fbl/algorithm.h>
+#include <fbl/unique_ptr.h>
+#include <zircon/assert.h>
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/threads.h>
+
+#include "vim.h"
+
+namespace vim {
+
+// TODO(rjascani): Remove this when not needed for testing any longer
+const pbus_dev_t tee_dev = []() {
+    pbus_dev_t dev;
+    dev.name = "tee";
+    dev.vid = PDEV_VID_GENERIC;
+    dev.pid = PDEV_PID_GENERIC;
+    dev.did = PDEV_DID_OPTEE;
+    return dev;
+}();
+
+zx_status_t Vim::Create(void* ctx, zx_device_t* parent) {
+    pbus_protocol_t pbus;
+    iommu_protocol_t iommu;
+    pbus_board_info_t info;
+
+    auto status = device_get_protocol(parent, ZX_PROTOCOL_PBUS, &pbus);
+    if (status != ZX_OK) {
+        return status;
+    }
+
+    // Set dummy board revision to facilitate testing of platform device get_board_info support.
+    info.board_revision = 1234;
+    pbus_set_board_info(&pbus, &info);
+
+    status = device_get_protocol(parent, ZX_PROTOCOL_IOMMU, &iommu);
+    if (status != ZX_OK) {
+        return status;
+    }
+
+    fbl::AllocChecker ac;
+    auto board = std::unique_ptr<Vim>(new (&ac) Vim(parent, &pbus, &iommu));
+    if (!ac.check()) {
+        return ZX_ERR_NO_MEMORY;
+    }
+
+    status = board->DdkAdd("vim", DEVICE_ADD_NON_BINDABLE);
+    if (status != ZX_OK) {
+        return status;
+    }
+
+    // Start up our protocol helpers and platform devices.
+    status = board->Start();
+
+    if (status == ZX_OK) {
+        // devmgr is now in charge of the device.
+        __UNUSED auto* dummy = board.release();
+    }
+
+    return status;
+}
+
+int Vim::Thread() {
+    zx_status_t status;
+    pdev_board_info_t info;
+
+    // Fetch the board info so that we can distinguish between the "vim2" and
+    // "vim2-machina" boards. The latter of which has fewer devices available
+    // to Zircon.
+    status = pbus_.GetBoardInfo(&info);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "Thread: GetBoardInfo failed: %d\n", status);
+        return -1;
+    }
+    enable_gpio_test_ = (info.pid == PDEV_PID_VIM2);
+
+    // Start protocol drivers before adding platform devices.
+    // Sysmem is started early so zx_vmo_create_contiguous() works.
+
+    if ((status = SysmemInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: SysmemInit failed: %d\n", status);
+        return -1;
+    }
+    if ((status = GpioInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: GpioInit failed: %d\n", status);
+        return -1;
+    }
+    if ((status = I2cInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: I2cInit failed: %d\n", status);
+        return -1;
+    }
+    if ((status = ClkInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: ClkInit failed: %d\n", status);
+        return -1;
+    }
+    if (info.pid == PDEV_PID_VIM2) {
+        if ((status = CanvasInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: CanvasInit failed: %d\n", status);
+            return -1;
+        }
+    }
+
+    // Start platform devices.
+    if ((status = UartInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: UartInit failed: %d\n", status);
+        return -1;
+    }
+
+    if ((status = SdEmmcInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: SdEmmcInit failed: %d\n", status);
+        return -1;
+    }
+
+    if ((status = SdioInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: SdioInit failed: %d\n", status);
+        return -1;
+    }
+
+    if ((status = EthInit()) != ZX_OK) {
+        zxlogf(ERROR, "Thread: EthInit failed: %d\n", status);
+        return -1;
+    }
+
+    if (info.pid == PDEV_PID_VIM2) {
+        if ((status = UsbInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: UsbInit failed: %d\n", status);
+            return -1;
+        }
+
+        if ((status = MaliInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: MaliInit failed: %d\n", status);
+            return -1;
+        }
+
+        if ((status = ThermalInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: ThermalInit failed: %d\n", status);
+            return -1;
+        }
+
+        if ((status = DisplayInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: DisplayInit failed: %d\n", status);
+            return -1;
+        }
+
+        if ((status = VideoInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: VideoInit failed: %d\n", status);
+            return -1;
+        }
+
+        if ((status = Led2472gInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: Led2472gInit failed: %d\n", status);
+            return -1;
+        }
+
+        // Remove this when not needed for testing any longer
+        if ((status = pbus_.DeviceAdd(&tee_dev)) != ZX_OK) {
+            zxlogf(ERROR, "vim_start_thread, could not add tee_dev: %d\n", status);
+            return -1;
+        }
+
+        if ((status = RtcInit()) != ZX_OK) {
+            zxlogf(ERROR, "Thread: RtcInit failed: %d\n", status);
+            return -1;
+        }
+    }
+
+    return ZX_OK;
+}
+
+zx_status_t Vim::Start() {
+    int rc = thrd_create_with_name(
+        &thread_,
+        [](void* arg) -> int {
+            return reinterpret_cast<Vim*>(arg)->Thread();
+        },
+        this,
+        "vim-start-thread");
+
+    if (rc != thrd_success) {
+        return ZX_ERR_INTERNAL;
+    }
+    return ZX_OK;
+}
+
+void Vim::DdkRelease() {
+    delete this;
+}
+zx_driver_ops_t vim_driver_ops = []() {
+    zx_driver_ops_t ops = {};
+    ops.version = DRIVER_OPS_VERSION;
+    ops.bind = Vim::Create;
+    return ops;
+}();
+
+} // namespace vim
+
+ZIRCON_DRIVER_BEGIN(vim, vim::vim_driver_ops, "zircon", "0.1", 4)
+BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
+    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_KHADAS),
+    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2),
+    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2_MACHINA),
+ZIRCON_DRIVER_END(vim)
diff --git a/system/dev/board/vim/vim.h b/system/dev/board/vim/vim.h
index 7d4c393..c5c2bb4 100644
--- a/system/dev/board/vim/vim.h
+++ b/system/dev/board/vim/vim.h
@@ -4,11 +4,17 @@
 
 #pragma once
 
-#include <ddk/device.h>
+#include <threads.h>
+
 #include <ddk/io-buffer.h>
-#include <ddk/protocol/gpioimpl.h>
-#include <ddk/protocol/iommu.h>
-#include <ddk/protocol/platform/bus.h>
+#include <ddktl/device.h>
+#include <ddktl/protocol/gpioimpl.h>
+#include <ddktl/protocol/iommu.h>
+#include <ddktl/protocol/platform/bus.h>
+
+#include <fbl/macros.h>
+
+namespace vim {
 
 // BTI IDs for our devices
 enum {
@@ -24,57 +30,51 @@
     BTI_SYSMEM,
 };
 
-typedef struct {
-    pbus_protocol_t pbus;
-    gpio_impl_protocol_t gpio;
-    zx_device_t* parent;
-    iommu_protocol_t iommu;
-} vim_bus_t;
+class Vim;
+using VimType = ddk::Device<Vim>;
 
-// vim-gpio.c
-zx_status_t vim_gpio_init(vim_bus_t* bus);
+// This is the main class for the VIM2 board driver.
+class Vim : public VimType {
+public:
+    explicit Vim(zx_device_t* parent, pbus_protocol_t* pbus, iommu_protocol_t* iommu)
+        : VimType(parent), pbus_(pbus), iommu_(iommu) {}
 
-// vim-i2c.c
-zx_status_t vim_i2c_init(vim_bus_t* bus);
+    static zx_status_t Create(void* ctx,zx_device_t* parent);
+    
+    // Device protocol implementation.
+    void DdkRelease();
 
-// vim-mali.c
-zx_status_t vim_mali_init(vim_bus_t* bus, uint32_t bti_index);
+private:
+    DISALLOW_COPY_ASSIGN_AND_MOVE(Vim);
 
-// vim-uart.c
-zx_status_t vim_uart_init(vim_bus_t* bus);
+    zx_status_t Start();
+    zx_status_t GpioInit();
+    zx_status_t I2cInit();
+    zx_status_t MaliInit();
+    zx_status_t UartInit();
+    zx_status_t UsbInit();
+    zx_status_t SdEmmcInit();
+    zx_status_t SdioInit();
+    zx_status_t EthInit();
+    zx_status_t ThermalInit();
+    zx_status_t DisplayInit();
+    zx_status_t VideoInit();
+    zx_status_t Led2472gInit();
+    zx_status_t RtcInit();
+    zx_status_t CanvasInit();
+    zx_status_t ClkInit();
+    zx_status_t EnableWifi32K();
+    zx_status_t SysmemInit();
 
-// vim-usb.c
-zx_status_t vim_usb_init(vim_bus_t* bus);
+    int Thread();
 
-// vim-sd-emmc.c
-zx_status_t vim_sd_emmc_init(vim_bus_t* bus);
+    ddk::PBusProtocolClient pbus_;
+    ddk::IommuProtocolClient iommu_;
+    ddk::GpioImplProtocolClient gpio_impl_;
+    thrd_t thread_;
 
-// vim-sd-emmc.c
-zx_status_t vim_sdio_init(vim_bus_t* bus);
+    bool enable_gpio_test_;
+};
 
-// vim-eth.c
-zx_status_t vim_eth_init(vim_bus_t* bus);
+} //namespace vim
 
-// vim-fanctl.c
-zx_status_t vim2_thermal_init(vim_bus_t* bus);
-
-// vim-display.c
-zx_status_t vim_display_init(vim_bus_t* bus);
-
-// vim-video.c
-zx_status_t vim_video_init(vim_bus_t* bus);
-
-// vim-led2472g.c
-zx_status_t vim_led2472g_init(vim_bus_t* bus);
-
-// vim-rtc.c
-zx_status_t vim_rtc_init(vim_bus_t* bus);
-
-// vim-canvas.c
-zx_status_t vim2_canvas_init(vim_bus_t* bus);
-
-// vim-clk.c
-zx_status_t vim_clk_init(vim_bus_t* bus);
-
-// vim-sysmem.c
-zx_status_t vim_sysmem_init(vim_bus_t* bus);