V4L/DVB: saa7134: add RM-K6 remote control support for Avermedia M135A
[safe/jmp/linux-2.6] / drivers / media / video / mx1_camera.c
index ed7856b..5c17f9e 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
@@ -36,6 +38,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-contig.h>
+#include <media/soc_mediabus.h>
 
 #include <asm/dma.h>
 #include <asm/fiq.h>
@@ -46,8 +49,6 @@
 /*
  * CSI registers
  */
-#define DMA_CCR(x)     (0x8c + ((x) << 6))     /* Control Registers */
-#define DMA_DIMR       0x08                    /* Interrupt mask Register */
 #define CSICR1         0x00                    /* CSI Control Register 1 */
 #define CSISR          0x08                    /* CSI Status Register */
 #define CSIRXR         0x10                    /* CSI RxFIFO Register */
 /* buffer for one video frame */
 struct mx1_buffer {
        /* common v4l buffer stuff -- must be first */
-       struct videobuf_buffer vb;
-       const struct soc_camera_data_format *fmt;
-       int inwork;
+       struct videobuf_buffer          vb;
+       enum v4l2_mbus_pixelcode        code;
+       int                             inwork;
 };
 
-/* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
+/*
+ * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
  * Interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too */
+ * one camera, they will have to modify this driver too
+ */
 struct mx1_camera_dev {
        struct soc_camera_host          soc_host;
        struct soc_camera_device        *icd;
@@ -125,17 +128,21 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
                              unsigned int *size)
 {
        struct soc_camera_device *icd = vq->priv_data;
+       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+                                               icd->current_fmt->host_fmt);
+
+       if (bytes_per_line < 0)
+               return bytes_per_line;
 
-       *size = icd->rect_current.width * icd->rect_current.height *
-               ((icd->current_fmt->depth + 7) >> 3);
+       *size = bytes_per_line * icd->user_height;
 
        if (!*count)
                *count = 32;
 
-       while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
-               (*count)--;
+       if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+               *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
 
-       dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+       dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
 
        return 0;
 }
@@ -147,11 +154,13 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
 
        BUG_ON(in_interrupt());
 
-       dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+       dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
-       /* This waits until this buffer is out of danger, i.e., until it is no
-        * longer in STATE_QUEUED or STATE_ACTIVE */
+       /*
+        * This waits until this buffer is out of danger, i.e., until it is no
+        * longer in STATE_QUEUED or STATE_ACTIVE
+        */
        videobuf_waiton(vb, 0, 0);
        videobuf_dma_contig_free(vq, vb);
 
@@ -164,8 +173,13 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
        struct soc_camera_device *icd = vq->priv_data;
        struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
        int ret;
+       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+                                               icd->current_fmt->host_fmt);
 
-       dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+       if (bytes_per_line < 0)
+               return bytes_per_line;
+
+       dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        /* Added list head initialization on alloc */
@@ -173,22 +187,24 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
 
        BUG_ON(NULL == icd->current_fmt);
 
-       /* I think, in buf_prepare you only have to protect global data,
-        * the actual buffer is yours */
+       /*
+        * I think, in buf_prepare you only have to protect global data,
+        * the actual buffer is yours
+        */
        buf->inwork = 1;
 
