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; 316 cap->minwidth = 48; 317 cap->minheight = 32; 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