You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2021/01/02 00:04:01 UTC

[incubator-nuttx] 01/01: BL602: Initial I2C support

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

btashton pushed a commit to branch bl602-i2c
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit b4ca0614e0f04dc91b2867089cf9c9c4899de9b7
Author: Brennan Ashton <ba...@brennanashton.com>
AuthorDate: Thu Dec 31 19:15:48 2020 -0800

    BL602: Initial I2C support
    
    This has primative polling support and does not yet handle NO_M_STOP.
    
    Signed-off-by: Brennan Ashton <ba...@brennanashton.com>
---
 arch/risc-v/src/bl602/Kconfig                      |   3 +
 arch/risc-v/src/bl602/Make.defs                    |   8 +-
 arch/risc-v/src/bl602/bl602_i2c.c                  | 449 +++++++++++++++++++++
 .../board.h => arch/risc-v/src/bl602/bl602_i2c.h   |  46 ++-
 arch/risc-v/src/bl602/hardware/bl602_hbn.h         |   2 +-
 boards/risc-v/bl602/bl602evb/include/board.h       |   5 +
 boards/risc-v/bl602/bl602evb/src/bl602_bringup.c   |   9 +
 7 files changed, 497 insertions(+), 25 deletions(-)

diff --git a/arch/risc-v/src/bl602/Kconfig b/arch/risc-v/src/bl602/Kconfig
index 8be82cf..330f93d 100644
--- a/arch/risc-v/src/bl602/Kconfig
+++ b/arch/risc-v/src/bl602/Kconfig
@@ -34,4 +34,7 @@ config BL602_TIMER0
 
 config BL602_TIMER1
 	bool "TIMER1"
+
+config BL602_I2C
+	bool "I2C"
 endmenu
diff --git a/arch/risc-v/src/bl602/Make.defs b/arch/risc-v/src/bl602/Make.defs
index 1d1b231..93eda35 100644
--- a/arch/risc-v/src/bl602/Make.defs
+++ b/arch/risc-v/src/bl602/Make.defs
@@ -53,10 +53,14 @@ CHIP_CSRCS += bl602_serial.c bl602_lowputc.c bl602_tim.c
 CHIP_CSRCS += bl602_start.c bl602_timerisr.c
 
 ifeq ($(CONFIG_TIMER),y)
-CHIP_CSRCS  += bl602_tim_lowerhalf.c
+CHIP_CSRCS += bl602_tim_lowerhalf.c
 endif
 ifeq ($(CONFIG_ONESHOT),y)
-CHIP_CSRCS  += bl602_oneshot_lowerhalf.c
+CHIP_CSRCS += bl602_oneshot_lowerhalf.c
+endif
+
+ifeq ($(CONFIG_I2C),y)
+CHIP_CSRCS += bl602_i2c.c
 endif
 
 CHIP_CSRCS += bl602_glb.c bl602_gpio.c bl602_hbn.c
