MLK-17025-1 media: camera: use the CLKO2 from SoC as MCLK for camera
authorRobby Cai <robby.cai@nxp.com>
Wed, 29 Nov 2017 07:35:09 +0000 (15:35 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:49:50 +0000 (14:49 -0500)
use internal clock as MCLK source for camera ov5640.
The driver will adjust the setting for ov5640 accordingly.

Signed-off-by: Robby Cai <robby.cai@nxp.com>
Reviewed-by: Sandor Yu <sandor.yu@nxp.com>
(cherry picked from commit 9bed75aca0b355e41279622407fd30c8b670445b)

drivers/media/platform/mxc/capture/ov5640_mipi_v2.c

index 2ac8478..ae41a66 100644 (file)
@@ -37,6 +37,7 @@
 
 #define OV5640_XCLK_MIN 6000000
 #define OV5640_XCLK_MAX 24000000
+#define OV5640_XCLK_20MHZ 20000000
 
 #define OV5640_CHIP_ID_HIGH_BYTE       0x300A
 #define OV5640_CHIP_ID_LOW_BYTE                0x300B
@@ -1527,6 +1528,42 @@ static struct v4l2_subdev_ops ov5640_subdev_ops = {
        .pad    = &ov5640_subdev_pad_ops,
 };
 
+static void ov5640_adjust_setting_20mhz(void)
+{
+       struct ov5640_mode_info *modeinfo;
+       struct reg_value *regsetting;
+       int i, j, k, array_size;
+
+       /* adjust for INIT mode */
+       regsetting = ov5640_init_setting_30fps_VGA;
+       array_size = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
+
+       for (k = 0; k < array_size; k++, regsetting++)
+               if (regsetting->u16RegAddr == 0x3036)
+                       regsetting->u8Val = 0x44;
+
+       /* adjust for other modes */
+       for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
+               for (j = 0; j < ov5640_mode_MAX; j++) {
+                       modeinfo = &ov5640_mode_info_data[i][j];
+                       regsetting = modeinfo->init_data_ptr;
+                       array_size = modeinfo->init_data_size;
+                       if (regsetting == NULL || array_size == 0)
+                               continue;
+
+                       for (k = 0; k < array_size; k++, regsetting++) {
+                               if (regsetting->u16RegAddr == 0x3036) {
+                                       if (modeinfo->width == 640)
+                                               regsetting->u8Val = 0x44;
+                                       else if (modeinfo->width == 720)
+                                               regsetting->u8Val = 0x87;
+                                       else
+                                               regsetting->u8Val = 0x65;
+                               }
+                       }
+               }
+       }
+}
 
 /*!
  * ov5640 I2C probe function
@@ -1591,6 +1628,9 @@ static int ov5640_probe(struct i2c_client *client,
                return retval;
        }
 
+       if (ov5640_data.mclk == OV5640_XCLK_20MHZ)
+               ov5640_adjust_setting_20mhz();
+
        retval = of_property_read_u32(dev->of_node, "mclk_source",
                                        (u32 *) &(ov5640_data.mclk_source));
        if (retval) {