camera: mediatek: add GC5035 sensor info and support for set digital gain

For GC5035, we must set the d-gain by implementing V4L2_CID_DIGITAL_GAIN
in SENSOR_CMD_SET_SENSOR_GAIN sendcommand to support set sensor d-gain
from HalSensor. In the meantime, GC5035 related sensor info is also added.

BUG=b:158423833
TEST=rebuild image and check d-gain can be set

Change-Id: Ice18e464ce2b4b948ccad920dd546f2326197f0a
Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2183970
Reviewed-by: Hung-yu Wu <hywu@chromium.org>
Tested-by: Xiaoyu XY17 He <hexy17@lenovo.corp-partner.google.com>
Commit-Queue: Hsu Wei-Cheng <mojahsu@chromium.org>
diff --git a/camera/hal/mediatek/mtkcam/custom/mt8183/hal/imgsensor_src/imgsensor_custom_info.h b/camera/hal/mediatek/mtkcam/custom/mt8183/hal/imgsensor_src/imgsensor_custom_info.h
index 4dc838a..e175b6d 100644
--- a/camera/hal/mediatek/mtkcam/custom/mt8183/hal/imgsensor_src/imgsensor_custom_info.h
+++ b/camera/hal/mediatek/mtkcam/custom/mt8183/hal/imgsensor_src/imgsensor_custom_info.h
@@ -28,6 +28,7 @@
         {OV2685_SENSOR_ID, SENSOR_DRVNAME_OV2685_MIPI_RAW, NULL},
         {OV8856_SENSOR_ID, SENSOR_DRVNAME_OV8856_MIPI_RAW, NULL},
         {OV02A10_SENSOR_ID, SENSOR_DRVNAME_OV02A10_MIPI_RAW, NULL},
+        {GC5035_SENSOR_ID, SENSOR_DRVNAME_GC5035_MIPI_RAW, NULL},
         /*  ADD sensor driver before this line */
         {0, {0}, NULL}, /* end of list */
 };
@@ -58,7 +59,7 @@
         {1600, 1200, 0, 0, 1600, 1200, 1600, 1200, 0, 0, 1600, 1200, 0, 0, 1600,
          1200}, /* hs video */
         {1600, 1200, 0, 0, 1600, 1200, 1600, 1200, 0, 0, 1600, 1200, 0, 0, 1600,
-         1200} /*slim video */
+         1200} /* slim video */
     },
     {// ov8856
      {3296, 2480, 0, 0, 3296, 2480, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264,
@@ -81,7 +82,20 @@
         {1600, 1200, 0, 0, 1600, 1200, 1600, 1200, 0, 0, 1600, 1200, 0, 0, 1600,
          1200}, /* hs video */
         {1600, 1200, 0, 0, 1600, 1200, 1600, 1200, 0, 0, 1600, 1200, 0, 0, 1600,
-         1200} /*slim video */
+         1200} /* slim video */
+    },
+    {
+        // gc5035
+        {2592, 1944, 0, 0, 2592, 1944, 2592, 1944, 0, 0, 2592, 1944, 0, 0, 2592,
+         1944}, /* preview */
+        {2592, 1944, 0, 0, 2592, 1944, 2592, 1944, 0, 0, 2592, 1944, 0, 0, 2592,
+         1944}, /* capture */
+        {2592, 1944, 0, 0, 2592, 1944, 1296, 972, 0, 0, 1296, 972, 0, 0, 1296,
+         972}, /* video */
+        {2592, 1944, 656, 492, 1280, 960, 640, 480, 0, 0, 640, 480, 0, 0, 640,
+         480}, /* hs video */
+        {2592, 1944, 16, 252, 2560, 1440, 1280, 720, 0, 0, 1280, 720, 0, 0,
+         1280, 720} /* slim video */
     },
 };
 
@@ -92,6 +106,11 @@
 
         .checksum_value = 0x6c259b92, /* checksum value for Camera Auto Test */
 