diff --git a/arch/risc-v/src/bl602/bl602_i2c.c b/arch/risc-v/src/bl602/bl602_i2c.c
new file mode 100644
index 0000000..d06635d
--- /dev/null
+++ b/arch/risc-v/src/bl602/bl602_i2c.c
@@ -0,0 +1,449 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_i2c.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/i2c/i2c_master.h>
+
+#include <nuttx/irq.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "riscv_arch.h"
+
+#include "hardware/bl602_glb.h"
+#include "hardware/bl602_hbn.h"
+#include "hardware/bl602_i2c.h"
+#include "bl602_i2c.h"
+#include "bl602_gpio.h"
+
+#ifdef CONFIG_BL602_I2C
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define I2C_TIMEOUT  (20*1000/CONFIG_USEC_PER_TICK) /* 20 mS */
+
+#define I2C_DEFAULT_FREQUENCY 400000
+#define I2C_FIFO_MAX_SIZE	    4
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct bl602_i2cdev_s
+{
+  struct i2c_master_s dev;     /* Generic I2C device */
+  uint32_t         base_freq;  /* branch frequency */
+
+  sem_t            mutex;      /* Only one thread can access at a time */
+  sem_t            wait;       /* Place to wait for transfer completion */
+  struct wdog_s    timeout;    /* watchdog to timeout for bus */
+  uint32_t         frequency;  /* Current I2C frequency */
+  ssize_t          reg_buff_offset;
+  ssize_t          rw_size;
+
+  struct i2c_msg_s *msgs;
+
+  int              error;      /* Error status of each transfers */
+  int              refs;       /* Reference count */
+};
+
+static struct bl602_i2cdev_s g_i2cdev =
+{
+  .refs = 0,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline int i2c_takesem(FAR sem_t *sem);
+static inline int i2c_givesem(FAR sem_t *sem);
+
+static int  bl602_i2c_interrupt(int irq, FAR void *context, FAR void *arg);
+static void bl602_i2c_timeout(wdparm_t arg);
+static void bl602_i2c_setfrequency(struct bl602_i2cdev_s *priv,
+                                   uint32_t frequency);
+static int  bl602_i2c_transfer(FAR struct i2c_master_s *dev,
+                               FAR struct i2c_msg_s *msgs, int count);
+#ifdef CONFIG_I2C_RESET
+static int bl602_i2c_reset(FAR struct i2c_master_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: i2c_takesem
+ ****************************************************************************/
+
+static inline int i2c_takesem(FAR sem_t *sem)
+{
+  return nxsem_wait_uninterruptible(sem);
+}
+
+/****************************************************************************
+ * Name: i2c_givesem
+ ****************************************************************************/
+
+static inline int i2c_givesem(FAR sem_t *sem)
+{
+  return nxsem_post(sem);
+}
+
+/****************************************************************************
+ * I2C device operations
+ ****************************************************************************/
+
+struct i2c_ops_s bl602_i2c_ops =
+{
+  .transfer = bl602_i2c_transfer,
+#ifdef CONFIG_I2C_RESET
+  .reset = bl602_i2c_reset,
+#endif
+};
+
+/****************************************************************************
+ * Name: bl602_i2c_setfrequency
+ *
+ * Description:
+ *   Set the frequency for the next transfer
+ *
+ ****************************************************************************/
+
+static void bl602_i2c_setfrequency(struct bl602_i2cdev_s *priv,
+                                   uint32_t frequency)
+{
+  uint16_t bclk_div;
+  uint32_t core_freq = getreg32(BL602_HBN_RSV2);
+  uint32_t i2c_clk_prd;
+  uint16_t i2c_clk_div = 1;
+  uint32_t reg;
+
+  i2cinfo("frequency=%lu\n", (unsigned long)frequency);
+  if (frequency == priv->frequency)
+    {
+      return;
+    }
+
+  bclk_div = ((getreg32(BL602_CLK_CFG0) & CLK_CFG0_REG_BCLK_DIV_MASK) >> \
+              CLK_CFG0_REG_BCLK_DIV_SHIFT) + 1;
+
+  i2c_clk_prd = ((core_freq / bclk_div / i2c_clk_div) / (frequency * 4));
+  if ((i2c_clk_prd - 1) > 0xff)
+    {
+      /* We cannot get enough scaling with just the PRD control
+       * the I2C clock could also be scaled here to increase the
+       * range.  For now we just cap it as this is not a standard
+       * frequency anyway.
+       */
+
+      i2c_clk_prd = 0xff;
+    }
+
+  i2cinfo("actual frequency=%lu\n",
+    (unsigned long)(core_freq / bclk_div / i2c_clk_div / 4 / i2c_clk_prd));
+
+  /* Set the I2C clock */
+
+  modifyreg32(BL602_CLK_CFG3, CLK_CFG3_I2C_CLK_DIV_MASK,
+              (i2c_clk_div - 1) << CLK_CFG3_I2C_CLK_DIV_SHIFT);
+
+  modifyreg32(BL602_CLK_CFG3, 0, CLK_CFG3_I2C_CLK_EN);
+
+  i2c_clk_prd -= 1;  /* Divider offest by 1 */
+  reg = i2c_clk_prd + \
+        (i2c_clk_prd << 8) + \
+        (i2c_clk_prd << 16) + \
+        (i2c_clk_prd << 24);
+
+  putreg32(reg, BL602_I2C_PRD_DATA);
+  putreg32(reg, BL602_I2C_PRD_START);
+  putreg32(reg, BL602_I2C_PRD_STOP);
+
+  priv->frequency = frequency;
+}
+
+/****************************************************************************
+ * Name: bl602_i2c_timeout
+ *
+ * Description:
+ *   Watchdog timer for timeout of I2C operation
+ *
+ ****************************************************************************/
+
+static void bl602_i2c_timeout(wdparm_t arg)
+{
+  struct bl602_i2cdev_s *priv = (struct bl602_i2cdev_s *)arg;
+  irqstate_t flags            = enter_critical_section();
+
+  priv->error = -ENODEV;
+  i2c_givesem(&priv->wait);
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: bl602_i2c_interrupt
+ *
+ * Description:
+ *   The I2C Interrupt Handler
+ *
+ ****************************************************************************/
+
+static int bl602_i2c_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+  FAR struct bl602_i2cdev_s *priv = (FAR struct bl602_i2cdev_s *)arg;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_i2c_transfer
+ *
+ * Description:
+ *   Perform a sequence of I2C transfers
+ *
+ ****************************************************************************/
+
+static int bl602_i2c_transfer(FAR struct i2c_master_s *dev,
+                              FAR struct i2c_msg_s *msgs, int count)
+{
+  struct bl602_i2cdev_s *priv = (struct bl602_i2cdev_s *)dev;
+  int i;
+  int ret    = 0;
+  int semval = 0;
+  int addr = -1;
+  uint32_t reg;
+
+  DEBUGASSERT(dev != NULL);
+
+  /* Get exclusive access to the I2C bus */
+
+  i2c_takesem(&priv->mutex);
+
+  ret = nxsem_get_value(&priv->wait, &semval);
+  DEBUGASSERT(ret == OK && semval == 0);
+
+  for (i = 0; i < count; i++, msgs++)
+    {
+      bl602_i2c_setfrequency(priv, msgs->frequency);
+
+      /* Set the slave address */
+
+      modifyreg32(BL602_I2C_CONFIG, I2C_CONFIG_CR_I2C_SLV_ADDR_MASK,
+                  msgs->addr << I2C_CONFIG_CR_I2C_SLV_ADDR_SHIFT);
+
+      if (msgs->length > I2C_FIFO_MAX_SIZE)
+        {
+          /* Too long to do in one transaction */
+
+          i2cinfo("msg is too long\n");
+          ret = -EINVAL;
+          break;
+        }
+
+      modifyreg32(BL602_I2C_CONFIG, I2C_CONFIG_CR_I2C_PKT_LEN_MASK,
+                  (msgs->length - 1) << I2C_CONFIG_CR_I2C_PKT_LEN_SHIFT);
+
+      /* Clear INT and FIFO status */
+
+      modifyreg32(BL602_I2C_INT_STS, 0,
+                  I2C_INT_STS_CR_NAK_CLR | \
+                  I2C_INT_STS_CR_ARB_CLR | \
+                  I2C_INT_STS_CR_END_CLR);
+      putreg32(0, BL602_I2C_FIFO_WDATA);
+      getreg32(BL602_I2C_FIFO_RDATA);
+      modifyreg32(BL602_I2C_FIFO_CONFIG_0, 0,
+                  I2C_FIFO_CONFIG_0_RX_FIFO_CLR | \
+                  I2C_FIFO_CONFIG_0_TX_FIFO_CLR);
+
+      if (msgs->flags & I2C_M_READ)
+        {
+          modifyreg32(BL602_I2C_CONFIG, 0, I2C_CONFIG_CR_I2C_PKT_DIR);
+        }
+      else
+        {
+          modifyreg32(BL602_I2C_CONFIG, I2C_CONFIG_CR_I2C_PKT_DIR, 0);
+          reg = 0;
+          memcpy((void *)&reg, msgs->buffer, msgs->length);
+          putreg32(reg, BL602_I2C_FIFO_WDATA);
+        }
+
+      /* Start the transaction */
+
+      modifyreg32(BL602_I2C_CONFIG, 0, I2C_CONFIG_CR_I2C_M_EN);
+
+      /* Wait for transfer to complete */
+
+      while (1)
+        {
+          reg = getreg32(BL602_I2C_INT_STS);
+          if (reg & I2C_INT_STS_NAK_INT)
+            {
+              i2cinfo("MSG NAK\n");
+              ret = -ENXIO;
+              break;
+            }
+          else if (reg & I2C_INT_STS_END_INT)
+            {
+              if (msgs->flags & I2C_M_READ)
+                {
+                  reg = getreg32(BL602_I2C_FIFO_RDATA);
+                  memcpy(msgs->buffer, (void *)&reg, msgs->length);
+                }
+
+              ret = OK;
+              break;
+            }
+        }
+
+      /* End the transaction */
+
+      modifyreg32(BL602_I2C_CONFIG, I2C_CONFIG_CR_I2C_M_EN, 0);
+
+      if (ret < 0)
+        {
+          break;
+        }
+    }
+
+  i2c_givesem(&priv->mutex);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_i2c_reset
+ *
+ * Description:
+ *   Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
+ *
+ * Input Parameters:
+ *   dev   - Device-specific state data
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_RESET
+static int bl602_i2c_reset(FAR struct i2c_master_s *dev)
+{
+  return OK;
+}
+#endif /* CONFIG_I2C_RESET */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bl602_i2cbus_initialize
+ *
+ * Description:
+ *   Initialise an I2C device
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *bl602_i2cbus_initialize(void)
+{
+  struct bl602_i2cdev_s *priv = &g_i2cdev;
+
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  priv->refs++;
+
+  /* Test if already initialized or not */
+
+  if (1 < priv->refs)
+    {
+      leave_critical_section(flags);
+      return &priv->dev;
+    }
+
+  priv->dev.ops = &bl602_i2c_ops;
+  priv->frequency = 0;
+
+  bl602_i2c_setfrequency(priv, I2C_DEFAULT_FREQUENCY);
+
+  leave_critical_section(flags);
+
+  /* Configure pin */
+
+  bl602_configgpio(BOARD_I2C_SCL);
+  bl602_configgpio(BOARD_I2C_SDA);
+
+  nxsem_init(&priv->mutex, 0, 1);
+  nxsem_init(&priv->wait, 0, 0);
+  nxsem_set_protocol(&priv->wait, SEM_PRIO_NONE);
+
+  /* Attach Interrupt Handler */
+
+  irq_attach(BL602_IRQ_I2C, bl602_i2c_interrupt, priv);
+
+  return &priv->dev;
+}
+
+/****************************************************************************
+ * Name: bl602_i2cbus_uninitialize
+ *
+ * Description:
+ *   Uninitialise an I2C device
+ *
+ ****************************************************************************/
+
+int bl602_i2cbus_uninitialize(FAR struct i2c_master_s *dev)
+{
+  struct bl602_i2cdev_s *priv = (struct bl602_i2cdev_s *)dev;
+
+  /* Decrement reference count and check for underflow */
+
+  if (priv->refs == 0)
+    {
+      return ERROR;
+    }
+
+  if (--priv->refs)
+    {
+      return OK;
+    }
+
+  up_disable_irq(BL602_IRQ_I2C);
+  irq_detach(BL602_IRQ_I2C);
+
+  wd_cancel(&priv->timeout);
+  nxsem_destroy(&priv->mutex);
+  nxsem_destroy(&priv->wait);
+
+  return OK;
+}
+
+#endif
diff --git a/boards/risc-v/bl602/bl602evb/include/board.h b/arch/risc-v/src/bl602/bl602_i2c.h
similarity index 69%
copy from boards/risc-v/bl602/bl602evb/include/board.h
copy to arch/risc-v/src/bl602/bl602_i2c.h
index bcfb38b..23c865d 100644
--- a/boards/risc-v/bl602/bl602evb/include/board.h
+++ b/arch/risc-v/src/bl602/bl602_i2c.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * boards/risc-v/bl602/bl602evb/include/board.h
+ * arch/risc-v/src/bl602/bl602_i2c.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __BOARDS_RISCV_BL602_BL602EVB_INCLUDE_BOARD_H
-#define __BOARDS_RISCV_BL602_BL602EVB_INCLUDE_BOARD_H
+#ifndef __ARCH_RISCV_SRC_BL602_BL602_I2C_H
+#define __ARCH_RISCV_SRC_BL602_BL602_I2C_H
 
 /****************************************************************************
  * Included Files
@@ -27,29 +27,16 @@
 
 #include <nuttx/config.h>
 
-/* Do not include BL602 header files here. */
+#include <stdint.h>
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* UART Configuration */
-
-#define BOARD_UART_0_RX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN7)
-#define BOARD_UART_0_TX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN16)
-#define BOARD_UART_1_RX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN3)
-#define BOARD_UART_1_TX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN4)
+#include <nuttx/i2c/i2c_master.h>
 
 /****************************************************************************
- * Public Types
+ * Public Data
  ****************************************************************************/
 
 #ifndef __ASSEMBLY__
 
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
 #undef EXTERN
 #if defined(__cplusplus)
 #define EXTERN extern "C"
@@ -64,14 +51,29 @@ extern "C"
  ****************************************************************************/
 
 /****************************************************************************
- * Name: litex_boardinitialize
+ * Name: bl602_i2cbus_initialize
+ *
+ * Description:
+ *   Initialise an I2C device
+ *
  ****************************************************************************/
 
-void bl602_boardinitialize(void);
+struct i2c_master_s *bl602_i2cbus_initialize(void);
+
+/****************************************************************************
+ * Name: bl602_i2cbus_uninitialize
+ *
+ * Description:
+ *   Uninitialise an I2C device
+ *
+ ****************************************************************************/
+
+int bl602_i2cbus_uninitialize(FAR struct i2c_master_s *dev);
 
 #undef EXTERN
 #if defined(__cplusplus)
 }
 #endif
+
 #endif /* __ASSEMBLY__ */
-#endif /* __BOARDS_RISC_V_BL602_BL602EVB_INCLUDE_BOARD_H */
+#endif /* __ARCH_RISCV_SRC_BL602_BL602_I2C_H */
diff --git a/arch/risc-v/src/bl602/hardware/bl602_hbn.h b/arch/risc-v/src/bl602/hardware/bl602_hbn.h
index 2954b45..eefc0a1 100644
--- a/arch/risc-v/src/bl602/hardware/bl602_hbn.h
+++ b/arch/risc-v/src/bl602/hardware/bl602_hbn.h
@@ -50,7 +50,7 @@
 #define BL602_HBN_SRAM_OFFSET          0x000034  /* HBN_SRAM */
 #define BL602_HBN_RSV0_OFFSET          0x000100  /* HBN_RSV0 */
 #define BL602_HBN_RSV1_OFFSET          0x000104  /* HBN_RSV1 */
-#define BL602_HBN_RSV2_OFFSET          0x000108  /* HBN_RSV2 */
+#define BL602_HBN_RSV2_OFFSET          0x000108  /* HBN_RSV2 sys core freq */
 #define BL602_HBN_RSV3_OFFSET          0x00010c  /* HBN_RSV3 */
 #define BL602_HBN_RC32K_CTRL0_OFFSET   0x000200  /* rc32k_ctrl0 */
 #define BL602_HBN_XTAL32K_OFFSET       0x000204  /* xtal32k */
diff --git a/boards/risc-v/bl602/bl602evb/include/board.h b/boards/risc-v/bl602/bl602evb/include/board.h
index bcfb38b..367b3f0 100644
--- a/boards/risc-v/bl602/bl602evb/include/board.h
+++ b/boards/risc-v/bl602/bl602evb/include/board.h
@@ -40,6 +40,11 @@
 #define BOARD_UART_1_RX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN3)
 #define BOARD_UART_1_TX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN4)
 
+/* I2C Configuration */
+
+#define BOARD_I2C_SCL (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_I2C | GPIO_PIN4)
+#define BOARD_I2C_SDA (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_I2C | GPIO_PIN3)
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
diff --git a/boards/risc-v/bl602/bl602evb/src/bl602_bringup.c b/boards/risc-v/bl602/bl602evb/src/bl602_bringup.c
index fdc7235..3f2283a 100644
--- a/boards/risc-v/bl602/bl602evb/src/bl602_bringup.c
+++ b/boards/risc-v/bl602/bl602evb/src/bl602_bringup.c
@@ -35,6 +35,7 @@
 #include <nuttx/input/buttons.h>
 #include <bl602_tim_lowerhalf.h>
 #include <bl602_oneshot_lowerhalf.h>
+#include <bl602_i2c.h>
 
 #include "chip.h"
 
@@ -52,6 +53,9 @@ int bl602_bringup(void)
   defined(CONFIG_BL602_TIMER1)
   struct oneshot_lowerhalf_s *os = NULL;
 #endif
+#ifdef CONFIG_BL602_I2C
+  struct i2c_master_s *i2c_bus;
+#endif
   int ret = OK;
 
 #ifdef CONFIG_FS_PROCFS
@@ -109,5 +113,10 @@ int bl602_bringup(void)
 #endif
 #endif
 
+#ifdef CONFIG_BL602_I2C
+  i2c_bus = bl602_i2cbus_initialize();
+  i2c_register(i2c_bus, 0);
+#endif
+
   return ret;
 }