You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2021/09/15 05:06:42 UTC

[incubator-nuttx] 01/04: drivers: video: Rearchitect video driver

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

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

commit 74df4b70b30132e94b8ca079223ddfe25d00dea5
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed Sep 15 12:02:33 2021 +0900

    drivers: video: Rearchitect video driver
    
    Rearchitect video driver:
    - Define two video I/F(struct imgsensor_ops_s and struct imgdata_ops_s),
      and support them.
    - CISIF driver supports new video I/F struct imgdata_ops_s.
    - ISX012 driver supports new video I/F struct imgsensor_ops_s.
    - Move ISX012 driver to general driver directory.
---
 arch/arm/include/cxd56xx/cisif.h                 |   54 +-
 arch/arm/src/cxd56xx/cxd56_cisif.c               |  474 ++-
 boards/arm/cxd56xx/common/src/cxd56_isx012.c     |    8 +-
 boards/arm/cxd56xx/drivers/Kconfig               |    1 -
 boards/arm/cxd56xx/drivers/Make.defs             |    1 -
 boards/arm/cxd56xx/drivers/camera/Kconfig        |    9 -
 boards/arm/cxd56xx/drivers/camera/Make.defs      |   27 -
 boards/arm/cxd56xx/drivers/camera/isx012.c       | 3869 ----------------------
 boards/arm/cxd56xx/spresense/src/cxd56_bringup.c |   19 +-
 drivers/video/Kconfig                            |   86 +
 drivers/video/Make.defs                          |    4 +
 drivers/video/isx012.c                           | 2917 ++++++++++++++++
 {include/nuttx => drivers}/video/isx012_range.h  |   32 +-
 {include/nuttx => drivers}/video/isx012_reg.h    |   16 +-
 drivers/video/video.c                            | 2055 ++++++++++--
 drivers/video/video_framebuff.c                  |   59 +-
 drivers/video/video_framebuff.h                  |   16 +-
 include/nuttx/video/{isx012.h => imgdata.h}      |   66 +-
 include/nuttx/video/imgsensor.h                  |  350 ++
 include/nuttx/video/isx012.h                     |    2 +-
 include/nuttx/video/video.h                      |  117 +-
 include/nuttx/video/video_halif.h                |   84 -
 22 files changed, 5632 insertions(+), 4634 deletions(-)

diff --git a/arch/arm/include/cxd56xx/cisif.h b/arch/arm/include/cxd56xx/cisif.h
index b42fcb7..9e60068 100644
--- a/arch/arm/include/cxd56xx/cisif.h
+++ b/arch/arm/include/cxd56xx/cisif.h
@@ -21,54 +21,6 @@
 #ifndef __ARCH_ARM_INCLUDE_CXD56XX_CISIF_H
 #define __ARCH_ARM_INCLUDE_CXD56XX_CISIF_H
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-typedef void (*notify_callback_t)(uint8_t code,
-                                  uint32_t size,
-                                  uint32_t addr);
-typedef void (*comp_callback_t)(uint8_t code,
-                                uint32_t size,
-                                uint32_t addr);
-
-struct cisif_init_yuv_param_s
-{
-  uint16_t          hsize;
-  uint16_t          vsize;
-  uint32_t          notify_size;
-  notify_callback_t notify_func;
-};
-
-typedef struct cisif_init_yuv_param_s cisif_init_yuv_param_t;
-
-struct cisif_init_jpeg_param_s
-{
-  uint32_t notify_size;
-  notify_callback_t notify_func;
-};
-
-typedef struct cisif_init_jpeg_param_s cisif_init_jpeg_param_t;
-
-struct cisif_sarea_s
-{
-  uint8_t *strg_addr;
-  uint32_t strg_size;
-};
-
-typedef struct cisif_sarea_s cisif_sarea_t;
-
-struct cisif_param_s
-{
-  uint32_t                format;
-  cisif_init_yuv_param_t  yuv_param;
-  cisif_init_jpeg_param_t jpg_param;
-  cisif_sarea_t           sarea;
-  comp_callback_t         comp_func;
-};
-
-typedef struct cisif_param_s cisif_param_t;
-
 #ifndef __ASSEMBLY__
 
 #undef EXTERN
@@ -84,11 +36,7 @@ extern "C"
  * Public Function Prototypes
  ****************************************************************************/
 
-int cxd56_cisifinit(void);
-int cxd56_cisiffinalize(void);
-int cxd56_cisifstartcapture(cisif_param_t *param, cisif_sarea_t *sarea);
-int cxd56_cisifstopcapture(void);
-int cxd56_cisifsetdmabuf(cisif_sarea_t *sarea);
+int cxd56_cisif_initialize(void);
 
 #undef EXTERN
 #if defined(__cplusplus)
diff --git a/arch/arm/src/cxd56xx/cxd56_cisif.c b/arch/arm/src/cxd56xx/cxd56_cisif.c
index 1e09519..b3f8cbd 100644
--- a/arch/arm/src/cxd56xx/cxd56_cisif.c
+++ b/arch/arm/src/cxd56xx/cxd56_cisif.c
@@ -35,8 +35,7 @@
 #include <nuttx/arch.h>
 
 #include <arch/chip/cisif.h>
-#include <nuttx/video/video.h>
-
+#include <nuttx/video/imgdata.h>
 #include "arm_arch.h"
 
 #include "cxd56_clock.h"
@@ -52,10 +51,22 @@
 
 /* #define CISIF_DBG_CONTI_CAP */
 
-#define YUV_VSIZE_MIN (64)
-#define YUV_HSIZE_MIN (96)
-#define YUV_VSIZE_MAX (360)
-#define YUV_HSIZE_MAX (480)
+#define YUV_VSIZE_STEP (1)
+#define YUV_HSIZE_STEP (1)
+#define YUV_VSIZE_MIN  (64)
+#define YUV_HSIZE_MIN  (96)
+#define YUV_VSIZE_MAX  (360)
+#define YUV_HSIZE_MAX  (480)
+
+#define JPG_VSIZE_STEP (1)
+#define JPG_HSIZE_STEP (1)
+#define JPG_VSIZE_MIN  (64)
+#define JPG_HSIZE_MIN  (96)
+#define JPG_VSIZE_MAX  (1944)
+#define JPG_HSIZE_MAX  (2592)
+
+#define CISIF_FMT_MIN  (1)
+#define CISIF_FMT_MAX  (3)
 
 #define JPG_INT_ALL   (JPG_ERR_STATUS_INT | \
                        JPG_MEM_OVF_INT    | \
@@ -108,6 +119,40 @@ typedef enum state_e state_t;
 
 typedef void (*intc_func_table)(uint8_t code);
 
+typedef void (*notify_callback_t)(uint8_t code,
+                                  uint32_t size,
+                                  uint32_t addr);
+typedef void (*comp_callback_t)(uint8_t code,
+                                uint32_t size,
+                                uint32_t addr);
+
+struct cisif_yuv_param_s
+{
+  uint16_t          hsize;
+  uint16_t          vsize;
+  uint32_t          notify_size;
+  notify_callback_t notify_func;
+};
+
+typedef struct cisif_yuv_param_s cisif_yuv_param_t;
+
+struct cisif_jpg_param_s
+{
+  uint32_t notify_size;
+  notify_callback_t notify_func;
+};
+
+typedef struct cisif_jpg_param_s cisif_jpg_param_t;
+
+struct cisif_param_s
+{
+  uint32_t           format;
+  cisif_yuv_param_t  yuv_param;
+  cisif_jpg_param_t  jpg_param;
+};
+
+typedef struct cisif_param_s cisif_param_t;
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -115,9 +160,8 @@ typedef void (*intc_func_table)(uint8_t code);
 static state_t g_state = STATE_STANDBY;
 static uint32_t g_storage_addr = 0;
 
-notify_callback_t g_jpg_notify_callback_func;
-notify_callback_t g_ycc_notify_callback_func;
-comp_callback_t   g_comp_callback_func;
+static notify_callback_t g_jpg_notify_callback_func;
+static notify_callback_t g_ycc_notify_callback_func;
 
 static bool     g_jpgint_receive;
 static bool     g_errint_receive;
@@ -129,6 +173,8 @@ static uint32_t g_cisif_time_start;
 static uint32_t g_cisif_time_stop;
 #endif
 
+static imgdata_capture_t g_cxd56_cisif_complete_capture;
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -145,15 +191,32 @@ static void     cisif_reg_write(uint16_t reg, uint32_t val);
 static uint32_t cisif_reg_read(uint16_t reg);
 
 static int cisif_check_param(cisif_param_t *p);
-static int cisif_set_yuv_param(cisif_param_t *p);
-static int cisif_set_jpg_param(cisif_param_t *p);
-
-static int cisif_check_sarea(void *s);
-static int cisif_set_yuv_sarea(void *s);
-static int cisif_set_jpg_sarea(void *s);
-static int cisif_set_intlev_sarea(void *s, uint32_t yuv_size);
-
-int cisif_intc_handler(int irq, FAR void *context, FAR void *arg);
+static int cisif_set_yuv_param(cisif_yuv_param_t *p);
+static int cisif_set_jpg_param(cisif_jpg_param_t *p);
+
+static int cisif_set_yuv_sarea(uint8_t *addr, uint32_t size);
+static int cisif_set_jpg_sarea(uint8_t *addr, uint32_t size);
+static int cisif_set_intlev_sarea(uint8_t *addr,
+                                  uint32_t total_size,
+                                  uint32_t yuv_size);
+static int cisif_intc_handler(int irq, FAR void *context, FAR void *arg);
+
+/* video image data operations */
+
+static int cxd56_cisif_init(void);
+static int cxd56_cisif_uninit(void);
+static int cxd56_cisif_validate_frame_setting
+             (uint8_t nr_datafmt,
+              FAR imgdata_format_t *datafmt,
+              FAR imgdata_interval_t *interval);
+static int cxd56_cisif_start_capture
+             (uint8_t nr_datafmt,
+              FAR imgdata_format_t *datafmt,
+              FAR imgdata_interval_t *interval,
+              imgdata_capture_t callback);
+static int cxd56_cisif_stop_capture(void);
+static int cxd56_cisif_validate_buf(uint8_t *addr, uint32_t size);
+static int cxd56_cisif_set_buf(uint8_t *addr, uint32_t size);
 
 const intc_func_table g_intcomp_func[] =
   {
@@ -188,6 +251,17 @@ const intc_func_table g_intcomp_func[] =
     cisif_jpg_err_int,       /* JPG_ERR_STATUS_INT */
   };
 
+const struct imgdata_ops_s g_cxd56_cisif_ops =
+  {
+    .init                   = cxd56_cisif_init,
+    .uninit                 = cxd56_cisif_uninit,
+    .validate_buf           = cxd56_cisif_validate_buf,
+    .set_buf                = cxd56_cisif_set_buf,
+    .validate_frame_setting = cxd56_cisif_validate_frame_setting,
+    .start_capture          = cxd56_cisif_start_capture,
+    .stop_capture           = cxd56_cisif_stop_capture,
+  };
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -290,7 +364,7 @@ static void cisif_callback_for_intlev(uint8_t code)
 
   /* Notify and get next addr */
 
-  g_comp_callback_func(0, size, g_storage_addr);
+  g_cxd56_cisif_complete_capture(0, size);
 
   g_jpgint_receive = false;
 
@@ -332,7 +406,7 @@ static void cisif_ycc_axi_trdn_int(uint8_t code)
   else
     {
       size = cisif_reg_read(CISIF_YCC_DSTRG_CONT);
-      g_comp_callback_func(0, size, g_storage_addr);
+      g_cxd56_cisif_complete_capture(0, size);
       cisif_reg_write(CISIF_YCC_DREAD_CONT, 0);
     }
 }
@@ -382,7 +456,7 @@ static void cisif_jpg_axi_trdn_int(uint8_t code)
   else
     {
       size = cisif_reg_read(CISIF_JPG_DSTRG_CONT);
-      g_comp_callback_func(0, size, g_storage_addr);
+      g_cxd56_cisif_complete_capture(0, size);
       cisif_reg_write(CISIF_JPG_DREAD_CONT, 0);
     }
 }
@@ -414,7 +488,7 @@ static void cisif_ycc_err_int(uint8_t code)
 #endif
 
   size = cisif_reg_read(CISIF_YCC_DSTRG_CONT);
-  g_comp_callback_func(code, size, g_storage_addr);
+  g_cxd56_cisif_complete_capture(code, size);
   cisif_reg_write(CISIF_YCC_DREAD_CONT, 0);
   g_errint_receive = true;
 }
@@ -426,16 +500,13 @@ static void cisif_ycc_err_int(uint8_t code)
 static void cisif_jpg_err_int(uint8_t code)
 {
   uint32_t size;
-  uint32_t addr;
 
 #ifdef CISIF_INTR_TRACE
   cisif_trace_time_stop("cisif_jpg_err_int");
 #endif
 
-  addr = g_storage_addr;
-
   size = cisif_reg_read(CISIF_JPG_DSTRG_CONT);
-  g_comp_callback_func(code, size, addr);
+  g_cxd56_cisif_complete_capture(code, size);
   cisif_reg_write(CISIF_JPG_DREAD_CONT, 0);
   g_errint_receive = true;
 }
@@ -444,7 +515,7 @@ static void cisif_jpg_err_int(uint8_t code)
  * cisif_intc_handler
  ****************************************************************************/
 
-int cisif_intc_handler(int irq, FAR void *context, FAR void *arg)
+static int cisif_intc_handler(int irq, FAR void *context, FAR void *arg)
 {
   uint32_t value;
   uint32_t enable;
@@ -488,6 +559,19 @@ static uint32_t cisif_reg_read(uint16_t reg)
   return getreg32(CXD56_CISIF_BASE + reg);
 }
 
+static bool is_uncompressed(uint32_t fmt)
+{
+  bool ret = false;
+
+  if ((fmt == IMGDATA_PIX_FMT_UYVY) ||
+      (fmt == IMGDATA_PIX_FMT_RGB565))
+    {
+      ret = true;
+    }
+
+  return ret;
+}
+
 /****************************************************************************
  * cisif_check_param
  ****************************************************************************/
@@ -499,23 +583,19 @@ static int cisif_check_param(cisif_param_t *p)
       return -EINVAL;
     }
 
-  if (p->comp_func == NULL)
-    {
-      return -EINVAL;
-    }
-
   switch (p->format)
     {
-      case V4L2_PIX_FMT_UYVY:
-      case V4L2_PIX_FMT_JPEG:
-      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:
+      case IMGDATA_PIX_FMT_UYVY:
+      case IMGDATA_PIX_FMT_RGB565:
+      case IMGDATA_PIX_FMT_JPEG:
+      case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG:
         break;
 
       default:
         return -EINVAL;
     }
 
-  if (p->format != V4L2_PIX_FMT_JPEG)
+  if (p->format != IMGDATA_PIX_FMT_JPEG)
     {
       if (p->yuv_param.hsize < YUV_HSIZE_MIN ||
           p->yuv_param.hsize > YUV_HSIZE_MAX ||
@@ -534,7 +614,7 @@ static int cisif_check_param(cisif_param_t *p)
         }
     }
 
-  if (p->format != V4L2_PIX_FMT_UYVY)
+  if (!is_uncompressed(p->format))
     {
       if (p->jpg_param.notify_func != NULL)
         {
@@ -549,46 +629,25 @@ static int cisif_check_param(cisif_param_t *p)
 }
 
 /****************************************************************************
- * cisif_check_sarea
- ****************************************************************************/
-
-static int cisif_check_sarea(void *s)
-{
-  if (s == NULL)
-    {
-      return -EINVAL;
-    }
-
-  cisif_sarea_t *ss = (cisif_sarea_t *)s;
-  if (ILLEGAL_BUFADDR_ALIGNMENT(ss->strg_addr) ||
-      ss->strg_size == 0)
-    {
-      return -EINVAL;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
  * cisif_set_yuvparam
  ****************************************************************************/
 
-static int cisif_set_yuv_param(cisif_param_t *p)
+static int cisif_set_yuv_param(cisif_yuv_param_t *p)
 {
   uint32_t act_size = 0;
 
-  act_size = (p->yuv_param.vsize & 0x1ff) << 16;
-  act_size |= p->yuv_param.hsize & 0x1ff;
+  act_size = (p->vsize & 0x1ff) << 16;
+  act_size |= p->hsize & 0x1ff;
 
   cisif_reg_write(CISIF_ACT_SIZE, act_size);
   cisif_reg_write(CISIF_CIS_SIZE, act_size);
 
   /* must align 32 bytes */
 
-  cisif_reg_write(CISIF_YCC_NSTRG_SIZE, (p->yuv_param.notify_size
-                                                 & 0xffffffe0));
+  cisif_reg_write(CISIF_YCC_NSTRG_SIZE,
+                  (p->notify_size & 0xffffffe0));
 
-  g_ycc_notify_callback_func = p->yuv_param.notify_func;
+  g_ycc_notify_callback_func = p->notify_func;
 
   return OK;
 }
@@ -597,14 +656,12 @@ static int cisif_set_yuv_param(cisif_param_t *p)
  * cisif_set_yuvsarea
  ****************************************************************************/
 
-static int cisif_set_yuv_sarea(void *s)
+static int cisif_set_yuv_sarea(uint8_t *addr, uint32_t size)
 {
-  cisif_sarea_t *ss = (cisif_sarea_t *)s;
-
   /* must align 32 bytes */
 
-  cisif_reg_write(CISIF_YCC_DAREA_SIZE, (ss->strg_size & 0xffffffe0));
-  cisif_reg_write(CISIF_YCC_START_ADDR, CXD56_PHYSADDR(ss->strg_addr));
+  cisif_reg_write(CISIF_YCC_DAREA_SIZE, (size & 0xffffffe0));
+  cisif_reg_write(CISIF_YCC_START_ADDR, CXD56_PHYSADDR(addr));
 
   return OK;
 }
@@ -613,14 +670,14 @@ static int cisif_set_yuv_sarea(void *s)
  * cisif_set_jpg_param
  ****************************************************************************/
 
-static int cisif_set_jpg_param(cisif_param_t *p)
+static int cisif_set_jpg_param(cisif_jpg_param_t *p)
 {
   /* must align 32 bytes */
 
-  cisif_reg_write(CISIF_JPG_NSTRG_SIZE, (p->jpg_param.notify_size
+  cisif_reg_write(CISIF_JPG_NSTRG_SIZE, (p->notify_size
                                                & 0xffffffe0));
 
-  g_jpg_notify_callback_func = p->jpg_param.notify_func;
+  g_jpg_notify_callback_func = p->notify_func;
 
   return OK;
 }
@@ -629,14 +686,12 @@ static int cisif_set_jpg_param(cisif_param_t *p)
  * cisif_set_jpg_sarea
  ****************************************************************************/
 
-static int cisif_set_jpg_sarea(void *s)
+static int cisif_set_jpg_sarea(uint8_t *addr, uint32_t size)
 {
-  cisif_sarea_t *ss = (cisif_sarea_t *)s;
-
   /* must align 32 bytes */
 
-  cisif_reg_write(CISIF_JPG_DAREA_SIZE, (ss->strg_size & 0xffffffe0));
-  cisif_reg_write(CISIF_JPG_START_ADDR, CXD56_PHYSADDR(ss->strg_addr));
+  cisif_reg_write(CISIF_JPG_DAREA_SIZE, (size & 0xffffffe0));
+  cisif_reg_write(CISIF_JPG_START_ADDR, CXD56_PHYSADDR(addr));
 
   return OK;
 }
@@ -645,41 +700,73 @@ static int cisif_set_jpg_sarea(void *s)
  * cisif_set_jpg_sarea
  ****************************************************************************/
 
-static int cisif_set_intlev_sarea(void *s, uint32_t yuv_size)
+static int cisif_set_intlev_sarea(uint8_t *addr,
+                                  uint32_t total_size,
+                                  uint32_t yuv_size)
 {
-  cisif_sarea_t *sarea = (cisif_sarea_t *)s;
-  cisif_sarea_t sarea_int;
-
-  if (sarea->strg_size < yuv_size)
+  if (total_size < yuv_size)
     {
       return -EINVAL;
     }
 
   /* Set for YUV */
 
-  sarea_int.strg_addr = sarea->strg_addr;
-  sarea_int.strg_size = yuv_size;
-  cisif_set_yuv_sarea(&sarea_int);
+  cisif_set_yuv_sarea(addr, yuv_size);
 
   /* Set for JPEG */
 
-  sarea_int.strg_addr = sarea->strg_addr + yuv_size;
-  sarea_int.strg_size = sarea->strg_size - yuv_size;
+  cisif_set_jpg_sarea(addr + yuv_size, total_size - yuv_size);
 
-  cisif_set_jpg_sarea(&sarea_int);
+  return OK;
+}
+
+/****************************************************************************
+ * cisif_chk_jpgfrmsize
+ ****************************************************************************/
+
+static int cisif_chk_jpgfrmsize(int w, int h)
+{
+  if ((w < JPG_HSIZE_MIN) ||
+      (w > JPG_HSIZE_MAX))
+    {
+      return -EINVAL;
+    }
+
+  if ((h < JPG_VSIZE_MIN) ||
+      (h > JPG_VSIZE_MAX))
+    {
+      return -EINVAL;
+    }
 
   return OK;
 }
 
 /****************************************************************************
- * Public Functions
+ * cisif_chk_yuvfrmsize
  ****************************************************************************/
 
+static int cisif_chk_yuvfrmsize(int w, int h)
+{
+  if ((w < YUV_HSIZE_MIN) ||
+      (w > YUV_HSIZE_MAX))
+    {
+      return -EINVAL;
+    }
+
+  if ((h < YUV_VSIZE_MIN) ||
+      (h > YUV_VSIZE_MAX))
+    {
+      return -EINVAL;
+    }
+
+  return OK;
+}
+
 /****************************************************************************
- * cxd56_cisifinit
+ * cxd56_cisif_init
  ****************************************************************************/
 
-int cxd56_cisifinit(void)
+static int cxd56_cisif_init(void)
 {
   if (g_state != STATE_STANDBY)
     {
@@ -708,15 +795,14 @@ int cxd56_cisifinit(void)
 #endif
 
   g_state = STATE_READY;
-
   return OK;
 }
 
 /****************************************************************************
- * cxd56_cisiffinalize
+ * cxd56_cisif_uninit
  ****************************************************************************/
 
-int cxd56_cisiffinalize(void)
+static int cxd56_cisif_uninit(void)
 {
   if (g_state != STATE_READY)
     {
@@ -741,19 +827,28 @@ int cxd56_cisiffinalize(void)
   cxd56_img_cisif_clock_disable();
 
   g_state = STATE_STANDBY;
-
   return OK;
 }
 
 /****************************************************************************
- * cxd56_cisifstartcapturing
+ * cxd56_cisif_start_capture
  ****************************************************************************/
 
-int cxd56_cisifstartcapture(
-  cisif_param_t *param,
-  cisif_sarea_t *sarea)
+static int cxd56_cisif_start_capture
+             (uint8_t nr_fmt,
+              FAR imgdata_format_t *fmt,
+              FAR imgdata_interval_t *interval,
+              imgdata_capture_t callback)
 {
-  uint32_t cisif_mode;
+  cisif_param_t param =
+    {
+      0
+    };
+
+  cisif_yuv_param_t *yuv = &param.yuv_param;
+  cisif_jpg_param_t *jpg = &param.jpg_param;
+
+  uint32_t mode;
   uint32_t interrupts = VS_INT;
   int ret;
 
@@ -762,47 +857,52 @@ int cxd56_cisifstartcapture(
       return -EPERM;
     }
 
-  ret = cisif_check_param(param);
-  if (ret != OK)
+  param.format = fmt[IMGDATA_FMT_MAIN].pixelformat;
+  if (param.format != IMGDATA_PIX_FMT_JPEG)
     {
-      return ret;
+      if (is_uncompressed(param.format))
+        {
+          yuv->hsize = fmt[IMGDATA_FMT_MAIN].width;
+          yuv->vsize = fmt[IMGDATA_FMT_MAIN].height;
+        }
+      else
+        {
+          yuv->hsize = fmt[IMGDATA_FMT_SUB].width;
+          yuv->vsize = fmt[IMGDATA_FMT_SUB].height;
+        }
     }
 
-  cisif_reg_write(CISIF_INTR_DISABLE, ALL_CLEAR_INT);
-
-  ret = cisif_check_sarea(sarea);
+  ret = cisif_check_param(&param);
   if (ret != OK)
     {
       return ret;
     }
 
-  switch (param->format)
+  cisif_reg_write(CISIF_INTR_DISABLE, ALL_CLEAR_INT);
+
+  switch (param.format)
     {
-      case V4L2_PIX_FMT_UYVY:
-        cisif_set_yuv_param(param);
-        cisif_set_yuv_sarea(sarea);
+      case IMGDATA_PIX_FMT_UYVY:
+      case IMGDATA_PIX_FMT_RGB565:
 
-        cisif_mode = MODE_YUV_TRS_EN;
+        cisif_set_yuv_param(yuv);
+
+        mode = MODE_YUV_TRS_EN;
         interrupts |= YCC_INT_ALL;
         break;
 
-      case V4L2_PIX_FMT_JPEG:
-        cisif_set_jpg_param(param);
-        cisif_set_jpg_sarea(sarea);
+      case IMGDATA_PIX_FMT_JPEG:
+        cisif_set_jpg_param(jpg);
 
-        cisif_mode = MODE_JPG_TRS_EN;
+        mode = MODE_JPG_TRS_EN;
         interrupts |= JPG_INT_ALL;
         break;
 
-      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:
-        cisif_set_yuv_param(param);
-        cisif_set_jpg_param(param);
-
-        cisif_set_intlev_sarea(sarea,
-                               YUV_SIZE(param->yuv_param.vsize,
-                               param->yuv_param.hsize));
+      case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG:
+        cisif_set_yuv_param(yuv);
+        cisif_set_jpg_param(jpg);
 
-        cisif_mode = MODE_INTLEV_TRS_EN;
+        mode = MODE_INTLEV_TRS_EN;
         interrupts |= YCC_INT_ALL | JPG_INT_ALL;
         g_jpgint_receive = false;
         break;
@@ -811,8 +911,7 @@ int cxd56_cisifstartcapture(
         return -EINVAL;
     }
 
-  g_comp_callback_func = param->comp_func;
-  g_storage_addr       = (uint32_t)sarea->strg_addr;
+  g_cxd56_cisif_complete_capture = callback;
 
   g_state = STATE_CAPTURE;
 
@@ -826,17 +925,16 @@ int cxd56_cisifstartcapture(
       interrupts |= JPG_NSTORAGE_INT;
     }
 
-  cisif_reg_write(CISIF_MODE, cisif_mode);
+  cisif_reg_write(CISIF_MODE, mode);
   cisif_reg_write(CISIF_INTR_CLEAR, interrupts);
   cisif_reg_write(CISIF_INTR_ENABLE, interrupts);
 
   cisif_reg_write(CISIF_DIN_ENABLE, 1);
-  cisif_reg_write(CISIF_EXE_CMD, 1);
 
   return OK;
 }
 
-int cxd56_cisifstopcapture(void)
+static int cxd56_cisif_stop_capture(void)
 {
   g_state = STATE_READY;
   cisif_reg_write(CISIF_DIN_ENABLE, 0);
@@ -846,42 +944,54 @@ int cxd56_cisifstopcapture(void)
   return OK;
 }
 
-int cxd56_cisifsetdmabuf(cisif_sarea_t *sarea)
+static int cxd56_cisif_validate_buf(uint8_t *addr, uint32_t size)
+{
+  if (ILLEGAL_BUFADDR_ALIGNMENT(addr) ||
+      size == 0)
+    {
+      return -EINVAL;
+    }
+
+  return OK;
+}
+
+static int cxd56_cisif_set_buf(uint8_t *addr, uint32_t size)
 {
   int      ret;
-  uint32_t cisif_mode;
-  uint32_t yuv_regsize;
-  uint32_t yuv_hsize;
-  uint32_t yuv_vsize;
+  uint32_t mode;
+  uint32_t regval;
+  uint16_t w;
+  uint16_t h;
 
-  ret = cisif_check_sarea(sarea);
+  ret = cxd56_cisif_validate_buf(addr, size);
   if (ret != OK)
     {
       return ret;
     }
 
-  cisif_mode = cisif_reg_read(CISIF_MODE);
+  mode = cisif_reg_read(CISIF_MODE);
 
-  switch (cisif_mode)
+  switch (mode)
     {
       case MODE_YUV_TRS_EN:
-        ret = cisif_set_yuv_sarea(sarea);
+        ret = cisif_set_yuv_sarea(addr, size);
         break;
 
       case MODE_JPG_TRS_EN:
-        ret = cisif_set_jpg_sarea(sarea);
+        ret = cisif_set_jpg_sarea(addr, size);
         break;
 
       default: /* MODE_INTLEV_TRS_EN */
 
         /* Get YUV frame size information */
 
-        yuv_regsize =  cisif_reg_read(CISIF_ACT_SIZE);
-        yuv_vsize = (yuv_regsize >> 16) & 0x1ff;
-        yuv_hsize = yuv_regsize & 0x01ff;
+        regval =  cisif_reg_read(CISIF_ACT_SIZE);
+        h = (regval >> 16) & 0x1ff;
+        w = regval & 0x01ff;
 
-        ret = cisif_set_intlev_sarea(sarea,
-                                     YUV_SIZE(yuv_vsize, yuv_hsize));
+        ret = cisif_set_intlev_sarea(addr,
+                                     size,
+                                     YUV_SIZE(w, h));
         break;
     }
 
@@ -891,7 +1001,83 @@ int cxd56_cisifsetdmabuf(cisif_sarea_t *sarea)
     }
 
   cisif_reg_write(CISIF_EXE_CMD, 1);
-  g_storage_addr = (uint32_t)sarea->strg_addr;
+  g_storage_addr = (uint32_t)addr;
+
+  return ret;
+}
+
+static int cxd56_cisif_validate_frame_setting
+             (uint8_t nr_datafmt,
+              FAR imgdata_format_t *datafmt,
+              FAR imgdata_interval_t *interval)
+{
+  int ret = OK;
+
+  if ((nr_datafmt < CISIF_FMT_MIN) || (nr_datafmt > CISIF_FMT_MAX))
+    {
+      return -EINVAL;
+    }
+
+  switch (datafmt[IMGDATA_FMT_MAIN].pixelformat)
+    {
+      case IMGDATA_PIX_FMT_UYVY:                /* YUV 4:2:2 */
+      case IMGDATA_PIX_FMT_RGB565:              /* RGB565 */
+
+        ret = cisif_chk_yuvfrmsize(datafmt[IMGDATA_FMT_MAIN].width,
+                                   datafmt[IMGDATA_FMT_MAIN].height);
+        break;
+
+      case IMGDATA_PIX_FMT_JPEG:                /* JPEG */
+
+        ret = cisif_chk_jpgfrmsize(datafmt[IMGDATA_FMT_MAIN].width,
+                                   datafmt[IMGDATA_FMT_MAIN].height);
+        break;
+
+      case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG:    /* JPEG + YUV 4:2:2 */
+
+        if ((nr_datafmt == 2) &&
+            !is_uncompressed(datafmt[IMGDATA_FMT_SUB].pixelformat))
+          {
+            /* Unsupported pixel format */
+
+            return -EINVAL;
+          }
+
+        ret = cisif_chk_jpgfrmsize(datafmt[IMGDATA_FMT_MAIN].width,
+                                   datafmt[IMGDATA_FMT_MAIN].height);
+        if (ret != OK)
+          {
+            return ret;
+          }
+
+        if (nr_datafmt == 2)
+          {
+            ret = cisif_chk_yuvfrmsize
+                    (datafmt[IMGDATA_FMT_SUB].width,
+                     datafmt[IMGDATA_FMT_SUB].height);
+          }
+
+        break;
+
+      default: /* Unsupported pixel format */
+
+        return -EINVAL;
+    }
 
   return ret;
 }
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * cxd56_cisif_initialize
+ ****************************************************************************/
+
+int cxd56_cisif_initialize(void)
+{
+  imgdata_register(&g_cxd56_cisif_ops);
+  return OK;
+}
+
diff --git a/boards/arm/cxd56xx/common/src/cxd56_isx012.c b/boards/arm/cxd56xx/common/src/cxd56_isx012.c
index a36d9bc..f8f5f7c 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_isx012.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_isx012.c
@@ -184,10 +184,10 @@ int board_isx012_initialize(int i2c_bus_num)
       return -ENODEV;
     }
 
-  ret = isx012_register(i2c);
+  ret = isx012_initialize(i2c);
   if (ret < 0)
     {
-      _err("Error registering ISX012.\n");
+      _err("Failed to initialize ISX012.\n");
     }
 
   return ret;
@@ -201,10 +201,10 @@ int board_isx012_uninitialize(void)
 
   /* Initialize i2c device */
 
-  ret = isx012_unregister();
+  ret = isx012_uninitialize();
   if (ret < 0)
     {
-      _err("Error unregistering ISX012.\n");
+      _err("Failed to uninitialize ISX012.\n");
     }
 
   if (!i2c)
diff --git a/boards/arm/cxd56xx/drivers/Kconfig b/boards/arm/cxd56xx/drivers/Kconfig
index 0c9ede0..d336be8 100644
--- a/boards/arm/cxd56xx/drivers/Kconfig
+++ b/boards/arm/cxd56xx/drivers/Kconfig
@@ -6,5 +6,4 @@
 if SPECIFIC_DRIVERS
 source "drivers/platform/audio/Kconfig"
 source "drivers/platform/sensors/Kconfig"
-source "drivers/platform/camera/Kconfig"
 endif
diff --git a/boards/arm/cxd56xx/drivers/Make.defs b/boards/arm/cxd56xx/drivers/Make.defs
index 16578f9..39073bd 100644
--- a/boards/arm/cxd56xx/drivers/Make.defs
+++ b/boards/arm/cxd56xx/drivers/Make.defs
@@ -20,4 +20,3 @@
 
 include platform/audio/Make.defs
 include platform/sensors/Make.defs
-include platform/camera/Make.defs
diff --git a/boards/arm/cxd56xx/drivers/camera/Kconfig b/boards/arm/cxd56xx/drivers/camera/Kconfig
deleted file mode 100644
index fc563df..0000000
--- a/boards/arm/cxd56xx/drivers/camera/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see the file kconfig-language.txt in the NuttX tools repository.
-#
-
-config VIDEO_ISX012
-	bool "ISX012 Image sensor"
-	default n
-	select I2C
diff --git a/boards/arm/cxd56xx/drivers/camera/Make.defs b/boards/arm/cxd56xx/drivers/camera/Make.defs
deleted file mode 100644
index 637f196..0000000
--- a/boards/arm/cxd56xx/drivers/camera/Make.defs
+++ /dev/null
@@ -1,27 +0,0 @@
-############################################################################
-# boards/arm/cxd56xx/drivers/camera/Make.defs
-#
-# 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.
-#
-############################################################################
-
-ifeq ($(CONFIG_VIDEO_ISX012),y)
-  CSRCS += isx012.c
-endif
-
-DEPPATH += --dep-path platform$(DELIM)camera
-VPATH += :platform$(DELIM)camera
-CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)platform$(DELIM)camera)
diff --git a/boards/arm/cxd56xx/drivers/camera/isx012.c b/boards/arm/cxd56xx/drivers/camera/isx012.c
deleted file mode 100644
index bbda6d3..0000000
--- a/boards/arm/cxd56xx/drivers/camera/isx012.c
+++ /dev/null
@@ -1,3869 +0,0 @@
-/****************************************************************************
- * boards/arm/cxd56xx/drivers/camera/isx012.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 <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/signal.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/i2c/i2c_master.h>
-#include <arch/board/board.h>
-#include <arch/chip/cisif.h>
-#include <arch/irq.h>
-
-#include <nuttx/video/isx012.h>
-#include <nuttx/video/isx012_reg.h>
-#include <nuttx/video/isx012_range.h>
-#include <nuttx/video/video_halif.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* The following macro is enabled because
- * it is to make stable startup. (other case)
- */
-
-/* #define ISX012_NOT_USE_NSTBY */
-
-/* The following macro is disabled because it is to see detailed control. */
-
-/* #define ISX012_CHECK_IN_DETAIL */
-
-/* Skip invalid frame because it occurs first due to the spec of isx012. */
-
-#define ISX012_FRAME_SKIP_EN
-
-#define OUT_HSIZE_QVGA           (320)
-#define OUT_VSIZE_QVGA           (240)
-#define OUT_HSIZE_VGA            (640)
-#define OUT_VSIZE_VGA            (480)
-#define OUT_HSIZE_HD            (1280)
-#define OUT_VSIZE_HD             (720)
-#define OUT_HSIZE_QUADVGA       (1280)
-#define OUT_VSIZE_QUADVGA        (960)
-#define OUT_HSIZE_FULLHD        (1920)
-#define OUT_VSIZE_FULLHD        (1080)
-#define OUT_HSIZE_3M            (2048)
-#define OUT_VSIZE_3M            (1536)
-#define OUT_HSIZE_5M            (2560)
-#define OUT_VSIZE_5M            (1920)
-
-#define OUT_YUV_VSIZE_MIN         (64)
-#define OUT_YUV_HSIZE_MIN         (96)
-#define OUT_JPG_VSIZE_MIN         (64)
-#define OUT_JPG_HSIZE_MIN         (96)
-#define OUT_YUV_15FPS_VSIZE_MAX  (360)
-#define OUT_YUV_15FPS_HSIZE_MAX  (480)
-#define OUT_YUV_30FPS_VSIZE_MAX  (360)
-#define OUT_YUV_30FPS_HSIZE_MAX  (480)
-#define OUT_YUV_60FPS_VSIZE_MAX  (360)
-#define OUT_YUV_60FPS_HSIZE_MAX  (480)
-#define OUT_YUV_120FPS_VSIZE_MAX (240)
-#define OUT_YUV_120FPS_HSIZE_MAX (320)
-#define OUT_JPG_15FPS_VSIZE_MAX (1944)
-#define OUT_JPG_15FPS_HSIZE_MAX (2592)
-#define OUT_JPG_30FPS_VSIZE_MAX  (960)
-#define OUT_JPG_30FPS_HSIZE_MAX (1280)
-#define OUT_JPG_60FPS_VSIZE_MAX  (480)
-#define OUT_JPG_60FPS_HSIZE_MAX  (640)
-#define OUT_JPG_120FPS_VSIZE_MAX (240)
-#define OUT_JPG_120FPS_HSIZE_MAX (320)
-
-#define OUT_YUVINT_30FPS_VSIZE_MAX  (240)
-#define OUT_YUVINT_30FPS_HSIZE_MAX  (400)
-#define OUT_JPGINT_30FPS_VSIZE_MAX  (960)
-#define OUT_JPGINT_30FPS_HSIZE_MAX (1280)
-#define OUT_JPGINT_15FPS_VSIZE_MAX (1224)
-#define OUT_JPGINT_15FPS_HSIZE_MAX (1632)
-
-#define VINT_TIMEOUT                (400) /* ms */
-#define VINT_WAIT_TIME                (5) /* ms */
-#define VINT_DELAY_TIME               (0) /* ms */
-#define CAMERA_MODE_TIMEOUT         (800) /* ms */
-#define CAMERA_MODE_WAIT_TIME        (10) /* ms */
-#define CAMERA_MODE_DELAY_TIME        (0) /* ms */
-#define DEVICE_STATE_TIMEOUT        (100) /* ms */
-#define DEVICE_STATE_WAIT_TIME        (1) /* ms */
-#define DEVICE_STATE_DELAY_TIME       (2) /* ms */
-
-#define I2CFREQ_STANDARD         (100000) /* Standard mode : 100kHz */
-#define I2CFREQ_FAST             (400000) /* Fast mode     : 400kHz */
-
-#define ISX012_SIZE_STEP              (2)
-
-#define CXC_RGB_DATA_UNIT_NUM        (27)
-#define CXC_RGB_DATA_UNIT_SIZE        (7)
-#define CXC_GRB_DATA_UNIT_NUM        (27)
-#define CXC_GRB_DATA_UNIT_SIZE        (7)
-#define SHD_RGB_DATA_UNIT_NUM        (27)
-#define SHD_RGB_DATA_UNIT_SIZE       (11)
-#define SHD_GRB_DATA_UNIT_NUM        (27)
-#define SHD_GRB_DATA_UNIT_SIZE       (11)
-#define SHD_R1_DATA_UNIT_NUM         (14)
-#define SHD_R1_DATA_UNIT_SIZE        (11)
-#define SHD_R2_DATA_UNIT_NUM         (14)
-#define SHD_R2_DATA_UNIT_SIZE        (11)
-#define SHD_B2_DATA_UNIT_NUM         (14)
-#define SHD_B2_DATA_UNIT_SIZE        (11)
-
-#ifdef CONFIG_DEBUG_IMAGER_ERROR
-#define imagererr(format, ...)     _err(format, ##__VA_ARGS__)
-#else
-#define imagererr(x...)
-#endif
-
-#ifdef CONFIG_DEBUG_IMAGER_WARN
-#define imagerwarn(format, ...)   _warn(format, ##__VA_ARGS__)
-#else
-#define imagerwarn(x...)
-#endif
-
-#ifdef CONFIG_DEBUG_IMAGER_INFO
-#define imagerinfo(format, ...)   _info(format, ##__VA_ARGS__)
-#else
-#define imagerinfo(x...)
-#endif
-
-#define CHECK_RANGE(value,min,max,step) do { \
-                                          if ((value < min) || \
-                                              (value > max) || \
-                                              ((value - min) % step != 0)) \
-                                            { \
-                                              return -EINVAL;\
-                                            } \
-                                         } while (0)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-enum isx012_state_e
-{
-  STATE_ISX012_PRESLEEP,
-  STATE_ISX012_SLEEP,
-  STATE_ISX012_ACTIVE,
-  STATE_ISX012_POWEROFF,
-};
-
-typedef enum isx012_state_e isx012_state_t;
-
-struct isx012_reg_s
-{
-  uint16_t regaddr;
-  uint16_t regval;
-  uint8_t  regsize;
-};
-
-typedef struct isx012_reg_s isx012_reg_t;
-
-struct isx012_conv_v4l2_to_regval_s
-{
-  int32_t v4l2;
-  int16_t regval;
-};
-
-typedef struct isx012_conv_v4l2_to_regval_s isx012_conv_v4l2_to_regval_t;
-
-struct isx012_modeparam_s
-{
-  uint8_t  fps;         /* use ISX012 register setting value */
-  uint32_t format;      /* use V4L2 definition */
-  uint16_t hsize;
-  uint16_t vsize;
-  uint16_t int_hsize;
-  uint16_t int_vsize;
-};
-
-typedef struct isx012_modeparam_s isx012_modeparam_t;
-
-struct isx012_param_s
-{
-  isx012_modeparam_t video;  /* Parameter for video capture mode */
-  isx012_modeparam_t still;  /* Parameter for still capture mode */
-};
-
-typedef struct isx012_param_s isx012_param_t;
-
-struct isx012_dev_s
-{
-  FAR struct i2c_master_s *i2c;        /* I2C interface */
-  uint8_t                 i2c_addr;    /* I2C address */
-  int                     i2c_freq;    /* Frequency */
-  isx012_state_t          state;       /* ISX012 status */
-  bool                    dma_state;   /* true means "in DMA" */
-  uint8_t                 mode;        /* ISX012 mode */
-  isx012_param_t          param;       /* ISX012 parameters */
-  void                    *video_priv; /* pointer to video private data */
-};
-
-typedef struct isx012_dev_s isx012_dev_t;
-
-#define ARRAY_NENTRIES(a) (sizeof(a)/sizeof(isx012_reg_t))
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* register operations */
-
-static uint16_t isx012_getreg(isx012_dev_t *priv,
-                              uint16_t regaddr, uint16_t regsize);
-static int     isx012_putreg(isx012_dev_t *priv, uint16_t regaddr,
-                             uint16_t regval, uint16_t regsize);
-static int     isx012_putreglist(isx012_dev_t *priv,
-                         FAR const isx012_reg_t *reglist, size_t nentries);
-#ifdef ISX012_CHECK_IN_DETAIL
-static int     isx012_putregs(isx012_dev_t *priv, uint16_t regaddr,
-                              uint8_t *regvals, uint8_t regsize);
-static int     isx012_chipid(FAR struct i2c_master_s *i2c);
-#endif
-
-static int isx012_chk_int_state(isx012_dev_t *priv,
-                                uint8_t  sts, uint32_t delay_time,
-                                uint32_t wait_time, uint32_t timeout);
-static int isx012_set_mode_param(isx012_dev_t *priv,
-                                 enum v4l2_buf_type type,
-                                 isx012_modeparam_t *param);
-static int isx012_change_camera_mode(isx012_dev_t *priv, uint8_t mode);
-static int isx012_change_device_state(isx012_dev_t *priv,
-                                      isx012_state_t state);
-static int isx012_set_supported_frminterval(uint32_t fps_index,
-                                            FAR struct v4l2_fract *interval);
-static int8_t isx012_get_maximum_fps(FAR struct v4l2_frmivalenum *frmival);
-static int isx012_set_shd(FAR isx012_dev_t *priv);
-
-static bool is_movie_needed(isx012_modeparam_t *param);
-
-/* video driver HAL infterface */
-
-static int isx012_open(FAR void *video_private);
-static int isx012_close(void);
-static int isx012_do_halfpush(bool enable);
-static int isx012_set_buftype(enum v4l2_buf_type type);
-static int isx012_set_buf(uint32_t bufaddr, uint32_t bufsize);
-static int isx012_cancel_dma(void);
-static int isx012_check_fmt(enum v4l2_buf_type buf_type,
-                            uint32_t           pixel_format);
-static int isx012_get_range_of_fmt(FAR struct v4l2_fmtdesc *format);
-static int isx012_get_range_of_framesize(FAR struct v4l2_frmsizeenum
-                                         *frmsize);
-static int isx012_try_format(FAR struct v4l2_format *format);
-static int isx012_set_format(FAR struct v4l2_format *format);
-static int isx012_get_range_of_frameinterval(FAR struct v4l2_frmivalenum
-                                             *frmival);
-static int isx012_set_frameinterval(FAR struct v4l2_streamparm *parm);
-static int isx012_get_range_of_ctrlval(FAR struct v4l2_query_ext_ctrl
-                                         *range);
-static int isx012_get_menu_of_ctrlval(FAR struct v4l2_querymenu *menu);
-static int isx012_get_ctrlval(uint16_t ctrl_class,
-                                FAR struct v4l2_ext_control *control);
-static int isx012_set_ctrlval(uint16_t ctrl_class,
-                                FAR struct v4l2_ext_control *control);
-static int isx012_refresh(void);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static isx012_dev_t   g_isx012_private;
-
-#ifndef ISX012_NOT_USE_NSTBY
-static const isx012_reg_t g_isx012_presleep[] =
-{
-  {PLL_CKSEL, 0x00, 0x01}, /* PLL_CKSEL */
-  {SRCCK_DIV, 0x00, 0x01}, /* SRCCK_DIV */
-  {INCK_SET,  0x17, 0x01}, /* INCK_SET */
-};
-#define ISX012_PRESLEEP_NENTRIES ARRAY_NENTRIES(g_isx012_presleep)
-#endif
-
-static const isx012_reg_t g_isx012_def_init[] =
-{
-#ifdef ISX012_NOT_USE_NSTBY
-  {PLL_CKSEL,         0x00, 0x01},
-  {SRCCK_DIV,         0x00, 0x01},
-#endif
-  {DRIVABILITY,       0xaa, 0x01},
-  {VIFCONFIG,       0x0200, 0x02},
-  {YUVCONFIG_TN,    0xff0a, 0x02},
-  {ILCODELEN,         0x00, 0x01},
-  {AFMODE_MONI,       0x01, 0x01},
-  {YUVCONFIG,       0xff6a, 0x02},
-  {VIF_REC601_Y,    0x10fe, 0x02},
-  {VIF_REC601_C,    0x10f0, 0x02},
-  {HSENS_MODE_SEL,    0x11, 0x01},
-  {VIF_CLKCONFIG1,    0x30, 0x01},
-  {VIF_CLKCONFIG2,    0x30, 0x01},
-  {VIF_CLKCONFIG3,    0x30, 0x01},
-  {VIF_CLKCONFIG4,    0x30, 0x01},
-  {VIF_CLKCONFIG5,    0x30, 0x01},
-  {VIF_CLKCONFIG6,    0x30, 0x01},
-  {VIF_CLKCONFIG7,    0x30, 0x01},
-  {VIF_CLKCONFIG8,    0x30, 0x01},
-  {VIF_CLKCONFIG9,    0x30, 0x01},
-  {VIF_CLKCONFIG10,   0x30, 0x01},
-  {VIF_CLKCONFIG11,   0x30, 0x01},
-  {VIF_CLKCONFIG12,   0x30, 0x01},
-  {VIF_CLKCONFIG13,   0x11, 0x01},
-  {VIF_CLKCONFIG14,   0x11, 0x01},
-  {VIF_CLKCONFIG15,   0x11, 0x01},
-  {VIF_CLKCONFIG16,   0x11, 0x01},
-#ifdef ISX012_NOT_USE_NSTBY
-  {INCK_SET,          0x17, 0x01}, /* INCK_SET */
-#endif
-  {FRM_FIX_SN1_2,     0xff, 0x01}, /* Fix framerate */
-  {FAST_MODECHG_EN,   0x01, 0x01},
-  {FAST_SHT_MODE_SEL, 0x01, 0x01},
-  {CAP_HALF_AE_CTRL,  0x07, 0x01}, /* HAFREL=HIGHSPEED, CAP=Auto  */
-  {HALF_AWB_CTRL,     0x01, 0x01},
-  {AESPEED_FAST,      0x0f, 0x01},
-  {FASTMOVE_TIMEOUT,  0x2d, 0x01},
-  {YGAMMA_MODE,       0x01, 0x01},
-  {INT_QLTY2,         0x50, 0x01},
-};
-#define ISX012_RESET_NENTRIES ARRAY_NENTRIES(g_isx012_def_init)
-
-static const uint8_t g_isx012_cxc_rgb_data[CXC_RGB_DATA_UNIT_NUM]
-                                          [CXC_RGB_DATA_UNIT_SIZE] =
-{
-  {0x01, 0x43, 0xc0, 0xf0, 0x4f, 0xfc, 0x13},  /* CXC_RGB_UNIT0  */
-  {0x80, 0x44, 0x20, 0x21, 0x48, 0x04, 0x0e},  /* CXC_RGB_UNIT1  */
-  {0x81, 0x43, 0xc0, 0x10, 0x30, 0xfc, 0x13},  /* CXC_RGB_UNIT2  */
-  {0xff, 0x04, 0x20, 0x11, 0x48, 0x08, 0x12},  /* CXC_RGB_UNIT3  */
-  {0x81, 0x43, 0xe0, 0x20, 0x48, 0x08, 0x12},  /* CXC_RGB_UNIT4  */
-  {0x80, 0x03, 0xe0, 0x00, 0x38, 0x04, 0x10},  /* CXC_RGB_UNIT5  */
-  {0x01, 0x84, 0x20, 0x21, 0x48, 0x04, 0x10},  /* CXC_RGB_UNIT6  */
-  {0x01, 0x04, 0xc0, 0x10, 0x20, 0x00, 0x08},  /* CXC_RGB_UNIT7  */
-  {0x81, 0x82, 0xc0, 0x20, 0x38, 0x08, 0x0e},  /* CXC_RGB_UNIT8  */
-  {0x01, 0x43, 0xc0, 0x10, 0x20, 0x04, 0x04},  /* CXC_RGB_UNIT9  */
-  {0x01, 0x41, 0x40, 0x10, 0x20, 0x08, 0x0a},  /* CXC_RGB_UNIT10 */
-  {0x82, 0x82, 0x80, 0x20, 0x20, 0x04, 0x04},  /* CXC_RGB_UNIT11 */
-  {0x82, 0x80, 0x20, 0x20, 0x08, 0x04, 0x06},  /* CXC_RGB_UNIT12 */
-  {0x81, 0x42, 0xa0, 0x10, 0x20, 0x04, 0x08},  /* CXC_RGB_UNIT13 */
-  {0x81, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00},  /* CXC_RGB_UNIT14 */
-  {0x01, 0x41, 0x80, 0x10, 0x20, 0x00, 0x08},  /* CXC_RGB_UNIT15 */
-  {0x00, 0x42, 0x20, 0x20, 0x08, 0x08, 0x00},  /* CXC_RGB_UNIT16 */
-  {0x82, 0xc0, 0x40, 0x20, 0x20, 0x08, 0x08},  /* CXC_RGB_UNIT17 */
-  {0x80, 0x02, 0xa0, 0x10, 0x20, 0x08, 0x04},  /* CXC_RGB_UNIT18 */
-  {0x02, 0x81, 0x60, 0x30, 0x20, 0x08, 0x0a},  /* CXC_RGB_UNIT19 */
-  {0x82, 0x42, 0xc0, 0x10, 0x30, 0x04, 0x0a},  /* CXC_RGB_UNIT20 */
-  {0x03, 0xc3, 0xa0, 0x40, 0x28, 0x0c, 0x0a},  /* CXC_RGB_UNIT21 */
-  {0x03, 0xc3, 0xc0, 0x20, 0x20, 0x08, 0x08},  /* CXC_RGB_UNIT22 */
-  {0x82, 0xc2, 0xc0, 0x30, 0x40, 0x10, 0x0e},  /* CXC_RGB_UNIT23 */
-  {0x84, 0x03, 0xa1, 0x40, 0x28, 0x08, 0x08},  /* CXC_RGB_UNIT24 */
-  {0x02, 0x82, 0xa0, 0x30, 0x30, 0x0c, 0x10},  /* CXC_RGB_UNIT25 */
-  {0x84, 0x03, 0xe1, 0x40, 0x28, 0x10, 0x0a},  /* CXC_RGB_UNIT26 */
-};
-
-static const uint8_t g_isx012_cxc_grb_data[CXC_GRB_DATA_UNIT_NUM]
-                                          [CXC_GRB_DATA_UNIT_SIZE] =
-{
-  {0x00, 0x3d, 0x40, 0x0f, 0xc0, 0x03, 0xf2},  /* CXC_GRB_UNIT0  */
-  {0x80, 0x7c, 0x80, 0x1f, 0xd8, 0x03, 0xf0},  /* CXC_GRB_UNIT1  */
-  {0x00, 0x3c, 0x40, 0x0f, 0xd0, 0x03, 0xf0},  /* CXC_GRB_UNIT2  */
-  {0x80, 0x3c, 0x20, 0x1f, 0xe0, 0x07, 0xf6},  /* CXC_GRB_UNIT3  */
-  {0x00, 0x3c, 0x00, 0x1f, 0xd0, 0x07, 0xf4},  /* CXC_GRB_UNIT4  */
-  {0x00, 0x3d, 0x40, 0x0f, 0xc8, 0x03, 0xf2},  /* CXC_GRB_UNIT5  */
-  {0x80, 0xfc, 0x5f, 0xff, 0xd7, 0x07, 0xf4},  /* CXC_GRB_UNIT6  */
-  {0x01, 0x7d, 0x40, 0x0f, 0xd0, 0xff, 0xf3},  /* CXC_GRB_UNIT7  */
-  {0x7f, 0xfd, 0x3f, 0x0f, 0xc8, 0x03, 0xf2},  /* CXC_GRB_UNIT8  */
-  {0x81, 0x7c, 0x20, 0x0f, 0xd0, 0xff, 0xf7},  /* CXC_GRB_UNIT9  */
-  {0x7e, 0xfe, 0x5f, 0x0f, 0xd8, 0x03, 0xf6},  /* CXC_GRB_UNIT10 */
-  {0x80, 0xbd, 0xa0, 0x2f, 0xe8, 0x07, 0xfa},  /* CXC_GRB_UNIT11 */
-  {0x80, 0xfe, 0xbf, 0x0f, 0xe8, 0xff, 0xf9},  /* CXC_GRB_UNIT12 */
-  {0x00, 0x3e, 0x80, 0x3f, 0xe8, 0x0f, 0xfa},  /* CXC_GRB_UNIT13 */
-  {0x02, 0x40, 0xe0, 0x0f, 0xf8, 0x03, 0xfe},  /* CXC_GRB_UNIT14 */
-  {0x80, 0x7f, 0xe0, 0x1f, 0xf8, 0x17, 0xfe},  /* CXC_GRB_UNIT15 */
-  {0x85, 0xff, 0xe0, 0x2f, 0x08, 0x04, 0x04},  /* CXC_GRB_UNIT16 */
-  {0x81, 0x40, 0x20, 0x20, 0x00, 0x08, 0x00},  /* CXC_GRB_UNIT17 */
-  {0x84, 0x00, 0x21, 0x30, 0x10, 0x0c, 0x06},  /* CXC_GRB_UNIT18 */
-  {0x02, 0x82, 0x40, 0x20, 0x10, 0x0c, 0x02},  /* CXC_GRB_UNIT19 */
-  {0x83, 0x00, 0x21, 0x40, 0x08, 0x10, 0x06},  /* CXC_GRB_UNIT20 */
-  {0x83, 0x82, 0xa0, 0x20, 0x20, 0x08, 0x08},  /* CXC_GRB_UNIT21 */
-  {0x02, 0x81, 0x40, 0x30, 0x18, 0x0c, 0x06},  /* CXC_GRB_UNIT22 */
-  {0x03, 0x81, 0x80, 0x10, 0x20, 0x04, 0x08},  /* CXC_GRB_UNIT23 */
-  {0x82, 0x82, 0x80, 0x20, 0x20, 0x0c, 0x06},  /* CXC_GRB_UNIT24 */
-  {0x83, 0xc1, 0x40, 0x20, 0x20, 0x04, 0x08},  /* CXC_GRB_UNIT25 */
-  {0x01, 0x82, 0xa0, 0x20, 0x20, 0x08, 0x08},  /* CXC_GRB_UNIT26 */
-};
-
-static const uint8_t g_isx012_shd_rgb_data[SHD_RGB_DATA_UNIT_NUM]
-                                          [SHD_RGB_DATA_UNIT_SIZE] =
-{
-  {0xf1, 0x59, 0x52, 0x7b, 0x98, 0xc4, 0x9d, 0x23, 0x29, 0x87, 0x46}, /* SHD_RGB_UNIT0  */
-  {0xc6, 0x81, 0xd1, 0x70, 0x56, 0xe4, 0x9c, 0x1b, 0x6d, 0x07, 0x48}, /* SHD_RGB_UNIT1  */
-  {0xdd, 0xf1, 0x51, 0x7d, 0xa8, 0xb4, 0x1e, 0x25, 0x49, 0xc7, 0x46}, /* SHD_RGB_UNIT2  */
-  {0xbd, 0xf1, 0x50, 0x6d, 0x2a, 0x44, 0x1b, 0x0a, 0x01, 0x87, 0x44}, /* SHD_RGB_UNIT3  */
-  {0xd0, 0xa9, 0x51, 0x77, 0x84, 0xd4, 0x9d, 0x1f, 0x2d, 0xc7, 0x44}, /* SHD_RGB_UNIT4  */
-  {0xa8, 0xa9, 0xcf, 0x62, 0x98, 0xa3, 0x17, 0xdb, 0xfc, 0x05, 0x38}, /* SHD_RGB_UNIT5  */
-  {0x90, 0xe1, 0x8e, 0x6a, 0x08, 0xc4, 0x9b, 0x0e, 0x11, 0x07, 0x43}, /* SHD_RGB_UNIT6  */
-  {0xac, 0xa9, 0x4f, 0x5d, 0x4e, 0x13, 0x15, 0xb9, 0xf8, 0x44, 0x2b}, /* SHD_RGB_UNIT7  */
-  {0x44, 0x21, 0xcb, 0x56, 0x0e, 0x63, 0x98, 0xe3, 0x78, 0x86, 0x3d}, /* SHD_RGB_UNIT8  */
-  {0xab, 0x81, 0x4f, 0x62, 0x7c, 0xc3, 0x94, 0xb4, 0x98, 0x84, 0x26}, /* SHD_RGB_UNIT9  */
-  {0x14, 0xe9, 0x48, 0x46, 0x4a, 0x12, 0x93, 0xa4, 0x84, 0xc5, 0x31}, /* SHD_RGB_UNIT10 */
-  {0x81, 0xe9, 0x4d, 0x67, 0xac, 0x73, 0x17, 0xd0, 0xdc, 0x24, 0x29}, /* SHD_RGB_UNIT11 */
-  {0x12, 0xb9, 0x08, 0x40, 0x02, 0x52, 0x10, 0x84, 0x6c, 0x64, 0x25}, /* SHD_RGB_UNIT12 */
-  {0x4c, 0x91, 0xcb, 0x5b, 0x4c, 0xe3, 0x19, 0xec, 0xdc, 0x05, 0x34}, /* SHD_RGB_UNIT13 */
-  {0x37, 0x39, 0x8a, 0x44, 0x2a, 0x02, 0x10, 0x80, 0x14, 0xe4, 0x20}, /* SHD_RGB_UNIT14 */
-  {0x1c, 0x51, 0x49, 0x53, 0xe4, 0x02, 0x17, 0xd3, 0xb8, 0xe6, 0x3d}, /* SHD_RGB_UNIT15 */
-  {0x8b, 0xd9, 0x8d, 0x53, 0xc8, 0x72, 0x12, 0x98, 0x50, 0x24, 0x23}, /* SHD_RGB_UNIT16 */
-  {0x19, 0x11, 0x89, 0x4c, 0x8c, 0x32, 0x16, 0xc7, 0x14, 0x06, 0x38}, /* SHD_RGB_UNIT17 */
-  {0xca, 0xc1, 0x10, 0x6c, 0xe0, 0x83, 0x97, 0xd0, 0x4c, 0xa5, 0x2d}, /* SHD_RGB_UNIT18 */
-  {0x3e, 0x99, 0x0a, 0x51, 0xbc, 0xc2, 0x15, 0xc2, 0x28, 0x26, 0x39}, /* SHD_RGB_UNIT19 */
-  {0xa5, 0x89, 0x0f, 0x7b, 0x8c, 0x64, 0x9d, 0x14, 0xb9, 0x46, 0x3e}, /* SHD_RGB_UNIT20 */
-  {0x8f, 0x41, 0xce, 0x5e, 0x5e, 0x03, 0x98, 0xdc, 0x50, 0xe6, 0x3a}, /* SHD_RGB_UNIT21 */
-  {0xb4, 0x49, 0x90, 0x72, 0x50, 0x74, 0xa1, 0x3a, 0x05, 0x88, 0x4b}, /* SHD_RGB_UNIT22 */
-  {0xe1, 0xd1, 0x91, 0x71, 0x38, 0xc4, 0x1b, 0x0a, 0xed, 0x86, 0x42}, /* SHD_RGB_UNIT23 */
-  {0xcb, 0x49, 0xd1, 0x78, 0x86, 0x74, 0x9f, 0x2d, 0xb9, 0x88, 0x51}, /* SHD_RGB_UNIT24 */
-  {0x11, 0x62, 0x93, 0x7c, 0x9c, 0x94, 0x1d, 0x1b, 0x41, 0x67, 0x46}, /* SHD_RGB_UNIT25 */
-  {0xcf, 0x81, 0x91, 0x77, 0x82, 0x54, 0x9f, 0x2a, 0x21, 0xa8, 0x4d}, /* SHD_RGB_UNIT26 */
-};
-
-static const uint8_t g_isx012_shd_grb_data[SHD_GRB_DATA_UNIT_NUM]
-                                          [SHD_GRB_DATA_UNIT_SIZE] =
-{
-  {0xe8, 0xa9, 0x0f, 0x78, 0xe4, 0x13, 0x9d, 0xf0, 0x04, 0xe7, 0x39}, /* SHD_GRB_UNIT0  */
-  {0xbd, 0x51, 0x0e, 0x6f, 0x94, 0x63, 0x1c, 0xea, 0x4c, 0x27, 0x3c}, /* SHD_GRB_UNIT1  */
-  {0xd7, 0x19, 0x4f, 0x7a, 0xf4, 0xd3, 0x1d, 0xf7, 0x20, 0xe7, 0x3a}, /* SHD_GRB_UNIT2  */
-  {0xb6, 0x11, 0x0e, 0x6c, 0x76, 0x03, 0x9b, 0xdd, 0xf0, 0x06, 0x39}, /* SHD_GRB_UNIT3  */
-  {0xc9, 0xc1, 0x8e, 0x75, 0xc8, 0xe3, 0x9c, 0xef, 0xf8, 0xa6, 0x39}, /* SHD_GRB_UNIT4  */
-  {0xa0, 0x69, 0x0d, 0x62, 0x20, 0x93, 0x97, 0xbf, 0xf4, 0xa5, 0x30}, /* SHD_GRB_UNIT5  */
-  {0x8c, 0xb1, 0x8c, 0x68, 0x60, 0x13, 0x9b, 0xe0, 0xcc, 0xa6, 0x38}, /* SHD_GRB_UNIT6  */
-  {0x9f, 0x71, 0x0d, 0x5c, 0xf4, 0x12, 0x15, 0xab, 0x00, 0x65, 0x28}, /* SHD_GRB_UNIT7  */
-  {0x44, 0x41, 0x0a, 0x56, 0xbc, 0x02, 0x98, 0xc4, 0x50, 0x26, 0x34}, /* SHD_GRB_UNIT8  */
-  {0x9a, 0x59, 0x4d, 0x5f, 0x16, 0x83, 0x14, 0xa8, 0x9c, 0x64, 0x25}, /* SHD_GRB_UNIT9  */
-  {0x15, 0xc1, 0xc8, 0x46, 0x38, 0x22, 0x13, 0x9a, 0x74, 0x65, 0x2c}, /* SHD_GRB_UNIT10 */
-  {0x78, 0x11, 0x4c, 0x63, 0x36, 0xb3, 0x96, 0xbb, 0xcc, 0x44, 0x27}, /* SHD_GRB_UNIT11 */
-  {0x11, 0xa1, 0x48, 0x40, 0x04, 0x72, 0x10, 0x83, 0x70, 0x84, 0x23}, /* SHD_GRB_UNIT12 */
-  {0x4a, 0x69, 0xca, 0x59, 0xe0, 0xf2, 0x98, 0xcc, 0xb0, 0xa5, 0x2e}, /* SHD_GRB_UNIT13 */
-  {0x33, 0xc1, 0x09, 0x44, 0x24, 0x02, 0x10, 0x80, 0x14, 0x84, 0x20}, /* SHD_GRB_UNIT14 */
-  {0x1b, 0xd1, 0x48, 0x52, 0x98, 0x72, 0x96, 0xb7, 0x8c, 0x06, 0x35}, /* SHD_GRB_UNIT15 */
-  {0x81, 0x39, 0xcc, 0x51, 0x96, 0x32, 0x92, 0x92, 0x48, 0x44, 0x22}, /* SHD_GRB_UNIT16 */
-  {0x17, 0xb9, 0x48, 0x4b, 0x5e, 0xa2, 0x15, 0xb0, 0xd8, 0x45, 0x30}, /* SHD_GRB_UNIT17 */
-  {0xc0, 0x19, 0xce, 0x69, 0x56, 0x23, 0x97, 0xba, 0x38, 0x05, 0x2a}, /* SHD_GRB_UNIT18 */
-  {0x3b, 0xe1, 0x09, 0x50, 0x82, 0x42, 0x95, 0xac, 0xf8, 0x05, 0x31}, /* SHD_GRB_UNIT19 */
-  {0x94, 0x19, 0x4d, 0x78, 0xca, 0xe3, 0x9c, 0xe8, 0xa8, 0xa6, 0x35}, /* SHD_GRB_UNIT20 */
-  {0x8b, 0x71, 0xcc, 0x5d, 0xf8, 0xa2, 0x97, 0xc0, 0x24, 0xa6, 0x32}, /* SHD_GRB_UNIT21 */
-  {0xa4, 0xb1, 0x8d, 0x6d, 0x96, 0xd3, 0xa0, 0x09, 0xe1, 0xa7, 0x3f}, /* SHD_GRB_UNIT22 */
-  {0xde, 0x09, 0xcf, 0x70, 0x92, 0x73, 0x9b, 0xe0, 0xcc, 0x06, 0x38}, /* SHD_GRB_UNIT23 */
-  {0xc0, 0x89, 0x4e, 0x74, 0xcc, 0x13, 0x1e, 0xfc, 0x84, 0x48, 0x45}, /* SHD_GRB_UNIT24 */
-  {0x06, 0x7a, 0xd0, 0x7a, 0xe6, 0x33, 0x1d, 0xef, 0x24, 0x07, 0x3b}, /* SHD_GRB_UNIT25 */
-  {0xc4, 0xb1, 0x0e, 0x74, 0xca, 0x33, 0x1e, 0xfc, 0xc4, 0x07, 0x41}, /* SHD_GRB_UNIT26 */
-};
-
-static const uint8_t g_isx012_shd_r1_data[SHD_R1_DATA_UNIT_NUM]
-                                         [SHD_R1_DATA_UNIT_SIZE] =
-{
-  {0x10, 0x92, 0x10, 0x82, 0xf8, 0x43, 0x1f, 0xfb, 0xf0, 0xe7, 0x40}, /* SHD_R1_UNIT0   */
-  {0x07, 0x92, 0xd0, 0x82, 0xec, 0x33, 0x9e, 0xed, 0x68, 0xe7, 0x3c}, /* SHD_R1_UNIT1   */
-  {0xfa, 0x21, 0xd0, 0x7e, 0xce, 0xa3, 0x1b, 0xcd, 0x20, 0xe6, 0x31}, /* SHD_R1_UNIT2   */
-  {0xa6, 0x69, 0xce, 0x78, 0xbc, 0xa3, 0x1b, 0xbe, 0x44, 0x25, 0x28}, /* SHD_R1_UNIT3   */
-  {0x45, 0x19, 0xcb, 0x65, 0x78, 0xe3, 0x1b, 0xc8, 0x3c, 0xa5, 0x24}, /* SHD_R1_UNIT4   */
-  {0x15, 0xc1, 0x48, 0x4d, 0xd6, 0x72, 0x99, 0xd3, 0xdc, 0x25, 0x27}, /* SHD_R1_UNIT5   */
-  {0x11, 0x01, 0x08, 0x41, 0x42, 0x42, 0x15, 0xc1, 0xa4, 0x06, 0x2f}, /* SHD_R1_UNIT6   */
-  {0x39, 0x89, 0x08, 0x40, 0x0a, 0x22, 0x12, 0xab, 0x0c, 0x26, 0x38}, /* SHD_R1_UNIT7   */
-  {0x91, 0x71, 0x4a, 0x49, 0x2c, 0xa2, 0x11, 0x9c, 0xc4, 0xa5, 0x33}, /* SHD_R1_UNIT8   */
-  {0xe2, 0xe1, 0x4d, 0x5f, 0xa4, 0x22, 0x94, 0xa3, 0xa0, 0x05, 0x34}, /* SHD_R1_UNIT9   */
-  {0xc7, 0x41, 0x50, 0x7c, 0x7e, 0xd3, 0x19, 0xc5, 0x48, 0x86, 0x35}, /* SHD_R1_UNIT10  */
-  {0xda, 0xa9, 0xcf, 0x8c, 0x42, 0x24, 0x20, 0xf5, 0x8c, 0x67, 0x3c}, /* SHD_R1_UNIT11  */
-  {0xf6, 0x89, 0xd0, 0x88, 0x90, 0x34, 0x23, 0x0b, 0x15, 0xa8, 0x3f}, /* SHD_R1_UNIT12  */
-  {0x00, 0x72, 0x10, 0x89, 0x68, 0x04, 0x69, 0x00, 0x00, 0x19, 0x26}, /* SHD_R1_UNIT13  */
-};
-
-static const uint8_t g_isx012_shd_r2_data[SHD_R2_DATA_UNIT_NUM]
-                                         [SHD_R2_DATA_UNIT_SIZE] =
-{
-  {0x3a, 0xe2, 0x11, 0x8c, 0x42, 0x74, 0xa1, 0x0c, 0x89, 0x08, 0x46}, /* SHD_R2_UNIT0   */
-  {0x30, 0xe2, 0xd1, 0x8c, 0x36, 0x54, 0x20, 0xfe, 0xec, 0x47, 0x41}, /* SHD_R2_UNIT1   */
-  {0x20, 0x5a, 0x91, 0x88, 0x16, 0x94, 0x1d, 0xda, 0x80, 0x26, 0x35}, /* SHD_R2_UNIT2   */
-  {0xc2, 0x69, 0x0f, 0x81, 0x00, 0x94, 0x9d, 0xc9, 0x84, 0xe5, 0x29}, /* SHD_R2_UNIT3   */
-  {0x54, 0xb1, 0x0b, 0x6c, 0xb2, 0xb3, 0x9d, 0xd4, 0x74, 0x85, 0x25}, /* SHD_R2_UNIT4   */
-  {0x1a, 0xf1, 0x08, 0x50, 0xfc, 0xe2, 0x1a, 0xe0, 0x2c, 0x66, 0x28}, /* SHD_R2_UNIT5   */
-  {0x14, 0x01, 0x88, 0x41, 0x4e, 0x32, 0x16, 0xcb, 0x08, 0x87, 0x31}, /* SHD_R2_UNIT6   */
-  {0x42, 0x99, 0x08, 0x40, 0x0c, 0x72, 0x92, 0xb1, 0x58, 0x86, 0x3b}, /* SHD_R2_UNIT7   */
-  {0xa8, 0xd9, 0xca, 0x4a, 0x32, 0xe2, 0x91, 0xa0, 0x04, 0x66, 0x36}, /* SHD_R2_UNIT8   */
-  {0x02, 0xc2, 0x4e, 0x64, 0xbe, 0xd2, 0x94, 0xa9, 0xe0, 0xc5, 0x36}, /* SHD_R2_UNIT9   */
-  {0xe1, 0x61, 0x91, 0x84, 0xb6, 0x43, 0x9b, 0xcf, 0x9c, 0x66, 0x38}, /* SHD_R2_UNIT10  */
-  {0xf6, 0xa1, 0x50, 0x97, 0x8e, 0x34, 0x22, 0x04, 0x01, 0x08, 0x40}, /* SHD_R2_UNIT11  */
-  {0x15, 0x9a, 0x51, 0x92, 0xf2, 0xd4, 0xa5, 0x1d, 0x99, 0xa8, 0x43}, /* SHD_R2_UNIT12  */
-  {0x21, 0x82, 0x91, 0x92, 0xbe, 0xf4, 0x9e, 0xf3, 0x4c, 0x87, 0x38}, /* SHD_R2_UNIT13  */
-};
-
-static const uint8_t g_isx012_shd_b2_data[SHD_B2_DATA_UNIT_NUM]
-                                         [SHD_B2_DATA_UNIT_SIZE] =
-{
-  {0xef, 0x39, 0xcf, 0x74, 0x88, 0xb3, 0x1b, 0xdf, 0x20, 0x47, 0x3b}, /* SHD_B2_UNIT0   */
-  {0xdf, 0x59, 0xcf, 0x77, 0x8c, 0x43, 0x1b, 0xd7, 0xb8, 0x46, 0x37}, /* SHD_B2_UNIT1   */
-  {0xcc, 0xc1, 0x0e, 0x73, 0x78, 0xa3, 0x99, 0xc1, 0xd0, 0x25, 0x2f}, /* SHD_B2_UNIT2   */
-  {0x87, 0x09, 0x0d, 0x6c, 0x64, 0x93, 0x99, 0xb6, 0x30, 0xc5, 0x27}, /* SHD_B2_UNIT3   */
-  {0x3f, 0xb1, 0x0a, 0x5f, 0x2a, 0x93, 0x99, 0xbc, 0x1c, 0x85, 0x24}, /* SHD_B2_UNIT4   */
-  {0x16, 0xc9, 0x48, 0x4c, 0xb6, 0x92, 0x17, 0xc4, 0x94, 0x85, 0x26}, /* SHD_B2_UNIT5   */
-  {0x10, 0x09, 0x88, 0x41, 0x3a, 0x52, 0x94, 0xb2, 0x2c, 0xc6, 0x2c}, /* SHD_B2_UNIT6   */
-  {0x33, 0x79, 0x08, 0x40, 0x08, 0xc2, 0x11, 0xa2, 0x94, 0x65, 0x34}, /* SHD_B2_UNIT7   */
-  {0x7e, 0x39, 0x4a, 0x48, 0x26, 0x52, 0x91, 0x96, 0x64, 0x05, 0x2f}, /* SHD_B2_UNIT8   */
-  {0xbf, 0x09, 0x8d, 0x5b, 0x92, 0xa2, 0x93, 0x9d, 0x4c, 0x65, 0x2f}, /* SHD_B2_UNIT9   */
-  {0x95, 0xf9, 0x0e, 0x73, 0x48, 0x63, 0x98, 0xb9, 0xd8, 0xa5, 0x30}, /* SHD_B2_UNIT10  */
-  {0xa5, 0xb1, 0x8d, 0x83, 0xf4, 0xa3, 0x1d, 0xe0, 0xd0, 0x06, 0x36}, /* SHD_B2_UNIT11  */
-  {0xbe, 0xa9, 0x4e, 0x79, 0x50, 0xd4, 0x20, 0xf6, 0x54, 0xa7, 0x38}, /* SHD_B2_UNIT12  */
-  {0xc5, 0x91, 0xce, 0x7a, 0xf4, 0x03, 0x44, 0x00, 0x60, 0x60, 0x00}, /* SHD_B2_UNIT13  */
-};
-
-static const isx012_reg_t g_isx012_shd_thresholds[] =
-{
-  {SHD_INP_TH_HB_H_R2, 0x1478, 2},
-  {SHD_INP_TH_HB_L_R2, 0x1380, 2},
-  {SHD_INP_TH_LB_H_R2, 0x10cc, 2},
-  {SHD_INP_TH_LB_L_R2, 0x1004, 2},
-  {SHD_INP_TH_HB_H_RB, 0x10cc, 2},
-  {SHD_INP_TH_HB_L_RB, 0x1004, 2},
-  {SHD_INP_TH_LB_H_RB, 0x0000, 2},
-  {SHD_INP_TH_LB_L_RB, 0x0000, 2},
-};
-
-#define ISX012_SHD_THRESHOLDS_NENTRIES ARRAY_NENTRIES(g_isx012_shd_thresholds)
-
-static const isx012_reg_t g_isx012_shd_wb[] =
-{
-  {NORMR,              0x1101, 2},
-  {NORMB,              0x0f7b, 2},
-  {AWBPRER,            0x0147, 2},
-  {AWBPREB,            0x022a, 2},
-  {SHD_PRER_OFFSET_R2, 0x001b, 2},
-  {SHD_PRER_OFFSET_RB, 0x000b, 2},
-  {SHD_PREB_OFFSET_RB, 0x0003, 2},
-};
-
-#define ISX012_SHD_WB_NENTRIES ARRAY_NENTRIES(g_isx012_shd_wb)
-
-static isx012_conv_v4l2_to_regval_t
-  g_isx012_supported_colorfx[ISX012_MAX_COLOREFFECT + 1] =
-{
-  {V4L2_COLORFX_NONE,         REGVAL_EFFECT_NONE},
-  {V4L2_COLORFX_BW,           REGVAL_EFFECT_MONOTONE},
-  {V4L2_COLORFX_SEPIA,        REGVAL_EFFECT_SEPIA},
-  {V4L2_COLORFX_NEGATIVE,     REGVAL_EFFECT_NEGPOS},
-  {V4L2_COLORFX_SKETCH,       REGVAL_EFFECT_SKETCH},
-  {V4L2_COLORFX_SOLARIZATION, REGVAL_EFFECT_SOLARIZATION},
-  {V4L2_COLORFX_PASTEL,       REGVAL_EFFECT_PASTEL},
-};
-
-static isx012_conv_v4l2_to_regval_t
-  g_isx012_supported_presetwb[ISX012_MAX_PRESETWB + 1] =
-{
-  {V4L2_WHITE_BALANCE_AUTO,         REGVAL_AWB_ATM},
-  {V4L2_WHITE_BALANCE_INCANDESCENT, REGVAL_AWB_LIGHTBULB},
-  {V4L2_WHITE_BALANCE_FLUORESCENT,  REGVAL_AWB_FLUORESCENTLIGHT},
-  {V4L2_WHITE_BALANCE_DAYLIGHT,     REGVAL_AWB_CLEARWEATHER},
-  {V4L2_WHITE_BALANCE_CLOUDY,       REGVAL_AWB_CLOUDYWEATHER},
-  {V4L2_WHITE_BALANCE_SHADE,        REGVAL_AWB_SHADE},
-};
-
-static isx012_conv_v4l2_to_regval_t
-  g_isx012_supported_photometry[ISX012_MAX_PHOTOMETRY + 1] =
-{
-  {V4L2_EXPOSURE_METERING_AVERAGE,         REGVAL_PHOTOMETRY_AVERAGE},
-  {V4L2_EXPOSURE_METERING_CENTER_WEIGHTED, REGVAL_PHOTOMETRY_CENTERWEIGHT},
-  {V4L2_EXPOSURE_METERING_SPOT,            REGVAL_PHOTOMETRY_SPOT},
-  {V4L2_EXPOSURE_METERING_MATRIX,          REGVAL_PHOTOMETRY_MULTIPATTERN},
-};
-
-static isx012_conv_v4l2_to_regval_t
-  g_isx012_supported_iso[ISX012_MAX_ISO + 1] =
-{
-  {25 * 1000,   REGVAL_ISO_25},
-  {32 * 1000,   REGVAL_ISO_32},
-  {40 * 1000,   REGVAL_ISO_40},
-  {50 * 1000,   REGVAL_ISO_50},
-  {64 * 1000,   REGVAL_ISO_64},
-  {80 * 1000,   REGVAL_ISO_80},
-  {100 * 1000,  REGVAL_ISO_100},
-  {125 * 1000,  REGVAL_ISO_125},
-  {160 * 1000,  REGVAL_ISO_160},
-  {200 * 1000,  REGVAL_ISO_200},
-  {250 * 1000,  REGVAL_ISO_250},
-  {320 * 1000,  REGVAL_ISO_320},
-  {400 * 1000,  REGVAL_ISO_400},
-  {500 * 1000,  REGVAL_ISO_500},
-  {640 * 1000,  REGVAL_ISO_640},
-  {800 * 1000,  REGVAL_ISO_800},
-  {1000 * 1000, REGVAL_ISO_1000},
-  {1250 * 1000, REGVAL_ISO_1250},
-  {1600 * 1000, REGVAL_ISO_1600},
-};
-
-static struct video_devops_s g_isx012_video_devops =
-{
-  .open                       = isx012_open,
-  .close                      = isx012_close,
-  .do_halfpush                = isx012_do_halfpush,
-  .set_buftype                = isx012_set_buftype,
-  .set_buf                    = isx012_set_buf,
-  .cancel_dma                 = isx012_cancel_dma,
-  .get_range_of_fmt           = isx012_get_range_of_fmt,
-  .get_range_of_framesize     = isx012_get_range_of_framesize,
-  .try_format                 = isx012_try_format,
-  .set_format                 = isx012_set_format,
-  .get_range_of_frameinterval = isx012_get_range_of_frameinterval,
-  .set_frameinterval          = isx012_set_frameinterval,
-  .get_range_of_ctrlvalue     = isx012_get_range_of_ctrlval,
-  .get_menu_of_ctrlvalue      = isx012_get_menu_of_ctrlval,
-  .get_ctrlvalue              = isx012_get_ctrlval,
-  .set_ctrlvalue              = isx012_set_ctrlval,
-  .refresh                    = isx012_refresh,
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static uint16_t isx012_getreg(isx012_dev_t *priv,
-                              uint16_t regaddr, uint16_t regsize)
-{
-  struct i2c_config_s config;
-  volatile uint16_t regval = 0;
-  volatile uint8_t buffer[2];
-  int ret;
-
-  /* Set up the I2C configuration */
-
-  config.frequency = priv->i2c_freq;
-  config.address   = priv->i2c_addr;
-  config.addrlen   = 7;
-  buffer[0] = regaddr >> 8;
-  buffer[1] = regaddr & 0xff;
-
-  /* Write the register address */
-
-  ret = i2c_write(priv->i2c, &config, (uint8_t *)buffer, 2);
-  if (ret < 0)
-    {
-      imagererr("i2c_write failed: %d\n", ret);
-      return 0;
-    }
-
-  /* Restart and read 16bits from the register */
-
-  ret = i2c_read(priv->i2c, &config, (uint8_t *)buffer, regsize);
-  if (ret < 0)
-    {
-      imagererr("i2c_read failed: %d\n", ret);
-      return 0;
-    }
-
-  memcpy((uint8_t *)&regval, (uint8_t *)buffer, regsize);
-
-  return regval;
-}
-
-static int isx012_putreg(isx012_dev_t *priv,
-                         uint16_t regaddr, uint16_t regval, uint16_t regsize)
-{
-  struct i2c_config_s config;
-  volatile uint8_t buffer[4];
-  int ret;
-
-  /* Set up the I2C configuration */
-
-  config.frequency = priv->i2c_freq;
-  config.address   = priv->i2c_addr;
-  config.addrlen   = 7;
-
-  /* Set up for the transfer */
-
-  buffer[0] = regaddr >> 8;   /* RegAddr Hi */
-  buffer[1] = regaddr & 0xff; /* RegAddr Low */
-
-  memcpy((uint8_t *)&buffer[2], (uint8_t *)&regval, regsize);
-
-  /* And do it */
-
-  ret = i2c_write(priv->i2c, &config,
-                 (uint8_t *)buffer, regsize + 2);
-  if (ret < 0)
-    {
-      imagererr("i2c_write failed: %d\n", ret);
-    }
-
-  return ret;
-}
-
-static int isx012_putreglist(isx012_dev_t *priv,
-                             FAR const isx012_reg_t *reglist,
-                             size_t nentries)
-{
-  FAR const isx012_reg_t *entry;
-  int ret = OK;
-
-  for (entry = reglist; nentries > 0; nentries--, entry++)
-    {
-      ret = isx012_putreg(priv, entry->regaddr,
-                          entry->regval, entry->regsize);
-      if (ret < 0)
-        {
-          imagererr("isx012_putreg failed: %d\n", ret);
-          return ret;
-        }
-    }
-
-  return ret;
-}
-
-static int isx012_chk_int_state(isx012_dev_t *priv,
-                                uint8_t sts, uint32_t delay_time,
-                                uint32_t wait_time, uint32_t timeout)
-{
-  int ret = 0;
-  volatile uint8_t data;
-  uint32_t time = 0;
-
-  nxsig_usleep(delay_time * 1000);
-  while (time < timeout)
-    {
-      data = isx012_getreg(priv, INTSTS0, sizeof(data));
-      data = data & sts;
-      if (data != 0)
-        {
-          ret = isx012_putreg(priv, INTCLR0, data, sizeof(data));
-          return ret;
-        }
-
-      nxsig_usleep(wait_time * 1000);
-      time += wait_time;
-    }
-
-  return ERROR;
-}
-
-static int isx012_replace_fmt_v4l2val_to_regval(uint32_t v4l2val,
-                                                uint8_t *regval)
-{
-  if (regval == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (v4l2val)
-    {
-      case V4L2_PIX_FMT_UYVY:
-        *regval = REGVAL_OUTFMT_YUV;
-        break;
-
-      case V4L2_PIX_FMT_JPEG:
-        *regval = REGVAL_OUTFMT_JPEG;
-        break;
-
-      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:
-        *regval = REGVAL_OUTFMT_INTERLEAVE;
-        break;
-
-      default:  /* Unsupported format */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static bool is_movie_needed(isx012_modeparam_t *param)
-{
-  bool need = true;
-
-  if (param->format == V4L2_PIX_FMT_UYVY)
-    {
-      if (param->fps >= REGVAL_FPSTYPE_30FPS)   /* This means fps <= 30 */
-        {
-          need = false;
-        }
-    }
-
-  return need;
-}
-
-static int isx012_set_mode_param(isx012_dev_t *priv,
-                                 enum v4l2_buf_type type,
-                                 isx012_modeparam_t *param)
-{
-  int ret = 0;
-  uint8_t format;
-  uint16_t fps_regaddr;
-  uint16_t fmt_regaddr;
-  uint16_t sensmode_regaddr;
-  uint16_t hsize_regaddr;
-  uint16_t vsize_regaddr;
-  uint8_t  sensmode;
-
-  /* Get register address for type  */
-
-  if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-    {
-      if (is_movie_needed(param))
-        {
-          if (priv->mode == REGVAL_MODESEL_HREL)
-            {
-              /* In Half release state,
-               * the setting which need movie mode is prohibited.
-               */
-
-              return -EPERM;
-            }
-
-          fps_regaddr      = FPSTYPE_MOVIE;
-          fmt_regaddr      = OUTFMT_MOVIE;
-          sensmode_regaddr = SENSMODE_MOVIE;
-          hsize_regaddr    = HSIZE_MOVIE;
-          vsize_regaddr    = VSIZE_MOVIE;
-        }
-      else
-        {
-          fps_regaddr      = FPSTYPE_MONI;
-          fmt_regaddr      = OUTFMT_MONI;
-          sensmode_regaddr = SENSMODE_MONI;
-          hsize_regaddr    = HSIZE_MONI;
-          vsize_regaddr    = VSIZE_MONI;
-        }
-    }
-  else
-    {
-      fps_regaddr      = FPSTYPE_CAP;
-      fmt_regaddr      = OUTFMT_CAP;
-      sensmode_regaddr = SENSMODE_CAP;
-      hsize_regaddr    = HSIZE_CAP;
-      vsize_regaddr    = VSIZE_CAP;
-    }
-
-  ret = isx012_putreg(priv, fps_regaddr,  param->fps, sizeof(uint8_t));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = isx012_replace_fmt_v4l2val_to_regval(param->format, &format);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = isx012_putreg(priv, fmt_regaddr,   format, sizeof(uint8_t));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  switch (param->fps)
-    {
-      case REGVAL_FPSTYPE_120FPS:
-        sensmode = REGVAL_SENSMODE_1_8;
-        break;
-
-      case REGVAL_FPSTYPE_60FPS:
-        sensmode = REGVAL_SENSMODE_1_4;
-        break;
-
-      case REGVAL_FPSTYPE_30FPS:
-        sensmode = REGVAL_SENSMODE_1_2;
-        break;
-
-      default:
-        sensmode = REGVAL_SENSMODE_ALLPIX;
-        break;
-    }
-
-  ret = isx012_putreg(priv, sensmode_regaddr,
-                      sensmode, sizeof(uint8_t));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = isx012_putreg(priv, hsize_regaddr,
-                      param->hsize, sizeof(uint16_t));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = isx012_putreg(priv, vsize_regaddr,
-                      param->vsize, sizeof(uint16_t));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  if (format == REGVAL_OUTFMT_INTERLEAVE)
-    {
-      ret = isx012_putreg(priv, HSIZE_TN,
-                          param->int_hsize, sizeof(uint16_t));
-      if (ret < 0)
-        {
-          return ret;
-        }
-
-      ret = isx012_putreg(priv, VSIZE_TN,
-                          param->int_vsize, sizeof(uint16_t));
-      if (ret < 0)
-        {
-          return ret;
-        }
-    }
-
-  return ret;
-}
-
-void isx012_callback(uint8_t code, uint32_t size, uint32_t addr)
-{
-  enum v4l2_buf_type type;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  if (priv->mode == REGVAL_MODESEL_CAP)
-    {
-      /* ISX012 capture mode => still capture */
-
-      type = V4L2_BUF_TYPE_STILL_CAPTURE;
-    }
-  else
-    {
-      /* ISX012 monitor/halfrelease/movie mode => video capture */
-
-      type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    }
-
-  video_common_notify_dma_done(code, type, size, priv->video_priv);
-
-  return;
-}
-
-/****************************************************************************
- * isx012_change_camera_mode
- ****************************************************************************/
-
-static int isx012_change_camera_mode(isx012_dev_t *priv, uint8_t mode)
-{
-  int      ret = 0;
-  uint16_t format_addr;
-  uint8_t  format_data;
-  uint32_t vifmode;
-#ifdef ISX012_FRAME_SKIP_EN
-  uint8_t mask_num;
-  int i;
-#endif /* ISX012_FRAME_SKIP_EN */
-
-  if (priv->state != STATE_ISX012_ACTIVE)
-    {
-      return -EPERM;
-    }
-
-  switch (mode)
-    {
-      case REGVAL_MODESEL_MON:
-      case REGVAL_MODESEL_HREL:
-        format_addr = OUTFMT_MONI;
-        break;
-
-      case REGVAL_MODESEL_MOV:
-        format_addr = OUTFMT_MOVIE;
-        break;
-
-      case REGVAL_MODESEL_CAP:
-        format_addr = OUTFMT_CAP;
-        break;
-
-      default:
-        return -EPERM;
-    }
-
-  format_data = isx012_getreg(priv, format_addr, 1);
-
-  switch (format_data) /* mode parallel */
-    {
-      case REGVAL_OUTFMT_YUV:
-        vifmode = REGVAL_VIFMODE_YUV_PARALLEL;
-        break;
-      case REGVAL_OUTFMT_JPEG:
-        vifmode = REGVAL_VIFMODE_JPEG_PARALLEL;
-        break;
-      case REGVAL_OUTFMT_INTERLEAVE:
-        vifmode = REGVAL_VIFMODE_INTERLEAVE_PARALLEL;
-        break;
-      case REGVAL_OUTFMT_RGB:
-        vifmode = REGVAL_VIFMODE_RGB_PARALLEL;
-        break;
-      default:
-        vifmode = REGVAL_VIFMODE_YUV_PARALLEL;
-        break;
-    }
-
-  ret = isx012_putreg(priv, VIFMODE, vifmode, sizeof(vifmode));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  isx012_putreg(priv, INTCLR0, CM_CHANGED_STS, 1);
-
-  ret = isx012_putreg(priv, MODESEL, mode, sizeof(mode));
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Wait CM_CHANGED */
-
-  ret = isx012_chk_int_state(priv, CM_CHANGED_STS,
-                                   CAMERA_MODE_DELAY_TIME,
-                                   CAMERA_MODE_WAIT_TIME,
-                                   CAMERA_MODE_TIMEOUT);
-  if (ret != 0)
-    {
-      return ret;
-    }
-
-#ifdef ISX012_FRAME_SKIP_EN
-  if (mode != REGVAL_MODESEL_HREL)
-    {
-      isx012_putreg(priv, INTCLR0, VINT_STS, 1);
-      mask_num = isx012_getreg(priv, RO_MASK_NUM, sizeof(mask_num));
-      for (i = 0; i < mask_num; i++)
-        {
-          /* Wait Next VINT */
-
-          ret = isx012_chk_int_state(priv, VINT_STS, VINT_DELAY_TIME,
-                                           VINT_WAIT_TIME, VINT_TIMEOUT);
-          if (ret != 0)
-            {
-              return ret;
-            }
-        }
-    }
-#endif /* ISX012_FRAME_SKIP_EN */
-
-  return OK;
-}
-
-/****************************************************************************
- * isx012_change_device_state
- ****************************************************************************/
-
-static int isx012_change_device_state(isx012_dev_t *priv,
-                                      isx012_state_t state)
-{
-  int ret = 0;
-#ifdef ISX012_FRAME_SKIP_EN
-  int i;
-  uint8_t mute_cnt;
-#endif /* ISX012_FRAME_SKIP_EN */
-
-  if (priv->state == STATE_ISX012_PRESLEEP || priv->state == state)
-    {
-      return -EPERM;
-    }
-
-  switch (state)
-    {
-      case STATE_ISX012_SLEEP:
-        isx012_putreg(priv, INTCLR0, OM_CHANGED_STS, 1);
-        board_isx012_set_sleep(1);
-        break;
-      case STATE_ISX012_ACTIVE:
-        isx012_putreg(priv, INTCLR0, OM_CHANGED_STS | CM_CHANGED_STS, 1);
-        board_isx012_release_sleep();
-        break;
-      case STATE_ISX012_PRESLEEP:
-        return -EPERM;
-      default:
-        return -EPERM;
-    }
-
-  /* Wait OM_CHANGED */
-
-  ret = isx012_chk_int_state(priv, OM_CHANGED_STS,
-                                   DEVICE_STATE_DELAY_TIME,
-                                   DEVICE_STATE_WAIT_TIME,
-                                   DEVICE_STATE_TIMEOUT);
-  if (ret != 0)
-    {
-      return ret;
-    }
-
-  priv->state = state;
-
-  if (state == STATE_ISX012_ACTIVE)
-    {
-      /* Wait CM_CHANGED -> Monitoring */
-
-      ret = isx012_chk_int_state(priv, CM_CHANGED_STS,
-                                       CAMERA_MODE_DELAY_TIME,
-                                       CAMERA_MODE_WAIT_TIME,
-                                       CAMERA_MODE_TIMEOUT);
-      if (ret != 0)
-        {
-          return ret;
-        }
-
-#ifdef ISX012_FRAME_SKIP_EN
-      mute_cnt = isx012_getreg(priv, MUTECNT, sizeof(mute_cnt));
-      isx012_putreg(priv, INTCLR0, VINT_STS, 1);
-      for (i = 0; i < mute_cnt; i++)
-        {
-          /* Wait Next VINT */
-
-          ret = isx012_chk_int_state(priv, VINT_STS, VINT_DELAY_TIME,
-                                           VINT_WAIT_TIME, VINT_TIMEOUT);
-          if (ret != 0)
-            {
-              return ret;
-            }
-        }
-#endif /* ISX012_FRAME_SKIP_EN */
-    }
-
-  priv->mode = REGVAL_MODESEL_MON;
-
-  return OK;
-}
-
-int init_isx012(FAR struct isx012_dev_s *priv)
-{
-  int ret;
-
-#ifdef ISX012_NOT_USE_NSTBY
-  board_isx012_release_sleep();
-  board_isx012_release_reset();
-  nxsig_usleep(6000);
-#else
-  board_isx012_release_reset();
-  nxsig_usleep(6000);
-#endif
-
-#ifdef ISX012_CHECK_IN_DETAIL
-  /* check the chip id */
-
-  ret = isx012_chipid(priv);
-  if (ret < 0)
-    {
-      imagererr("isx012_chipid failed: %d\n", ret);
-      board_isx012_set_reset();
-      return ret;
-    }
-#endif
-
-  /* Wait OM_CHANGED Power OFF -> PreSleep */
-
-  ret = isx012_chk_int_state(priv, OM_CHANGED_STS, DEVICE_STATE_DELAY_TIME,
-                             DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
-  if (ret != OK)
-    {
-      imagererr("OM_CHANGED_STS(PreSleep) is Not occurred: %d\n", ret);
-      return ret;
-    }
-
-  priv->state = STATE_ISX012_PRESLEEP;
-
-#ifndef ISX012_NOT_USE_NSTBY
-  /* set the isx012 clock */
-
-  /* Write INCK_SET register ISX012 change state PreSleep -> Sleep */
-
-  ret = isx012_putreglist(priv, g_isx012_presleep, ISX012_PRESLEEP_NENTRIES);
-  if (ret != OK)
-    {
-      imagererr("isx012_putreglist(INCK_SET) failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Wait OM_CHANGED PreSleep -> Sleep */
-
-  ret = isx012_chk_int_state(priv, OM_CHANGED_STS, DEVICE_STATE_DELAY_TIME,
-                             DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
-  if (ret != OK)
-    {
-      imagererr("OM_CHANGED_STS(Sleep) is Not occurred: %d\n", ret);
-      return ret;
-    }
-#endif
-
-  priv->state = STATE_ISX012_SLEEP;
-  priv->i2c_freq = I2CFREQ_FAST;
-
-  /* initialize the isx012 hardware */
-
-  ret = isx012_putreglist(priv, g_isx012_def_init, ISX012_RESET_NENTRIES);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreglist failed: %d\n", ret);
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  /* Set shading adjustment */
-
-  ret = isx012_set_shd(priv);
-  if (ret < 0)
-    {
-      imagererr("isx012_set_shd failed: %d\n", ret);
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  /* monitor mode default format: YUV4:2:2 QVGA */
-
-  priv->param.video.fps         = REGVAL_FPSTYPE_30FPS;
-  priv->param.video.format      = V4L2_PIX_FMT_UYVY;
-  priv->param.video.hsize       = VIDEO_HSIZE_QVGA;
-  priv->param.video.vsize       = VIDEO_VSIZE_QVGA;
-  priv->param.video.int_hsize   = 0;
-  priv->param.video.int_vsize   = 0;
-
-  ret = isx012_set_mode_param(priv,
-                              V4L2_BUF_TYPE_VIDEO_CAPTURE,
-                              &priv->param.video);
-  if (ret < 0)
-    {
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  /* capture mode default format: JPEG FULLHD */
-
-  priv->param.still.fps         = REGVAL_FPSTYPE_15FPS;
-  priv->param.still.format      = V4L2_PIX_FMT_JPEG;
-  priv->param.still.hsize       = VIDEO_HSIZE_FULLHD;
-  priv->param.still.vsize       = VIDEO_VSIZE_FULLHD;
-  priv->param.still.int_hsize   = 0;
-  priv->param.still.int_vsize   = 0;
-
-  ret = isx012_set_mode_param(priv,
-                              V4L2_BUF_TYPE_STILL_CAPTURE,
-                              &priv->param.still);
-  if (ret < 0)
-    {
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  return ret;
-}
-
-static int isx012_open(FAR void *video_private)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  int ret = 0;
-
-  ret = board_isx012_power_on();
-  if (ret < 0)
-    {
-      imagererr("Failed to power on %d\n", ret);
-      return ret;
-    }
-
-  ret = init_isx012(priv);
-  if (ret < 0)
-    {
-      imagererr("Failed to init_isx012 %d\n", ret);
-      board_isx012_set_reset();
-      board_isx012_power_off();
-      return ret;
-    }
-
-  ret = cxd56_cisifinit();
-  if (ret < 0)
-    {
-      imagererr("Fail cxd56_cisifinit %d\n", ret);
-      return ret;
-    }
-
-  /* Save video private information address */
-
-  g_isx012_private.video_priv = video_private;
-
-  return ret;
-}
-
-static int isx012_close(void)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  g_isx012_private.video_priv = NULL;
-
-  int ret = 0;
-
-  if (priv->state == STATE_ISX012_ACTIVE)
-    {
-      board_isx012_set_sleep(1);
-    }
-
-  board_isx012_set_reset();
-
-  ret = board_isx012_power_off();
-  if (ret < 0)
-    {
-      imagererr("Failed to power off %d\n", ret);
-      return ret;
-    }
-
-  ret = cxd56_cisifstopcapture();
-  if (ret < 0)
-    {
-      imagererr("Fail cxd56_cisifstopcapture %d\n", ret);
-      return ret;
-    }
-
-  ret = cxd56_cisiffinalize();
-  if (ret < 0)
-    {
-      imagererr("Fail cxd56_cisiffinalize %d\n", ret);
-      return ret;
-    }
-
-  priv->i2c_freq = I2CFREQ_STANDARD;
-  priv->state    = STATE_ISX012_POWEROFF;
-
-  return ret;
-}
-
-static int isx012_do_halfpush(bool enable)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  uint8_t                 mode;
-  int                     ret = -EPERM;
-
-  if (enable)
-    {
-      /* state transition : MONITORING -> HALFRELEASE */
-
-      if (priv->mode == REGVAL_MODESEL_MON)
-        {
-          mode = REGVAL_MODESEL_HREL;
-          ret = OK;
-        }
-    }
-  else
-    {
-      /* state transition : HALFRELEASE -> MONITORING */
-
-      if (priv->mode == REGVAL_MODESEL_HREL)
-        {
-          mode = REGVAL_MODESEL_MON;
-          ret = OK;
-        }
-    }
-
-  if (ret == OK)
-    {
-      ret = isx012_change_camera_mode(priv, mode);
-      if (ret == OK)
-        {
-          priv->mode = mode;
-        }
-    }
-
-  return ret;
-}
-
-static int isx012_set_buftype(enum v4l2_buf_type type)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  uint8_t                 mode;
-  int                     ret = OK;
-
-  if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-    {
-      if (priv->mode == REGVAL_MODESEL_HREL)
-        {
-          /* state transition : HALFRELEASE -> HALFRELEASE */
-
-          mode = REGVAL_MODESEL_HREL;
-        }
-      else
-        {
-          /* state transition : CAPTURE    -> MONITORING
-           *                 or MONITORING -> MONITORING
-           */
-
-          if (is_movie_needed(&priv->param.video))
-            {
-              mode = REGVAL_MODESEL_MOV;
-            }
-          else
-            {
-              mode = REGVAL_MODESEL_MON;
-            }
-        }
-    }
-  else
-    {
-      /* state transition : any -> CAPTURE */
-
-      mode = REGVAL_MODESEL_CAP;
-    }
-
-  /* In no active case, activate */
-
-  if (priv->state != STATE_ISX012_ACTIVE)
-    {
-      isx012_change_device_state(priv, STATE_ISX012_ACTIVE);
-    }
-
-  if (mode != priv->mode)
-    {
-      ret = isx012_change_camera_mode(priv, mode);
-      if (ret == OK)
-        {
-          priv->mode = mode;
-        }
-    }
-
-  return ret;
-}
-
-static int isx012_set_buf(uint32_t bufaddr, uint32_t bufsize)
-{
-  int ret;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  isx012_modeparam_t *mode_param = NULL;
-
-  cisif_param_t cis_param =
-    {
-       0
-    };
-
-  cisif_sarea_t sarea =
-    {
-       0
-    };
-
-  sarea.strg_addr     = (uint8_t *)bufaddr;
-  sarea.strg_size     = bufsize;
-
-  if (priv->dma_state)
-    {
-      ret = cxd56_cisifsetdmabuf(&sarea);
-    }
-  else
-    {
-      if (priv->mode == REGVAL_MODESEL_CAP)
-        {
-          mode_param = &priv->param.still;
-        }
-      else
-        {
-          mode_param = &priv->param.video;
-        }
-
-      switch (mode_param->format)
-        {
-          case V4L2_PIX_FMT_UYVY: /* Set YUV 4:2:2 information */
-
-            cis_param.yuv_param.hsize = mode_param->hsize;
-            cis_param.yuv_param.vsize = mode_param->vsize;
-
-            break;
-
-          case V4L2_PIX_FMT_JPEG: /* Set JPEG information */
-
-            /* no setting */
-
-            break;
-
-          case V4L2_PIX_FMT_JPEG_WITH_SUBIMG: /* Set JPEG + YUV 4:2:2 information */
-
-            cis_param.yuv_param.hsize = mode_param->int_hsize;
-            cis_param.yuv_param.vsize = mode_param->int_vsize;
-
-            break;
-
-          default: /* Unsupported format */
-
-            return -EINVAL;
-        }
-
-      cis_param.format    = mode_param->format;
-      cis_param.comp_func = isx012_callback;
-
-      ret = cxd56_cisifstartcapture(&cis_param, &sarea);
-      if (ret != OK)
-        {
-          return ret;
-        }
-
-      priv->dma_state = true;
-    }
-
-  return ret;
-}
-
-static int isx012_cancel_dma(void)
-{
-  int ret;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  ret =  cxd56_cisifstopcapture();
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  priv->dma_state = false;
-  return ret;
-}
-
-static int isx012_check_fmt(enum v4l2_buf_type buf_type,
-                            uint32_t           pixel_format)
-{
-  switch (buf_type)
-    {
-      case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-      case V4L2_BUF_TYPE_STILL_CAPTURE:
-        if ((pixel_format != V4L2_PIX_FMT_JPEG) &&
-            (pixel_format != V4L2_PIX_FMT_JPEG_WITH_SUBIMG) &&
-            (pixel_format != V4L2_PIX_FMT_UYVY))
-          {
-            /* Unsupported format */
-
-            return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported type */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_get_range_of_fmt(FAR struct v4l2_fmtdesc *format)
-{
-  if (format == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (format->type)
-    {
-      case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-      case V4L2_BUF_TYPE_STILL_CAPTURE:
-        switch (format->index)
-          {
-            case 0: /* JPEG */
-
-              strncpy(format->description, "JPEG", V4L2_FMT_DSC_MAX);
-              format->pixelformat = V4L2_PIX_FMT_JPEG;
-
-              break;
-
-            case 1: /* JPEG + YUV 4:2:2 */
-
-              strncpy(format->description,
-                      "JPEG + YUV 4:2:2",
-                      V4L2_FMT_DSC_MAX);
-              format->pixelformat        = V4L2_PIX_FMT_JPEG_WITH_SUBIMG;
-              format->subimg_pixelformat = V4L2_PIX_FMT_UYVY;
-
-              break;
-
-            case 2: /* YUV 4:2:2 */
-
-              strncpy(format->description, "YUV 4:2:2", V4L2_FMT_DSC_MAX);
-              format->pixelformat = V4L2_PIX_FMT_UYVY;
-
-              break;
-
-            default:  /* 3, 4, ... */
-              return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported type */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_get_range_of_framesize(
-                     FAR struct v4l2_frmsizeenum *frmsize)
-{
-  int ret;
-
-  if (frmsize == NULL)
-    {
-      return -EINVAL;
-    }
-
-  if (frmsize->index != 0)
-    {
-      return -EINVAL;
-    }
-
-  ret = isx012_check_fmt(frmsize->buf_type, frmsize->pixel_format);
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  switch (frmsize->pixel_format)
-    {
-      case V4L2_PIX_FMT_UYVY:                /* YUV 4:2:2 */
-        frmsize->type                        = V4L2_FRMSIZE_TYPE_STEPWISE;
-        frmsize->stepwise.min_width          = OUT_YUV_HSIZE_MIN;
-        frmsize->stepwise.max_width          = OUT_YUV_15FPS_HSIZE_MAX;
-        frmsize->stepwise.step_width         = ISX012_SIZE_STEP;
-        frmsize->stepwise.min_height         = OUT_YUV_VSIZE_MIN;
-        frmsize->stepwise.max_height         = OUT_YUV_15FPS_VSIZE_MAX;
-        frmsize->stepwise.step_height        = ISX012_SIZE_STEP;
-
-        break;
-
-      case V4L2_PIX_FMT_JPEG:                /* JPEG */
-        frmsize->type                        = V4L2_FRMSIZE_TYPE_STEPWISE;
-        frmsize->stepwise.min_width          = OUT_JPG_HSIZE_MIN;
-        frmsize->stepwise.max_width          = OUT_JPG_15FPS_HSIZE_MAX;
-        frmsize->stepwise.step_width         = ISX012_SIZE_STEP;
-        frmsize->stepwise.min_height         = OUT_JPG_VSIZE_MIN;
-        frmsize->stepwise.max_height         = OUT_JPG_15FPS_VSIZE_MAX;
-        frmsize->stepwise.step_height        = ISX012_SIZE_STEP;
-
-        break;
-
-      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:    /* JPEG + YUV 4:2:2 */
-        if (frmsize->subimg_pixel_format != V4L2_PIX_FMT_UYVY)
-          {
-            /* Unsupported pixel format */
-
-            return -EINVAL;
-          }
-
-        frmsize->type                        = V4L2_FRMSIZE_TYPE_STEPWISE;
-        frmsize->stepwise.min_width          = OUT_JPG_HSIZE_MIN;
-        frmsize->stepwise.max_width          = OUT_JPGINT_15FPS_HSIZE_MAX;
-        frmsize->stepwise.step_width         = ISX012_SIZE_STEP;
-        frmsize->stepwise.min_height         = OUT_JPG_VSIZE_MIN;
-        frmsize->stepwise.max_height         = OUT_JPGINT_15FPS_VSIZE_MAX;
-        frmsize->stepwise.step_height        = ISX012_SIZE_STEP;
-
-        frmsize->subimg_type                 = V4L2_FRMSIZE_TYPE_STEPWISE;
-        frmsize->subimg.stepwise.min_width   = OUT_YUV_HSIZE_MIN;
-        frmsize->subimg.stepwise.max_width   = OUT_YUVINT_30FPS_HSIZE_MAX;
-        frmsize->subimg.stepwise.step_width  = ISX012_SIZE_STEP;
-        frmsize->subimg.stepwise.min_height  = OUT_YUV_VSIZE_MIN;
-        frmsize->subimg.stepwise.max_height  = OUT_YUVINT_30FPS_VSIZE_MAX;
-        frmsize->subimg.stepwise.step_height = ISX012_SIZE_STEP;
-
-        break;
-
-      default: /* Unsupported pixel format */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_try_format(FAR struct v4l2_format *format)
-{
-  int ret;
-  FAR struct v4l2_frmsizeenum support;
-
-  if (format == NULL)
-    {
-      return -EINVAL;
-    }
-
-  /* Get supported frame size information */
-
-  support.index               = 0;
-  support.buf_type            = format->type;
-  support.pixel_format        = format->fmt.pix.pixelformat;
-  support.subimg_pixel_format = format->fmt.pix.subimg_pixelformat;
-
-  ret = isx012_get_range_of_framesize(&support);
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  CHECK_RANGE(format->fmt.pix.width,
-              support.stepwise.min_width,
-              support.stepwise.max_width,
-              support.stepwise.step_width);
-
-  CHECK_RANGE(format->fmt.pix.height,
-              support.stepwise.min_height,
-              support.stepwise.max_height,
-              support.stepwise.step_height);
-
-  if (support.pixel_format == V4L2_PIX_FMT_JPEG_WITH_SUBIMG)
-    {
-      CHECK_RANGE(format->fmt.pix.subimg_width,
-                  support.subimg.stepwise.min_width,
-                  support.subimg.stepwise.max_width,
-                  support.subimg.stepwise.step_width);
-
-      CHECK_RANGE(format->fmt.pix.subimg_height,
-                  support.subimg.stepwise.min_height,
-                  support.subimg.stepwise.max_height,
-                  support.subimg.stepwise.step_height);
-    }
-
-  return OK;
-}
-
-static int isx012_set_format(FAR struct v4l2_format *format)
-{
-  int                     ret;
-  int8_t                  max_fps;
-  struct v4l2_frmivalenum frmival;
-  isx012_modeparam_t      mode_param;
-  FAR isx012_modeparam_t  *current_param;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  ret = isx012_try_format(format);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  frmival.index               = 0;
-  frmival.buf_type            = format->type;
-  frmival.pixel_format        = format->fmt.pix.pixelformat;
-  frmival.width               = format->fmt.pix.width;
-  frmival.height              = format->fmt.pix.height;
-  frmival.subimg_pixel_format = format->fmt.pix.subimg_pixelformat;
-  frmival.subimg_width        = format->fmt.pix.subimg_width;
-  frmival.subimg_height       = format->fmt.pix.subimg_height;
-
-  max_fps = isx012_get_maximum_fps(&frmival);
-  if (max_fps < 0)
-    {
-      return max_fps;
-    }
-
-  switch (format->type)
-    {
-      case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-        current_param = &priv->param.video;
-        break;
-
-      case V4L2_BUF_TYPE_STILL_CAPTURE:
-        current_param = &priv->param.still;
-        break;
-
-      default:
-        return -EINVAL;
-    }
-
-  memcpy(&mode_param, current_param, sizeof(mode_param));
-
-  mode_param.format    = format->fmt.pix.pixelformat;
-  mode_param.hsize     = format->fmt.pix.width;
-  mode_param.vsize     = format->fmt.pix.height;
-  mode_param.int_hsize = format->fmt.pix.subimg_width;
-  mode_param.int_vsize = format->fmt.pix.subimg_height;
-
-  if (mode_param.fps < max_fps)
-    {
-      mode_param.fps = max_fps;
-    }
-
-  ret = isx012_set_mode_param(priv,
-                              format->type,
-                              &mode_param);
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  memcpy(current_param, &mode_param, sizeof(mode_param));
-
-  return OK;
-}
-
-static int isx012_set_supported_frminterval(uint32_t fps_index,
-                                            FAR struct v4l2_fract *interval)
-{
-  switch (fps_index)
-    {
-      case REGVAL_FPSTYPE_120FPS:
-        interval->numerator   = 1;
-        interval->denominator = 120;
-
-        break;
-
-      case REGVAL_FPSTYPE_60FPS:
-        interval->numerator   = 1;
-        interval->denominator = 60;
-
-        break;
-
-      case REGVAL_FPSTYPE_30FPS:
-        interval->numerator   = 1;
-        interval->denominator = 30;
-
-        break;
-
-      case REGVAL_FPSTYPE_15FPS:
-        interval->numerator   = 1;
-        interval->denominator = 15;
-
-        break;
-
-      case REGVAL_FPSTYPE_7_5FPS:
-        interval->numerator   = 2;
-        interval->denominator = 15;
-
-        break;
-
-      case REGVAL_FPSTYPE_6FPS:
-        interval->numerator   = 1;
-        interval->denominator = 6;
-
-        break;
-
-      case REGVAL_FPSTYPE_5FPS:
-        interval->numerator   = 1;
-        interval->denominator = 5;
-
-        break;
-
-      default:
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int8_t isx012_get_maximum_fps(FAR struct v4l2_frmivalenum *frmival)
-{
-  int     ret;
-  uint8_t max_fps = REGVAL_FPSTYPE_120FPS;
-
-  if (frmival == NULL)
-    {
-      return -EINVAL;
-    }
-
-  ret = isx012_check_fmt(frmival->buf_type, frmival->pixel_format);
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  switch (frmival->pixel_format)
-    {
-      case V4L2_PIX_FMT_UYVY:                /* YUV 4:2:2 */
-        if ((frmival->width  < OUT_YUV_HSIZE_MIN) ||
-            (frmival->height < OUT_YUV_VSIZE_MIN) ||
-            (frmival->width  > OUT_YUV_15FPS_HSIZE_MAX) ||
-            (frmival->height > OUT_YUV_15FPS_VSIZE_MAX))
-          {
-            /* IN frame size is out of range */
-
-            return -EINVAL;
-          }
-        else if ((frmival->width  <= OUT_YUV_120FPS_HSIZE_MAX) &&
-                 (frmival->height <= OUT_YUV_120FPS_VSIZE_MAX))
-          {
-            /* support 120FPS, 60FPS, 30FPS, 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_120FPS;
-          }
-        else
-          {
-            /* support 60FPS, 30FPS, 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_60FPS;
-          }
-
-        break;
-
-      case V4L2_PIX_FMT_JPEG:                /* JPEG */
-        if ((frmival->width  < OUT_JPG_HSIZE_MIN) ||
-            (frmival->height < OUT_JPG_VSIZE_MIN) ||
-            (frmival->width  > OUT_JPG_15FPS_HSIZE_MAX) ||
-            (frmival->height > OUT_JPG_15FPS_VSIZE_MAX))
-          {
-            /* IN frame size is out of range */
-
-            return -EINVAL;
-          }
-        else if ((frmival->width  <= OUT_JPG_120FPS_HSIZE_MAX) &&
-                 (frmival->height <= OUT_JPG_120FPS_VSIZE_MAX))
-          {
-             /* support 120FPS, 60FPS, 30FPS, 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_120FPS;
-          }
-        else if ((frmival->width  <= OUT_JPG_60FPS_HSIZE_MAX) &&
-                 (frmival->height <= OUT_JPG_60FPS_VSIZE_MAX))
-          {
-            /* support 60FPS, 30FPS, 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_60FPS;
-          }
-        else if ((frmival->width  <= OUT_JPG_30FPS_HSIZE_MAX) &&
-                 (frmival->height <= OUT_JPG_30FPS_VSIZE_MAX))
-          {
-            /* support 30FPS, 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_30FPS;
-          }
-        else
-          {
-            /* support 15FPS, 7.5FPS, 6FPS, and 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_15FPS;
-          }
-
-        break;
-
-      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:    /* JPEG + YUV 4:2:2 */
-        if (frmival->subimg_pixel_format != V4L2_PIX_FMT_UYVY)
-          {
-            /* Unsupported pixel format */
-
-            return -EINVAL;
-          }
-
-        if ((frmival->width         < OUT_JPG_HSIZE_MIN) ||
-            (frmival->height        < OUT_JPG_VSIZE_MIN) ||
-            (frmival->width         > OUT_JPGINT_15FPS_HSIZE_MAX) ||
-            (frmival->height        > OUT_JPGINT_15FPS_VSIZE_MAX) ||
-            (frmival->subimg_width  < OUT_YUV_HSIZE_MIN) ||
-            (frmival->subimg_height < OUT_YUV_VSIZE_MIN) ||
-            (frmival->subimg_width  > OUT_YUVINT_30FPS_HSIZE_MAX) ||
-            (frmival->subimg_height > OUT_YUVINT_30FPS_VSIZE_MAX))
-          {
-            /* IN frame size is out of range */
-
-            return -EINVAL;
-          }
-        else if ((frmival->width  <= OUT_JPGINT_30FPS_HSIZE_MAX) &&
-                 (frmival->height <= OUT_JPGINT_30FPS_VSIZE_MAX))
-          {
-            /* support 30FPS, 15FPS, 7.5FPS, 6FPS, 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_30FPS;
-          }
-        else
-          {
-            /* support 15FPS, 7.5FPS, 6FPS, 5FPS */
-
-            max_fps = REGVAL_FPSTYPE_15FPS;
-          }
-
-        break;
-
-      default:
-        return -EINVAL;
-    }
-
-  return (int8_t)max_fps;
-}
-
-static int isx012_get_range_of_frameinterval
-           (FAR struct v4l2_frmivalenum *frmival)
-{
-  int    ret;
-  int8_t max_fps;
-
-  max_fps = isx012_get_maximum_fps(frmival);
-  if (max_fps < 0)
-    {
-      return max_fps;
-    }
-
-  frmival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
-  ret = isx012_set_supported_frminterval(frmival->index + max_fps,
-                                         &frmival->discrete);
-  return ret;
-}
-
-static int isx012_change_fraction_to_fps(FAR struct v4l2_fract *interval)
-{
-  if (interval->denominator == interval->numerator * 120)         /* 120FPS */
-    {
-      return REGVAL_FPSTYPE_120FPS;
-    }
-  else if(interval->denominator == interval->numerator * 60)      /* 60FPS */
-    {
-      return REGVAL_FPSTYPE_60FPS;
-    }
-  else if(interval->denominator == interval->numerator * 30)      /* 30FPS */
-    {
-      return REGVAL_FPSTYPE_30FPS;
-    }
-  else if(interval->denominator == interval->numerator * 15)      /* 15FPS */
-    {
-      return REGVAL_FPSTYPE_15FPS;
-    }
-  else if(interval->denominator * 10 == interval->numerator * 75) /* 7.5FPS */
-    {
-      return REGVAL_FPSTYPE_7_5FPS;
-    }
-  else if(interval->denominator == interval->numerator * 6)       /* 6FPS */
-    {
-      return REGVAL_FPSTYPE_6FPS;
-    }
-  else if(interval->denominator == interval->numerator * 5)       /* 5FPS */
-    {
-      return REGVAL_FPSTYPE_5FPS;
-    }
-  else
-    {
-      return -EINVAL;
-    }
-}
-
-static int isx012_set_frameinterval(FAR struct v4l2_streamparm *parm)
-{
-  int                     ret;
-  int8_t                  fps;
-  int8_t                  max_fps;
-  isx012_modeparam_t      mode_param;
-  FAR isx012_modeparam_t  *current_param;
-  struct v4l2_frmivalenum frmival;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  fps = isx012_change_fraction_to_fps(&parm->parm.capture.timeperframe);
-  if (fps < 0)
-    {
-      return fps;
-    }
-
-  frmival.buf_type = parm->type;
-  switch (frmival.buf_type)
-    {
-      case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-        current_param = &priv->param.video;
-        break;
-
-      case V4L2_BUF_TYPE_STILL_CAPTURE:
-        current_param = &priv->param.still;
-        break;
-
-      default:
-        return -EINVAL;
-    }
-
-  memcpy(&mode_param, current_param, sizeof(mode_param));
-
-  /* Get maximum fps settable value in current image format */
-
-  frmival.pixel_format        = mode_param.format;
-  frmival.height              = mode_param.vsize;
-  frmival.width               = mode_param.hsize;
-  frmival.subimg_pixel_format = V4L2_PIX_FMT_UYVY;
-  frmival.subimg_height       = mode_param.int_vsize;
-  frmival.subimg_width        = mode_param.int_hsize;
-  max_fps = isx012_get_maximum_fps(&frmival);
-  if (max_fps < 0)
-    {
-      return fps;
-    }
-
-  if (fps < max_fps)
-    {
-      return -EINVAL;
-    }
-
-  mode_param.fps = fps;
-
-  ret = isx012_set_mode_param(priv,
-                              parm->type,
-                              &mode_param);
-  if (ret != OK)
-    {
-      return ret;
-    }
-
-  memcpy(current_param, &mode_param, sizeof(mode_param));
-
-  return OK;
-}
-
-static int isx012_get_range_of_ctrlval(FAR struct v4l2_query_ext_ctrl *range)
-{
-  if (range == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (range->ctrl_class)
-    {
-      case V4L2_CTRL_CLASS_USER:
-        switch (range->id)
-          {
-            case V4L2_CID_BRIGHTNESS:
-              range->type          = ISX012_TYPE_BRIGHTNESS;
-              range->minimum       = ISX012_MIN_BRIGHTNESS;
-              range->maximum       = ISX012_MAX_BRIGHTNESS;
-              range->step          = ISX012_STEP_BRIGHTNESS;
-              range->default_value = ISX012_DEF_BRIGHTNESS;
-              strncpy(range->name,
-                      ISX012_NAME_BRIGHTNESS,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_CONTRAST:
-              range->type          = ISX012_TYPE_CONTRAST;
-              range->minimum       = ISX012_MIN_CONTRAST;
-              range->maximum       = ISX012_MAX_CONTRAST;
-              range->step          = ISX012_STEP_CONTRAST;
-              range->default_value = ISX012_DEF_CONTRAST;
-              strncpy(range->name,
-                      ISX012_NAME_CONTRAST,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_SATURATION:
-              range->type          = ISX012_TYPE_SATURATION;
-              range->minimum       = ISX012_MIN_SATURATION;
-              range->maximum       = ISX012_MAX_SATURATION;
-              range->step          = ISX012_STEP_SATURATION;
-              range->default_value = ISX012_DEF_SATURATION;
-              strncpy(range->name,
-                      ISX012_NAME_SATURATION,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_HUE:
-              range->type          = ISX012_TYPE_HUE;
-              range->minimum       = ISX012_MIN_HUE;
-              range->maximum       = ISX012_MAX_HUE;
-              range->step          = ISX012_STEP_HUE;
-              range->default_value = ISX012_DEF_HUE;
-              strncpy(range->name,
-                      ISX012_NAME_HUE,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_AUTO_WHITE_BALANCE:
-              range->type          = ISX012_TYPE_AUTOWB;
-              range->minimum       = ISX012_MIN_AUTOWB;
-              range->maximum       = ISX012_MAX_AUTOWB;
-              range->step          = ISX012_STEP_AUTOWB;
-              range->default_value = ISX012_DEF_AUTOWB;
-              strncpy(range->name,
-                      ISX012_NAME_AUTOWB,
-                      sizeof(range->name));
-
-              break;
-            case V4L2_CID_GAMMA_CURVE:
-              range->type          = ISX012_TYPE_GAMMACURVE;
-              range->minimum       = ISX012_MIN_GAMMACURVE;
-              range->maximum       = ISX012_MAX_GAMMACURVE;
-              range->step          = ISX012_STEP_GAMMACURVE;
-              range->default_value = ISX012_DEF_GAMMACURVE;
-              strncpy(range->name,
-                      ISX012_NAME_GAMMACURVE,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_EXPOSURE:
-              range->type          = ISX012_TYPE_EXPOSURE;
-              range->minimum       = ISX012_MIN_EXPOSURE;
-              range->maximum       = ISX012_MAX_EXPOSURE;
-              range->step          = ISX012_STEP_EXPOSURE;
-              range->default_value = ISX012_DEF_EXPOSURE;
-              strncpy(range->name,
-                      ISX012_NAME_EXPOSURE,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_HFLIP:
-              range->type          = ISX012_TYPE_HFLIP;
-              range->minimum       = ISX012_MIN_HFLIP;
-              range->maximum       = ISX012_MAX_HFLIP;
-              range->step          = ISX012_STEP_HFLIP;
-              range->default_value = ISX012_DEF_HFLIP;
-              strncpy(range->name,
-                      ISX012_NAME_HFLIP,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_VFLIP:
-              range->type          = ISX012_TYPE_VFLIP;
-              range->minimum       = ISX012_MIN_VFLIP;
-              range->maximum       = ISX012_MAX_VFLIP;
-              range->step          = ISX012_STEP_VFLIP;
-              range->default_value = ISX012_DEF_VFLIP;
-              strncpy(range->name,
-                      ISX012_NAME_VFLIP,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_HFLIP_STILL:
-              range->type          = ISX012_TYPE_HFLIP_STILL;
-              range->minimum       = ISX012_MIN_HFLIP_STILL;
-              range->maximum       = ISX012_MAX_HFLIP_STILL;
-              range->step          = ISX012_STEP_HFLIP_STILL;
-              range->default_value = ISX012_DEF_HFLIP_STILL;
-              strncpy(range->name,
-                      ISX012_NAME_HFLIP_STILL,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_VFLIP_STILL:
-              range->type          = ISX012_TYPE_VFLIP_STILL;
-              range->minimum       = ISX012_MIN_VFLIP_STILL;
-              range->maximum       = ISX012_MAX_VFLIP_STILL;
-              range->step          = ISX012_STEP_VFLIP_STILL;
-              range->default_value = ISX012_DEF_VFLIP_STILL;
-              strncpy(range->name,
-                      ISX012_NAME_VFLIP_STILL,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_SHARPNESS:
-              range->type          = ISX012_TYPE_SHARPNESS;
-              range->minimum       = ISX012_MIN_SHARPNESS;
-              range->maximum       = ISX012_MAX_SHARPNESS;
-              range->step          = ISX012_STEP_SHARPNESS;
-              range->default_value = ISX012_DEF_SHARPNESS;
-              strncpy(range->name,
-                      ISX012_NAME_SHARPNESS,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_COLOR_KILLER:
-              range->type          = ISX012_TYPE_COLORKILLER;
-              range->minimum       = ISX012_MIN_COLORKILLER;
-              range->maximum       = ISX012_MAX_COLORKILLER;
-              range->step          = ISX012_STEP_COLORKILLER;
-              range->default_value = ISX012_DEF_COLORKILLER;
-              strncpy(range->name,
-                      ISX012_NAME_COLORKILLER,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_COLORFX:
-              range->type          = ISX012_TYPE_COLOREFFECT;
-              range->minimum       = ISX012_MIN_COLOREFFECT;
-              range->maximum       = ISX012_MAX_COLOREFFECT;
-              range->step          = ISX012_STEP_COLOREFFECT;
-              range->default_value = ISX012_DEF_COLOREFFECT;
-              strncpy(range->name,
-                      ISX012_NAME_COLOREFFECT,
-                      sizeof(range->name));
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_CAMERA:
-        switch (range->id)
-          {
-            case V4L2_CID_EXPOSURE_AUTO:
-              range->type          = ISX012_TYPE_EXPOSUREAUTO;
-              range->minimum       = ISX012_MIN_EXPOSUREAUTO;
-              range->maximum       = ISX012_MAX_EXPOSUREAUTO;
-              range->step          = ISX012_STEP_EXPOSUREAUTO;
-              range->default_value = ISX012_DEF_EXPOSUREAUTO;
-              strncpy(range->name,
-                      ISX012_NAME_EXPOSUREAUTO,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_EXPOSURE_ABSOLUTE:
-              range->type          = ISX012_TYPE_EXPOSURETIME;
-              range->minimum       = ISX012_MIN_EXPOSURETIME;
-              range->maximum       = ISX012_MAX_EXPOSURETIME;
-              range->step          = ISX012_STEP_EXPOSURETIME;
-              range->default_value = ISX012_DEF_EXPOSURETIME;
-              strncpy(range->name,
-                      ISX012_NAME_EXPOSURETIME,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_EXPOSURE_METERING:
-              range->type          = ISX012_TYPE_PHOTOMETRY;
-              range->minimum       = ISX012_MIN_PHOTOMETRY;
-              range->maximum       = ISX012_MAX_PHOTOMETRY;
-              range->step          = ISX012_STEP_PHOTOMETRY;
-              range->default_value = ISX012_DEF_PHOTOMETRY;
-              strncpy(range->name,
-                      ISX012_NAME_PHOTOMETRY,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_ZOOM_ABSOLUTE:
-              range->type          = ISX012_TYPE_ZOOM;
-              range->minimum       = ISX012_MIN_ZOOM;
-              range->maximum       = ISX012_MAX_ZOOM;
-              range->step          = ISX012_STEP_ZOOM;
-              range->default_value = ISX012_DEF_ZOOM;
-              strncpy(range->name,
-                      ISX012_NAME_ZOOM,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
-              range->type          = ISX012_TYPE_PRESETWB;
-              range->minimum       = ISX012_MIN_PRESETWB;
-              range->maximum       = ISX012_MAX_PRESETWB;
-              range->step          = ISX012_STEP_PRESETWB;
-              range->default_value = ISX012_DEF_PRESETWB;
-              strncpy(range->name,
-                      ISX012_NAME_PRESETWB,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_WIDE_DYNAMIC_RANGE:
-              range->type          = ISX012_TYPE_YGAMMA;
-              range->minimum       = ISX012_MIN_YGAMMA;
-              range->maximum       = ISX012_MAX_YGAMMA;
-              range->step          = ISX012_STEP_YGAMMA;
-              range->default_value = ISX012_DEF_YGAMMA;
-              strncpy(range->name,
-                      ISX012_NAME_YGAMMA,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY:
-              range->type          = ISX012_TYPE_ISO;
-              range->minimum       = ISX012_MIN_ISO;
-              range->maximum       = ISX012_MAX_ISO;
-              range->step          = ISX012_STEP_ISO;
-              range->default_value = ISX012_DEF_ISO;
-              strncpy(range->name,
-                      ISX012_NAME_ISO,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY_AUTO:
-              range->type          = ISX012_TYPE_ISOAUTO;
-              range->minimum       = ISX012_MIN_ISOAUTO;
-              range->maximum       = ISX012_MAX_ISOAUTO;
-              range->step          = ISX012_STEP_ISOAUTO;
-              range->default_value = ISX012_DEF_ISOAUTO;
-              strncpy(range->name,
-                      ISX012_NAME_ISOAUTO,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_3A_LOCK:
-              range->type          = ISX012_TYPE_3ALOCK;
-              range->minimum       = ISX012_MIN_3ALOCK;
-              range->maximum       = ISX012_MAX_3ALOCK;
-              range->step          = ISX012_STEP_3ALOCK;
-              range->default_value = ISX012_DEF_3ALOCK;
-              strncpy(range->name,
-                      ISX012_NAME_3ALOCK,
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_3A_PARAMETER:
-              range->type          = V4L2_CTRL_TYPE_U16;
-              range->minimum       = 0;
-              range->maximum       = 65535;
-              range->step          = 1;
-              range->elems         = 3;
-              strncpy(range->name,
-                      "AWB/AE parameter",
-                      sizeof(range->name));
-
-              break;
-
-            case V4L2_CID_3A_STATUS:
-              range->type          = V4L2_CTRL_TYPE_INTEGER;
-              range->minimum       = 0;
-              range->maximum       = 3;
-              range->step          = 1;
-              strncpy(range->name,
-                      "AWB/AE status",
-                      sizeof(range->name));
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_JPEG:
-        switch (range->id)
-          {
-            case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-              range->type          = ISX012_TYPE_JPGQUALITY;
-              range->minimum       = ISX012_MIN_JPGQUALITY;
-              range->maximum       = ISX012_MAX_JPGQUALITY;
-              range->step          = ISX012_STEP_JPGQUALITY;
-              range->default_value = ISX012_DEF_JPGQUALITY;
-              strncpy(range->name,
-                      ISX012_NAME_JPGQUALITY,
-                      sizeof(range->name));
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported control class */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_get_menu_of_ctrlval(FAR struct v4l2_querymenu *menu)
-{
-  if (menu == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (menu->ctrl_class)
-    {
-      case V4L2_CTRL_CLASS_USER:
-        switch (menu->id)
-          {
-            case V4L2_CID_COLORFX:
-              if (menu->index > ISX012_MAX_COLOREFFECT)
-                {
-                  return -EINVAL;
-                }
-
-              menu->value = g_isx012_supported_colorfx[menu->index].v4l2;
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_CAMERA:
-        switch (menu->id)
-          {
-            case V4L2_CID_EXPOSURE_METERING:
-              if (menu->index > ISX012_MAX_PHOTOMETRY)
-                {
-                  return -EINVAL;
-                }
-
-              menu->value = g_isx012_supported_photometry[menu->index].v4l2;
-
-              break;
-
-            case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
-              if (menu->index > ISX012_MAX_PRESETWB)
-                {
-                  return -EINVAL;
-                }
-
-              menu->value = g_isx012_supported_presetwb[menu->index].v4l2;
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY:
-              if (menu->index > ISX012_MAX_ISO)
-                {
-                  return -EINVAL;
-                }
-
-              menu->value = g_isx012_supported_iso[menu->index].v4l2;
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported control class */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_get_ctrlval(uint16_t ctrl_class,
-                                FAR struct v4l2_ext_control *control)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  int16_t    readvalue;
-  uint8_t    cnt;
-  uint8_t    threea_enable;
-  uint16_t   read_src;
-  uint16_t   *read_dst;
-  int        ret = -EINVAL;
-
-  if (control == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (ctrl_class)
-    {
-      case V4L2_CTRL_CLASS_USER:
-        switch (control->id)
-          {
-            case V4L2_CID_BRIGHTNESS:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_BRIGHTNESS,
-                                             ISX012_SIZE_BRIGHTNESS);
-              break;
-
-            case V4L2_CID_CONTRAST:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_CONTRAST,
-                                             ISX012_SIZE_CONTRAST);
-              break;
-
-            case V4L2_CID_SATURATION:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_SATURATION,
-                                             ISX012_SIZE_SATURATION);
-              break;
-
-            case V4L2_CID_HUE:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_HUE,
-                                             ISX012_SIZE_HUE);
-              break;
-
-            case V4L2_CID_AUTO_WHITE_BALANCE:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_AUTOWB,
-                                        ISX012_SIZE_AUTOWB);
-
-              /* Convert to V4L2 value */
-
-              if (readvalue & REGVAL_CPUEXT_BIT_AWBSTOP)
-                {
-                  control->value = false;
-                }
-              else
-                {
-                  control->value = true;
-                }
-
-              break;
-
-            case V4L2_CID_GAMMA_CURVE:
-              if (control->p_u16 == NULL)
-                {
-                  return -EINVAL;
-                }
-
-              read_src = ISX012_REG_GAMMACURVE;
-              read_dst = control->p_u16;
-
-              for (cnt = 0; cnt < ISX012_ELEMS_GAMMACURVE; cnt++)
-                {
-                  *read_dst = isx012_getreg(priv,
-                                            read_src,
-                                            ISX012_SIZE_GAMMACURVE);
-                  read_src += ISX012_SIZE_GAMMACURVE;
-                  read_dst++;
-                }
-
-              break;
-
-            case V4L2_CID_EXPOSURE:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_EXPOSURE,
-                                             ISX012_SIZE_EXPOSURE);
-              break;
-
-            case V4L2_CID_HFLIP:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_HFLIP,
-                                        ISX012_SIZE_HFLIP);
-
-              if (readvalue & REGVAL_READVECT_BIT_H)
-                {
-                  control->value = true;
-                }
-              else
-                {
-                  control->value = false;
-                }
-
-              break;
-
-            case V4L2_CID_VFLIP:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_VFLIP,
-                                        ISX012_SIZE_VFLIP);
-
-              if (readvalue & REGVAL_READVECT_BIT_V)
-                {
-                  control->value = true;
-                }
-              else
-                {
-                  control->value = false;
-                }
-
-              break;
-
-            case V4L2_CID_HFLIP_STILL:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_HFLIP_STILL,
-                                        ISX012_SIZE_HFLIP_STILL);
-
-              if (readvalue & REGVAL_READVECT_BIT_H)
-                {
-                  control->value = true;
-                }
-              else
-                {
-                  control->value = false;
-                }
-
-              break;
-
-            case V4L2_CID_VFLIP_STILL:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_VFLIP_STILL,
-                                        ISX012_SIZE_VFLIP_STILL);
-
-              if (readvalue & REGVAL_READVECT_BIT_V)
-                {
-                  control->value = true;
-                }
-              else
-                {
-                  control->value = false;
-                }
-
-              break;
-
-            case V4L2_CID_SHARPNESS:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_SHARPNESS,
-                                             ISX012_SIZE_SHARPNESS);
-              break;
-
-            case V4L2_CID_COLOR_KILLER:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_COLORKILLER,
-                                        ISX012_SIZE_COLORKILLER);
-
-              if (readvalue == REGVAL_EFFECT_MONOTONE)
-                {
-                  control->value = true;
-                }
-              else
-                {
-                  control->value = false;
-                }
-
-              break;
-
-            case V4L2_CID_COLORFX:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_COLOREFFECT,
-                                        ISX012_SIZE_COLOREFFECT);
-
-              for (cnt = 0; cnt <= ISX012_MAX_COLOREFFECT; cnt++)
-                {
-                  if (g_isx012_supported_colorfx[cnt].regval == readvalue)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              control->value = g_isx012_supported_colorfx[cnt].v4l2;
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_CAMERA:
-        switch (control->id)
-          {
-            case V4L2_CID_EXPOSURE_AUTO:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_EXPOSURETIME,
-                                        ISX012_SIZE_EXPOSURETIME);
-
-              if (readvalue)
-                {
-                  control->value = V4L2_EXPOSURE_MANUAL;
-                }
-              else
-                {
-                  control->value = V4L2_EXPOSURE_AUTO;
-                }
-
-              break;
-
-            case V4L2_CID_EXPOSURE_ABSOLUTE:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_EXPOSURETIME,
-                                             ISX012_SIZE_EXPOSURETIME);
-
-              break;
-
-            case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_PRESETWB,
-                                        ISX012_SIZE_PRESETWB);
-
-              for (cnt = 0; cnt <= ISX012_MAX_PRESETWB; cnt++)
-                {
-                  if (g_isx012_supported_presetwb[cnt].regval == readvalue)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              control->value = g_isx012_supported_presetwb[cnt].v4l2;
-
-              break;
-
-            case V4L2_CID_WIDE_DYNAMIC_RANGE:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_YGAMMA,
-                                        ISX012_SIZE_YGAMMA);
-              if (readvalue)
-                {
-                  control->value = false;
-                }
-              else
-                {
-                  control->value = true;
-                }
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_ISO,
-                                        ISX012_SIZE_ISO);
-
-              for (cnt = 0; cnt <= ISX012_MAX_ISO; cnt++)
-                {
-                  if (g_isx012_supported_iso[cnt].regval == readvalue)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              control->value = g_isx012_supported_iso[cnt].v4l2;
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY_AUTO:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_ISOAUTO,
-                                        ISX012_SIZE_ISOAUTO);
-              if (readvalue == REGVAL_ISO_AUTO)
-                {
-                  control->value = V4L2_ISO_SENSITIVITY_AUTO;
-                }
-              else
-                {
-                  control->value = V4L2_ISO_SENSITIVITY_MANUAL;
-                }
-              break;
-
-            case V4L2_CID_EXPOSURE_METERING:
-              readvalue = isx012_getreg(priv,
-                                        ISX012_REG_PHOTOMETRY,
-                                        ISX012_SIZE_PHOTOMETRY);
-
-              for (cnt = 0; cnt <= ISX012_MAX_PHOTOMETRY; cnt++)
-                {
-                  if (g_isx012_supported_photometry[cnt].regval == readvalue)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              control->value = g_isx012_supported_photometry[cnt].v4l2;
-
-              break;
-
-            case V4L2_CID_3A_PARAMETER:
-              if (control->p_u16 == NULL)
-                {
-                  return -EINVAL;
-                }
-
-              /* Get AWB parameter */
-
-              control->p_u16[0] = isx012_getreg(priv,
-                                                RATIO_R,
-                                                2);
-              control->p_u16[1] = isx012_getreg(priv,
-                                                RATIO_B,
-                                                2);
-
-              /* Get AE parameter */
-
-              control->p_u16[2] = isx012_getreg(priv,
-                                                AELEVEL,
-                                                2);
-
-              break;
-
-            case V4L2_CID_3A_STATUS:
-
-              /* Initialize returned status */
-
-              control->value = V4L2_3A_STATUS_STABLE;
-
-              /* Get AWB/AE enable or not */
-
-              threea_enable = isx012_getreg(priv,
-                                            CPUEXT,
-                                            1);
-
-              /* Check AWB */
-
-              if ((threea_enable & REGVAL_CPUEXT_BIT_AWBSTOP)
-                  != REGVAL_CPUEXT_BIT_AWBSTOP)
-                {
-                  /* Check AWB status */
-
-                  readvalue = isx012_getreg(priv,
-                                            AWBSTS,
-                                            1);
-                  if (readvalue != REGVAL_AWBSTS_STOP) /* AWB is not stopped */
-                    {
-                      control->value |= V4L2_3A_STATUS_AWB_OPERATING;
-                    }
-                }
-
-              /* Check AE */
-
-              if ((threea_enable & REGVAL_CPUEXT_BIT_AESTOP)
-                  != REGVAL_CPUEXT_BIT_AESTOP)
-                {
-                  /* Check AE status */
-
-                  readvalue = isx012_getreg(priv,
-                                            AESTS,
-                                            1);
-                  if (readvalue != REGVAL_AESTS_STOP) /* AE is not stopped */
-                    {
-                      control->value |= V4L2_3A_STATUS_AE_OPERATING;
-                    }
-                }
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_JPEG:
-        switch (control->id)
-          {
-            case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-              control->value = isx012_getreg(priv,
-                                             ISX012_REG_JPGQUALITY,
-                                             ISX012_SIZE_JPGQUALITY);
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported control class */
-
-        return -EINVAL;
-    }
-
-  return OK;
-}
-
-static int isx012_set_ctrlval(uint16_t ctrl_class,
-                                FAR struct v4l2_ext_control *control)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-  int       ret = -EINVAL;
-  uint8_t   cnt;
-  uint16_t  *write_src;
-  uint16_t  write_dst;
-  uint16_t  regval;
-  uint16_t  exposure_time_lsb;
-  uint16_t  exposure_time_msb;
-
-  if (control == NULL)
-    {
-      return -EINVAL;
-    }
-
-  switch (ctrl_class)
-    {
-      case V4L2_CTRL_CLASS_USER:
-        switch (control->id)
-          {
-            case V4L2_CID_BRIGHTNESS:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_BRIGHTNESS,
-                          ISX012_MAX_BRIGHTNESS,
-                          ISX012_STEP_BRIGHTNESS);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_BRIGHTNESS,
-                                  control->value,
-                                  ISX012_SIZE_BRIGHTNESS);
-
-              break;
-
-            case V4L2_CID_CONTRAST:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_CONTRAST,
-                          ISX012_MAX_CONTRAST,
-                          ISX012_STEP_CONTRAST);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_CONTRAST,
-                                  control->value,
-                                  ISX012_SIZE_CONTRAST);
-
-              break;
-
-            case V4L2_CID_SATURATION:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_SATURATION,
-                          ISX012_MAX_SATURATION,
-                          ISX012_STEP_SATURATION);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_SATURATION,
-                                  control->value,
-                                  ISX012_SIZE_SATURATION);
-
-              break;
-
-            case V4L2_CID_HUE:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_HUE,
-                          ISX012_MAX_HUE,
-                          ISX012_STEP_HUE);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_HUE,
-                                  control->value,
-                                  ISX012_SIZE_HUE);
-
-              break;
-
-            case V4L2_CID_AUTO_WHITE_BALANCE:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_AUTOWB,
-                          ISX012_MAX_AUTOWB,
-                          ISX012_STEP_AUTOWB);
-
-              regval = isx012_getreg(priv,
-                                     ISX012_REG_AUTOWB,
-                                     ISX012_SIZE_AUTOWB);
-
-              if (control->value)
-                {
-                  /* Because true means setting auto white balance
-                   * turn off the stop bit
-                   */
-
-                  regval &= ~REGVAL_CPUEXT_BIT_AWBSTOP;
-                }
-              else
-                {
-                  /* Because false means stopping auto white balance,
-                   * turn on the stop bit.
-                   */
-
-                  regval |= REGVAL_CPUEXT_BIT_AWBSTOP;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_AUTOWB,
-                                  regval,
-                                  ISX012_SIZE_AUTOWB);
-
-              break;
-
-            case V4L2_CID_GAMMA_CURVE:
-              if (control->p_u16 == NULL)
-                {
-                  return -EINVAL;
-                }
-
-              write_src = control->p_u16;
-              write_dst = ISX012_REG_GAMMACURVE;
-
-              for (cnt = 0; cnt < ISX012_ELEMS_GAMMACURVE; cnt++)
-                {
-                  CHECK_RANGE(*write_src,
-                              ISX012_MIN_GAMMACURVE,
-                              ISX012_MAX_GAMMACURVE,
-                              ISX012_STEP_GAMMACURVE);
-
-                  ret = isx012_putreg(priv,
-                                      write_dst,
-                                      *write_src,
-                                      ISX012_SIZE_GAMMACURVE);
-
-                  write_src++;
-                  write_dst += ISX012_SIZE_GAMMACURVE;
-                }
-
-              break;
-
-            case V4L2_CID_EXPOSURE:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_EXPOSURE,
-                          ISX012_MAX_EXPOSURE,
-                          ISX012_STEP_EXPOSURE);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_EXPOSURE,
-                                  control->value,
-                                  ISX012_SIZE_EXPOSURE);
-
-              break;
-
-            case V4L2_CID_HFLIP:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_HFLIP,
-                          ISX012_MAX_HFLIP,
-                          ISX012_STEP_HFLIP);
-
-              regval = isx012_getreg(priv,
-                                     ISX012_REG_HFLIP,
-                                     ISX012_SIZE_HFLIP);
-
-              if (control->value)
-                {
-                  regval |= REGVAL_READVECT_BIT_H;
-                }
-              else
-                {
-                  regval &= ~REGVAL_READVECT_BIT_H;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_HFLIP,
-                                  regval,
-                                  ISX012_SIZE_HFLIP);
-
-              break;
-
-            case V4L2_CID_VFLIP:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_VFLIP,
-                          ISX012_MAX_VFLIP,
-                          ISX012_STEP_VFLIP);
-
-              regval = isx012_getreg(priv,
-                                     ISX012_REG_VFLIP,
-                                     ISX012_SIZE_VFLIP);
-
-              if (control->value)
-                {
-                  regval |= REGVAL_READVECT_BIT_V;
-                }
-              else
-                {
-                  regval &= ~REGVAL_READVECT_BIT_V;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_VFLIP,
-                                  regval,
-                                  ISX012_SIZE_VFLIP);
-
-              break;
-
-            case V4L2_CID_HFLIP_STILL:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_HFLIP_STILL,
-                          ISX012_MAX_HFLIP_STILL,
-                          ISX012_STEP_HFLIP_STILL);
-
-              regval = isx012_getreg(priv,
-                                     ISX012_REG_HFLIP_STILL,
-                                     ISX012_SIZE_HFLIP_STILL);
-
-              if (control->value)
-                {
-                  regval |= REGVAL_READVECT_BIT_H;
-                }
-              else
-                {
-                  regval &= ~REGVAL_READVECT_BIT_H;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_HFLIP_STILL,
-                                  regval,
-                                  ISX012_SIZE_HFLIP_STILL);
-
-              break;
-
-            case V4L2_CID_VFLIP_STILL:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_VFLIP_STILL,
-                          ISX012_MAX_VFLIP_STILL,
-                          ISX012_STEP_VFLIP_STILL);
-
-              regval = isx012_getreg(priv,
-                                     ISX012_REG_VFLIP_STILL,
-                                     ISX012_SIZE_VFLIP_STILL);
-
-              if (control->value)
-                {
-                  regval |= REGVAL_READVECT_BIT_V;
-                }
-              else
-                {
-                  regval &= ~REGVAL_READVECT_BIT_V;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_VFLIP_STILL,
-                                  regval,
-                                  ISX012_SIZE_VFLIP_STILL);
-
-              break;
-
-            case V4L2_CID_SHARPNESS:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_SHARPNESS,
-                          ISX012_MAX_SHARPNESS,
-                          ISX012_STEP_SHARPNESS);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_SHARPNESS,
-                                  control->value,
-                                  ISX012_SIZE_SHARPNESS);
-
-              break;
-
-            case V4L2_CID_COLOR_KILLER:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_COLORKILLER,
-                          ISX012_MAX_COLORKILLER,
-                          ISX012_STEP_COLORKILLER);
-
-              if (control->value)
-                {
-                  regval = REGVAL_EFFECT_MONOTONE;
-                }
-              else
-                {
-                  regval = REGVAL_EFFECT_NONE;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_COLORKILLER,
-                                  regval,
-                                  ISX012_SIZE_COLORKILLER);
-
-              break;
-
-            case V4L2_CID_COLORFX:
-              for (cnt = 0; cnt <= ISX012_MAX_COLOREFFECT; cnt++)
-                {
-                  if (g_isx012_supported_colorfx[cnt].v4l2 == control->value)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_COLOREFFECT,
-                                  g_isx012_supported_colorfx[cnt].regval,
-                                  ISX012_SIZE_COLOREFFECT);
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_CAMERA:
-        switch (control->id)
-          {
-            case V4L2_CID_EXPOSURE_AUTO:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_EXPOSUREAUTO,
-                          ISX012_MAX_EXPOSUREAUTO,
-                          ISX012_STEP_EXPOSUREAUTO);
-
-              if (control->value == V4L2_EXPOSURE_AUTO)
-                {
-                  /* Register is the same as V4L2_CID_EXPOSURE_ABSOLUTE.
-                   * If this register value = REGVAL_EXPOSURETIME_AUTO(=0),
-                   *  it means auto. Otherwise, it means manual.
-                   */
-
-                  ret = isx012_putreg(priv,
-                                      ISX012_REG_EXPOSURETIME,
-                                      REGVAL_EXPOSURETIME_AUTO,
-                                      ISX012_SIZE_EXPOSURETIME);
-                }
-              else
-                {
-                  /* In manual case, read current value of register which
-                   * value adjusted automatically by ISX012 HW is set to.
-                   * It has 32bits length which is composed of LSB 16bits
-                   *  and MSB 16bits.
-                   */
-
-                  exposure_time_lsb = isx012_getreg
-                                      (priv,
-                                       ISX012_REG_EXPOSUREAUTOVALUE_LSB,
-                                       ISX012_SIZE_EXPOSUREAUTOVALUE);
-                  exposure_time_msb = isx012_getreg
-                                      (priv,
-                                       ISX012_REG_EXPOSUREAUTOVALUE_MSB,
-                                       ISX012_SIZE_EXPOSUREAUTOVALUE);
-
-                  /* Register value adjusted automatically by ISX012 HW
-                   *  has the different unit from manual value register.
-                   *   automatic value register : 1   microsec unit
-                   *   manual    value register : 100 microsec unit
-                   */
-
-                  regval = (uint16_t)(((exposure_time_msb << 16)
-                                        | exposure_time_lsb)
-                                       / ISX012_UNIT_EXPOSURETIME_US);
-                  ret = isx012_putreg(priv,
-                                      ISX012_REG_EXPOSURETIME,
-                                      regval,
-                                      ISX012_SIZE_EXPOSURETIME);
-                }
-
-              break;
-
-            case V4L2_CID_EXPOSURE_ABSOLUTE:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_EXPOSURETIME,
-                          ISX012_MAX_EXPOSURETIME,
-                          ISX012_STEP_EXPOSURETIME);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_EXPOSURETIME,
-                                  control->value,
-                                  ISX012_SIZE_EXPOSURETIME);
-              break;
-
-            case V4L2_CID_WIDE_DYNAMIC_RANGE:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_YGAMMA,
-                          ISX012_MAX_YGAMMA,
-                          ISX012_STEP_YGAMMA);
-
-              if (control->value)
-                {
-                  regval = REGVAL_YGAMMA_AUTO;
-                }
-              else
-                {
-                  regval = REGVAL_YGAMMA_OFF;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_YGAMMA,
-                                  regval,
-                                  ISX012_SIZE_YGAMMA);
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY:
-              for (cnt = 0; cnt <= ISX012_MAX_ISO; cnt++)
-                {
-                  if (g_isx012_supported_iso[cnt].v4l2
-                       == control->value)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_ISO,
-                                  g_isx012_supported_iso[cnt].regval,
-                                  ISX012_SIZE_ISO);
-
-              break;
-
-            case V4L2_CID_ISO_SENSITIVITY_AUTO:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_ISOAUTO,
-                          ISX012_MAX_ISOAUTO,
-                          ISX012_STEP_ISOAUTO);
-
-              if (control->value == V4L2_ISO_SENSITIVITY_AUTO)
-                {
-                  ret = isx012_putreg(priv,
-                                      ISX012_REG_ISOAUTO,
-                                      REGVAL_ISO_AUTO,
-                                      ISX012_SIZE_ISOAUTO);
-                }
-              else
-                {
-                  /* In manual case, read auto adjust value and set it */
-
-                  regval = isx012_getreg(priv,
-                                         ISX012_REG_ISOAUTOVALUE,
-                                         ISX012_SIZE_ISOAUTOVALUE);
-                  ret = isx012_putreg(priv,
-                                      ISX012_REG_ISO,
-                                      regval,
-                                      ISX012_SIZE_ISO);
-                }
-
-              break;
-
-            case V4L2_CID_EXPOSURE_METERING:
-              for (cnt = 0; cnt <= ISX012_MAX_PHOTOMETRY; cnt++)
-                {
-                  if (g_isx012_supported_photometry[cnt].v4l2
-                       == control->value)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_PHOTOMETRY,
-                                  g_isx012_supported_photometry[cnt].regval,
-                                  ISX012_SIZE_PHOTOMETRY);
-
-              break;
-
-            case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
-              for (cnt = 0; cnt <= ISX012_MAX_PRESETWB; cnt++)
-                {
-                  if (g_isx012_supported_presetwb[cnt].v4l2
-                      == control->value)
-                    {
-                      ret = OK;
-                      break;
-                    }
-                }
-
-              if (ret != OK)
-                {
-                  return ret;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_PRESETWB,
-                                  g_isx012_supported_presetwb[cnt].regval,
-                                  ISX012_SIZE_PRESETWB);
-
-              break;
-
-            case V4L2_CID_3A_LOCK:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_3ALOCK,
-                          ISX012_MAX_3ALOCK,
-                          ISX012_STEP_3ALOCK);
-
-              regval = 0;
-
-              if ((control->value & V4L2_LOCK_EXPOSURE)
-                    == V4L2_LOCK_EXPOSURE)
-                {
-                  regval |= REGVAL_CPUEXT_BIT_AESTOP;
-                }
-
-              if ((control->value & V4L2_LOCK_WHITE_BALANCE)
-                    == V4L2_LOCK_WHITE_BALANCE)
-                {
-                  regval |= REGVAL_CPUEXT_BIT_AWBSTOP;
-                }
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_3ALOCK,
-                                  regval,
-                                  ISX012_SIZE_3ALOCK);
-
-              break;
-
-            case V4L2_CID_3A_PARAMETER:
-
-              /* AWB parameter : red */
-
-              ret = isx012_putreg(priv,
-                                  INIT_CONT_INR,
-                                  control->p_u16[0],
-                                  2);
-              ret = isx012_putreg(priv,
-                                  INIT_CONT_OUTR,
-                                  control->p_u16[0],
-                                  2);
-
-              /* AWB parameter : blue */
-
-              ret = isx012_putreg(priv,
-                                  INIT_CONT_INB,
-                                  control->p_u16[1],
-                                  2);
-              ret = isx012_putreg(priv,
-                                  INIT_CONT_OUTB,
-                                  control->p_u16[1],
-                                  2);
-
-              /* AE parameter */
-
-              ret = isx012_putreg(priv,
-                                  AE_START_LEVEL,
-                                  control->p_u16[2],
-                                  2);
-
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      case V4L2_CTRL_CLASS_JPEG:
-        switch (control->id)
-          {
-            case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-              CHECK_RANGE(control->value,
-                          ISX012_MIN_JPGQUALITY,
-                          ISX012_MAX_JPGQUALITY,
-                          ISX012_STEP_JPGQUALITY);
-
-              ret = isx012_putreg(priv,
-                                  ISX012_REG_JPGQUALITY,
-                                  control->value,
-                                  ISX012_SIZE_JPGQUALITY);
-              break;
-
-            default: /* Unsupported control id */
-
-              return -EINVAL;
-          }
-
-        break;
-
-      default: /* Unsupported control class */
-
-        return -EINVAL;
-    }
-
-  return ret;
-}
-
-static int isx012_refresh(void)
-{
-  int ret = 0;
-  uint8_t mask_num;
-  int i;
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  if (priv->state != STATE_ISX012_ACTIVE)
-    {
-      /* In inactive state, setting is reflected in activated timing */
-
-      return OK;
-    }
-
-  if (priv->mode != REGVAL_MODESEL_MON)
-    {
-      return -EPERM;
-    }
-
-  /* Set MONI_REFRESH */
-
-  isx012_putreg(priv, INTCLR0, CM_CHANGED_STS, 1);
-  ret = isx012_putreg(priv, MONI_REFRESH, 1, 1);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Wait CM_CHANGED */
-
-  ret = isx012_chk_int_state(priv, CM_CHANGED_STS,
-                                   CAMERA_MODE_DELAY_TIME,
-                                   CAMERA_MODE_WAIT_TIME,
-                                   CAMERA_MODE_TIMEOUT);
-  if (ret != 0)
-    {
-      return ret;
-    }
-
-  /* Invalid frame skip */
-
-  isx012_putreg(priv, INTCLR0, VINT_STS, 1);
-  mask_num = isx012_getreg(priv, RO_MASK_NUM, sizeof(mask_num));
-  for (i = 0; i < mask_num; i++)
-    {
-      /* Wait Next VINT */
-
-      ret = isx012_chk_int_state(priv, VINT_STS, VINT_DELAY_TIME,
-                                       VINT_WAIT_TIME, VINT_TIMEOUT);
-      if (ret != 0)
-        {
-          return ret;
-        }
-    }
-
-  return OK;
-}
-
-static int isx012_set_shd(FAR isx012_dev_t *priv)
-{
-  int ret;
-  int unit_cnt;
-  int size_cnt;
-
-  /* At first, disable CXC and SHD */
-
-  ret = isx012_putreg(priv, SHD_EN, 0x50, 1);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreg(disable CXC/SHD) failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Set CXC Validity */
-
-  ret = isx012_putreg(priv, CXC_VALID, 0x8282, 2);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreg(CXC_VALID) failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Set CXC R Gb data */
-
-  for (unit_cnt = 0; unit_cnt < CXC_RGB_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < CXC_RGB_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              CXC_RGB_UNIT(unit_cnt, size_cnt),
-                              g_isx012_cxc_rgb_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(CXC R Gb) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set CXC G Rb data */
-
-  for (unit_cnt = 0; unit_cnt < CXC_GRB_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < CXC_GRB_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              CXC_GRB_UNIT(unit_cnt, size_cnt),
-                              g_isx012_cxc_grb_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(CXC G Rb) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD Validity */
-
-  ret = isx012_putreg(priv, SHD_VALID, 0x9191, 2);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreg(SHD_VALID) failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Set SHD R Gb data */
-
-  for (unit_cnt = 0; unit_cnt < SHD_RGB_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < SHD_RGB_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              SHD_RGB_UNIT(unit_cnt, size_cnt),
-                              g_isx012_shd_rgb_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(SHD R Gb) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD G Rb data */
-
-  for (unit_cnt = 0; unit_cnt < SHD_GRB_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < SHD_GRB_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              SHD_GRB_UNIT(unit_cnt, size_cnt),
-                              g_isx012_shd_grb_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(SHD G Rb) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD R1 data */
-
-  for (unit_cnt = 0; unit_cnt < SHD_R1_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < SHD_R1_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              SHD_R1_UNIT(unit_cnt, size_cnt),
-                              g_isx012_shd_r1_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(SHD R1) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD R2 data */
-
-  for (unit_cnt = 0; unit_cnt < SHD_R2_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < SHD_R2_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              SHD_R2_UNIT(unit_cnt, size_cnt),
-                              g_isx012_shd_r2_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(SHD R2) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD B2 data */
-
-  for (unit_cnt = 0; unit_cnt < SHD_B2_DATA_UNIT_NUM; unit_cnt++)
-    {
-      for (size_cnt = 0; size_cnt < SHD_B2_DATA_UNIT_SIZE; size_cnt++)
-        {
-          ret = isx012_putreg(priv,
-                              SHD_B2_UNIT(unit_cnt, size_cnt),
-                              g_isx012_shd_b2_data[unit_cnt][size_cnt],
-                              1);
-          if (ret < 0)
-            {
-              imagererr("isx012_putreg(SHD B2) failed: %d\n", ret);
-              return ret;
-            }
-        }
-    }
-
-  /* Set SHD thresholds data */
-
-  ret = isx012_putreglist(priv, g_isx012_shd_thresholds,
-                          ISX012_SHD_THRESHOLDS_NENTRIES);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreglist failed(SHD thresholds): %d\n", ret);
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  /* Set SHD white balance data */
-
-  ret = isx012_putreglist(priv, g_isx012_shd_wb, ISX012_SHD_WB_NENTRIES);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreglist(SHD white balance) failed: %d\n", ret);
-      board_isx012_set_reset();
-      return ret;
-    }
-
-  /* Enable CXC and SHD */
-
-  ret = isx012_putreg(priv, SHD_EN, 0x57, 1);
-  if (ret < 0)
-    {
-      imagererr("isx012_putreg(enable CXC/SHD) failed: %d\n", ret);
-      return ret;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-int isx012_register(FAR struct i2c_master_s *i2c)
-{
-  FAR struct isx012_dev_s *priv = &g_isx012_private;
-
-  /* Save i2c information */
-
-  priv->i2c        = i2c;
-  priv->i2c_addr   = ISX012_I2C_SLV_ADDR;
-  priv->i2c_freq   = I2CFREQ_STANDARD;
-
-  /* Initialize other information */
-
-  priv->state      = STATE_ISX012_POWEROFF;
-
-  return OK;
-}
-
-int isx012_unregister(void)
-{
-  /* no procedure */
-
-  return OK;
-}
-
-FAR struct video_devops_s *isx012_initialize(void)
-{
-  /* return address of video operations variable */
-
-  return &g_isx012_video_devops;
-}
-
-int isx012_uninitialize(void)
-{
-  /* No procedure */
-
-  return OK;
-}
diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
index b9a81a5..4c78f6e 100644
--- a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
+++ b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
@@ -109,6 +109,10 @@
 #  include <nuttx/video/fb.h>
 #endif
 
+#ifdef CONFIG_CXD56_CISIF
+#  include <arch/chip/cisif.h>
+#endif
+
 #include "spresense.h"
 
 /****************************************************************************
@@ -191,9 +195,6 @@ int cxd56_bringup(void)
 {
   struct pm_cpu_wakelock_s wlock;
   int ret;
-#ifdef CONFIG_VIDEO_ISX012
-  FAR const struct video_devops_s *devops;
-#endif
 
   ret = nsh_cpucom_initialize();
   if (ret < 0)
@@ -375,16 +376,18 @@ int cxd56_bringup(void)
   ret = board_isx012_initialize(IMAGER_I2C);
   if (ret < 0)
     {
-      _err("ERROR: Failed to initialize ISX012 board. %d\n", ret);
+      _err("ERROR: Failed to initialize ISX012 board. %d\n", errno);
     }
+#endif /* CONFIG_VIDEO_ISX012 */
 
-  devops  = isx012_initialize();
-  if (devops == NULL)
+#ifdef CONFIG_CXD56_CISIF
+  ret = cxd56_cisif_initialize();
+  if (ret < 0)
     {
-      _err("ERROR: Failed to populate ISX012 devops. %d\n", ret);
+      _err("ERROR: Failed to initialize CISIF. %d\n", errno);
       ret = ERROR;
     }
-#endif /* CONFIG_VIDEO_ISX012 */
+#endif /* CONFIG_CXD56_CISIF */
 
 #if defined(CONFIG_CXD56_SDIO)
   /* In order to prevent Hi-Z from being input to the SD Card controller,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5da6fd2..fb3265b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -56,6 +56,87 @@ config VIDEO_STREAM
 	---help---
 		Enable video Stream support
 
+if VIDEO_STREAM
+
+config VIDEO_SCENE_BACKLIGHT
+        bool "Enable backlight scene"
+        default y
+        ---help---
+                Enable backlight scene
+
+config VIDEO_SCENE_BEACHSNOW
+        bool "Enable beach snow scene"
+        default y
+        ---help---
+                Enable beach snow scene
+
+config VIDEO_SCENE_CANDLELIGHT
+        bool "Enable candle light scene"
+        default y
+        ---help---
+                Enable candle light scene
+
+config VIDEO_SCENE_DAWNDUSK
+        bool "Enable dawn dusk scene"
+        default y
+        ---help---
+                Enable dawn dusk scene
+
+config VIDEO_SCENE_FALLCOLORS
+        bool "Enable fall colors scene"
+        default y
+        ---help---
+                Enable fall colors scene
+
+config VIDEO_SCENE_FIREWORKS
+        bool "Enable fireworks scene"
+        default y
+        ---help---
+                Enable fireworks scene
+
+config VIDEO_SCENE_LANDSCAPE
+        bool "Enable landscape scene"
+        default y
+        ---help---
+                Enable landscape scene
+
+config VIDEO_SCENE_NIGHT
+        bool "Enable night scene"
+        default y
+        ---help---
+                Enable night scene
+
+config VIDEO_SCENE_PARTYINDOOR
+        bool "Enable party and indoor scene"
+        default y
+        ---help---
+                Enable party and indoor scene
+
+config VIDEO_SCENE_PORTRAIT
+        bool "Enable portrait scene"
+        default y
+        ---help---
+                Enable portrait scene
+
+config VIDEO_SCENE_SPORTS
+        bool "Enable sports scene"
+        default y
+        ---help---
+                Enable sports scene
+
+config VIDEO_SCENE_SUNSET
+        bool "Enable sunset scene"
+        default y
+        ---help---
+                Enable sunset scene
+
+config VIDEO_SCENE_TEXT
+        bool "Enable text scene"
+        default y
+        ---help---
+                Enable text scene
+endif
+
 config VIDEO_MAX7456
 	bool "Maxim 7456 Monochrome OSD"
 	default n
@@ -64,6 +145,11 @@ config VIDEO_MAX7456
 		Support for the Maxim 7456 monochrome on-screen display
 		multiplexer.
 
+config VIDEO_ISX012
+        bool "ISX012 Image sensor"
+        default n
+        select I2C
+
 config VIDEO_OV2640
 	bool "OV2640 camera chip"
 	default n
diff --git a/drivers/video/Make.defs b/drivers/video/Make.defs
index 545e02a..5803680 100644
--- a/drivers/video/Make.defs
+++ b/drivers/video/Make.defs
@@ -34,6 +34,10 @@ endif
 
 ifeq ($(CONFIG_I2C),y)
 
+ifeq ($(CONFIG_VIDEO_ISX012),y)
+  CSRCS += isx012.c
+endif
+
 ifeq ($(CONFIG_VIDEO_OV2640),y)
   CSRCS += ov2640.c
 endif
diff --git a/drivers/video/isx012.c b/drivers/video/isx012.c
new file mode 100644
index 0000000..62630e6
--- /dev/null
+++ b/drivers/video/isx012.c
@@ -0,0 +1,2917 @@
+/****************************************************************************
+ * drivers/video/isx012.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 <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/signal.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/i2c/i2c_master.h>
+#include <arch/board/board.h>
+#include <arch/irq.h>
+
+#include <nuttx/video/isx012.h>
+#include "isx012_reg.h"
+#include "isx012_range.h"
+#include <nuttx/video/imgsensor.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The following macro is enabled because
+ * it is to make stable startup. (other case)
+ */
+
+/* #define ISX012_NOT_USE_NSTBY */
+
+/* The following macro is disabled because it is to see detailed control. */
+
+/* #define ISX012_CHECK_IN_DETAIL */
+
+/* Skip invalid frame because it occurs first due to the spec of isx012. */
+
+#define ISX012_FRAME_SKIP_EN
+
+#define OUT_HSIZE_QVGA           (320)
+#define OUT_VSIZE_QVGA           (240)
+#define OUT_HSIZE_VGA            (640)
+#define OUT_VSIZE_VGA            (480)
+#define OUT_HSIZE_HD            (1280)
+#define OUT_VSIZE_HD             (720)
+#define OUT_HSIZE_QUADVGA       (1280)
+#define OUT_VSIZE_QUADVGA        (960)
+#define OUT_HSIZE_FULLHD        (1920)
+#define OUT_VSIZE_FULLHD        (1080)
+#define OUT_HSIZE_3M            (2048)
+#define OUT_VSIZE_3M            (1536)
+#define OUT_HSIZE_5M            (2560)
+#define OUT_VSIZE_5M            (1920)
+
+#define OUT_YUV_VSIZE_MIN         (64)
+#define OUT_YUV_HSIZE_MIN         (96)
+#define OUT_JPG_VSIZE_MIN         (64)
+#define OUT_JPG_HSIZE_MIN         (96)
+#define OUT_YUV_15FPS_VSIZE_MAX  (600)
+#define OUT_YUV_15FPS_HSIZE_MAX  (800)
+#define OUT_YUV_30FPS_VSIZE_MAX  (600)
+#define OUT_YUV_30FPS_HSIZE_MAX  (800)
+#define OUT_YUV_60FPS_VSIZE_MAX  (480)
+#define OUT_YUV_60FPS_HSIZE_MAX  (640)
+#define OUT_YUV_120FPS_VSIZE_MAX (240)
+#define OUT_YUV_120FPS_HSIZE_MAX (320)
+#define OUT_JPG_15FPS_VSIZE_MAX (1944)
+#define OUT_JPG_15FPS_HSIZE_MAX (2592)
+#define OUT_JPG_30FPS_VSIZE_MAX  (960)
+#define OUT_JPG_30FPS_HSIZE_MAX (1280)
+#define OUT_JPG_60FPS_VSIZE_MAX  (480)
+#define OUT_JPG_60FPS_HSIZE_MAX  (640)
+#define OUT_JPG_120FPS_VSIZE_MAX (240)
+#define OUT_JPG_120FPS_HSIZE_MAX (320)
+
+#define OUT_YUVINT_30FPS_VSIZE_MAX  (240)
+#define OUT_YUVINT_30FPS_HSIZE_MAX  (400)
+#define OUT_JPGINT_30FPS_VSIZE_MAX  (960)
+#define OUT_JPGINT_30FPS_HSIZE_MAX (1280)
+#define OUT_JPGINT_15FPS_VSIZE_MAX (1224)
+#define OUT_JPGINT_15FPS_HSIZE_MAX (1632)
+
+#define VINT_TIMEOUT                (400) /* ms */
+#define VINT_WAIT_TIME                (5) /* ms */
+#define VINT_DELAY_TIME               (0) /* ms */
+#define CAMERA_MODE_TIMEOUT         (800) /* ms */
+#define CAMERA_MODE_WAIT_TIME        (10) /* ms */
+#define CAMERA_MODE_DELAY_TIME        (0) /* ms */
+#define DEVICE_STATE_TIMEOUT        (100) /* ms */
+#define DEVICE_STATE_WAIT_TIME        (1) /* ms */
+#define DEVICE_STATE_DELAY_TIME       (2) /* ms */
+
+#define I2CFREQ_STANDARD         (100000) /* Standard mode : 100kHz */
+#define I2CFREQ_FAST             (400000) /* Fast mode     : 400kHz */
+
+#define ISX012_SIZE_STEP              (2)
+
+#define CXC_RGB_DATA_UNIT_NUM        (27)
+#define CXC_RGB_DATA_UNIT_SIZE        (7)
+#define CXC_GRB_DATA_UNIT_NUM        (27)
+#define CXC_GRB_DATA_UNIT_SIZE        (7)
+#define SHD_RGB_DATA_UNIT_NUM        (27)
+#define SHD_RGB_DATA_UNIT_SIZE       (11)
+#define SHD_GRB_DATA_UNIT_NUM        (27)
+#define SHD_GRB_DATA_UNIT_SIZE       (11)
+#define SHD_R1_DATA_UNIT_NUM         (14)
+#define SHD_R1_DATA_UNIT_SIZE        (11)
+#define SHD_R2_DATA_UNIT_NUM         (14)
+#define SHD_R2_DATA_UNIT_SIZE        (11)
+#define SHD_B2_DATA_UNIT_NUM         (14)
+#define SHD_B2_DATA_UNIT_SIZE        (11)
+
+#define ISX012_ELEMS_3APARAM         (3)
+
+#ifdef CONFIG_DEBUG_IMAGER_ERROR
+#define imagererr(format, ...)     _err(format, ##__VA_ARGS__)
+#else
+#define imagererr(x...)
+#endif
+
+#ifdef CONFIG_DEBUG_IMAGER_WARN
+#define imagerwarn(format, ...)   _warn(format, ##__VA_ARGS__)
+#else
+#define imagerwarn(x...)
+#endif
+
+#ifdef CONFIG_DEBUG_IMAGER_INFO
+#define imagerinfo(format, ...)   _info(format, ##__VA_ARGS__)
+#else
+#define imagerinfo(x...)
+#endif
+
+#define VALIDATE_VALUE(val, min, max, step) (((val >= min) && \
+                                              (val <= max) && \
+                                              (((val - min) % step) == 0) ? \
+                                              OK : -EINVAL))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum isx012_state_e
+{
+  STATE_ISX012_PRESLEEP,
+  STATE_ISX012_SLEEP,
+  STATE_ISX012_ACTIVE,
+  STATE_ISX012_POWEROFF,
+};
+
+typedef enum isx012_state_e isx012_state_t;
+
+struct isx012_reg_s
+{
+  uint16_t regaddr;
+  uint16_t regval;
+  uint8_t  regsize;
+};
+
+typedef struct isx012_reg_s isx012_reg_t;
+
+struct isx012_dev_s
+{
+  FAR struct i2c_master_s *i2c;        /* I2C interface */
+  uint8_t                 i2c_addr;    /* I2C address */
+  int                     i2c_freq;    /* Frequency */
+  isx012_state_t          state;       /* ISX012 status */
+  uint8_t                 mode;        /* ISX012 mode */
+};
+
+typedef struct isx012_dev_s isx012_dev_t;
+
+#define ARRAY_NENTRIES(a) (sizeof(a)/sizeof(a[0]))
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* register operations */
+
+static uint16_t isx012_getreg(isx012_dev_t *priv,
+                              uint16_t regaddr, uint16_t regsize);
+static int     isx012_putreg(isx012_dev_t *priv, uint16_t regaddr,
+                             uint16_t regval, uint16_t regsize);
+static int     isx012_putreglist(isx012_dev_t *priv,
+                         FAR const isx012_reg_t *reglist, size_t nentries);
+#ifdef ISX012_CHECK_IN_DETAIL
+static int     isx012_putregs(isx012_dev_t *priv, uint16_t regaddr,
+                              uint8_t *regvals, uint8_t regsize);
+static int     isx012_chipid(FAR struct i2c_master_s *i2c);
+#endif
+
+static int isx012_chk_int_state(isx012_dev_t *priv,
+                                uint8_t  sts, uint32_t delay_time,
+                                uint32_t wait_time, uint32_t timeout);
+static int isx012_set_mode_param(isx012_dev_t *priv,
+                                 imgsensor_stream_type_t type,
+                                 uint8_t nr_fmt,
+                                 imgsensor_format_t *fmt,
+                                 imgsensor_interval_t *interval);
+static int isx012_change_camera_mode(isx012_dev_t *priv, uint8_t mode);
+static int isx012_change_device_state(isx012_dev_t *priv,
+                                      isx012_state_t state);
+static int isx012_replace_frameinterval_to_regval
+                (FAR imgsensor_interval_t *interval);
+static int8_t isx012_get_maximum_fps
+                (uint8_t nr_datafmt,
+                 FAR imgsensor_format_t *datafmt);
+static int isx012_set_shd(FAR isx012_dev_t *priv);
+static bool is_movie_needed(uint8_t fmt, uint8_t fps);
+
+/* image sensor device operations interface */
+
+static int isx012_init(void);
+static int isx012_uninit(void);
+static int isx012_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_datafmt,
+                                         FAR imgsensor_format_t *datafmts,
+                                         FAR imgsensor_interval_t *interval);
+static int isx012_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_datafmt,
+                                FAR imgsensor_format_t *datafmts,
+                                FAR imgsensor_interval_t *interval);
+static int isx012_stop_capture(imgsensor_stream_type_t type);
+static int isx012_get_supported_value
+             (uint32_t id, FAR imgsensor_supported_value_t *value);
+static int isx012_get_value
+             (uint32_t id, uint32_t size, FAR imgsensor_value_t *value);
+static int isx012_set_value
+             (uint32_t id, uint32_t size, imgsensor_value_t value);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static isx012_dev_t   g_isx012_private;
+
+#ifndef ISX012_NOT_USE_NSTBY
+static const isx012_reg_t g_isx012_presleep[] =
+{
+  {PLL_CKSEL, 0x00, 0x01}, /* PLL_CKSEL */
+  {SRCCK_DIV, 0x00, 0x01}, /* SRCCK_DIV */
+  {INCK_SET,  0x17, 0x01}, /* INCK_SET */
+};
+#define ISX012_PRESLEEP_NENTRIES ARRAY_NENTRIES(g_isx012_presleep)
+#endif
+
+static const isx012_reg_t g_isx012_def_init[] =
+{
+#ifdef ISX012_NOT_USE_NSTBY
+  {PLL_CKSEL,         0x00, 0x01},
+  {SRCCK_DIV,         0x00, 0x01},
+#endif
+  {DRIVABILITY,       0xaa, 0x01},
+  {VIFCONFIG,       0x0200, 0x02},
+  {YUVCONFIG_TN,    0xff0a, 0x02},
+  {ILCODELEN,         0x00, 0x01},
+  {AFMODE_MONI,       0x01, 0x01},
+  {YUVCONFIG,       0xff6a, 0x02},
+  {VIF_REC601_Y,    0x10fe, 0x02},
+  {VIF_REC601_C,    0x10f0, 0x02},
+  {HSENS_MODE_SEL,    0x11, 0x01},
+  {VIF_CLKCONFIG1,    0x30, 0x01},
+  {VIF_CLKCONFIG2,    0x30, 0x01},
+  {VIF_CLKCONFIG3,    0x30, 0x01},
+  {VIF_CLKCONFIG4,    0x30, 0x01},
+  {VIF_CLKCONFIG5,    0x30, 0x01},
+  {VIF_CLKCONFIG6,    0x30, 0x01},
+  {VIF_CLKCONFIG7,    0x30, 0x01},
+  {VIF_CLKCONFIG8,    0x30, 0x01},
+  {VIF_CLKCONFIG9,    0x30, 0x01},
+  {VIF_CLKCONFIG10,   0x30, 0x01},
+  {VIF_CLKCONFIG11,   0x30, 0x01},
+  {VIF_CLKCONFIG12,   0x30, 0x01},
+  {VIF_CLKCONFIG13,   0x11, 0x01},
+  {VIF_CLKCONFIG14,   0x11, 0x01},
+  {VIF_CLKCONFIG15,   0x11, 0x01},
+  {VIF_CLKCONFIG16,   0x11, 0x01},
+#ifdef ISX012_NOT_USE_NSTBY
+  {INCK_SET,          0x17, 0x01}, /* INCK_SET */
+#endif
+  {FRM_FIX_SN1_2,     0xff, 0x01}, /* Fix framerate */
+  {FAST_MODECHG_EN,   0x01, 0x01},
+  {FAST_SHT_MODE_SEL, 0x01, 0x01},
+  {CAP_HALF_AE_CTRL,  0x07, 0x01}, /* HAFREL=HIGHSPEED, CAP=Auto  */
+  {HALF_AWB_CTRL,     0x01, 0x01},
+  {AESPEED_FAST,      0x0f, 0x01},
+  {FASTMOVE_TIMEOUT,  0x2d, 0x01},
+  {YGAMMA_MODE,       0x01, 0x01},
+  {INT_QLTY2,         0x50, 0x01},
+};
+
+#define ISX012_RESET_NENTRIES ARRAY_NENTRIES(g_isx012_def_init)
+
+static const uint8_t g_isx012_cxc_rgb_data[CXC_RGB_DATA_UNIT_NUM]
+                                          [CXC_RGB_DATA_UNIT_SIZE] =
+{
+  {0x01, 0x43, 0xc0, 0xf0, 0x4f, 0xfc, 0x13},  /* CXC_RGB_UNIT0  */
+  {0x80, 0x44, 0x20, 0x21, 0x48, 0x04, 0x0e},  /* CXC_RGB_UNIT1  */
+  {0x81, 0x43, 0xc0, 0x10, 0x30, 0xfc, 0x13},  /* CXC_RGB_UNIT2  */
+  {0xff, 0x04, 0x20, 0x11, 0x48, 0x08, 0x12},  /* CXC_RGB_UNIT3  */
+  {0x81, 0x43, 0xe0, 0x20, 0x48, 0x08, 0x12},  /* CXC_RGB_UNIT4  */
+  {0x80, 0x03, 0xe0, 0x00, 0x38, 0x04, 0x10},  /* CXC_RGB_UNIT5  */
+  {0x01, 0x84, 0x20, 0x21, 0x48, 0x04, 0x10},  /* CXC_RGB_UNIT6  */
+  {0x01, 0x04, 0xc0, 0x10, 0x20, 0x00, 0x08},  /* CXC_RGB_UNIT7  */
+  {0x81, 0x82, 0xc0, 0x20, 0x38, 0x08, 0x0e},  /* CXC_RGB_UNIT8  */
+  {0x01, 0x43, 0xc0, 0x10, 0x20, 0x04, 0x04},  /* CXC_RGB_UNIT9  */
+  {0x01, 0x41, 0x40, 0x10, 0x20, 0x08, 0x0a},  /* CXC_RGB_UNIT10 */
+  {0x82, 0x82, 0x80, 0x20, 0x20, 0x04, 0x04},  /* CXC_RGB_UNIT11 */
+  {0x82, 0x80, 0x20, 0x20, 0x08, 0x04, 0x06},  /* CXC_RGB_UNIT12 */
+  {0x81, 0x42, 0xa0, 0x10, 0x20, 0x04, 0x08},  /* CXC_RGB_UNIT13 */
+  {0x81, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00},  /* CXC_RGB_UNIT14 */
+  {0x01, 0x41, 0x80, 0x10, 0x20, 0x00, 0x08},  /* CXC_RGB_UNIT15 */
+  {0x00, 0x42, 0x20, 0x20, 0x08, 0x08, 0x00},  /* CXC_RGB_UNIT16 */
+  {0x82, 0xc0, 0x40, 0x20, 0x20, 0x08, 0x08},  /* CXC_RGB_UNIT17 */
+  {0x80, 0x02, 0xa0, 0x10, 0x20, 0x08, 0x04},  /* CXC_RGB_UNIT18 */
+  {0x02, 0x81, 0x60, 0x30, 0x20, 0x08, 0x0a},  /* CXC_RGB_UNIT19 */
+  {0x82, 0x42, 0xc0, 0x10, 0x30, 0x04, 0x0a},  /* CXC_RGB_UNIT20 */
+  {0x03, 0xc3, 0xa0, 0x40, 0x28, 0x0c, 0x0a},  /* CXC_RGB_UNIT21 */
+  {0x03, 0xc3, 0xc0, 0x20, 0x20, 0x08, 0x08},  /* CXC_RGB_UNIT22 */
+  {0x82, 0xc2, 0xc0, 0x30, 0x40, 0x10, 0x0e},  /* CXC_RGB_UNIT23 */
+  {0x84, 0x03, 0xa1, 0x40, 0x28, 0x08, 0x08},  /* CXC_RGB_UNIT24 */
+  {0x02, 0x82, 0xa0, 0x30, 0x30, 0x0c, 0x10},  /* CXC_RGB_UNIT25 */
+  {0x84, 0x03, 0xe1, 0x40, 0x28, 0x10, 0x0a},  /* CXC_RGB_UNIT26 */
+};
+
+static const uint8_t g_isx012_cxc_grb_data[CXC_GRB_DATA_UNIT_NUM]
+                                          [CXC_GRB_DATA_UNIT_SIZE] =
+{
+  {0x00, 0x3d, 0x40, 0x0f, 0xc0, 0x03, 0xf2},  /* CXC_GRB_UNIT0  */
+  {0x80, 0x7c, 0x80, 0x1f, 0xd8, 0x03, 0xf0},  /* CXC_GRB_UNIT1  */
+  {0x00, 0x3c, 0x40, 0x0f, 0xd0, 0x03, 0xf0},  /* CXC_GRB_UNIT2  */
+  {0x80, 0x3c, 0x20, 0x1f, 0xe0, 0x07, 0xf6},  /* CXC_GRB_UNIT3  */
+  {0x00, 0x3c, 0x00, 0x1f, 0xd0, 0x07, 0xf4},  /* CXC_GRB_UNIT4  */
+  {0x00, 0x3d, 0x40, 0x0f, 0xc8, 0x03, 0xf2},  /* CXC_GRB_UNIT5  */
+  {0x80, 0xfc, 0x5f, 0xff, 0xd7, 0x07, 0xf4},  /* CXC_GRB_UNIT6  */
+  {0x01, 0x7d, 0x40, 0x0f, 0xd0, 0xff, 0xf3},  /* CXC_GRB_UNIT7  */
+  {0x7f, 0xfd, 0x3f, 0x0f, 0xc8, 0x03, 0xf2},  /* CXC_GRB_UNIT8  */
+  {0x81, 0x7c, 0x20, 0x0f, 0xd0, 0xff, 0xf7},  /* CXC_GRB_UNIT9  */
+  {0x7e, 0xfe, 0x5f, 0x0f, 0xd8, 0x03, 0xf6},  /* CXC_GRB_UNIT10 */
+  {0x80, 0xbd, 0xa0, 0x2f, 0xe8, 0x07, 0xfa},  /* CXC_GRB_UNIT11 */
+  {0x80, 0xfe, 0xbf, 0x0f, 0xe8, 0xff, 0xf9},  /* CXC_GRB_UNIT12 */
+  {0x00, 0x3e, 0x80, 0x3f, 0xe8, 0x0f, 0xfa},  /* CXC_GRB_UNIT13 */
+  {0x02, 0x40, 0xe0, 0x0f, 0xf8, 0x03, 0xfe},  /* CXC_GRB_UNIT14 */
+  {0x80, 0x7f, 0xe0, 0x1f, 0xf8, 0x17, 0xfe},  /* CXC_GRB_UNIT15 */
+  {0x85, 0xff, 0xe0, 0x2f, 0x08, 0x04, 0x04},  /* CXC_GRB_UNIT16 */
+  {0x81, 0x40, 0x20, 0x20, 0x00, 0x08, 0x00},  /* CXC_GRB_UNIT17 */
+  {0x84, 0x00, 0x21, 0x30, 0x10, 0x0c, 0x06},  /* CXC_GRB_UNIT18 */
+  {0x02, 0x82, 0x40, 0x20, 0x10, 0x0c, 0x02},  /* CXC_GRB_UNIT19 */
+  {0x83, 0x00, 0x21, 0x40, 0x08, 0x10, 0x06},  /* CXC_GRB_UNIT20 */
+  {0x83, 0x82, 0xa0, 0x20, 0x20, 0x08, 0x08},  /* CXC_GRB_UNIT21 */
+  {0x02, 0x81, 0x40, 0x30, 0x18, 0x0c, 0x06},  /* CXC_GRB_UNIT22 */
+  {0x03, 0x81, 0x80, 0x10, 0x20, 0x04, 0x08},  /* CXC_GRB_UNIT23 */
+  {0x82, 0x82, 0x80, 0x20, 0x20, 0x0c, 0x06},  /* CXC_GRB_UNIT24 */
+  {0x83, 0xc1, 0x40, 0x20, 0x20, 0x04, 0x08},  /* CXC_GRB_UNIT25 */
+  {0x01, 0x82, 0xa0, 0x20, 0x20, 0x08, 0x08},  /* CXC_GRB_UNIT26 */
+};
+
+static const uint8_t g_isx012_shd_rgb_data[SHD_RGB_DATA_UNIT_NUM]
+                                          [SHD_RGB_DATA_UNIT_SIZE] =
+{
+  {0xf1, 0x59, 0x52, 0x7b, 0x98, 0xc4, 0x9d, 0x23, 0x29, 0x87, 0x46}, /* SHD_RGB_UNIT0  */
+  {0xc6, 0x81, 0xd1, 0x70, 0x56, 0xe4, 0x9c, 0x1b, 0x6d, 0x07, 0x48}, /* SHD_RGB_UNIT1  */
+  {0xdd, 0xf1, 0x51, 0x7d, 0xa8, 0xb4, 0x1e, 0x25, 0x49, 0xc7, 0x46}, /* SHD_RGB_UNIT2  */
+  {0xbd, 0xf1, 0x50, 0x6d, 0x2a, 0x44, 0x1b, 0x0a, 0x01, 0x87, 0x44}, /* SHD_RGB_UNIT3  */
+  {0xd0, 0xa9, 0x51, 0x77, 0x84, 0xd4, 0x9d, 0x1f, 0x2d, 0xc7, 0x44}, /* SHD_RGB_UNIT4  */
+  {0xa8, 0xa9, 0xcf, 0x62, 0x98, 0xa3, 0x17, 0xdb, 0xfc, 0x05, 0x38}, /* SHD_RGB_UNIT5  */
+  {0x90, 0xe1, 0x8e, 0x6a, 0x08, 0xc4, 0x9b, 0x0e, 0x11, 0x07, 0x43}, /* SHD_RGB_UNIT6  */
+  {0xac, 0xa9, 0x4f, 0x5d, 0x4e, 0x13, 0x15, 0xb9, 0xf8, 0x44, 0x2b}, /* SHD_RGB_UNIT7  */
+  {0x44, 0x21, 0xcb, 0x56, 0x0e, 0x63, 0x98, 0xe3, 0x78, 0x86, 0x3d}, /* SHD_RGB_UNIT8  */
+  {0xab, 0x81, 0x4f, 0x62, 0x7c, 0xc3, 0x94, 0xb4, 0x98, 0x84, 0x26}, /* SHD_RGB_UNIT9  */
+  {0x14, 0xe9, 0x48, 0x46, 0x4a, 0x12, 0x93, 0xa4, 0x84, 0xc5, 0x31}, /* SHD_RGB_UNIT10 */
+  {0x81, 0xe9, 0x4d, 0x67, 0xac, 0x73, 0x17, 0xd0, 0xdc, 0x24, 0x29}, /* SHD_RGB_UNIT11 */
+  {0x12, 0xb9, 0x08, 0x40, 0x02, 0x52, 0x10, 0x84, 0x6c, 0x64, 0x25}, /* SHD_RGB_UNIT12 */
+  {0x4c, 0x91, 0xcb, 0x5b, 0x4c, 0xe3, 0x19, 0xec, 0xdc, 0x05, 0x34}, /* SHD_RGB_UNIT13 */
+  {0x37, 0x39, 0x8a, 0x44, 0x2a, 0x02, 0x10, 0x80, 0x14, 0xe4, 0x20}, /* SHD_RGB_UNIT14 */
+  {0x1c, 0x51, 0x49, 0x53, 0xe4, 0x02, 0x17, 0xd3, 0xb8, 0xe6, 0x3d}, /* SHD_RGB_UNIT15 */
+  {0x8b, 0xd9, 0x8d, 0x53, 0xc8, 0x72, 0x12, 0x98, 0x50, 0x24, 0x23}, /* SHD_RGB_UNIT16 */
+  {0x19, 0x11, 0x89, 0x4c, 0x8c, 0x32, 0x16, 0xc7, 0x14, 0x06, 0x38}, /* SHD_RGB_UNIT17 */
+  {0xca, 0xc1, 0x10, 0x6c, 0xe0, 0x83, 0x97, 0xd0, 0x4c, 0xa5, 0x2d}, /* SHD_RGB_UNIT18 */
+  {0x3e, 0x99, 0x0a, 0x51, 0xbc, 0xc2, 0x15, 0xc2, 0x28, 0x26, 0x39}, /* SHD_RGB_UNIT19 */
+  {0xa5, 0x89, 0x0f, 0x7b, 0x8c, 0x64, 0x9d, 0x14, 0xb9, 0x46, 0x3e}, /* SHD_RGB_UNIT20 */
+  {0x8f, 0x41, 0xce, 0x5e, 0x5e, 0x03, 0x98, 0xdc, 0x50, 0xe6, 0x3a}, /* SHD_RGB_UNIT21 */
+  {0xb4, 0x49, 0x90, 0x72, 0x50, 0x74, 0xa1, 0x3a, 0x05, 0x88, 0x4b}, /* SHD_RGB_UNIT22 */
+  {0xe1, 0xd1, 0x91, 0x71, 0x38, 0xc4, 0x1b, 0x0a, 0xed, 0x86, 0x42}, /* SHD_RGB_UNIT23 */
+  {0xcb, 0x49, 0xd1, 0x78, 0x86, 0x74, 0x9f, 0x2d, 0xb9, 0x88, 0x51}, /* SHD_RGB_UNIT24 */
+  {0x11, 0x62, 0x93, 0x7c, 0x9c, 0x94, 0x1d, 0x1b, 0x41, 0x67, 0x46}, /* SHD_RGB_UNIT25 */
+  {0xcf, 0x81, 0x91, 0x77, 0x82, 0x54, 0x9f, 0x2a, 0x21, 0xa8, 0x4d}, /* SHD_RGB_UNIT26 */
+};
+
+static const uint8_t g_isx012_shd_grb_data[SHD_GRB_DATA_UNIT_NUM]
+                                          [SHD_GRB_DATA_UNIT_SIZE] =
+{
+  {0xe8, 0xa9, 0x0f, 0x78, 0xe4, 0x13, 0x9d, 0xf0, 0x04, 0xe7, 0x39}, /* SHD_GRB_UNIT0  */
+  {0xbd, 0x51, 0x0e, 0x6f, 0x94, 0x63, 0x1c, 0xea, 0x4c, 0x27, 0x3c}, /* SHD_GRB_UNIT1  */
+  {0xd7, 0x19, 0x4f, 0x7a, 0xf4, 0xd3, 0x1d, 0xf7, 0x20, 0xe7, 0x3a}, /* SHD_GRB_UNIT2  */
+  {0xb6, 0x11, 0x0e, 0x6c, 0x76, 0x03, 0x9b, 0xdd, 0xf0, 0x06, 0x39}, /* SHD_GRB_UNIT3  */
+  {0xc9, 0xc1, 0x8e, 0x75, 0xc8, 0xe3, 0x9c, 0xef, 0xf8, 0xa6, 0x39}, /* SHD_GRB_UNIT4  */
+  {0xa0, 0x69, 0x0d, 0x62, 0x20, 0x93, 0x97, 0xbf, 0xf4, 0xa5, 0x30}, /* SHD_GRB_UNIT5  */
+  {0x8c, 0xb1, 0x8c, 0x68, 0x60, 0x13, 0x9b, 0xe0, 0xcc, 0xa6, 0x38}, /* SHD_GRB_UNIT6  */
+  {0x9f, 0x71, 0x0d, 0x5c, 0xf4, 0x12, 0x15, 0xab, 0x00, 0x65, 0x28}, /* SHD_GRB_UNIT7  */
+  {0x44, 0x41, 0x0a, 0x56, 0xbc, 0x02, 0x98, 0xc4, 0x50, 0x26, 0x34}, /* SHD_GRB_UNIT8  */
+  {0x9a, 0x59, 0x4d, 0x5f, 0x16, 0x83, 0x14, 0xa8, 0x9c, 0x64, 0x25}, /* SHD_GRB_UNIT9  */
+  {0x15, 0xc1, 0xc8, 0x46, 0x38, 0x22, 0x13, 0x9a, 0x74, 0x65, 0x2c}, /* SHD_GRB_UNIT10 */
+  {0x78, 0x11, 0x4c, 0x63, 0x36, 0xb3, 0x96, 0xbb, 0xcc, 0x44, 0x27}, /* SHD_GRB_UNIT11 */
+  {0x11, 0xa1, 0x48, 0x40, 0x04, 0x72, 0x10, 0x83, 0x70, 0x84, 0x23}, /* SHD_GRB_UNIT12 */
+  {0x4a, 0x69, 0xca, 0x59, 0xe0, 0xf2, 0x98, 0xcc, 0xb0, 0xa5, 0x2e}, /* SHD_GRB_UNIT13 */
+  {0x33, 0xc1, 0x09, 0x44, 0x24, 0x02, 0x10, 0x80, 0x14, 0x84, 0x20}, /* SHD_GRB_UNIT14 */
+  {0x1b, 0xd1, 0x48, 0x52, 0x98, 0x72, 0x96, 0xb7, 0x8c, 0x06, 0x35}, /* SHD_GRB_UNIT15 */
+  {0x81, 0x39, 0xcc, 0x51, 0x96, 0x32, 0x92, 0x92, 0x48, 0x44, 0x22}, /* SHD_GRB_UNIT16 */
+  {0x17, 0xb9, 0x48, 0x4b, 0x5e, 0xa2, 0x15, 0xb0, 0xd8, 0x45, 0x30}, /* SHD_GRB_UNIT17 */
+  {0xc0, 0x19, 0xce, 0x69, 0x56, 0x23, 0x97, 0xba, 0x38, 0x05, 0x2a}, /* SHD_GRB_UNIT18 */
+  {0x3b, 0xe1, 0x09, 0x50, 0x82, 0x42, 0x95, 0xac, 0xf8, 0x05, 0x31}, /* SHD_GRB_UNIT19 */
+  {0x94, 0x19, 0x4d, 0x78, 0xca, 0xe3, 0x9c, 0xe8, 0xa8, 0xa6, 0x35}, /* SHD_GRB_UNIT20 */
+  {0x8b, 0x71, 0xcc, 0x5d, 0xf8, 0xa2, 0x97, 0xc0, 0x24, 0xa6, 0x32}, /* SHD_GRB_UNIT21 */
+  {0xa4, 0xb1, 0x8d, 0x6d, 0x96, 0xd3, 0xa0, 0x09, 0xe1, 0xa7, 0x3f}, /* SHD_GRB_UNIT22 */
+  {0xde, 0x09, 0xcf, 0x70, 0x92, 0x73, 0x9b, 0xe0, 0xcc, 0x06, 0x38}, /* SHD_GRB_UNIT23 */
+  {0xc0, 0x89, 0x4e, 0x74, 0xcc, 0x13, 0x1e, 0xfc, 0x84, 0x48, 0x45}, /* SHD_GRB_UNIT24 */
+  {0x06, 0x7a, 0xd0, 0x7a, 0xe6, 0x33, 0x1d, 0xef, 0x24, 0x07, 0x3b}, /* SHD_GRB_UNIT25 */
+  {0xc4, 0xb1, 0x0e, 0x74, 0xca, 0x33, 0x1e, 0xfc, 0xc4, 0x07, 0x41}, /* SHD_GRB_UNIT26 */
+};
+
+static const uint8_t g_isx012_shd_r1_data[SHD_R1_DATA_UNIT_NUM]
+                                         [SHD_R1_DATA_UNIT_SIZE] =
+{
+  {0x10, 0x92, 0x10, 0x82, 0xf8, 0x43, 0x1f, 0xfb, 0xf0, 0xe7, 0x40}, /* SHD_R1_UNIT0   */
+  {0x07, 0x92, 0xd0, 0x82, 0xec, 0x33, 0x9e, 0xed, 0x68, 0xe7, 0x3c}, /* SHD_R1_UNIT1   */
+  {0xfa, 0x21, 0xd0, 0x7e, 0xce, 0xa3, 0x1b, 0xcd, 0x20, 0xe6, 0x31}, /* SHD_R1_UNIT2   */
+  {0xa6, 0x69, 0xce, 0x78, 0xbc, 0xa3, 0x1b, 0xbe, 0x44, 0x25, 0x28}, /* SHD_R1_UNIT3   */
+  {0x45, 0x19, 0xcb, 0x65, 0x78, 0xe3, 0x1b, 0xc8, 0x3c, 0xa5, 0x24}, /* SHD_R1_UNIT4   */
+  {0x15, 0xc1, 0x48, 0x4d, 0xd6, 0x72, 0x99, 0xd3, 0xdc, 0x25, 0x27}, /* SHD_R1_UNIT5   */
+  {0x11, 0x01, 0x08, 0x41, 0x42, 0x42, 0x15, 0xc1, 0xa4, 0x06, 0x2f}, /* SHD_R1_UNIT6   */
+  {0x39, 0x89, 0x08, 0x40, 0x0a, 0x22, 0x12, 0xab, 0x0c, 0x26, 0x38}, /* SHD_R1_UNIT7   */
+  {0x91, 0x71, 0x4a, 0x49, 0x2c, 0xa2, 0x11, 0x9c, 0xc4, 0xa5, 0x33}, /* SHD_R1_UNIT8   */
+  {0xe2, 0xe1, 0x4d, 0x5f, 0xa4, 0x22, 0x94, 0xa3, 0xa0, 0x05, 0x34}, /* SHD_R1_UNIT9   */
+  {0xc7, 0x41, 0x50, 0x7c, 0x7e, 0xd3, 0x19, 0xc5, 0x48, 0x86, 0x35}, /* SHD_R1_UNIT10  */
+  {0xda, 0xa9, 0xcf, 0x8c, 0x42, 0x24, 0x20, 0xf5, 0x8c, 0x67, 0x3c}, /* SHD_R1_UNIT11  */
+  {0xf6, 0x89, 0xd0, 0x88, 0x90, 0x34, 0x23, 0x0b, 0x15, 0xa8, 0x3f}, /* SHD_R1_UNIT12  */
+  {0x00, 0x72, 0x10, 0x89, 0x68, 0x04, 0x69, 0x00, 0x00, 0x19, 0x26}, /* SHD_R1_UNIT13  */
+};
+
+static const uint8_t g_isx012_shd_r2_data[SHD_R2_DATA_UNIT_NUM]
+                                         [SHD_R2_DATA_UNIT_SIZE] =
+{
+  {0x3a, 0xe2, 0x11, 0x8c, 0x42, 0x74, 0xa1, 0x0c, 0x89, 0x08, 0x46}, /* SHD_R2_UNIT0   */
+  {0x30, 0xe2, 0xd1, 0x8c, 0x36, 0x54, 0x20, 0xfe, 0xec, 0x47, 0x41}, /* SHD_R2_UNIT1   */
+  {0x20, 0x5a, 0x91, 0x88, 0x16, 0x94, 0x1d, 0xda, 0x80, 0x26, 0x35}, /* SHD_R2_UNIT2   */
+  {0xc2, 0x69, 0x0f, 0x81, 0x00, 0x94, 0x9d, 0xc9, 0x84, 0xe5, 0x29}, /* SHD_R2_UNIT3   */
+  {0x54, 0xb1, 0x0b, 0x6c, 0xb2, 0xb3, 0x9d, 0xd4, 0x74, 0x85, 0x25}, /* SHD_R2_UNIT4   */
+  {0x1a, 0xf1, 0x08, 0x50, 0xfc, 0xe2, 0x1a, 0xe0, 0x2c, 0x66, 0x28}, /* SHD_R2_UNIT5   */
+  {0x14, 0x01, 0x88, 0x41, 0x4e, 0x32, 0x16, 0xcb, 0x08, 0x87, 0x31}, /* SHD_R2_UNIT6   */
+  {0x42, 0x99, 0x08, 0x40, 0x0c, 0x72, 0x92, 0xb1, 0x58, 0x86, 0x3b}, /* SHD_R2_UNIT7   */
+  {0xa8, 0xd9, 0xca, 0x4a, 0x32, 0xe2, 0x91, 0xa0, 0x04, 0x66, 0x36}, /* SHD_R2_UNIT8   */
+  {0x02, 0xc2, 0x4e, 0x64, 0xbe, 0xd2, 0x94, 0xa9, 0xe0, 0xc5, 0x36}, /* SHD_R2_UNIT9   */
+  {0xe1, 0x61, 0x91, 0x84, 0xb6, 0x43, 0x9b, 0xcf, 0x9c, 0x66, 0x38}, /* SHD_R2_UNIT10  */
+  {0xf6, 0xa1, 0x50, 0x97, 0x8e, 0x34, 0x22, 0x04, 0x01, 0x08, 0x40}, /* SHD_R2_UNIT11  */
+  {0x15, 0x9a, 0x51, 0x92, 0xf2, 0xd4, 0xa5, 0x1d, 0x99, 0xa8, 0x43}, /* SHD_R2_UNIT12  */
+  {0x21, 0x82, 0x91, 0x92, 0xbe, 0xf4, 0x9e, 0xf3, 0x4c, 0x87, 0x38}, /* SHD_R2_UNIT13  */
+};
+
+static const uint8_t g_isx012_shd_b2_data[SHD_B2_DATA_UNIT_NUM]
+                                         [SHD_B2_DATA_UNIT_SIZE] =
+{
+  {0xef, 0x39, 0xcf, 0x74, 0x88, 0xb3, 0x1b, 0xdf, 0x20, 0x47, 0x3b}, /* SHD_B2_UNIT0   */
+  {0xdf, 0x59, 0xcf, 0x77, 0x8c, 0x43, 0x1b, 0xd7, 0xb8, 0x46, 0x37}, /* SHD_B2_UNIT1   */
+  {0xcc, 0xc1, 0x0e, 0x73, 0x78, 0xa3, 0x99, 0xc1, 0xd0, 0x25, 0x2f}, /* SHD_B2_UNIT2   */
+  {0x87, 0x09, 0x0d, 0x6c, 0x64, 0x93, 0x99, 0xb6, 0x30, 0xc5, 0x27}, /* SHD_B2_UNIT3   */
+  {0x3f, 0xb1, 0x0a, 0x5f, 0x2a, 0x93, 0x99, 0xbc, 0x1c, 0x85, 0x24}, /* SHD_B2_UNIT4   */
+  {0x16, 0xc9, 0x48, 0x4c, 0xb6, 0x92, 0x17, 0xc4, 0x94, 0x85, 0x26}, /* SHD_B2_UNIT5   */
+  {0x10, 0x09, 0x88, 0x41, 0x3a, 0x52, 0x94, 0xb2, 0x2c, 0xc6, 0x2c}, /* SHD_B2_UNIT6   */
+  {0x33, 0x79, 0x08, 0x40, 0x08, 0xc2, 0x11, 0xa2, 0x94, 0x65, 0x34}, /* SHD_B2_UNIT7   */
+  {0x7e, 0x39, 0x4a, 0x48, 0x26, 0x52, 0x91, 0x96, 0x64, 0x05, 0x2f}, /* SHD_B2_UNIT8   */
+  {0xbf, 0x09, 0x8d, 0x5b, 0x92, 0xa2, 0x93, 0x9d, 0x4c, 0x65, 0x2f}, /* SHD_B2_UNIT9   */
+  {0x95, 0xf9, 0x0e, 0x73, 0x48, 0x63, 0x98, 0xb9, 0xd8, 0xa5, 0x30}, /* SHD_B2_UNIT10  */
+  {0xa5, 0xb1, 0x8d, 0x83, 0xf4, 0xa3, 0x1d, 0xe0, 0xd0, 0x06, 0x36}, /* SHD_B2_UNIT11  */
+  {0xbe, 0xa9, 0x4e, 0x79, 0x50, 0xd4, 0x20, 0xf6, 0x54, 0xa7, 0x38}, /* SHD_B2_UNIT12  */
+  {0xc5, 0x91, 0xce, 0x7a, 0xf4, 0x03, 0x44, 0x00, 0x60, 0x60, 0x00}, /* SHD_B2_UNIT13  */
+};
+
+static const isx012_reg_t g_isx012_shd_thresholds[] =
+{
+  {SHD_INP_TH_HB_H_R2, 0x1478, 2},
+  {SHD_INP_TH_HB_L_R2, 0x1380, 2},
+  {SHD_INP_TH_LB_H_R2, 0x10cc, 2},
+  {SHD_INP_TH_LB_L_R2, 0x1004, 2},
+  {SHD_INP_TH_HB_H_RB, 0x10cc, 2},
+  {SHD_INP_TH_HB_L_RB, 0x1004, 2},
+  {SHD_INP_TH_LB_H_RB, 0x0000, 2},
+  {SHD_INP_TH_LB_L_RB, 0x0000, 2},
+};
+
+#define ISX012_SHD_THRESHOLDS_NENTRIES ARRAY_NENTRIES(g_isx012_shd_thresholds)
+
+static const isx012_reg_t g_isx012_shd_wb[] =
+{
+  {NORMR,              0x1101, 2},
+  {NORMB,              0x0f7b, 2},
+  {AWBPRER,            0x0147, 2},
+  {AWBPREB,            0x022a, 2},
+  {SHD_PRER_OFFSET_R2, 0x001b, 2},
+  {SHD_PRER_OFFSET_RB, 0x000b, 2},
+  {SHD_PREB_OFFSET_RB, 0x0003, 2},
+};
+
+#define ISX012_SHD_WB_NENTRIES ARRAY_NENTRIES(g_isx012_shd_wb)
+
+static int32_t g_isx012_colorfx_actual[] =
+{
+  IMGSENSOR_COLORFX_NONE,
+  IMGSENSOR_COLORFX_BW,
+  IMGSENSOR_COLORFX_SEPIA,
+  IMGSENSOR_COLORFX_NEGATIVE,
+  IMGSENSOR_COLORFX_SKETCH,
+  IMGSENSOR_COLORFX_SOLARIZATION,
+  IMGSENSOR_COLORFX_PASTEL
+};
+
+static uint8_t g_isx012_colorfx_regval[] =
+{
+  REGVAL_EFFECT_NONE,
+  REGVAL_EFFECT_MONOTONE,
+  REGVAL_EFFECT_SEPIA,
+  REGVAL_EFFECT_NEGPOS,
+  REGVAL_EFFECT_SKETCH,
+  REGVAL_EFFECT_SOLARIZATION,
+  REGVAL_EFFECT_PASTEL
+};
+
+static int32_t g_isx012_presetwb_actual[] =
+{
+  IMGSENSOR_WHITE_BALANCE_AUTO,
+  IMGSENSOR_WHITE_BALANCE_INCANDESCENT,
+  IMGSENSOR_WHITE_BALANCE_FLUORESCENT,
+  IMGSENSOR_WHITE_BALANCE_DAYLIGHT,
+  IMGSENSOR_WHITE_BALANCE_CLOUDY,
+  IMGSENSOR_WHITE_BALANCE_SHADE
+};
+
+static uint8_t g_isx012_presetwb_regval[] =
+{
+  REGVAL_AWB_ATM,
+  REGVAL_AWB_LIGHTBULB,
+  REGVAL_AWB_FLUORESCENTLIGHT,
+  REGVAL_AWB_CLEARWEATHER,
+  REGVAL_AWB_CLOUDYWEATHER,
+  REGVAL_AWB_SHADE
+};
+
+static int32_t g_isx012_photometry_actual[] =
+{
+  IMGSENSOR_EXPOSURE_METERING_AVERAGE,
+  IMGSENSOR_EXPOSURE_METERING_CENTER_WEIGHTED,
+  IMGSENSOR_EXPOSURE_METERING_SPOT,
+  IMGSENSOR_EXPOSURE_METERING_MATRIX
+};
+
+static uint8_t g_isx012_photometry_regval[] =
+{
+  REGVAL_PHOTOMETRY_AVERAGE,
+  REGVAL_PHOTOMETRY_CENTERWEIGHT,
+  REGVAL_PHOTOMETRY_SPOT,
+  REGVAL_PHOTOMETRY_MULTIPATTERN
+};
+
+static int32_t g_isx012_iso_actual[] =
+{
+  25 * 1000,
+  32 * 1000,
+  40 * 1000,
+  50 * 1000,
+  64 * 1000,
+  80 * 1000,
+  100 * 1000,
+  125 * 1000,
+  160 * 1000,
+  200 * 1000,
+  250 * 1000,
+  320 * 1000,
+  400 * 1000,
+  500 * 1000,
+  640 * 1000,
+  800 * 1000,
+  1000 * 1000,
+  1250 * 1000,
+  1600 * 1000
+};
+
+static uint8_t g_isx012_iso_regval[] =
+{
+  REGVAL_ISO_25,
+  REGVAL_ISO_32,
+  REGVAL_ISO_40,
+  REGVAL_ISO_50,
+  REGVAL_ISO_64,
+  REGVAL_ISO_80,
+  REGVAL_ISO_100,
+  REGVAL_ISO_125,
+  REGVAL_ISO_160,
+  REGVAL_ISO_200,
+  REGVAL_ISO_250,
+  REGVAL_ISO_320,
+  REGVAL_ISO_400,
+  REGVAL_ISO_500,
+  REGVAL_ISO_640,
+  REGVAL_ISO_800,
+  REGVAL_ISO_1000,
+  REGVAL_ISO_1250,
+  REGVAL_ISO_1600
+};
+
+static struct imgsensor_ops_s g_isx012_ops =
+{
+  .init                   = isx012_init,
+  .uninit                 = isx012_uninit,
+  .validate_frame_setting = isx012_validate_frame_setting,
+  .start_capture          = isx012_start_capture,
+  .stop_capture           = isx012_stop_capture,
+  .get_supported_value    = isx012_get_supported_value,
+  .get_value              = isx012_get_value,
+  .set_value              = isx012_set_value,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint16_t isx012_getreg(isx012_dev_t *priv,
+                              uint16_t regaddr, uint16_t regsize)
+{
+  struct i2c_config_s config;
+  volatile uint16_t regval = 0;
+  volatile uint8_t buffer[2];
+  int ret;
+
+  /* Set up the I2C configuration */
+
+  config.frequency = priv->i2c_freq;
+  config.address   = priv->i2c_addr;
+  config.addrlen   = 7;
+  buffer[0] = regaddr >> 8;
+  buffer[1] = regaddr & 0xff;
+
+  /* Write the register address */
+
+  ret = i2c_write(priv->i2c, &config, (uint8_t *)buffer, 2);
+  if (ret < 0)
+    {
+      imagererr("i2c_write failed: %d\n", ret);
+      return 0;
+    }
+
+  /* Restart and read 16bits from the register */
+
+  ret = i2c_read(priv->i2c, &config, (uint8_t *)buffer, regsize);
+  if (ret < 0)
+    {
+      imagererr("i2c_read failed: %d\n", ret);
+      return 0;
+    }
+
+  memcpy((uint8_t *)&regval, (uint8_t *)buffer, regsize);
+
+  return regval;
+}
+
+static int isx012_putreg(isx012_dev_t *priv,
+                         uint16_t regaddr, uint16_t regval, uint16_t regsize)
+{
+  struct i2c_config_s config;
+  volatile uint8_t buffer[4];
+  int ret;
+
+  /* Set up the I2C configuration */
+
+  config.frequency = priv->i2c_freq;
+  config.address   = priv->i2c_addr;
+  config.addrlen   = 7;
+
+  /* Set up for the transfer */
+
+  buffer[0] = regaddr >> 8;   /* RegAddr Hi */
+  buffer[1] = regaddr & 0xff; /* RegAddr Low */
+
+  memcpy((uint8_t *)&buffer[2], (uint8_t *)&regval, regsize);
+
+  /* And do it */
+
+  ret = i2c_write(priv->i2c, &config,
+                 (uint8_t *)buffer, regsize + 2);
+  if (ret < 0)
+    {
+      imagererr("i2c_write failed: %d\n", ret);
+    }
+
+  return ret;
+}
+
+static int isx012_putreglist(isx012_dev_t *priv,
+                             FAR const isx012_reg_t *reglist,
+                             size_t nentries)
+{
+  FAR const isx012_reg_t *entry;
+  int ret = OK;
+
+  for (entry = reglist; nentries > 0; nentries--, entry++)
+    {
+      ret = isx012_putreg(priv, entry->regaddr,
+                          entry->regval, entry->regsize);
+      if (ret < 0)
+        {
+          imagererr("isx012_putreg failed: %d\n", ret);
+          return ret;
+        }
+    }
+
+  return ret;
+}
+
+static int isx012_chk_int_state(isx012_dev_t *priv,
+                                uint8_t sts, uint32_t delay_time,
+                                uint32_t wait_time, uint32_t timeout)
+{
+  int ret = 0;
+  volatile uint8_t data;
+  uint32_t time = 0;
+
+  nxsig_usleep(delay_time * 1000);
+  while (time < timeout)
+    {
+      data = isx012_getreg(priv, INTSTS0, sizeof(data));
+      data = data & sts;
+      if (data != 0)
+        {
+          ret = isx012_putreg(priv, INTCLR0, data, sizeof(data));
+          return ret;
+        }
+
+      nxsig_usleep(wait_time * 1000);
+      time += wait_time;
+    }
+
+  return ERROR;
+}
+
+static int isx012_replace_fmt_to_regval(uint8_t nr_fmt,
+                                        imgsensor_format_t *fmt)
+{
+  int ret;
+
+  if (fmt == NULL)
+    {
+      return -EINVAL;
+    }
+
+  switch (fmt[IMGSENSOR_FMT_MAIN].pixelformat)
+    {
+      case IMGSENSOR_PIX_FMT_UYVY:
+        ret = REGVAL_OUTFMT_YUV;
+        break;
+
+      case IMGSENSOR_PIX_FMT_RGB565:
+        ret = REGVAL_OUTFMT_RGB;
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG:
+        ret = REGVAL_OUTFMT_JPEG;
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG_WITH_SUBIMG:
+        if (nr_fmt == 1)
+          {
+            ret = REGVAL_OUTFMT_JPEG;
+          }
+        else
+          {
+            ret = REGVAL_OUTFMT_INTERLEAVE;
+          }
+
+        break;
+
+      default:  /* Unsupported format */
+
+        ret = -EINVAL;
+    }
+
+  return ret;
+}
+
+static bool is_movie_needed(uint8_t fmt, uint8_t fps)
+{
+  bool need = true;
+
+  if ((fmt == IMGSENSOR_PIX_FMT_UYVY) ||
+      (fmt == IMGSENSOR_PIX_FMT_RGB565))
+    {
+      if (fps >= REGVAL_FPSTYPE_30FPS)   /* This means fps <= 30 */
+        {
+          need = false;
+        }
+    }
+
+  return need;
+}
+
+static int isx012_set_mode_param(isx012_dev_t *priv,
+                                 imgsensor_stream_type_t type,
+                                 uint8_t nr_fmt,
+                                 imgsensor_format_t *fmt,
+                                 imgsensor_interval_t *interval)
+{
+  int ret = 0;
+  int fmt_val = isx012_replace_fmt_to_regval(nr_fmt, fmt);
+  int fps_val = isx012_replace_frameinterval_to_regval(interval);
+  uint16_t fps_addr;
+  uint16_t fmt_addr;
+  uint16_t smode_addr;
+  uint16_t hsize_addr;
+  uint16_t vsize_addr;
+  uint8_t  smode;
+  uint8_t  mode;
+
+  /* Get register address for type  */
+
+  if (type == IMGSENSOR_STREAM_TYPE_VIDEO)
+    {
+      if (is_movie_needed(fmt_val, fps_val))
+        {
+          if (priv->mode == REGVAL_MODESEL_HREL)
+            {
+              /* In Half release state,
+               * the setting which need movie mode is prohibited.
+               */
+
+              return -EPERM;
+            }
+
+          fps_addr   = FPSTYPE_MOVIE;
+          fmt_addr   = OUTFMT_MOVIE;
+          smode_addr = SENSMODE_MOVIE;
+          hsize_addr = HSIZE_MOVIE;
+          vsize_addr = VSIZE_MOVIE;
+          mode       = REGVAL_MODESEL_MOV;
+        }
+      else
+        {
+          fps_addr   = FPSTYPE_MONI;
+          fmt_addr   = OUTFMT_MONI;
+          smode_addr = SENSMODE_MONI;
+          hsize_addr = HSIZE_MONI;
+          vsize_addr = VSIZE_MONI;
+          mode       = REGVAL_MODESEL_MON;
+        }
+    }
+  else
+    {
+      fps_addr   = FPSTYPE_CAP;
+      fmt_addr   = OUTFMT_CAP;
+      smode_addr = SENSMODE_CAP;
+      hsize_addr = HSIZE_CAP;
+      vsize_addr = VSIZE_CAP;
+      mode       = REGVAL_MODESEL_CAP;
+    }
+
+  ret = isx012_putreg(priv, fps_addr, fps_val, sizeof(uint8_t));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = isx012_putreg(priv, fmt_addr, fmt_val, sizeof(uint8_t));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  switch (fps_val)
+    {
+      case REGVAL_FPSTYPE_120FPS:
+        smode = REGVAL_SENSMODE_1_8;
+        break;
+
+      case REGVAL_FPSTYPE_60FPS:
+        smode = REGVAL_SENSMODE_1_4;
+        break;
+
+      case REGVAL_FPSTYPE_30FPS:
+        smode = REGVAL_SENSMODE_1_2;
+        break;
+
+      default:
+        smode = REGVAL_SENSMODE_ALLPIX;
+        break;
+    }
+
+  ret = isx012_putreg(priv, smode_addr, smode, sizeof(uint8_t));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = isx012_putreg(priv,
+                      hsize_addr,
+                      fmt[IMGSENSOR_FMT_MAIN].width,
+                      sizeof(uint16_t));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = isx012_putreg(priv,
+                      vsize_addr,
+                      fmt[IMGSENSOR_FMT_MAIN].height,
+                      sizeof(uint16_t));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (fmt_val == REGVAL_OUTFMT_INTERLEAVE)
+    {
+      ret = isx012_putreg(priv,
+                          HSIZE_TN,
+                          fmt[IMGSENSOR_FMT_SUB].width,
+                          sizeof(uint16_t));
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      ret = isx012_putreg(priv,
+                          VSIZE_TN,
+                          fmt[IMGSENSOR_FMT_SUB].height,
+                          sizeof(uint16_t));
+      if (ret < 0)
+        {
+          return ret;
+        }
+    }
+
+  if (priv->state != STATE_ISX012_ACTIVE)
+    {
+      isx012_change_device_state(priv, STATE_ISX012_ACTIVE);
+    }
+
+  ret = isx012_change_camera_mode(priv, mode);
+  if (ret == OK)
+    {
+      priv->mode = mode;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * isx012_change_camera_mode
+ ****************************************************************************/
+
+static int isx012_change_camera_mode(isx012_dev_t *priv, uint8_t mode)
+{
+  int      ret = 0;
+  uint16_t fmt_addr;
+  uint8_t  fmt;
+  uint32_t vifmode;
+#ifdef ISX012_FRAME_SKIP_EN
+  uint8_t mask_num;
+  int i;
+#endif /* ISX012_FRAME_SKIP_EN */
+
+  if (priv->state != STATE_ISX012_ACTIVE)
+    {
+      return -EPERM;
+    }
+
+  switch (mode)
+    {
+      case REGVAL_MODESEL_MON:
+      case REGVAL_MODESEL_HREL:
+        fmt_addr = OUTFMT_MONI;
+        break;
+
+      case REGVAL_MODESEL_MOV:
+        fmt_addr = OUTFMT_MOVIE;
+        break;
+
+      case REGVAL_MODESEL_CAP:
+        fmt_addr = OUTFMT_CAP;
+        break;
+
+      default:
+        return -EPERM;
+    }
+
+  fmt = isx012_getreg(priv, fmt_addr, 1);
+
+  switch (fmt) /* mode parallel */
+    {
+      case REGVAL_OUTFMT_YUV:
+        vifmode = REGVAL_VIFMODE_YUV_PARALLEL;
+        break;
+      case REGVAL_OUTFMT_JPEG:
+        vifmode = REGVAL_VIFMODE_JPEG_PARALLEL;
+        break;
+      case REGVAL_OUTFMT_INTERLEAVE:
+        vifmode = REGVAL_VIFMODE_INTERLEAVE_PARALLEL;
+        break;
+      case REGVAL_OUTFMT_RGB:
+        vifmode = REGVAL_VIFMODE_RGB_PARALLEL;
+        break;
+      default:
+        vifmode = REGVAL_VIFMODE_YUV_PARALLEL;
+        break;
+    }
+
+  ret = isx012_putreg(priv, VIFMODE, vifmode, sizeof(vifmode));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (mode != isx012_getreg(priv, MODESEL, sizeof(mode)))
+    {
+      isx012_putreg(priv, INTCLR0, CM_CHANGED_STS, 1);
+
+      ret = isx012_putreg(priv, MODESEL, mode, sizeof(mode));
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      /* Wait CM_CHANGED */
+
+      ret = isx012_chk_int_state(priv,
+                                 CM_CHANGED_STS,
+                                 CAMERA_MODE_DELAY_TIME,
+                                 CAMERA_MODE_WAIT_TIME,
+                                 CAMERA_MODE_TIMEOUT);
+      if (ret != 0)
+        {
+          return ret;
+        }
+    }
+
+#ifdef ISX012_FRAME_SKIP_EN
+  if (mode != REGVAL_MODESEL_HREL)
+    {
+      isx012_putreg(priv, INTCLR0, VINT_STS, 1);
+      mask_num = isx012_getreg(priv, RO_MASK_NUM, sizeof(mask_num));
+      for (i = 0; i < mask_num; i++)
+        {
+          /* Wait Next VINT */
+
+          ret = isx012_chk_int_state(priv, VINT_STS, VINT_DELAY_TIME,
+                                           VINT_WAIT_TIME, VINT_TIMEOUT);
+          if (ret != 0)
+            {
+              return ret;
+            }
+        }
+    }
+#endif /* ISX012_FRAME_SKIP_EN */
+
+  return OK;
+}
+
+/****************************************************************************
+ * isx012_change_device_state
+ ****************************************************************************/
+
+static int isx012_change_device_state(isx012_dev_t *priv,
+                                      isx012_state_t state)
+{
+  int ret = 0;
+#ifdef ISX012_FRAME_SKIP_EN
+  int i;
+  uint8_t mute_cnt;
+#endif /* ISX012_FRAME_SKIP_EN */
+
+  if (priv->state == STATE_ISX012_PRESLEEP || priv->state == state)
+    {
+      return -EPERM;
+    }
+
+  switch (state)
+    {
+      case STATE_ISX012_SLEEP:
+        isx012_putreg(priv, INTCLR0, OM_CHANGED_STS, 1);
+        board_isx012_set_sleep(1);
+        break;
+      case STATE_ISX012_ACTIVE:
+        isx012_putreg(priv, INTCLR0, OM_CHANGED_STS | CM_CHANGED_STS, 1);
+        board_isx012_release_sleep();
+        break;
+      case STATE_ISX012_PRESLEEP:
+        return -EPERM;
+      default:
+        return -EPERM;
+    }
+
+  /* Wait OM_CHANGED */
+
+  ret = isx012_chk_int_state(priv, OM_CHANGED_STS,
+                                   DEVICE_STATE_DELAY_TIME,
+                                   DEVICE_STATE_WAIT_TIME,
+                                   DEVICE_STATE_TIMEOUT);
+  if (ret != 0)
+    {
+      return ret;
+    }
+
+  priv->state = state;
+
+  if (state == STATE_ISX012_ACTIVE)
+    {
+      /* Wait CM_CHANGED -> Monitoring */
+
+      ret = isx012_chk_int_state(priv, CM_CHANGED_STS,
+                                       CAMERA_MODE_DELAY_TIME,
+                                       CAMERA_MODE_WAIT_TIME,
+                                       CAMERA_MODE_TIMEOUT);
+      if (ret != 0)
+        {
+          return ret;
+        }
+
+#ifdef ISX012_FRAME_SKIP_EN
+      mute_cnt = isx012_getreg(priv, MUTECNT, sizeof(mute_cnt));
+      isx012_putreg(priv, INTCLR0, VINT_STS, 1);
+      for (i = 0; i < mute_cnt; i++)
+        {
+          /* Wait Next VINT */
+
+          ret = isx012_chk_int_state(priv, VINT_STS, VINT_DELAY_TIME,
+                                           VINT_WAIT_TIME, VINT_TIMEOUT);
+          if (ret != 0)
+            {
+              return ret;
+            }
+        }
+#endif  /* ISX012_FRAME_SKIP_EN */
+    }
+
+  priv->mode = REGVAL_MODESEL_MON;
+
+  return OK;
+}
+
+int init_isx012(FAR struct isx012_dev_s *priv)
+{
+  int ret;
+
+#ifdef ISX012_NOT_USE_NSTBY
+  board_isx012_release_sleep();
+  board_isx012_release_reset();
+  nxsig_usleep(6000);
+#else
+  board_isx012_release_reset();
+  nxsig_usleep(6000);
+#endif
+
+#ifdef ISX012_CHECK_IN_DETAIL
+  /* check the chip id */
+
+  ret = isx012_chipid(priv);
+  if (ret < 0)
+    {
+      imagererr("isx012_chipid failed: %d\n", ret);
+      board_isx012_set_reset();
+      return ret;
+    }
+#endif
+
+  /* Wait OM_CHANGED Power OFF -> PreSleep */
+
+  ret = isx012_chk_int_state(priv, OM_CHANGED_STS, DEVICE_STATE_DELAY_TIME,
+                             DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
+  if (ret != OK)
+    {
+      imagererr("OM_CHANGED_STS(PreSleep) is Not occurred: %d\n", ret);
+      return ret;
+    }
+
+  priv->state = STATE_ISX012_PRESLEEP;
+
+#ifndef ISX012_NOT_USE_NSTBY
+  /* set the isx012 clock */
+
+  /* Write INCK_SET register ISX012 change state PreSleep -> Sleep */
+
+  ret = isx012_putreglist(priv, g_isx012_presleep, ISX012_PRESLEEP_NENTRIES);
+  if (ret != OK)
+    {
+      imagererr("isx012_putreglist(INCK_SET) failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Wait OM_CHANGED PreSleep -> Sleep */
+
+  ret = isx012_chk_int_state(priv, OM_CHANGED_STS, DEVICE_STATE_DELAY_TIME,
+                             DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
+  if (ret != OK)
+    {
+      imagererr("OM_CHANGED_STS(Sleep) is Not occurred: %d\n", ret);
+      return ret;
+    }
+#endif
+
+  priv->state = STATE_ISX012_SLEEP;
+  priv->i2c_freq = I2CFREQ_FAST;
+
+  /* initialize the isx012 hardware */
+
+  ret = isx012_putreglist(priv, g_isx012_def_init, ISX012_RESET_NENTRIES);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreglist failed: %d\n", ret);
+      board_isx012_set_reset();
+      return ret;
+    }
+
+  /* Set shading adjustment */
+
+  ret = isx012_set_shd(priv);
+  if (ret < 0)
+    {
+      imagererr("isx012_set_shd failed: %d\n", ret);
+      board_isx012_set_reset();
+      return ret;
+    }
+
+  return ret;
+}
+
+static int isx012_init(void)
+{
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+  int ret = 0;
+
+  ret = board_isx012_power_on();
+  if (ret < 0)
+    {
+      imagererr("Failed to power on %d\n", ret);
+      return ret;
+    }
+
+  ret = init_isx012(priv);
+  if (ret < 0)
+    {
+      imagererr("Failed to init_isx012 %d\n", ret);
+      board_isx012_set_reset();
+      board_isx012_power_off();
+      return ret;
+    }
+
+  return ret;
+}
+
+static int isx012_uninit(void)
+{
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+
+  int ret = 0;
+
+  if (priv->state == STATE_ISX012_ACTIVE)
+    {
+      board_isx012_set_sleep(1);
+    }
+
+  board_isx012_set_reset();
+
+  ret = board_isx012_power_off();
+  if (ret < 0)
+    {
+      imagererr("Failed to power off %d\n", ret);
+      return ret;
+    }
+
+  priv->i2c_freq = I2CFREQ_STANDARD;
+  priv->state    = STATE_ISX012_POWEROFF;
+
+  return ret;
+}
+
+static int8_t isx012_get_maximum_fps(uint8_t nr_fmt,
+                                     FAR imgsensor_format_t *fmt)
+{
+  int8_t max_fps = REGVAL_FPSTYPE_120FPS;
+  uint16_t main_w;
+  uint16_t main_h;
+  uint16_t sub_w;
+  uint16_t sub_h;
+
+  main_w = fmt[IMGSENSOR_FMT_MAIN].width;
+  main_h = fmt[IMGSENSOR_FMT_MAIN].height;
+
+  switch (fmt[IMGSENSOR_FMT_MAIN].pixelformat)
+    {
+      case IMGSENSOR_PIX_FMT_UYVY:                /* YUV 4:2:2 */
+      case IMGSENSOR_PIX_FMT_RGB565:              /* RGB565 */
+
+        if ((main_w < OUT_YUV_HSIZE_MIN) ||
+            (main_h < OUT_YUV_VSIZE_MIN) ||
+            (main_w > OUT_YUV_15FPS_HSIZE_MAX) ||
+            (main_h > OUT_YUV_15FPS_VSIZE_MAX))
+          {
+            /* IN frame size is out of range */
+
+            return -EINVAL;
+          }
+        else if ((main_w <= OUT_YUV_120FPS_HSIZE_MAX) &&
+                 (main_h <= OUT_YUV_120FPS_VSIZE_MAX))
+          {
+            max_fps = REGVAL_FPSTYPE_120FPS;
+          }
+        else
+          {
+            max_fps = REGVAL_FPSTYPE_60FPS;
+          }
+
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG:                /* JPEG */
+
+        if ((main_w < OUT_JPG_HSIZE_MIN) ||
+            (main_h < OUT_JPG_VSIZE_MIN) ||
+            (main_w > OUT_JPG_15FPS_HSIZE_MAX) ||
+            (main_h > OUT_JPG_15FPS_VSIZE_MAX))
+          {
+            /* IN frame size is out of range */
+
+            return -EINVAL;
+          }
+        else if ((main_w <= OUT_JPG_120FPS_HSIZE_MAX) &&
+                 (main_h <= OUT_JPG_120FPS_VSIZE_MAX))
+          {
+            max_fps = REGVAL_FPSTYPE_120FPS;
+          }
+        else if ((main_w <= OUT_JPG_60FPS_HSIZE_MAX) &&
+                 (main_h <= OUT_JPG_60FPS_VSIZE_MAX))
+          {
+            max_fps = REGVAL_FPSTYPE_60FPS;
+          }
+        else if ((main_w <= OUT_JPG_30FPS_HSIZE_MAX) &&
+                 (main_h <= OUT_JPG_30FPS_VSIZE_MAX))
+          {
+            max_fps = REGVAL_FPSTYPE_30FPS;
+          }
+        else
+          {
+            max_fps = REGVAL_FPSTYPE_15FPS;
+          }
+
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG_WITH_SUBIMG: /* JPEG + sub image */
+
+        if (nr_fmt == 1)
+          {
+            sub_w = OUT_YUV_HSIZE_MIN;
+            sub_h = OUT_YUV_VSIZE_MIN;
+          }
+        else
+          {
+            if (fmt[IMGSENSOR_FMT_SUB].pixelformat
+                != IMGSENSOR_PIX_FMT_UYVY)
+              {
+                /* Unsupported pixel format */
+
+                return -EINVAL;
+              }
+
+            sub_w  = fmt[IMGSENSOR_FMT_SUB].width;
+            sub_h  = fmt[IMGSENSOR_FMT_SUB].height;
+          }
+
+        if ((main_w < OUT_JPG_HSIZE_MIN) ||
+            (main_h < OUT_JPG_VSIZE_MIN) ||
+            (main_w > OUT_JPGINT_15FPS_HSIZE_MAX) ||
+            (main_h > OUT_JPGINT_15FPS_VSIZE_MAX) ||
+            (sub_w  < OUT_YUV_HSIZE_MIN) ||
+            (sub_h  < OUT_YUV_VSIZE_MIN) ||
+            (sub_w  > OUT_YUVINT_30FPS_HSIZE_MAX) ||
+            (sub_h  > OUT_YUVINT_30FPS_VSIZE_MAX))
+          {
+            /* IN frame size is out of range */
+
+            return -EINVAL;
+          }
+        else if ((main_w <= OUT_JPGINT_30FPS_HSIZE_MAX) &&
+                 (main_h <= OUT_JPGINT_30FPS_VSIZE_MAX))
+          {
+            max_fps = REGVAL_FPSTYPE_30FPS;
+          }
+        else
+          {
+            max_fps = REGVAL_FPSTYPE_15FPS;
+          }
+
+        break;
+
+      default:
+        return -EINVAL;
+    }
+
+  return max_fps;
+}
+
+static int isx012_replace_frameinterval_to_regval
+           (FAR imgsensor_interval_t *interval)
+{
+  /* Avoid multiplication overflow */
+
+  if ((interval->denominator * 2) / 2 != interval->denominator)
+    {
+      return -EINVAL;
+    }
+
+  /* Avoid division by zero */
+
+  if (interval->numerator == 0)
+    {
+      return -EINVAL;
+    }
+
+  /* Support only 1/x or 2/x. */
+
+  if (((interval->denominator * 2) % interval->numerator) != 0)
+    {
+      return -EINVAL;
+    }
+
+  /* Switch by FPS * 2 */
+
+  switch ((interval->denominator * 2) / interval->numerator)
+    {
+      case 240 : /* 120FPS */
+        return REGVAL_FPSTYPE_120FPS;
+
+      case 120 : /* 60FPS */
+        return REGVAL_FPSTYPE_60FPS;
+
+      case 60 :  /* 30FPS */
+        return REGVAL_FPSTYPE_30FPS;
+
+      case 30 :  /* 15FPS */
+        return REGVAL_FPSTYPE_15FPS;
+
+      case 20 :  /* 10FPS */
+        return REGVAL_FPSTYPE_10FPS;
+
+      case 15 :  /* 7.5FPS */
+        return REGVAL_FPSTYPE_7_5FPS;
+
+      case 12 :  /* 6FPS */
+        return REGVAL_FPSTYPE_6FPS;
+
+      case 10 :  /* 5FPS */
+        return REGVAL_FPSTYPE_5FPS;
+
+      default :
+        return -EINVAL;
+    }
+}
+
+static int isx012_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_fmt,
+                                         FAR imgsensor_format_t *fmt,
+                                         FAR imgsensor_interval_t *interval)
+{
+  int max_fps;
+  int arg_fps;
+
+  if ((fmt == NULL) ||
+      (interval == NULL))
+    {
+      return -EINVAL;
+    }
+
+  if ((nr_fmt < 1) || (nr_fmt > 2))
+    {
+      return -EINVAL;
+    }
+
+  max_fps = isx012_get_maximum_fps(nr_fmt, fmt);
+  if (max_fps == -EINVAL)
+    {
+      return -EINVAL;
+    }
+
+  arg_fps = isx012_replace_frameinterval_to_regval(interval);
+  if (arg_fps == -EINVAL)
+    {
+      return -EINVAL;
+    }
+
+  if (max_fps > arg_fps)
+    {
+      return -EINVAL;
+    }
+
+  return OK;
+}
+
+static int isx012_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_fmt,
+                                FAR imgsensor_format_t *fmt,
+                                FAR imgsensor_interval_t *interval)
+{
+  int ret;
+
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+
+  ret = isx012_validate_frame_setting(type, nr_fmt, fmt, interval);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  return isx012_set_mode_param(priv, type, nr_fmt, fmt, interval);
+}
+
+static int isx012_stop_capture(imgsensor_stream_type_t type)
+{
+  return OK;
+}
+
+static int isx012_get_supported_value
+             (uint32_t id, FAR imgsensor_supported_value_t *value)
+{
+  int ret = OK;
+  imgsensor_capability_range_t *range = &value->u.range;
+  imgsensor_capability_discrete_t *discrete = &value->u.discrete;
+  imgsensor_capability_elems_t *elems = &value->u.elems;
+
+  ASSERT(value);
+
+  switch (id)
+    {
+      case IMGSENSOR_ID_BRIGHTNESS:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_BRIGHTNESS;
+        range->maximum       = ISX012_MAX_BRIGHTNESS;
+        range->step          = ISX012_STEP_BRIGHTNESS;
+        range->default_value = ISX012_DEF_BRIGHTNESS;
+
+        break;
+
+      case IMGSENSOR_ID_CONTRAST:
+        value->type          = IMGSENSOR_CTRL_TYPE_U8FIXEDPOINT_Q7;
+        range->minimum       = ISX012_MIN_CONTRAST;
+        range->maximum       = ISX012_MAX_CONTRAST;
+        range->step          = ISX012_STEP_CONTRAST;
+        range->default_value = ISX012_DEF_CONTRAST;
+
+        break;
+
+      case IMGSENSOR_ID_SATURATION:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_SATURATION;
+        range->maximum       = ISX012_MAX_SATURATION;
+        range->step          = ISX012_STEP_SATURATION;
+        range->default_value = ISX012_DEF_SATURATION;
+
+        break;
+
+      case IMGSENSOR_ID_HUE:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_HUE;
+        range->maximum       = ISX012_MAX_HUE;
+        range->step          = ISX012_STEP_HUE;
+        range->default_value = ISX012_DEF_HUE;
+
+        break;
+
+      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_AUTOWB;
+        range->maximum       = ISX012_MAX_AUTOWB;
+        range->step          = ISX012_STEP_AUTOWB;
+        range->default_value = ISX012_DEF_AUTOWB;
+
+        break;
+      case IMGSENSOR_ID_GAMMA_CURVE:
+        value->type          = IMGSENSOR_CTRL_TYPE_U16;
+        elems->minimum       = ISX012_MIN_GAMMACURVE;
+        elems->maximum       = ISX012_MAX_GAMMACURVE;
+        elems->step          = ISX012_STEP_GAMMACURVE;
+        elems->nr_elems      = ISX012_ELEMS_GAMMACURVE;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER_TIMES_3;
+        range->minimum       = ISX012_MIN_EXPOSURE;
+        range->maximum       = ISX012_MAX_EXPOSURE;
+        range->step          = ISX012_STEP_EXPOSURE;
+        range->default_value = ISX012_DEF_EXPOSURE;
+
+        break;
+
+      case IMGSENSOR_ID_HFLIP_VIDEO:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_HFLIP;
+        range->maximum       = ISX012_MAX_HFLIP;
+        range->step          = ISX012_STEP_HFLIP;
+        range->default_value = ISX012_DEF_HFLIP;
+
+        break;
+
+      case IMGSENSOR_ID_VFLIP_VIDEO:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_VFLIP;
+        range->maximum       = ISX012_MAX_VFLIP;
+        range->step          = ISX012_STEP_VFLIP;
+        range->default_value = ISX012_DEF_VFLIP;
+
+        break;
+
+      case IMGSENSOR_ID_HFLIP_STILL:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_HFLIP_STILL;
+        range->maximum       = ISX012_MAX_HFLIP_STILL;
+        range->step          = ISX012_STEP_HFLIP_STILL;
+        range->default_value = ISX012_DEF_HFLIP_STILL;
+
+        break;
+
+      case IMGSENSOR_ID_VFLIP_STILL:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_VFLIP_STILL;
+        range->maximum       = ISX012_MAX_VFLIP_STILL;
+        range->step          = ISX012_STEP_VFLIP_STILL;
+        range->default_value = ISX012_DEF_VFLIP_STILL;
+
+        break;
+
+      case IMGSENSOR_ID_SHARPNESS:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_SHARPNESS;
+        range->maximum       = ISX012_MAX_SHARPNESS;
+        range->step          = ISX012_STEP_SHARPNESS;
+        range->default_value = ISX012_DEF_SHARPNESS;
+
+        break;
+
+      case IMGSENSOR_ID_COLOR_KILLER:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_COLORKILLER;
+        range->maximum       = ISX012_MAX_COLORKILLER;
+        range->step          = ISX012_STEP_COLORKILLER;
+        range->default_value = ISX012_DEF_COLORKILLER;
+
+        break;
+
+      case IMGSENSOR_ID_COLORFX:
+        value->type = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
+        discrete->nr_values
+          = ARRAY_NENTRIES(g_isx012_colorfx_actual);
+        discrete->values = g_isx012_colorfx_actual;
+        discrete->default_value = IMGSENSOR_COLORFX_NONE;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_AUTO:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_EXPOSUREAUTO;
+        range->maximum       = ISX012_MAX_EXPOSUREAUTO;
+        range->step          = ISX012_STEP_EXPOSUREAUTO;
+        range->default_value = ISX012_DEF_EXPOSUREAUTO;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_ABSOLUTE:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_EXPOSURETIME;
+        range->maximum       = ISX012_MAX_EXPOSURETIME;
+        range->step          = ISX012_STEP_EXPOSURETIME;
+        range->default_value = ISX012_DEF_EXPOSURETIME;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_METERING:
+        value->type = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
+        discrete->nr_values
+          = ARRAY_NENTRIES(g_isx012_photometry_actual);
+        discrete->values = g_isx012_photometry_actual;
+        discrete->default_value
+          = IMGSENSOR_EXPOSURE_METERING_AVERAGE;
+
+        break;
+
+      case IMGSENSOR_ID_AUTO_N_PRESET_WB:
+        value->type = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
+        discrete->nr_values = ARRAY_NENTRIES(g_isx012_presetwb_actual);
+        discrete->values = g_isx012_presetwb_actual;
+        discrete->default_value = IMGSENSOR_WHITE_BALANCE_AUTO;
+
+        break;
+
+      case IMGSENSOR_ID_WIDE_DYNAMIC_RANGE:
+        value->type          = IMGSENSOR_CTRL_TYPE_BOOLEAN;
+        range->minimum       = ISX012_MIN_YGAMMA;
+        range->maximum       = ISX012_MAX_YGAMMA;
+        range->step          = ISX012_STEP_YGAMMA;
+        range->default_value = ISX012_DEF_YGAMMA;
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY:
+        value->type             = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
+        discrete->nr_values     = ARRAY_NENTRIES(g_isx012_iso_actual);
+        discrete->values        = g_isx012_iso_actual;
+        discrete->default_value = 0;
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY_AUTO:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_ISOAUTO;
+        range->maximum       = ISX012_MAX_ISOAUTO;
+        range->step          = ISX012_STEP_ISOAUTO;
+        range->default_value = ISX012_DEF_ISOAUTO;
+
+        break;
+
+      case IMGSENSOR_ID_3A_LOCK:
+        value->type          = IMGSENSOR_CTRL_TYPE_BITMASK;
+        range->minimum       = ISX012_MIN_3ALOCK;
+        range->maximum       = ISX012_MAX_3ALOCK;
+        range->step          = ISX012_STEP_3ALOCK;
+        range->default_value = ISX012_DEF_3ALOCK;
+
+        break;
+
+      case IMGSENSOR_ID_3A_PARAMETER:
+        value->type          = IMGSENSOR_CTRL_TYPE_U16;
+        elems->minimum       = 0;
+        elems->maximum       = 65535;
+        elems->step          = 1;
+        elems->nr_elems      = ISX012_ELEMS_3APARAM;
+
+        break;
+
+      case IMGSENSOR_ID_3A_STATUS:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = 0;
+        range->maximum       = 3;
+        range->step          = 1;
+        range->default_value = 3;
+
+        break;
+
+      case IMGSENSOR_ID_JPEG_QUALITY:
+        value->type          = IMGSENSOR_CTRL_TYPE_INTEGER;
+        range->minimum       = ISX012_MIN_JPGQUALITY;
+        range->maximum       = ISX012_MAX_JPGQUALITY;
+        range->step          = ISX012_STEP_JPGQUALITY;
+        range->default_value = ISX012_DEF_JPGQUALITY;
+
+        break;
+
+      default: /* Unsupported parameter */
+        ret = -EINVAL;
+
+        break;
+    }
+
+  return ret;
+}
+
+static int isx012_get_value(uint32_t id,
+                            uint32_t size,
+                            FAR imgsensor_value_t *value)
+{
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+  uint16_t   readvalue;
+  uint8_t    cnt;
+  uint8_t    threea_enable;
+  uint16_t   read_src;
+  uint16_t   *read_dst;
+  int        ret = OK;
+
+  ASSERT(value);
+
+  switch (id)
+    {
+      case IMGSENSOR_ID_BRIGHTNESS:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_BRIGHTNESS,
+                                  ISX012_SIZE_BRIGHTNESS);
+
+        value->value32 = (int32_t)(int8_t)(0x00ff & readvalue);
+        break;
+
+      case IMGSENSOR_ID_CONTRAST:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_CONTRAST,
+                                       ISX012_SIZE_CONTRAST);
+        break;
+
+      case IMGSENSOR_ID_SATURATION:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_SATURATION,
+                                       ISX012_SIZE_SATURATION);
+        break;
+
+      case IMGSENSOR_ID_HUE:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_HUE,
+                                       ISX012_SIZE_HUE);
+        break;
+
+      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_AUTOWB,
+                                  ISX012_SIZE_AUTOWB);
+
+        /* Convert to video driver's value */
+
+        value->value32 = (readvalue & REGVAL_CPUEXT_BIT_AWBSTOP) ? 0 : 1;
+
+        break;
+
+      case IMGSENSOR_ID_GAMMA_CURVE:
+        if (value->p_u16 == NULL)
+          {
+            return -EINVAL;
+          }
+
+        if (size != ISX012_ELEMS_GAMMACURVE * sizeof(uint16_t))
+          {
+            return -EINVAL;
+          }
+
+        read_src = ISX012_REG_GAMMACURVE;
+        read_dst = value->p_u16;
+
+        for (cnt = 0; cnt < ISX012_ELEMS_GAMMACURVE; cnt++)
+          {
+            *read_dst = isx012_getreg(priv,
+                                      read_src,
+                                      ISX012_SIZE_GAMMACURVE);
+            read_src += ISX012_SIZE_GAMMACURVE;
+            read_dst++;
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_EXPOSURE,
+                                  ISX012_SIZE_EXPOSURE);
+
+        value->value32 = (int32_t)(int8_t)(0x00ff & readvalue);
+
+        break;
+
+      case IMGSENSOR_ID_HFLIP_VIDEO:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_HFLIP,
+                                  ISX012_SIZE_HFLIP);
+
+        value->value32 = (readvalue & REGVAL_READVECT_BIT_H) ? 1 : 0;
+
+        break;
+
+      case IMGSENSOR_ID_VFLIP_VIDEO:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_VFLIP,
+                                  ISX012_SIZE_VFLIP);
+
+        value->value32 = (readvalue & REGVAL_READVECT_BIT_V) ? 1 : 0;
+
+        break;
+
+      case IMGSENSOR_ID_HFLIP_STILL:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_HFLIP_STILL,
+                                  ISX012_SIZE_HFLIP_STILL);
+
+        value->value32 = (readvalue & REGVAL_READVECT_BIT_H) ? 1 : 0;
+
+        break;
+
+      case IMGSENSOR_ID_VFLIP_STILL:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_VFLIP_STILL,
+                                  ISX012_SIZE_VFLIP_STILL);
+
+        value->value32 = (readvalue & REGVAL_READVECT_BIT_V) ? 1 : 0;
+
+        break;
+
+      case IMGSENSOR_ID_SHARPNESS:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_SHARPNESS,
+                                       ISX012_SIZE_SHARPNESS);
+        break;
+
+      case IMGSENSOR_ID_COLOR_KILLER:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_COLORKILLER,
+                                  ISX012_SIZE_COLORKILLER);
+
+        value->value32 = (readvalue == REGVAL_EFFECT_MONOTONE) ? 1 : 0;
+
+        break;
+
+      case IMGSENSOR_ID_COLORFX:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_COLOREFFECT,
+                                  ISX012_SIZE_COLOREFFECT);
+
+        ret = -EINVAL;
+        for (cnt = 0; cnt < ARRAY_NENTRIES(g_isx012_colorfx_regval); cnt++)
+          {
+            if (g_isx012_colorfx_regval[cnt] == readvalue)
+              {
+                value->value32 = g_isx012_colorfx_actual[cnt];
+                ret = OK;
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_AUTO:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_EXPOSURETIME,
+                                  ISX012_SIZE_EXPOSURETIME);
+
+        value->value32 = readvalue ?
+                         IMGSENSOR_EXPOSURE_MANUAL : IMGSENSOR_EXPOSURE_AUTO;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_ABSOLUTE:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_EXPOSURETIME,
+                                       ISX012_SIZE_EXPOSURETIME);
+
+        break;
+
+      case IMGSENSOR_ID_AUTO_N_PRESET_WB:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_PRESETWB,
+                                  ISX012_SIZE_PRESETWB);
+
+        for (cnt = 0; cnt < ARRAY_NENTRIES(g_isx012_presetwb_regval); cnt++)
+          {
+            if (g_isx012_presetwb_regval[cnt] == readvalue)
+              {
+                value->value32 = g_isx012_presetwb_actual[cnt];
+                ret = OK;
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_WIDE_DYNAMIC_RANGE:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_YGAMMA,
+                                  ISX012_SIZE_YGAMMA);
+        value->value32 = readvalue ? 0 : 1;
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY:
+        readvalue = isx012_getreg(priv, ISX012_REG_ISO, ISX012_SIZE_ISO);
+
+        ret = -EINVAL;
+        for (cnt = 0; cnt < ARRAY_NENTRIES(g_isx012_presetwb_regval); cnt++)
+          {
+            if (g_isx012_iso_regval[cnt] == readvalue)
+              {
+                value->value32 = g_isx012_iso_actual[cnt];
+                ret = OK;
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY_AUTO:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_ISOAUTO,
+                                  ISX012_SIZE_ISOAUTO);
+
+        value->value32 = (readvalue == REGVAL_ISO_AUTO) ?
+                         IMGSENSOR_ISO_SENSITIVITY_AUTO :
+                         IMGSENSOR_ISO_SENSITIVITY_MANUAL;
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_METERING:
+        readvalue = isx012_getreg(priv,
+                                  ISX012_REG_PHOTOMETRY,
+                                  ISX012_SIZE_PHOTOMETRY);
+
+        ret = -EINVAL;
+        for (cnt = 0;
+             cnt < ARRAY_NENTRIES(g_isx012_photometry_regval);
+             cnt++)
+          {
+            if (g_isx012_photometry_regval[cnt] == readvalue)
+              {
+                value->value32 = g_isx012_photometry_actual[cnt];
+                ret = OK;
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_3A_PARAMETER:
+        if (value->p_u16 == NULL)
+          {
+            return -EINVAL;
+          }
+
+        if (size != ISX012_ELEMS_3APARAM * sizeof(uint16_t))
+          {
+            return -EINVAL;
+          }
+
+        /* Get AWB parameter */
+
+        value->p_u16[0] = isx012_getreg(priv, RATIO_R, 2);
+        value->p_u16[1] = isx012_getreg(priv, RATIO_B, 2);
+
+        /* Get AE parameter */
+
+        value->p_u16[2] = isx012_getreg(priv, AELEVEL, 2);
+
+        break;
+
+      case IMGSENSOR_ID_3A_STATUS:
+
+        /* Initialize returned status */
+
+        value->value32 = IMGSENSOR_3A_STATUS_STABLE;
+
+        /* Get AWB/AE enable or not */
+
+        threea_enable = isx012_getreg(priv, CPUEXT, 1);
+
+        if ((threea_enable & REGVAL_CPUEXT_BIT_AWBSTOP)
+               != REGVAL_CPUEXT_BIT_AWBSTOP)
+          {
+            readvalue = isx012_getreg(priv, AWBSTS, 1);
+            if (readvalue != REGVAL_AWBSTS_STOP) /* AWB is not stopped */
+              {
+                value->value32 |= IMGSENSOR_3A_STATUS_AWB_OPERATING;
+              }
+          }
+
+        if ((threea_enable & REGVAL_CPUEXT_BIT_AESTOP)
+               != REGVAL_CPUEXT_BIT_AESTOP)
+          {
+            readvalue = isx012_getreg(priv, AESTS, 1);
+            if (readvalue != REGVAL_AESTS_STOP) /* AE is not stopped */
+              {
+                value->value32 |= IMGSENSOR_3A_STATUS_AE_OPERATING;
+              }
+          }
+        break;
+
+      case IMGSENSOR_ID_JPEG_QUALITY:
+        value->value32 = isx012_getreg(priv,
+                                       ISX012_REG_JPGQUALITY,
+                                       ISX012_SIZE_JPGQUALITY);
+        break;
+
+      default: /* Unsupported id */
+
+        ret = -EINVAL;
+        break;
+    }
+
+  return ret;
+}
+
+static int isx012_set_value(uint32_t id,
+                            uint32_t size,
+                            FAR imgsensor_value_t value)
+{
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+  int       ret = -EINVAL;
+  uint8_t   cnt;
+  uint16_t  *write_src;
+  uint16_t  write_dst;
+  uint16_t  regval;
+  uint16_t  exposure_time_lsb;
+  uint16_t  exposure_time_msb;
+
+  switch (id)
+    {
+      case IMGSENSOR_ID_BRIGHTNESS:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_BRIGHTNESS,
+                             ISX012_MAX_BRIGHTNESS,
+                             ISX012_STEP_BRIGHTNESS);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_BRIGHTNESS,
+                            value.value32,
+                            ISX012_SIZE_BRIGHTNESS);
+        break;
+
+      case IMGSENSOR_ID_CONTRAST:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_CONTRAST,
+                             ISX012_MAX_CONTRAST,
+                             ISX012_STEP_CONTRAST);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_CONTRAST,
+                            value.value32,
+                            ISX012_SIZE_CONTRAST);
+        break;
+
+      case IMGSENSOR_ID_SATURATION:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_SATURATION,
+                             ISX012_MAX_SATURATION,
+                             ISX012_STEP_SATURATION);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_SATURATION,
+                            value.value32,
+                            ISX012_SIZE_SATURATION);
+        break;
+
+      case IMGSENSOR_ID_HUE:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_HUE,
+                             ISX012_MAX_HUE,
+                             ISX012_STEP_HUE);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_HUE,
+                            value.value32,
+                            ISX012_SIZE_HUE);
+        break;
+
+      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_AUTOWB,
+                             ISX012_MAX_AUTOWB,
+                             ISX012_STEP_AUTOWB);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = isx012_getreg(priv,
+                               ISX012_REG_AUTOWB,
+                               ISX012_SIZE_AUTOWB);
+
+        if (value.value32)
+          {
+            /* Because true means setting auto white balance
+             * turn off the stop bit
+             */
+
+            regval &= ~REGVAL_CPUEXT_BIT_AWBSTOP;
+          }
+        else
+          {
+            /* Because false means stopping auto white balance,
+             * turn on the stop bit.
+             */
+
+            regval |= REGVAL_CPUEXT_BIT_AWBSTOP;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_AUTOWB,
+                            regval,
+                            ISX012_SIZE_AUTOWB);
+        break;
+
+      case IMGSENSOR_ID_GAMMA_CURVE:
+        if (value.p_u16 == NULL)
+          {
+            return -EINVAL;
+          }
+
+        if (size != ISX012_ELEMS_GAMMACURVE * 2)
+          {
+            return -EINVAL;
+          }
+
+        write_src = value.p_u16;
+        write_dst = ISX012_REG_GAMMACURVE;
+
+        for (cnt = 0; cnt < ISX012_ELEMS_GAMMACURVE; cnt++)
+          {
+            ret = VALIDATE_VALUE(*write_src,
+                                 ISX012_MIN_GAMMACURVE,
+                                 ISX012_MAX_GAMMACURVE,
+                                 ISX012_STEP_GAMMACURVE);
+            if (ret != OK)
+              {
+                break;
+              }
+
+            ret = isx012_putreg(priv,
+                                write_dst,
+                                *write_src,
+                                ISX012_SIZE_GAMMACURVE);
+
+            write_src++;
+            write_dst += ISX012_SIZE_GAMMACURVE;
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_EXPOSURE,
+                             ISX012_MAX_EXPOSURE,
+                             ISX012_STEP_EXPOSURE);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_EXPOSURE,
+                            value.value32,
+                            ISX012_SIZE_EXPOSURE);
+
+        break;
+
+      case IMGSENSOR_ID_HFLIP_VIDEO:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_HFLIP,
+                             ISX012_MAX_HFLIP,
+                             ISX012_STEP_HFLIP);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = isx012_getreg(priv,
+                               ISX012_REG_HFLIP,
+                               ISX012_SIZE_HFLIP);
+
+        if (value.value32)
+          {
+            regval |= REGVAL_READVECT_BIT_H;
+          }
+        else
+          {
+            regval &= ~REGVAL_READVECT_BIT_H;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_HFLIP,
+                            regval,
+                            ISX012_SIZE_HFLIP);
+        break;
+
+      case IMGSENSOR_ID_VFLIP_VIDEO:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_VFLIP,
+                             ISX012_MAX_VFLIP,
+                             ISX012_STEP_VFLIP);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = isx012_getreg(priv,
+                               ISX012_REG_VFLIP,
+                               ISX012_SIZE_VFLIP);
+
+        if (value.value32)
+          {
+            regval |= REGVAL_READVECT_BIT_V;
+          }
+        else
+          {
+            regval &= ~REGVAL_READVECT_BIT_V;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_VFLIP,
+                            regval,
+                            ISX012_SIZE_VFLIP);
+        break;
+
+      case IMGSENSOR_ID_HFLIP_STILL:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_HFLIP_STILL,
+                             ISX012_MAX_HFLIP_STILL,
+                             ISX012_STEP_HFLIP_STILL);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = isx012_getreg(priv,
+                               ISX012_REG_HFLIP_STILL,
+                               ISX012_SIZE_HFLIP_STILL);
+
+        if (value.value32)
+          {
+            regval |= REGVAL_READVECT_BIT_H;
+          }
+        else
+          {
+            regval &= ~REGVAL_READVECT_BIT_H;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_HFLIP_STILL,
+                            regval,
+                            ISX012_SIZE_HFLIP_STILL);
+
+        break;
+
+      case IMGSENSOR_ID_VFLIP_STILL:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_VFLIP_STILL,
+                             ISX012_MAX_VFLIP_STILL,
+                             ISX012_STEP_VFLIP_STILL);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = isx012_getreg(priv,
+                               ISX012_REG_VFLIP_STILL,
+                               ISX012_SIZE_VFLIP_STILL);
+
+        if (value.value32)
+          {
+            regval |= REGVAL_READVECT_BIT_V;
+          }
+        else
+          {
+            regval &= ~REGVAL_READVECT_BIT_V;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_VFLIP_STILL,
+                            regval,
+                            ISX012_SIZE_VFLIP_STILL);
+        break;
+
+      case IMGSENSOR_ID_SHARPNESS:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_SHARPNESS,
+                             ISX012_MAX_SHARPNESS,
+                             ISX012_STEP_SHARPNESS);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_SHARPNESS,
+                            value.value32,
+                            ISX012_SIZE_SHARPNESS);
+        break;
+
+      case IMGSENSOR_ID_COLOR_KILLER:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_COLORKILLER,
+                             ISX012_MAX_COLORKILLER,
+                             ISX012_STEP_COLORKILLER);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg
+                (priv,
+                 ISX012_REG_COLORKILLER,
+                 value.value32 ? REGVAL_EFFECT_MONOTONE : REGVAL_EFFECT_NONE,
+                 ISX012_SIZE_COLORKILLER);
+
+        break;
+
+      case IMGSENSOR_ID_COLORFX:
+        for (cnt = 0; cnt < ARRAY_NENTRIES(g_isx012_colorfx_actual); cnt++)
+          {
+            if (g_isx012_colorfx_actual[cnt] == value.value32)
+              {
+                ret = isx012_putreg(priv,
+                                    ISX012_REG_COLOREFFECT,
+                                    g_isx012_colorfx_regval[cnt],
+                                    ISX012_SIZE_COLOREFFECT);
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_AUTO:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_EXPOSUREAUTO,
+                             ISX012_MAX_EXPOSUREAUTO,
+                             ISX012_STEP_EXPOSUREAUTO);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        if (value.value32 == IMGSENSOR_EXPOSURE_AUTO)
+          {
+            /* Register is the same as IMGSENSOR_ID_EXPOSURE_ABSOLUTE.
+             * If this register value = REGVAL_EXPOSURETIME_AUTO(=0),
+             *  it means auto. Otherwise, it means manual.
+             */
+
+            ret = isx012_putreg(priv,
+                                ISX012_REG_EXPOSURETIME,
+                                REGVAL_EXPOSURETIME_AUTO,
+                                ISX012_SIZE_EXPOSURETIME);
+          }
+        else
+          {
+            /* In manual case, read current value of register which
+             * value adjusted automatically by ISX012 HW is set to.
+             * It has 32bits length which is composed of LSB 16bits
+             *  and MSB 16bits.
+             */
+
+            exposure_time_lsb = isx012_getreg
+                                (priv,
+                                 ISX012_REG_EXPOSUREAUTOVALUE_LSB,
+                                 ISX012_SIZE_EXPOSUREAUTOVALUE);
+            exposure_time_msb = isx012_getreg
+                                (priv,
+                                 ISX012_REG_EXPOSUREAUTOVALUE_MSB,
+                                 ISX012_SIZE_EXPOSUREAUTOVALUE);
+
+            /* Register value adjusted automatically by ISX012 HW
+             *  has the different unit from manual value register.
+             *   automatic value register : 1   microsec unit
+             *   manual    value register : 100 microsec unit
+             */
+
+            regval = (uint16_t)(((exposure_time_msb << 16)
+                                  | exposure_time_lsb)
+                                 / ISX012_UNIT_EXPOSURETIME_US);
+            ret = isx012_putreg(priv,
+                                ISX012_REG_EXPOSURETIME,
+                                regval,
+                                ISX012_SIZE_EXPOSURETIME);
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_ABSOLUTE:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_EXPOSURETIME,
+                             ISX012_MAX_EXPOSURETIME,
+                             ISX012_STEP_EXPOSURETIME);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_EXPOSURETIME,
+                            value.value32,
+                            ISX012_SIZE_EXPOSURETIME);
+        break;
+
+      case IMGSENSOR_ID_WIDE_DYNAMIC_RANGE:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_YGAMMA,
+                             ISX012_MAX_YGAMMA,
+                             ISX012_STEP_YGAMMA);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        if (value.value32)
+          {
+            regval = REGVAL_YGAMMA_AUTO;
+          }
+        else
+          {
+            regval = REGVAL_YGAMMA_OFF;
+          }
+
+        ret = isx012_putreg
+                (priv,
+                 ISX012_REG_YGAMMA,
+                 value.value32 ? REGVAL_YGAMMA_AUTO : REGVAL_YGAMMA_OFF,
+                 ISX012_SIZE_YGAMMA);
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY:
+        for (cnt = 0; cnt < ARRAY_NENTRIES(g_isx012_iso_actual); cnt++)
+          {
+            if (g_isx012_iso_actual[cnt]
+                 == value.value32)
+              {
+                ret = isx012_putreg(priv,
+                                    ISX012_REG_ISO,
+                                    g_isx012_iso_regval[cnt],
+                                    ISX012_SIZE_ISO);
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_ISO_SENSITIVITY_AUTO:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_ISOAUTO,
+                             ISX012_MAX_ISOAUTO,
+                             ISX012_STEP_ISOAUTO);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        if (value.value32 == IMGSENSOR_ISO_SENSITIVITY_AUTO)
+          {
+            ret = isx012_putreg(priv,
+                                ISX012_REG_ISOAUTO,
+                                REGVAL_ISO_AUTO,
+                                ISX012_SIZE_ISOAUTO);
+          }
+        else
+          {
+            /* In manual case, read auto adjust value and set it */
+
+            regval = isx012_getreg(priv,
+                                   ISX012_REG_ISOAUTOVALUE,
+                                   ISX012_SIZE_ISOAUTOVALUE);
+            ret = isx012_putreg(priv,
+                                ISX012_REG_ISO,
+                                regval,
+                                ISX012_SIZE_ISO);
+          }
+
+        break;
+
+      case IMGSENSOR_ID_EXPOSURE_METERING:
+        for (cnt = 0;
+             cnt < ARRAY_NENTRIES(g_isx012_photometry_actual);
+             cnt++)
+          {
+            if (g_isx012_photometry_actual[cnt]
+                 == value.value32)
+              {
+                ret = isx012_putreg(priv,
+                                    ISX012_REG_PHOTOMETRY,
+                                    g_isx012_photometry_regval[cnt],
+                                    ISX012_SIZE_PHOTOMETRY);
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_AUTO_N_PRESET_WB:
+        for (cnt = 0;
+             cnt < ARRAY_NENTRIES(g_isx012_presetwb_actual);
+             cnt++)
+          {
+            if (g_isx012_presetwb_actual[cnt] == value.value32)
+              {
+                ret = isx012_putreg(priv,
+                                    ISX012_REG_PRESETWB,
+                                    g_isx012_presetwb_regval[cnt],
+                                    ISX012_SIZE_PRESETWB);
+                break;
+              }
+          }
+
+        break;
+
+      case IMGSENSOR_ID_3A_LOCK:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_3ALOCK,
+                             ISX012_MAX_3ALOCK,
+                             ISX012_STEP_3ALOCK);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        regval = 0;
+
+        if ((value.value32 & IMGSENSOR_LOCK_EXPOSURE)
+              == IMGSENSOR_LOCK_EXPOSURE)
+          {
+            regval |= REGVAL_CPUEXT_BIT_AESTOP;
+          }
+
+        if ((value.value32 & IMGSENSOR_LOCK_WHITE_BALANCE)
+              == IMGSENSOR_LOCK_WHITE_BALANCE)
+          {
+            regval |= REGVAL_CPUEXT_BIT_AWBSTOP;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_3ALOCK,
+                            regval,
+                            ISX012_SIZE_3ALOCK);
+
+        break;
+
+      case IMGSENSOR_ID_3A_PARAMETER:
+
+        /* AWB parameter : red */
+
+        ret = isx012_putreg(priv, INIT_CONT_INR, value.p_u16[0], 2);
+        ret = isx012_putreg(priv, INIT_CONT_OUTR, value.p_u16[0], 2);
+
+        /* AWB parameter : blue */
+
+        ret = isx012_putreg(priv, INIT_CONT_INB, value.p_u16[1], 2);
+        ret = isx012_putreg(priv, INIT_CONT_OUTB, value.p_u16[1], 2);
+
+        /* AE parameter */
+
+        ret = isx012_putreg(priv, AE_START_LEVEL, value.p_u16[2], 2);
+
+        break;
+
+      case IMGSENSOR_ID_JPEG_QUALITY:
+        ret = VALIDATE_VALUE(value.value32,
+                             ISX012_MIN_JPGQUALITY,
+                             ISX012_MAX_JPGQUALITY,
+                             ISX012_STEP_JPGQUALITY);
+        if (ret != OK)
+          {
+            break;
+          }
+
+        ret = isx012_putreg(priv,
+                            ISX012_REG_JPGQUALITY,
+                            value.value32,
+                            ISX012_SIZE_JPGQUALITY);
+        break;
+
+      default: /* Unsupported control id */
+
+        break;
+    }
+
+  return ret;
+}
+
+static int isx012_set_shd(FAR isx012_dev_t *priv)
+{
+  int ret;
+  int unit_cnt;
+  int size_cnt;
+
+  /* At first, disable CXC and SHD */
+
+  ret = isx012_putreg(priv, SHD_EN, 0x50, 1);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreg(disable CXC/SHD) failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Set CXC Validity */
+
+  ret = isx012_putreg(priv, CXC_VALID, 0x8282, 2);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreg(CXC_VALID) failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Set CXC R Gb data */
+
+  for (unit_cnt = 0; unit_cnt < CXC_RGB_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < CXC_RGB_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              CXC_RGB_UNIT(unit_cnt, size_cnt),
+                              g_isx012_cxc_rgb_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(CXC R Gb) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set CXC G Rb data */
+
+  for (unit_cnt = 0; unit_cnt < CXC_GRB_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < CXC_GRB_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              CXC_GRB_UNIT(unit_cnt, size_cnt),
+                              g_isx012_cxc_grb_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(CXC G Rb) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD Validity */
+
+  ret = isx012_putreg(priv, SHD_VALID, 0x9191, 2);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreg(SHD_VALID) failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Set SHD R Gb data */
+
+  for (unit_cnt = 0; unit_cnt < SHD_RGB_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < SHD_RGB_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              SHD_RGB_UNIT(unit_cnt, size_cnt),
+                              g_isx012_shd_rgb_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(SHD R Gb) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD G Rb data */
+
+  for (unit_cnt = 0; unit_cnt < SHD_GRB_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < SHD_GRB_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              SHD_GRB_UNIT(unit_cnt, size_cnt),
+                              g_isx012_shd_grb_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(SHD G Rb) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD R1 data */
+
+  for (unit_cnt = 0; unit_cnt < SHD_R1_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < SHD_R1_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              SHD_R1_UNIT(unit_cnt, size_cnt),
+                              g_isx012_shd_r1_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(SHD R1) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD R2 data */
+
+  for (unit_cnt = 0; unit_cnt < SHD_R2_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < SHD_R2_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              SHD_R2_UNIT(unit_cnt, size_cnt),
+                              g_isx012_shd_r2_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(SHD R2) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD B2 data */
+
+  for (unit_cnt = 0; unit_cnt < SHD_B2_DATA_UNIT_NUM; unit_cnt++)
+    {
+      for (size_cnt = 0; size_cnt < SHD_B2_DATA_UNIT_SIZE; size_cnt++)
+        {
+          ret = isx012_putreg(priv,
+                              SHD_B2_UNIT(unit_cnt, size_cnt),
+                              g_isx012_shd_b2_data[unit_cnt][size_cnt],
+                              1);
+          if (ret < 0)
+            {
+              imagererr("isx012_putreg(SHD B2) failed: %d\n", ret);
+              return ret;
+            }
+        }
+    }
+
+  /* Set SHD thresholds data */
+
+  ret = isx012_putreglist(priv, g_isx012_shd_thresholds,
+                          ISX012_SHD_THRESHOLDS_NENTRIES);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreglist failed(SHD thresholds): %d\n", ret);
+      board_isx012_set_reset();
+      return ret;
+    }
+
+  /* Set SHD white balance data */
+
+  ret = isx012_putreglist(priv, g_isx012_shd_wb, ISX012_SHD_WB_NENTRIES);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreglist(SHD white balance) failed: %d\n", ret);
+      board_isx012_set_reset();
+      return ret;
+    }
+
+  /* Enable CXC and SHD */
+
+  ret = isx012_putreg(priv, SHD_EN, 0x57, 1);
+  if (ret < 0)
+    {
+      imagererr("isx012_putreg(enable CXC/SHD) failed: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int isx012_initialize(FAR struct i2c_master_s *i2c)
+{
+  FAR struct isx012_dev_s *priv = &g_isx012_private;
+
+  /* Save i2c information */
+
+  priv->i2c        = i2c;
+  priv->i2c_addr   = ISX012_I2C_SLV_ADDR;
+  priv->i2c_freq   = I2CFREQ_STANDARD;
+
+  /* Regiser image sensor operations variable */
+
+  imgsensor_register(&g_isx012_ops);
+
+  /* Initialize other information */
+
+  priv->state      = STATE_ISX012_POWEROFF;
+
+  return OK;
+}
+
+int isx012_uninitialize(void)
+{
+  /* No procedure */
+
+  return OK;
+}
diff --git a/include/nuttx/video/isx012_range.h b/drivers/video/isx012_range.h
similarity index 87%
rename from include/nuttx/video/isx012_range.h
rename to drivers/video/isx012_range.h
index 22534fd..698ba9d 100644
--- a/include/nuttx/video/isx012_range.h
+++ b/drivers/video/isx012_range.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * include/nuttx/video/isx012_range.h
+ * drivers/video/isx012_range.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -29,7 +29,6 @@
 /* Definition for control brightness */
 
 #define ISX012_TYPE_BRIGHTNESS      V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_BRIGHTNESS      "Brightness"
 #define ISX012_DEF_BRIGHTNESS       (0)
 #define ISX012_MIN_BRIGHTNESS       (-128)
 #define ISX012_MAX_BRIGHTNESS       (127)
@@ -40,7 +39,6 @@
 /* Definition for control contrast */
 
 #define ISX012_TYPE_CONTRAST        V4L2_CTRL_TYPE_U8FIXEDPOINT_Q7
-#define ISX012_NAME_CONTRAST        "Contrast"
 #define ISX012_DEF_CONTRAST         (0x80)
 #define ISX012_MIN_CONTRAST         (0x00)
 #define ISX012_MAX_CONTRAST         (0xFF)
@@ -51,7 +49,6 @@
 /* Definition for control saturation */
 
 #define ISX012_TYPE_SATURATION      V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_SATURATION      "Saturation"
 #define ISX012_DEF_SATURATION       (0)
 #define ISX012_MIN_SATURATION       (0)
 #define ISX012_MAX_SATURATION       (255)
@@ -62,7 +59,6 @@
 /* Definition for control hue */
 
 #define ISX012_TYPE_HUE             V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_HUE             "Hue"
 #define ISX012_DEF_HUE              (0)
 #define ISX012_MIN_HUE              (0)
 #define ISX012_MAX_HUE              (255)
@@ -73,7 +69,6 @@
 /* Definition for control auto white balance */
 
 #define ISX012_TYPE_AUTOWB          V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_AUTOWB          "Automatic white balance"
 #define ISX012_DEF_AUTOWB           true
 #define ISX012_MIN_AUTOWB           false
 #define ISX012_MAX_AUTOWB           true
@@ -84,7 +79,6 @@
 /* Definition for control red balance */
 
 #define ISX012_TYPE_REDBALANCE      V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_REDBALANCE      "Red balance"
 #define ISX012_DEF_REDBALANCE       (0)
 #define ISX012_MIN_REDBALANCE       (0)
 #define ISX012_MAX_REDBALANCE       (65535)
@@ -95,7 +89,6 @@
 /* Definition for control blue balance */
 
 #define ISX012_TYPE_BLUEBALANCE     V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_BLUEBALANCE     "Red balance"
 #define ISX012_DEF_BLUEBALANCE      (0)
 #define ISX012_MIN_BLUEBALANCE      (0)
 #define ISX012_MAX_BLUEBALANCE      (65535)
@@ -106,7 +99,6 @@
 /* Definition for control gamma curve */
 
 #define ISX012_TYPE_GAMMACURVE      V4L2_CTRL_TYPE_U16
-#define ISX012_NAME_GAMMACURVE      "Gamma adjustment(curve)"
 #define ISX012_DEF_GAMMACURVE       (0)
 #define ISX012_MIN_GAMMACURVE       (0)
 #define ISX012_MAX_GAMMACURVE       (511)
@@ -119,7 +111,6 @@
 /* Definition for control exposure value */
 
 #define ISX012_TYPE_EXPOSURE        V4L2_CTRL_TYPE_INTEGER_TIMES_3
-#define ISX012_NAME_EXPOSURE        "Exposure value"
 #define ISX012_DEF_EXPOSURE         (0)
 #define ISX012_MIN_EXPOSURE         (-6)
 #define ISX012_MAX_EXPOSURE         (6)
@@ -130,7 +121,6 @@
 /* Definition for control horizontal mirroring(V4L2_BUF_TYPE_VIDEO_CAPTURE) */
 
 #define ISX012_TYPE_HFLIP           V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_HFLIP           "Mirror horizontally(VIDEO)"
 #define ISX012_DEF_HFLIP            false
 #define ISX012_MIN_HFLIP            false
 #define ISX012_MAX_HFLIP            true
@@ -141,7 +131,6 @@
 /* Definition for control vertical mirroring(V4L2_BUF_TYPE_VIDEO_CAPTURE) */
 
 #define ISX012_TYPE_VFLIP           V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_VFLIP           "Mirror vertically(VIDEO)"
 #define ISX012_DEF_VFLIP            false
 #define ISX012_MIN_VFLIP            false
 #define ISX012_MAX_VFLIP            true
@@ -152,7 +141,6 @@
 /* Definition for control horizontal mirroring(V4L2_BUF_TYPE_STILL_CAPTURE) */
 
 #define ISX012_TYPE_HFLIP_STILL     V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_HFLIP_STILL     "Mirror horizontally(STILL)"
 #define ISX012_DEF_HFLIP_STILL      false
 #define ISX012_MIN_HFLIP_STILL      false
 #define ISX012_MAX_HFLIP_STILL      true
@@ -163,7 +151,6 @@
 /* Definition for control vertical mirroring(V4L2_BUF_TYPE_STILL_CAPTURE) */
 
 #define ISX012_TYPE_VFLIP_STILL     V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_VFLIP_STILL     "Mirror vertically(STILL)"
 #define ISX012_DEF_VFLIP_STILL      false
 #define ISX012_MIN_VFLIP_STILL      false
 #define ISX012_MAX_VFLIP_STILL      true
@@ -174,7 +161,6 @@
 /* Definition for control sharpness */
 
 #define ISX012_TYPE_SHARPNESS       V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_SHARPNESS       "Sharpness"
 #define ISX012_DEF_SHARPNESS        (0)
 #define ISX012_MIN_SHARPNESS        (0)
 #define ISX012_MAX_SHARPNESS        (255)
@@ -185,7 +171,6 @@
 /* Definition for control color killer */
 
 #define ISX012_TYPE_COLORKILLER     V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_COLORKILLER     "Color killer"
 #define ISX012_DEF_COLORKILLER      false
 #define ISX012_MIN_COLORKILLER      false
 #define ISX012_MAX_COLORKILLER      true
@@ -196,7 +181,6 @@
 /* Definition for control color effect */
 
 #define ISX012_TYPE_COLOREFFECT     V4L2_CTRL_TYPE_INTEGER_MENU
-#define ISX012_NAME_COLOREFFECT     "Color effect"
 #define ISX012_DEF_COLOREFFECT      V4L2_COLORFX_NONE
 #define ISX012_MIN_COLOREFFECT      (0)
 #define ISX012_MAX_COLOREFFECT      (6)
@@ -207,7 +191,6 @@
 /* Definition for control auto exposure */
 
 #define ISX012_TYPE_EXPOSUREAUTO         V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_EXPOSUREAUTO         "Auto Exposure"
 #define ISX012_DEF_EXPOSUREAUTO          (0)
 #define ISX012_MIN_EXPOSUREAUTO          (0)
 #define ISX012_MAX_EXPOSUREAUTO          (1)
@@ -220,10 +203,9 @@
 /* Definition for control exposure time */
 
 #define ISX012_TYPE_EXPOSURETIME    V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_EXPOSURETIME    "Exposure time(usec)"
 #define ISX012_DEF_EXPOSURETIME     (0)
 #define ISX012_MIN_EXPOSURETIME     (1)
-#define ISX012_MAX_EXPOSURETIME     (10000)
+#define ISX012_MAX_EXPOSURETIME     (21000)
 #define ISX012_STEP_EXPOSURETIME    (1)
 #define ISX012_REG_EXPOSURETIME     SHT_PREMODE_TYPE1
 #define ISX012_SIZE_EXPOSURETIME    (2)
@@ -233,7 +215,6 @@
 /* Definition for control photometry */
 
 #define ISX012_TYPE_PHOTOMETRY    V4L2_CTRL_TYPE_INTEGER_MENU
-#define ISX012_NAME_PHOTOMETRY    "Photometry"
 #define ISX012_DEF_PHOTOMETRY     V4L2_EXPOSURE_METERING_AVERAGE
 #define ISX012_MIN_PHOTOMETRY     (0)
 #define ISX012_MAX_PHOTOMETRY     (3)
@@ -244,7 +225,6 @@
 /* Definition for control zoom */
 
 #define ISX012_TYPE_ZOOM            V4L2_CTRL_TYPE_U16FIXEDPOINT_Q8
-#define ISX012_NAME_ZOOM            "Zoom"
 #define ISX012_DEF_ZOOM             (0x0100)
 #define ISX012_MIN_ZOOM             (0x0100)
 #define ISX012_MAX_ZOOM             (0x1000)
@@ -255,7 +235,6 @@
 /* Definition for control preset white balance */
 
 #define ISX012_TYPE_PRESETWB        V4L2_CTRL_TYPE_INTEGER_MENU
-#define ISX012_NAME_PRESETWB        "Preset white balance"
 #define ISX012_DEF_PRESETWB         V4L2_WHITE_BALANCE_AUTO
 #define ISX012_MIN_PRESETWB         (0)
 #define ISX012_MAX_PRESETWB         (5)
@@ -266,7 +245,6 @@
 /* Definition for control YGAMMA adujust */
 
 #define ISX012_TYPE_YGAMMA          V4L2_CTRL_TYPE_BOOLEAN
-#define ISX012_NAME_YGAMMA          "Wide dynamic range"
 #define ISX012_DEF_YGAMMA           (false)
 #define ISX012_MIN_YGAMMA           (false)
 #define ISX012_MAX_YGAMMA           (true)
@@ -277,7 +255,6 @@
 /* Definition for control ISO sensitivity */
 
 #define ISX012_TYPE_ISO              V4L2_CTRL_TYPE_INTEGER_MENU
-#define ISX012_NAME_ISO              "ISO sensitivity"
 #define ISX012_DEF_ISO               (0)
 #define ISX012_MIN_ISO               (0)
 #define ISX012_MAX_ISO               (18)
@@ -288,7 +265,6 @@
 /* Definition for control ISO automatic */
 
 #define ISX012_TYPE_ISOAUTO          V4L2_CTRL_TYPE_INTEGER_MENU
-#define ISX012_NAME_ISOAUTO          "Automatic ISO sensitivity"
 #define ISX012_DEF_ISOAUTO           (false)
 #define ISX012_MIN_ISOAUTO           (0)
 #define ISX012_MAX_ISOAUTO           (1)
@@ -301,7 +277,6 @@
 /* Definition for control 3A lock */
 
 #define ISX012_TYPE_3ALOCK           V4L2_CTRL_TYPE_BITMASK
-#define ISX012_NAME_3ALOCK           "Lock AWB/AE"
 #define ISX012_DEF_3ALOCK            (0)
 #define ISX012_MIN_3ALOCK            (0)
 #define ISX012_MAX_3ALOCK            (3)
@@ -312,8 +287,7 @@
 /* Definition for control JPEG compression quality */
 
 #define ISX012_TYPE_JPGQUALITY      V4L2_CTRL_TYPE_INTEGER
-#define ISX012_NAME_JPGQUALITY      "JPEG compression quality"
-#define ISX012_DEF_JPGQUALITY       (75)
+#define ISX012_DEF_JPGQUALITY       (80)
 #define ISX012_MIN_JPGQUALITY       (1)
 #define ISX012_MAX_JPGQUALITY       (100)
 #define ISX012_STEP_JPGQUALITY      (1)
diff --git a/include/nuttx/video/isx012_reg.h b/drivers/video/isx012_reg.h
similarity index 98%
rename from include/nuttx/video/isx012_reg.h
rename to drivers/video/isx012_reg.h
index 35976eb..143d8f1 100644
--- a/include/nuttx/video/isx012_reg.h
+++ b/drivers/video/isx012_reg.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * include/nuttx/video/isx012_reg.h
+ * drivers/video/isx012_reg.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -41,6 +41,8 @@
 #define MODE_BASE                   (0x6A00)
 #define PICT_BASE                   (0x6C00)
 #define GAMMA_BASE                  (0x7000)
+#define GAMMA1_BASE                 (0x7200)
+#define GAMMA2_BASE                 (0x7400)
 #define JPEG_BASE                   (0x7800)
 #define AUTOCOM_BASE                (0x7C00)
 #define VFRMPARA_BASE               (0x8800)
@@ -777,6 +779,18 @@
 #define G0_0CLIP_B                  (GAMMA_BASE+0x0044)
 #define G0_KNOT_GAINCTRL_TH_L       (GAMMA_BASE+0x0046)
 #define G0_KNOT_GAINCTRL_TH_H       (GAMMA_BASE+0x0047)
+#define G1_LOWGM_ON_R               (GAMMA1_BASE+0x003A)
+#define G1_0CLIP_R                  (GAMMA1_BASE+0x003C)
+#define G1_LOWGM_ON_G               (GAMMA1_BASE+0x003E)
+#define G1_0CLIP_G                  (GAMMA1_BASE+0x0040)
+#define G1_LOWGM_ON_B               (GAMMA1_BASE+0x0042)
+#define G1_0CLIP_B                  (GAMMA1_BASE+0x0044)
+#define G2_LOWGM_ON_R               (GAMMA2_BASE+0x003A)
+#define G2_0CLIP_R                  (GAMMA2_BASE+0x003C)
+#define G2_LOWGM_ON_G               (GAMMA2_BASE+0x003E)
+#define G2_0CLIP_G                  (GAMMA2_BASE+0x0040)
+#define G2_LOWGM_ON_B               (GAMMA2_BASE+0x0042)
+#define G2_0CLIP_B                  (GAMMA2_BASE+0x0044)
 
 /* JPEG OFFSET */
 
diff --git a/drivers/video/video.c b/drivers/video/video.c
index 33b3b5d..6b9c1e9 100644
--- a/drivers/video/video.c
+++ b/drivers/video/video.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <fcntl.h>
+#include <assert.h>
 #include <errno.h>
 #include <poll.h>
 
@@ -38,7 +39,8 @@
 
 #include <arch/board/board.h>
 
-#include <nuttx/video/video_halif.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
 
 #include "video_framebuff.h"
 
@@ -46,12 +48,10 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define video_printf(format, ...)   _info(format, ##__VA_ARGS__)
-
 #define MAX_VIDEO_FILE_PATH     (32)
-
-#define VIDEO_TRUE              (1)
-#define VIDEO_FALSE             (0)
+#define MAX_VIDEO_FMT           (2)
+#define VIDEO_FMT_MAIN          (0)
+#define VIDEO_FMT_SUB           (1)
 
 #define VIDEO_REMAINING_CAPNUM_INFINITY (-1)
 
@@ -75,50 +75,70 @@
 #define videoinfo(x...)
 #endif
 
+#define VIDEO_SCENE_MAX (sizeof(g_video_scene_parameter) / \
+                         sizeof(video_scene_params_t))
+
+#define VIDEO_ID(x, y) (((x) << 16) | y)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 enum video_state_e
 {
-  VIDEO_STATE_STREAMOFF = 0, /* DMA trigger event is not received */
-  VIDEO_STATE_STREAMON  = 1, /* DMA trigger event is received,
-                              * but DMA is not operated.
+  VIDEO_STATE_STREAMOFF = 0, /* capture trigger event is not received */
+  VIDEO_STATE_STREAMON  = 1, /* capture trigger event is received,
+                              * but capture is not operated.
                               */
-  VIDEO_STATE_DMA       = 2, /* On DMA */
+  VIDEO_STATE_CAPTURE   = 2, /* On capture */
 };
 
 enum video_state_transition_cause
 {
-  CAUSE_VIDEO_STOP  = 0,     /* Stop  DMA event for video stream */
-  CAUSE_VIDEO_START = 1,     /* Start DMA event for video stream */
+  CAUSE_VIDEO_STOP  = 0,     /* Stop  capture event for video stream */
+  CAUSE_VIDEO_START = 1,     /* Start capture event for video stream */
   CAUSE_VIDEO_DQBUF = 2,     /* DQBUF timing    for video stream */
-  CAUSE_STILL_STOP  = 3,     /* Stop  DMA event for still stream */
-  CAUSE_STILL_START = 4,     /* Start DMA event for still stream */
+  CAUSE_STILL_STOP  = 3,     /* Stop  capture event for still stream */
+  CAUSE_STILL_START = 4,     /* Start capture event for still stream */
 };
 
 enum video_waitend_cause_e
 {
-  VIDEO_WAITEND_CAUSE_DMADONE   = 0,
+  VIDEO_WAITEND_CAUSE_CAPTUREDONE   = 0,
   VIDEO_WAITEND_CAUSE_DQCANCEL  = 1,
   VIDEO_WAITEND_CAUSE_STILLSTOP = 2,
 };
 
-struct video_wait_dma_s
+struct video_wait_capture_s
 {
   FAR sem_t            dqbuf_wait_flg;
-  FAR vbuf_container_t *done_container; /* Save container which dma done */
+
+  /* Save container which capture is done */
+
+  FAR vbuf_container_t *done_container;
   enum video_waitend_cause_e waitend_cause;
 };
 
-typedef struct video_wait_dma_s video_wait_dma_t;
+typedef struct video_wait_capture_s video_wait_capture_t;
+
+struct video_format_s
+{
+  uint16_t width;
+  uint16_t height;
+  uint32_t pixelformat;
+};
+
+typedef struct video_format_s video_format_t;
 
 struct video_type_inf_s
 {
   sem_t                lock_state;
   enum video_state_e   state;
   int32_t              remaining_capnum;
-  video_wait_dma_t     wait_dma;
+  video_wait_capture_t wait_capture;
+  uint8_t              nr_fmt;
+  video_format_t       fmt[MAX_VIDEO_FMT];
+  struct v4l2_fract    frame_interval;
   video_framebuff_t    bufinf;
 };
 
@@ -129,13 +149,62 @@ struct video_mng_s
   FAR char           *devpath;     /* parameter of video_initialize() */
   sem_t              lock_open_num;
   uint8_t            open_num;
-  FAR struct pollfd  *poll_wait;   /* poll(setup) information */
   video_type_inf_t   video_inf;
   video_type_inf_t   still_inf;
 };
 
 typedef struct video_mng_s video_mng_t;
 
+struct video_scene_params_s
+{
+  uint8_t mode;   /* enum v4l2_scene_mode */
+
+  int32_t brightness;
+  int32_t contrast;
+  int32_t saturation;
+  int32_t hue;
+  bool    awb;
+  int32_t red;
+  int32_t blue;
+  int32_t gamma;
+  uint32_t gamma_curve_sz;
+  uint8_t *gamma_curve;
+  int32_t ev;
+  bool    hflip_video;
+  bool    vflip_video;
+  bool    hflip_still;
+  bool    vflip_still;
+  int32_t sharpness;
+  enum v4l2_colorfx colorfx;
+  bool    auto_brightness;
+  int32_t rotate;
+  enum  v4l2_exposure_auto_type ae;
+  int32_t exposure_time;
+  int32_t focus;
+  bool    af;
+  int32_t zoom;
+  int32_t iris;
+  enum v4l2_auto_n_preset_white_balance wb;
+  int32_t wdr;
+  bool    stabilization;
+  enum v4l2_iso_sensitivity_auto_type iso_auto;
+  int32_t iso;
+  enum v4l2_exposure_metering meter;
+  int32_t threea_lock;
+  enum v4l2_flash_led_mode led;
+  int32_t jpeg_quality;
+};
+
+typedef struct video_scene_params_s video_scene_params_t;
+
+struct video_parameter_name_s
+{
+  uint32_t id;
+  char     *name;
+};
+
+typedef struct video_parameter_name_s video_parameter_name_t;
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -145,9 +214,6 @@ typedef struct video_mng_s video_mng_t;
 static int video_open(FAR struct file *filep);
 static int video_close(FAR struct file *filep);
 static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-static int video_poll(FAR struct file   *filep,
-                      FAR struct pollfd *fds,
-                      bool              setup);
 
 /* Common function */
 
@@ -164,6 +230,10 @@ static bool is_taking_still_picture(FAR video_mng_t *vmng);
 static bool is_bufsize_sufficient(FAR video_mng_t *vmng, uint32_t bufsize);
 static void cleanup_resources(FAR video_mng_t *vmng);
 static bool is_sem_waited(FAR sem_t *sem);
+static int save_scene_param(enum v4l2_scene_mode mode,
+                            uint32_t id,
+                            struct v4l2_ext_control *control);
+static int video_complete_capture(uint8_t  err_code, uint32_t datasize);
 
 /* internal function for each cmds of ioctl */
 
@@ -175,18 +245,16 @@ static int video_dqbuf(FAR struct video_mng_s *vmng,
                        FAR struct v4l2_buffer *buf);
 static int video_cancel_dqbuf(FAR struct video_mng_s *vmng,
                               enum v4l2_buf_type type);
-static int video_enum_fmt(FAR struct v4l2_fmtdesc *fmt);
-static int video_enum_framesizes(FAR struct v4l2_frmsizeenum *frmsize);
 static int video_s_fmt(FAR struct video_mng_s *priv,
                        FAR struct v4l2_format *fmt);
-static int video_enum_frameintervals(FAR struct v4l2_frmivalenum *frmival);
 static int video_s_parm(FAR struct video_mng_s *priv,
                         FAR struct v4l2_streamparm *parm);
 static int video_streamon(FAR struct video_mng_s *vmng,
                           FAR enum v4l2_buf_type *type);
 static int video_streamoff(FAR struct video_mng_s *vmng,
                            FAR enum v4l2_buf_type *type);
-static int video_do_halfpush(bool enable);
+static int video_do_halfpush(FAR struct video_mng_s *priv,
+                             bool enable);
 static int video_takepict_start(FAR struct video_mng_s *vmng,
                                 int32_t                capture_num);
 static int video_takepict_stop(FAR struct video_mng_s *vmng,
@@ -202,12 +270,11 @@ static int video_g_ext_ctrls(FAR struct video_mng_s *priv,
                              FAR struct v4l2_ext_controls *ctrls);
 static int video_s_ext_ctrls(FAR struct video_mng_s *priv,
                              FAR struct v4l2_ext_controls *ctrls);
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-static const struct video_devops_s *g_video_devops;
+static int video_query_ext_ctrl_scene(FAR struct v4s_query_ext_ctrl_scene
+                                      *ctrl);
+static int video_querymenu_scene(FAR struct v4s_querymenu_scene *menu);
+static int video_g_ext_ctrls_scene(FAR struct v4s_ext_controls_scene *ctrls);
+static int video_s_ext_ctrls_scene(FAR struct v4s_ext_controls_scene *ctrls);
 
 /****************************************************************************
  * Private Data
@@ -222,17 +289,135 @@ static const struct file_operations g_video_fops =
   0,                        /* seek */
   video_ioctl,              /* ioctl */
 #ifndef CONFIG_DISABLE_POLL
-  video_poll,               /* poll */
+  0,                        /* poll */
 #endif
   0                         /* unlink */
 };
 
 static bool is_initialized = false;
-static FAR void *video_handler;
 
-/****************************************************************************
- * Public Data
- ****************************************************************************/
+enum v4l2_scene_mode g_video_scene_mode = V4L2_SCENE_MODE_NONE;
+video_scene_params_t g_video_scene_parameter[] =
+{
+    {
+      .mode = V4L2_SCENE_MODE_NONE,
+    },
+#ifdef CONFIG_VIDEO_SCENE_BACKLIGHT
+    {
+      .mode = V4L2_SCENE_MODE_BACKLIGHT,
+    },
+#endif /* CONFIG_VIDEO_SCENE_BACKLIGHT */
+#ifdef CONFIG_VIDEO_SCENE_BEACHSNOW
+    {
+      .mode = V4L2_SCENE_MODE_BEACH_SNOW,
+    },
+#endif /* CONFIG_VIDEO_SCENE_BEACHSNOW */
+#ifdef CONFIG_VIDEO_SCENE_CANDLELIGHT
+    {
+      .mode = V4L2_SCENE_MODE_CANDLE_LIGHT,
+    },
+#endif /* CONFIG_VIDEO_SCENE_CANDLELIGHT */
+#ifdef CONFIG_VIDEO_SCENE_DAWNDUSK
+    {
+      .mode = V4L2_SCENE_MODE_DAWN_DUSK,
+    },
+#endif /* CONFIG_VIDEO_SCENE_DAWNDUSK */
+#ifdef CONFIG_VIDEO_SCENE_FALLCOLORS
+    {
+      .mode = V4L2_SCENE_MODE_FALL_COLORS,
+    },
+#endif /* CONFIG_VIDEO_SCENE_FALLCOLORS */
+#ifdef CONFIG_VIDEO_SCENE_FIREWORKS
+    {
+      .mode = V4L2_SCENE_MODE_FIREWORKS,
+    },
+#endif /* CONFIG_VIDEO_SCENE_FIREWORKS */
+#ifdef CONFIG_VIDEO_SCENE_LANDSCAPE
+    {
+      .mode = V4L2_SCENE_MODE_LANDSCAPE,
+    },
+#endif /* CONFIG_VIDEO_SCENE_LANDSCAPE */
+#ifdef CONFIG_VIDEO_SCENE_NIGHT
+    {
+      .mode = V4L2_SCENE_MODE_NIGHT,
+    },
+#endif /* CONFIG_VIDEO_SCENE_NIGHT */
+#ifdef CONFIG_VIDEO_SCENE_PARTYINDOOR
+    {
+      .mode = V4L2_SCENE_MODE_PARTY_INDOOR,
+    },
+#endif /* CONFIG_VIDEO_SCENE_PARTYINDOOR */
+#ifdef CONFIG_VIDEO_SCENE_PORTRAIT
+    {
+      .mode = V4L2_SCENE_MODE_PORTRAIT,
+    },
+#endif /* CONFIG_VIDEO_SCENE_PORTRAIT */
+#ifdef CONFIG_VIDEO_SCENE_SPORTS
+    {
+      .mode = V4L2_SCENE_MODE_SPORTS,
+    },
+#endif /* CONFIG_VIDEO_SCENE_SPORTS */
+#ifdef CONFIG_VIDEO_SCENE_SUNSET
+    {
+      .mode = V4L2_SCENE_MODE_SUNSET,
+    },
+#endif /* CONFIG_VIDEO_SCENE_SUNSET */
+#ifdef CONFIG_VIDEO_SCENE_TEXT
+    {
+      .mode = V4L2_SCENE_MODE_TEXT,
+    },
+#endif /* CONFIG_VIDEO_SCENE_TEXT */
+};
+
+static video_parameter_name_t g_video_parameter_name[] =
+{
+  {IMGSENSOR_ID_BRIGHTNESS,           "Brightness"},
+  {IMGSENSOR_ID_CONTRAST,             "Contrast"},
+  {IMGSENSOR_ID_SATURATION,           "Saturation"},
+  {IMGSENSOR_ID_HUE,                  "Hue"},
+  {IMGSENSOR_ID_AUTO_WHITE_BALANCE,   "Automatic white balance"},
+  {IMGSENSOR_ID_RED_BALANCE,          "Red balance"},
+  {IMGSENSOR_ID_BLUE_BALANCE,         "Blue balance"},
+  {IMGSENSOR_ID_GAMMA,                "Gamma value"},
+  {IMGSENSOR_ID_GAMMA_CURVE,          "Gamma adjustment(curve)"},
+  {IMGSENSOR_ID_EXPOSURE,             "Exposure value"},
+  {IMGSENSOR_ID_HFLIP_VIDEO,          "Mirror horizontally(VIDEO)"},
+  {IMGSENSOR_ID_VFLIP_VIDEO,          "Mirror vertically(VIDEO)"},
+  {IMGSENSOR_ID_HFLIP_STILL,          "Mirror horizontally(STILL)"},
+  {IMGSENSOR_ID_VFLIP_STILL,          "Mirror vertically(STILL)"},
+  {IMGSENSOR_ID_SHARPNESS,            "Sharpness"},
+  {IMGSENSOR_ID_COLOR_KILLER,         "Color killer"},
+  {IMGSENSOR_ID_COLORFX,              "Color effect"},
+  {IMGSENSOR_ID_AUTOBRIGHTNESS,       "Auto brightness"},
+  {IMGSENSOR_ID_ROTATE,               "Rotate"},
+  {IMGSENSOR_ID_EXPOSURE_AUTO,        "Auto Exposure"},
+  {IMGSENSOR_ID_EXPOSURE_ABSOLUTE,    "Exposure time(100 usec)"},
+  {IMGSENSOR_ID_FOCUS_ABSOLUTE,       "Focus(absolute value)"},
+  {IMGSENSOR_ID_FOCUS_RELATIVE,       "Focus(relative value)"},
+  {IMGSENSOR_ID_FOCUS_AUTO,           "Continuous Auto Focus"},
+  {IMGSENSOR_ID_ZOOM_ABSOLUTE,        "Zoom(absolute value)"},
+  {IMGSENSOR_ID_ZOOM_RELATIVE,        "Zoom(relative value)"},
+  {IMGSENSOR_ID_ZOOM_CONTINUOUS,      "Continuous zoom"},
+  {IMGSENSOR_ID_IRIS_ABSOLUTE,        "Iris(absolute value)"},
+  {IMGSENSOR_ID_IRIS_RELATIVE,        "Iris(relative value)"},
+  {IMGSENSOR_ID_AUTO_N_PRESET_WB,     "Preset white balance"},
+  {IMGSENSOR_ID_WIDE_DYNAMIC_RANGE,   "Wide dynamic range"},
+  {IMGSENSOR_ID_IMG_STABILIZATION,    "Image stabilization"},
+  {IMGSENSOR_ID_ISO_SENSITIVITY,      "ISO sensitivity"},
+  {IMGSENSOR_ID_ISO_SENSITIVITY_AUTO, "Automatic ISO sensitivity"},
+  {IMGSENSOR_ID_EXPOSURE_METERING,    "Photometry"},
+  {IMGSENSOR_ID_3A_LOCK,              "Lock AWB/AE"},
+  {IMGSENSOR_ID_AUTO_FOCUS_START,     "Start single Auto Focus"},
+  {IMGSENSOR_ID_AUTO_FOCUS_STOP,      "Stop single Auto Focus"},
+  {IMGSENSOR_ID_3A_PARAMETER,         "3A parameter"},
+  {IMGSENSOR_ID_3A_STATUS,            "3A status"},
+  {IMGSENSOR_ID_FLASH_LED_MODE,       "LED mode"},
+  {IMGSENSOR_ID_JPEG_QUALITY,         "JPEG compression quality"}
+};
+
+static FAR void *video_handler;
+static FAR const struct imgsensor_ops_s *g_video_sensor_ops;
+static FAR const struct imgdata_ops_s *g_video_data_ops;
 
 /****************************************************************************
  * Private Functions
@@ -299,13 +484,13 @@ static enum video_state_e estimate_next_video_state
           }
         else
           {
-            return VIDEO_STATE_DMA;
+            return VIDEO_STATE_CAPTURE;
           }
 
       case CAUSE_STILL_STOP:
         if (current_state == VIDEO_STATE_STREAMON)
           {
-            return VIDEO_STATE_DMA;
+            return VIDEO_STATE_CAPTURE;
           }
         else
           {
@@ -313,7 +498,7 @@ static enum video_state_e estimate_next_video_state
           }
 
       case CAUSE_STILL_START:
-        if (current_state == VIDEO_STATE_DMA)
+        if (current_state == VIDEO_STATE_CAPTURE)
           {
             return VIDEO_STATE_STREAMON;
           }
@@ -326,7 +511,7 @@ static enum video_state_e estimate_next_video_state
         if ((current_state == VIDEO_STATE_STREAMON) &&
              !is_taking_still_picture(vmng))
           {
-            return VIDEO_STATE_DMA;
+            return VIDEO_STATE_CAPTURE;
           }
         else
           {
@@ -338,23 +523,137 @@ static enum video_state_e estimate_next_video_state
     }
 }
 
+static void convert_to_imgdatafmt(FAR video_format_t *video,
+                                  FAR imgdata_format_t *data)
+{
+  ASSERT(video && data);
+
+  data->width       = video->width;
+  data->height      = video->height;
+  switch (video->pixelformat)
+    {
+      case V4L2_PIX_FMT_UYVY :
+        data->pixelformat = IMGDATA_PIX_FMT_UYVY;
+        break;
+
+      case V4L2_PIX_FMT_RGB565 :
+        data->pixelformat = IMGDATA_PIX_FMT_RGB565;
+        break;
+
+      case V4L2_PIX_FMT_JPEG :
+        data->pixelformat = IMGDATA_PIX_FMT_JPEG;
+        break;
+
+      default : /* V4L2_PIX_FMT_JPEG_WITH_SUBIMG */
+        data->pixelformat = IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG;
+        break;
+    }
+}
+
+static void convert_to_imgsensorfmt(FAR video_format_t *video,
+                                    FAR imgsensor_format_t *sensor)
+{
+  ASSERT(video && sensor);
+
+  sensor->width       = video->width;
+  sensor->height      = video->height;
+  switch (video->pixelformat)
+    {
+      case V4L2_PIX_FMT_UYVY :
+        sensor->pixelformat = IMGSENSOR_PIX_FMT_UYVY;
+        break;
+
+      case V4L2_PIX_FMT_RGB565 :
+        sensor->pixelformat = IMGSENSOR_PIX_FMT_RGB565;
+        break;
+
+      case V4L2_PIX_FMT_JPEG :
+        sensor->pixelformat = IMGSENSOR_PIX_FMT_JPEG;
+        break;
+
+      default : /* V4L2_PIX_FMT_JPEG_WITH_SUBIMG */
+        sensor->pixelformat = IMGSENSOR_PIX_FMT_JPEG_WITH_SUBIMG;
+        break;
+    }
+}
+
+static void convert_to_imgdatainterval(FAR struct v4l2_fract *video,
+                                       FAR imgdata_interval_t *data)
+{
+  ASSERT(video && data);
+
+  data->numerator   = video->numerator;
+  data->denominator = video->denominator;
+}
+
+static void convert_to_imgsensorinterval(FAR struct v4l2_fract *video,
+                                         FAR imgsensor_interval_t *sensor)
+{
+  ASSERT(video && sensor);
+
+  sensor->numerator   = video->numerator;
+  sensor->denominator = video->denominator;
+}
+
+static int start_capture(enum v4l2_buf_type type,
+                         uint8_t nr_fmt,
+                         FAR video_format_t *fmt,
+                         FAR struct v4l2_fract *interval,
+                         uint32_t bufaddr, uint32_t bufsize)
+{
+  imgdata_format_t df[MAX_VIDEO_FMT];
+  imgsensor_format_t sf[MAX_VIDEO_FMT];
+  imgdata_interval_t di;
+  imgsensor_interval_t si;
+
+  ASSERT(fmt && interval && g_video_sensor_ops && g_video_data_ops);
+
+  if ((g_video_sensor_ops->start_capture == NULL) ||
+      (g_video_data_ops->start_capture == NULL) ||
+      (g_video_data_ops->set_buf == NULL))
+    {
+      return -ENOTTY;
+    }
+
+  convert_to_imgdatafmt(&fmt[VIDEO_FMT_MAIN], &df[IMGDATA_FMT_MAIN]);
+  convert_to_imgdatafmt(&fmt[VIDEO_FMT_SUB], &df[IMGDATA_FMT_SUB]);
+  convert_to_imgdatainterval(interval, &di);
+  convert_to_imgsensorfmt(&fmt[VIDEO_FMT_MAIN], &sf[IMGSENSOR_FMT_MAIN]);
+  convert_to_imgsensorfmt(&fmt[VIDEO_FMT_SUB], &sf[IMGSENSOR_FMT_SUB]);
+  convert_to_imgsensorinterval(interval, &si);
+
+  g_video_sensor_ops->start_capture
+    ((type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+     IMGSENSOR_STREAM_TYPE_VIDEO : IMGSENSOR_STREAM_TYPE_STILL,
+     nr_fmt,
+     sf,
+     &si);
+  g_video_data_ops->start_capture(nr_fmt, df, &di, video_complete_capture);
+  g_video_data_ops->set_buf((uint8_t *)bufaddr, bufsize);
+
+  return OK;
+}
+
 static void change_video_state(FAR video_mng_t    *vmng,
                                enum video_state_e next_state)
 {
   enum video_state_e current_state = vmng->video_inf.state;
   enum video_state_e updated_next_state = next_state;
-  FAR vbuf_container_t *dma_container;
+  FAR vbuf_container_t *container;
 
-  if ((current_state != VIDEO_STATE_DMA) &&
-      (next_state    == VIDEO_STATE_DMA))
+  if ((current_state != VIDEO_STATE_CAPTURE) &&
+      (next_state    == VIDEO_STATE_CAPTURE))
     {
-      dma_container =
-              video_framebuff_get_dma_container(&vmng->video_inf.bufinf);
-      if (dma_container)
+      container =
+              video_framebuff_get_vacant_container(&vmng->video_inf.bufinf);
+      if (container)
         {
-          g_video_devops->set_buftype(V4L2_BUF_TYPE_VIDEO_CAPTURE);
-          g_video_devops->set_buf(dma_container->buf.m.userptr,
-                                  dma_container->buf.length);
+          start_capture(V4L2_BUF_TYPE_VIDEO_CAPTURE,
+                        vmng->video_inf.nr_fmt,
+                        vmng->video_inf.fmt,
+                        &vmng->video_inf.frame_interval,
+                        container->buf.m.userptr,
+                        container->buf.length);
         }
       else
         {
@@ -363,10 +662,10 @@ static void change_video_state(FAR video_mng_t    *vmng,
     }
   else
     {
-      if ((current_state == VIDEO_STATE_DMA) &&
-          (next_state    != VIDEO_STATE_DMA))
+      if ((current_state == VIDEO_STATE_CAPTURE) &&
+          (next_state    != VIDEO_STATE_CAPTURE))
         {
-          g_video_devops->cancel_dma();
+          g_video_data_ops->stop_capture();
         }
     }
 
@@ -378,7 +677,7 @@ static void change_video_state(FAR video_mng_t    *vmng,
 static bool is_taking_still_picture(FAR video_mng_t *vmng)
 {
   return ((vmng->still_inf.state == VIDEO_STATE_STREAMON) ||
-          (vmng->still_inf.state == VIDEO_STATE_DMA));
+          (vmng->still_inf.state == VIDEO_STATE_CAPTURE));
 }
 
 static bool is_bufsize_sufficient(FAR video_mng_t *vmng, uint32_t bufsize)
@@ -388,21 +687,196 @@ static bool is_bufsize_sufficient(FAR video_mng_t *vmng, uint32_t bufsize)
   return true;
 }
 
+static void initialize_frame_setting(FAR uint8_t *nr_fmt,
+                                     FAR video_format_t *fmt,
+                                     FAR struct v4l2_fract *interval)
+{
+  ASSERT(nr_fmt && fmt && interval);
+
+  /* Initial setting : QVGA YUV4:2:2 15FPS */
+
+  *nr_fmt = 1;
+  fmt[VIDEO_FMT_MAIN].width       = VIDEO_HSIZE_QVGA;
+  fmt[VIDEO_FMT_MAIN].height      = VIDEO_VSIZE_QVGA;
+  fmt[VIDEO_FMT_MAIN].pixelformat = V4L2_PIX_FMT_UYVY;
+  interval->denominator = 15;
+  interval->numerator   = 1;
+}
+
 static void initialize_streamresources(FAR video_type_inf_t *type_inf)
 {
   memset(type_inf, 0, sizeof(video_type_inf_t));
   type_inf->remaining_capnum = VIDEO_REMAINING_CAPNUM_INFINITY;
   nxsem_init(&type_inf->lock_state, 0, 1);
-  nxsem_init(&type_inf->wait_dma.dqbuf_wait_flg, 0, 0);
+  nxsem_init(&type_inf->wait_capture.dqbuf_wait_flg, 0, 0);
+  initialize_frame_setting(&type_inf->nr_fmt,
+                           type_inf->fmt,
+                           &type_inf->frame_interval);
   video_framebuff_init(&type_inf->bufinf);
 
   return;
 }
 
+static int32_t get_default_value(uint32_t id)
+{
+  int ret;
+  imgsensor_supported_value_t value;
+
+  if ((g_video_sensor_ops == NULL) ||
+      (g_video_sensor_ops->get_supported_value == NULL))
+    {
+      return -EINVAL;
+    }
+
+  ret = g_video_sensor_ops->get_supported_value(id, &value);
+  if (ret != OK)
+    {
+      /* Don't care(unsupported parameter) */
+
+      return 0;
+    }
+
+  switch (value.type)
+    {
+      case IMGSENSOR_CTRL_TYPE_INTEGER_MENU:
+        return value.u.discrete.default_value;
+
+      case IMGSENSOR_CTRL_TYPE_U8:
+      case IMGSENSOR_CTRL_TYPE_U16:
+      case IMGSENSOR_CTRL_TYPE_U32:
+
+        /* Don't care */
+
+        return 0;
+
+      default:
+        return value.u.range.default_value;
+    }
+}
+
+static int32_t initialize_scene_gamma(uint8_t **gamma)
+{
+  int ret;
+  imgsensor_supported_value_t sup_val;
+  imgsensor_value_t val;
+  int32_t sz;
+
+  *gamma = NULL;
+
+  ASSERT(g_video_sensor_ops);
+
+  if ((g_video_sensor_ops->get_supported_value == NULL) ||
+      (g_video_sensor_ops->get_value == NULL))
+    {
+      return -ENOTTY;
+    }
+
+  ret = g_video_sensor_ops->get_supported_value
+          (IMGSENSOR_ID_GAMMA_CURVE, &sup_val);
+  if (ret != OK)
+    {
+      /* Unsupported parameter */
+
+      return -EINVAL;
+    }
+
+  switch (sup_val.type)
+    {
+      case IMGSENSOR_CTRL_TYPE_U8:
+        sz = sup_val.u.elems.nr_elems * sizeof(uint8_t);
+        if (sz / sizeof(uint8_t) != sup_val.u.elems.nr_elems)
+          {
+            /* Multiplication overflow */
+
+            return -EINVAL;
+          }
+
+        break;
+
+      case IMGSENSOR_CTRL_TYPE_U16:
+        sz = sup_val.u.elems.nr_elems * sizeof(uint16_t);
+        if (sz / sizeof(uint16_t) != sup_val.u.elems.nr_elems)
+          {
+            /* Multiplication overflow */
+
+            return -EINVAL;
+          }
+
+        break;
+
+      default: /* IMGSENSOR_CTRL_TYPE_U32 */
+        sz = sup_val.u.elems.nr_elems * sizeof(uint32_t);
+        if (sz / sizeof(uint32_t) != sup_val.u.elems.nr_elems)
+          {
+            /* Multiplication overflow */
+
+            return -EINVAL;
+          }
+
+        break;
+    }
+
+  *gamma = malloc(sz);
+  val.p_u8 = (uint8_t *)*gamma;
+  g_video_sensor_ops->get_value(IMGSENSOR_ID_GAMMA_CURVE, sz, &val);
+  return sz;
+}
+
+static void initialize_scene_parameter(video_scene_params_t *sp)
+{
+  ASSERT(sp);
+
+  sp->brightness      = get_default_value(IMGSENSOR_ID_BRIGHTNESS);
+  sp->contrast        = get_default_value(IMGSENSOR_ID_CONTRAST);
+  sp->saturation      = get_default_value(IMGSENSOR_ID_SATURATION);
+  sp->hue             = get_default_value(IMGSENSOR_ID_HUE);
+  sp->awb             = get_default_value(IMGSENSOR_ID_AUTO_WHITE_BALANCE);
+  sp->red             = get_default_value(IMGSENSOR_ID_RED_BALANCE);
+  sp->blue            = get_default_value(IMGSENSOR_ID_BLUE_BALANCE);
+  sp->gamma           = get_default_value(IMGSENSOR_ID_GAMMA);
+  sp->gamma_curve_sz  = initialize_scene_gamma(&sp->gamma_curve);
+  sp->ev              = get_default_value(IMGSENSOR_ID_EXPOSURE);
+  sp->hflip_video     = get_default_value(IMGSENSOR_ID_HFLIP_VIDEO);
+  sp->vflip_video     = get_default_value(IMGSENSOR_ID_VFLIP_VIDEO);
+  sp->hflip_still     = get_default_value(IMGSENSOR_ID_HFLIP_STILL);
+  sp->vflip_still     = get_default_value(IMGSENSOR_ID_VFLIP_STILL);
+  sp->sharpness       = get_default_value(IMGSENSOR_ID_SHARPNESS);
+  sp->colorfx         = get_default_value(IMGSENSOR_ID_COLORFX);
+  sp->auto_brightness = get_default_value(IMGSENSOR_ID_AUTOBRIGHTNESS);
+  sp->rotate          = get_default_value(IMGSENSOR_ID_ROTATE);
+  sp->ae              = get_default_value(IMGSENSOR_ID_EXPOSURE_AUTO);
+  sp->exposure_time   = get_default_value(IMGSENSOR_ID_EXPOSURE_ABSOLUTE);
+  sp->focus           = get_default_value(IMGSENSOR_ID_FOCUS_ABSOLUTE);
+  sp->af              = get_default_value(IMGSENSOR_ID_FOCUS_AUTO);
+  sp->zoom            = get_default_value(IMGSENSOR_ID_ZOOM_ABSOLUTE);
+  sp->iris            = get_default_value(IMGSENSOR_ID_IRIS_ABSOLUTE);
+  sp->wb              = get_default_value(IMGSENSOR_ID_AUTO_N_PRESET_WB);
+  sp->wdr             = get_default_value(IMGSENSOR_ID_WIDE_DYNAMIC_RANGE);
+  sp->stabilization   = get_default_value(IMGSENSOR_ID_IMG_STABILIZATION);
+  sp->iso_auto        = get_default_value(IMGSENSOR_ID_ISO_SENSITIVITY_AUTO);
+  sp->iso             = get_default_value(IMGSENSOR_ID_ISO_SENSITIVITY);
+  sp->meter           = get_default_value(IMGSENSOR_ID_EXPOSURE_METERING);
+  sp->threea_lock     = get_default_value(IMGSENSOR_ID_3A_LOCK);
+  sp->led             = get_default_value(IMGSENSOR_ID_FLASH_LED_MODE);
+  sp->jpeg_quality    = get_default_value(IMGSENSOR_ID_JPEG_QUALITY);
+}
+
+static void initialize_scenes_parameter(void)
+{
+  int i;
+  video_scene_params_t *sp = &g_video_scene_parameter[0];
+
+  for (i = 0; i < VIDEO_SCENE_MAX; i++)
+    {
+      initialize_scene_parameter(sp++);
+    }
+}
+
 static void initialize_resources(FAR video_mng_t *vmng)
 {
   initialize_streamresources(&vmng->video_inf);
   initialize_streamresources(&vmng->still_inf);
+  initialize_scenes_parameter();
 
   return;
 }
@@ -410,7 +884,7 @@ static void initialize_resources(FAR video_mng_t *vmng)
 static void cleanup_streamresources(FAR video_type_inf_t *type_inf)
 {
   video_framebuff_uninit(&type_inf->bufinf);
-  nxsem_destroy(&type_inf->wait_dma.dqbuf_wait_flg);
+  nxsem_destroy(&type_inf->wait_capture.dqbuf_wait_flg);
   nxsem_destroy(&type_inf->lock_state);
   memset(type_inf, 0, sizeof(video_type_inf_t));
   type_inf->remaining_capnum = VIDEO_REMAINING_CAPNUM_INFINITY;
@@ -418,20 +892,42 @@ static void cleanup_streamresources(FAR video_type_inf_t *type_inf)
   return;
 }
 
+static void cleanup_scene_parameter(video_scene_params_t *sp)
+{
+  ASSERT(sp);
+
+  if (sp->gamma_curve)
+    {
+      free(sp->gamma_curve);
+    }
+}
+
+static void cleanup_scenes_parameter(void)
+{
+  int i;
+  video_scene_params_t *sp = &g_video_scene_parameter[0];
+
+  for (i = 0; i < VIDEO_SCENE_MAX; i++, sp++)
+    {
+      cleanup_scene_parameter(sp);
+    }
+}
+
 static void cleanup_resources(FAR video_mng_t *vmng)
 {
   /* clean up resource */
 
-  if ((vmng->video_inf.state == VIDEO_STATE_DMA) ||
-      (vmng->still_inf.state == VIDEO_STATE_DMA))
+  if ((vmng->video_inf.state == VIDEO_STATE_CAPTURE) ||
+      (vmng->still_inf.state == VIDEO_STATE_CAPTURE))
     {
-      /* If in DMA, stop */
+      /* If in capture, stop */
 
-      g_video_devops->cancel_dma();
+      g_video_data_ops->stop_capture();
     }
 
   cleanup_streamresources(&vmng->video_inf);
   cleanup_streamresources(&vmng->still_inf);
+  cleanup_scenes_parameter();
 
   return;
 }
@@ -463,10 +959,14 @@ static int video_open(FAR struct file *filep)
     {
       /* Only in first execution, open device */
 
-      ret = g_video_devops->open(priv);
+      ret = g_video_sensor_ops->init();
       if (ret == OK)
         {
-          initialize_resources(priv);
+          ret = g_video_data_ops->init();
+          if (ret == OK)
+            {
+              initialize_resources(priv);
+            }
         }
     }
 
@@ -499,7 +999,8 @@ static int video_close(FAR struct file *filep)
   if (priv->open_num == 0)
     {
       cleanup_resources(priv);
-      g_video_devops->close();
+      g_video_sensor_ops->uninit();
+      g_video_data_ops->uninit();
     }
 
   video_unlock(&priv->lock_open_num);
@@ -527,9 +1028,9 @@ static int video_reqbufs(FAR struct video_mng_s         *vmng,
 
   flags = enter_critical_section();
 
-  if (type_inf->state == VIDEO_STATE_DMA)
+  if (type_inf->state == VIDEO_STATE_CAPTURE)
     {
-      /* In DMA, REQBUFS is not permitted */
+      /* In capture, REQBUFS is not permitted */
 
       ret = -EPERM;
     }
@@ -595,13 +1096,17 @@ static int video_qbuf(FAR struct video_mng_s *vmng,
         }
       else
         {
-          container = video_framebuff_get_dma_container(&type_inf->bufinf);
+          container = video_framebuff_get_vacant_container
+                      (&type_inf->bufinf);
           if (container)
             {
-              g_video_devops->set_buftype(buf->type);
-              g_video_devops->set_buf(container->buf.m.userptr,
-                                      container->buf.length);
-              type_inf->state = VIDEO_STATE_DMA;
+              start_capture(buf->type,
+                            type_inf->nr_fmt,
+                            type_inf->fmt,
+                            &type_inf->frame_interval,
+                            container->buf.m.userptr,
+                            container->buf.length);
+              type_inf->state = VIDEO_STATE_CAPTURE;
             }
         }
     }
@@ -638,17 +1143,17 @@ static int video_dqbuf(FAR struct video_mng_s *vmng,
   container = video_framebuff_dq_valid_container(&type_inf->bufinf);
   if (container == NULL)
     {
-      /* Not yet done DMA. Wait done */
+      /* Not yet done capture. Wait done */
 
-      dqbuf_wait_flg = &type_inf->wait_dma.dqbuf_wait_flg;
+      dqbuf_wait_flg = &type_inf->wait_capture.dqbuf_wait_flg;
 
-      /* Loop until semaphore is unlocked by DMA done or DQCANCEL */
+      /* Loop until semaphore is unlocked by capture done or DQCANCEL */
 
       do
         {
           if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
             {
-              /* If start DMA condition is satisfied, start DMA */
+              /* If start capture condition is satisfied, start capture */
 
               flags = enter_critical_section();
               next_video_state = estimate_next_video_state
@@ -657,27 +1162,27 @@ static int video_dqbuf(FAR struct video_mng_s *vmng,
               leave_critical_section(flags);
             }
 
-          nxsem_wait(dqbuf_wait_flg);
+          nxsem_wait_uninterruptible(dqbuf_wait_flg);
         }
-      while (type_inf->wait_dma.waitend_cause ==
+      while (type_inf->wait_capture.waitend_cause ==
                    VIDEO_WAITEND_CAUSE_STILLSTOP);
 
-      container = type_inf->wait_dma.done_container;
+      container = type_inf->wait_capture.done_container;
 
       if (!container)
         {
-          /* Waking up without DMA data means abort.
+          /* Waking up without captured data means abort.
            * Therefore, Check cause.
            */
 
-          if (type_inf->wait_dma.waitend_cause
+          if (type_inf->wait_capture.waitend_cause
                == VIDEO_WAITEND_CAUSE_DQCANCEL)
             {
               return -ECANCELED;
             }
         }
 
-      type_inf->wait_dma.done_container = NULL;
+      type_inf->wait_capture.done_container = NULL;
     }
 
   memcpy(buf, &container->buf, sizeof(struct v4l2_buffer));
@@ -698,108 +1203,223 @@ static int video_cancel_dqbuf(FAR struct video_mng_s *vmng,
       return -EINVAL;
     }
 
-  if (!is_sem_waited(&type_inf->wait_dma.dqbuf_wait_flg))
+  if (!is_sem_waited(&type_inf->wait_capture.dqbuf_wait_flg))
     {
       /* In not waiting DQBUF case, return OK */
 
       return OK;
     }
 
-  type_inf->wait_dma.waitend_cause = VIDEO_WAITEND_CAUSE_DQCANCEL;
+  type_inf->wait_capture.waitend_cause = VIDEO_WAITEND_CAUSE_DQCANCEL;
 
-  /* If DMA is done before nxsem_post, cause is overwritten */
+  /* If capture is done before nxsem_post, cause is overwritten */
 
-  nxsem_post(&type_inf->wait_dma.dqbuf_wait_flg);
+  nxsem_post(&type_inf->wait_capture.dqbuf_wait_flg);
 
   return OK;
 }
 
-static int video_enum_fmt(FAR struct v4l2_fmtdesc *fmt)
+static int validate_frame_setting(enum v4l2_buf_type type,
+                                  uint8_t nr_fmt,
+                                  FAR video_format_t *vfmt,
+                                  FAR struct v4l2_fract *interval)
 {
   int ret;
+  imgdata_format_t df[MAX_VIDEO_FMT];
+  imgsensor_format_t sf[MAX_VIDEO_FMT];
+  imgdata_interval_t di;
+  imgsensor_interval_t si;
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->get_range_of_fmt == NULL))
+  ASSERT(vfmt && interval && g_video_sensor_ops && g_video_data_ops);
+
+  if ((g_video_sensor_ops->validate_frame_setting == NULL) ||
+      (g_video_data_ops->validate_frame_setting == NULL))
     {
-      return -EINVAL;
+      return -ENOTTY;
     }
 
-  ret = g_video_devops->get_range_of_fmt(fmt);
-
-  return ret;
-}
+  /* Return OK only in case both image data driver and
+   * image sensor driver support.
+   */
 
-static int video_enum_framesizes(FAR struct v4l2_frmsizeenum *frmsize)
-{
-  int ret;
+  convert_to_imgdatafmt(&vfmt[VIDEO_FMT_MAIN], &df[IMGDATA_FMT_MAIN]);
+  convert_to_imgdatafmt(&vfmt[VIDEO_FMT_SUB], &df[IMGDATA_FMT_SUB]);
+  convert_to_imgdatainterval(interval, &di);
+  convert_to_imgsensorfmt(&vfmt[VIDEO_FMT_MAIN], &sf[IMGSENSOR_FMT_MAIN]);
+  convert_to_imgsensorfmt(&vfmt[VIDEO_FMT_SUB], &sf[IMGSENSOR_FMT_SUB]);
+  convert_to_imgsensorinterval(interval, &si);
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->get_range_of_framesize == NULL))
+  ret = g_video_sensor_ops->validate_frame_setting(type, nr_fmt, sf, &si);
+  if (ret != OK)
     {
-      return -EINVAL;
+      return ret;
     }
 
-  ret = g_video_devops->get_range_of_framesize(frmsize);
-
-  return ret;
+  return g_video_data_ops->validate_frame_setting(nr_fmt, df, &di);
 }
 
-static int video_try_fmt(FAR struct v4l2_format *fmt)
+static int video_try_fmt(FAR struct video_mng_s *priv,
+                         FAR struct v4l2_format *v4l2)
 {
-  int ret;
+  FAR video_type_inf_t *type_inf;
+  uint8_t nr_fmt;
+  video_format_t vf[MAX_VIDEO_FMT];
+
+  ASSERT(priv && g_video_sensor_ops && g_video_data_ops);
+
+  if ((g_video_sensor_ops->validate_frame_setting == NULL) ||
+      (g_video_data_ops->validate_frame_setting == NULL))
+    {
+      return -ENOTTY;
+    }
+
+  if (v4l2 == NULL)
+    {
+      return -EINVAL;
+    }
 
-  if ((g_video_devops == NULL) || (g_video_devops->try_format == NULL))
+  type_inf = get_video_type_inf(priv, v4l2->type);
+  if (type_inf == NULL)
     {
       return -EINVAL;
     }
 
-  ret = g_video_devops->try_format(fmt);
+  switch (v4l2->fmt.pix.pixelformat)
+    {
+      case V4L2_PIX_FMT_SUBIMG_UYVY:
+      case V4L2_PIX_FMT_SUBIMG_RGB565:
+        if (type_inf->fmt[VIDEO_FMT_MAIN].pixelformat
+              != V4L2_PIX_FMT_JPEG_WITH_SUBIMG)
+          {
+            return -EPERM;
+          }
+
+        /* Validate both main image and subimage. */
 
-  return ret;
+        nr_fmt = 2;
+        memcpy(&vf[VIDEO_FMT_MAIN],
+               &type_inf->fmt[VIDEO_FMT_MAIN],
+               sizeof(video_format_t));
+        vf[VIDEO_FMT_SUB].width       = v4l2->fmt.pix.width;
+        vf[VIDEO_FMT_SUB].height      = v4l2->fmt.pix.height;
+        vf[VIDEO_FMT_SUB].pixelformat
+          = (v4l2->fmt.pix.pixelformat == V4L2_PIX_FMT_SUBIMG_UYVY) ?
+              V4L2_PIX_FMT_UYVY : V4L2_PIX_FMT_RGB565;
+
+        break;
+
+      case V4L2_PIX_FMT_UYVY:
+      case V4L2_PIX_FMT_RGB565:
+      case V4L2_PIX_FMT_JPEG:
+      case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:
+        nr_fmt = 1;
+        vf[VIDEO_FMT_MAIN].width       = v4l2->fmt.pix.width;
+        vf[VIDEO_FMT_MAIN].height      = v4l2->fmt.pix.height;
+        vf[VIDEO_FMT_MAIN].pixelformat = v4l2->fmt.pix.pixelformat;
+
+        break;
+
+      default:
+        return -EINVAL;
+    }
+
+  return validate_frame_setting(v4l2->type,
+                                nr_fmt,
+                                vf,
+                                &type_inf->frame_interval);
 }
 
 static int video_s_fmt(FAR struct video_mng_s *priv,
                        FAR struct v4l2_format *fmt)
 {
   int ret;
+  FAR video_type_inf_t *type_inf;
+
+  ret = video_try_fmt(priv, fmt);
+  if (ret != 0)
+    {
+      return ret;
+    }
 
-  if ((g_video_devops == NULL) || (g_video_devops->set_format == NULL))
+  type_inf = get_video_type_inf(priv, fmt->type);
+  if (type_inf == NULL)
     {
       return -EINVAL;
     }
 
-  ret = g_video_devops->set_format(fmt);
+  if (type_inf->state != VIDEO_STATE_STREAMOFF)
+    {
+      return -EBUSY;
+    }
 
-  return ret;
-}
+  switch (fmt->fmt.pix.pixelformat)
+    {
+      case V4L2_PIX_FMT_SUBIMG_UYVY:
+      case V4L2_PIX_FMT_SUBIMG_RGB565:
+        if (type_inf->fmt[VIDEO_FMT_MAIN].pixelformat
+              != V4L2_PIX_FMT_JPEG_WITH_SUBIMG)
+          {
+            return -EPERM;
+          }
 
-static int video_enum_frameintervals(FAR struct v4l2_frmivalenum *frmival)
-{
-  int ret;
+        type_inf->fmt[VIDEO_FMT_SUB].width  = fmt->fmt.pix.width;
+        type_inf->fmt[VIDEO_FMT_SUB].height = fmt->fmt.pix.height;
+        type_inf->fmt[VIDEO_FMT_SUB].pixelformat
+          = (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_SUBIMG_UYVY) ?
+              V4L2_PIX_FMT_UYVY : V4L2_PIX_FMT_RGB565;
+        type_inf->nr_fmt = 2;
+        break;
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->get_range_of_frameinterval == NULL))
-    {
-      return -EINVAL;
+      default:
+        type_inf->fmt[VIDEO_FMT_MAIN].width  = fmt->fmt.pix.width;
+        type_inf->fmt[VIDEO_FMT_MAIN].height = fmt->fmt.pix.height;
+        type_inf->fmt[VIDEO_FMT_MAIN].pixelformat
+          = fmt->fmt.pix.pixelformat;
+        type_inf->nr_fmt = 1;
+        break;
     }
 
-  ret = g_video_devops->get_range_of_frameinterval(frmival);
-
-  return ret;
+  return OK;
 }
 
 static int video_s_parm(FAR struct video_mng_s *priv,
                         FAR struct v4l2_streamparm *parm)
 {
   int ret;
+  FAR video_type_inf_t *type_inf;
+
+  ASSERT(g_video_sensor_ops && g_video_data_ops);
+
+  if ((g_video_sensor_ops->validate_frame_setting == NULL) ||
+      (g_video_data_ops->validate_frame_setting == NULL) ||
+      (parm == NULL))
+    {
+      return -EINVAL;
+    }
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->set_frameinterval == NULL))
+  type_inf = get_video_type_inf(priv, parm->type);
+  if (type_inf == NULL)
     {
       return -EINVAL;
     }
 
-  ret = g_video_devops->set_frameinterval(parm);
+  if (type_inf->state != VIDEO_STATE_STREAMOFF)
+    {
+      return -EBUSY;
+    }
+
+  ret = validate_frame_setting(parm->type,
+                               type_inf->nr_fmt,
+                               type_inf->fmt,
+                               &parm->parm.capture.timeperframe);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  memcpy(&type_inf->frame_interval,
+         &parm->parm.capture.timeperframe,
+         sizeof(struct v4l2_fract));
 
   return ret;
 }
@@ -891,14 +1511,29 @@ static int video_streamoff(FAR struct video_mng_s *vmng,
   return ret;
 }
 
-static int video_do_halfpush(bool enable)
+static int video_do_halfpush(FAR struct video_mng_s *priv, bool enable)
 {
-  if ((g_video_devops == NULL) || (g_video_devops->do_halfpush == NULL))
-    {
-      return -EINVAL;
-    }
+  int ret;
+  struct v4l2_ext_controls ext_controls;
+  struct v4l2_ext_control  control[2];
+
+  /* Replace to VIDIOC_S_EXT_CTRLS format */
 
-  return g_video_devops->do_halfpush(enable);
+  control[0].id    = V4L2_CID_3A_LOCK;
+  control[0].value = enable ?
+                     (V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE) : 0;
+  control[1].id    = V4L2_CID_AUTO_FOCUS_START;
+  control[1].value = enable ? true : false;
+
+  ext_controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
+  ext_controls.count      = 2;
+  ext_controls.controls   = control;
+
+  /* Execute VIDIOC_S_EXT_CTRLS */
+
+  ret = video_s_ext_ctrls(priv, &ext_controls);
+
+  return ret;
 }
 
 static int video_takepict_start(FAR struct video_mng_s *vmng,
@@ -906,8 +1541,9 @@ static int video_takepict_start(FAR struct video_mng_s *vmng,
 {
   irqstate_t           flags;
   enum video_state_e   next_video_state;
-  FAR vbuf_container_t *dma_container;
-  int                  ret = OK;
+  FAR vbuf_container_t *container;
+
+  int                  ret = OK;
 
   if (vmng == NULL)
     {
@@ -918,17 +1554,17 @@ static int video_takepict_start(FAR struct video_mng_s *vmng,
 
   if (vmng->still_inf.state != VIDEO_STATE_STREAMOFF)
     {
-    ret = -EPERM;
+      ret = -EPERM;
     }
   else
     {
       if (capture_num > 0)
         {
-         vmng->still_inf.remaining_capnum = capture_num;
+          vmng->still_inf.remaining_capnum = capture_num;
         }
       else
         {
-         vmng->still_inf.remaining_capnum = VIDEO_REMAINING_CAPNUM_INFINITY;
+          vmng->still_inf.remaining_capnum = VIDEO_REMAINING_CAPNUM_INFINITY;
         }
 
       /* Control video stream prior to still stream */
@@ -941,16 +1577,20 @@ static int video_takepict_start(FAR struct video_mng_s *vmng,
 
       leave_critical_section(flags);
 
-      dma_container = video_framebuff_get_dma_container
-                       (&vmng->still_inf.bufinf);
-      if (dma_container)
+      container = video_framebuff_get_vacant_container
+                             (&vmng->still_inf.bufinf);
+      if (container)
         {
-          /* Start video stream DMA */
+          /* Start still stream capture */
 
-          g_video_devops->set_buftype(V4L2_BUF_TYPE_STILL_CAPTURE);
-          g_video_devops->set_buf(dma_container->buf.m.userptr,
-                                  dma_container->buf.length);
-          vmng->still_inf.state = VIDEO_STATE_DMA;
+          start_capture(V4L2_BUF_TYPE_STILL_CAPTURE,
+                        vmng->still_inf.nr_fmt,
+                        vmng->still_inf.fmt,
+                        &vmng->still_inf.frame_interval,
+                        container->buf.m.userptr,
+                        container->buf.length);
+
+          vmng->still_inf.state = VIDEO_STATE_CAPTURE;
         }
       else
         {
@@ -984,9 +1624,9 @@ static int video_takepict_stop(FAR struct video_mng_s *vmng, bool halfpush)
   else
     {
       flags = enter_critical_section();
-      if (vmng->still_inf.state == VIDEO_STATE_DMA)
+      if (vmng->still_inf.state == VIDEO_STATE_CAPTURE)
         {
-          g_video_devops->cancel_dma();
+          g_video_data_ops->stop_capture();
         }
 
       leave_critical_section(flags);
@@ -1020,14 +1660,8 @@ static int video_queryctrl(FAR struct v4l2_queryctrl *ctrl)
 
   /* Replace to VIDIOC_QUERY_EXT_CTRL format */
 
-  ext_ctrl.ctrl_class     = ctrl->ctrl_class;
-  ext_ctrl.id             = ctrl->id;
-  ext_ctrl.type           = ctrl->type;
-  ext_ctrl.minimum        = ctrl->minimum;
-  ext_ctrl.maximum        = ctrl->maximum;
-  ext_ctrl.step           = ctrl->step;
-  ext_ctrl.default_value  = ctrl->default_value;
-  ext_ctrl.flags          = ctrl->flags;
+  ext_ctrl.ctrl_class = ctrl->ctrl_class;
+  ext_ctrl.id         = ctrl->id;
 
   ret = video_query_ext_ctrl(&ext_ctrl);
 
@@ -1059,34 +1693,161 @@ static int video_queryctrl(FAR struct v4l2_queryctrl *ctrl)
   return OK;
 }
 
-static int video_query_ext_ctrl(FAR struct v4l2_query_ext_ctrl *ctrl)
+static void set_parameter_name(uint32_t id, char *name)
+{
+  int cnt;
+  int size
+    = sizeof(g_video_parameter_name) / sizeof(video_parameter_name_t);
+
+  for (cnt = 0; cnt < size; cnt++)
+    {
+      if (g_video_parameter_name[cnt].id == id)
+        {
+          break;
+        }
+    }
+
+  ASSERT(cnt < size);
+
+  /* copy size = 32 is due to V4L2 specification. */
+
+  strncpy(name, g_video_parameter_name[cnt].name, 32);
+}
+
+static int video_query_ext_ctrl(FAR struct v4l2_query_ext_ctrl *attr)
 {
   int ret;
+  imgsensor_supported_value_t value;
+  imgsensor_capability_range_t *range = &value.u.range;
+  imgsensor_capability_discrete_t *disc = &value.u.discrete;
+  imgsensor_capability_elems_t *elem = &value.u.elems;
+
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->get_supported_value == NULL)
+    {
+      return -ENOTTY;
+    }
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->get_range_of_ctrlvalue == NULL))
+  if (attr == NULL)
     {
       return -EINVAL;
     }
 
-  ret = g_video_devops->get_range_of_ctrlvalue(ctrl);
+  if ((attr->ctrl_class == V4L2_CTRL_CLASS_CAMERA) &&
+      (attr->id == V4L2_CID_SCENE_MODE))
+    {
+      /* Scene mode is processed in only video driver. */
 
-  return ret;
+      attr->type          = V4L2_CTRL_TYPE_INTEGER_MENU;
+      attr->minimum       = 0;
+      attr->maximum       = VIDEO_SCENE_MAX - 1;
+      attr->step          = 1;
+      attr->default_value = 0;
+      strncpy(attr->name, "Scene Mode", 32);
+    }
+  else
+    {
+      ret = g_video_sensor_ops->get_supported_value
+              (VIDEO_ID(attr->ctrl_class, attr->id),
+               &value);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      attr->type = value.type;
+
+      switch (value.type)
+        {
+          case IMGSENSOR_CTRL_TYPE_INTEGER_MENU:
+            attr->minimum       = 0;
+            attr->maximum       = disc->nr_values - 1;
+            attr->step          = 1;
+            attr->default_value = disc->default_value;
+            break;
+
+          case IMGSENSOR_CTRL_TYPE_U8:
+          case IMGSENSOR_CTRL_TYPE_U16:
+          case IMGSENSOR_CTRL_TYPE_U32:
+            attr->minimum = elem->minimum;
+            attr->maximum = elem->maximum;
+            attr->step    = elem->step;
+            attr->elems   = elem->nr_elems;
+            break;
+
+          default:
+            attr->minimum       = range->minimum;
+            attr->maximum       = range->maximum;
+            attr->step          = range->step;
+            attr->default_value = range->default_value;
+            break;
+        }
+
+      set_parameter_name(VIDEO_ID(attr->ctrl_class, attr->id),
+                         attr->name);
+    }
+
+  return OK;
 }
 
 static int video_querymenu(FAR struct v4l2_querymenu *menu)
 {
   int ret;
+  imgsensor_supported_value_t value;
+
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->get_supported_value == NULL)
+    {
+      return -ENOTTY;
+    }
 
-  if ((g_video_devops == NULL) ||
-      (g_video_devops->get_menu_of_ctrlvalue == NULL))
+  if (menu == NULL)
     {
       return -EINVAL;
     }
 
-  ret = g_video_devops->get_menu_of_ctrlvalue(menu);
+  if ((menu->ctrl_class == V4L2_CTRL_CLASS_CAMERA) &&
+      (menu->id == V4L2_CID_SCENE_MODE))
+    {
+      /* Scene mode is processed in only video driver. */
 
-  return ret;
+      if (menu->index > VIDEO_SCENE_MAX - 1)
+        {
+          return -EINVAL;
+        }
+
+      menu->value = g_video_scene_parameter[menu->index].mode;
+    }
+  else
+    {
+      ret = g_video_sensor_ops->get_supported_value
+              (VIDEO_ID(menu->ctrl_class, menu->id),
+               &value);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      if (value.type != IMGSENSOR_CTRL_TYPE_INTEGER_MENU)
+        {
+          /* VIDIOC_QUERYMENU is used only for
+           * IMGSENSOR_CTRL_TYPE_INTEGER_MENU.
+           */
+
+          return -EINVAL;
+        }
+
+      if (menu->index >= value.u.discrete.nr_values)
+        {
+          return -EINVAL;
+        }
+
+      menu->value = value.u.discrete.values[menu->index];
+    }
+
+  return OK;
 }
 
 static int video_g_ctrl(FAR struct video_mng_s *priv,
@@ -1158,6 +1919,13 @@ static int video_g_ext_ctrls(FAR struct video_mng_s *priv,
   int cnt;
   FAR struct v4l2_ext_control *control;
 
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->get_value == NULL)
+    {
+      return -ENOTTY;
+    }
+
   if ((priv == NULL) || (ctrls == NULL))
     {
       return -EINVAL;
@@ -1167,8 +1935,10 @@ static int video_g_ext_ctrls(FAR struct video_mng_s *priv,
        cnt < ctrls->count;
        cnt++, control++)
     {
-      ret = g_video_devops->get_ctrlvalue(ctrls->ctrl_class, control);
-
+      ret = g_video_sensor_ops->get_value
+              (VIDEO_ID(ctrls->ctrl_class, control->id),
+               control->size,
+               (imgsensor_value_t *)&control->value64);
       if (ret < 0)
         {
           /* Set cnt in that error occurred */
@@ -1181,6 +1951,117 @@ static int video_g_ext_ctrls(FAR struct video_mng_s *priv,
   return ret;
 }
 
+static int set_intvalue(uint32_t id, int32_t value32)
+{
+  imgsensor_value_t value;
+
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->set_value == NULL)
+    {
+      return -ENOTTY;
+    }
+
+  value.value32 = value32;
+  return g_video_sensor_ops->set_value(id, sizeof(int32_t), value);
+}
+
+static int set_pvalue(uint32_t id, int size, void *pval)
+{
+  imgsensor_value_t value;
+
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->set_value == NULL)
+    {
+      return -ENOTTY;
+    }
+
+  value.p_u8 = (uint8_t *)pval;
+  return g_video_sensor_ops->set_value(id, size, value);
+}
+
+static video_scene_params_t *search_scene_param(enum v4l2_scene_mode mode)
+{
+  int i;
+  video_scene_params_t *sp = &g_video_scene_parameter[0];
+
+  for (i = 0; i < VIDEO_SCENE_MAX; i++, sp++)
+    {
+      if (sp->mode == mode)
+        {
+          return sp;
+        }
+    }
+
+  return NULL;
+}
+
+static int reflect_scene_parameter(enum v4l2_scene_mode mode)
+{
+  video_scene_params_t *sp;
+
+  sp = search_scene_param(mode);
+  if (sp == NULL)
+    {
+      /* Unsupported scene mode */
+
+      return -EINVAL;
+    }
+
+  set_intvalue(IMGSENSOR_ID_BRIGHTNESS, sp->brightness);
+  set_intvalue(IMGSENSOR_ID_CONTRAST, sp->contrast);
+  set_intvalue(IMGSENSOR_ID_SATURATION, sp->saturation);
+  set_intvalue(IMGSENSOR_ID_HUE , sp->hue);
+  set_intvalue(IMGSENSOR_ID_AUTO_WHITE_BALANCE, sp->awb);
+  set_intvalue(IMGSENSOR_ID_RED_BALANCE , sp->red);
+  set_intvalue(IMGSENSOR_ID_BLUE_BALANCE, sp->blue);
+  set_intvalue(IMGSENSOR_ID_GAMMA, sp->gamma);
+  set_pvalue(IMGSENSOR_ID_GAMMA_CURVE, sp->gamma_curve_sz, sp->gamma_curve);
+  set_intvalue(IMGSENSOR_ID_EXPOSURE, sp->ev);
+  set_intvalue(IMGSENSOR_ID_HFLIP_VIDEO, sp->hflip_video);
+  set_intvalue(IMGSENSOR_ID_VFLIP_VIDEO, sp->vflip_video);
+  set_intvalue(IMGSENSOR_ID_HFLIP_STILL, sp->hflip_still);
+  set_intvalue(IMGSENSOR_ID_VFLIP_STILL, sp->vflip_still);
+  set_intvalue(IMGSENSOR_ID_SHARPNESS, sp->sharpness);
+  set_intvalue(IMGSENSOR_ID_COLORFX, sp->colorfx);
+  set_intvalue(IMGSENSOR_ID_AUTOBRIGHTNESS, sp->auto_brightness);
+  set_intvalue(IMGSENSOR_ID_ROTATE, sp->rotate);
+  set_intvalue(IMGSENSOR_ID_EXPOSURE_AUTO, sp->ae);
+  if ((sp->ae == V4L2_EXPOSURE_MANUAL) ||
+      (sp->ae == V4L2_EXPOSURE_SHUTTER_PRIORITY))
+    {
+      set_intvalue(IMGSENSOR_ID_EXPOSURE_ABSOLUTE, sp->exposure_time);
+    }
+
+  set_intvalue(IMGSENSOR_ID_FOCUS_ABSOLUTE, sp->focus);
+  set_intvalue(IMGSENSOR_ID_FOCUS_AUTO, sp->af);
+  set_intvalue(IMGSENSOR_ID_ZOOM_ABSOLUTE, sp->zoom);
+  if ((sp->ae == V4L2_EXPOSURE_MANUAL) ||
+      (sp->ae == V4L2_EXPOSURE_APERTURE_PRIORITY))
+    {
+      set_intvalue(IMGSENSOR_ID_IRIS_ABSOLUTE, sp->iris);
+    }
+
+  set_intvalue(IMGSENSOR_ID_AUTO_N_PRESET_WB, sp->wb);
+  set_intvalue(IMGSENSOR_ID_WIDE_DYNAMIC_RANGE, sp->wdr);
+  set_intvalue(IMGSENSOR_ID_IMG_STABILIZATION, sp->stabilization);
+  set_intvalue(IMGSENSOR_ID_ISO_SENSITIVITY_AUTO, sp->iso_auto);
+  if (sp->iso_auto == V4L2_ISO_SENSITIVITY_MANUAL)
+    {
+      set_intvalue(IMGSENSOR_ID_ISO_SENSITIVITY, sp->iso);
+    }
+
+  set_intvalue(IMGSENSOR_ID_EXPOSURE_METERING, sp->meter);
+  set_intvalue(IMGSENSOR_ID_3A_LOCK, sp->threea_lock);
+  set_intvalue(IMGSENSOR_ID_FLASH_LED_MODE, sp->led);
+  set_intvalue(IMGSENSOR_ID_JPEG_QUALITY, sp->jpeg_quality);
+
+  g_video_scene_mode = mode;
+
+  return OK;
+}
+
 static int video_s_ext_ctrls(FAR struct video_mng_s *priv,
                              FAR struct v4l2_ext_controls *ctrls)
 {
@@ -1188,6 +2069,13 @@ static int video_s_ext_ctrls(FAR struct video_mng_s *priv,
   int cnt;
   FAR struct v4l2_ext_control *control;
 
+  ASSERT(g_video_sensor_ops);
+
+  if (g_video_sensor_ops->set_value == NULL)
+    {
+      return -ENOTTY;
+    }
+
   if ((priv == NULL) || (ctrls == NULL))
     {
       return -EINVAL;
@@ -1197,7 +2085,28 @@ static int video_s_ext_ctrls(FAR struct video_mng_s *priv,
        cnt < ctrls->count;
        cnt++, control++)
     {
-      ret = g_video_devops->set_ctrlvalue(ctrls->ctrl_class, control);
+      if ((ctrls->ctrl_class == V4L2_CTRL_CLASS_CAMERA) &&
+          (control->id == V4L2_CID_SCENE_MODE))
+        {
+          ret = reflect_scene_parameter(control->value);
+        }
+      else
+        {
+          ret = g_video_sensor_ops->set_value
+                  (VIDEO_ID(ctrls->ctrl_class, control->id),
+                   control->size,
+                   (imgsensor_value_t)control->value64);
+          if (ret == 0)
+            {
+              if (g_video_scene_mode == V4L2_SCENE_MODE_NONE)
+                {
+                  save_scene_param
+                  (V4L2_SCENE_MODE_NONE,
+                   VIDEO_ID(ctrls->ctrl_class, control->id),
+                   control);
+                }
+            }
+        }
 
       if (ret < 0)
         {
@@ -1211,184 +2120,692 @@ static int video_s_ext_ctrls(FAR struct video_mng_s *priv,
   return ret;
 }
 
-/****************************************************************************
- * Name: video_ioctl
- *
- * Description:
- *   Standard character driver ioctl method.
- *
- ****************************************************************************/
-
-static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+static int video_query_ext_ctrl_scene
+             (FAR struct v4s_query_ext_ctrl_scene *attr)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR video_mng_t  *priv  = (FAR video_mng_t *)inode->i_private;
-  int ret = OK;
+  if (attr == NULL)
+    {
+      return -EINVAL;
+    }
 
-  switch (cmd)
+  return video_query_ext_ctrl(&attr->control);
+}
+
+static int video_querymenu_scene(FAR struct v4s_querymenu_scene *menu)
+{
+  if (menu == NULL)
     {
-      case VIDIOC_REQBUFS:
-        ret = video_reqbufs(priv, (FAR struct v4l2_requestbuffers *)arg);
+      return -EINVAL;
+    }
 
-        break;
+  return video_querymenu(&menu->menu);
+}
 
-      case VIDIOC_QBUF:
-        ret = video_qbuf(priv, (FAR struct v4l2_buffer *)arg);
+static int read_scene_param(enum v4l2_scene_mode mode,
+                            uint32_t id,
+                            struct v4l2_ext_control *control)
+{
+  int ret = OK;
... 1915 lines suppressed ...