You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2018/12/03 12:42:24 UTC

[mynewt-core] 13/15: hw/drivers: Add bus driver support to BQ27Z561

This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 23687151470bfea13f83bce87bf0996c096b9535
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Fri Nov 23 17:41:00 2018 +0100

    hw/drivers: Add bus driver support to BQ27Z561
---
 hw/drivers/bq27z561/include/bq27z561/bq27z561.h |  21 ++
 hw/drivers/bq27z561/src/bq27z561.c              | 276 +++++++++++++++++++-----
 2 files changed, 238 insertions(+), 59 deletions(-)

diff --git a/hw/drivers/bq27z561/include/bq27z561/bq27z561.h b/hw/drivers/bq27z561/include/bq27z561/bq27z561.h
index 6b64ddc..ae8ae6b 100644
--- a/hw/drivers/bq27z561/include/bq27z561/bq27z561.h
+++ b/hw/drivers/bq27z561/include/bq27z561/bq27z561.h
@@ -162,11 +162,13 @@ struct bq27z561_itf
     struct os_mutex *itf_lock;
 };
 
+#if !MYNEWT_VAL(BUS_DRIVER_PRESENT)
 struct bq27z561_init_arg
 {
     struct bq27z561_itf itf;
     struct os_dev *battery;
 };
+#endif
 
 /* BQ27Z561 device */
 struct bq27z561
@@ -177,8 +179,10 @@ struct bq27z561
     /* Configuration values */
     struct bq27z561_cfg bq27_cfg;
 
+#if !MYNEWT_VAL(BUS_DRIVER_PRESENT)
     /* Interface */
     struct bq27z561_itf bq27_itf;
+#endif
 
     /* Device initialization complete flag */
     uint8_t bq27_initialized;
@@ -605,6 +609,23 @@ int bq27z561_init(struct os_dev * dev, void * arg);
 int bq27z561_shell_init(void);
 #endif
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+/**
+ * Create I2C bus node for BQ27Z561
+ *
+ * @param node         Bus node
+ * @param name         Device name
+ * @param i2c_cfg      I2C node configuration
+ * @param battery_dev  Battery device
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+bq27z561_create_i2c_dev(struct bus_i2c_node *node, const char *name,
+                        const struct bus_i2c_node_cfg *i2c_cfg,
+                        struct os_dev *battery_dev);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/drivers/bq27z561/src/bq27z561.c b/hw/drivers/bq27z561/src/bq27z561.c
index cf455df..dc3c3b1 100644
--- a/hw/drivers/bq27z561/src/bq27z561.c
+++ b/hw/drivers/bq27z561/src/bq27z561.c
@@ -23,8 +23,12 @@
 #include "os/mynewt.h"
 #include "bq27z561/bq27z561.h"
 #include "hal/hal_gpio.h"
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+#include "bus/bus.h"
+#else
 #include "hal/hal_i2c.h"
 #include "i2cn/i2cn.h"
+#endif
 
 #include "battery/battery_prop.h"
 
@@ -66,18 +70,7 @@ bq27z561_temp_to_celsius(uint16_t temp)
     return temp_c;
 }
 
-static int
-bq27z561_open(struct os_dev *dev, uint32_t timeout, void *arg)
-{
-    return 0;
-}
-
-static int
-bq27z561_close(struct os_dev *dev)
-{
-    return 0;
-}
-
+#if !MYNEWT_VAL(BUS_DRIVER_PRESENT)
 /**
  * Lock access to the bq27z561_itf specified by si. Blocks until lock acquired.
  *
@@ -125,11 +118,16 @@ bq27z561_itf_unlock(struct bq27z561_itf *bi)
 
     os_mutex_release(bi->itf_lock);
 }
+#endif
 
 static int
 bq27z561_rd_std_reg_byte(struct bq27z561 *dev, uint8_t reg, uint8_t *val)
 {
     int rc;
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write_read_transact(&dev->dev.dev, &reg, 1, val, 1);
+#else
     struct hal_i2c_master_data i2c;
 
     i2c.address = dev->bq27_itf.itf_addr;
@@ -160,6 +158,8 @@ bq27z561_rd_std_reg_byte(struct bq27z561 *dev, uint8_t reg, uint8_t *val)
 
 err:
     bq27z561_itf_unlock(&dev->bq27_itf);
+
+#endif
     return rc;
 }
 
@@ -167,6 +167,10 @@ int
 bq27z561_rd_std_reg_word(struct bq27z561 *dev, uint8_t reg, uint16_t *val)
 {
     int rc;
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write_read_transact(&dev->dev.dev, &reg, 1, val, 2);
+#else
     struct hal_i2c_master_data i2c;
 
     i2c.address = dev->bq27_itf.itf_addr;
@@ -196,6 +200,7 @@ bq27z561_rd_std_reg_word(struct bq27z561 *dev, uint8_t reg, uint16_t *val)
 
 err:
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     /* XXX: add big-endian support */
 