-       if (buf->fmt    != icd->current_fmt ||
-           vb->width   != icd->rect_current.width ||
-           vb->height  != icd->rect_current.height ||
+       if (buf->code   != icd->current_fmt->code ||
+           vb->width   != icd->user_width ||
+           vb->height  != icd->user_height ||
            vb->field   != field) {
-               buf->fmt        = icd->current_fmt;
-               vb->width       = icd->rect_current.width;
-               vb->height      = icd->rect_current.height;
+               buf->code       = icd->current_fmt->code;
+               vb->width       = icd->user_width;
+               vb->height      = icd->user_height;
                vb->field       = field;
                vb->state       = VIDEOBUF_NEEDS_INIT;
        }
 
-       vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+       vb->size = bytes_per_line * vb->height;
        if (0 != vb->baddr && vb->bsize < vb->size) {
                ret = -EINVAL;
                goto out;
@@ -216,10 +232,11 @@ out:
 static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 {
        struct videobuf_buffer *vbuf = &pcdev->active->vb;
+       struct device *dev = pcdev->icd->dev.parent;
        int ret;
 
        if (unlikely(!pcdev->active)) {
-               dev_err(pcdev->icd->dev.parent, "DMA End IRQ with no active buffer\n");
+               dev_err(dev, "DMA End IRQ with no active buffer\n");
                return -EFAULT;
        }
 
@@ -229,7 +246,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
                vbuf->size, pcdev->res->start +
                CSIRXR, DMA_MODE_READ);
        if (unlikely(ret))
-               dev_err(pcdev->icd->dev.parent, "Failed to setup DMA sg list\n");
+               dev_err(dev, "Failed to setup DMA sg list\n");
 
        return ret;
 }
@@ -243,7 +260,7 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
        struct mx1_camera_dev *pcdev = ici->priv;
        struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 
-       dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+       dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        list_add_tail(&vb->queue, &pcdev->capture);
@@ -270,22 +287,23 @@ static void mx1_videobuf_release(struct videobuf_queue *vq,
        struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 #ifdef DEBUG
        struct soc_camera_device *icd = vq->priv_data;
+       struct device *dev = icd->dev.parent;
 
-       dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+       dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        switch (vb->state) {
        case VIDEOBUF_ACTIVE:
-               dev_dbg(&icd->dev, "%s (active)\n", __func__);
+               dev_dbg(dev, "%s (active)\n", __func__);
                break;
        case VIDEOBUF_QUEUED:
-               dev_dbg(&icd->dev, "%s (queued)\n", __func__);
+               dev_dbg(dev, "%s (queued)\n", __func__);
                break;
        case VIDEOBUF_PREPARED:
-               dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
+               dev_dbg(dev, "%s (prepared)\n", __func__);
                break;
        default:
-               dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
+               dev_dbg(dev, "%s (unknown)\n", __func__);
                break;
        }
 #endif
@@ -325,6 +343,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
 static void mx1_camera_dma_irq(int channel, void *data)
 {
        struct mx1_camera_dev *pcdev = data;
+       struct device *dev = pcdev->icd->dev.parent;
        struct mx1_buffer *buf;
        struct videobuf_buffer *vb;
        unsigned long flags;
@@ -334,14 +353,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
        imx_dma_disable(channel);
 
        if (unlikely(!pcdev->active)) {
-               dev_err(pcdev->icd->dev.parent, "DMA End IRQ with no active buffer\n");
+               dev_err(dev, "DMA End IRQ with no active buffer\n");
                goto out;
        }
 
        vb = &pcdev->active->vb;
        buf = container_of(vb, struct mx1_buffer, vb);
        WARN_ON(buf->inwork || list_empty(&vb->queue));
-       dev_dbg(pcdev->icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+       dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        mx1_camera_wakeup(pcdev, vb, buf);
@@ -377,12 +396,15 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
 
        lcdclk = clk_get_rate(pcdev->clk);
 
-       /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here
-        * they get a nice Oops */
+       /*
+        * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
+        * they get a nice Oops
+        */
        div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
-       dev_dbg(pcdev->icd->dev.parent, "System clock %lukHz, target freq %dkHz, "
-               "divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
+       dev_dbg(pcdev->icd->dev.parent,
+               "System clock %lukHz, target freq %dkHz, divisor %lu\n",
+               lcdclk / 1000, mclk / 1000, div);
 
        return div;
 }
@@ -415,8 +437,10 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
        clk_disable(pcdev->clk);
 }
 
-/* The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface */
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on i.MX1/i.MXL camera sensor interface
+ */
 static int mx1_camera_add_device(struct soc_camera_device *icd)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -428,7 +452,7 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
                goto ebusy;
        }
 
-       dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n",
+       dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
                 icd->devnum);
 
        mx1_camera_activate(pcdev);
@@ -454,7 +478,7 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
        /* Stop DMA engine */
        imx_dma_disable(pcdev->dma_chan);
 
-       dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n",
+       dev_info(icd->dev.parent, "MX1 Camera driver detached from camera %d\n",
                 icd->devnum);
 
        mx1_camera_deactivate(pcdev);
@@ -482,12 +506,10 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 
        /* MX1 supports only 8bit buswidth */
        common_flags = soc_camera_bus_param_compatible(camera_flags,
-                                                              CSI_BUS_FLAGS);
+                                                      CSI_BUS_FLAGS);
        if (!common_flags)
                return -EINVAL;
 
