V4L/DVB (9787): soc-camera: let camera host drivers decide upon pixel format
[safe/jmp/linux-2.6] / drivers / media / video / pxa_camera.c
index cf96b2c..a375872 100644 (file)
@@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
                pdata->init(pcdev->dev);
        }
 
-       if (pdata && pdata->power) {
-               dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__);
-               pdata->power(pcdev->dev, 1);
-       }
-
-       if (pdata && pdata->reset) {
-               dev_dbg(pcdev->dev, "%s: Releasing camera reset\n",
-                       __func__);
-               pdata->reset(pcdev->dev, 1);
-       }
-
        CICR0 = 0x3FF;   /* disable all interrupts */
 
        if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
@@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
 
 static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
 {
-       struct pxacamera_platform_data *board = pcdev->pdata;
-
        clk_disable(pcdev->clk);
-
-       if (board && board->reset) {
-               dev_dbg(pcdev->dev, "%s: Asserting camera reset\n",
-                       __func__);
-               board->reset(pcdev->dev, 0);
-       }
-
-       if (board && board->power) {
-               dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__);
-               board->power(pcdev->dev, 0);
-       }
 }
 
 static irqreturn_t pxa_camera_irq(int irq, void *data)
@@ -931,12 +907,43 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 static int pxa_camera_set_fmt_cap(struct soc_camera_device *icd,
                                  __u32 pixfmt, struct v4l2_rect *rect)
 {
-       return icd->ops->set_fmt_cap(icd, pixfmt, rect);
+       const struct soc_camera_data_format *cam_fmt;
+       int ret;
+
+       /*
+        * TODO: find a suitable supported by the SoC output format, check
+        * whether the sensor supports one of acceptable input formats.
+        */
+       if (pixfmt) {
+               cam_fmt = soc_camera_format_by_fourcc(icd, pixfmt);
+               if (!cam_fmt)
+                       return -EINVAL;
+       }
+
+       ret = icd->ops->set_fmt_cap(icd, pixfmt, rect);
+       if (pixfmt && !ret)
+               icd->current_fmt = cam_fmt;
+
+       return ret;
 }
 
 static int pxa_camera_try_fmt_cap(struct soc_camera_device *icd,
                                  struct v4l2_format *f)
 {
+       const struct soc_camera_data_format *cam_fmt;
+       int ret = pxa_camera_try_bus_param(icd, f->fmt.pix.pixelformat);
+
+       if (ret < 0)
+               return ret;
+
+       /*
+        * TODO: find a suitable supported by the SoC output format, check
+        * whether the sensor supports one of acceptable input formats.
+        */
+       cam_fmt = soc_camera_format_by_fourcc(icd, f->fmt.pix.pixelformat);
+       if (!cam_fmt)
+               return -EINVAL;
+
        /* limit to pxa hardware capabilities */
        if (f->fmt.pix.height < 32)
                f->fmt.pix.height = 32;
@@ -948,6 +955,10 @@ static int pxa_camera_try_fmt_cap(struct soc_camera_device *icd,
                f->fmt.pix.width = 2048;
        f->fmt.pix.width &= ~0x01;
 
+       f->fmt.pix.bytesperline = f->fmt.pix.width *
+               DIV_ROUND_UP(cam_fmt->depth, 8);
+       f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
        /* limit to sensor capabilities */
        return icd->ops->try_fmt_cap(icd, f);
 }
@@ -1063,7 +1074,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
        .reqbufs        = pxa_camera_reqbufs,
        .poll           = pxa_camera_poll,
        .querycap       = pxa_camera_querycap,
-       .try_bus_param  = pxa_camera_try_bus_param,
        .set_bus_param  = pxa_camera_set_bus_param,
 };
 
@@ -1144,31 +1154,31 @@ static int pxa_camera_probe(struct platform_device *pdev)
        pcdev->dev = &pdev->dev;
 
        /* request dma */
-       pcdev->dma_chans[0] = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
-                                             pxa_camera_dma_irq_y, pcdev);
-       if (pcdev->dma_chans[0] < 0) {
+       err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
+                             pxa_camera_dma_irq_y, pcdev);
+       if (err < 0) {
                dev_err(pcdev->dev, "Can't request DMA for Y\n");
-               err = -ENOMEM;
                goto exit_iounmap;
        }
+       pcdev->dma_chans[0] = err;
        dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
 
-       pcdev->dma_chans[1] = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
-                                             pxa_camera_dma_irq_u, pcdev);
-       if (pcdev->dma_chans[1] < 0) {
+       err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
+                             pxa_camera_dma_irq_u, pcdev);
+       if (err < 0) {
                dev_err(pcdev->dev, "Can't request DMA for U\n");
-               err = -ENOMEM;
                goto exit_free_dma_y;
        }
+       pcdev->dma_chans[1] = err;
        dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
 
-       pcdev->dma_chans[2] = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
-                                             pxa_camera_dma_irq_v, pcdev);
-       if (pcdev->dma_chans[0] < 0) {
+       err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
+                             pxa_camera_dma_irq_v, pcdev);
+       if (err < 0) {
                dev_err(pcdev->dev, "Can't request DMA for V\n");
-               err = -ENOMEM;
                goto exit_free_dma_u;
        }
+       pcdev->dma_chans[2] = err;
        dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
 
        DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;