@@ -207,11 +212,15 @@ bq27z561_wr_std_reg_byte(struct bq27z561 *dev, uint8_t reg, uint8_t val)
 {
     int rc;
     uint8_t buf[2];
-    struct hal_i2c_master_data i2c;
 
     buf[0] = reg;
     buf[1] = val;
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(&dev->dev.dev, buf, 2);
+#else
+    struct hal_i2c_master_data i2c;
+
     i2c.address = dev->bq27_itf.itf_num;
     i2c.len     = 2;
     i2c.buffer  = buf;
@@ -228,6 +237,7 @@ bq27z561_wr_std_reg_byte(struct bq27z561 *dev, uint8_t reg, uint8_t val)
     }
 
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     return rc;
 }
@@ -237,12 +247,16 @@ bq27z561_wr_std_reg_word(struct bq27z561 *dev, uint8_t reg, uint16_t val)
 {
     int rc;
     uint8_t buf[3];
-    struct hal_i2c_master_data i2c;
 
     buf[0] = reg;
     buf[1] = (uint8_t)val;
     buf[2] = (uint8_t)(val >> 8);
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(&dev->dev.dev, buf, 3);
+#else
+    struct hal_i2c_master_data i2c;
+
     i2c.address = dev->bq27_itf.itf_num;
     i2c.len     = 3;
     i2c.buffer  = buf;
@@ -261,6 +275,7 @@ bq27z561_wr_std_reg_word(struct bq27z561 *dev, uint8_t reg, uint16_t val)
 
 err:
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     return rc;
 }
@@ -272,7 +287,6 @@ bq27x561_wr_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *buf,
     /* NOTE: add three here for register and two-byte command */
     int rc;
     uint8_t tmpbuf[BQ27Z561_MAX_ALT_MFG_CMD_LEN + 3];
-    struct hal_i2c_master_data i2c;
 
     if ((len > 0) && (buf == NULL)) {
         return BQ27Z561_ERR_INV_PARAMS;
@@ -291,6 +305,11 @@ bq27x561_wr_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *buf,
         memcpy(&tmpbuf[3], buf, len);
     }
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(&dev->dev.dev, tmpbuf, len + 3);
+#else
+    struct hal_i2c_master_data i2c;
+
     i2c.address = dev->bq27_itf.itf_addr;
     i2c.len = len + 3;
     i2c.buffer = tmpbuf;
@@ -308,6 +327,7 @@ bq27x561_wr_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *buf,
     }
 
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     return rc;
 }