-       icd->buswidth = 8;
-
        /* Make choises, based on platform choice */
        if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
                (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
@@ -540,20 +562,43 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        const struct soc_camera_format_xlate *xlate;
        struct v4l2_pix_format *pix = &f->fmt.pix;
-       int ret;
+       struct v4l2_mbus_framefmt mf;
+       int ret, buswidth;
 
        xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
        if (!xlate) {
-               dev_warn(icd->dev.parent, "Format %x not found\n", pix->pixelformat);
+               dev_warn(icd->dev.parent, "Format %x not found\n",
+                        pix->pixelformat);
                return -EINVAL;
        }
 
-       ret = v4l2_subdev_call(sd, video, s_fmt, f);
-       if (!ret) {
-               icd->buswidth = xlate->buswidth;
-               icd->current_fmt = xlate->host_fmt;
+       buswidth = xlate->host_fmt->bits_per_sample;
+       if (buswidth > 8) {
+               dev_warn(icd->dev.parent,
+                        "bits-per-sample %d for format %x unsupported\n",
+                        buswidth, pix->pixelformat);
+               return -EINVAL;
        }
 
+       mf.width        = pix->width;
+       mf.height       = pix->height;
+       mf.field        = pix->field;
+       mf.colorspace   = pix->colorspace;
+       mf.code         = xlate->code;
+
+       ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+       if (ret < 0)
+               return ret;
+
+       if (mf.code != xlate->code)
+               return -EINVAL;
+
+       pix->width              = mf.width;
+       pix->height             = mf.height;
+       pix->field              = mf.field;
+       pix->colorspace         = mf.colorspace;
+       icd->current_fmt        = xlate;
+
        return ret;
 }
 
@@ -561,10 +606,36 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd,
                              struct v4l2_format *f)
 {
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       const struct soc_camera_format_xlate *xlate;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct v4l2_mbus_framefmt mf;
+       int ret;
        /* TODO: limit to mx1 hardware capabilities */
 
+       xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+       if (!xlate) {
+               dev_warn(icd->dev.parent, "Format %x not found\n",
+                        pix->pixelformat);
+               return -EINVAL;
+       }
+
+       mf.width        = pix->width;
+       mf.height       = pix->height;
+       mf.field        = pix->field;
+       mf.colorspace   = pix->colorspace;
+       mf.code         = xlate->code;
+
        /* limit to sensor capabilities */
-       return v4l2_subdev_call(sd, video, try_fmt, f);
+       ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+       if (ret < 0)
+               return ret;
+
+       pix->width      = mf.width;
+       pix->height     = mf.height;
+       pix->field      = mf.field;
+       pix->colorspace = mf.colorspace;
+
+       return 0;
 }
 
 static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -572,10 +643,12 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf,
 {
        int i;
 
-       /* This is for locking debugging only. I removed spinlocks and now I
+       /*
+        * This is for locking debugging only. I removed spinlocks and now I
         * check whether .prepare is ever called on a linked buffer, or whether
         * a dma IRQ can occur for an in-work or unlinked buffer. Until now
-        * it hadn't triggered */
+        * it hadn't triggered
+        */
        for (i = 0; i < p->count; i++) {
                struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i],
                                                      struct mx1_buffer, vb);
@@ -644,7 +717,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!res || !irq) {
+       if (!res || (int)irq <= 0) {
                err = -ENODEV;
                goto exit;
        }
@@ -709,7 +782,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
                               pcdev);
 
        imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
-                              IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+                              IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
        /* burst length : 16 words = 64 bytes */
        imx_dma_config_burstlen(pcdev->dma_chan, 0);
 
@@ -723,8 +796,8 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
        set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
                                                   &mx1_camera_sof_fiq_start);
 
-       regs.ARM_r8 = DMA_BASE + DMA_DIMR;
-       regs.ARM_r9 = DMA_BASE + DMA_CCR(pcdev->dma_chan);
+       regs.ARM_r8 = (long)MX1_DMA_DIMR;
+       regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
        regs.ARM_r10 = (long)pcdev->base + CSICR1;
        regs.ARM_fp = (long)pcdev->base + CSISR;
        regs.ARM_sp = 1 << pcdev->dma_chan;