static int isx012_set_value()

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;
}