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:41 UTC

[incubator-nuttx] branch master updated (b991b75 -> 050ee01)

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

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


    from b991b75  net/local: add FIONSPACE support
     new 74df4b7  drivers: video: Rearchitect video driver
     new a4fcd65  boards: cxd56xx: Update defconfig of camera example
     new ebd7362  drivers/video: Replace error output macro to verr
     new 050ee01  boards: cxd56xx: Add VIDEO configuration to mpy defconfig

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Kconfig                                            |   32 +
 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 --------------------
 .../spresense/configs/example_camera/defconfig     |   13 +-
 boards/arm/cxd56xx/spresense/configs/mpy/defconfig |    2 +
 boards/arm/cxd56xx/spresense/src/cxd56_bringup.c   |   19 +-
 drivers/video/Kconfig                              |   86 +
 drivers/video/Make.defs                            |    4 +
 drivers/video/isx012.c                             | 2899 +++++++++++++++
 {include/nuttx => drivers}/video/isx012_range.h    |   32 +-
 {include/nuttx => drivers}/video/isx012_reg.h      |   16 +-
 drivers/video/video.c                              | 2076 +++++++++--
 drivers/video/video_framebuff.c                    |   59 +-
 drivers/video/video_framebuff.h                    |   16 +-
 include/debug.h                                    |   18 +
 include/nuttx/{net/neighbor.h => video/imgdata.h}  |   93 +-
 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 -
 26 files changed, 5670 insertions(+), 4691 deletions(-)
 delete mode 100644 boards/arm/cxd56xx/drivers/camera/Kconfig
 delete mode 100644 boards/arm/cxd56xx/drivers/camera/Make.defs
 delete mode 100644 boards/arm/cxd56xx/drivers/camera/isx012.c
 create mode 100644 drivers/video/isx012.c
 rename {include/nuttx => drivers}/video/isx012_range.h (87%)
 rename {include/nuttx => drivers}/video/isx012_reg.h (98%)
 copy include/nuttx/{net/neighbor.h => video/imgdata.h} (51%)
 create mode 100644 include/nuttx/video/imgsensor.h
 delete mode 100644 include/nuttx/video/video_halif.h

[incubator-nuttx] 02/04: boards: cxd56xx: Update defconfig of camera example

Posted by je...@apache.org.
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 a4fcd654a44b9edb06717f88051aa7198c023f76
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed Sep 15 12:06:03 2021 +0900

    boards: cxd56xx: Update defconfig of camera example
    
    Add LCD and NX configurations to camera example as apps/examples/camera changes.
---
 .../arm/cxd56xx/spresense/configs/example_camera/defconfig  | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig b/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig
index 96ac632..fae7fd7 100644
--- a/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig
+++ b/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig
@@ -9,6 +9,8 @@
 # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set
 # CONFIG_MMCSD_SPI is not set
 # CONFIG_MTD_SMART_WEAR_LEVEL is not set
+# CONFIG_NXFONTS_DISABLE_16BPP is not set
+# CONFIG_NX_DISABLE_16BPP is not set
 # CONFIG_STANDARD_SERIAL is not set
 CONFIG_ARCH="arm"
 CONFIG_ARCH_BOARD="spresense"
@@ -26,7 +28,7 @@ CONFIG_CXD56_CISIF=y
 CONFIG_CXD56_I2C0=y
 CONFIG_CXD56_I2C2=y
 CONFIG_CXD56_I2C=y
-CONFIG_CXD56_SPI4=y
+CONFIG_CXD56_SDIO=y
 CONFIG_CXD56_SPI5=y
 CONFIG_CXD56_SPI=y
 CONFIG_CXD56_USBDEV=y
@@ -34,6 +36,7 @@ CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
 CONFIG_DRIVERS_VIDEO=y
 CONFIG_EXAMPLES_CAMERA=y
+CONFIG_EXAMPLES_CAMERA_OUTPUT_LCD=y
 CONFIG_FAT_LCNAMES=y
 CONFIG_FAT_LFN=y
 CONFIG_FAT_MAXFNAME=255
@@ -43,8 +46,13 @@ CONFIG_FS_PROCFS_REGISTER=y
 CONFIG_FS_SMARTFS=y
 CONFIG_HAVE_CXX=y
 CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_LCD=y
+CONFIG_LCD_ILI9340=y
+CONFIG_LCD_ILI9340_IFACE0=y
+CONFIG_LCD_ILI9340_IFACE0_RLANDSCAPE=y
 CONFIG_MMCSD=y
 CONFIG_MMCSD_SDIO=y
+CONFIG_MQ_MAXMSGSIZE=64
 CONFIG_MTD_BYTE_WRITE=y
 CONFIG_MTD_PARTITION=y
 CONFIG_MTD_SMART=y