+        .sensor_agc_param_map =
+            {
+                {0, 0},
+            },
+
         .pre =
             {
                 /*data rate 1099.20 Mbps/lane */
@@ -344,6 +363,11 @@
 
         .checksum_value = 0x6c259b92, /* checksum value for Camera Auto Test */
 
+        .sensor_agc_param_map =
+            {
+                {0, 0},
+            },
+
         .pre =
             {
                 /*data rate 1099.20 Mbps/lane */
@@ -596,6 +620,11 @@
 
         .checksum_value = 0xb1893b4f, /* checksum value for Camera Auto Test */
 
+        .sensor_agc_param_map =
+            {
+                {0, 0},
+            },
+
         .pre =
             {
                 .pclk = 144000000,   /*record different mode's pclk*/
@@ -831,6 +860,11 @@
 
         .checksum_value = 0xb1893b4f, /* checksum value for Camera Auto Test */
 
+        .sensor_agc_param_map =
+            {
+                {0, 0},
+            },
+
         .pre =
             {
                 /*data rate 1099.20 Mbps/lane */
@@ -1074,6 +1108,280 @@
         .SensorGainfactor = 6,
         .SensorHFlip = 0,
         .SensorVFlip = 0,
+    },
+    {
+        .sensor_id =
+            GC5035_SENSOR_ID, /* record sensor id defined in Kd_imgsensor.h */
+
+        .checksum_value = 0xcde448ca, /* checksum value for Camera Auto Test */
+
+        .sensor_agc_param_map =
+            {
+                /* GC5035 */
+                {256, 0},
+                {302, 1},
+                {358, 2},
+                {425, 3},
+                {502, 8},
+                {599, 9},
+                {717, 10},
+                {845, 11},
+                {998, 12},
+                {1203, 13},
+                {1434, 14},
+                {1710, 15},
+                {1997, 16},
+                {2355, 17},
+                {2816, 18},
+                {3318, 19},
+                {3994, 20},
+            },
+
+        .pre =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 175200000,   /* record different mode's pclk */
+                .linelength = 2920,  /* record different mode's linelength */
+                .framelength = 2008, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2592, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    1944, /* record different mode's height of grabwindow */
+                /*     following for MIPIDataLowPwr2HighSpeedSettleDelayCount by
+                   different scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*     following for GetDefaultFramerateByScenario()    */
+                .max_framerate = 300,
+            },
+        .cap =
+            {
+                /*data rate 1499.20 Mbps/lane */
+                .pclk = 175200000,
+                .linelength = 2920,
+                .framelength = 2008,
+                .startx = 0,
+                .starty = 0,
+                .grabwindow_width = 2592,
+                .grabwindow_height = 1944,
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                .max_framerate = 300,
+            },
+        .cap1 =
+            {
+                /*data rate 1499.20 Mbps/lane */
+                .pclk = 141600000,
+                .linelength = 2920,
+                .framelength = 2008,
+                .startx = 0,
+                .starty = 0,
+                .grabwindow_width = 2592,
+                .grabwindow_height = 1944,
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                .max_framerate = 240,
+            },
+
+        .normal_video =
+            {
+                /*data rate 1499.20 Mbps/lane */
+                .pclk = 87600000,
+                .linelength = 1460,
+                .framelength = 2008,
+                .startx = 0,
+                .starty = 0,
+                .grabwindow_width = 1296,
+                .grabwindow_height = 972,
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                .max_framerate = 300,
+            },
+        .hs_video =
+            {
+                /*data rate 600 Mbps/lane */
+                .pclk = 175200000,
+                .linelength = 1896,
+                .framelength = 1536,
+                .startx = 0,
+                .starty = 0,
+                .grabwindow_width = 1280,
+                .grabwindow_height = 720,
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                .max_framerate = 600,
+            },
+        .slim_video =
+            {
+                /*data rate 792 Mbps/lane */
+                .pclk = 87600000,
+                .linelength = 1460,
+                .framelength = 2008,
+                .startx = 0,
+                .starty = 0,
+                .grabwindow_width = 1280,
+                .grabwindow_height = 720,
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                .max_framerate = 300,
+            },
+        .custom1 =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 531000000,   /* record different mode's pclk */
+                .linelength = 6024,  /* record different mode's linelength */
+                .framelength = 2896, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2672, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    2008, /* record different mode's height of grabwindow */
+                /*         following for
+                   MIPIDataLowPwr2HighSpeedSettleDelayCount by different
+                   scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*         following for GetDefaultFramerateByScenario() */
+                .max_framerate = 300,
+            },
+
+        .custom2 =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 531000000,   /* record different mode's pclk */
+                .linelength = 6024,  /* record different mode's linelength */
+                .framelength = 2896, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2672, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    2008, /* record different mode's height of grabwindow */
+                /*     following for MIPIDataLowPwr2HighSpeedSettleDelayCount by
+                   different scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*     following for GetDefaultFramerateByScenario()    */
+                .max_framerate = 300,
+            },
+        .custom3 =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 531000000,   /* record different mode's pclk */
+                .linelength = 6024,  /* record different mode's linelength */
+                .framelength = 2896, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2672, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    2008, /* record different mode's height of grabwindow */
+                /*     following for MIPIDataLowPwr2HighSpeedSettleDelayCount by
+                   different scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*     following for GetDefaultFramerateByScenario()    */
+                .max_framerate = 300,
+            },
+        .custom4 =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 531000000,   /* record different mode's pclk */
+                .linelength = 6024,  /* record different mode's linelength */
+                .framelength = 2896, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2672, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    2008, /* record different mode's height of grabwindow */
+                /*     following for MIPIDataLowPwr2HighSpeedSettleDelayCount by
+                   different scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*     following for GetDefaultFramerateByScenario()    */
+                .max_framerate = 300,
+            },
+        .custom5 =
+            {
+                /*data rate 1099.20 Mbps/lane */
+                .pclk = 531000000,   /* record different mode's pclk */
+                .linelength = 6024,  /* record different mode's linelength */
+                .framelength = 2896, /* record different mode's framelength */
+                .startx = 0, /* record different mode's startx of grabwindow */
+                .starty = 0, /* record different mode's starty of grabwindow */
+                .grabwindow_width =
+                    2672, /* record different mode's width of grabwindow */
+                .grabwindow_height =
+                    2008, /* record different mode's height of grabwindow */
+                /*     following for MIPIDataLowPwr2HighSpeedSettleDelayCount by
+                   different scenario    */
+                .mipi_data_lp2hs_settle_dc = 85, /* unit , ns */
+                /*     following for GetDefaultFramerateByScenario()    */
+                .max_framerate = 300,
+            },
+        .ae_shut_delay_frame = 0,
+        /* shutter delay frame for AE cycle, 2 frame with
+           ispGain_delay-shut_delay=2-0=2 */
+        .ae_sensor_gain_delay_frame = 0,
+        /* sensor gain delay frame for AE cycle,2 frame with
+           ispGain_delay-sensor_gain_delay=2-0=2 */
+        .ae_ispGain_delay_frame = 2, /* isp gain delay frame for AE cycle */
+        .ihdr_support = 0,           /* 1, support; 0,not support */
+        .ihdr_le_firstline = 0,      /* 1,le first ; 0, se first */
+        .temperature_support = 1,    /* 1, support; 0,not support */
+        .sensor_mode_num = 5,        /* support sensor mode num */
+
+        .cap_delay_frame = 2,      /* enter capture delay frame num */
+        .pre_delay_frame = 2,      /* enter preview delay frame num */
+        .video_delay_frame = 2,    /* enter video delay frame num */
+        .hs_video_delay_frame = 2, /* enter high speed video  delay frame num */
+        .slim_video_delay_frame = 2, /* enter slim video delay frame num */
+
+        .margin = 16,     /* sensor framelength & shutter margin */
+        .min_shutter = 4, /* min shutter */
+        .max_frame_length =
+            0x3fff, /* max framelength by sensor register's limitation */
+
+        .isp_driving_current = ISP_DRIVING_6MA, /* mclk driving current */
+        .sensor_interface_type =
+            SENSOR_INTERFACE_TYPE_MIPI, /* sensor_interface_type */
+        .mipi_sensor_type =
+            MIPI_OPHY_NCSI2, /* 0,MIPI_OPHY_NCSI2;  1,MIPI_OPHY_CSI2 */
+        .mipi_settle_delay_mode = MIPI_SETTLEDELAY_AUTO,
+        /* 0,MIPI_SETTLEDELAY_AUTO; 1,MIPI_SETTLEDELAY_MANNUAL */
+        .sensor_output_dataformat =
+            SENSOR_OUTPUT_FORMAT_RAW_R, /* sensor output first pixel color */
+        .mclk = 24, /* mclk value, suggest 24 or 26 for 24Mhz or 26Mhz */
+        /* record sensor support all write id addr, only support 4must end with
+           0xff */
+        .i2c_speed = 400,                    /* i2c read/write speed */
+        .mipi_lane_num = SENSOR_MIPI_4_LANE, /* mipi lane num */
+
+        .SensorClockPolarity = SENSOR_CLOCK_POLARITY_LOW,
+        .SensorClockFallingPolarity = SENSOR_CLOCK_POLARITY_LOW,
+        .SensorHsyncPolarity = SENSOR_CLOCK_POLARITY_LOW,
+        .SensorVsyncPolarity = SENSOR_CLOCK_POLARITY_LOW,
+        .SensorInterruptDelayLines = 4,
+        .SensorResetActiveHigh = false,
+        .SensorResetDelayCount = 5,
+        .SensorMasterClockSwitch = 0,
+        .PDAF_Support = PDAF_SUPPORT_CAMSV,
+/* 0: NO PDAF, 1: PDAF Raw Data mode, 2:PDAF VC mode */
+#if defined(GC5035_ZHDR)
+        .HDR_Support = 3, /*0: NO HDR, 1: iHDR, 2:mvHDR, 3:zHDR */
+        /*0: no support, 1: G0,R0.B0, 2: G0,R0.B1, 3: G0,R1.B0, 4: G0,R1.B1 */
+        /*5: G1,R0.B0, 6: G1,R0.B1, 7: G1,R1.B0, 8: G1,R1.B1 */
+        .ZHDR_Mode = 8,
+#else
+        .HDR_Support = 2,
+#endif
+        .SensorClockDividCount = 3,
+        .SensorClockRisingCount = 0,
+        .SensorClockFallingCount = 2,
+        .SensorPixelClockCount = 3,
+        .SensorDataLatchCount = 2,
+        .MIPIDataLowPwr2HighSpeedTermDelayCount = 0,
+        .MIPICLKLowPwr2HighSpeedTermDelayCount = 0,
+        .SensorWidthSampling = 0,
+        .SensorHightSampling = 0,
+        .SensorPacketECCOrder = 1,
+        .SensorGainfactor = 2,
+        .SensorHFlip = 0,
+        .SensorVFlip = 0,
     }};
 
 #endif  // CAMERA_HAL_MEDIATEK_MTKCAM_CUSTOM_MT8183_HAL_IMGSENSOR_SRC_IMGSENSOR_CUSTOM_INFO_H_
