Merge "msm: camera: Convert CSIPHY into platform device" into msm-3.0
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 3636963..41f8879 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -1419,6 +1419,9 @@
msm_get_cam_resources(s_info);
platform_device_register(cam_dev[i]);
}
+
+ platform_device_register(&msm8960_device_csiphy0);
+ platform_device_register(&msm8960_device_csiphy1);
}
#endif
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 60ddc52..5cc2d1b 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5396,9 +5396,12 @@
CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, "msm_camera_ov2720.0"),
CLK_LOOKUP("csi_pix_clk", csi_pix_clk.c, NULL),
CLK_LOOKUP("csi_rdi_clk", csi_rdi_clk.c, NULL),
- CLK_LOOKUP("csiphy_timer_src_clk", csiphy_timer_src_clk.c, NULL),
- CLK_LOOKUP("csi0phy_timer_clk", csi0phy_timer_clk.c, NULL),
- CLK_LOOKUP("csi1phy_timer_clk", csi1phy_timer_clk.c, NULL),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.0"),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.1"),
+ CLK_LOOKUP("csiphy_timer_clk", csi0phy_timer_clk.c, "msm_csiphy.0"),
+ CLK_LOOKUP("csiphy_timer_clk", csi1phy_timer_clk.c, "msm_csiphy.1"),
CLK_LOOKUP("dsi_byte_div_clk", dsi1_byte_clk.c, NULL),
CLK_LOOKUP("dsi_byte_div_clk", dsi2_byte_clk.c, NULL),
CLK_LOOKUP("dsi_esc_clk", dsi1_esc_clk.c, NULL),
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 5d0a13c..d9bf7db 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1035,18 +1035,6 @@
.flags = IORESOURCE_IRQ,
},
{
- .name = "csiphy0",
- .start = 0x04800C00,
- .end = 0x04800C00 + SZ_1K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "csiphy0",
- .start = CSIPHY_4LN_IRQ,
- .end = CSIPHY_4LN_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- {
.name = "csid1",
.start = 0x04800400,
.end = 0x04800400 + SZ_1K - 1,
@@ -1059,18 +1047,6 @@
.flags = IORESOURCE_IRQ,
},
{
- .name = "csiphy1",
- .start = 0x04801000,
- .end = 0x04801000 + SZ_1K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "csiphy1",
- .start = MSM8960_CSIPHY_2LN_IRQ,
- .end = MSM8960_CSIPHY_2LN_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- {
.name = "s3d_rw",
.start = 0x008003E0,
.end = 0x008003E0 + SZ_16 - 1,
@@ -1091,6 +1067,50 @@
s_info->num_resources = ARRAY_SIZE(msm_camera_resources);
return 0;
}
+
+static struct resource msm_csiphy0_resources[] = {
+ {
+ .name = "csiphy",
+ .start = 0x04800C00,
+ .end = 0x04800C00 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "csiphy",
+ .start = CSIPHY_4LN_IRQ,
+ .end = CSIPHY_4LN_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_csiphy1_resources[] = {
+ {
+ .name = "csiphy",
+ .start = 0x04801000,
+ .end = 0x04801000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "csiphy",
+ .start = MSM8960_CSIPHY_2LN_IRQ,
+ .end = MSM8960_CSIPHY_2LN_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm8960_device_csiphy0 = {
+ .name = "msm_csiphy",
+ .id = 0,
+ .resource = msm_csiphy0_resources,
+ .num_resources = ARRAY_SIZE(msm_csiphy0_resources),
+};
+
+struct platform_device msm8960_device_csiphy1 = {
+ .name = "msm_csiphy",
+ .id = 1,
+ .resource = msm_csiphy1_resources,
+ .num_resources = ARRAY_SIZE(msm_csiphy1_resources),
+};
#endif
static struct resource resources_ssbi_pm8921[] = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 4af3e68..b706fcd 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -58,6 +58,8 @@
extern struct platform_device msm8960_device_qup_i2c_gsbi12;
extern struct platform_device msm8960_device_qup_spi_gsbi1;
extern struct platform_device msm8960_gemini_device;
+extern struct platform_device msm8960_device_csiphy0;
+extern struct platform_device msm8960_device_csiphy1;
extern struct platform_device apq8064_device_uart_gsbi1;
extern struct platform_device apq8064_device_uart_gsbi3;
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 59c4cab..d0cf567 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -4,8 +4,9 @@
endif
ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
+ EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
- obj-$(CONFIG_MSM_CAMERA) += io/ sensors/ actuators/
+ obj-$(CONFIG_MSM_CAMERA) += io/ sensors/ actuators/ csi/
else
obj-$(CONFIG_MSM_CAMERA) += msm_camera.o
endif
diff --git a/drivers/media/video/msm/csi/Makefile b/drivers/media/video/msm/csi/Makefile
new file mode 100644
index 0000000..4ec67e6
--- /dev/null
+++ b/drivers/media/video/msm/csi/Makefile
@@ -0,0 +1,3 @@
+GCC_VERSION := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/video/msm
+obj-$(CONFIG_ARCH_MSM8960) += msm_csiphy.o
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
new file mode 100644
index 0000000..b62ec84
--- /dev/null
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -0,0 +1,312 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include "msm_csiphy.h"
+#include "msm.h"
+
+#define DBG_CSIPHY 0
+
+#define V4L2_IDENT_CSIPHY 50003
+
+/*MIPI CSI PHY registers*/
+#define MIPI_CSIPHY_LNn_CFG1_ADDR 0x0
+#define MIPI_CSIPHY_LNn_CFG2_ADDR 0x4
+#define MIPI_CSIPHY_LNn_CFG3_ADDR 0x8
+#define MIPI_CSIPHY_LNn_CFG4_ADDR 0xC
+#define MIPI_CSIPHY_LNn_CFG5_ADDR 0x10
+#define MIPI_CSIPHY_LNCK_CFG1_ADDR 0x100
+#define MIPI_CSIPHY_LNCK_CFG2_ADDR 0x104
+#define MIPI_CSIPHY_LNCK_CFG3_ADDR 0x108
+#define MIPI_CSIPHY_LNCK_CFG4_ADDR 0x10C
+#define MIPI_CSIPHY_LNCK_CFG5_ADDR 0x110
+#define MIPI_CSIPHY_LNCK_MISC1_ADDR 0x128
+#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR 0x1E0
+#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR 0x1E8
+#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR 0x0144
+#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR 0x0180
+#define MIPI_CSIPHY_INTERRUPT_STATUS1_ADDR 0x0184
+#define MIPI_CSIPHY_INTERRUPT_STATUS2_ADDR 0x0188
+#define MIPI_CSIPHY_INTERRUPT_STATUS3_ADDR 0x018C
+#define MIPI_CSIPHY_INTERRUPT_STATUS4_ADDR 0x0190
+#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR 0x01A0
+#define MIPI_CSIPHY_INTERRUPT_MASK1_ADDR 0x01A4
+#define MIPI_CSIPHY_INTERRUPT_MASK2_ADDR 0x01A8
+#define MIPI_CSIPHY_INTERRUPT_MASK3_ADDR 0x01AC
+#define MIPI_CSIPHY_INTERRUPT_MASK4_ADDR 0x01B0
+#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR 0x01C0
+#define MIPI_CSIPHY_INTERRUPT_CLEAR1_ADDR 0x01C4
+#define MIPI_CSIPHY_INTERRUPT_CLEAR2_ADDR 0x01C8
+#define MIPI_CSIPHY_INTERRUPT_CLEAR3_ADDR 0x01CC
+#define MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR 0x01D0
+
+int msm_csiphy_config(struct csiphy_cfg_params *cfg_params)
+{
+ int rc = 0;
+ int i = 0;
+ uint32_t val = 0;
+ struct csiphy_device *csiphy_dev;
+ struct msm_camera_csiphy_params *csiphy_params;
+ void __iomem *csiphybase;
+ csiphy_dev = v4l2_get_subdevdata(cfg_params->subdev);
+ csiphybase = csiphy_dev->base;
+ csiphy_params = cfg_params->parms;
+ if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
+ CDBG("%s: unsupported lane cnt %d\n",
+ __func__, csiphy_params->lane_cnt);
+ return rc;
+ }
+
+ val = 0x3;
+ msm_io_w((((1 << csiphy_params->lane_cnt) - 1) << 2) | val,
+ csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+ msm_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
+ msm_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
+
+ for (i = 0; i < csiphy_params->lane_cnt; i++) {
+ msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
+ msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+ msm_io_w(csiphy_params->settle_cnt,
+ csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*i);
+ msm_io_w(0x00000052,
+ csiphybase + MIPI_CSIPHY_LNn_CFG5_ADDR + 0x40*i);
+ }
+
+ msm_io_w(0x00000000, csiphybase + MIPI_CSIPHY_LNCK_CFG1_ADDR);
+ msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+ msm_io_w(csiphy_params->settle_cnt,
+ csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
+ msm_io_w(0x5, csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR);
+ msm_io_w(0x2, csiphybase + MIPI_CSIPHY_LNCK_CFG5_ADDR);
+ msm_io_w(0x0, csiphybase + 0x128);
+
+ msm_io_w(0x24,
+ csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
+ msm_io_w(0x24,
+ csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
+
+ for (i = 1; i <= csiphy_params->lane_cnt; i++) {
+ msm_io_w(0x6F,
+ csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR + 0x4*i);
+ msm_io_w(0x6F,
+ csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
+ }
+ return rc;
+}
+
+static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
+{
+ uint32_t irq;
+ struct csiphy_device *csiphy_dev = data;
+ irq = msm_io_r(csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR);
+ msm_io_w(irq, csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
+ CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS0 = 0x%x\n", __func__, irq);
+ irq = msm_io_r(csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_STATUS1_ADDR);
+ msm_io_w(irq, csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_CLEAR1_ADDR);
+ CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS1 = 0x%x\n", __func__, irq);
+ irq = msm_io_r(csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_STATUS2_ADDR);
+ msm_io_w(irq, csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_CLEAR2_ADDR);
+ CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS2 = 0x%x\n", __func__, irq);
+ irq = msm_io_r(csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_STATUS3_ADDR);
+ msm_io_w(irq, csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_CLEAR3_ADDR);
+ CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS3 = 0x%x\n", __func__, irq);
+ irq = msm_io_r(csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_STATUS4_ADDR);
+ msm_io_w(irq, csiphy_dev->base + MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR);
+ CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS4 = 0x%x\n", __func__, irq);
+ msm_io_w(0x1, csiphy_dev->base + 0x164);
+ msm_io_w(0x0, csiphy_dev->base + 0x164);
+ return IRQ_HANDLED;
+}
+
+static int msm_csiphy_subdev_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ BUG_ON(!chip);
+ chip->ident = V4L2_IDENT_CSIPHY;
+ chip->revision = 0;
+ return 0;
+}
+
+static struct msm_cam_clk_info csiphy_clk_info[] = {
+ {"csiphy_timer_src_clk", 177780000},
+ {"csiphy_timer_clk", -1},
+};
+
+static int msm_csiphy_init(struct v4l2_subdev *sd)
+{
+ int rc = 0;
+ struct csiphy_device *csiphy_dev;
+ csiphy_dev = v4l2_get_subdevdata(sd);
+ if (csiphy_dev == NULL) {
+ rc = -ENOMEM;
+ return rc;
+ }
+
+ csiphy_dev->base = ioremap(csiphy_dev->mem->start,
+ resource_size(csiphy_dev->mem));
+ if (!csiphy_dev->base) {
+ rc = -ENOMEM;
+ return rc;
+ }
+
+ rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_clk_info,
+ csiphy_dev->csiphy_clk, ARRAY_SIZE(csiphy_clk_info), 1);
+
+ if (rc < 0) {
+ iounmap(csiphy_dev->base);
+ return rc;
+ }
+
+#if DBG_CSIPHY
+ enable_irq(csiphy_dev->irq->start);
+#endif
+
+ return 0;
+}
+
+static int msm_csiphy_release(struct v4l2_subdev *sd)
+{
+ struct csiphy_device *csiphy_dev;
+ int i;
+ csiphy_dev = v4l2_get_subdevdata(sd);
+ for (i = 0; i < 4; i++)
+ msm_io_w(0x0, csiphy_dev->base +
+ MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+
+ msm_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+ msm_io_w(0x0, csiphy_dev->base + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
+
+ msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_clk_info,
+ csiphy_dev->csiphy_clk, ARRAY_SIZE(csiphy_clk_info), 0);
+
+#if DBG_CSIPHY
+ disable_irq(csiphy_dev->irq->start);
+#endif
+ iounmap(csiphy_dev->base);
+ return 0;
+}
+
+static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct csiphy_cfg_params cfg_params;
+ switch (cmd) {
+ case VIDIOC_MSM_CSIPHY_CFG:
+ cfg_params.subdev = sd;
+ cfg_params.parms = arg;
+ return msm_csiphy_config(
+ (struct csiphy_cfg_params *)&cfg_params);
+ case VIDIOC_MSM_CSIPHY_INIT:
+ return msm_csiphy_init(sd);
+ case VIDIOC_MSM_CSIPHY_RELEASE:
+ return msm_csiphy_release(sd);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static struct v4l2_subdev_core_ops msm_csiphy_subdev_core_ops = {
+ .g_chip_ident = &msm_csiphy_subdev_g_chip_ident,
+ .ioctl = &msm_csiphy_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = {
+ .core = &msm_csiphy_subdev_core_ops,
+};
+
+static int __devinit csiphy_probe(struct platform_device *pdev)
+{
+ struct csiphy_device *new_csiphy_dev;
+ int rc = 0;
+ CDBG("%s: device id = %d\n", __func__, pdev->id);
+ new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL);
+ if (!new_csiphy_dev) {
+ pr_err("%s: no enough memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ v4l2_subdev_init(&new_csiphy_dev->subdev, &msm_csiphy_subdev_ops);
+ v4l2_set_subdevdata(&new_csiphy_dev->subdev, new_csiphy_dev);
+ platform_set_drvdata(pdev, &new_csiphy_dev->subdev);
+
+ mutex_init(&new_csiphy_dev->mutex);
+
+ new_csiphy_dev->mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "csiphy");
+ if (!new_csiphy_dev->mem) {
+ pr_err("%s: no mem resource?\n", __func__);
+ rc = -ENODEV;
+ goto csiphy_no_resource;
+ }
+ new_csiphy_dev->irq = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "csiphy");
+ if (!new_csiphy_dev->irq) {
+ pr_err("%s: no irq resource?\n", __func__);
+ rc = -ENODEV;
+ goto csiphy_no_resource;
+ }
+ new_csiphy_dev->io = request_mem_region(new_csiphy_dev->mem->start,
+ resource_size(new_csiphy_dev->mem), pdev->name);
+ if (!new_csiphy_dev->io) {
+ pr_err("%s: no valid mem region\n", __func__);
+ rc = -EBUSY;
+ goto csiphy_no_resource;
+ }
+
+ rc = request_irq(new_csiphy_dev->irq->start, msm_csiphy_irq,
+ IRQF_TRIGGER_RISING, "csiphy", new_csiphy_dev);
+ if (rc < 0) {
+ release_mem_region(new_csiphy_dev->mem->start,
+ resource_size(new_csiphy_dev->mem));
+ pr_err("%s: irq request fail\n", __func__);
+ rc = -EBUSY;
+ goto csiphy_no_resource;
+ }
+ disable_irq(new_csiphy_dev->irq->start);
+
+ new_csiphy_dev->pdev = pdev;
+ return 0;
+
+csiphy_no_resource:
+ mutex_destroy(&new_csiphy_dev->mutex);
+ kfree(new_csiphy_dev);
+ return 0;
+}
+
+static struct platform_driver csiphy_driver = {
+ .probe = csiphy_probe,
+ .driver = {
+ .name = MSM_CSIPHY_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_csiphy_init_module(void)
+{
+ return platform_driver_register(&csiphy_driver);
+}
+
+static void __exit msm_csiphy_exit_module(void)
+{
+ platform_driver_unregister(&csiphy_driver);
+}
+
+module_init(msm_csiphy_init_module);
+module_exit(msm_csiphy_exit_module);
+MODULE_DESCRIPTION("MSM CSIPHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/csi/msm_csiphy.h b/drivers/media/video/msm/csi/msm_csiphy.h
new file mode 100644
index 0000000..522a1c1
--- /dev/null
+++ b/drivers/media/video/msm/csi/msm_csiphy.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CSIPHY_H
+#define MSM_CSIPHY_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct csiphy_device {
+ struct platform_device *pdev;
+ struct v4l2_subdev subdev;
+ struct resource *mem;
+ struct resource *irq;
+ struct resource *io;
+ void __iomem *base;
+ struct mutex mutex;
+
+ struct clk *csiphy_clk[2];
+};
+
+struct csiphy_cfg_params {
+ struct v4l2_subdev *subdev;
+ void *parms;
+};
+
+#define VIDIOC_MSM_CSIPHY_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct csiphy_cfg_params)
+
+#define VIDIOC_MSM_CSIPHY_INIT \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct v4l2_subdev*)
+
+#define VIDIOC_MSM_CSIPHY_RELEASE \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct v4l2_subdev*)
+
+#endif
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index f9cf5de..ef6d684 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -41,6 +41,8 @@
#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
+#define MSM_CSIPHY_DRV_NAME "msm_csiphy"
+
/* msm queue management APIs*/
#define msm_dequeue(queue, member) ({ \
@@ -113,6 +115,7 @@
NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
NOTIFY_VPE_MSG_EVT,
NOTIFY_PCLK_CHANGE, /* arg = pclk */
+ NOTIFY_CSIPHY_CFG, /* arg = msm_camera_csiphy_params */
NOTIFY_INVALID
};
@@ -215,6 +218,7 @@
struct v4l2_subdev *vpe_sdev; /* vpe sub device : VPE */
struct v4l2_subdev *flash_sdev; /* vpe sub device : VPE */
struct msm_cam_config_dev *config_device;
+ struct v4l2_subdev *csiphy_sdev; /*csiphy sub device*/
struct v4l2_subdev *ispif_sdev; /* ispif sub device */
struct v4l2_subdev *act_sdev; /* actuator sub device */
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index 0e4429e..65bf3ad 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -26,40 +26,8 @@
#include <mach/msm_bus_board.h>
#define DBG_CSID 0
-#define DBG_CSIPHY 0
#define BUFF_SIZE_128 128
-/* MIPI CSI PHY registers */
-#define MIPI_CSIPHY_LNn_CFG1_ADDR 0x0
-#define MIPI_CSIPHY_LNn_CFG2_ADDR 0x4
-#define MIPI_CSIPHY_LNn_CFG3_ADDR 0x8
-#define MIPI_CSIPHY_LNn_CFG4_ADDR 0xC
-#define MIPI_CSIPHY_LNn_CFG5_ADDR 0x10
-#define MIPI_CSIPHY_LNCK_CFG1_ADDR 0x100
-#define MIPI_CSIPHY_LNCK_CFG2_ADDR 0x104
-#define MIPI_CSIPHY_LNCK_CFG3_ADDR 0x108
-#define MIPI_CSIPHY_LNCK_CFG4_ADDR 0x10C
-#define MIPI_CSIPHY_LNCK_CFG5_ADDR 0x110
-#define MIPI_CSIPHY_LNCK_MISC1_ADDR 0x128
-#define MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR 0x1E0
-#define MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR 0x1E8
-#define MIPI_CSIPHY_GLBL_PWR_CFG_ADDR 0x0144
-#define MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR 0x0180
-#define MIPI_CSIPHY_INTERRUPT_STATUS1_ADDR 0x0184
-#define MIPI_CSIPHY_INTERRUPT_STATUS2_ADDR 0x0188
-#define MIPI_CSIPHY_INTERRUPT_STATUS3_ADDR 0x018C
-#define MIPI_CSIPHY_INTERRUPT_STATUS4_ADDR 0x0190
-#define MIPI_CSIPHY_INTERRUPT_MASK0_ADDR 0x01A0
-#define MIPI_CSIPHY_INTERRUPT_MASK1_ADDR 0x01A4
-#define MIPI_CSIPHY_INTERRUPT_MASK2_ADDR 0x01A8
-#define MIPI_CSIPHY_INTERRUPT_MASK3_ADDR 0x01AC
-#define MIPI_CSIPHY_INTERRUPT_MASK4_ADDR 0x01B0
-#define MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR 0x01C0
-#define MIPI_CSIPHY_INTERRUPT_CLEAR1_ADDR 0x01C4
-#define MIPI_CSIPHY_INTERRUPT_CLEAR2_ADDR 0x01C8
-#define MIPI_CSIPHY_INTERRUPT_CLEAR3_ADDR 0x01CC
-#define MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR 0x01D0
-
/* MIPI CSID registers */
#define CSID_HW_VERSION_ADDR 0x0
#define CSID_CORE_CTRL_ADDR 0x4
@@ -122,11 +90,8 @@
static struct clk *camio_csi_rdi_clk;
static struct clk *camio_csi_rdi1_clk;
static struct clk *camio_csi_rdi2_clk;
-static struct clk *camio_csiphy0_timer_clk;
-static struct clk *camio_csiphy1_timer_clk;
static struct clk *camio_vfe_pclk;
static struct clk *camio_csi0_phy_clk;
-static struct clk *camio_csiphy_timer_src_clk;
/*static struct clk *camio_vfe_pclk;*/
static struct clk *camio_jpeg_clk;
@@ -144,10 +109,10 @@
static struct msm_camera_io_clk camio_clk;
static struct platform_device *camio_dev;
-static struct resource *csidio, *csiphyio, *s3drw_io, *s3dctl_io;
-static struct resource *csid_mem, *csiphy_mem, *s3drw_mem, *s3dctl_mem;
-static struct resource *csid_irq, *csiphy_irq;
-void __iomem *csidbase, *csiphybase, *s3d_rw, *s3d_ctl;
+static struct resource *csidio, *s3drw_io, *s3dctl_io;
+static struct resource *csid_mem, *s3drw_mem, *s3dctl_mem;
+static struct resource *csid_irq;
+void __iomem *csidbase, *s3d_rw, *s3d_ctl;
struct msm_bus_scale_pdata *cam_bus_scale_table;
@@ -533,22 +498,6 @@
msm_camio_clk_rate_set_2(clk, csid_core);
break;
- case CAMIO_CSIPHY0_TIMER_CLK:
- camio_csiphy0_timer_clk =
- clk = clk_get(NULL, "csi0phy_timer_clk");
- break;
-
- case CAMIO_CSIPHY1_TIMER_CLK:
- camio_csiphy1_timer_clk =
- clk = clk_get(NULL, "csi1phy_timer_clk");
- break;
-
- case CAMIO_CSIPHY_TIMER_SRC_CLK:
- camio_csiphy_timer_src_clk =
- clk = clk_get(NULL, "csiphy_timer_src_clk");
- msm_camio_clk_rate_set_2(clk, 177780000);
- break;
-
case CAMIO_CSI0_PCLK:
camio_csi0_pclk =
clk = clk_get(NULL, "csi_pclk");
@@ -645,14 +594,6 @@
clk = camio_csi_rdi_clk;
break;
- case CAMIO_CSIPHY0_TIMER_CLK:
- clk = camio_csiphy0_timer_clk;
- break;
-
- case CAMIO_CSIPHY_TIMER_SRC_CLK:
- clk = camio_csiphy_timer_src_clk;
- break;
-
case CAMIO_CSI0_PCLK:
clk = camio_csi0_pclk;
break;
@@ -735,56 +676,6 @@
return IRQ_HANDLED;
}
#endif
-/*
-void msm_io_read_interrupt(void)
-{
- uint32_t irq;
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS0 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS0 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS1_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS1 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS2_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS2 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS3_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS3 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS4_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS4 = 0x%x\n", __func__, irq);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR1_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR2_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR3_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR);
- msm_io_w(0x1, csiphybase + 0x164);
- msm_io_w(0x0, csiphybase + 0x164);
- return;
-}
-*/
-#if DBG_CSIPHY
-static irqreturn_t msm_io_csiphy_irq(int irq_num, void *data)
-{
- uint32_t irq;
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS0_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS0 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS1_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR1_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS1 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS2_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR2_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS2 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS3_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR3_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS3 = 0x%x\n", __func__, irq);
- irq = msm_io_r(csiphybase + MIPI_CSIPHY_INTERRUPT_STATUS4_ADDR);
- msm_io_w(irq, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR);
- CDBG("%s MIPI_CSIPHY_INTERRUPT_STATUS4 = 0x%x\n", __func__, irq);
- msm_io_w(0x1, csiphybase + 0x164);
- msm_io_w(0x0, csiphybase + 0x164);
- return IRQ_HANDLED;
-}
-#endif
static int msm_camio_enable_v2_clks(void)
{
@@ -837,18 +728,7 @@
rc = msm_camio_clk_enable(CAMIO_CSI0_PHY_CLK);
if (rc < 0)
goto csi0_phy_fail;
- rc = msm_camio_clk_enable(CAMIO_CSIPHY_TIMER_SRC_CLK);
- if (rc < 0)
- goto csiphy_timer_src_fail;
- if (csid_core == 0) {
- rc = msm_camio_clk_enable(CAMIO_CSIPHY0_TIMER_CLK);
- if (rc < 0)
- goto csiphy0_timer_fail;
- } else if (csid_core == 1) {
- rc = msm_camio_clk_enable(CAMIO_CSIPHY1_TIMER_CLK);
- if (rc < 0)
- goto csiphy1_timer_fail;
- }
+
rc = msm_camio_clk_enable(CAMIO_CSI0_PCLK);
if (rc < 0)
goto csi0p_fail;
@@ -882,12 +762,6 @@
vfe_fail:
msm_camio_clk_disable(CAMIO_CSI0_PCLK);
csi0p_fail:
- msm_camio_clk_disable(CAMIO_CSIPHY0_TIMER_CLK);
-csiphy1_timer_fail:
- msm_camio_clk_disable(CAMIO_CSIPHY1_TIMER_CLK);
-csiphy0_timer_fail:
- msm_camio_clk_disable(CAMIO_CSIPHY_TIMER_SRC_CLK);
-csiphy_timer_src_fail:
msm_camio_clk_disable(CAMIO_CSI0_PHY_CLK);
csi0_phy_fail:
msm_camio_clk_disable(CAMIO_CSI0_CLK);
@@ -917,11 +791,6 @@
msm_camio_clk_disable(CAMIO_VFE_PCLK);
msm_camio_clk_disable(CAMIO_VFE_CLK);
msm_camio_clk_disable(CAMIO_CSI0_PCLK);
- if (csid_core == 0)
- msm_camio_clk_disable(CAMIO_CSIPHY0_TIMER_CLK);
- else if (csid_core == 1)
- msm_camio_clk_disable(CAMIO_CSIPHY1_TIMER_CLK);
- msm_camio_clk_disable(CAMIO_CSIPHY_TIMER_SRC_CLK);
msm_camio_clk_disable(CAMIO_CSI0_PHY_CLK);
msm_camio_clk_disable(CAMIO_CSI0_CLK);
if (csid_core == 1)
@@ -1047,12 +916,10 @@
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
uint8_t csid_core = camdev->csid_core;
char csid[] = "csid0";
- char csiphy[] = "csiphy0";
if (csid_core < 0 || csid_core > 2)
return -ENODEV;
csid[4] = '0' + csid_core;
- csiphy[6] = '0' + csid_core;
camio_dev = pdev;
camio_clk = camdev->ioclk;
@@ -1072,16 +939,6 @@
pr_err("%s: no irq resource?\n", __func__);
return -ENODEV;
}
- csiphy_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, csiphy);
- if (!csiphy_mem) {
- pr_err("%s: no mem resource?\n", __func__);
- return -ENODEV;
- }
- csiphy_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, csiphy);
- if (!csiphy_irq) {
- pr_err("%s: no irq resource?\n", __func__);
- return -ENODEV;
- }
csidio = request_mem_region(csid_mem->start,
resource_size(csid_mem), pdev->name);
@@ -1101,35 +958,13 @@
if (rc < 0)
goto csi_irq_fail;
#endif
- csiphyio = request_mem_region(csiphy_mem->start,
- resource_size(csiphy_mem), pdev->name);
- if (!csidio) {
- rc = -EBUSY;
- goto csi_irq_fail;
- }
- csiphybase = ioremap(csiphy_mem->start,
- resource_size(csiphy_mem));
- if (!csiphybase) {
- rc = -ENOMEM;
- goto csiphy_busy;
- }
-#if DBG_CSIPHY
- rc = request_irq(csiphy_irq->start, msm_io_csiphy_irq,
- IRQF_TRIGGER_RISING, "csiphy", 0);
- if (rc < 0)
- goto csiphy_irq_fail;
-#endif
msm_camio_enable_v2_clks();
CDBG("camio enable done\n");
return 0;
-#if DBG_CSIPHY
-csiphy_irq_fail:
- iounmap(csiphybase);
-#endif
-csiphy_busy:
- release_mem_region(csiphy_mem->start, resource_size(csiphy_mem));
+#if DBG_CSID
csi_irq_fail:
iounmap(csidbase);
+#endif
csi_busy:
release_mem_region(csid_mem->start, resource_size(csid_mem));
common_fail:
@@ -1144,12 +979,6 @@
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
uint8_t csid_core = camdev->csid_core;
-#if DBG_CSIPHY
- free_irq(csiphy_irq->start, 0);
-#endif
- iounmap(csiphybase);
- release_mem_region(csiphy_mem->start, resource_size(csiphy_mem));
-
#if DBG_CSID
free_irq(csid_irq->start, 0);
#endif
@@ -1355,54 +1184,6 @@
return rc;
}
-int msm_camio_csiphy_config(struct msm_camera_csiphy_params *csiphy_params)
-{
- int rc = 0;
- int i = 0;
- uint32_t val = 0;
- if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
- CDBG("%s: unsupported lane cnt %d\n",
- __func__, csiphy_params->lane_cnt);
- return rc;
- }
-
- val = 0x3;
- msm_io_w((((1 << csiphy_params->lane_cnt) - 1) << 2) | val,
- csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
- msm_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
- msm_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
-
- for (i = 0; i < csiphy_params->lane_cnt; i++) {
- msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
- msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
- msm_io_w(csiphy_params->settle_cnt,
- csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*i);
- msm_io_w(0x00000052,
- csiphybase + MIPI_CSIPHY_LNn_CFG5_ADDR + 0x40*i);
- }
-
- msm_io_w(0x00000000, csiphybase + MIPI_CSIPHY_LNCK_CFG1_ADDR);
- msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
- msm_io_w(csiphy_params->settle_cnt,
- csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
- msm_io_w(0x5, csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR);
- msm_io_w(0x2, csiphybase + MIPI_CSIPHY_LNCK_CFG5_ADDR);
- msm_io_w(0x0, csiphybase + 0x128);
-
- msm_io_w(0x24,
- csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
- msm_io_w(0x24,
- csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
-
- for (i = 1; i <= csiphy_params->lane_cnt; i++) {
- msm_io_w(0x6F,
- csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR + 0x4*i);
- msm_io_w(0x6F,
- csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR + 0x4*i);
- }
- return rc;
-}
-
void msm_camio_mode_config(enum msm_cam_mode mode)
{
uint32_t val;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index a7fe8a2..1a5b14c 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -28,6 +28,7 @@
#include <linux/android_pmem.h>
#include "msm.h"
+#include "msm_csiphy.h"
#include "msm_ispif.h"
#ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -219,6 +220,10 @@
case NOTIFY_PCLK_CHANGE:
rc = msm_camio_vfe_clk_rate_set(*(uint32_t *)arg);
break;
+ case NOTIFY_CSIPHY_CFG:
+ rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
+ core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
+ break;
default:
break;
}
@@ -313,11 +318,53 @@
return rc;
}
+static int msm_mctl_subdev_match_core(struct device *dev, void *data)
+{
+ int core_index = (int)data;
+ struct platform_device *pdev = to_platform_device(dev);
+
+ if (pdev->id == core_index)
+ return 1;
+ else
+ return 0;
+}
+
+static int msm_mctl_register_subdevs(struct msm_cam_media_controller *p_mctl,
+ int core_index)
+{
+ struct device_driver *driver;
+ struct device *dev;
+ int rc = -ENODEV;
+
+ /* register csiphy subdev */
+ driver = driver_find(MSM_CSIPHY_DRV_NAME, &platform_bus_type);
+ if (!driver)
+ goto out;
+
+ dev = driver_find_device(driver, NULL, (void *)core_index,
+ msm_mctl_subdev_match_core);
+ if (!dev)
+ goto out_put_driver;
+
+ p_mctl->csiphy_sdev = dev_get_drvdata(dev);
+ put_driver(driver);
+
+ rc = 0;
+ return rc;
+out_put_driver:
+ put_driver(driver);
+out:
+ return rc;
+}
+
static int msm_mctl_open(struct msm_cam_media_controller *p_mctl,
const char *const apps_id)
{
int rc = 0;
struct msm_sync *sync = NULL;
+ struct msm_camera_sensor_info *sinfo;
+ struct msm_camera_device_platform_data *camdev;
+ uint8_t csid_core;
D("%s\n", __func__);
if (!p_mctl) {
pr_err("%s: param is NULL", __func__);
@@ -332,6 +379,16 @@
if (!sync->opencnt) {
wake_lock(&sync->wake_lock);
+ sinfo = sync->pdev->dev.platform_data;
+ camdev = sinfo->pdata;
+ csid_core = camdev->csid_core;
+ rc = msm_mctl_register_subdevs(p_mctl, csid_core);
+ if (rc < 0) {
+ pr_err("%s: msm_mctl_register_subdevs failed:%d\n",
+ __func__, rc);
+ goto msm_open_done;
+ }
+
/* turn on clock */
rc = msm_camio_sensor_clk_on(sync->pdev);
if (rc < 0) {
@@ -350,6 +407,14 @@
goto msm_open_done;
}
+ rc = v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
+ VIDIOC_MSM_CSIPHY_INIT, NULL);
+ if (rc < 0) {
+ pr_err("%s: csiphy initialization failed %d\n",
+ __func__, rc);
+ goto msm_open_done;
+ }
+
/*This has to be after isp_open, because isp_open initialize
*platform resource. This dependency needs to be removed. */
rc = msm_ispif_init(&p_mctl->ispif_sdev, sync->pdev);
@@ -385,13 +450,13 @@
static int msm_mctl_release(struct msm_cam_media_controller *p_mctl)
{
- struct msm_sync *sync = NULL;
int rc = 0;
-
- sync = &(p_mctl->sync);
-
+ struct msm_sync *sync = &(p_mctl->sync);
msm_ispif_release(p_mctl->ispif_sdev);
+ v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
+ VIDIOC_MSM_CSIPHY_RELEASE, NULL);
+
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
p_mctl->isp_sdev->isp_release(&p_mctl->sync);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 19cf8c7..c31e750 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -243,7 +243,8 @@
v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
NOTIFY_CID_CHANGE, NULL);
mb();
- rc = msm_camio_csiphy_config(
+ v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSIPHY_CFG,
&s_ctrl->curr_csi_params->csiphy_params);
mb();
msleep(20);