summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuxi Sun <b36102@freescale.com>2012-02-06 17:29:49 +0800
committerYuxi Sun <b36102@freescale.com>2012-02-08 16:37:06 +0800
commit217f64e3c2b2f8a50c99fd9509eb551efe480129 (patch)
tree92f19265d01d8d751bac962a3131380fa979cc90
parent45fb250ee2c72a7aacd583c7ba501326ab2787c4 (diff)
ENGR00173864 MX6Q ipu capture: add multi camera switch
Add IOCTRL command V4L2_CID_MXC_SWITCH_CAM for multi camera switch Signed-off-by: Yuxi Sun <b36102@freescale.com>
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.c41
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.h27
-rw-r--r--include/linux/mxc_v4l2.h5
3 files changed, 68 insertions, 5 deletions
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
index ada0e7168cae..b2ece92436fb 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
@@ -40,6 +40,8 @@
#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;
@@ -1009,8 +1011,9 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
*/
static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
{
- int ret = 0;
+ int i, ret = 0;
int tmp_rotation = IPU_ROTATE_NONE;
+ struct sensor_data *sensor_data;
pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
@@ -1179,6 +1182,25 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
ipu_csi_flash_strobe(true);
#endif
break;
+ 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++) {
+ if (i != c->value) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ }
+ }
+ sensor_data = cam->all_sensors[c->value]->priv;
+ if (sensor_data->io_init)
+ sensor_data->io_init();
+ cam->sensor = cam->all_sensors[c->value];
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, true, true);
+ vidioc_int_s_power(cam->sensor, 1);
+ vidioc_int_dev_init(cam->sensor);
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, false, false);
+ }
+ break;
default:
pr_debug(" default case\n");
ret = -EINVAL;
@@ -2773,17 +2795,32 @@ 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;
pr_debug("In MVC: mxc_v4l2_master_attach\n");
pr_debug(" slave.name = %s\n", slave->name);
pr_debug(" master.name = %s\n", slave->u.slave->master->name);
- cam->sensor = slave;
if (slave == NULL) {
pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
return -1;
}
+ cam->sensor = slave;
+
+ if (sensor_index < MXC_SENSOR_NUM) {
+ cam->all_sensors[sensor_index] = slave;
+ sensor_index++;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
+ return -1;
+ }
+
+ for (i = 0; i < sensor_index - 1; i++) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ }
+
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, true, true);
vidioc_int_s_power(cam->sensor, 1);
vidioc_int_dev_init(slave);
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
index 350d4bd7f59c..5b7b0bfe7706 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -194,10 +194,35 @@ typedef struct _cam_data {
/* camera sensor interface */
struct camera_sensor *cam_sensor; /* old version */
+ struct v4l2_int_device *all_sensors[2];
struct v4l2_int_device *sensor;
void *ipu;
} cam_data;
+struct sensor_data {
+ const struct ov5642_platform_data *platform_data;
+ struct v4l2_int_device *v4l2_int_device;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ int csi;
+
+ void (*io_init)(void);
+};
+
#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) \
|| defined(CONFIG_VIDEO_MXC_CSI_CAMERA_MODULE) \
|| defined(CONFIG_VIDEO_MXC_CSI_CAMERA)
diff --git a/include/linux/mxc_v4l2.h b/include/linux/mxc_v4l2.h
index e83e5923c2a4..dd106ff31265 100644
--- a/include/linux/mxc_v4l2.h
+++ b/include/linux/mxc_v4l2.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -29,7 +29,8 @@
#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
-#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
#define V4L2_MXC_ROTATE_NONE 0
#define V4L2_MXC_ROTATE_VERT_FLIP 1