Skip to content

Commit

Permalink
drivers/video: Support spot position setting
Browse files Browse the repository at this point in the history
Add new control id V4L2_CID_EXPOSURE_METERING_SPOT_POSITION
to support spot position setting in spot exposure metering.
  • Loading branch information
SPRESENSE committed Feb 6, 2023
1 parent d25be15 commit 625119a
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 0 deletions.
120 changes: 120 additions & 0 deletions drivers/video/isx012.c
Expand Up @@ -152,6 +152,11 @@
#define CLIP_SIZE_UNIT (8)
#define RESCALE_FOR_CLIP(v, a, b) (((v) * (a)) / (b))

/* The number of whole image splits for spot position decision. */

#define ISX012_SPOT_POSITION_SPLIT_NUM_X (9)
#define ISX012_SPOT_POSITION_SPLIT_NUM_Y (7)

/****************************************************************************
* Private Types
****************************************************************************/
Expand Down Expand Up @@ -1902,6 +1907,15 @@ static int isx012_get_supported_value

break;

case IMGSENSOR_ID_SPOT_POSITION:
value->type = IMGSENSOR_CTRL_TYPE_INTEGER;
range->minimum = ISX012_MIN_SPOTPOS;
range->maximum = ISX012_MAX_SPOTPOS;
range->step = ISX012_STEP_SPOTPOS;
range->default_value = ISX012_DEF_SPOTPOS;

break;

case IMGSENSOR_ID_AUTO_N_PRESET_WB:
value->type = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
discrete->nr_values = ARRAY_NENTRIES(g_isx012_presetwb_actual);
Expand Down Expand Up @@ -1981,6 +1995,70 @@ static int isx012_get_supported_value
return ret;
}

static void get_current_framesize(FAR struct isx012_dev_s *priv,
FAR uint16_t *w,
FAR uint16_t *h)
{
uint16_t w_addr = HSIZE_MONI;
uint16_t h_addr = VSIZE_MONI;

switch (priv->mode)
{
case REGVAL_MODESEL_MON:
w_addr = HSIZE_MONI;
h_addr = VSIZE_MONI;
break;

case REGVAL_MODESEL_MOV:
w_addr = HSIZE_MOVIE;
h_addr = VSIZE_MOVIE;
break;

case REGVAL_MODESEL_CAP:
w_addr = HSIZE_CAP;
h_addr = VSIZE_CAP;
break;

default:
/* It do not comes here due to register specification. */

break;
}

*w = isx012_getreg(priv, w_addr, 2);
*h = isx012_getreg(priv, h_addr, 2);
}

static uint16_t restore_spot_position(uint8_t regval,
uint16_t w,
uint16_t split)
{
return ((regval * w) / split + (w / split) / 2);
}


static int32_t get_spot_position(FAR struct isx012_dev_s *priv)
{
uint16_t regval;
uint16_t reg_x;
uint16_t reg_y;
uint16_t x;
uint16_t y;
uint16_t w;
uint16_t h;

regval = isx012_getreg(priv, SPOT_FRM_NUM, 1);
reg_x = regval % ISX012_SPOT_POSITION_SPLIT_NUM_X;
reg_y = regval / ISX012_SPOT_POSITION_SPLIT_NUM_X;

get_current_framesize(priv, &w, &h);

x = restore_spot_position(reg_x, w, ISX012_SPOT_POSITION_SPLIT_NUM_X);
y = restore_spot_position(reg_y, h, ISX012_SPOT_POSITION_SPLIT_NUM_Y);

return ((x << 16) | y);
}

static int isx012_get_value(uint32_t id,
uint32_t size,
FAR imgsensor_value_t *value)
Expand Down Expand Up @@ -2245,6 +2323,10 @@ static int isx012_get_value(uint32_t id,

break;

case IMGSENSOR_ID_SPOT_POSITION:
value->value32 = get_spot_position(priv);
break;

case IMGSENSOR_ID_3A_PARAMETER:
if (value->p_u16 == NULL)
{
Expand Down Expand Up @@ -2354,6 +2436,31 @@ static int set_clip(uint32_t size, uint32_t *val, isx012_rect_t *target)
return OK;
}

static int set_spot_position(FAR struct isx012_dev_s *priv, int32_t val)
{
uint16_t w;
uint16_t h;
uint16_t x = (uint16_t)((val & 0xffff0000) >> 16);
uint16_t y = (uint16_t)(val & 0xffff);
uint8_t reg_x;
uint8_t reg_y;
uint8_t reg;

get_current_framesize(priv, &w, &h);

if ((x >= w) || (y >= h))
{
return -EINVAL;
}

reg_x = (x * ISX012_SPOT_POSITION_SPLIT_NUM_X) / w;
reg_y = (y * ISX012_SPOT_POSITION_SPLIT_NUM_Y) / h;

reg = reg_y * ISX012_SPOT_POSITION_SPLIT_NUM_X + reg_x;

return isx012_putreg(priv, SPOT_FRM_NUM, reg, 1);
}

static int isx012_set_value(uint32_t id,
uint32_t size,
FAR imgsensor_value_t value)
Expand Down Expand Up @@ -2854,6 +2961,19 @@ static int isx012_set_value(uint32_t id,

break;

case IMGSENSOR_ID_SPOT_POSITION:
ret = VALIDATE_VALUE(value.value32,
ISX012_MIN_SPOTPOS,
ISX012_MAX_SPOTPOS,
ISX012_STEP_SPOTPOS);
if (ret != OK)
{
break;
}

ret = set_spot_position(priv, value.value32);
break;

case IMGSENSOR_ID_AUTO_N_PRESET_WB:
for (cnt = 0;
cnt < ARRAY_NENTRIES(g_isx012_presetwb_actual);
Expand Down
10 changes: 10 additions & 0 deletions drivers/video/isx012_range.h
Expand Up @@ -222,6 +222,16 @@
#define ISX012_REG_PHOTOMETRY AE_SUB_SN1
#define ISX012_SIZE_PHOTOMETRY (1)

/* Definition for control spot position */

#define ISX012_TYPE_SPOTPOS V4L2_CTRL_TYPE_INTEGER
#define ISX012_DEF_SPOTPOS (0x051003cc)
#define ISX012_MIN_SPOTPOS (0)
#define ISX012_MAX_SPOTPOS (0x0a200798)
#define ISX012_STEP_SPOTPOS (1)
#define ISX012_REG_SPOTPOS SPOT_FRM_NUM
#define ISX012_SIZE_SPOTPOS (1)

/* Definition for control zoom */

#define ISX012_TYPE_ZOOM V4L2_CTRL_TYPE_U16FIXEDPOINT_Q8
Expand Down
1 change: 1 addition & 0 deletions drivers/video/isx012_reg.h
Expand Up @@ -667,6 +667,7 @@
#define AE_INIT_MASK_CNT (AE_BASE+0x002B)
#define AESPEED_INIT (AE_BASE+0x0031)
#define AESPEED_FAST (AE_BASE+0x0032)
#define SPOT_FRM_NUM (AE_BASE+0x0033)
#define FASTMOVE_TIMEOUT (AE_BASE+0x003D)
#define AE_START_LEVEL (AE_BASE+0x0040)

Expand Down

0 comments on commit 625119a

Please sign in to comment.