diff --git a/camera/hal/mediatek/mtkcam/custom/mt8183/kernel/imgsensor/kd_imgsensor.h b/camera/hal/mediatek/mtkcam/custom/mt8183/kernel/imgsensor/kd_imgsensor.h
index 0446665..dad5e57 100644
--- a/camera/hal/mediatek/mtkcam/custom/mt8183/kernel/imgsensor/kd_imgsensor.h
+++ b/camera/hal/mediatek/mtkcam/custom/mt8183/kernel/imgsensor/kd_imgsensor.h
@@ -293,6 +293,7 @@
 #define GC0310_SENSOR_ID 0xa310
 #define GC0313MIPI_YUV_SENSOR_ID 0xD0
 #define GC0312_SENSOR_ID 0xb310
+#define GC5035_SENSOR_ID 0x5035
 /*SP*/
 #define SP0A19_YUV_SENSOR_ID 0xA6
 #define SP2518_YUV_SENSOR_ID 0x53
@@ -475,6 +476,7 @@
 #define SENSOR_DRVNAME_GC0310_YUV "gc0310_yuv"
 #define SENSOR_DRVNAME_GC0312_YUV "gc0312_yuv"
 #define SENSOR_DRVNAME_GC0313MIPI_YUV "gc0313_mipi_yuv"
