• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
39 static unsigned int debug;
40 module_param(debug, int, 0644);
41 MODULE_PARM_DESC(debug, "enable debug messages");
42 MODULE_AUTHOR("Bill Dirks");
43 MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
44 MODULE_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 
59 static int
get_v4l_control(struct file * file,int cid,v4l2_kioctl drv)60 get_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 
86 static int
set_v4l_control(struct file * file,int cid,int value,v4l2_kioctl drv)87 set_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 
124 static 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 
142 static unsigned int __pure
palette_to_pixelformat(unsigned int palette)143 palette_to_pixelformat(unsigned int palette)
144 {
145 	if (palette < ARRAY_SIZE(palette2pixelformat))
146 		return palette2pixelformat[palette];
147 	else
148 		return 0;
149 }
150 
151 static unsigned int __attribute_const__
pixelformat_to_palette(unsigned int pixelformat)152 pixelformat_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 
poll_one(struct file * file,struct poll_wqueues * pwq)197 static 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 
count_inputs(struct file * file,v4l2_kioctl drv)220 static 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 
check_size(struct file * file,v4l2_kioctl drv,int * maxw,int * maxh)236 static 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 
262 done:
263 	return 0;
264 }
265 
266 /* ----------------------------------------------------------------- */
267 
v4l1_compat_get_capabilities(struct video_capability * cap,struct file * file,v4l2_kioctl drv)268 static 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 
320 done:
321 	kfree(cap2);
322 	return err;
323 }
324 
v4l1_compat_get_frame_buffer(struct video_buffer * buffer,struct file * file,v4l2_kioctl drv)325 static 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 	}
375 done:
376 	return err;
377 }
378 
v4l1_compat_set_frame_buffer(struct video_buffer * buffer,struct file * file,v4l2_kioctl drv)379 static 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 
v4l1_compat_get_win_cap_dimensions(struct video_window * win,struct file * file,v4l2_kioctl drv)415 static 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;
458 done:
459 	kfree(fmt);
460 	return err;
461 }
462 
v4l1_compat_set_win_cap_dimensions(struct video_window * win,struct file * file,v4l2_kioctl drv)463 static 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 
v4l1_compat_turn_preview_on_off(int * on,struct file * file,v4l2_kioctl drv)515 static 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 
v4l1_compat_get_input_info(struct video_channel * chan,struct file * file,v4l2_kioctl drv)535 static 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 	}
579 done:
580 	return err;
581 }
582 
v4l1_compat_set_input(struct video_channel * chan,struct file * file,v4l2_kioctl drv)583 static 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 	}
605 	if (0 != sid) {
606 		err = drv(file, VIDIOC_S_STD, &sid);
607 		if (err < 0)
608 			dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err);
609 	}
610 	return err;
611 }
612 
v4l1_compat_get_picture(struct video_picture * pict,struct file * file,v4l2_kioctl drv)613 static noinline long v4l1_compat_get_picture(
614 					struct video_picture *pict,
615 					struct file *file,
616 					v4l2_kioctl drv)
617 {
618 	long err;
619 	struct v4l2_format *fmt;
620 
621 	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
622 	if (!fmt) {
623 		err = -ENOMEM;
624 		return err;
625 	}
626 
627 	pict->brightness = get_v4l_control(file,
628 					   V4L2_CID_BRIGHTNESS, drv);
629 	pict->hue = get_v4l_control(file,
630 				    V4L2_CID_HUE, drv);
631 	pict->contrast = get_v4l_control(file,
632 					 V4L2_CID_CONTRAST, drv);
633 	pict->colour = get_v4l_control(file,
634 				       V4L2_CID_SATURATION, drv);
635 	pict->whiteness = get_v4l_control(file,
636 					  V4L2_CID_WHITENESS, drv);
637 
638 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
639 	err = drv(file, VIDIOC_G_FMT, fmt);
640 	if (err < 0) {
641 		dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err);
642 		goto done;
643 	}
644 
645 	pict->depth   = ((fmt->fmt.pix.bytesperline << 3)
646 			 + (fmt->fmt.pix.width - 1))
647 			 / fmt->fmt.pix.width;
648 	pict->palette = pixelformat_to_palette(
649 		fmt->fmt.pix.pixelformat);
650 done:
651 	kfree(fmt);
652 	return err;
653 }
654 
v4l1_compat_set_picture(struct video_picture * pict,struct file * file,v4l2_kioctl drv)655 static noinline long v4l1_compat_set_picture(
656 					struct video_picture *pict,
657 					struct file *file,
658 					v4l2_kioctl drv)
659 {
660 	long err;
661 	struct v4l2_framebuffer fbuf;
662 	int mem_err = 0, ovl_err = 0;
663 	struct v4l2_format *fmt;
664 
665 	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
666 	if (!fmt) {
667 		err = -ENOMEM;
668 		return err;
669 	}
670 	memset(&fbuf, 0, sizeof(fbuf));
671 
672 	set_v4l_control(file,
673 			V4L2_CID_BRIGHTNESS, pict->brightness, drv);
674 	set_v4l_control(file,
675 			V4L2_CID_HUE, pict->hue, drv);
676 	set_v4l_control(file,
677 			V4L2_CID_CONTRAST, pict->contrast, drv);
678 	set_v4l_control(file,
679 			V4L2_CID_SATURATION, pict->colour, drv);
680 	set_v4l_control(file,
681 			V4L2_CID_WHITENESS, pict->whiteness, drv);
682 	/*
683 	 * V4L1 uses this ioctl to set both memory capture and overlay
684 	 * pixel format, while V4L2 has two different ioctls for this.
685 	 * Some cards may not support one or the other, and may support
686 	 * different pixel formats for memory vs overlay.
687 	 */
688 
689 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
690 	err = drv(file, VIDIOC_G_FMT, fmt);
691 	/* If VIDIOC_G_FMT failed, then the driver likely doesn't
692 	   support memory capture.  Trying to set the memory capture
693 	   parameters would be pointless.  */
694 	if (err < 0) {
695 		dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err);
696 		mem_err = -1000;  /* didn't even try */
697 	} else if (fmt->fmt.pix.pixelformat !=
698 		 palette_to_pixelformat(pict->palette)) {
699 		fmt->fmt.pix.pixelformat = palette_to_pixelformat(
700 			pict->palette);
701 		mem_err = drv(file, VIDIOC_S_FMT, fmt);
702 		if (mem_err < 0)
703 			dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
704 				mem_err);
705 	}
706 
707 	err = drv(file, VIDIOC_G_FBUF, &fbuf);
708 	/* If VIDIOC_G_FBUF failed, then the driver likely doesn't
709 	   support overlay.  Trying to set the overlay parameters
710 	   would be quite pointless.  */
711 	if (err < 0) {
712 		dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err);
713 		ovl_err = -1000;  /* didn't even try */
714 	} else if (fbuf.fmt.pixelformat !=
715 		 palette_to_pixelformat(pict->palette)) {
716 		fbuf.fmt.pixelformat = palette_to_pixelformat(
717 			pict->palette);
718 		ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf);
719 		if (ovl_err < 0)
720 			dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
721 				ovl_err);
722 	}
723 	if (ovl_err < 0 && mem_err < 0) {
724 		/* ioctl failed, couldn't set either parameter */
725 		if (mem_err != -1000)
726 			err = mem_err;
727 		else if (ovl_err == -EPERM)
728 			err = 0;
729 		else
730 			err = ovl_err;
731 	} else
732 		err = 0;
733 	kfree(fmt);
734 	return err;
735 }
736 
v4l1_compat_get_tuner(struct video_tuner * tun,struct file * file,v4l2_kioctl drv)737 static noinline long v4l1_compat_get_tuner(
738 					struct video_tuner *tun,
739 					struct file *file,
740 					v4l2_kioctl drv)
741 {
742 	long err;
743 	int i;
744 	struct v4l2_tuner	tun2;
745 	struct v4l2_standard	std2;
746 	v4l2_std_id    		sid;
747 
748 	memset(&tun2, 0, sizeof(tun2));
749 	err = drv(file, VIDIOC_G_TUNER, &tun2);
750 	if (err < 0) {
751 		dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err);
752 		goto done;
753 	}
754 	memcpy(tun->name, tun2.name,
755 	       min(sizeof(tun->name), sizeof(tun2.name)));
756 	tun->name[sizeof(tun->name) - 1] = 0;
757 	tun->rangelow = tun2.rangelow;
758 	tun->rangehigh = tun2.rangehigh;
759 	tun->flags = 0;
760 	tun->mode = VIDEO_MODE_AUTO;
761 
762 	for (i = 0; i < 64; i++) {
763 		memset(&std2, 0, sizeof(std2));
764 		std2.index = i;
765 		if (0 != drv(file, VIDIOC_ENUMSTD, &std2))
766 			break;
767 		if (std2.id & V4L2_STD_PAL)
768 			tun->flags |= VIDEO_TUNER_PAL;
769 		if (std2.id & V4L2_STD_NTSC)
770 			tun->flags |= VIDEO_TUNER_NTSC;
771 		if (std2.id & V4L2_STD_SECAM)
772 			tun->flags |= VIDEO_TUNER_SECAM;
773 	}
774 
775 	err = drv(file, VIDIOC_G_STD, &sid);
776 	if (err < 0)
777 		dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err);
778 	if (err == 0) {
779 		if (sid & V4L2_STD_PAL)
780 			tun->mode = VIDEO_MODE_PAL;
781 		if (sid & V4L2_STD_NTSC)
782 			tun->mode = VIDEO_MODE_NTSC;
783 		if (sid & V4L2_STD_SECAM)
784 			tun->mode = VIDEO_MODE_SECAM;
785 	}
786 
787 	if (tun2.capability & V4L2_TUNER_CAP_LOW)
788 		tun->flags |= VIDEO_TUNER_LOW;
789 	if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
790 		tun->flags |= VIDEO_TUNER_STEREO_ON;
791 	tun->signal = tun2.signal;
792 done:
793 	return err;
794 }
795 
v4l1_compat_select_tuner(struct video_tuner * tun,struct file * file,v4l2_kioctl drv)796 static noinline long v4l1_compat_select_tuner(
797 					struct video_tuner *tun,
798 					struct file *file,
799 					v4l2_kioctl drv)
800 {
801 	long err;
802 	struct v4l2_tuner	t;/*84 bytes on x86_64*/
803 	memset(&t, 0, sizeof(t));
804 
805 	t.index = tun->tuner;
806 
807 	err = drv(file, VIDIOC_S_INPUT, &t);
808 	if (err < 0)
809 		dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err);
810 	return err;
811 }
812 
v4l1_compat_get_frequency(unsigned long * freq,struct file * file,v4l2_kioctl drv)813 static noinline long v4l1_compat_get_frequency(
814 					unsigned long *freq,
815 					struct file *file,
816 					v4l2_kioctl drv)
817 {
818 	long err;
819 	struct v4l2_frequency   freq2;
820 	memset(&freq2, 0, sizeof(freq2));
821 
822 	freq2.tuner = 0;
823 	err = drv(file, VIDIOC_G_FREQUENCY, &freq2);
824 	if (err < 0)
825 		dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err);
826 	if (0 == err)
827 		*freq = freq2.frequency;
828 	return err;
829 }
830 
v4l1_compat_set_frequency(unsigned long * freq,struct file * file,v4l2_kioctl drv)831 static noinline long v4l1_compat_set_frequency(
832 					unsigned long *freq,
833 					struct file *file,
834 					v4l2_kioctl drv)
835 {
836 	long err;
837 	struct v4l2_frequency   freq2;
838 	memset(&freq2, 0, sizeof(freq2));
839 
840 	drv(file, VIDIOC_G_FREQUENCY, &freq2);
841 	freq2.frequency = *freq;
842 	err = drv(file, VIDIOC_S_FREQUENCY, &freq2);
843 	if (err < 0)
844 		dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err);
845 	return err;
846 }
847 
v4l1_compat_get_audio(struct video_audio * aud,struct file * file,v4l2_kioctl drv)848 static noinline long v4l1_compat_get_audio(
849 					struct video_audio *aud,
850 					struct file *file,
851 					v4l2_kioctl drv)
852 {
853 	long err;
854 	int i;
855 	struct v4l2_queryctrl	qctrl2;
856 	struct v4l2_audio	aud2;
857 	struct v4l2_tuner	tun2;
858 	memset(&aud2, 0, sizeof(aud2));
859 
860 	err = drv(file, VIDIOC_G_AUDIO, &aud2);
861 	if (err < 0) {
862 		dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err);
863 		goto done;
864 	}
865 	memcpy(aud->name, aud2.name,
866 	       min(sizeof(aud->name), sizeof(aud2.name)));
867 	aud->name[sizeof(aud->name) - 1] = 0;
868 	aud->audio = aud2.index;
869 	aud->flags = 0;
870 	i = get_v4l_control(file, V4L2_CID_AUDIO_VOLUME, drv);
871 	if (i >= 0) {
872 		aud->volume = i;
873 		aud->flags |= VIDEO_AUDIO_VOLUME;
874 	}
875 	i = get_v4l_control(file, V4L2_CID_AUDIO_BASS, drv);
876 	if (i >= 0) {
877 		aud->bass = i;
878 		aud->flags |= VIDEO_AUDIO_BASS;
879 	}
880 	i = get_v4l_control(file, V4L2_CID_AUDIO_TREBLE, drv);
881 	if (i >= 0) {
882 		aud->treble = i;
883 		aud->flags |= VIDEO_AUDIO_TREBLE;
884 	}
885 	i = get_v4l_control(file, V4L2_CID_AUDIO_BALANCE, drv);
886 	if (i >= 0) {
887 		aud->balance = i;
888 		aud->flags |= VIDEO_AUDIO_BALANCE;
889 	}
890 	i = get_v4l_control(file, V4L2_CID_AUDIO_MUTE, drv);
891 	if (i >= 0) {
892 		if (i)
893 			aud->flags |= VIDEO_AUDIO_MUTE;
894 		aud->flags |= VIDEO_AUDIO_MUTABLE;
895 	}
896 	aud->step = 1;
897 	qctrl2.id = V4L2_CID_AUDIO_VOLUME;
898 	if (drv(file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
899 	    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
900 		aud->step = qctrl2.step;
901 	aud->mode = 0;
902 
903 	memset(&tun2, 0, sizeof(tun2));
904 	err = drv(file, VIDIOC_G_TUNER, &tun2);
905 	if (err < 0) {
906 		dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err);
907 		err = 0;
908 		goto done;
909 	}
910 
911 	if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
912 		aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
913 	else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
914 		aud->mode = VIDEO_SOUND_STEREO;
915 	else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
916 		aud->mode = VIDEO_SOUND_MONO;
917 done:
918 	return err;
919 }
920 
v4l1_compat_set_audio(struct video_audio * aud,struct file * file,v4l2_kioctl drv)921 static noinline long v4l1_compat_set_audio(
922 					struct video_audio *aud,
923 					struct file *file,
924 					v4l2_kioctl drv)
925 {
926 	long err;
927 	struct v4l2_audio	aud2;
928 	struct v4l2_tuner	tun2;
929 
930 	memset(&aud2, 0, sizeof(aud2));
931 	memset(&tun2, 0, sizeof(tun2));
932 
933 	aud2.index = aud->audio;
934 	err = drv(file, VIDIOC_S_AUDIO, &aud2);
935 	if (err < 0) {
936 		dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err);
937 		goto done;
938 	}
939 
940 	set_v4l_control(file, V4L2_CID_AUDIO_VOLUME,
941 			aud->volume, drv);
942 	set_v4l_control(file, V4L2_CID_AUDIO_BASS,
943 			aud->bass, drv);
944 	set_v4l_control(file, V4L2_CID_AUDIO_TREBLE,
945 			aud->treble, drv);
946 	set_v4l_control(file, V4L2_CID_AUDIO_BALANCE,
947 			aud->balance, drv);
948 	set_v4l_control(file, V4L2_CID_AUDIO_MUTE,
949 			!!(aud->flags & VIDEO_AUDIO_MUTE), drv);
950 
951 	err = drv(file, VIDIOC_G_TUNER, &tun2);
952 	if (err < 0)
953 		dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err);
954 	if (err == 0) {
955 		switch (aud->mode) {
956 		default:
957 		case VIDEO_SOUND_MONO:
958 		case VIDEO_SOUND_LANG1:
959 			tun2.audmode = V4L2_TUNER_MODE_MONO;
960 			break;
961 		case VIDEO_SOUND_STEREO:
962 			tun2.audmode = V4L2_TUNER_MODE_STEREO;
963 			break;
964 		case VIDEO_SOUND_LANG2:
965 			tun2.audmode = V4L2_TUNER_MODE_LANG2;
966 			break;
967 		}
968 		err = drv(file, VIDIOC_S_TUNER, &tun2);
969 		if (err < 0)
970 			dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err);
971 	}
972 	err = 0;
973 done:
974 	return err;
975 }
976 
v4l1_compat_capture_frame(struct video_mmap * mm,struct file * file,v4l2_kioctl drv)977 static noinline long v4l1_compat_capture_frame(
978 					struct video_mmap *mm,
979 					struct file *file,
980 					v4l2_kioctl drv)
981 {
982 	long err;
983 	enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
984 	struct v4l2_buffer	buf;
985 	struct v4l2_format	*fmt;
986 
987 	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
988 	if (!fmt) {
989 		err = -ENOMEM;
990 		return err;
991 	}
992 	memset(&buf, 0, sizeof(buf));
993 
994 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
995 	err = drv(file, VIDIOC_G_FMT, fmt);
996 	if (err < 0) {
997 		dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err);
998 		goto done;
999 	}
1000 	if (mm->width   != fmt->fmt.pix.width  ||
1001 	    mm->height  != fmt->fmt.pix.height ||
1002 	    palette_to_pixelformat(mm->format) !=
1003 	    fmt->fmt.pix.pixelformat) {
1004 		/* New capture format...  */
1005 		fmt->fmt.pix.width = mm->width;
1006 		fmt->fmt.pix.height = mm->height;
1007 		fmt->fmt.pix.pixelformat =
1008 			palette_to_pixelformat(mm->format);
1009 		fmt->fmt.pix.field = V4L2_FIELD_ANY;
1010 		fmt->fmt.pix.bytesperline = 0;
1011 		err = drv(file, VIDIOC_S_FMT, fmt);
1012 		if (err < 0) {
1013 			dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err);
1014 			goto done;
1015 		}
1016 	}
1017 	buf.index = mm->frame;
1018 	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1019 	err = drv(file, VIDIOC_QUERYBUF, &buf);
1020 	if (err < 0) {
1021 		dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err);
1022 		goto done;
1023 	}
1024 	err = drv(file, VIDIOC_QBUF, &buf);
1025 	if (err < 0) {
1026 		dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err);
1027 		goto done;
1028 	}
1029 	err = drv(file, VIDIOC_STREAMON, &captype);
1030 	if (err < 0)
1031 		dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err);
1032 done:
1033 	kfree(fmt);
1034 	return err;
1035 }
1036 
v4l1_compat_sync(int * i,struct file * file,v4l2_kioctl drv)1037 static noinline long v4l1_compat_sync(
1038 				int *i,
1039 				struct file *file,
1040 				v4l2_kioctl drv)
1041 {
1042 	long err;
1043 	enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1044 	struct v4l2_buffer buf;
1045 	struct poll_wqueues *pwq;
1046 
1047 	memset(&buf, 0, sizeof(buf));
1048 	buf.index = *i;
1049 	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1050 	err = drv(file, VIDIOC_QUERYBUF, &buf);
1051 	if (err < 0) {
1052 		/*  No such buffer */
1053 		dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
1054 		goto done;
1055 	}
1056 	if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) {
1057 		/* Buffer is not mapped  */
1058 		err = -EINVAL;
1059 		goto done;
1060 	}
1061 
1062 	/* make sure capture actually runs so we don't block forever */
1063 	err = drv(file, VIDIOC_STREAMON, &captype);
1064 	if (err < 0) {
1065 		dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err);
1066 		goto done;
1067 	}
1068 
1069 	pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
1070 	/*  Loop as long as the buffer is queued, but not done  */
1071 	while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
1072 						== V4L2_BUF_FLAG_QUEUED) {
1073 		err = poll_one(file, pwq);
1074 		if (err < 0 ||	/* error or sleep was interrupted  */
1075 		    err == 0)	/* timeout? Shouldn't occur.  */
1076 			break;
1077 		err = drv(file, VIDIOC_QUERYBUF, &buf);
1078 		if (err < 0)
1079 			dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
1080 	}
1081 	kfree(pwq);
1082 	if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
1083 		goto done;
1084 	do {
1085 		err = drv(file, VIDIOC_DQBUF, &buf);
1086 		if (err < 0)
1087 			dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err);
1088 	} while (err == 0 && buf.index != *i);
1089 done:
1090 	return err;
1091 }
1092 
v4l1_compat_get_vbi_format(struct vbi_format * fmt,struct file * file,v4l2_kioctl drv)1093 static noinline long v4l1_compat_get_vbi_format(
1094 				struct vbi_format *fmt,
1095 				struct file *file,
1096 				v4l2_kioctl drv)
1097 {
1098 	long err;
1099 	struct v4l2_format *fmt2;
1100 
1101 	fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1102 	if (!fmt2) {
1103 		err = -ENOMEM;
1104 		return err;
1105 	}
1106 	fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1107 
1108 	err = drv(file, VIDIOC_G_FMT, fmt2);
1109 	if (err < 0) {
1110 		dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err);
1111 		goto done;
1112 	}
1113 	if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
1114 		err = -EINVAL;
1115 		goto done;
1116 	}
1117 	memset(fmt, 0, sizeof(*fmt));
1118 	fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
1119 	fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
1120 	fmt->sample_format    = VIDEO_PALETTE_RAW;
1121 	fmt->start[0]         = fmt2->fmt.vbi.start[0];
1122 	fmt->count[0]         = fmt2->fmt.vbi.count[0];
1123 	fmt->start[1]         = fmt2->fmt.vbi.start[1];
1124 	fmt->count[1]         = fmt2->fmt.vbi.count[1];
1125 	fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
1126 done:
1127 	kfree(fmt2);
1128 	return err;
1129 }
1130 
v4l1_compat_set_vbi_format(struct vbi_format * fmt,struct file * file,v4l2_kioctl drv)1131 static noinline long v4l1_compat_set_vbi_format(
1132 				struct vbi_format *fmt,
1133 				struct file *file,
1134 				v4l2_kioctl drv)
1135 {
1136 	long err;
1137 	struct v4l2_format	*fmt2 = NULL;
1138 
1139 	if (VIDEO_PALETTE_RAW != fmt->sample_format) {
1140 		err = -EINVAL;
1141 		return err;
1142 	}
1143 
1144 	fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1145 	if (!fmt2) {
1146 		err = -ENOMEM;
1147 		return err;
1148 	}
1149 	fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1150 	fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
1151 	fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
1152 	fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
1153 	fmt2->fmt.vbi.start[0]         = fmt->start[0];
1154 	fmt2->fmt.vbi.count[0]         = fmt->count[0];
1155 	fmt2->fmt.vbi.start[1]         = fmt->start[1];
1156 	fmt2->fmt.vbi.count[1]         = fmt->count[1];
1157 	fmt2->fmt.vbi.flags            = fmt->flags;
1158 	err = drv(file, VIDIOC_TRY_FMT, fmt2);
1159 	if (err < 0) {
1160 		dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err);
1161 		goto done;
1162 	}
1163 
1164 	if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1165 	    fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
1166 	    fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
1167 	    fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
1168 	    fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
1169 	    fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
1170 	    fmt2->fmt.vbi.count[1]         != fmt->count[1]         ||
1171 	    fmt2->fmt.vbi.flags            != fmt->flags) {
1172 		err = -EINVAL;
1173 		goto done;
1174 	}
1175 	err = drv(file, VIDIOC_S_FMT, fmt2);
1176 	if (err < 0)
1177 		dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err);
1178 done:
1179 	kfree(fmt2);
1180 	return err;
1181 }
1182 
1183 /*
1184  *	This function is exported.
1185  */
1186 long
v4l_compat_translate_ioctl(struct file * file,int cmd,void * arg,v4l2_kioctl drv)1187 v4l_compat_translate_ioctl(struct file		*file,
1188 			   int			cmd,
1189 			   void			*arg,
1190 			   v4l2_kioctl          drv)
1191 {
1192 	long err;
1193 
1194 	switch (cmd) {
1195 	case VIDIOCGCAP:	/* capability */
1196 		err = v4l1_compat_get_capabilities(arg, file, drv);
1197 		break;
1198 	case VIDIOCGFBUF: /*  get frame buffer  */
1199 		err = v4l1_compat_get_frame_buffer(arg, file, drv);
1200 		break;
1201 	case VIDIOCSFBUF: /*  set frame buffer  */
1202 		err = v4l1_compat_set_frame_buffer(arg, file, drv);
1203 		break;
1204 	case VIDIOCGWIN: /*  get window or capture dimensions  */
1205 		err = v4l1_compat_get_win_cap_dimensions(arg, file, drv);
1206 		break;
1207 	case VIDIOCSWIN: /*  set window and/or capture dimensions  */
1208 		err = v4l1_compat_set_win_cap_dimensions(arg, file, drv);
1209 		break;
1210 	case VIDIOCCAPTURE: /*  turn on/off preview  */
1211 		err = v4l1_compat_turn_preview_on_off(arg, file, drv);
1212 		break;
1213 	case VIDIOCGCHAN: /*  get input information  */
1214 		err = v4l1_compat_get_input_info(arg, file, drv);
1215 		break;
1216 	case VIDIOCSCHAN: /*  set input  */
1217 		err = v4l1_compat_set_input(arg, file, drv);
1218 		break;
1219 	case VIDIOCGPICT: /*  get tone controls & partial capture format  */
1220 		err = v4l1_compat_get_picture(arg, file, drv);
1221 		break;
1222 	case VIDIOCSPICT: /*  set tone controls & partial capture format  */
1223 		err = v4l1_compat_set_picture(arg, file, drv);
1224 		break;
1225 	case VIDIOCGTUNER: /*  get tuner information  */
1226 		err = v4l1_compat_get_tuner(arg, file, drv);
1227 		break;
1228 	case VIDIOCSTUNER: /*  select a tuner input  */
1229 		err = v4l1_compat_select_tuner(arg, file, drv);
1230 		break;
1231 	case VIDIOCGFREQ: /*  get frequency  */
1232 		err = v4l1_compat_get_frequency(arg, file, drv);
1233 		break;
1234 	case VIDIOCSFREQ: /*  set frequency  */
1235 		err = v4l1_compat_set_frequency(arg, file, drv);
1236 		break;
1237 	case VIDIOCGAUDIO: /*  get audio properties/controls  */
1238 		err = v4l1_compat_get_audio(arg, file, drv);
1239 		break;
1240 	case VIDIOCSAUDIO: /*  set audio controls  */
1241 		err = v4l1_compat_set_audio(arg, file, drv);
1242 		break;
1243 	case VIDIOCMCAPTURE: /*  capture a frame  */
1244 		err = v4l1_compat_capture_frame(arg, file, drv);
1245 		break;
1246 	case VIDIOCSYNC: /*  wait for a frame  */
1247 		err = v4l1_compat_sync(arg, file, drv);
1248 		break;
1249 	case VIDIOCGVBIFMT: /* query VBI data capture format */
1250 		err = v4l1_compat_get_vbi_format(arg, file, drv);
1251 		break;
1252 	case VIDIOCSVBIFMT:
1253 		err = v4l1_compat_set_vbi_format(arg, file, drv);
1254 		break;
1255 	default:
1256 		err = -ENOIOCTLCMD;
1257 		break;
1258 	}
1259 
1260 	return err;
1261 }
1262 EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1263 
1264 /*
1265  * Local variables:
1266  * c-basic-offset: 8
1267  * End:
1268  */
1269