fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / media / video / v4l1-compat.c
index c75ca87..8a13e59 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ *
  *     Video for Linux Two
  *     Backward Compatibility Layer
  *
  *
  */
 
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
-#include <linux/config.h>
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -34,6 +31,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/videodev.h>
+#include <media/v4l2-common.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -44,7 +42,7 @@
 #endif
 
 static unsigned int debug  = 0;
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug,"enable debug messages");
 MODULE_AUTHOR("Bill Dirks");
 MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
@@ -116,7 +114,7 @@ set_v4l_control(struct inode            *inode,
                if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
                        value = 65535;
                ctrl2.id = qctrl2.id;
-               ctrl2.value = 
+               ctrl2.value =
                        (value * (qctrl2.maximum - qctrl2.minimum)
                         + 32767)
                        / 65535;
@@ -256,7 +254,7 @@ static int check_size(struct inode         *inode,
 
        memset(&desc2,0,sizeof(desc2));
        memset(&fmt2,0,sizeof(fmt2));
-       
+
        desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2))
                goto done;
@@ -307,9 +305,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        {
                struct video_capability *cap = arg;
 
-               cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL);
+               cap2 = kzalloc(sizeof(*cap2),GFP_KERNEL);
                memset(cap, 0, sizeof(*cap));
-               memset(cap2, 0, sizeof(*cap2));
                memset(&fbuf2, 0, sizeof(fbuf2));
 
                err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
@@ -326,7 +323,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        err = 0;
                }
 