+#define SENSOR_DRVNAME_GC5035_MIPI_RAW "gc5035_mipi_raw"
 /*SP*/
 #define SENSOR_DRVNAME_SP0A19_YUV "sp0a19_yuv"
 #define SENSOR_DRVNAME_SP2518_YUV "sp2518_yuv"
diff --git a/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.cpp b/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.cpp
index 6b15635..5ca7edb 100644
--- a/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.cpp
+++ b/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.cpp
@@ -366,6 +366,7 @@
       mScenarioId(0),
       mHdrMode(0),
       mPdafMode(0),
+      mDgainRatio(0),
       mFramerate(0) {
   memset(&mSensorDynamicInfo, 0, sizeof(SensorDynamicInfo));
 }
@@ -701,9 +702,20 @@
   m_pixClk = pix_clk;
   m_linelength = line_length;
   m_framelength = framelength;
+  m_margin = pImgsensorInfo->margin;
+  m_minShutter = pImgsensorInfo->min_shutter;
+  m_maxFramelength = pImgsensorInfo->max_frame_length;
   m_LineTimeInus = (line_length * 1000000 + ((pix_clk / 1000) - 1)) /
                    (pix_clk / 1000);  // 1000 base , 33657 mean 33.657 us
   m_SensorGainFactor = pImgsensorInfo->SensorGainfactor;