@@ -316,48 +336,80 @@ bq27z561_err_t
 bq27x561_rd_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *val,
                         int val_len)
 {
-    bq27z561_err_t rc;
+    bq27z561_err_t ret;
+    int rc;
     uint8_t tmpbuf[36];
     uint8_t len;
     uint16_t cmd_read;
     uint8_t chksum;
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    struct os_dev *odev = &dev->dev.dev;
+#else
     struct hal_i2c_master_data i2c;
+#endif
 
     if ((val_len == 0) || (val == NULL)) {
         return BQ27Z561_ERR_INV_PARAMS;
     }
 
-    tmpbuf[0] = BQ27Z561_REG_CNTL;
-    tmpbuf[1] = (uint8_t)cmd;
-    tmpbuf[2] = (uint8_t)(cmd >> 8);
-
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_lock(odev, BUS_NODE_LOCK_DEFAULT_TIMEOUT);
+    if (rc) {
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
     i2c.address = dev->bq27_itf.itf_addr;
-    i2c.len = 3;
-    i2c.buffer = tmpbuf;
 
     rc = bq27z561_itf_lock(&dev->bq27_itf, MYNEWT_VAL(BQ27Z561_ITF_LOCK_TMO));
     if (rc) {
         return rc;
     }
+#endif
 
+    tmpbuf[0] = BQ27Z561_REG_CNTL;
+    tmpbuf[1] = (uint8_t)cmd;
+    tmpbuf[2] = (uint8_t)(cmd >> 8);
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(odev, tmpbuf, 3);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
+    i2c.len = 3;
+    i2c.buffer = tmpbuf;
     rc = i2cn_master_write(dev->bq27_itf.itf_num, &i2c, MYNEWT_VAL(BQ27Z561_I2C_TIMEOUT_TICKS), 1,
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
+#endif
 
     tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write_read_transact(odev, tmpbuf, 1, tmpbuf, 36);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+
+    (void)bus_node_unlock(odev);
+#else
     i2c.len = 1;
     i2c.buffer = tmpbuf;
-
     rc = i2cn_master_write(dev->bq27_itf.itf_num, &i2c, MYNEWT_VAL(BQ27Z561_I2C_TIMEOUT_TICKS), 0,
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
@@ -368,19 +420,20 @@ bq27x561_rd_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *val,
                           MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (rd) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
 
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     /* Verify that first two bytes are the command */
     cmd_read = tmpbuf[0];
     cmd_read |= ((uint16_t)tmpbuf[1]) << 8;
     if (cmd_read != cmd) {
         BQ27Z561_LOG(ERROR, "cmd mismatch (cmd=%x cmd_ret=%x\n", cmd, cmd_read);
-        rc = BQ27Z561_ERR_CMD_MISMATCH;
+        ret = BQ27Z561_ERR_CMD_MISMATCH;
         goto err;
     }
 
@@ -391,7 +444,7 @@ bq27x561_rd_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *val,
      */
     len = tmpbuf[35];
     if (len < 5) {
-        rc = BQ27Z561_ERR_ALT_MFG_LEN;
+        ret = BQ27Z561_ERR_ALT_MFG_LEN;
         goto err;
     }
 
@@ -401,7 +454,7 @@ bq27x561_rd_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *val,
     if (chksum != tmpbuf[34]) {
         BQ27Z561_LOG(ERROR, "chksum failure for cmd %u (calc=%u read=%u)", cmd,
                        chksum, tmpbuf[34]);
-        rc = BQ27Z561_ERR_CHKSUM_FAIL;
+        ret = BQ27Z561_ERR_CHKSUM_FAIL;
     }
 
     /* Now copy returned data. We subtract command from length */
@@ -411,10 +464,10 @@ bq27x561_rd_alt_mfg_cmd(struct bq27z561 *dev, uint16_t cmd, uint8_t *val,
     }
     memcpy(val, &tmpbuf[2], val_len);
 
-    rc = BQ27Z561_OK;
+    ret = BQ27Z561_OK;
 
 err:
-    return rc;
+    return ret;
 }
 
 bq27z561_err_t
@@ -422,8 +475,13 @@ bq27x561_rd_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
 {
     uint8_t tmpbuf[BQ27Z561_MAX_FLASH_RW_LEN + 2];
     uint16_t addr_read;
-    bq27z561_err_t rc;
+    bq27z561_err_t ret;
+    int rc;
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    struct os_dev *odev = &dev->dev.dev;
+#else
     struct hal_i2c_master_data i2c;
+#endif
 
     if ((buflen == 0) || !buf || (buflen > BQ27Z561_MAX_FLASH_RW_LEN)) {
         return BQ27Z561_ERR_INV_PARAMS;
@@ -433,29 +491,57 @@ bq27x561_rd_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
         return BQ27Z561_ERR_INV_FLASH_ADDR;
     }
 
-    tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
-    tmpbuf[1] = (uint8_t)addr;
-    tmpbuf[2] = (uint8_t)(addr >> 8);
-
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_lock(odev, BUS_NODE_LOCK_DEFAULT_TIMEOUT);
+    if (rc) {
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
     i2c.address = dev->bq27_itf.itf_addr;
-    i2c.len = 3;
-    i2c.buffer = tmpbuf;
 
     rc = bq27z561_itf_lock(&dev->bq27_itf, MYNEWT_VAL(BQ27Z561_ITF_LOCK_TMO));
     if (rc) {
         return rc;
     }
+#endif
+
+    tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
+    tmpbuf[1] = (uint8_t)addr;
+    tmpbuf[2] = (uint8_t)(addr >> 8);
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(odev, tmpbuf, 3);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
+    i2c.len = 3;
+    i2c.buffer = tmpbuf;
     rc = i2cn_master_write(dev->bq27_itf.itf_num, &i2c, MYNEWT_VAL(BQ27Z561_I2C_TIMEOUT_TICKS), 1,
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
+#endif
 
     tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write_read_transact(odev, tmpbuf, 1, tmpbuf, buflen + 2);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+
+    (void)bus_node_unlock(odev);
+#else
     i2c.len = 1;
     i2c.buffer = tmpbuf;
 
@@ -463,7 +549,7 @@ bq27x561_rd_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
@@ -474,12 +560,13 @@ bq27x561_rd_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
                           MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (rd) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         bq27z561_itf_unlock(&dev->bq27_itf);
         goto err;
     }
 
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
     /* Verify that first two bytes are the address*/
     addr_read = tmpbuf[0];
@@ -487,17 +574,17 @@ bq27x561_rd_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
     if (addr_read != addr) {
         BQ27Z561_LOG(ERROR, "addr mismatch (addr_read=%x addr_ret=%x\n", addr_read,
                         addr);
-        rc = BQ27Z561_ERR_FLASH_ADDR_MISMATCH;
+        ret = BQ27Z561_ERR_FLASH_ADDR_MISMATCH;
         goto err;
     }
 
     /* Now copy returned data. */
     memcpy(buf, &tmpbuf[2], buflen);
 
-    rc = BQ27Z561_OK;
+    ret = BQ27Z561_OK;
 
 err:
-    return rc;
+    return ret;
 }
 
 bq27z561_err_t
@@ -505,8 +592,13 @@ bq27x561_wr_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
 {
     uint8_t tmpbuf[BQ27Z561_MAX_FLASH_RW_LEN + 2];
     uint8_t chksum;
-    bq27z561_err_t rc;
+    bq27z561_err_t ret;
+    int rc;
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    struct os_dev *odev = &dev->dev.dev;
+#else
     struct hal_i2c_master_data i2c;
+#endif
 
     if ((buflen == 0) || (!buf) || (buflen > BQ27Z561_MAX_FLASH_RW_LEN)) {
         return BQ27Z561_ERR_INV_PARAMS;
@@ -516,27 +608,44 @@ bq27x561_wr_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
         return BQ27Z561_ERR_INV_FLASH_ADDR;
     }
 
-    tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
-    tmpbuf[1] = (uint8_t)addr;
-    tmpbuf[2] = (uint8_t)(addr >> 8);
-    memcpy(&tmpbuf[3], buf, buflen);
-
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_lock(odev, BUS_NODE_LOCK_DEFAULT_TIMEOUT);
+    if (rc) {
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
     i2c.address = dev->bq27_itf.itf_addr;
-    i2c.len = buflen + 3;
-    i2c.buffer = tmpbuf;
 
     rc = bq27z561_itf_lock(&dev->bq27_itf, MYNEWT_VAL(BQ27Z561_ITF_LOCK_TMO));
     if (rc) {
         return rc;
     }
+#endif
+
+    tmpbuf[0] = BQ27Z561_REG_MFRG_ACC;
+    tmpbuf[1] = (uint8_t)addr;
+    tmpbuf[2] = (uint8_t)(addr >> 8);
+    memcpy(&tmpbuf[3], buf, buflen);
 
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(odev, tmpbuf, buflen + 3);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+#else
+    i2c.len = buflen + 3;
+    i2c.buffer = tmpbuf;
     rc = i2cn_master_write(dev->bq27_itf.itf_num, &i2c, MYNEWT_VAL(BQ27Z561_I2C_TIMEOUT_TICKS), 1,
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
         goto err;
     }
+#endif
 
     /* Calculate checksum */
     chksum = bq27z561_calc_chksum(&tmpbuf[1], buflen + 2);
@@ -545,20 +654,35 @@ bq27x561_wr_flash(struct bq27z561 *dev, uint16_t addr, uint8_t *buf, int buflen)
     tmpbuf[0] = BQ27Z561_REG_CHKSUM;
     tmpbuf[1] = chksum;
     tmpbuf[2] = buflen + 4;
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = bus_node_simple_write(odev, tmpbuf, 3);
+    if (rc) {
+        (void)bus_node_unlock(odev);
+        ret = BQ27Z561_ERR_I2C_ERR;
+        goto err;
+    }
+
+    (void)bus_node_unlock(odev);
+
+    ret = BQ27Z561_OK;
+
+err:
+#else
     i2c.len = 3;
     i2c.buffer = tmpbuf;
-
     rc = i2cn_master_write(dev->bq27_itf.itf_num, &i2c, MYNEWT_VAL(BQ27Z561_I2C_TIMEOUT_TICKS), 1,
                            MYNEWT_VAL(BQ27Z561_I2C_RETRIES));
     if (rc != 0) {
         BQ27Z561_LOG(ERROR, "I2C reg read (wr) failed 0x%02X\n", tmpbuf[0]);
-        rc = BQ27Z561_ERR_I2C_ERR;
+        ret = BQ27Z561_ERR_I2C_ERR;
     }
 
 err:
     bq27z561_itf_unlock(&dev->bq27_itf);
+#endif
 
-    return rc;
+    return ret;
 }
 
 #if 0
@@ -1196,26 +1320,35 @@ int
 bq27z561_init(struct os_dev *dev, void *arg)
 {
     struct bq27z561 *bq27;
+#if !MYNEWT_VAL(BUS_DRIVER_PRESENT)
     struct bq27z561_init_arg *init_arg = (struct bq27z561_init_arg *)arg;
+#endif
+    struct os_dev *battery;
 
     if (!dev || !arg) {
         return SYS_ENODEV;
     }
 
-    OS_DEV_SETHANDLERS(dev, bq27z561_open, bq27z561_close);
-
     bq27 = (struct bq27z561 *)dev;
 
     bq27->bq27_initialized = 0;
 
+#if !MYNEWT_VAL(BUS_DRIVER_PRESENT)
     /* Copy the interface struct */
     bq27->bq27_itf = init_arg->itf;
+#endif
 
     bq27->dev.bd_funcs = &bq27z561_drv_funcs;
     bq27->dev.bd_driver_properties = bq27z561_battery_properties;
     bq27->dev.bd_driver_data = bq27;
 
-    battery_add_driver(init_arg->battery, &bq27->dev);
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    battery = arg;
+#else
+    battery = init_arg->battery;
+#endif
+
+    battery_add_driver(battery, &bq27->dev);
 
     return 0;
 }
@@ -1228,3 +1361,28 @@ int bq27z561_pkg_init(void)
     return 0;
 #endif
 }
+
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+static void
+init_node_cb(struct bus_node *bnode, void *arg)
+{
+    bq27z561_init((struct os_dev *)bnode, arg);
+}
+
+int
+bq27z561_create_i2c_dev(struct bus_i2c_node *node, const char *name,
+                        const struct bus_i2c_node_cfg *i2c_cfg,
+                        struct os_dev *battery_dev)
+{
+    struct bus_node_callbacks cbs = {
+        .init = init_node_cb,
+    };
+    int rc;
+
+    bus_node_set_callbacks((struct os_dev *)node, &cbs);
+
+    rc = bus_i2c_node_create(name, node, i2c_cfg, battery_dev);
+
+    return rc;
+}
+#endif