Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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