• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/media/video/
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