@@ -54,6 +62,9 @@ CONFIG_NAME_MAX=765
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_READLINE=y
+CONFIG_NX=y
+CONFIG_NXFONT_SERIF22X29=y
+CONFIG_NX_BLOCKING=y
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=1572864
 CONFIG_RAM_START=0x0d000000

[incubator-nuttx] 04/04: boards: cxd56xx: Add VIDEO configuration to mpy defconfig

Posted by je...@apache.org.
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 050ee011e5ad2b63754bfb50c0110a5bf1c441fc
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed Sep 15 12:09:15 2021 +0900

    boards: cxd56xx: Add VIDEO configuration to mpy defconfig
    
    New CISIF which supports rearchitected video driver needs VIDEO configuration.
    Add VIDEO configuration because mpy defconfig includes CISIF.
---
 boards/arm/cxd56xx/spresense/configs/mpy/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/boards/arm/cxd56xx/spresense/configs/mpy/defconfig b/boards/arm/cxd56xx/spresense/configs/mpy/defconfig
index ebd22f3..9b98ef1 100644
--- a/boards/arm/cxd56xx/spresense/configs/mpy/defconfig
+++ b/boards/arm/cxd56xx/spresense/configs/mpy/defconfig
@@ -43,6 +43,7 @@ CONFIG_CXD56_UART2=y
 CONFIG_CXD56_USBDEV=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DRIVERS_VIDEO=y
 CONFIG_FAT_LCNAMES=y
 CONFIG_FAT_LFN=y
 CONFIG_FAT_MAXFNAME=255
@@ -93,3 +94,4 @@ CONFIG_USBMSC=y
 CONFIG_USBMSC_EPBULKIN=1
 CONFIG_USBMSC_REMOVABLE=y
 CONFIG_USER_ENTRYPOINT="spresense_main"
+CONFIG_VIDEO_STREAM=y

[incubator-nuttx] 03/04: drivers/video: Replace error output macro to verr

Posted by je...@apache.org.
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 ebd736240eca90030866c5feeed33f8f73cb7967
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed Sep 15 12:06:31 2021 +0900

    drivers/video: Replace error output macro to verr
    
    Add video debug macros verr/vwarn/vinfo, and replace error output macro to verr.
---
 Kconfig                | 32 +++++++++++++++++++++++
 drivers/video/isx012.c | 70 +++++++++++++++++++-------------------------------
 drivers/video/video.c  | 27 +++----------------
 include/debug.h        | 18 +++++++++++++
 4 files changed, 80 insertions(+), 67 deletions(-)

diff --git a/Kconfig b/Kconfig
index 2401cf3..3441d5d 100644
--- a/Kconfig
+++ b/Kconfig
@@ -1774,6 +1774,38 @@ config DEBUG_MOTOR_INFO
 		Enable motor informational output to SYSLOG.
 
 endif # DEBUG_MOTOR
+
+config DEBUG_VIDEO
+        bool "Video Debug Features"
+        default n
+        depends on DRIVERS_VIDEO
+        ---help---
+                Enable video debug features.
+
+if DEBUG_VIDEO
+
+config DEBUG_VIDEO_ERROR
+        bool "Video Error Output"
+        default n
+        depends on DEBUG_ERROR
+        ---help---
+                Enable video error output to SYSLOG.
+
+config DEBUG_VIDEO_WARN
+        bool "Video Warnings Output"
+        default n
+        depends on DEBUG_WARN
+        ---help---
+                Enable video warning output to SYSLOG.
+
+config DEBUG_VIDEO_INFO
+        bool "Video Informational Output"
+        default n
+        depends on DEBUG_INFO
+        ---help---
+                Enable video informational output to SYSLOG.
+
+endif # DEBUG_VIDEO
 endif # DEBUG_FEATURES
 
 config ARCH_HAVE_STACKCHECK
diff --git a/drivers/video/isx012.c b/drivers/video/isx012.c
index 62630e6..2d99813 100644
--- a/drivers/video/isx012.c
+++ b/drivers/video/isx012.c
@@ -135,24 +135,6 @@
 
 #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) ? \
