linux/drivers/media/video/v4l1-compat.c
<<
>>
Prefs
   1/*
   2 *
   3 *      Video for Linux Two
   4 *      Backward Compatibility Layer
   5 *
   6 *      Support subroutines for providing V4L2 drivers with backward
   7 *      compatibility with applications using the old API.
   8 *
   9 *      This program is free software; you can redistribute it and/or
  10 *      modify it under the terms of the GNU General Public License
  11 *      as published by the Free Software Foundation; either version
  12 *      2 of the License, or (at your option) any later version.
  13 *
  14 * Author:      Bill Dirks <bill@thedirks.org>
  15 *              et al.
  16 *
  17 */
  18
  19
  20#include <linux/init.h>
  21#include <linux/module.h>
  22#include <linux/types.h>
  23#include <linux/kernel.h>
  24#include <linux/sched.h>
  25#include <linux/mm.h>
  26#include <linux/fs.h>
  27#include <linux/file.h>
  28#include <linux/string.h>
  29#include <linux/errno.h>
  30#include <linux/slab.h>
  31#include <linux/videodev.h>
  32#include <media/v4l2-common.h>
  33#include <media/v4l2-ioctl.h>
  34
  35#include <asm/uaccess.h>
  36#include <asm/system.h>
  37#include <asm/pgtable.h>
  38
  39static unsigned int debug;
  40module_param(debug, int, 0644);
  41MODULE_PARM_DESC(debug, "enable debug messages");
  42MODULE_AUTHOR("Bill Dirks");
  43MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
  44MODULE_LICENSE("GPL");
  45
  46#define dprintk(fmt, arg...) \
  47        do { \
  48                if (debug) \
  49                        printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\
  50        } while (0)
  51
  52/*
  53 *      I O C T L   T R A N S L A T I O N
  54 *
  55 *      From here on down is the code for translating the numerous
  56 *      ioctl commands from the old API to the new API.
  57 */
  58
  59static int
  60get_v4l_control(struct file             *file,
  61                int                     cid,
  62                v4l2_kioctl             drv)
  63{
  64        struct v4l2_queryctrl   qctrl2;
  65        struct v4l2_control     ctrl2;
  66        int                     err;
  67
  68        qctrl2.id = cid;
  69        err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
  70        if (err < 0)
  71                dprintk("VIDIOC_QUERYCTRL: %d\n", err);
  72        if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {
  73                ctrl2.id = qctrl2.id;
  74                err = drv(file, VIDIOC_G_CTRL, &ctrl2);
  75                if (err < 0) {
  76                        dprintk("VIDIOC_G_CTRL: %d\n", err);
  77                        return 0;
  78                }
  79                return DIV_ROUND_CLOSEST((ctrl2.value-qctrl2.minimum) * 65535,
  80                                         qctrl2.maximum - qctrl2.minimum);
  81        }
  82        return 0;
  83}
  84
  85static int
  86set_v4l_control(struct file             *file,
  87                int                     cid,
  88                int                     value,
  89                v4l2_kioctl             drv)
  90{
  91        struct v4l2_queryctrl   qctrl2;
  92        struct v4l2_control     ctrl2;
  93        int                     err;
  94
  95        qctrl2.id = cid;
  96        err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
  97        if (err < 0)
  98                dprintk("VIDIOC_QUERYCTRL: %d\n", err);
  99        if (err == 0 &&
 100            !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
 101            !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) {
 102                if (value < 0)
 103                        value = 0;
 104                if (value > 65535)
 105                        value = 65535;
 106                if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
 107                        value = 65535;
 108                ctrl2.id = qctrl2.id;
 109                ctrl2.value =
 110                        (value * (qctrl2.maximum - qctrl2.minimum)
 111                         + 32767)
 112                        / 65535;
 113                ctrl2.value += qctrl2.minimum;
 114                err = drv(file, VIDIOC_S_CTRL, &ctrl2);
 115                if (err < 0)
 116                        dprintk("VIDIOC_S_CTRL: %d\n", err);
 117        }
 118        return 0;
 119}
 120
 121/* ----------------------------------------------------------------- */
 122
 123static const unsigned int palette2pixelformat[] = {
 124        [VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
 125        [VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
 126        [VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
 127        [VIDEO_PALETTE_RGB24]   = V4L2_PIX_FMT_BGR24,
 128        [VIDEO_PALETTE_RGB32]   = V4L2_PIX_FMT_BGR32,
 129        /* yuv packed pixel */
 130        [VIDEO_PALETTE_YUYV]    = V4L2_PIX_FMT_YUYV,
 131        [VIDEO_PALETTE_YUV422]  = V4L2_PIX_FMT_YUYV,
 132        [VIDEO_PALETTE_UYVY]    = V4L2_PIX_FMT_UYVY,
 133        /* yuv planar */
 134        [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
 135        [VIDEO_PALETTE_YUV420]  = V4L2_PIX_FMT_YUV420,
 136        [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
 137        [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
 138        [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 139};
 140
 141static unsigned int __pure
 142palette_to_pixelformat(unsigned int palette)
 143{
 144        if (palette < ARRAY_SIZE(palette2pixelformat))
 145                return palette2pixelformat[palette];
 146        else
 147                return 0;
 148}
 149
 150static unsigned int __attribute_const__
 151pixelformat_to_palette(unsigned int pixelformat)
 152{
 153        int     palette = 0;
 154        switch (pixelformat) {
 155        case V4L2_PIX_FMT_GREY:
 156                palette = VIDEO_PALETTE_GREY;
 157                break;
 158        case V4L2_PIX_FMT_RGB555:
 159                palette = VIDEO_PALETTE_RGB555;
 160                break;
 161        case V4L2_PIX_FMT_RGB565:
 162                palette = VIDEO_PALETTE_RGB565;
 163                break;
 164        case V4L2_PIX_FMT_BGR24:
 165                palette = VIDEO_PALETTE_RGB24;
 166                break;
 167        case V4L2_PIX_FMT_BGR32:
 168                palette = VIDEO_PALETTE_RGB32;
 169                break;
 170        /* yuv packed pixel */
 171        case V4L2_PIX_FMT_YUYV:
 172                palette = VIDEO_PALETTE_YUYV;
 173                break;
 174        case V4L2_PIX_FMT_UYVY:
 175                palette = VIDEO_PALETTE_UYVY;
 176                break;
 177        /* yuv planar */
 178        case V4L2_PIX_FMT_YUV410:
 179                palette = VIDEO_PALETTE_YUV420;
 180                break;
 181        case V4L2_PIX_FMT_YUV420:
 182                palette = VIDEO_PALETTE_YUV420;
 183                break;
 184        case V4L2_PIX_FMT_YUV411P:
 185                palette = VIDEO_PALETTE_YUV411P;
 186                break;
 187        case V4L2_PIX_FMT_YUV422P:
 188                palette = VIDEO_PALETTE_YUV422P;
 189                break;
 190        }
 191        return palette;
 192}
 193
 194/* ----------------------------------------------------------------- */
 195
 196static int poll_one(struct file *file, struct poll_wqueues *pwq)
 197{
 198        int retval = 1;
 199        poll_table *table;
 200
 201        poll_initwait(pwq);
 202        table = &pwq->pt;
 203        for (;;) {
 204                int mask;
 205                mask = file->f_op->poll(file, table);
 206                if (mask & POLLIN)
 207                        break;
 208                table = NULL;
 209                if (signal_pending(current)) {
 210                        retval = -ERESTARTSYS;
 211                        break;
 212                }
 213                poll_schedule(pwq, TASK_INTERRUPTIBLE);
 214        }
 215        poll_freewait(pwq);
 216        return retval;
 217}
 218
 219static int count_inputs(
 220                        struct file *file,
 221                        v4l2_kioctl drv)
 222{
 223        struct v4l2_input input2;
 224        int i;
 225
 226        for (i = 0;; i++) {
 227                memset(&input2, 0, sizeof(input2));
 228                input2.index = i;
 229                if (0 != drv(file, VIDIOC_ENUMINPUT, &input2))
 230                        break;
 231        }
 232        return i;
 233}
 234
 235static int check_size(
 236                struct file *file,
 237                v4l2_kioctl drv,
 238                int *maxw,
 239                int *maxh)
 240{
 241        struct v4l2_fmtdesc desc2;
 242        struct v4l2_format  fmt2;
 243
 244        memset(&desc2, 0, sizeof(desc2));
 245        memset(&fmt2, 0, sizeof(fmt2));
 246
 247        desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 248        if (0 != drv(file, VIDIOC_ENUM_FMT, &desc2))
 249                goto done;
 250
 251        fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 252        fmt2.fmt.pix.width       = 10000;
 253        fmt2.fmt.pix.height      = 10000;
 254        fmt2.fmt.pix.pixelformat = desc2.pixelformat;
 255        if (0 != drv(file, VIDIOC_TRY_FMT, &fmt2))
 256                goto done;
 257
 258        *maxw = fmt2.fmt.pix.width;
 259        *maxh = fmt2.fmt.pix.height;
 260
 261done:
 262        return 0;
 263}
 264
 265/* ----------------------------------------------------------------- */
 266
 267static noinline long v4l1_compat_get_capabilities(
 268                                        struct video_capability *cap,
 269                                        struct file *file,
 270                                        v4l2_kioctl drv)
 271{
 272        long err;
 273        struct v4l2_framebuffer fbuf;
 274        struct v4l2_capability *cap2;
 275
 276        cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);
 277        if (!cap2) {
 278                err = -ENOMEM;
 279                return err;
 280        }
 281        memset(cap, 0, sizeof(*cap));
 282        memset(&fbuf, 0, sizeof(fbuf));
 283
 284        err = drv(file, VIDIOC_QUERYCAP, cap2);
 285        if (err < 0) {
 286                dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %ld\n", err);
 287                goto done;
 288        }
 289        if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
 290                err = drv(file, VIDIOC_G_FBUF, &fbuf);
 291                if (err < 0) {
 292                        dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %ld\n", err);
 293                        memset(&fbuf, 0, sizeof(fbuf));
 294                }
 295                err = 0;
 296        }
 297
 298        memcpy(cap->name, cap2->card,
 299               min(sizeof(cap->name), sizeof(cap2->card)));
 300        cap->name[sizeof(cap->name) - 1] = 0;
 301        if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
 302                cap->type |= VID_TYPE_CAPTURE;
 303        if (cap2->capabilities & V4L2_CAP_TUNER)
 304                cap->type |= VID_TYPE_TUNER;
 305        if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
 306                cap->type |= VID_TYPE_TELETEXT;
 307        if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
 308                cap->type |= VID_TYPE_OVERLAY;
 309        if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
 310                cap->type |= VID_TYPE_CLIPPING;
 311
 312        cap->channels  = count_inputs(file, drv);
 313        check_size(file, drv,
 314                   &cap->maxwidth, &cap->maxheight);
 315        cap->audios    =  0; /* FIXME */
 316        cap->minwidth  = 48; /* FIXME */
 317        cap->minheight = 32; /* FIXME */
 318
 319done:
 320        kfree(cap2);
 321        return err;
 322}
 323
 324static noinline long v4l1_compat_get_frame_buffer(
 325                                        struct video_buffer *buffer,
 326                                        struct file *file,
 327                                        v4l2_kioctl drv)
 328{
 329        long err;
 330        struct v4l2_framebuffer fbuf;
 331
 332        memset(buffer, 0, sizeof(*buffer));
 333        memset(&fbuf, 0, sizeof(fbuf));
 334
 335        err = drv(file, VIDIOC_G_FBUF, &fbuf);
 336        if (err < 0) {
 337                dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %ld\n", err);
 338                goto done;
 339        }
 340        buffer->base   = fbuf.base;
 341        buffer->height = fbuf.fmt.height;
 342        buffer->width  = fbuf.fmt.width;
 343
 344        switch (fbuf.fmt.pixelformat) {
 345        case V4L2_PIX_FMT_RGB332:
 346                buffer->depth = 8;
 347                break;
 348        case V4L2_PIX_FMT_RGB555:
 349                buffer->depth = 15;
 350                break;
 351        case V4L2_PIX_FMT_RGB565:
 352                buffer->depth = 16;
 353                break;
 354        case V4L2_PIX_FMT_BGR24:
 355                buffer->depth = 24;
 356                break;
 357        case V4L2_PIX_FMT_BGR32:
 358                buffer->depth = 32;
 359                break;
 360        default:
 361                buffer->depth = 0;
 362        }
 363        if (fbuf.fmt.bytesperline) {
 364                buffer->bytesperline = fbuf.fmt.bytesperline;
 365                if (!buffer->depth && buffer->width)
 366                        buffer->depth   = ((fbuf.fmt.bytesperline<<3)
 367                                          + (buffer->width-1))
 368                                          / buffer->width;
 369        } else {
 370                buffer->bytesperline =
 371                        (buffer->width * buffer->depth + 7) & 7;
 372                buffer->bytesperline >>= 3;
 373        }
 374done:
 375        return err;
 376}
 377
 378static noinline long v4l1_compat_set_frame_buffer(
 379                                        struct video_buffer *buffer,
 380                                        struct file *file,
 381                                        v4l2_kioctl drv)
 382{
 383        long err;
 384        struct v4l2_framebuffer fbuf;
 385
 386        memset(&fbuf, 0, sizeof(fbuf));
 387        fbuf.base       = buffer->base;
 388        fbuf.fmt.height = buffer->height;
 389        fbuf.fmt.width  = buffer->width;
 390        switch (buffer->depth) {
 391        case 8:
 392                fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
 393                break;
 394        case 15:
 395                fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
 396                break;
 397        case 16:
 398                fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
 399                break;
 400        case 24:
 401                fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
 402                break;
 403        case 32:
 404                fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
 405                break;
 406        }
 407        fbuf.fmt.bytesperline = buffer->bytesperline;
 408        err = drv(file, VIDIOC_S_FBUF, &fbuf);
 409        if (err < 0)
 410                dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %ld\n", err);
 411        return err;
 412}
 413
 414static noinline long v4l1_compat_get_win_cap_dimensions(
 415                                        struct video_window *win,
 416                                        struct file *file,
 417                                        v4l2_kioctl drv)
 418{
 419        long err;
 420        struct v4l2_format *fmt;
 421
 422        fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
 423        if (!fmt) {
 424                err = -ENOMEM;
 425                return err;
 426        }
 427        memset(win, 0, sizeof(*win));
 428
 429        fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
 430        err = drv(file, VIDIOC_G_FMT, fmt);
 431        if (err < 0)
 432                dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %ld\n", err);
 433        if (err == 0) {
 434                win->x         = fmt->fmt.win.w.left;
 435                win->y         = fmt->fmt.win.w.top;
 436                win->width     = fmt->fmt.win.w.width;
 437                win->height    = fmt->fmt.win.w.height;
 438                win->chromakey = fmt->fmt.win.chromakey;
 439                win->clips     = NULL;
 440                win->clipcount = 0;
 441                goto done;
 442        }
 443
 444        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 445        err = drv(file, VIDIOC_G_FMT, fmt);
 446        if (err < 0) {
 447                dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %ld\n", err);
 448                goto done;
 449        }
 450        win->x         = 0;
 451        win->y         = 0;
 452        win->width     = fmt->fmt.pix.width;
 453        win->height    = fmt->fmt.pix.height;
 454        win->chromakey = 0;
 455        win->clips     = NULL;
 456        win->clipcount = 0;
 457done:
 458        kfree(fmt);
 459        return err;
 460}
 461
 462static noinline long v4l1_compat_set_win_cap_dimensions(
 463                                        struct video_window *win,
 464                                        struct file *file,
 465                                        v4l2_kioctl drv)
 466{
 467        long err, err1, err2;
 468        struct v4l2_format *fmt;
 469
 470        fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
 471        if (!fmt) {
 472                err = -ENOMEM;
 473                return err;
 474        }
 475        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 476        drv(file, VIDIOC_STREAMOFF, &fmt->type);
 477        err1 = drv(file, VIDIOC_G_FMT, fmt);
 478        if (err1 < 0)
 479                dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %ld\n", err1);
 480        if (err1 == 0) {
 481                fmt->fmt.pix.width  = win->width;
 482                fmt->fmt.pix.height = win->height;
 483                fmt->fmt.pix.field  = V4L2_FIELD_ANY;
 484                fmt->fmt.pix.bytesperline = 0;
 485                err = drv(file, VIDIOC_S_FMT, fmt);
 486                if (err < 0)
 487                        dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %ld\n",
 488                                err);
 489                win->width  = fmt->fmt.pix.width;
 490                win->height = fmt->fmt.pix.height;
 491        }
 492
 493        memset(fmt, 0, sizeof(*fmt));
 494        fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
 495        fmt->fmt.win.w.left    = win->x;
 496        fmt->fmt.win.w.top     = win->y;
 497        fmt->fmt.win.w.width   = win->width;
 498        fmt->fmt.win.w.height  = win->height;
 499        fmt->fmt.win.chromakey = win->chromakey;
 500        fmt->fmt.win.clips     = (void __user *)win->clips;
 501        fmt->fmt.win.clipcount = win->clipcount;
 502        err2 = drv(file, VIDIOC_S_FMT, fmt);
 503        if (err2 < 0)
 504                dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %ld\n", err2);
 505
 506        if (err1 != 0 && err2 != 0)
 507                err = err1;
 508        else
 509                err = 0;
 510        kfree(fmt);
 511        return err;
 512}
 513
 514static noinline long v4l1_compat_turn_preview_on_off(
 515                                        int *on,
 516                                        struct file *file,
 517                                        v4l2_kioctl drv)
 518{
 519        long err;
 520        enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 521
 522        if (0 == *on) {
 523                /* dirty hack time.  But v4l1 has no STREAMOFF
 524                 * equivalent in the API, and this one at
 525                 * least comes close ... */
 526                drv(file, VIDIOC_STREAMOFF, &captype);
 527        }
 528        err = drv(file, VIDIOC_OVERLAY, on);
 529        if (err < 0)
 530                dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld\n", err);
 531        return err;
 532}
 533
 534static noinline long v4l1_compat_get_input_info(
 535                                        struct video_channel *chan,
 536                                        struct file *file,
 537                                        v4l2_kioctl drv)
 538{
 539        long err;
 540        struct v4l2_input       input2;
 541        v4l2_std_id             sid;
 542
 543        memset(&input2, 0, sizeof(input2));
 544        input2.index = chan->channel;
 545        err = drv(file, VIDIOC_ENUMINPUT, &input2);
 546        if (err < 0) {
 547                dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
 548                        "channel=%d err=%ld\n", chan->channel, err);
 549                goto done;
 550        }
 551        chan->channel = input2.index;
 552        memcpy(chan->name, input2.name,
 553               min(sizeof(chan->name), sizeof(input2.name)));
 554        chan->name[sizeof(chan->name) - 1] = 0;
 555        chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
 556        chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
 557        switch (input2.type) {
 558        case V4L2_INPUT_TYPE_TUNER:
 559                chan->type = VIDEO_TYPE_TV;
 560                break;
 561        default:
 562        case V4L2_INPUT_TYPE_CAMERA:
 563                chan->type = VIDEO_TYPE_CAMERA;
 564                break;
 565        }
 566        chan->norm = 0;
 567        /* Note: G_STD might not be present for radio receivers,
 568         * so we should ignore any errors. */
 569        if (drv(file, VIDIOC_G_STD, &sid) == 0) {
 570                if (sid & V4L2_STD_PAL)
 571                        chan->norm = VIDEO_MODE_PAL;
 572                if (sid & V4L2_STD_NTSC)
 573                        chan->norm = VIDEO_MODE_NTSC;
 574                if (sid & V4L2_STD_SECAM)
 575                        chan->norm = VIDEO_MODE_SECAM;
 576                if (sid == V4L2_STD_ALL)
 577                        chan->norm = VIDEO_MODE_AUTO;
 578        }
 579done:
 580        return err;
 581}
 582
 583static noinline long v4l1_compat_set_input(
 584                                        struct video_channel *chan,
 585                                        struct file *file,
 586                                        v4l2_kioctl drv)
 587{
 588        long err;
 589        v4l2_std_id sid = 0;
 590
 591        err = drv(file, VIDIOC_S_INPUT, &chan->channel);
 592        if (err < 0)
 593                dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %ld\n", err);
 594        switch (chan->norm) {
 595        case VIDEO_MODE_PAL:
 596                sid = V4L2_STD_PAL;
 597                break;
 598        case VIDEO_MODE_NTSC:
 599                sid = V4L2_STD_NTSC;
 600                break;
 601        case VIDEO_MODE_SECAM:
 602                sid = V4L2_STD_SECAM;
 603                break;
 604        case VIDEO_MODE_AUTO:
 605                sid = V4L2_STD_ALL;
 606                break;
 607        }
 608        if (0 != sid) {
 609                err = drv(file, VIDIOC_S_STD, &sid);
 610                if (err < 0)
 611                        dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err);
 612        }
 613        return err;
 614}
 615
 616static noinline long v4l1_compat_get_picture(
 617                                        struct video_picture *pict,
 618                                        struct file *file,
 619                                        v4l2_kioctl drv)
 620{
 621        long err;
 622        struct v4l2_format *fmt;
 623
 624        fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
 625        if (!fmt) {
 626                err = -ENOMEM;
 627                return err;
 628        }
 629
 630        pict->brightness = get_v4l_control(file,
 631                                           V4L2_CID_BRIGHTNESS, drv);
 632        pict->hue = get_v4l_control(file,
 633                                    V4L2_CID_HUE, drv);
 634        pict->contrast = get_v4l_control(file,
 635                                         V4L2_CID_CONTRAST, drv);
 636        pict->colour = get_v4l_control(file,
 637                                       V4L2_CID_SATURATION, drv);
 638        pict->whiteness = get_v4l_control(file,
 639                                          V4L2_CID_WHITENESS, drv);
 640
 641        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 642        err = drv(file, VIDIOC_G_FMT, fmt);
 643        if (err < 0) {
 644                dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err);
 645                goto done;
 646        }
 647
 648        pict->depth   = ((fmt->fmt.pix.bytesperline << 3)
 649                         + (fmt->fmt.pix.width - 1))
 650                         / fmt->fmt.pix.width;
 651        pict->palette = pixelformat_to_palette(
 652                fmt->fmt.pix.pixelformat);
 653done:
 654        kfree(fmt);
 655        return err;
 656}
 657
 658static noinline long v4l1_compat_set_picture(
 659                                        struct video_picture *pict,
 660                                        struct file *file,
 661                                        v4l2_kioctl drv)
 662{
 663        long err;
 664        struct v4l2_framebuffer fbuf;
 665        int mem_err = 0, ovl_err = 0;
 666        struct v4l2_format *fmt;
 667
 668        fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
 669        if (!fmt) {
 670                err = -ENOMEM;
 671                return err;
 672        }
 673        memset(&fbuf, 0, sizeof(fbuf));
 674
 675        set_v4l_control(file,
 676                        V4L2_CID_BRIGHTNESS, pict->brightness, drv);
 677        set_v4l_control(file,
 678                        V4L2_CID_HUE, pict->hue, drv);
 679        set_v4l_control(file,
 680                        V4L2_CID_CONTRAST, pict->contrast, drv);
 681        set_v4l_control(file,
 682                        V4L2_CID_SATURATION, pict->colour, drv);
 683        set_v4l_control(file,
 684                        V4L2_CID_WHITENESS, pict->whiteness, drv);
 685        /*
 686         * V4L1 uses this ioctl to set both memory capture and overlay
 687         * pixel format, while V4L2 has two different ioctls for this.
 688         * Some cards may not support one or the other, and may support
 689         * different pixel formats for memory vs overlay.
 690         */
 691
 692        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 693        err = drv(file, VIDIOC_G_FMT, fmt);
 694        /* If VIDIOC_G_FMT failed, then the driver likely doesn't
 695           support memory capture.  Trying to set the memory capture
 696           parameters would be pointless.  */
 697        if (err < 0) {
 698                dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err);
 699                mem_err = -1000;  /* didn't even try */
 700        } else if (fmt->fmt.pix.pixelformat !=
 701                 palette_to_pixelformat(pict->palette)) {
 702                fmt->fmt.pix.pixelformat = palette_to_pixelformat(
 703                        pict->palette);
 704                mem_err = drv(file, VIDIOC_S_FMT, fmt);
 705                if (mem_err < 0)
 706                        dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
 707                                mem_err);
 708        }
 709
 710        err = drv(file, VIDIOC_G_FBUF, &fbuf);
 711        /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
 712           support overlay.  Trying to set the overlay parameters
 713           would be quite pointless.  */
 714        if (err < 0) {
 715                dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err);
 716                ovl_err = -1000;  /* didn't even try */
 717        } else if (fbuf.fmt.pixelformat !=
 718                 palette_to_pixelformat(pict->palette)) {
 719                fbuf.fmt.pixelformat = palette_to_pixelformat(
 720                        pict->palette);
 721                ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf);
 722                if (ovl_err < 0)
 723                        dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
 724                                ovl_err);
 725        }
 726        if (ovl_err < 0 && mem_err < 0) {
 727                /* ioctl failed, couldn't set either parameter */
 728                if (mem_err != -1000)
 729                        err = mem_err;
 730                else if (ovl_err == -EPERM)
 731                        err = 0;
 732                else
 733                        err = ovl_err;
 734        } else
 735                err = 0;
 736        kfree(fmt);
 737        return err;
 738}
 739
 740static noinline long v4l1_compat_get_tuner(
 741                                        struct video_tuner *tun,
 742                                        struct file *file,
 743                                        v4l2_kioctl drv)
 744{
 745        long err;
 746        int i;
 747        struct v4l2_tuner       tun2;
 748        struct v4l2_standard    std2;
 749        v4l2_std_id             sid;
 750
 751        memset(&tun2, 0, sizeof(tun2));
 752        err = drv(file, VIDIOC_G_TUNER, &tun2);
 753        if (err < 0) {
 754                dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err);
 755                goto done;
 756        }
 757        memcpy(tun->name, tun2.name,
 758               min(sizeof(tun->name), sizeof(tun2.name)));
 759        tun->name[sizeof(tun->name) - 1] = 0;
 760        tun->rangelow = tun2.rangelow;
 761        tun->rangehigh = tun2.rangehigh;
 762        tun->flags = 0;
 763        tun->mode = VIDEO_MODE_AUTO;
 764
 765        for (i = 0; i < 64; i++) {
 766                memset(&std2, 0, sizeof(std2));
 767                std2.index = i;
 768                if (0 != drv(file, VIDIOC_ENUMSTD, &std2))
 769                        break;
 770                if (std2.id & V4L2_STD_PAL)
 771                        tun->flags |= VIDEO_TUNER_PAL;
 772                if (std2.id & V4L2_STD_NTSC)
 773                        tun->flags |= VIDEO_TUNER_NTSC;
 774                if (std2.id & V4L2_STD_SECAM)
 775                        tun->flags |= VIDEO_TUNER_SECAM;
 776        }
 777
 778        /* Note: G_STD might not be present for radio receivers,
 779         * so we should ignore any errors. */
 780        if (drv(file, VIDIOC_G_STD, &sid) == 0) {
 781                if (sid & V4L2_STD_PAL)
 782                        tun->mode = VIDEO_MODE_PAL;
 783                if (sid & V4L2_STD_NTSC)
 784                        tun->mode = VIDEO_MODE_NTSC;
 785                if (sid & V4L2_STD_SECAM)
 786                        tun->mode = VIDEO_MODE_SECAM;
 787        }
 788
 789        if (tun2.capability & V4L2_TUNER_CAP_LOW)
 790                tun->flags |= VIDEO_TUNER_LOW;
 791        if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
 792                tun->flags |= VIDEO_TUNER_STEREO_ON;
 793        tun->signal = tun2.signal;
 794done:
 795        return err;
 796}
 797
 798static noinline long v4l1_compat_select_tuner(
 799                                        struct video_tuner *tun,
 800                                        struct file *file,
 801                                        v4l2_kioctl drv)
 802{
 803        long err;
 804        struct v4l2_tuner       t;/*84 bytes on x86_64*/
 805        memset(&t, 0, sizeof(t));
 806
 807        t.index = tun->tuner;
 808
 809        err = drv(file, VIDIOC_S_TUNER, &t);
 810        if (err < 0)
 811                dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err);
 812        return err;
 813}
 814
 815static noinline long v4l1_compat_get_frequency(
 816                                        unsigned long *freq,
 817                                        struct file *file,
 818                                        v4l2_kioctl drv)
 819{
 820        long err;
 821        struct v4l2_frequency   freq2;
 822        memset(&freq2, 0, sizeof(freq2));
 823
 824        freq2.tuner = 0;
 825        err = drv(file, VIDIOC_G_FREQUENCY, &freq2);
 826        if (err < 0)
 827                dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err);
 828        if (0 == err)
 829                *freq = freq2.frequency;
 830        return err;
 831}
 832
 833static noinline long v4l1_compat_set_frequency(
 834                                        unsigned long *freq,
 835                                        struct file *file,
 836                                        v4l2_kioctl drv)
 837{
 838        long err;
 839        struct v4l2_frequency   freq2;
 840        memset(&freq2, 0, sizeof(freq2));
 841
 842        drv(file, VIDIOC_G_FREQUENCY, &freq2);
 843        freq2.frequency = *freq;
 844        err = drv(file, VIDIOC_S_FREQUENCY, &freq2);
 845        if (err < 0)
 846                dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err);
 847        return err;
 848}
 849
 850static noinline long v4l1_compat_get_audio(
 851                                        struct video_audio *aud,
 852                                        struct file *file,
 853                                        v4l2_kioctl drv)
 854{
 855        long err;
 856        int i;
 857        struct v4l2_queryctrl   qctrl2;
 858        struct v4l2_audio       aud2;
 859        struct v4l2_tuner       tun2;
 860        memset(&aud2, 0, sizeof(aud2));
 861
 862        err = drv(file, VIDIOC_G_AUDIO, &aud2);
 863        if (err < 0) {
 864                dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err);
 865                goto done;
 866        }
 867        memcpy(aud->name, aud2.name,
 868               min(sizeof(aud->name), sizeof(aud2.name)));
 869        aud->name[sizeof(aud->name) - 1] = 0;
 870        aud->audio = aud2.index;
 871        aud->flags = 0;
 872        i = get_v4l_control(file, V4L2_CID_AUDIO_VOLUME, drv);
 873        if (i >= 0) {
 874                aud->volume = i;
 875                aud->flags |= VIDEO_AUDIO_VOLUME;
 876        }
 877        i = get_v4l_control(file, V4L2_CID_AUDIO_BASS, drv);
 878        if (i >= 0) {
 879                aud->bass = i;
 880                aud->flags |= VIDEO_AUDIO_BASS;
 881        }
 882        i = get_v4l_control(file, V4L2_CID_AUDIO_TREBLE, drv);
 883        if (i >= 0) {
 884                aud->treble = i;
 885                aud->flags |= VIDEO_AUDIO_TREBLE;
 886        }
 887        i = get_v4l_control(file, V4L2_CID_AUDIO_BALANCE, drv);
 888        if (i >= 0) {
 889                aud->balance = i;
 890                aud->flags |= VIDEO_AUDIO_BALANCE;
 891        }
 892        i = get_v4l_control(file, V4L2_CID_AUDIO_MUTE, drv);
 893        if (i >= 0) {
 894                if (i)
 895                        aud->flags |= VIDEO_AUDIO_MUTE;
 896                aud->flags |= VIDEO_AUDIO_MUTABLE;
 897        }
 898        aud->step = 1;
 899        qctrl2.id = V4L2_CID_AUDIO_VOLUME;
 900        if (drv(file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
 901            !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
 902                aud->step = qctrl2.step;
 903        aud->mode = 0;
 904
 905        memset(&tun2, 0, sizeof(tun2));
 906        err = drv(file, VIDIOC_G_TUNER, &tun2);
 907        if (err < 0) {
 908                dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err);
 909                err = 0;
 910                goto done;
 911        }
 912
 913        if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
 914                aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 915        else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
 916                aud->mode = VIDEO_SOUND_STEREO;
 917        else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
 918                aud->mode = VIDEO_SOUND_MONO;
 919done:
 920        return err;
 921}
 922
 923static noinline long v4l1_compat_set_audio(
 924                                        struct video_audio *aud,
 925                                        struct file *file,
 926                                        v4l2_kioctl drv)
 927{
 928        long err;
 929        struct v4l2_audio       aud2;
 930        struct v4l2_tuner       tun2;
 931
 932        memset(&aud2, 0, sizeof(aud2));
 933        memset(&tun2, 0, sizeof(tun2));
 934
 935        aud2.index = aud->audio;
 936        err = drv(file, VIDIOC_S_AUDIO, &aud2);
 937        if (err < 0) {
 938                dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err);
 939                goto done;
 940        }
 941
 942        set_v4l_control(file, V4L2_CID_AUDIO_VOLUME,
 943                        aud->volume, drv);
 944        set_v4l_control(file, V4L2_CID_AUDIO_BASS,
 945                        aud->bass, drv);
 946        set_v4l_control(file, V4L2_CID_AUDIO_TREBLE,
 947                        aud->treble, drv);
 948        set_v4l_control(file, V4L2_CID_AUDIO_BALANCE,
 949                        aud->balance, drv);
 950        set_v4l_control(file, V4L2_CID_AUDIO_MUTE,
 951                        !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
 952
 953        err = drv(file, VIDIOC_G_TUNER, &tun2);
 954        if (err < 0)
 955                dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err);
 956        if (err == 0) {
 957                switch (aud->mode) {
 958                default:
 959                case VIDEO_SOUND_MONO:
 960                case VIDEO_SOUND_LANG1:
 961                        tun2.audmode = V4L2_TUNER_MODE_MONO;
 962                        break;
 963                case VIDEO_SOUND_STEREO:
 964                        tun2.audmode = V4L2_TUNER_MODE_STEREO;
 965                        break;
 966                case VIDEO_SOUND_LANG2:
 967                        tun2.audmode = V4L2_TUNER_MODE_LANG2;
 968                        break;
 969                }
 970                err = drv(file, VIDIOC_S_TUNER, &tun2);
 971                if (err < 0)
 972                        dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err);
 973        }
 974        err = 0;
 975done:
 976        return err;
 977}
 978
 979static noinline long v4l1_compat_capture_frame(
 980                                        struct video_mmap *mm,
 981                                        struct file *file,
 982                                        v4l2_kioctl drv)
 983{
 984        long err;
 985        enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 986        struct v4l2_buffer      buf;
 987        struct v4l2_format      *fmt;
 988
 989        fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
 990        if (!fmt) {
 991                err = -ENOMEM;
 992                return err;
 993        }
 994        memset(&buf, 0, sizeof(buf));
 995
 996        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 997        err = drv(file, VIDIOC_G_FMT, fmt);
 998        if (err < 0) {
 999                dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err);
1000                goto done;
1001        }
1002        if (mm->width   != fmt->fmt.pix.width  ||
1003            mm->height  != fmt->fmt.pix.height ||
1004            palette_to_pixelformat(mm->format) !=
1005            fmt->fmt.pix.pixelformat) {
1006                /* New capture format...  */
1007                fmt->fmt.pix.width = mm->width;
1008                fmt->fmt.pix.height = mm->height;
1009                fmt->fmt.pix.pixelformat =
1010                        palette_to_pixelformat(mm->format);
1011                fmt->fmt.pix.field = V4L2_FIELD_ANY;
1012                fmt->fmt.pix.bytesperline = 0;
1013                err = drv(file, VIDIOC_S_FMT, fmt);
1014                if (err < 0) {
1015                        dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err);
1016                        goto done;
1017                }
1018        }
1019        buf.index = mm->frame;
1020        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1021        err = drv(file, VIDIOC_QUERYBUF, &buf);
1022        if (err < 0) {
1023                dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err);
1024                goto done;
1025        }
1026        err = drv(file, VIDIOC_QBUF, &buf);
1027        if (err < 0) {
1028                dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err);
1029                goto done;
1030        }
1031        err = drv(file, VIDIOC_STREAMON, &captype);
1032        if (err < 0)
1033                dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err);
1034done:
1035        kfree(fmt);
1036        return err;
1037}
1038
1039static noinline long v4l1_compat_sync(
1040                                int *i,
1041                                struct file *file,
1042                                v4l2_kioctl drv)
1043{
1044        long err;
1045        enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1046        struct v4l2_buffer buf;
1047        struct poll_wqueues *pwq;
1048
1049        memset(&buf, 0, sizeof(buf));
1050        buf.index = *i;
1051        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1052        err = drv(file, VIDIOC_QUERYBUF, &buf);
1053        if (err < 0) {
1054                /*  No such buffer */
1055                dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
1056                goto done;
1057        }
1058        if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) {
1059                /* Buffer is not mapped  */
1060                err = -EINVAL;
1061                goto done;
1062        }
1063
1064        /* make sure capture actually runs so we don't block forever */
1065        err = drv(file, VIDIOC_STREAMON, &captype);
1066        if (err < 0) {
1067                dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err);
1068                goto done;
1069        }
1070
1071        pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
1072        /*  Loop as long as the buffer is queued, but not done  */
1073        while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
1074                                                == V4L2_BUF_FLAG_QUEUED) {
1075                err = poll_one(file, pwq);
1076                if (err < 0 ||  /* error or sleep was interrupted  */
1077                    err == 0)   /* timeout? Shouldn't occur.  */
1078                        break;
1079                err = drv(file, VIDIOC_QUERYBUF, &buf);
1080                if (err < 0)
1081                        dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
1082        }
1083        kfree(pwq);
1084        if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
1085                goto done;
1086        do {
1087                err = drv(file, VIDIOC_DQBUF, &buf);
1088                if (err < 0)
1089                        dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err);
1090        } while (err == 0 && buf.index != *i);
1091done:
1092        return err;
1093}
1094
1095static noinline long v4l1_compat_get_vbi_format(
1096                                struct vbi_format *fmt,
1097                                struct file *file,
1098                                v4l2_kioctl drv)
1099{
1100        long err;
1101        struct v4l2_format *fmt2;
1102
1103        fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1104        if (!fmt2) {
1105                err = -ENOMEM;
1106                return err;
1107        }
1108        fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1109
1110        err = drv(file, VIDIOC_G_FMT, fmt2);
1111        if (err < 0) {
1112                dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err);
1113                goto done;
1114        }
1115        if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
1116                err = -EINVAL;
1117                goto done;
1118        }
1119        memset(fmt, 0, sizeof(*fmt));
1120        fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
1121        fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
1122        fmt->sample_format    = VIDEO_PALETTE_RAW;
1123        fmt->start[0]         = fmt2->fmt.vbi.start[0];
1124        fmt->count[0]         = fmt2->fmt.vbi.count[0];
1125        fmt->start[1]         = fmt2->fmt.vbi.start[1];
1126        fmt->count[1]         = fmt2->fmt.vbi.count[1];
1127        fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
1128done:
1129        kfree(fmt2);
1130        return err;
1131}
1132
1133static noinline long v4l1_compat_set_vbi_format(
1134                                struct vbi_format *fmt,
1135                                struct file *file,
1136                                v4l2_kioctl drv)
1137{
1138        long err;
1139        struct v4l2_format      *fmt2 = NULL;
1140
1141        if (VIDEO_PALETTE_RAW != fmt->sample_format) {
1142                err = -EINVAL;
1143                return err;
1144        }
1145
1146        fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1147        if (!fmt2) {
1148                err = -ENOMEM;
1149                return err;
1150        }
1151        fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1152        fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
1153        fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
1154        fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
1155        fmt2->fmt.vbi.start[0]         = fmt->start[0];
1156        fmt2->fmt.vbi.count[0]         = fmt->count[0];
1157        fmt2->fmt.vbi.start[1]         = fmt->start[1];
1158        fmt2->fmt.vbi.count[1]         = fmt->count[1];
1159        fmt2->fmt.vbi.flags            = fmt->flags;
1160        err = drv(file, VIDIOC_TRY_FMT, fmt2);
1161        if (err < 0) {
1162                dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err);
1163                goto done;
1164        }
1165
1166        if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1167            fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
1168            fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
1169            fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
1170            fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
1171            fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
1172            fmt2->fmt.vbi.count[1]         != fmt->count[1]         ||
1173            fmt2->fmt.vbi.flags            != fmt->flags) {
1174                err = -EINVAL;
1175                goto done;
1176        }
1177        err = drv(file, VIDIOC_S_FMT, fmt2);
1178        if (err < 0)
1179                dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err);
1180done:
1181        kfree(fmt2);
1182        return err;
1183}
1184
1185/*
1186 *      This function is exported.
1187 */
1188long
1189v4l_compat_translate_ioctl(struct file          *file,
1190                           int                  cmd,
1191                           void                 *arg,
1192                           v4l2_kioctl          drv)
1193{
1194        long err;
1195
1196        switch (cmd) {
1197        case VIDIOCGCAP:        /* capability */
1198                err = v4l1_compat_get_capabilities(arg, file, drv);
1199                break;
1200        case VIDIOCGFBUF: /*  get frame buffer  */
1201                err = v4l1_compat_get_frame_buffer(arg, file, drv);
1202                break;
1203        case VIDIOCSFBUF: /*  set frame buffer  */
1204                err = v4l1_compat_set_frame_buffer(arg, file, drv);
1205                break;
1206        case VIDIOCGWIN: /*  get window or capture dimensions  */
1207                err = v4l1_compat_get_win_cap_dimensions(arg, file, drv);
1208                break;
1209        case VIDIOCSWIN: /*  set window and/or capture dimensions  */
1210                err = v4l1_compat_set_win_cap_dimensions(arg, file, drv);
1211                break;
1212        case VIDIOCCAPTURE: /*  turn on/off preview  */
1213                err = v4l1_compat_turn_preview_on_off(arg, file, drv);
1214                break;
1215        case VIDIOCGCHAN: /*  get input information  */
1216                err = v4l1_compat_get_input_info(arg, file, drv);
1217                break;
1218        case VIDIOCSCHAN: /*  set input  */
1219                err = v4l1_compat_set_input(arg, file, drv);
1220                break;
1221        case VIDIOCGPICT: /*  get tone controls & partial capture format  */
1222                err = v4l1_compat_get_picture(arg, file, drv);
1223                break;
1224        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
1225                err = v4l1_compat_set_picture(arg, file, drv);
1226                break;
1227        case VIDIOCGTUNER: /*  get tuner information  */
1228                err = v4l1_compat_get_tuner(arg, file, drv);
1229                break;
1230        case VIDIOCSTUNER: /*  select a tuner input  */
1231                err = v4l1_compat_select_tuner(arg, file, drv);
1232                break;
1233        case VIDIOCGFREQ: /*  get frequency  */
1234                err = v4l1_compat_get_frequency(arg, file, drv);
1235                break;
1236        case VIDIOCSFREQ: /*  set frequency  */
1237                err = v4l1_compat_set_frequency(arg, file, drv);
1238                break;
1239        case VIDIOCGAUDIO: /*  get audio properties/controls  */
1240                err = v4l1_compat_get_audio(arg, file, drv);
1241                break;
1242        case VIDIOCSAUDIO: /*  set audio controls  */
1243                err = v4l1_compat_set_audio(arg, file, drv);
1244                break;
1245        case VIDIOCMCAPTURE: /*  capture a frame  */
1246                err = v4l1_compat_capture_frame(arg, file, drv);
1247                break;
1248        case VIDIOCSYNC: /*  wait for a frame  */
1249                err = v4l1_compat_sync(arg, file, drv);
1250                break;
1251        case VIDIOCGVBIFMT: /* query VBI data capture format */
1252                err = v4l1_compat_get_vbi_format(arg, file, drv);
1253                break;
1254        case VIDIOCSVBIFMT:
1255                err = v4l1_compat_set_vbi_format(arg, file, drv);
1256                break;
1257        default:
1258                err = -ENOIOCTLCMD;
1259                break;
1260        }
1261
1262        return err;
1263}
1264EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1265
1266/*
1267 * Local variables:
1268 * c-basic-offset: 8
1269 * End:
1270 */
1271