You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2021/09/15 05:06:42 UTC
[incubator-nuttx] 01/04: drivers: video: Rearchitect video driver
This is an automated email from the ASF dual-hosted git repository.
jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 74df4b70b30132e94b8ca079223ddfe25d00dea5
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed Sep 15 12:02:33 2021 +0900
drivers: video: Rearchitect video driver
Rearchitect video driver:
- Define two video I/F(struct imgsensor_ops_s and struct imgdata_ops_s),
and support them.
- CISIF driver supports new video I/F struct imgdata_ops_s.
- ISX012 driver supports new video I/F struct imgsensor_ops_s.
- Move ISX012 driver to general driver directory.
---
arch/arm/include/cxd56xx/cisif.h | 54 +-
arch/arm/src/cxd56xx/cxd56_cisif.c | 474 ++-
boards/arm/cxd56xx/common/src/cxd56_isx012.c | 8 +-
boards/arm/cxd56xx/drivers/Kconfig | 1 -
boards/arm/cxd56xx/drivers/Make.defs | 1 -
boards/arm/cxd56xx/drivers/camera/Kconfig | 9 -
boards/arm/cxd56xx/drivers/camera/Make.defs | 27 -
boards/arm/cxd56xx/drivers/camera/isx012.c | 3869 ----------------------
boards/arm/cxd56xx/spresense/src/cxd56_bringup.c | 19 +-
drivers/video/Kconfig | 86 +
drivers/video/Make.defs | 4 +
drivers/video/isx012.c | 2917 ++++++++++++++++
{include/nuttx => drivers}/video/isx012_range.h | 32 +-
{include/nuttx => drivers}/video/isx012_reg.h | 16 +-
drivers/video/video.c | 2055 ++++++++++--
drivers/video/video_framebuff.c | 59 +-
drivers/video/video_framebuff.h | 16 +-
include/nuttx/video/{isx012.h => imgdata.h} | 66 +-
include/nuttx/video/imgsensor.h | 350 ++
include/nuttx/video/isx012.h | 2 +-
include/nuttx/video/video.h | 117 +-
include/nuttx/video/video_halif.h | 84 -
22 files changed, 5632 insertions(+), 4634 deletions(-)
diff --git a/arch/arm/include/cxd56xx/cisif.h b/arch/arm/include/cxd56xx/cisif.h
index b42fcb7..9e60068 100644
--- a/arch/arm/include/cxd56xx/cisif.h
+++ b/arch/arm/include/cxd56xx/cisif.h
@@ -21,54 +21,6 @@
#ifndef __ARCH_ARM_INCLUDE_CXD56XX_CISIF_H
#define __ARCH_ARM_INCLUDE_CXD56XX_CISIF_H
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-typedef void (*notify_callback_t)(uint8_t code,
- uint32_t size,
- uint32_t addr);
-typedef void (*comp_callback_t)(uint8_t code,
- uint32_t size,
- uint32_t addr);
-
-struct cisif_init_yuv_param_s
-{
- uint16_t hsize;
- uint16_t vsize;
- uint32_t notify_size;
- notify_callback_t notify_func;
-};
-
-typedef struct cisif_init_yuv_param_s cisif_init_yuv_param_t;
-
-struct cisif_init_jpeg_param_s
-{
- uint32_t notify_size;
- notify_callback_t notify_func;
-};
-
-typedef struct cisif_init_jpeg_param_s cisif_init_jpeg_param_t;
-
-struct cisif_sarea_s
-{
- uint8_t *strg_addr;
- uint32_t strg_size;
-};
-
-typedef struct cisif_sarea_s cisif_sarea_t;
-
-struct cisif_param_s
-{
- uint32_t format;
- cisif_init_yuv_param_t yuv_param;
- cisif_init_jpeg_param_t jpg_param;
- cisif_sarea_t sarea;
- comp_callback_t comp_func;
-};
-
-typedef struct cisif_param_s cisif_param_t;
-
#ifndef __ASSEMBLY__
#undef EXTERN
@@ -84,11 +36,7 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
-int cxd56_cisifinit(void);
-int cxd56_cisiffinalize(void);
-int cxd56_cisifstartcapture(cisif_param_t *param, cisif_sarea_t *sarea);
-int cxd56_cisifstopcapture(void);
-int cxd56_cisifsetdmabuf(cisif_sarea_t *sarea);
+int cxd56_cisif_initialize(void);
#undef EXTERN
#if defined(__cplusplus)
diff --git a/arch/arm/src/cxd56xx/cxd56_cisif.c b/arch/arm/src/cxd56xx/cxd56_cisif.c
index 1e09519..b3f8cbd 100644
--- a/arch/arm/src/cxd56xx/cxd56_cisif.c
+++ b/arch/arm/src/cxd56xx/cxd56_cisif.c
@@ -35,8 +35,7 @@
#include <nuttx/arch.h>
#include <arch/chip/cisif.h>
-#include <nuttx/video/video.h>
-
+#include <nuttx/video/imgdata.h>
#include "arm_arch.h"
#include "cxd56_clock.h"
@@ -52,10 +51,22 @@
/* #define CISIF_DBG_CONTI_CAP */
-#define YUV_VSIZE_MIN (64)
-#define YUV_HSIZE_MIN (96)
-#define YUV_VSIZE_MAX (360)
-#define YUV_HSIZE_MAX (480)
+#define YUV_VSIZE_STEP (1)
+#define YUV_HSIZE_STEP (1)
+#define YUV_VSIZE_MIN (64)
+#define YUV_HSIZE_MIN (96)
+#define YUV_VSIZE_MAX (360)
+#define YUV_HSIZE_MAX (480)
+
+#define JPG_VSIZE_STEP (1)
+#define JPG_HSIZE_STEP (1)
+#define JPG_VSIZE_MIN (64)
+#define JPG_HSIZE_MIN (96)
+#define JPG_VSIZE_MAX (1944)
+#define JPG_HSIZE_MAX (2592)
+
+#define CISIF_FMT_MIN (1)
+#define CISIF_FMT_MAX (3)
#define JPG_INT_ALL (JPG_ERR_STATUS_INT | \
JPG_MEM_OVF_INT | \
@@ -108,6 +119,40 @@ typedef enum state_e state_t;
typedef void (*intc_func_table)(uint8_t code);
+typedef void (*notify_callback_t)(uint8_t code,
+ uint32_t size,
+ uint32_t addr);
+typedef void (*comp_callback_t)(uint8_t code,
+ uint32_t size,
+ uint32_t addr);
+
+struct cisif_yuv_param_s
+{
+ uint16_t hsize;
+ uint16_t vsize;
+ uint32_t notify_size;
+ notify_callback_t notify_func;
+};
+
+typedef struct cisif_yuv_param_s cisif_yuv_param_t;
+
+struct cisif_jpg_param_s
+{
+ uint32_t notify_size;
+ notify_callback_t notify_func;
+};
+
+typedef struct cisif_jpg_param_s cisif_jpg_param_t;
+
+struct cisif_param_s
+{
+ uint32_t format;
+ cisif_yuv_param_t yuv_param;
+ cisif_jpg_param_t jpg_param;
+};
+
+typedef struct cisif_param_s cisif_param_t;
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -115,9 +160,8 @@ typedef void (*intc_func_table)(uint8_t code);
static state_t g_state = STATE_STANDBY;
static uint32_t g_storage_addr = 0;
-notify_callback_t g_jpg_notify_callback_func;
-notify_callback_t g_ycc_notify_callback_func;
-comp_callback_t g_comp_callback_func;
+static notify_callback_t g_jpg_notify_callback_func;
+static notify_callback_t g_ycc_notify_callback_func;
static bool g_jpgint_receive;
static bool g_errint_receive;
@@ -129,6 +173,8 @@ static uint32_t g_cisif_time_start;
static uint32_t g_cisif_time_stop;
#endif
+static imgdata_capture_t g_cxd56_cisif_complete_capture;
+
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@@ -145,15 +191,32 @@ static void cisif_reg_write(uint16_t reg, uint32_t val);
static uint32_t cisif_reg_read(uint16_t reg);
static int cisif_check_param(cisif_param_t *p);
-static int cisif_set_yuv_param(cisif_param_t *p);
-static int cisif_set_jpg_param(cisif_param_t *p);
-
-static int cisif_check_sarea(void *s);
-static int cisif_set_yuv_sarea(void *s);
-static int cisif_set_jpg_sarea(void *s);
-static int cisif_set_intlev_sarea(void *s, uint32_t yuv_size);
-
-int cisif_intc_handler(int irq, FAR void *context, FAR void *arg);
+static int cisif_set_yuv_param(cisif_yuv_param_t *p);
+static int cisif_set_jpg_param(cisif_jpg_param_t *p);
+
+static int cisif_set_yuv_sarea(uint8_t *addr, uint32_t size);
+static int cisif_set_jpg_sarea(uint8_t *addr, uint32_t size);
+static int cisif_set_intlev_sarea(uint8_t *addr,
+ uint32_t total_size,
+ uint32_t yuv_size);
+static int cisif_intc_handler(int irq, FAR void *context, FAR void *arg);
+
+/* video image data operations */
+
+static int cxd56_cisif_init(void);
+static int cxd56_cisif_uninit(void);
+static int cxd56_cisif_validate_frame_setting
+ (uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval);
+static int cxd56_cisif_start_capture
+ (uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval,
+ imgdata_capture_t callback);
+static int cxd56_cisif_stop_capture(void);
+static int cxd56_cisif_validate_buf(uint8_t *addr, uint32_t size);
+static int cxd56_cisif_set_buf(uint8_t *addr, uint32_t size);
const intc_func_table g_intcomp_func[] =
{
@@ -188,6 +251,17 @@ const intc_func_table g_intcomp_func[] =
cisif_jpg_err_int, /* JPG_ERR_STATUS_INT */
};
+const struct imgdata_ops_s g_cxd56_cisif_ops =
+ {
+ .init = cxd56_cisif_init,
+ .uninit = cxd56_cisif_uninit,
+ .validate_buf = cxd56_cisif_validate_buf,
+ .set_buf = cxd56_cisif_set_buf,
+ .validate_frame_setting = cxd56_cisif_validate_frame_setting,
+ .start_capture = cxd56_cisif_start_capture,
+ .stop_capture = cxd56_cisif_stop_capture,
+ };
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -290,7 +364,7 @@ static void cisif_callback_for_intlev(uint8_t code)
/* Notify and get next addr */
- g_comp_callback_func(0, size, g_storage_addr);
+ g_cxd56_cisif_complete_capture(0, size);
g_jpgint_receive = false;
@@ -332,7 +406,7 @@ static void cisif_ycc_axi_trdn_int(uint8_t code)
else
{
size = cisif_reg_read(CISIF_YCC_DSTRG_CONT);
- g_comp_callback_func(0, size, g_storage_addr);
+ g_cxd56_cisif_complete_capture(0, size);
cisif_reg_write(CISIF_YCC_DREAD_CONT, 0);
}
}
@@ -382,7 +456,7 @@ static void cisif_jpg_axi_trdn_int(uint8_t code)
else
{
size = cisif_reg_read(CISIF_JPG_DSTRG_CONT);
- g_comp_callback_func(0, size, g_storage_addr);
+ g_cxd56_cisif_complete_capture(0, size);
cisif_reg_write(CISIF_JPG_DREAD_CONT, 0);
}
}
@@ -414,7 +488,7 @@ static void cisif_ycc_err_int(uint8_t code)
#endif
size = cisif_reg_read(CISIF_YCC_DSTRG_CONT);
- g_comp_callback_func(code, size, g_storage_addr);
+ g_cxd56_cisif_complete_capture(code, size);
cisif_reg_write(CISIF_YCC_DREAD_CONT, 0);
g_errint_receive = true;
}
@@ -426,16 +500,13 @@ static void cisif_ycc_err_int(uint8_t code)
static void cisif_jpg_err_int(uint8_t code)
{
uint32_t size;
- uint32_t addr;
#ifdef CISIF_INTR_TRACE
cisif_trace_time_stop("cisif_jpg_err_int");
#endif
- addr = g_storage_addr;
-
size = cisif_reg_read(CISIF_JPG_DSTRG_CONT);
- g_comp_callback_func(code, size, addr);
+ g_cxd56_cisif_complete_capture(code, size);
cisif_reg_write(CISIF_JPG_DREAD_CONT, 0);
g_errint_receive = true;
}
@@ -444,7 +515,7 @@ static void cisif_jpg_err_int(uint8_t code)
* cisif_intc_handler
****************************************************************************/
-int cisif_intc_handler(int irq, FAR void *context, FAR void *arg)
+static int cisif_intc_handler(int irq, FAR void *context, FAR void *arg)
{
uint32_t value;
uint32_t enable;
@@ -488,6 +559,19 @@ static uint32_t cisif_reg_read(uint16_t reg)
return getreg32(CXD56_CISIF_BASE + reg);
}
+static bool is_uncompressed(uint32_t fmt)
+{
+ bool ret = false;
+
+ if ((fmt == IMGDATA_PIX_FMT_UYVY) ||
+ (fmt == IMGDATA_PIX_FMT_RGB565))
+ {
+ ret = true;
+ }
+
+ return ret;
+}
+
/****************************************************************************
* cisif_check_param
****************************************************************************/
@@ -499,23 +583,19 @@ static int cisif_check_param(cisif_param_t *p)
return -EINVAL;
}
- if (p->comp_func == NULL)
- {
- return -EINVAL;
- }
-
switch (p->format)
{
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_JPEG_WITH_SUBIMG:
+ case IMGDATA_PIX_FMT_UYVY:
+ case IMGDATA_PIX_FMT_RGB565:
+ case IMGDATA_PIX_FMT_JPEG:
+ case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG:
break;
default:
return -EINVAL;
}
- if (p->format != V4L2_PIX_FMT_JPEG)
+ if (p->format != IMGDATA_PIX_FMT_JPEG)
{
if (p->yuv_param.hsize < YUV_HSIZE_MIN ||
p->yuv_param.hsize > YUV_HSIZE_MAX ||
@@ -534,7 +614,7 @@ static int cisif_check_param(cisif_param_t *p)
}
}
- if (p->format != V4L2_PIX_FMT_UYVY)
+ if (!is_uncompressed(p->format))
{
if (p->jpg_param.notify_func != NULL)
{
@@ -549,46 +629,25 @@ static int cisif_check_param(cisif_param_t *p)
}
/****************************************************************************
- * cisif_check_sarea
- ****************************************************************************/
-
-static int cisif_check_sarea(void *s)
-{
- if (s == NULL)
- {
- return -EINVAL;
- }
-
- cisif_sarea_t *ss = (cisif_sarea_t *)s;
- if (ILLEGAL_BUFADDR_ALIGNMENT(ss->strg_addr) ||
- ss->strg_size == 0)
- {
- return -EINVAL;
- }
-
- return OK;
-}
-
-/****************************************************************************
* cisif_set_yuvparam
****************************************************************************/
-static int cisif_set_yuv_param(cisif_param_t *p)
+static int cisif_set_yuv_param(cisif_yuv_param_t *p)
{
uint32_t act_size = 0;
- act_size = (p->yuv_param.vsize & 0x1ff) << 16;
- act_size |= p->yuv_param.hsize & 0x1ff;
+ act_size = (p->vsize & 0x1ff) << 16;
+ act_size |= p->hsize & 0x1ff;
cisif_reg_write(CISIF_ACT_SIZE, act_size);
cisif_reg_write(CISIF_CIS_SIZE, act_size);
/* must align 32 bytes */
- cisif_reg_write(CISIF_YCC_NSTRG_SIZE, (p->yuv_param.notify_size
- & 0xffffffe0));
+ cisif_reg_write(CISIF_YCC_NSTRG_SIZE,
+ (p->notify_size & 0xffffffe0));
- g_ycc_notify_callback_func = p->yuv_param.notify_func;
+ g_ycc_notify_callback_func = p->notify_func;
return OK;
}
@@ -597,14 +656,12 @@ static int cisif_set_yuv_param(cisif_param_t *p)
* cisif_set_yuvsarea
****************************************************************************/
-static int cisif_set_yuv_sarea(void *s)
+static int cisif_set_yuv_sarea(uint8_t *addr, uint32_t size)
{
- cisif_sarea_t *ss = (cisif_sarea_t *)s;
-
/* must align 32 bytes */
- cisif_reg_write(CISIF_YCC_DAREA_SIZE, (ss->strg_size & 0xffffffe0));
- cisif_reg_write(CISIF_YCC_START_ADDR, CXD56_PHYSADDR(ss->strg_addr));
+ cisif_reg_write(CISIF_YCC_DAREA_SIZE, (size & 0xffffffe0));
+ cisif_reg_write(CISIF_YCC_START_ADDR, CXD56_PHYSADDR(addr));
return OK;
}
@@ -613,14 +670,14 @@ static int cisif_set_yuv_sarea(void *s)
* cisif_set_jpg_param
****************************************************************************/
-static int cisif_set_jpg_param(cisif_param_t *p)
+static int cisif_set_jpg_param(cisif_jpg_param_t *p)
{
/* must align 32 bytes */
- cisif_reg_write(CISIF_JPG_NSTRG_SIZE, (p->jpg_param.notify_size
+ cisif_reg_write(CISIF_JPG_NSTRG_SIZE, (p->notify_size
& 0xffffffe0));
- g_jpg_notify_callback_func = p->jpg_param.notify_func;
+ g_jpg_notify_callback_func = p->notify_func;
return OK;
}
@@ -629,14 +686,12 @@ static int cisif_set_jpg_param(cisif_param_t *p)
* cisif_set_jpg_sarea
****************************************************************************/
-static int cisif_set_jpg_sarea(void *s)
+static int cisif_set_jpg_sarea(uint8_t *addr, uint32_t size)
{
- cisif_sarea_t *ss = (cisif_sarea_t *)s;
-
/* must align 32 bytes */
- cisif_reg_write(CISIF_JPG_DAREA_SIZE, (ss->strg_size & 0xffffffe0));
- cisif_reg_write(CISIF_JPG_START_ADDR, CXD56_PHYSADDR(ss->strg_addr));
+ cisif_reg_write(CISIF_JPG_DAREA_SIZE, (size & 0xffffffe0));
+ cisif_reg_write(CISIF_JPG_START_ADDR, CXD56_PHYSADDR(addr));
return OK;
}
@@ -645,41 +700,73 @@ static int cisif_set_jpg_sarea(void *s)
* cisif_set_jpg_sarea
****************************************************************************/
-static int cisif_set_intlev_sarea(void *s, uint32_t yuv_size)
+static int cisif_set_intlev_sarea(uint8_t *addr,
+ uint32_t total_size,
+ uint32_t yuv_size)
{
- cisif_sarea_t *sarea = (cisif_sarea_t *)s;
- cisif_sarea_t sarea_int;
-
- if (sarea->strg_size < yuv_size)
+ if (total_size < yuv_size)
{
return -EINVAL;
}
/* Set for YUV */
- sarea_int.strg_addr = sarea->strg_addr;
- sarea_int.strg_size = yuv_size;
- cisif_set_yuv_sarea(&sarea_int);
+ cisif_set_yuv_sarea(addr, yuv_size);
/* Set for JPEG */
- sarea_int.strg_addr = sarea->strg_addr + yuv_size;
- sarea_int.strg_size = sarea->strg_size - yuv_size;
+ cisif_set_jpg_sarea(addr + yuv_size, total_size - yuv_size);
- cisif_set_jpg_sarea(&sarea_int);
+ return OK;
+}
+
+/****************************************************************************
+ * cisif_chk_jpgfrmsize
+ ****************************************************************************/
+
+static int cisif_chk_jpgfrmsize(int w, int h)
+{
+ if ((w < JPG_HSIZE_MIN) ||
+ (w > JPG_HSIZE_MAX))
+ {
+ return -EINVAL;
+ }
+
+ if ((h < JPG_VSIZE_MIN) ||
+ (h > JPG_VSIZE_MAX))
+ {
+ return -EINVAL;
+ }
return OK;
}
/****************************************************************************
- * Public Functions
+ * cisif_chk_yuvfrmsize
****************************************************************************/
+static int cisif_chk_yuvfrmsize(int w, int h)
+{
+ if ((w < YUV_HSIZE_MIN) ||
+ (w > YUV_HSIZE_MAX))
+ {
+ return -EINVAL;
+ }
+
+ if ((h < YUV_VSIZE_MIN) ||
+ (h > YUV_VSIZE_MAX))
+ {
+ return -EINVAL;
+ }
+
+ return OK;
+}
+
/****************************************************************************
- * cxd56_cisifinit
+ * cxd56_cisif_init
****************************************************************************/
-int cxd56_cisifinit(void)
+static int cxd56_cisif_init(void)
{
if (g_state != STATE_STANDBY)
{
@@ -708,15 +795,14 @@ int cxd56_cisifinit(void)
#endif
g_state = STATE_READY;
-
return OK;
}
/****************************************************************************
- * cxd56_cisiffinalize
+ * cxd56_cisif_uninit
****************************************************************************/
-int cxd56_cisiffinalize(void)
+static int cxd56_cisif_uninit(void)
{
if (g_state != STATE_READY)
{
@@ -741,19 +827,28 @@ int cxd56_cisiffinalize(void)
cxd56_img_cisif_clock_disable();
g_state = STATE_STANDBY;
-
return OK;
}
/****************************************************************************
- * cxd56_cisifstartcapturing
+ * cxd56_cisif_start_capture
****************************************************************************/
-int cxd56_cisifstartcapture(
- cisif_param_t *param,
- cisif_sarea_t *sarea)
+static int cxd56_cisif_start_capture
+ (uint8_t nr_fmt,
+ FAR imgdata_format_t *fmt,
+ FAR imgdata_interval_t *interval,
+ imgdata_capture_t callback)
{
- uint32_t cisif_mode;
+ cisif_param_t param =
+ {
+ 0
+ };
+
+ cisif_yuv_param_t *yuv = ¶m.yuv_param;
+ cisif_jpg_param_t *jpg = ¶m.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(¶m);
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 *)®val, (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 *)®val, 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 *)®val, (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 *)®val, 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 ...