@@ -667,7 +649,7 @@ static uint16_t isx012_getreg(isx012_dev_t *priv,
   ret = i2c_write(priv->i2c, &config, (uint8_t *)buffer, 2);
   if (ret < 0)
     {
-      imagererr("i2c_write failed: %d\n", ret);
+      verr("i2c_write failed: %d\n", ret);
       return 0;
     }
 
@@ -676,7 +658,7 @@ static uint16_t isx012_getreg(isx012_dev_t *priv,
   ret = i2c_read(priv->i2c, &config, (uint8_t *)buffer, regsize);
   if (ret < 0)
     {
-      imagererr("i2c_read failed: %d\n", ret);
+      verr("i2c_read failed: %d\n", ret);
       return 0;
     }
 
@@ -711,7 +693,7 @@ static int isx012_putreg(isx012_dev_t *priv,
                  (uint8_t *)buffer, regsize + 2);
   if (ret < 0)
     {
-      imagererr("i2c_write failed: %d\n", ret);
+      verr("i2c_write failed: %d\n", ret);
     }
 
   return ret;
@@ -730,7 +712,7 @@ static int isx012_putreglist(isx012_dev_t *priv,
                           entry->regval, entry->regsize);
       if (ret < 0)
         {
-          imagererr("isx012_putreg failed: %d\n", ret);
+          verr("isx012_putreg failed: %d\n", ret);
           return ret;
         }
     }
@@ -1185,7 +1167,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
   ret = isx012_chipid(priv);
   if (ret < 0)
     {
-      imagererr("isx012_chipid failed: %d\n", ret);
+      verr("isx012_chipid failed: %d\n", ret);
       board_isx012_set_reset();
       return ret;
     }
@@ -1197,7 +1179,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
                              DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
   if (ret != OK)
     {
-      imagererr("OM_CHANGED_STS(PreSleep) is Not occurred: %d\n", ret);
+      verr("OM_CHANGED_STS(PreSleep) is Not occurred: %d\n", ret);
       return ret;
     }
 
@@ -1211,7 +1193,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
   ret = isx012_putreglist(priv, g_isx012_presleep, ISX012_PRESLEEP_NENTRIES);
   if (ret != OK)
     {
-      imagererr("isx012_putreglist(INCK_SET) failed: %d\n", ret);
+      verr("isx012_putreglist(INCK_SET) failed: %d\n", ret);
       return ret;
     }
 
@@ -1221,7 +1203,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
                              DEVICE_STATE_WAIT_TIME, DEVICE_STATE_TIMEOUT);
   if (ret != OK)
     {
-      imagererr("OM_CHANGED_STS(Sleep) is Not occurred: %d\n", ret);
+      verr("OM_CHANGED_STS(Sleep) is Not occurred: %d\n", ret);
       return ret;
     }
 #endif
@@ -1234,7 +1216,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
   ret = isx012_putreglist(priv, g_isx012_def_init, ISX012_RESET_NENTRIES);
   if (ret < 0)
     {
-      imagererr("isx012_putreglist failed: %d\n", ret);
+      verr("isx012_putreglist failed: %d\n", ret);
       board_isx012_set_reset();
       return ret;
     }
@@ -1244,7 +1226,7 @@ int init_isx012(FAR struct isx012_dev_s *priv)
   ret = isx012_set_shd(priv);
   if (ret < 0)
     {
-      imagererr("isx012_set_shd failed: %d\n", ret);
+      verr("isx012_set_shd failed: %d\n", ret);
       board_isx012_set_reset();
       return ret;
     }
@@ -1260,14 +1242,14 @@ static int isx012_init(void)
   ret = board_isx012_power_on();
   if (ret < 0)
     {
-      imagererr("Failed to power on %d\n", ret);
+      verr("Failed to power on %d\n", ret);
       return ret;
     }
 
   ret = init_isx012(priv);
   if (ret < 0)
     {
-      imagererr("Failed to init_isx012 %d\n", ret);
+      verr("Failed to init_isx012 %d\n", ret);
       board_isx012_set_reset();
       board_isx012_power_off();
       return ret;
@@ -1292,7 +1274,7 @@ static int isx012_uninit(void)
   ret = board_isx012_power_off();
   if (ret < 0)
     {
-      imagererr("Failed to power off %d\n", ret);
+      verr("Failed to power off %d\n", ret);
       return ret;
     }
 
@@ -2703,7 +2685,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
   ret = isx012_putreg(priv, SHD_EN, 0x50, 1);
   if (ret < 0)
     {
-      imagererr("isx012_putreg(disable CXC/SHD) failed: %d\n", ret);
+      verr("isx012_putreg(disable CXC/SHD) failed: %d\n", ret);
       return ret;
     }
 
@@ -2712,7 +2694,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
   ret = isx012_putreg(priv, CXC_VALID, 0x8282, 2);
   if (ret < 0)
     {
-      imagererr("isx012_putreg(CXC_VALID) failed: %d\n", ret);
+      verr("isx012_putreg(CXC_VALID) failed: %d\n", ret);
       return ret;
     }
 
@@ -2728,7 +2710,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(CXC R Gb) failed: %d\n", ret);
+              verr("isx012_putreg(CXC R Gb) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2746,7 +2728,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(CXC G Rb) failed: %d\n", ret);
+              verr("isx012_putreg(CXC G Rb) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2757,7 +2739,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
   ret = isx012_putreg(priv, SHD_VALID, 0x9191, 2);
   if (ret < 0)
     {
-      imagererr("isx012_putreg(SHD_VALID) failed: %d\n", ret);
+      verr("isx012_putreg(SHD_VALID) failed: %d\n", ret);
       return ret;
     }
 
@@ -2773,7 +2755,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(SHD R Gb) failed: %d\n", ret);
+              verr("isx012_putreg(SHD R Gb) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2791,7 +2773,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(SHD G Rb) failed: %d\n", ret);
+              verr("isx012_putreg(SHD G Rb) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2809,7 +2791,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(SHD R1) failed: %d\n", ret);
+              verr("isx012_putreg(SHD R1) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2827,7 +2809,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(SHD R2) failed: %d\n", ret);
+              verr("isx012_putreg(SHD R2) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2845,7 +2827,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                               1);
           if (ret < 0)
             {
-              imagererr("isx012_putreg(SHD B2) failed: %d\n", ret);
+              verr("isx012_putreg(SHD B2) failed: %d\n", ret);
               return ret;
             }
         }
@@ -2857,7 +2839,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
                           ISX012_SHD_THRESHOLDS_NENTRIES);
   if (ret < 0)
     {
-      imagererr("isx012_putreglist failed(SHD thresholds): %d\n", ret);
+      verr("isx012_putreglist failed(SHD thresholds): %d\n", ret);
       board_isx012_set_reset();
       return ret;
     }
@@ -2867,7 +2849,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
   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);
