]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/pxa_camera.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / video / pxa_camera.c
index aa7efc45d3644f355d30f042260881255be9fb92..07c334f25aae69bf257a2a0cff91465bd5e784b9 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/version.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <linux/mutex.h>
 #include <linux/clk.h>
 
 #include <media/v4l2-common.h>
@@ -35,7 +34,7 @@
 
 #include <linux/videodev2.h>
 
-#include <asm/dma.h>
+#include <mach/dma.h>
 #include <mach/pxa-regs.h>
 #include <mach/camera.h>
 
                        CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
                        CICR0_EOFM | CICR0_FOM)
 
-static DEFINE_MUTEX(camera_lock);
-
 /*
  * Structures
  */
@@ -813,16 +810,17 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-/* The following two functions absolutely depend on the fact, that
- * there can be only one camera on PXA quick capture interface */
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on PXA quick capture interface
+ * Called with .video_lock held
+ */
 static int pxa_camera_add_device(struct soc_camera_device *icd)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct pxa_camera_dev *pcdev = ici->priv;
        int ret;
 
-       mutex_lock(&camera_lock);
-
        if (pcdev->icd) {
                ret = -EBUSY;
                goto ebusy;
@@ -838,11 +836,10 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
                pcdev->icd = icd;
 
 ebusy:
-       mutex_unlock(&camera_lock);
-
        return ret;
 }
 
+/* Called with .video_lock held */
 static void pxa_camera_remove_device(struct soc_camera_device *icd)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -1158,23 +1155,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct pxa_camera_dev *pcdev = ici->priv;
-       const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL;
-       const struct soc_camera_format_xlate *xlate;
+       const struct soc_camera_data_format *cam_fmt = NULL;
+       const struct soc_camera_format_xlate *xlate = NULL;
        struct soc_camera_sense sense = {
                .master_clock = pcdev->mclk,
                .pixel_clock_max = pcdev->ciclk / 4,
        };
-       int ret, buswidth;
+       int ret;
 
-       xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
-       if (!xlate) {
-               dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
-               return -EINVAL;
-       }
+       if (pixfmt) {
+               xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+               if (!xlate) {
+                       dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+                       return -EINVAL;
+               }
 
-       buswidth = xlate->buswidth;
-       host_fmt = xlate->host_fmt;
-       cam_fmt = xlate->cam_fmt;
+               cam_fmt = xlate->cam_fmt;
+       }
 
        /* If PCLK is used to latch data from the sensor, check sense */
        if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
@@ -1204,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
        }
 
        if (pixfmt && !ret) {
-               icd->buswidth = buswidth;
-               icd->current_fmt = host_fmt;
+               icd->buswidth = xlate->buswidth;
+               icd->current_fmt = xlate->host_fmt;
        }
 
        return ret;
@@ -1218,6 +1215,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
        const struct soc_camera_format_xlate *xlate;
        struct v4l2_pix_format *pix = &f->fmt.pix;
        __u32 pixfmt = pix->pixelformat;
+       enum v4l2_field field;
        int ret;
 
        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
@@ -1247,6 +1245,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
        ret = icd->ops->try_fmt(icd, f);
        pix->pixelformat = xlate->host_fmt->fourcc;
 
+       field = pix->field;
+
+       if (field == V4L2_FIELD_ANY) {
+               pix->field = V4L2_FIELD_NONE;
+       } else if (field != V4L2_FIELD_NONE) {
+               dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+               return -EINVAL;
+       }
+
        return ret;
 }
 
@@ -1395,7 +1402,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
                goto exit;
        }
 
-       pcdev->clk = clk_get(&pdev->dev, "CAMCLK");
+       pcdev->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(pcdev->clk)) {
                err = PTR_ERR(pcdev->clk);
                goto exit_kfree;