summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Kudrick <jeff.kudrick@freescale.com>2012-06-11 13:02:40 -0500
committerJeff Kudrick <jeff.kudrick@freescale.com>2012-06-11 13:02:40 -0500
commitdfab7be58bc1ae8910fe363c8ab78f63483cf613 (patch)
tree6e6670d84fa96d724defbd1d15b0f885ad60a7c3
parent569dc9187a890c0b04779df0af882df69fd093aa (diff)
ENGR00211151: Cannot connect to Camera after start/stop Camcorder many times
Aligned latest i.MX6 ICS 3.0.15 kernel changes for media processing and Camera support. Signed-off-by: Jeff Kudrick <jeff.kudrick@freescale.com>
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_enc.c5
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.c124
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.h8
-rw-r--r--drivers/media/video/mxc/capture/ov3640.c3
-rw-r--r--drivers/media/video/mxc/capture/ov5640.c3
-rw-r--r--drivers/media/video/mxc/capture/ov5640_mipi.c17
-rw-r--r--drivers/media/video/mxc/capture/ov5642.c5
-rw-r--r--drivers/media/video/mxc/capture/ov8820_mipi.c6
-rw-r--r--drivers/media/video/mxc/output/mxc_vout.c20
-rw-r--r--include/linux/fsl_devices.h8
10 files changed, 125 insertions, 74 deletions
diff --git a/drivers/media/video/mxc/capture/ipu_prp_enc.c b/drivers/media/video/mxc/capture/ipu_prp_enc.c
index 6710cba5d817..02515b35ba03 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_enc.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -170,7 +170,8 @@ static int prp_enc_setup(cam_data *cam)
return err;
}
- ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_ENC, cam->csi, true, true);
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_ENC,
+ cam->mclk_source, true, true);
grotation = cam->rotation;
if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
index 28ca0c557271..c2bda758a362 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
@@ -32,19 +32,19 @@
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/dma-mapping.h>
+#include <linux/delay.h>
#include <linux/mxcfb.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-int-device.h>
+#include <linux/fsl_devices.h>
#include "mxc_v4l2_capture.h"
#include "ipu_prp_sw.h"
#define init_MUTEX(sem) sema_init(sem, 1)
#define MXC_SENSOR_NUM 2
-static int sensor_index;
-static int video_nr = -1, local_buf_num;
-static cam_data *g_cam;
+static int video_nr = -1;
/*! This data is used for the output to the display. */
#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 3
@@ -404,7 +404,7 @@ static int mxc_streamon(cam_data *cam)
}
cam->ping_pong_csi = 0;
- local_buf_num = 0;
+ cam->local_buf_num = 0;
if (cam->enc_update_eba) {
frame =
list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
@@ -1229,7 +1229,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
case V4L2_CID_MXC_SWITCH_CAM:
if (cam->sensor != cam->all_sensors[c->value]) {
/* power down other cameraes before enable new one */
- for (i = 0; i < sensor_index; i++) {
+ for (i = 0; i < cam->sensor_index; i++) {
if (i != c->value) {
vidioc_int_dev_exit(cam->all_sensors[i]);
vidioc_int_s_power(cam->all_sensors[i], 0);
@@ -1684,12 +1684,13 @@ static int mxc_v4l_open(struct file *file)
cam_fmt.fmt.pix.pixelformat,
csi_param);
- ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi,
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->mclk_source,
true, true);
vidioc_int_s_power(cam->sensor, 1);
+ msleep(1);
vidioc_int_init(cam->sensor);
vidioc_int_dev_init(cam->sensor);
-}
+ }
file->private_data = dev;
@@ -1724,12 +1725,13 @@ static int mxc_v4l_close(struct file *file)
err = stop_preview(cam);
cam->overlay_on = false;
}
- if (cam->capture_pid == current->pid) {
- err |= mxc_streamoff(cam);
- wake_up_interruptible(&cam->enc_queue);
- }
if (--cam->open_count == 0) {
+ if (cam->capture_pid == current->pid) {
+ err |= mxc_streamoff(cam);
+ wake_up_interruptible(&cam->enc_queue);
+ }
+
vidioc_int_s_power(cam->sensor, 0);
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi,
false, false);
@@ -2518,7 +2520,7 @@ static void camera_callback(u32 mask, void *dev)
struct mxc_v4l_frame,
queue);
- if (done_frame->ipu_buf_num != local_buf_num)
+ if (done_frame->ipu_buf_num != cam->local_buf_num)
goto next;
/*
@@ -2555,7 +2557,7 @@ next:
list_del(cam->ready_q.next);
list_add_tail(&ready_frame->queue,
&cam->working_q);
- ready_frame->ipu_buf_num = local_buf_num;
+ ready_frame->ipu_buf_num = cam->local_buf_num;
}
} else {
if (cam->enc_update_eba)
@@ -2564,7 +2566,7 @@ next:
&cam->ping_pong_csi);
}
- local_buf_num = (local_buf_num == 0) ? 1 : 0;
+ cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
return;
}
@@ -2578,11 +2580,13 @@ next:
*/
static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
{
+ struct fsl_mxc_capture_platform_data *pdata = pdev->dev.platform_data;
+
pr_debug("In MVC: init_camera_struct\n");
/* Default everything to 0 */
memset(cam, 0, sizeof(cam_data));
- cam->ipu = ipu_get_soc(0);
+ cam->ipu = ipu_get_soc(pdata->ipu);
if (cam->ipu == NULL)
pr_err("ERROR: v4l2 capture: failed to get ipu\n");
else if (cam->ipu == ERR_PTR(-ENODEV))
@@ -2639,8 +2643,8 @@ static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
cam->win.w.left = 0;
cam->win.w.top = 0;
- cam->csi = 0; /* Need to determine how to set this correctly with
- * multiple video input devices. */
+ cam->csi = pdata->csi;
+ cam->mclk_source = pdata->mclk_source;
cam->enc_callback = camera_callback;
init_waitqueue_head(&cam->power_queue);
@@ -2654,6 +2658,12 @@ static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
pr_err("ERROR: v4l2 capture: Allocate dummy frame "
"failed.\n");
cam->dummy_frame.buffer.length = SZ_8M;
+
+ cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
+ cam->self->module = THIS_MODULE;
+ sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
+ cam->self->type = v4l2_int_type_master;
+ cam->self->u.master = &mxc_v4l2_master;
}
static ssize_t show_streaming(struct device *dev,
@@ -2661,9 +2671,9 @@ static ssize_t show_streaming(struct device *dev,
{
struct video_device *video_dev = container_of(dev,
struct video_device, dev);
- cam_data *g_cam = video_get_drvdata(video_dev);
+ cam_data *cam = video_get_drvdata(video_dev);
- if (g_cam->capture_on)
+ if (cam->capture_on)
return sprintf(buf, "stream on\n");
else
return sprintf(buf, "stream off\n");
@@ -2675,9 +2685,9 @@ static ssize_t show_overlay(struct device *dev,
{
struct video_device *video_dev = container_of(dev,
struct video_device, dev);
- cam_data *g_cam = video_get_drvdata(video_dev);
+ cam_data *cam = video_get_drvdata(video_dev);
- if (g_cam->overlay_on)
+ if (cam->overlay_on)
return sprintf(buf, "overlay on\n");
else
return sprintf(buf, "overlay off\n");
@@ -2694,38 +2704,38 @@ static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
*/
static int mxc_v4l2_probe(struct platform_device *pdev)
{
- /* Create g_cam and initialize it. */
- g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
- if (g_cam == NULL) {
+ /* Create cam and initialize it. */
+ cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
+ if (cam == NULL) {
pr_err("ERROR: v4l2 capture: failed to register camera\n");
return -1;
}
- init_camera_struct(g_cam, pdev);
+ init_camera_struct(cam, pdev);
pdev->dev.release = camera_platform_release;
/* Set up the v4l2 device and register it*/
- mxc_v4l2_int_device.priv = g_cam;
+ cam->self->priv = cam;
/* This function contains a bug that won't let this be rmmod'd. */
- v4l2_int_device_register(&mxc_v4l2_int_device);
+ v4l2_int_device_register(cam->self);
/* register v4l video device */
- if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
+ if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
== -1) {
- kfree(g_cam);
- g_cam = NULL;
+ kfree(cam);
+ cam = NULL;
pr_err("ERROR: v4l2 capture: video_register_device failed\n");
return -1;
}
pr_debug(" Video device registered: %s #%d\n",
- g_cam->video_dev->name, g_cam->video_dev->minor);
+ cam->video_dev->name, cam->video_dev->minor);
- if (device_create_file(&g_cam->video_dev->dev,
+ if (device_create_file(&cam->video_dev->dev,
&dev_attr_fsl_v4l2_capture_property))
dev_err(&pdev->dev, "Error on creating sysfs file"
" for capture\n");
- if (device_create_file(&g_cam->video_dev->dev,
+ if (device_create_file(&cam->video_dev->dev,
&dev_attr_fsl_v4l2_overlay_property))
dev_err(&pdev->dev, "Error on creating sysfs file"
" for overlay\n");
@@ -2743,31 +2753,31 @@ static int mxc_v4l2_probe(struct platform_device *pdev)
*/
static int mxc_v4l2_remove(struct platform_device *pdev)
{
+ cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
- if (g_cam->dummy_frame.vaddress != 0) {
- dma_free_coherent(0, g_cam->dummy_frame.buffer.length,
- g_cam->dummy_frame.vaddress,
- g_cam->dummy_frame.paddress);
- g_cam->dummy_frame.vaddress = 0;
+ if (cam->dummy_frame.vaddress != 0) {
+ dma_free_coherent(0, cam->dummy_frame.buffer.length,
+ cam->dummy_frame.vaddress,
+ cam->dummy_frame.paddress);
+ cam->dummy_frame.vaddress = 0;
}
- if (g_cam->open_count) {
+ if (cam->open_count) {
pr_err("ERROR: v4l2 capture:camera open "
"-- setting ops to NULL\n");
return -EBUSY;
} else {
- device_remove_file(&g_cam->video_dev->dev,
+ device_remove_file(&cam->video_dev->dev,
&dev_attr_fsl_v4l2_capture_property);
- device_remove_file(&g_cam->video_dev->dev,
+ device_remove_file(&cam->video_dev->dev,
&dev_attr_fsl_v4l2_overlay_property);
pr_info("V4L2 freeing image input device\n");
v4l2_int_device_unregister(&mxc_v4l2_int_device);
- video_unregister_device(g_cam->video_dev);
+ video_unregister_device(cam->video_dev);
- mxc_free_frame_buf(g_cam);
- kfree(g_cam);
- g_cam = NULL;
+ mxc_free_frame_buf(cam);
+ kfree(cam);
}
pr_info("V4L2 unregistering video\n");
@@ -2864,6 +2874,7 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
cam_data *cam = slave->u.slave->master->priv;
struct v4l2_format cam_fmt;
int i;
+ struct sensor_data *sdata = slave->priv;
pr_debug("In MVC: mxc_v4l2_master_attach\n");
pr_debug(" slave.name = %s\n", slave->name);
@@ -2874,17 +2885,22 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
return -1;
}
+ if (sdata->csi != cam->csi) {
+ pr_debug("%s: csi doesn't match\n", __func__);
+ return -1;
+ }
+
cam->sensor = slave;
- if (sensor_index < MXC_SENSOR_NUM) {
- cam->all_sensors[sensor_index] = slave;
- sensor_index++;
+ if (cam->sensor_index < MXC_SENSOR_NUM) {
+ cam->all_sensors[cam->sensor_index] = slave;
+ cam->sensor_index++;
} else {
pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
return -1;
}
- for (i = 0; i < sensor_index; i++) {
+ for (i = 0; i < cam->sensor_index; i++) {
vidioc_int_dev_exit(cam->all_sensors[i]);
vidioc_int_s_power(cam->all_sensors[i], 0);
}
@@ -2936,23 +2952,23 @@ static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
pr_debug("In MVC:mxc_v4l2_master_detach\n");
- if (sensor_index > 1) {
- for (i = 0; i < sensor_index; i++) {
+ if (cam->sensor_index > 1) {
+ for (i = 0; i < cam->sensor_index; i++) {
if (cam->all_sensors[i] != slave)
continue;
/* Move all the sensors behind this
* sensor one step forward
*/
- for (; i < sensor_index - 1; i++)
+ for (; i < cam->sensor_index - 1; i++)
cam->all_sensors[i] = cam->all_sensors[i+1];
break;
}
/* Point current sensor to the last one */
- cam->sensor = cam->all_sensors[sensor_index - 2];
+ cam->sensor = cam->all_sensors[cam->sensor_index - 2];
} else
cam->sensor = NULL;
- sensor_index--;
+ cam->sensor_index--;
vidioc_int_dev_exit(slave);
}
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
index 5b7b0bfe7706..dcb90a9f4ce5 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
@@ -34,6 +34,8 @@
#include <mach/ipu-v3.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-int-device.h>
+
#define FRAME_NUM 10
@@ -190,12 +192,17 @@ typedef struct _cam_data {
bool low_power;
wait_queue_head_t power_queue;
unsigned int csi;
+ u8 mclk_source;
int current_input;
+ int local_buf_num;
+
/* camera sensor interface */
struct camera_sensor *cam_sensor; /* old version */
struct v4l2_int_device *all_sensors[2];
struct v4l2_int_device *sensor;
+ struct v4l2_int_device *self;
+ int sensor_index;
void *ipu;
} cam_data;
@@ -218,6 +225,7 @@ struct sensor_data {
int ae_mode;
u32 mclk;
+ u8 mclk_source;
int csi;
void (*io_init)(void);
diff --git a/drivers/media/video/mxc/capture/ov3640.c b/drivers/media/video/mxc/capture/ov3640.c
index b1d1abb884d9..69a3ad43b22c 100644
--- a/drivers/media/video/mxc/capture/ov3640.c
+++ b/drivers/media/video/mxc/capture/ov3640.c
@@ -1354,7 +1354,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
ov3640_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
- set_mclk_rate(&ov3640_data.mclk, ov3640_data.csi);
+ set_mclk_rate(&ov3640_data.mclk, ov3640_data.mclk_source);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
@@ -1442,6 +1442,7 @@ static int ov3640_probe(struct i2c_client *client,
memset(&ov3640_data, 0, sizeof(ov3640_data));
ov3640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov3640_data.mclk = plat_data->mclk;
+ ov3640_data.mclk_source = plat_data->mclk_source;
ov3640_data.csi = plat_data->csi;
ov3640_data.io_init = plat_data->io_init;
diff --git a/drivers/media/video/mxc/capture/ov5640.c b/drivers/media/video/mxc/capture/ov5640.c
index f9087499b5f1..c2dfe314c65d 100644
--- a/drivers/media/video/mxc/capture/ov5640.c
+++ b/drivers/media/video/mxc/capture/ov5640.c
@@ -1309,7 +1309,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
ov5640_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
- set_mclk_rate(&ov5640_data.mclk, ov5640_data.csi);
+ set_mclk_rate(&ov5640_data.mclk, ov5640_data.mclk_source);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
@@ -1397,6 +1397,7 @@ static int ov5640_probe(struct i2c_client *client,
memset(&ov5640_data, 0, sizeof(ov5640_data));
ov5640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5640_data.mclk = plat_data->mclk;
+ ov5640_data.mclk_source = plat_data->mclk_source;
ov5640_data.csi = plat_data->csi;
ov5640_data.io_init = plat_data->io_init;
diff --git a/drivers/media/video/mxc/capture/ov5640_mipi.c b/drivers/media/video/mxc/capture/ov5640_mipi.c
index 2d9d83b7b139..9ffca952cc29 100644
--- a/drivers/media/video/mxc/capture/ov5640_mipi.c
+++ b/drivers/media/video/mxc/capture/ov5640_mipi.c
@@ -195,7 +195,7 @@ static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
};
static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
- {0x3035, 0x24, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
{0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
{0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
{0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
@@ -237,7 +237,7 @@ static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
};
static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
- {0x3035, 0x24, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
+ {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
{0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
{0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
{0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
@@ -909,6 +909,15 @@ bool binning_on(void)
return false;
}
+static void ov5640_set_virtual_channel(int channel)
+{
+ u8 channel_id;
+
+ ov5640_read_reg(0x4814, &channel_id);
+ channel_id &= ~(3 << 6);
+ ov5640_write_reg(0x4814, channel_id | (channel << 6));
+}
+
static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
enum ov5640_mode mode)
{
@@ -1164,6 +1173,7 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
OV5640_set_AE_target(AE_Target);
OV5640_get_light_frequency();
OV5640_set_bandingfilter();
+ ov5640_set_virtual_channel(ov5640_data.csi);
if (mipi_csi2_info) {
unsigned int i;
@@ -1604,7 +1614,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
ov5640_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
- set_mclk_rate(&ov5640_data.mclk, ov5640_data.csi);
+ set_mclk_rate(&ov5640_data.mclk, ov5640_data.mclk_source);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
@@ -1712,6 +1722,7 @@ static int ov5640_probe(struct i2c_client *client,
memset(&ov5640_data, 0, sizeof(ov5640_data));
ov5640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5640_data.mclk = plat_data->mclk;
+ ov5640_data.mclk_source = plat_data->mclk_source;
ov5640_data.csi = plat_data->csi;
ov5640_data.io_init = plat_data->io_init;
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c
index f8f8a6c12ab4..58ee92eef678 100644
--- a/drivers/media/video/mxc/capture/ov5642.c
+++ b/drivers/media/video/mxc/capture/ov5642.c
@@ -279,7 +279,7 @@ static struct reg_value ov5642_initial_setting[] = {
{0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
{0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
{0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
- {0x302b, 0x00, 0, 0},
+ {0x302b, 0x00, 0, 300},
};
static struct reg_value ov5642_setting_15fps_QCIF_176_144[] = {
@@ -3255,7 +3255,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
ov5642_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
- set_mclk_rate(&ov5642_data.mclk, ov5642_data.csi);
+ set_mclk_rate(&ov5642_data.mclk, ov5642_data.mclk_source);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
@@ -3368,6 +3368,7 @@ static int ov5642_probe(struct i2c_client *client,
memset(&ov5642_data, 0, sizeof(ov5642_data));
ov5642_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5642_data.mclk = plat_data->mclk;
+ ov5642_data.mclk_source = plat_data->mclk_source;
ov5642_data.csi = plat_data->csi;
ov5642_data.io_init = plat_data->io_init;
diff --git a/drivers/media/video/mxc/capture/ov8820_mipi.c b/drivers/media/video/mxc/capture/ov8820_mipi.c
index 4c2a49d8bef5..6fddbb03fc0b 100644
--- a/drivers/media/video/mxc/capture/ov8820_mipi.c
+++ b/drivers/media/video/mxc/capture/ov8820_mipi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -92,6 +92,7 @@ struct sensor {
int ae_mode;
u32 mclk;
+ u8 mclk_source;
int csi;
} ov8820_data;
@@ -762,7 +763,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
ov8820_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
- set_mclk_rate(&ov8820_data.mclk, ov8820_data.csi);
+ set_mclk_rate(&ov8820_data.mclk, ov8820_data.mclk_source);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
@@ -871,6 +872,7 @@ static int ov8820_probe(struct i2c_client *client,
memset(&ov8820_data, 0, sizeof(ov8820_data));
ov8820_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov8820_data.mclk = plat_data->mclk;
+ ov8820_data.mclk_source = plat_data->mclk_source;
ov8820_data.csi = plat_data->csi;
ov8820_data.i2c_client = client;
diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c
index aebe57fda0c5..68a084a64e77 100644
--- a/drivers/media/video/mxc/output/mxc_vout.c
+++ b/drivers/media/video/mxc/output/mxc_vout.c
@@ -1675,16 +1675,18 @@ static void release_disp_output(struct mxc_vout_output *vout)
set_window_position(vout, &pos);
if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
- console_lock();
- fbi->fix.smem_start = vout->fb_smem_start;
- fbi->fix.smem_len = vout->fb_smem_len;
- vout->fb_var.activate |= FB_ACTIVATE_FORCE;
- fbi->flags |= FBINFO_MISC_USEREVENT;
- ret = fb_set_var(fbi, &vout->fb_var);
- fbi->flags &= ~FBINFO_MISC_USEREVENT;
- console_unlock();
- if (ret < 0)
+ if ((vout->fb_smem_len != 0) && (vout->fb_smem_start != 0)) {
+ console_lock();
+ fbi->fix.smem_start = vout->fb_smem_start;
+ fbi->fix.smem_len = vout->fb_smem_len;
+ vout->fb_var.activate |= FB_ACTIVATE_FORCE;
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ ret = fb_set_var(fbi, &vout->fb_var);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ if (ret < 0)
v4l2_err(vout->vfd->v4l2_dev, "ERR: fb_set_var.\n");
+ }
console_lock();
fbi->flags |= FBINFO_MISC_USEREVENT;
fb_blank(fbi, FB_BLANK_UNBLANK);
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index bec8fe9cd838..1dcea253f651 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -280,12 +280,20 @@ struct fsl_mxc_hdmi_core_platform_data {
int disp_id;
};
+struct fsl_mxc_capture_platform_data {
+ int csi;
+ int ipu;
+ u8 mclk_source;
+ u8 is_mipi;
+};
+
struct fsl_mxc_camera_platform_data {
char *core_regulator;
char *io_regulator;
char *analog_regulator;
char *gpo_regulator;
u32 mclk;
+ u8 mclk_source;
u32 csi;
void (*pwdn)(int pwdn);
void (*io_init)(void);