+  m_SensorGainBase = GAIN_BASE_3A >> m_SensorGainFactor;
+  mDgainRatio = m_SensorGainBase;
+  m_SensorGainMapSize = sizeof(pImgsensorInfo->sensor_agc_param_map) /
+                        sizeof(pImgsensorInfo->sensor_agc_param_map[0]);
+  m_SensorAgcParam = pImgsensorInfo->sensor_agc_param_map;
+  if (!m_SensorAgcParam) {
+    CAM_LOGW("sensorIdx (%d), m_SensorAgcParam is NULL\n", sensorIdx);
+  }
 
   aFormat.pad = 0;
   aFormat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
@@ -759,7 +771,7 @@
   IMGSENSOR_SENSOR_IDX sensorIdx = IMGSENSOR_SENSOR_IDX_MAP(indexDual);
   int sensor_fd = HalSensorList::singleton()->querySensorFd(sensorIdx);
   v4l2_control control;
-  unsigned int u32temp = 0, u32temp1 = 0;
+  unsigned int u32temp = 0, u32temp1 = 0, u32temp2 = 0;
 
   switch (cmd) {
     case SENSOR_CMD_GET_SENSOR_PIXELMODE:
@@ -829,17 +841,52 @@
     case SENSOR_CMD_SET_SENSOR_GAIN:
       if ((reinterpret_cast<MUINT32*>(arg1) != NULL) &&
           (arg1_size == sizeof(MUINT32))) {
-        control.id = V4L2_CID_ANALOGUE_GAIN;
-        u32temp = *reinterpret_cast<MUINT32*>(arg1);
-        control.value = u32temp >> m_SensorGainFactor;
-        CAM_LOGD("SENSOR_GAIN %d(%d) m_SensorGainFactor %d", control.value,
-                 u32temp, m_SensorGainFactor);
-        ret = ioctl(sensor_fd, VIDIOC_S_CTRL, &control);
-        if (ret < 0) {
-          CAM_LOGE("[%s] set SENSOR GAIN fail %d", __FUNCTION__, control.value);
+        if (m_SensorAgcParam->auto_pregain) {
+          u32temp = *reinterpret_cast<MUINT32*>(arg1);
+          u32temp1 = u32temp >> m_SensorGainFactor;
+          for (u32temp2 = m_SensorGainMapSize - 1; u32temp2 > 0; u32temp2--) {
+            if (u32temp1 >= m_SensorAgcParam[u32temp2].auto_pregain) {
+              break;
+            }
+          }
+
+          control.id = V4L2_CID_ANALOGUE_GAIN;
+          control.value = m_SensorAgcParam[u32temp2].col_code;
+          ret = ioctl(sensor_fd, VIDIOC_S_CTRL, &control);
+          if (ret < 0) {
+            CAM_LOGE("[%s] set SENSOR A-GAIN fail %d\n", __FUNCTION__,
+                     control.value);
+          }
+
+          if (m_SensorAgcParam[u32temp2].auto_pregain) {
+            u32temp1 = u32temp1 * mDgainRatio /
+                       (m_SensorAgcParam[u32temp2].auto_pregain);
+          } else {
+            CAM_LOGE("AGC index (%d), auto_pregain is NULL\n", u32temp2);
+            return MFALSE;
+          }
+
+          CAM_LOGD("Mapped AGC PARAM pregain(%d)\n",
+                   m_SensorAgcParam[u32temp2].auto_pregain);
+          control.id = V4L2_CID_DIGITAL_GAIN;
+          control.value = u32temp1;
+          ret = ioctl(sensor_fd, VIDIOC_S_CTRL, &control);
+          if (ret < 0) {
+            CAM_LOGE("[%s] set SENSOR D-GAIN fail %d\n", __FUNCTION__,
+                     control.value);
+          }
+        } else {
+          control.id = V4L2_CID_ANALOGUE_GAIN;
+          u32temp = *reinterpret_cast<MUINT32*>(arg1);
+          control.value = u32temp >> m_SensorGainFactor;
+          ret = ioctl(sensor_fd, VIDIOC_S_CTRL, &control);
+          if (ret < 0) {
+            CAM_LOGE("[%s] set SENSOR A-GAIN fail %d\n", __FUNCTION__,
+                     control.value);
+          }
         }
       } else {
-        CAM_LOGE("%s(0x%x) wrong input params", __FUNCTION__, cmd);
+        CAM_LOGE("%s(0x%x) wrong input params\n", __FUNCTION__, cmd);
         ret = MFALSE;
       }
       break;
@@ -859,10 +906,19 @@
           CAM_LOGE("[%s] set SENSOR VBLANK fail %d", __FUNCTION__,
                    control.value);
         }
+        u32temp = (u32temp < m_minShutter) ? m_minShutter : u32temp;
+        u32temp = (u32temp > (m_maxFramelength - m_margin))
+                      ? (m_maxFramelength - m_margin)
+                      : u32temp;
+        u32temp1 = u32temp & ~3;
+        if (u32temp1 > 0) {
+          mDgainRatio = m_SensorGainBase * u32temp / u32temp1;
+        } else {
+          CAM_LOGW("[%s] too small exp-lines, using SensorGainBase\n",
+                   __FUNCTION__);
+        }
         control.id = V4L2_CID_EXPOSURE;
-        control.value = u32temp;
-        CAM_LOGD("EXP_TIME %d(%d) m_LineTimeInus %d vblank %d", u32temp,
-                 *(MUINT32*)arg1, m_LineTimeInus, m_vblank);
+        control.value = u32temp1;
         ret = ioctl(sensor_fd, VIDIOC_S_CTRL, &control);
         if (ret < 0) {
           CAM_LOGE("[%s] set SENSOR EXPOSURE fail %d", __FUNCTION__,
diff --git a/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.h b/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.h
index 4c9ac1c..ae84bc5 100644
--- a/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.h
+++ b/camera/hal/mediatek/mtkcam/drv/sensor/HalSensor.h
@@ -131,13 +131,20 @@
   MUINT32 mScenarioId;
   MUINT32 mHdrMode;
   MUINT32 mPdafMode;
+  MUINT32 mDgainRatio;
   MUINT32 mFramerate;  // max frame rate: unit linelength
   MUINT32 m_LineTimeInus;
   MUINT32 m_vblank;
   MUINT32 m_pixClk;
   MUINT32 m_linelength;
+  MUINT32 m_margin;
+  MUINT32 m_minShutter;
+  MUINT32 m_maxFramelength;
   MUINT32 m_framelength;
+  MUINT32 m_SensorGainBase;
   MUINT32 m_SensorGainFactor;
+  MUINT32 m_SensorGainMapSize;
+  struct imgsensor_agc_param_struct* m_SensorAgcParam;
 };
 };      // namespace NSHalSensor
 };      // namespace NSCam