-               memcpy(cap->name, cap2->card, 
+               memcpy(cap->name, cap2->card,
                       min(sizeof(cap->name), sizeof(cap2->card)));
                cap->name[sizeof(cap->name) - 1] = 0;
                if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
@@ -352,6 +349,9 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        {
                struct video_buffer     *buffer = arg;
 
+               memset(buffer, 0, sizeof(*buffer));
+               memset(&fbuf2, 0, sizeof(fbuf2));
+
                err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
                if (err < 0) {
                        dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
@@ -364,7 +364,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                switch (fbuf2.fmt.pixelformat) {
                case V4L2_PIX_FMT_RGB332:
                        buffer->depth = 8;
-                               break;
+                       break;
                case V4L2_PIX_FMT_RGB555:
                        buffer->depth = 15;
                        break;
@@ -380,10 +380,14 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                default:
                        buffer->depth = 0;
                }
-               if (0 != fbuf2.fmt.bytesperline)
+               if (fbuf2.fmt.bytesperline) {
                        buffer->bytesperline = fbuf2.fmt.bytesperline;
-               else {
-                       buffer->bytesperline = 
+                       if (!buffer->depth && buffer->width)
+                               buffer->depth   = ((fbuf2.fmt.bytesperline<<3)
+                                                 + (buffer->width-1) )
+                                                 /buffer->width;
+               } else {
+                       buffer->bytesperline =
                                (buffer->width * buffer->depth + 7) & 7;
                        buffer->bytesperline >>= 3;
                }
@@ -424,9 +428,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        {
                struct video_window     *win = arg;
 
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                memset(win,0,sizeof(*win));
-               memset(fmt2,0,sizeof(*fmt2));
 
                fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
@@ -463,8 +466,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                struct video_window     *win = arg;
                int err1,err2;
 
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
-               memset(fmt2,0,sizeof(*fmt2));
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
                err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
@@ -597,17 +599,17 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                pict->whiteness = get_v4l_control(inode, file,
                                                  V4L2_CID_WHITENESS, drv);
 
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
-               memset(fmt2,0,sizeof(*fmt2));
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
                if (err < 0) {
                        dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
                        break;
                }
-#if 0 /* FIXME */
-               pict->depth   = fmt2->fmt.pix.depth;
-#endif
+
+               pict->depth   = ((fmt2->fmt.pix.bytesperline<<3)
+                                + (fmt2->fmt.pix.width-1) )
+                                /fmt2->fmt.pix.width;
                pict->palette = pixelformat_to_palette(
                        fmt2->fmt.pix.pixelformat);
                break;
@@ -615,6 +617,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
        {
                struct video_picture    *pict = arg;
+               memset(&fbuf2, 0, sizeof(fbuf2));
 
                set_v4l_control(inode, file,
                                V4L2_CID_BRIGHTNESS, pict->brightness, drv);
@@ -627,13 +630,12 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                set_v4l_control(inode, file,
                                V4L2_CID_WHITENESS, pict->whiteness, drv);
 
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
-               memset(fmt2,0,sizeof(*fmt2));
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
                if (err < 0)
                        dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
-               if (fmt2->fmt.pix.pixelformat != 
+               if (fmt2->fmt.pix.pixelformat !=
                    palette_to_pixelformat(pict->palette)) {
                        fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
                                pict->palette);
@@ -708,18 +710,22 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        }
        case VIDIOCSTUNER: /*  select a tuner input  */
        {
-#if 0 /* FIXME */
-               err = drv(inode, file, VIDIOC_S_INPUT, &i);
+               struct video_tuner      *tun = arg;
+               struct v4l2_tuner       t;
+               memset(&t,0,sizeof(t));
+
+               t.index=tun->tuner;
+
+               err = drv(inode, file, VIDIOC_S_INPUT, &t);
                if (err < 0)
                        dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
-#else
-               err = 0;
-#endif
+
                break;
        }
        case VIDIOCGFREQ: /*  get frequency  */
        {
-               int *freq = arg;
+               unsigned long *freq = arg;
+               memset(&freq2,0,sizeof(freq2));
 
                freq2.tuner = 0;
                err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -731,9 +737,9 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        }
        case VIDIOCSFREQ: /*  set frequency  */
        {
-               int *freq = arg;
+               unsigned long *freq = arg;
+               memset(&freq2,0,sizeof(freq2));
 
-               freq2.tuner = 0;
                drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
                freq2.frequency = *freq;
                err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
@@ -744,6 +750,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCGAUDIO: /*  get audio properties/controls  */
        {
                struct video_audio      *aud = arg;
+               memset(&aud2,0,sizeof(aud2));
 
                err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
                if (err < 0) {
@@ -787,12 +794,15 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
                        aud->step = qctrl2.step;
                aud->mode = 0;
+
+               memset(&tun2,0,sizeof(tun2));
                err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
                if (err < 0) {
                        dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
                        err = 0;
                        break;
                }
+
                if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
                        aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
                else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
@@ -807,7 +817,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
 
                memset(&aud2,0,sizeof(aud2));
                memset(&tun2,0,sizeof(tun2));
-               
+
                aud2.index = aud->audio;
                err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
                if (err < 0) {
@@ -815,7 +825,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        break;
                }
 
-               set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, 
+               set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
                                aud->volume, drv);
                set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
                                aud->bass, drv);
@@ -850,29 +860,22 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                err = 0;
                break;
        }
-#if 0
-       case VIDIOCGMBUF:
-               /* v4l2 drivers must implement that themself.  The
-                  mmap() differences can't be translated fully
-                  transparent, thus there is no point to try that */
-#endif
        case VIDIOCMCAPTURE: /*  capture a frame  */
        {
                struct video_mmap       *mm = arg;
 
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                memset(&buf2,0,sizeof(buf2));
-               memset(fmt2,0,sizeof(*fmt2));
-               
+
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
                if (err < 0) {
                        dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
                        break;
                }
-               if (mm->width   != fmt2->fmt.pix.width  || 
+               if (mm->width   != fmt2->fmt.pix.width  ||
                    mm->height  != fmt2->fmt.pix.height ||
-                   palette_to_pixelformat(mm->format) != 
+                   palette_to_pixelformat(mm->format) !=
                    fmt2->fmt.pix.pixelformat)
                {/* New capture format...  */
                        fmt2->fmt.pix.width = mm->width;
@@ -908,6 +911,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        {
                int                     *i = arg;
 
+               memset(&buf2,0,sizeof(buf2));
                buf2.index = *i;
                buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
@@ -955,16 +959,19 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCGVBIFMT: /* query VBI data capture format */
        {
                struct vbi_format      *fmt = arg;
-               
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
-               memset(fmt2, 0, sizeof(*fmt2));
+
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
-               
+
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
                if (err < 0) {
                        dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
                        break;
                }
+               if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
+                       err = -EINVAL;
+                       break;
+               }
                memset(fmt, 0, sizeof(*fmt));
                fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
                fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
@@ -974,23 +981,27 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                fmt->start[1]         = fmt2->fmt.vbi.start[1];
                fmt->count[1]         = fmt2->fmt.vbi.count[1];
                fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
-                break;
+               break;
        }
        case VIDIOCSVBIFMT:
        {
                struct vbi_format      *fmt = arg;
-               
-               fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
-               memset(fmt2, 0, sizeof(*fmt2));
+
+               if (VIDEO_PALETTE_RAW != fmt->sample_format) {
+                       err = -EINVAL;
+                       break;
+               }
+
+               fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
 
                fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
                fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
                fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
                fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
-               fmt2->fmt.vbi.start[0]         = fmt->start[0]; 
-               fmt2->fmt.vbi.count[0]         = fmt->count[0]; 
-               fmt2->fmt.vbi.start[1]         = fmt->start[1]; 
-               fmt2->fmt.vbi.count[1]         = fmt->count[1]; 
+               fmt2->fmt.vbi.start[0]         = fmt->start[0];
+               fmt2->fmt.vbi.count[0]         = fmt->count[0];
+               fmt2->fmt.vbi.start[1]         = fmt->start[1];
+               fmt2->fmt.vbi.count[1]         = fmt->count[1];
                fmt2->fmt.vbi.flags            = fmt->flags;
                err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
                if (err < 0) {
@@ -1000,7 +1011,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
 
                if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
                    fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
-                   VIDEO_PALETTE_RAW              != fmt->sample_format    ||
+                   fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
                    fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
                    fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
                    fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
@@ -1014,16 +1025,14 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
                break;
        }
-       
+
        default:
                err = -ENOIOCTLCMD;
                break;
        }
 
-       if (cap2)
-               kfree(cap2);
-       if (fmt2)
-               kfree(fmt2);
+       kfree(cap2);
+       kfree(fmt2);
        return err;
 }