[COMMON] fimc-is2: support digital gain setting for OV12A10/0V12A10FF/OV16885C
authorxff <fangfang.xu@samsung.com>
Thu, 21 Mar 2019 09:21:41 +0000 (17:21 +0800)
committerlingsen1 <lingsen1@lenovo.com>
Mon, 10 Jun 2019 03:24:51 +0000 (11:24 +0800)
Change-Id: I1cc0a583e85c452d5bd7ae2502102ec4c9ed9540
Signed-off-by: xff <fangfang.xu@samsung.com>
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-12a10.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-12a10ff.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-16885c.c

index 58cf4df257b429da7289241855cbd4ef7574192a..024440ccda35bffe6f0026bea35f740fbf64b6c0 100755 (executable)
@@ -1251,6 +1251,17 @@ int sensor_12a10_cis_get_max_analog_gain(struct v4l2_subdev *subdev, u32 *max_ag
        return ret;
 }
 
+#define REG_1X_BASE_DGAIN_VALUE        1000
+#define REG_1X_BASE_DGAIN          0x0400
+
+u32 sensor_12a10_dgain_to_reg_value(u32 permile)
+{
+       u32 reg_dgain;
+       reg_dgain = permile * REG_1X_BASE_DGAIN / REG_1X_BASE_DGAIN_VALUE;
+
+       return reg_dgain;
+}
+
 int sensor_12a10_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_param *dgain)
 {
        int ret = 0;
@@ -1260,6 +1271,7 @@ int sensor_12a10_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_para
 
        u16 long_gain = 0;
        u16 short_gain = 0;
+       u8 reg_short_gain[2] = {0};
 
 #ifdef DEBUG_SENSOR_TIME
        struct timeval st, end;
@@ -1283,8 +1295,8 @@ int sensor_12a10_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_para
 
        cis_data = cis->cis_data;
 
-       long_gain = (u16)sensor_cis_calc_dgain_code(dgain->long_val);
-       short_gain = (u16)sensor_cis_calc_dgain_code(dgain->short_val);
+       long_gain = (u16)sensor_12a10_dgain_to_reg_value(dgain->long_val);
+       short_gain = (u16)sensor_12a10_dgain_to_reg_value(dgain->short_val);
 
        if (long_gain < cis->cis_data->min_digital_gain[0])
                long_gain = cis->cis_data->min_digital_gain[0];
@@ -1298,6 +1310,11 @@ int sensor_12a10_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_para
        if (short_gain > cis->cis_data->max_digital_gain[0])
                short_gain = cis->cis_data->max_digital_gain[0];
 
+       reg_short_gain[0] = (short_gain & 0x3FFF) >> 8;
+       reg_short_gain[1] = (short_gain & 0xFF);
+       fimc_is_sensor_write8(client, 0x350A, reg_short_gain[0]);
+       fimc_is_sensor_write8(client, 0x350B, reg_short_gain[1]);
+
        dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_dgain = %d/%d us, long_gain(%#x), short_gain(%#x)\n",
                cis->id, __func__, cis->cis_data->sen_vsync_count, dgain->long_val,
                dgain->short_val, long_gain, short_gain);
@@ -1400,8 +1417,8 @@ int sensor_12a10_cis_get_min_digital_gain(struct v4l2_subdev *subdev, u32 *min_d
        }
 
        cis_data = cis->cis_data;
-    cis_data->min_digital_gain[0] = 0x100;
-    cis_data->min_digital_gain[1] = 1000;
+    cis_data->min_digital_gain[0] = REG_1X_BASE_DGAIN;
+    cis_data->min_digital_gain[1] = REG_1X_BASE_DGAIN_VALUE;
        *min_dgain = cis_data->min_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
@@ -1443,8 +1460,8 @@ int sensor_12a10_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max_d
        }
 
        cis_data = cis->cis_data;
-       cis_data->max_digital_gain[0] = 0x100;
-       cis_data->max_digital_gain[1] = 1000;
+       cis_data->max_digital_gain[0] = 0x3FFF;
+       cis_data->max_digital_gain[1] = 16000;
        *max_dgain = cis_data->max_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
index a86409d06cf15c1480d23ee4e460e241a827c408..1504c0333112af8f00d67fe0a79cf373239f1a96 100755 (executable)
@@ -1251,6 +1251,17 @@ int sensor_12a10ff_cis_get_max_analog_gain(struct v4l2_subdev *subdev, u32 *max_
        return ret;
 }
 