diff --git a/camera/hal/mediatek/mtkcam/drv/sensor/img_sensor.h b/camera/hal/mediatek/mtkcam/drv/sensor/img_sensor.h
index 7d4bb51..26f6843 100644
--- a/camera/hal/mediatek/mtkcam/drv/sensor/img_sensor.h
+++ b/camera/hal/mediatek/mtkcam/drv/sensor/img_sensor.h
@@ -17,6 +17,9 @@
 #ifndef CAMERA_HAL_MEDIATEK_MTKCAM_DRV_SENSOR_IMG_SENSOR_H_
 #define CAMERA_HAL_MEDIATEK_MTKCAM_DRV_SENSOR_IMG_SENSOR_H_
 
+#define SENSOR_GAIN_MAP_SIZE 17
+#define GAIN_BASE_3A 1024
+
 enum IMGSENSOR_MODE {
   IMGSENSOR_MODE_INIT,
   IMGSENSOR_MODE_PREVIEW,
@@ -77,10 +80,19 @@
   MUINT8 i2c_write_id; /* record current sensor's i2c write id */
 };
 
+/* SENSOR PRIVATE STRUCT FOR AGC PARAMETER */
+struct imgsensor_agc_param_struct {
+  MUINT32 auto_pregain;
+  MUINT32 col_code;
+};
+
 /* SENSOR PRIVATE STRUCT FOR CONSTANT*/
 struct imgsensor_info_struct {
   MUINT32 sensor_id;      /* record sensor id defined in Kd_imgsensor.h */
   MUINT32 checksum_value; /* checksum value for Camera Auto Test */
+
+  struct imgsensor_agc_param_struct sensor_agc_param_map[SENSOR_GAIN_MAP_SIZE];
+
   struct imgsensor_mode_struct pre; /* preview scenario relative information */
   struct imgsensor_mode_struct cap; /* capture scenario relative information */
   struct imgsensor_mode_struct cap1;