+      verr("isx012_putreglist(SHD white balance) failed: %d\n", ret);
       board_isx012_set_reset();
       return ret;
     }
@@ -2877,7 +2859,7 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
   ret = isx012_putreg(priv, SHD_EN, 0x57, 1);
   if (ret < 0)
     {
-      imagererr("isx012_putreg(enable CXC/SHD) failed: %d\n", ret);
+      verr("isx012_putreg(enable CXC/SHD) failed: %d\n", ret);
       return ret;
     }
 
diff --git a/drivers/video/video.c b/drivers/video/video.c
index 6b9c1e9..e5bb203 100644
--- a/drivers/video/video.c
+++ b/drivers/video/video.c
@@ -25,6 +25,7 @@
 
 #include <sys/ioctl.h>
 
+#include <debug.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -55,26 +56,6 @@
 
 #define VIDEO_REMAINING_CAPNUM_INFINITY (-1)
 
-/* Debug option */
-
-#ifdef CONFIG_DEBUG_VIDEO_ERROR
-#define videoerr(format, ...)     _err(format, ##__VA_ARGS__)
-#else
-#define videoerr(x...)
-#endif
-
-#ifdef CONFIG_DEBUG_VIDEO_WARN
-#define videowarn(format, ...)   _warn(format, ##__VA_ARGS__)
-#else
-#define videowarn(x...)
-#endif
-
-#ifdef CONFIG_DEBUG_VIDEO_INFO
-#define videoinfo(format, ...)   _info(format, ##__VA_ARGS__)
-#else
-#define videoinfo(x...)
-#endif
-
 #define VIDEO_SCENE_MAX (sizeof(g_video_scene_parameter) / \
                          sizeof(video_scene_params_t))
 
@@ -2795,7 +2776,7 @@ static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         break;
 
       default:
-        videoerr("Unrecognized cmd: %d\n", cmd);
+        verr("Unrecognized cmd: %d\n", cmd);
         ret = - ENOTTY;
         break;
     }
@@ -2830,7 +2811,7 @@ static FAR void *video_register(FAR const char *devpath)
   priv = (FAR video_mng_t *)kmm_malloc(sizeof(video_mng_t));
   if (!priv)
     {
-      videoerr("Failed to allocate instance\n");
+      verr("Failed to allocate instance\n");
       return NULL;
     }
 
@@ -2857,7 +2838,7 @@ static FAR void *video_register(FAR const char *devpath)
   ret = register_driver(priv->devpath, &g_video_fops, 0666, priv);
   if (ret < 0)
     {
-      videoerr("Failed to register driver: %d\n", ret);
+      verr("Failed to register driver: %d\n", ret);
       kmm_free(priv->devpath);
       kmm_free(priv);
       return NULL;
diff --git a/include/debug.h b/include/debug.h
index a869897..995020b 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -754,6 +754,24 @@
 #  define mtrinfo     _none
 #endif
 
+#ifdef CONFIG_DEBUG_VIDEO_ERROR
+#  define verr        _err
+#else
+#  define verr        _none
+#endif
+
+#ifdef CONFIG_DEBUG_VIDEO_WARN
+#  define vwarn       _warn
+#else
+#  define vwarn       _none
+#endif
+
+#ifdef CONFIG_DEBUG_VIDEO_INFO
+#  define vinfo       _info
+#else
+#  define vinfo       _none
+#endif
+
 /* Buffer dumping macros do not depend on varargs */
 
 #ifdef CONFIG_DEBUG_ERROR

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

Posted by je...@apache.org.
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 ...