From f20b2db179b2cc9f941d5ed3b994d5eaa6dd50ea Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Tue, 10 Jun 2014 18:25:07 -0700 Subject: mxc_v4l2_capture: match ipu/csi/mipi instead of only ipu/csi (cherry picked from commit f3ce4f51a39f0eb6727166cbdba3e92b37f237e8) Conflicts: drivers/media/platform/mxc/capture/mxc_v4l2_capture.c --- .../media/platform/mxc/capture/mxc_v4l2_capture.c | 67 +++++++++++++++++++--- .../media/platform/mxc/capture/mxc_v4l2_capture.h | 2 + 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c index dfc63b79b971..57b16d06fd4d 100644 --- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c +++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c @@ -34,9 +34,12 @@ #include #include #include +#include +#include #include #include #include +#include #include #include #include @@ -1598,6 +1601,8 @@ void power_off_camera(cam_data *cam) schedule_delayed_work(&cam->power_down_work, (HZ * 2)); } +unsigned long csi_in_use; + /*! * V4L interface - open function * @@ -1615,6 +1620,7 @@ static int mxc_v4l_open(struct file *file) cam_data *cam = video_get_drvdata(dev); int err = 0; struct sensor_data *sensor; + int csi_bit; pr_debug("\nIn MVC: mxc_v4l_open\n"); pr_debug(" device name is %s\n", dev->name); @@ -1639,11 +1645,45 @@ static int mxc_v4l_open(struct file *file) } down(&cam->busy_lock); + err = 0; if (signal_pending(current)) goto oops; if (cam->open_count++ == 0) { + struct regmap *gpr; + + csi_bit = (cam->ipu_id << 1) | cam->csi; + if (test_and_set_bit(csi_bit, &csi_in_use)) { + pr_err("%s: %s CSI already in use\n", __func__, dev->name); + err = -EBUSY; + cam->open_count = 0; + goto oops; + } + cam->csi_in_use = 1; + + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); + if (!IS_ERR(gpr)) { + if (of_machine_is_compatible("fsl,imx6q")) { + if (cam->ipu_id == cam->csi) { + unsigned shift = 19 + cam->csi; + unsigned mask = 1 << shift; + unsigned val = (cam->mipi_camera ? 0 : 1) << shift; + + regmap_update_bits(gpr, IOMUXC_GPR1, mask, val); + } + } else if (of_machine_is_compatible("fsl,imx6dl")) { + unsigned shift = cam->csi * 3; + unsigned mask = 7 << shift; + unsigned val = (cam->mipi_camera ? csi_bit : 4) << shift; + + regmap_update_bits(gpr, IOMUXC_GPR13, mask, val); + } + } else { + pr_err("%s: failed to find fsl,imx6q-iomux-gpr regmap\n", + __func__); + } + wait_event_interruptible(cam->power_queue, cam->low_power == false); @@ -1823,6 +1863,13 @@ static int mxc_v4l_close(struct file *file) mxc_free_frames(cam); cam->enc_counter++; power_off_camera(cam); + + if (cam->csi_in_use) { + int csi_bit = (cam->ipu_id << 1) | cam->csi; + + clear_bit(csi_bit, &csi_in_use); + cam->csi_in_use = 0; + } } up(&cam->busy_lock); @@ -2659,7 +2706,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev) const struct of_device_id *of_id = of_match_device(mxc_v4l2_dt_ids, &pdev->dev); struct device_node *np = pdev->dev.of_node; - int ipu_id, csi_id, mclk_source; + int ipu_id, csi_id, mclk_source, mipi_camera; int ret = 0; struct v4l2_device *v4l2_dev; static int camera_id; @@ -2684,6 +2731,10 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev) return ret; } + ret = of_property_read_u32(np, "mipi_camera", &mipi_camera); + if (ret) + mipi_camera = 0; + /* Default everything to 0 */ memset(cam, 0, sizeof(cam_data)); @@ -2773,6 +2824,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev) cam->ipu_id = ipu_id; cam->csi = csi_id; + cam->mipi_camera = mipi_camera; cam->mclk_source = mclk_source; cam->mclk_on[cam->mclk_source] = false; @@ -3046,12 +3098,9 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave) return -1; } - if (sdata->ipu_id != cam->ipu_id) { - pr_debug("%s: ipu doesn't match\n", __func__); - return -1; - } - if (sdata->csi != cam->csi) { - pr_debug("%s: csi doesn't match\n", __func__); + if ((sdata->ipu_id != cam->ipu_id) || (sdata->csi != cam->csi) || (sdata->mipi_camera != cam->mipi_camera)) { + pr_info("%s: ipu(%d:%d)/csi(%d:%d)/mipi(%d:%d) doesn't match\n", __func__, + sdata->ipu_id, cam->ipu_id, sdata->csi, cam->csi, sdata->mipi_camera, cam->mipi_camera); return -1; } @@ -3105,6 +3154,10 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave) __func__, cam->crop_current.width, cam->crop_current.height); + pr_info("%s: ipu%d:/csi%d %s attached %s:%s\n", __func__, + cam->ipu_id, cam->csi, cam->mipi_camera ? "mipi" : "parallel", + slave->name, slave->u.slave->master->name); + return 0; } diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h index f4a92a4892b1..5542c416b7bf 100644 --- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h +++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h @@ -210,6 +210,8 @@ typedef struct _cam_data { wait_queue_head_t power_queue; unsigned int ipu_id; unsigned int csi; + unsigned mipi_camera; + int csi_in_use; u8 mclk_source; bool mclk_on[2]; /* two mclk sources at most now */ int current_input; -- cgit v1.2.3