This patch adds the soc_camera support in the platform driver: mmp-driver.c.
Specified board driver also should be modified to support soc_camera by passing
some platform datas to platform driver.

Currently the soc_camera mode in mmp driver only supports B_DMA_contig mode.

Signed-off-by: Libin Yang <lby...@marvell.com>
Signed-off-by: Albert Wang <twan...@marvell.com>
---
 drivers/media/platform/Makefile                  |    4 +-
 drivers/media/platform/marvell-ccic/Kconfig      |   22 ++++
 drivers/media/platform/marvell-ccic/mmp-driver.c |  147 ++++++++++++++--------
 include/media/mmp-camera.h                       |    2 +
 4 files changed, 120 insertions(+), 55 deletions(-)

diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index baaa550..95c1ce5 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -11,8 +11,6 @@ obj-$(CONFIG_VIDEO_TIMBERDALE)        += timblogiw.o
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
 obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
-obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
-obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
 
 obj-$(CONFIG_VIDEO_OMAP2)              += omap2cam.o
 obj-$(CONFIG_VIDEO_OMAP3)      += omap3isp/
@@ -43,6 +41,8 @@ obj-$(CONFIG_VIDEO_SH_VOU)            += sh_vou.o
 
 obj-$(CONFIG_SOC_CAMERA)               += soc_camera/
 
+obj-$(CONFIG_VIDEO_MARVELL_CCIC)       += marvell-ccic/
+
 obj-y  += davinci/
 
 obj-$(CONFIG_ARCH_OMAP)        += omap/
diff --git a/drivers/media/platform/marvell-ccic/Kconfig 
b/drivers/media/platform/marvell-ccic/Kconfig
index bf739e3..910c068 100755
--- a/drivers/media/platform/marvell-ccic/Kconfig
+++ b/drivers/media/platform/marvell-ccic/Kconfig
@@ -1,23 +1,45 @@
+config VIDEO_MARVELL_CCIC
+       tristate
+config VIDEO_MRVL_SOC_CAMERA
+       bool
+
 config VIDEO_CAFE_CCIC
        tristate "Marvell 88ALP01 (Cafe) CMOS Camera Controller support"
        depends on PCI && I2C && VIDEO_V4L2
        select VIDEO_OV7670
        select VIDEOBUF2_VMALLOC
        select VIDEOBUF2_DMA_CONTIG
+       select VIDEO_MARVELL_CCIC
        ---help---
          This is a video4linux2 driver for the Marvell 88ALP01 integrated
          CMOS camera controller.  This is the controller found on first-
          generation OLPC systems.
 
+choice
+       prompt "Camera support on Marvell MMP"
+       depends on ARCH_MMP && VIDEO_V4L2
+       optional
 config VIDEO_MMP_CAMERA
        tristate "Marvell Armada 610 integrated camera controller support"
        depends on ARCH_MMP && I2C && VIDEO_V4L2
        select VIDEO_OV7670
        select I2C_GPIO
        select VIDEOBUF2_DMA_SG
+       select VIDEO_MARVELL_CCIC
        ---help---
          This is a Video4Linux2 driver for the integrated camera
          controller found on Marvell Armada 610 application
          processors (and likely beyond).  This is the controller found
          in OLPC XO 1.75 systems.
 
+config VIDEO_MMP_SOC_CAMERA
+       bool "Marvell MMP camera driver based on SOC_CAMERA"
+       depends on VIDEO_DEV && SOC_CAMERA && ARCH_MMP && VIDEO_V4L2
+       select VIDEOBUF2_DMA_CONTIG
+       select VIDEO_MARVELL_CCIC
+       select VIDEO_MRVL_SOC_CAMERA
+       ---help---
+         This is a Video4Linux2 driver for the Marvell Mobile Soc
+         PXA910/PXA688/PXA2128/PXA988 CCIC
+         (CMOS Camera Interface Controller)
+endchoice
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c 
b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 40c243e..cd850f4 100755
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -28,6 +28,10 @@
 #include <linux/list.h>
 #include <linux/pm.h>
 #include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 
 #include "mcam-core.h"
 
@@ -40,6 +44,8 @@ struct mmp_camera {
        struct platform_device *pdev;
        struct mcam_camera mcam;
        struct list_head devlist;
+       /* will change here */
+       struct clk *clk[3];     /* CCIC_GATE, CCIC_RST, CCIC_DBG clocks */
        int irq;
 };
 