+#define REG_1X_BASE_DGAIN_VALUE        1000
+#define REG_1X_BASE_DGAIN          0x0400
+
+u32 sensor_12a10ff_dgain_to_reg_value(u32 permile)
+{
+       u32 reg_dgain;
+       reg_dgain = permile * REG_1X_BASE_DGAIN / REG_1X_BASE_DGAIN_VALUE;
+
+       return reg_dgain;
+}
+
 int sensor_12a10ff_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_param *dgain)
 {
        int ret = 0;
@@ -1260,6 +1271,7 @@ int sensor_12a10ff_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_pa
 
        u16 long_gain = 0;
        u16 short_gain = 0;
+       u8 reg_short_gain[2] = {0};
 
 #ifdef DEBUG_SENSOR_TIME
        struct timeval st, end;
@@ -1283,8 +1295,8 @@ int sensor_12a10ff_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_pa
 
        cis_data = cis->cis_data;
 
-       long_gain = (u16)sensor_cis_calc_dgain_code(dgain->long_val);
-       short_gain = (u16)sensor_cis_calc_dgain_code(dgain->short_val);
+       long_gain = (u16)sensor_12a10ff_dgain_to_reg_value(dgain->long_val);
+       short_gain = (u16)sensor_12a10ff_dgain_to_reg_value(dgain->short_val);
 
        if (long_gain < cis->cis_data->min_digital_gain[0])
                long_gain = cis->cis_data->min_digital_gain[0];
@@ -1298,6 +1310,11 @@ int sensor_12a10ff_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_pa
        if (short_gain > cis->cis_data->max_digital_gain[0])
                short_gain = cis->cis_data->max_digital_gain[0];
 
+       reg_short_gain[0] = (short_gain & 0x3FFF) >> 8;
+       reg_short_gain[1] = (short_gain & 0xFF);
+       fimc_is_sensor_write8(client, 0x350A, reg_short_gain[0]);
+       fimc_is_sensor_write8(client, 0x350B, reg_short_gain[1]);
+
        dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_dgain = %d/%d us, long_gain(%#x), short_gain(%#x)\n",
                cis->id, __func__, cis->cis_data->sen_vsync_count, dgain->long_val,
                dgain->short_val, long_gain, short_gain);
@@ -1400,8 +1417,8 @@ int sensor_12a10ff_cis_get_min_digital_gain(struct v4l2_subdev *subdev, u32 *min
        }
 
        cis_data = cis->cis_data;
-    cis_data->min_digital_gain[0] = 0x100;
-    cis_data->min_digital_gain[1] = 1000;
+    cis_data->min_digital_gain[0] = REG_1X_BASE_DGAIN;
+    cis_data->min_digital_gain[1] = REG_1X_BASE_DGAIN_VALUE;
        *min_dgain = cis_data->min_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
@@ -1443,8 +1460,8 @@ int sensor_12a10ff_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max
        }
 
        cis_data = cis->cis_data;
-       cis_data->max_digital_gain[0] = 0x100;
-       cis_data->max_digital_gain[1] = 1000;
+       cis_data->max_digital_gain[0] = 0x3FFF;
+       cis_data->max_digital_gain[1] = 16000;
        *max_dgain = cis_data->max_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
index 709d6e5cfdaa956e0b91df60faf34da9bab8b1ff..ac13de96bcb30af5e4eabcb5f87120d2dcd12d3a 100755 (executable)
@@ -1250,6 +1250,17 @@ int sensor_16885c_cis_get_max_analog_gain(struct v4l2_subdev *subdev, u32 *max_a
        return ret;
 }
 
+#define REG_1X_BASE_DGAIN_VALUE        1000
+#define REG_1X_BASE_DGAIN          0x0400
+
+u32 sensor_16885c_dgain_to_reg_value(u32 permile)
+{
+       u32 reg_dgain;
+       reg_dgain = permile * REG_1X_BASE_DGAIN / REG_1X_BASE_DGAIN_VALUE;
+
+       return reg_dgain;
+}
+
 int sensor_16885c_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_param *dgain)
 {
        int ret = 0;
@@ -1259,6 +1270,7 @@ int sensor_16885c_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_par
 
        u16 long_gain = 0;
        u16 short_gain = 0;
+       u8 reg_short_gain[2] = {0};
 
 #ifdef DEBUG_SENSOR_TIME
        struct timeval st, end;
@@ -1282,8 +1294,8 @@ int sensor_16885c_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_par
 
        cis_data = cis->cis_data;
 
-       long_gain = (u16)sensor_cis_calc_dgain_code(dgain->long_val);
-       short_gain = (u16)sensor_cis_calc_dgain_code(dgain->short_val);
+       long_gain = (u16)sensor_16885c_dgain_to_reg_value(dgain->long_val);
+       short_gain = (u16)sensor_16885c_dgain_to_reg_value(dgain->short_val);
 
        if (long_gain < cis->cis_data->min_digital_gain[0])
                long_gain = cis->cis_data->min_digital_gain[0];
@@ -1297,6 +1309,11 @@ int sensor_16885c_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_par
        if (short_gain > cis->cis_data->max_digital_gain[0])
                short_gain = cis->cis_data->max_digital_gain[0];
 
+       reg_short_gain[0] = (short_gain & 0x3FFF) >> 8;
+       reg_short_gain[1] = (short_gain & 0xFF);
+       fimc_is_sensor_write8(client, 0x3676, reg_short_gain[0]);
+       fimc_is_sensor_write8(client, 0x3677, reg_short_gain[1]);
+
        dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_dgain = %d/%d us, long_gain(%#x), short_gain(%#x)\n",
                cis->id, __func__, cis->cis_data->sen_vsync_count, dgain->long_val,
                dgain->short_val, long_gain, short_gain);
@@ -1399,8 +1416,8 @@ int sensor_16885c_cis_get_min_digital_gain(struct v4l2_subdev *subdev, u32 *min_
        }
 
        cis_data = cis->cis_data;
-    cis_data->min_digital_gain[0] = 0x100;
-    cis_data->min_digital_gain[1] = 1000;
+    cis_data->min_digital_gain[0] = REG_1X_BASE_DGAIN;
+    cis_data->min_digital_gain[1] = REG_1X_BASE_DGAIN_VALUE;
        *min_dgain = cis_data->min_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
@@ -1442,8 +1459,8 @@ int sensor_16885c_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max_
        }
 
        cis_data = cis->cis_data;
-       cis_data->max_digital_gain[0] = 0x100;
-       cis_data->max_digital_gain[1] = 1000;
+       cis_data->max_digital_gain[0] = 0x3FFF;
+       cis_data->max_digital_gain[1] = 16000;
        *max_dgain = cis_data->max_digital_gain[1];
 
        dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,