media: tegra: Tegra V4L2 camera
[linux-2.6.git] / drivers / media / video / omap24xxcam.c
index 805faae..eb97bff 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/videodev2.h>
 #include <linux/pci.h>         /* needed for videobufs */
-#include <linux/version.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
 #include "omap24xxcam.h"
 
-#define OMAP24XXCAM_VERSION KERNEL_VERSION(0, 0, 0)
+#define OMAP24XXCAM_VERSION "0.0.1"
 
 #define RESET_TIMEOUT_NS 10000
 
@@ -307,11 +308,11 @@ static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb)
                        order--;
 
                /* try to allocate as many contiguous pages as possible */
-               page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
+               page = alloc_pages(GFP_KERNEL, order);
                /* if allocation fails, try to allocate smaller amount */
                while (page == NULL) {
                        order--;
-                       page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
+                       page = alloc_pages(GFP_KERNEL, order);
                        if (page == NULL && !order) {
                                err = -ENOMEM;
                                goto out;
@@ -419,13 +420,13 @@ static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
        struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
 
        /* wait for buffer, especially to get out of the sgdma queue */
-       videobuf_waiton(vb, 0, 0);
+       videobuf_waiton(vbq, vb, 0, 0);
        if (vb->memory == V4L2_MEMORY_MMAP) {
                dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
                             dma->direction);
                dma->direction = DMA_NONE;
        } else {
-               videobuf_dma_unmap(vbq, videobuf_to_dma(vb));
+               videobuf_dma_unmap(vbq->dev, videobuf_to_dma(vb));
                videobuf_dma_free(videobuf_to_dma(vb));
        }
 
@@ -451,8 +452,8 @@ static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
        *size = fh->pix.sizeimage;
 
        /* accessing fh->cam->capture_mem is ok, it's constant */
-       while (*size * *cnt > fh->cam->capture_mem)
-               (*cnt)--;
+       if (*size * *cnt > fh->cam->capture_mem)
+               *cnt = fh->cam->capture_mem / *size;
 
        return 0;
 }
@@ -991,7 +992,6 @@ static int vidioc_querycap(struct file *file, void *fh,
 
        strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));
        strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));
-       cap->version = OMAP24XXCAM_VERSION;
        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 
        return 0;
@@ -1197,7 +1197,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
        atomic_inc(&cam->reset_disable);
 
-       flush_scheduled_work();
+       flush_work_sync(&cam->sensor_reset_work);
 
        rval = videobuf_streamoff(q);
        if (!rval) {
@@ -1285,9 +1285,6 @@ static int vidioc_g_parm(struct file *file, void *fh,
        struct omap24xxcam_device *cam = ofh->cam;
        int rval;
 
-       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
        mutex_lock(&cam->mutex);
        rval = vidioc_int_g_parm(cam->sdev, a);
        mutex_unlock(&cam->mutex);
@@ -1303,9 +1300,6 @@ static int vidioc_s_parm(struct file *file, void *fh,
        struct v4l2_streamparm old_streamparm;
        int rval;
 
-       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
        mutex_lock(&cam->mutex);
        if (cam->streaming) {
                rval = -EBUSY;
@@ -1410,7 +1404,7 @@ static int omap24xxcam_mmap_buffers(struct file *file,
        }
 
        size = 0;
-       for (i = first; i <= last; i++) {
+       for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
                struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
 
                for (j = 0; j < dma->sglen; j++) {
@@ -1456,12 +1450,11 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
 
 static int omap24xxcam_open(struct file *file)
 {
-       int minor = video_devdata(file)->minor;
        struct omap24xxcam_device *cam = omap24xxcam.priv;
        struct omap24xxcam_fh *fh;
        struct v4l2_format format;
 
-       if (!cam || !cam->vfd || (cam->vfd->minor != minor))
+       if (!cam || !cam->vfd)
                return -ENODEV;
 
        fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -1497,7 +1490,7 @@ static int omap24xxcam_open(struct file *file)
        videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL,
                                &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
                                V4L2_FIELD_NONE,
-                               sizeof(struct videobuf_buffer), fh);
+                               sizeof(struct videobuf_buffer), fh, NULL);
 
        return 0;
 
@@ -1518,7 +1511,7 @@ static int omap24xxcam_release(struct file *file)
 
        atomic_inc(&cam->reset_disable);
 
-       flush_scheduled_work();
+       flush_work_sync(&cam->sensor_reset_work);
 
        /* stop streaming capture */
        videobuf_streamoff(&fh->vbq);
@@ -1542,7 +1535,7 @@ static int omap24xxcam_release(struct file *file)
         * not be scheduled anymore since streaming is already
         * disabled.)
         */
-       flush_scheduled_work();
+       flush_work_sync(&cam->sensor_reset_work);
 
        mutex_lock(&cam->mutex);
        if (atomic_dec_return(&cam->users) == 0) {
@@ -1665,9 +1658,7 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
        vfd->parent = cam->dev;
 
        strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
-       vfd->vfl_type            = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
        vfd->fops                = &omap24xxcam_fops;
-       vfd->minor               = -1;
        vfd->ioctl_ops           = &omap24xxcam_ioctl_fops;
 
        omap24xxcam_hwinit(cam);
@@ -1678,14 +1669,14 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
 
        if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
                dev_err(cam->dev, "could not register V4L device\n");
-               vfd->minor = -1;
                rval = -EBUSY;
                goto err;
        }
 
        omap24xxcam_poweron_reset(cam);
 
-       dev_info(cam->dev, "registered device video%d\n", vfd->minor);
+       dev_info(cam->dev, "registered device %s\n",
+                video_device_node_name(vfd));
 
        return 0;
 
@@ -1702,7 +1693,7 @@ static void omap24xxcam_device_unregister(struct v4l2_int_device *s)
        omap24xxcam_sensor_exit(cam);
 
        if (cam->vfd) {
-               if (cam->vfd->minor == -1) {
+               if (!video_is_registered(cam->vfd)) {
                        /*
                         * The device was never registered, so release the
                         * video_device struct directly.
@@ -1744,7 +1735,7 @@ static struct v4l2_int_device omap24xxcam = {
  *
  */
 
-static int __init omap24xxcam_probe(struct platform_device *pdev)
+static int __devinit omap24xxcam_probe(struct platform_device *pdev)
 {
        struct omap24xxcam_device *cam;
        struct resource *mem;
@@ -1775,14 +1766,13 @@ static int __init omap24xxcam_probe(struct platform_device *pdev)
                dev_err(cam->dev, "no mem resource?\n");
                goto err;
        }
-       if (!request_mem_region(mem->start, (mem->end - mem->start) + 1,
-                               pdev->name)) {
+       if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
                dev_err(cam->dev,
                        "cannot reserve camera register I/O region\n");
                goto err;
        }
        cam->mmio_base_phys = mem->start;
-       cam->mmio_size = (mem->end - mem->start) + 1;
+       cam->mmio_size = resource_size(mem);
 
        /* map the region */
        cam->mmio_base = (unsigned long)
@@ -1896,6 +1886,7 @@ static void __exit omap24xxcam_cleanup(void)
 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
 MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(OMAP24XXCAM_VERSION);
 module_param(video_nr, int, 0);
 MODULE_PARM_DESC(video_nr,
                 "Minor number for video device (-1 ==> auto assign)");