@@ -144,15 +150,17 @@ static void mmpcam_power_up(struct mcam_camera *mcam)
  * Provide power to the sensor.
  */
        mcam_reg_write(mcam, REG_CLKCTRL, 0x60000002);
-       pdata = cam->pdev->dev.platform_data;
-       gpio_set_value(pdata->sensor_power_gpio, 1);
-       mdelay(5);
+       if (mcam->chip_id == V4L2_IDENT_ARMADA610) {
+               pdata = cam->pdev->dev.platform_data;
+               gpio_set_value(pdata->sensor_power_gpio, 1);
+               mdelay(5);
+               /* reset is active low */
+               gpio_set_value(pdata->sensor_reset_gpio, 0);
+               mdelay(5);
+               gpio_set_value(pdata->sensor_reset_gpio, 1);
+               mdelay(5);
+       }
        mcam_reg_clear_bit(mcam, REG_CTRL1, 0x10000000);
-       gpio_set_value(pdata->sensor_reset_gpio, 0); /* reset is active low */
-       mdelay(5);
-       gpio_set_value(pdata->sensor_reset_gpio, 1); /* reset is active low */
-       mdelay(5);
-
        mcam_clk_set(mcam, 1);
 }
 
@@ -165,13 +173,14 @@ static void mmpcam_power_down(struct mcam_camera *mcam)
  */
        iowrite32(0, cam->power_regs + REG_CCIC_DCGCR);
        iowrite32(0, cam->power_regs + REG_CCIC_CRCR);
-/*
- * Shut down the sensor.
- */
-       pdata = cam->pdev->dev.platform_data;
-       gpio_set_value(pdata->sensor_power_gpio, 0);
-       gpio_set_value(pdata->sensor_reset_gpio, 0);
-
+       if (mcam->chip_id == V4L2_IDENT_ARMADA610) {
+               /*
+                * Shut down the sensor.
+                */
+               pdata = cam->pdev->dev.platform_data;
+               gpio_set_value(pdata->sensor_power_gpio, 0);
+               gpio_set_value(pdata->sensor_reset_gpio, 0);
+       }
        mcam_clk_set(mcam, 0);
 }
 
@@ -303,6 +312,52 @@ static void mcam_init_clk(struct mcam_camera *mcam,
                mcam->clk_num = 0;
 }
 
+static int mmp_probe(struct mcam_camera *mcam, struct platform_device *pdev)
+{
+       struct mmp_camera_platform_data *pdata;
+       int ret;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -ENODEV;
+
+       /*
+        * Find the i2c adapter.  This assumes, of course, that the
+        * i2c bus is already up and functioning.
+        * soc-camera manages i2c interface in sensor side
+        */
+       mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
+       if (mcam->i2c_adapter == NULL) {
+               dev_err(&pdev->dev, "No i2c adapter\n");
+               return -ENODEV;
+       }
+       /*
+        * Sensor GPIO pins.
+        */
+       ret = devm_gpio_request(&pdev->dev, pdata->sensor_power_gpio,
+                               "cam-power");
+       if (ret) {
+               dev_err(&pdev->dev, "Can't get sensor power gpio %d",
+                               pdata->sensor_power_gpio);
+               return ret;
+       }
+       gpio_direction_output(pdata->sensor_power_gpio, 0);
+       ret = devm_gpio_request(&pdev->dev, pdata->sensor_reset_gpio,
+                               "cam-reset");
+       if (ret) {
+               dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
+                               pdata->sensor_reset_gpio);
+               return ret;
+       }
+       gpio_direction_output(pdata->sensor_reset_gpio, 0);
+
+       /*
+        * Power the device up and hand it off to the core.
+        */
+       mmpcam_power_up(mcam);
+       return ret;
+}
+
 static int mmpcam_probe(struct platform_device *pdev)
 {
        struct mmp_camera *cam;
@@ -322,6 +377,7 @@ static int mmpcam_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&cam->devlist);
 
        mcam = &cam->mcam;
+       spin_lock_init(&mcam->dev_lock);
        mcam->plat_power_up = mmpcam_power_up;
        mcam->plat_power_down = mmpcam_power_down;
        mcam->ctlr_reset = mcam_ctlr_reset;
@@ -329,14 +385,23 @@ static int mmpcam_probe(struct platform_device *pdev)
        mcam->pll1 = NULL;
        mcam->dev = &pdev->dev;
        mcam->use_smbus = 0;
