in drivers/video/isx012.c [2458:3067]
static int isx012_set_value(FAR struct imgsensor_s *sensor,
uint32_t id, uint32_t size,
imgsensor_value_t value)
{
FAR isx012_dev_t *priv = (FAR isx012_dev_t *)sensor;
int ret = -EINVAL;
uint8_t cnt;
FAR 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_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);
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;
case IMGSENSOR_ID_CLIP_VIDEO:
ret = set_clip(size, value.p_u32, &priv->clip_video);
break;
case IMGSENSOR_ID_CLIP_STILL:
ret = set_clip(size, value.p_u32, &priv->clip_still);
break;
default: /* Unsupported control id */
break;
}
return ret;
}