+       mcam->card_name = pdata->name;
+       mcam->mclk_min = pdata->mclk_min;
+       mcam->mclk_src = pdata->mclk_src;
+       mcam->mclk_div = pdata->mclk_div;
+       if (pdata->chip_id != V4L2_IDENT_NONE)
+               mcam->chip_id = pdata->chip_id;
+       else
+               mcam->chip_id = V4L2_IDENT_ARMADA610;
+       /* set B_DMA_sg as default */
+       mcam->buffer_mode = B_DMA_sg;
        mcam->ccic_id = pdev->id;
        mcam->bus_type = pdata->bus_type;
        mcam->dphy = pdata->dphy;
        mcam->mipi_enabled = 0;
        mcam->lane = pdata->lane;
-       mcam->chip_id = V4L2_IDENT_ARMADA610;
-       mcam->buffer_mode = B_DMA_sg;
-       spin_lock_init(&mcam->dev_lock);
+       INIT_LIST_HEAD(&mcam->buffers);
+
        /*
         * Get our I/O memory.
         */
@@ -366,40 +431,13 @@ static int mmpcam_probe(struct platform_device *pdev)
        }
 
        mcam_init_clk(mcam, pdata, 1);
-       /*
-        * Find the i2c adapter.  This assumes, of course, that the
-        * i2c bus is already up and functioning.
-        */
-       mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
-       if (mcam->i2c_adapter == NULL) {
-               dev_err(&pdev->dev, "No i2c adapter\n");
-               ret = -ENODEV;
-               goto out_uninit_clk;
-       }
-       /*
-        * Sensor GPIO pins.
-        */
-       ret = devm_gpio_request(&pdev->dev, pdata->sensor_power_gpio,
-                                       "cam-power");
-       if (ret) {
-               dev_err(&pdev->dev, "Can't get sensor power gpio %d",
-                               pdata->sensor_power_gpio);
-               goto out_uninit_clk;
-       }
-       gpio_direction_output(pdata->sensor_power_gpio, 0);
-       ret = devm_gpio_request(&pdev->dev, pdata->sensor_reset_gpio,
-                                       "cam-reset");
-       if (ret) {
-               dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
-                               pdata->sensor_reset_gpio);
-               goto out_uninit_clk;
+
+       if (mcam->chip_id == V4L2_IDENT_ARMADA610) {
+               ret = mmp_probe(mcam, pdev);
+               if (ret)
+                       goto out_uninit_clk;
        }
-       gpio_direction_output(pdata->sensor_reset_gpio, 0);
 
-       /*
-        * Power the device up and hand it off to the core.
-        */
-       mmpcam_power_up(mcam);
        ret = mccic_register(mcam);
        if (ret)
                goto out_power_down;
@@ -415,6 +453,9 @@ static int mmpcam_probe(struct platform_device *pdev)
        cam->irq = res->start;
        ret = devm_request_irq(&pdev->dev, cam->irq, mmpcam_irq, IRQF_SHARED,
                                        "mmp-camera", mcam);
+       if (ret)
+               goto out_unregister;
+
        if (ret == 0) {
                mmpcam_add_device(cam);
                return 0;
@@ -423,7 +464,8 @@ static int mmpcam_probe(struct platform_device *pdev)
 out_unregister:
        mccic_shutdown(mcam);
 out_power_down:
-       mmpcam_power_down(mcam);
+       if (mcam->chip_id == V4L2_IDENT_ARMADA610)
+               mmpcam_power_down(mcam);
 out_uninit_clk:
        mcam_init_clk(mcam, pdata, 0);
        return ret;
@@ -433,12 +475,11 @@ out_uninit_clk:
 static int mmpcam_remove(struct mmp_camera *cam)
 {
        struct mcam_camera *mcam = &cam->mcam;
-       struct mmp_camera_platform_data *pdata;
+       struct mmp_camera_platform_data *pdata = cam->pdev->dev.platform_data;
 
        mmpcam_remove_device(cam);
        mccic_shutdown(mcam);
        mmpcam_power_down(mcam);
-       pdata = cam->pdev->dev.platform_data;
        mcam_init_clk(mcam, pdata, 0);
        return 0;
 }
diff --git a/include/media/mmp-camera.h b/include/media/mmp-camera.h
index 9968031..ec4f21f 100755
--- a/include/media/mmp-camera.h
+++ b/include/media/mmp-camera.h
@@ -7,10 +7,12 @@ struct mmp_camera_platform_data {
        struct platform_device *i2c_device;
        int sensor_power_gpio;
        int sensor_reset_gpio;
+       char name[16];
        enum v4l2_mbus_type bus_type;
        int mclk_min;
        int mclk_src;
        int mclk_div;
+       int chip_id;
        /*
         * MIPI support
         */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to