15bc3cb74SMauro Carvalho Chehab /*
25bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
35bc3cb74SMauro Carvalho Chehab  *
45bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
55bc3cb74SMauro Carvalho Chehab  *
65bc3cb74SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or
75bc3cb74SMauro Carvalho Chehab  * modify it under the terms of the GNU General Public License
85bc3cb74SMauro Carvalho Chehab  * as published by the Free Software Foundation; either version
95bc3cb74SMauro Carvalho Chehab  * 2 of the License, or (at your option) any later version.
105bc3cb74SMauro Carvalho Chehab  *
115bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
125bc3cb74SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
135bc3cb74SMauro Carvalho Chehab  */
145bc3cb74SMauro Carvalho Chehab 
155bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
185bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
195bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
205bc3cb74SMauro Carvalho Chehab 
215bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
225bc3cb74SMauro Carvalho Chehab 
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
29c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
305bc3cb74SMauro Carvalho Chehab 
31aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
32aa32f4c0SHans Verkuil 
335bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
345bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
355bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
365bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
375bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
385bc3cb74SMauro Carvalho Chehab 
3973f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4073f35418SHans Verkuil 
415bc3cb74SMauro Carvalho Chehab struct std_descr {
425bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
435bc3cb74SMauro Carvalho Chehab 	const char *descr;
445bc3cb74SMauro Carvalho Chehab };
455bc3cb74SMauro Carvalho Chehab 
465bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
475bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC, 	"NTSC"      },
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL, 	"PAL"       },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B, 	"PAL-B"     },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G, 	"PAL-G"     },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H, 	"PAL-H"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I, 	"PAL-I"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D, 	"PAL-D"     },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K, 	"PAL-K"     },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M, 	"PAL-M"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N, 	"PAL-N"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60, 	"PAL-60"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM, 	"SECAM"     },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
775bc3cb74SMauro Carvalho Chehab 	{ 0, 			"Unknown"   }
785bc3cb74SMauro Carvalho Chehab };
795bc3cb74SMauro Carvalho Chehab 
805bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
815bc3cb74SMauro Carvalho Chehab  */
825bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
835bc3cb74SMauro Carvalho Chehab {
845bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
855bc3cb74SMauro Carvalho Chehab 	int i;
865bc3cb74SMauro Carvalho Chehab 
875bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
885bc3cb74SMauro Carvalho Chehab 	   64 bit comparations. So, on that architecture, with some gcc
895bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
905bc3cb74SMauro Carvalho Chehab 	 */
915bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
925bc3cb74SMauro Carvalho Chehab 
935bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
945bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
955bc3cb74SMauro Carvalho Chehab 			break;
965bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
975bc3cb74SMauro Carvalho Chehab }
985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
995bc3cb74SMauro Carvalho Chehab 
1005bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1015bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1025bc3cb74SMauro Carvalho Chehab {
1035bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1045bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1065bc3cb74SMauro Carvalho Chehab 	} else {
1075bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1095bc3cb74SMauro Carvalho Chehab 	}
1105bc3cb74SMauro Carvalho Chehab }
1115bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1125bc3cb74SMauro Carvalho Chehab 
1135bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1145bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1155bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1165bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1175bc3cb74SMauro Carvalho Chehab {
1185bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1195bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1205bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
1215bc3cb74SMauro Carvalho Chehab 	strlcpy(vs->name, name, sizeof(vs->name));
1225bc3cb74SMauro Carvalho Chehab 	return 0;
1235bc3cb74SMauro Carvalho Chehab }
1245bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1255bc3cb74SMauro Carvalho Chehab 
1265bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1275bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1285bc3cb74SMauro Carvalho Chehab 
1295bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1305bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1315bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1325bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1335bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1345bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1355bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1365bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1375bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1385bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1395bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1405bc3cb74SMauro Carvalho Chehab };
1415bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1425bc3cb74SMauro Carvalho Chehab 
1435bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
144839aa56dSHans Verkuil 	[0]				   = "0",
1455bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1465bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1475bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1485bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1495bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1505bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1515bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1525bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1535bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1545bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1556f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1565bc3cb74SMauro Carvalho Chehab };
1575bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1585bc3cb74SMauro Carvalho Chehab 
1595bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1605bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
1615bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
1625bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
163051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
1645bc3cb74SMauro Carvalho Chehab };
1655bc3cb74SMauro Carvalho Chehab 
166d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
1675bc3cb74SMauro Carvalho Chehab 
1685bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
1695bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
1705bc3cb74SMauro Carvalho Chehab 
1715bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
1725bc3cb74SMauro Carvalho Chehab {
1735bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
1745bc3cb74SMauro Carvalho Chehab 
17527d5a87cSHans Verkuil 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, "
1765bc3cb74SMauro Carvalho Chehab 		"capabilities=0x%08x, device_caps=0x%08x\n",
17727d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
17827d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
17927d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
1805bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
1815bc3cb74SMauro Carvalho Chehab }
1825bc3cb74SMauro Carvalho Chehab 
1835bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
1845bc3cb74SMauro Carvalho Chehab {
1855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
1865bc3cb74SMauro Carvalho Chehab 
18727d5a87cSHans Verkuil 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, "
1885bc3cb74SMauro Carvalho Chehab 		"std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
18927d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
19027d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
19127d5a87cSHans Verkuil 		p->capabilities);
1925bc3cb74SMauro Carvalho Chehab }
1935bc3cb74SMauro Carvalho Chehab 
1945bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
1955bc3cb74SMauro Carvalho Chehab {
1965bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
1975bc3cb74SMauro Carvalho Chehab 
19827d5a87cSHans Verkuil 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, "
1995bc3cb74SMauro Carvalho Chehab 		"modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
20027d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
20127d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2025bc3cb74SMauro Carvalho Chehab }
2035bc3cb74SMauro Carvalho Chehab 
2045bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2055bc3cb74SMauro Carvalho Chehab {
2065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2075bc3cb74SMauro Carvalho Chehab 
2085bc3cb74SMauro Carvalho Chehab 	if (write_only)
2095bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2105bc3cb74SMauro Carvalho Chehab 	else
21127d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
21227d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
21327d5a87cSHans Verkuil 			p->capability, p->mode);
2145bc3cb74SMauro Carvalho Chehab }
2155bc3cb74SMauro Carvalho Chehab 
2165bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2175bc3cb74SMauro Carvalho Chehab {
2185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2195bc3cb74SMauro Carvalho Chehab 
2205bc3cb74SMauro Carvalho Chehab 	if (write_only)
2215bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2225bc3cb74SMauro Carvalho Chehab 	else
22327d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
22427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
22527d5a87cSHans Verkuil 			p->capability, p->mode);
2265bc3cb74SMauro Carvalho Chehab }
2275bc3cb74SMauro Carvalho Chehab 
2285bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2295bc3cb74SMauro Carvalho Chehab {
2305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2315bc3cb74SMauro Carvalho Chehab 
23227d5a87cSHans Verkuil 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n",
2335bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
2345bc3cb74SMauro Carvalho Chehab 		p->flags, (p->pixelformat & 0xff),
2355bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >>  8) & 0xff,
2365bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 16) & 0xff,
2375bc3cb74SMauro Carvalho Chehab 		(p->pixelformat >> 24) & 0xff,
23827d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2395bc3cb74SMauro Carvalho Chehab }
2405bc3cb74SMauro Carvalho Chehab 
2415bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2425bc3cb74SMauro Carvalho Chehab {
2435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2465bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
24987185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
2505bc3cb74SMauro Carvalho Chehab 	unsigned i;
2515bc3cb74SMauro Carvalho Chehab 
2525bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2535bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2555bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2565bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
2575bc3cb74SMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, "
2585bc3cb74SMauro Carvalho Chehab 			"pixelformat=%c%c%c%c, field=%s, "
259c96fd46aSLaurent Pinchart 			"bytesperline=%u, sizeimage=%u, colorspace=%d, "
26074fdcb2eSHans Verkuil 			"flags=0x%x, ycbcr_enc=%u, quantization=%u, "
26174fdcb2eSHans Verkuil 			"xfer_func=%u\n",
2625bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
2635bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
2645bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
2655bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
2665bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
2675bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2685bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
269736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
27074fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2715bc3cb74SMauro Carvalho Chehab 		break;
2725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2735bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2745bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
2755bc3cb74SMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, "
2765bc3cb74SMauro Carvalho Chehab 			"format=%c%c%c%c, field=%s, "
2771e8faa59SHans Verkuil 			"colorspace=%d, num_planes=%u, flags=0x%x, "
27874fdcb2eSHans Verkuil 			"ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
2795bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
2805bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
2815bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
2825bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
2835bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
2845bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
285736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
28674fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
2875bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < mp->num_planes; i++)
2885bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
2895bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
2905bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
2915bc3cb74SMauro Carvalho Chehab 		break;
2925bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
2945bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
295560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
296560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
297560dde24SHans Verkuil 		 * pointer. */
298560dde24SHans Verkuil 		pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n",
299560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3005bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
301560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
302560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3035bc3cb74SMauro Carvalho Chehab 		break;
3045bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3065bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
3075bc3cb74SMauro Carvalho Chehab 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, "
3085bc3cb74SMauro Carvalho Chehab 			"sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
3095bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3105bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3115bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3125bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3135bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3145bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3155bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3165bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3175bc3cb74SMauro Carvalho Chehab 		break;
3185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3195bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3205bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3215bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3225bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3235bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3245bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3255bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3265bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3275bc3cb74SMauro Carvalho Chehab 		break;
328582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
329582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
330582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
331582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
332582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
333582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
334582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
335582c52cbSAntti Palosaari 		break;
3365bc3cb74SMauro Carvalho Chehab 	}
3375bc3cb74SMauro Carvalho Chehab }
3385bc3cb74SMauro Carvalho Chehab 
3395bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3405bc3cb74SMauro Carvalho Chehab {
3415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3425bc3cb74SMauro Carvalho Chehab 
3435bc3cb74SMauro Carvalho Chehab 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, "
3445bc3cb74SMauro Carvalho Chehab 		"height=%u, pixelformat=%c%c%c%c, "
345560dde24SHans Verkuil 		"bytesperline=%u, sizeimage=%u, colorspace=%d\n",
3465bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3475bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3485bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3495bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3505bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3515bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3525bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3535bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3545bc3cb74SMauro Carvalho Chehab }
3555bc3cb74SMauro Carvalho Chehab 
3565bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3575bc3cb74SMauro Carvalho Chehab {
3585bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3595bc3cb74SMauro Carvalho Chehab }
3605bc3cb74SMauro Carvalho Chehab 
3615bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3625bc3cb74SMauro Carvalho Chehab {
3635bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3645bc3cb74SMauro Carvalho Chehab 
3655bc3cb74SMauro Carvalho Chehab 	if (write_only)
366560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3675bc3cb74SMauro Carvalho Chehab 	else
36827d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, "
3695bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
37027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3715bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3725bc3cb74SMauro Carvalho Chehab }
3735bc3cb74SMauro Carvalho Chehab 
3745bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3755bc3cb74SMauro Carvalho Chehab {
3765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3775bc3cb74SMauro Carvalho Chehab 
3785bc3cb74SMauro Carvalho Chehab 	if (write_only)
3795bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3805bc3cb74SMauro Carvalho Chehab 	else
38127d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, "
3825bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, signal=%u, afc=%d, "
3835bc3cb74SMauro Carvalho Chehab 			"rxsubchans=0x%x, audmode=%u\n",
38427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3855bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3865bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3875bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3885bc3cb74SMauro Carvalho Chehab }
3895bc3cb74SMauro Carvalho Chehab 
3905bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3915bc3cb74SMauro Carvalho Chehab {
3925bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3935bc3cb74SMauro Carvalho Chehab 
3945bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
3955bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
3965bc3cb74SMauro Carvalho Chehab }
3975bc3cb74SMauro Carvalho Chehab 
3985bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
3995bc3cb74SMauro Carvalho Chehab {
4005bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4015bc3cb74SMauro Carvalho Chehab 
40227d5a87cSHans Verkuil 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, "
4035bc3cb74SMauro Carvalho Chehab 		"framelines=%u\n", p->index,
40427d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4055bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4065bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4075bc3cb74SMauro Carvalho Chehab 		p->framelines);
4085bc3cb74SMauro Carvalho Chehab }
4095bc3cb74SMauro Carvalho Chehab 
4105bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4115bc3cb74SMauro Carvalho Chehab {
4125bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4135bc3cb74SMauro Carvalho Chehab }
4145bc3cb74SMauro Carvalho Chehab 
4155bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4165bc3cb74SMauro Carvalho Chehab {
4175bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4185bc3cb74SMauro Carvalho Chehab 
41979e8c7beSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
42079e8c7beSMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u\n",
42179e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
42279e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4235bc3cb74SMauro Carvalho Chehab }
4245bc3cb74SMauro Carvalho Chehab 
4255bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4265bc3cb74SMauro Carvalho Chehab {
4275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4285bc3cb74SMauro Carvalho Chehab 
4295bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4305bc3cb74SMauro Carvalho Chehab 		p->count,
4315bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4325bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4335bc3cb74SMauro Carvalho Chehab }
4345bc3cb74SMauro Carvalho Chehab 
4355bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4365bc3cb74SMauro Carvalho Chehab {
4375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4395bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4405bc3cb74SMauro Carvalho Chehab 	int i;
4415bc3cb74SMauro Carvalho Chehab 
4425bc3cb74SMauro Carvalho Chehab 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, "
4435bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, field=%s, sequence=%d, memory=%s",
4445bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4455bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4465bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4475bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4485bc3cb74SMauro Carvalho Chehab 			p->index,
4495bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names),
4505bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4515bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4525bc3cb74SMauro Carvalho Chehab 
4535bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4545bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4555bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4565bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4575bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
458560dde24SHans Verkuil 				"plane %d: bytesused=%d, data_offset=0x%08x, "
4595bc3cb74SMauro Carvalho Chehab 				"offset/userptr=0x%lx, length=%d\n",
4605bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4615bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4625bc3cb74SMauro Carvalho Chehab 		}
4635bc3cb74SMauro Carvalho Chehab 	} else {
464560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4655bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4665bc3cb74SMauro Carvalho Chehab 	}
4675bc3cb74SMauro Carvalho Chehab 
4685bc3cb74SMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, "
4695bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, frames=%d, userbits=0x%08x\n",
4705bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4715bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4725bc3cb74SMauro Carvalho Chehab }
4735bc3cb74SMauro Carvalho Chehab 
474b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
475b799d09aSTomasz Stanislawski {
476b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
477b799d09aSTomasz Stanislawski 
478b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
479b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
480b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
481b799d09aSTomasz Stanislawski }
482b799d09aSTomasz Stanislawski 
4835bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4845bc3cb74SMauro Carvalho Chehab {
4855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4865bc3cb74SMauro Carvalho Chehab 
4875bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
4885bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
4895bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
4905bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4915bc3cb74SMauro Carvalho Chehab }
4925bc3cb74SMauro Carvalho Chehab 
4935bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4945bc3cb74SMauro Carvalho Chehab {
4955bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4965bc3cb74SMauro Carvalho Chehab 
4975bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
4985bc3cb74SMauro Carvalho Chehab 
4995bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5005bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5015bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5025bc3cb74SMauro Carvalho Chehab 
5035bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, "
5045bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, readbuffers=%d\n",
5055bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5065bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5075bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5085bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5095bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5105bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5115bc3cb74SMauro Carvalho Chehab 
5125bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, "
5135bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, writebuffers=%d\n",
5145bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5155bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5165bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
517560dde24SHans Verkuil 	} else {
518560dde24SHans Verkuil 		pr_cont("\n");
5195bc3cb74SMauro Carvalho Chehab 	}
5205bc3cb74SMauro Carvalho Chehab }
5215bc3cb74SMauro Carvalho Chehab 
5225bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5235bc3cb74SMauro Carvalho Chehab {
5245bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5255bc3cb74SMauro Carvalho Chehab 
52627d5a87cSHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, "
5275bc3cb74SMauro Carvalho Chehab 		"step=%d, default=%d, flags=0x%08x\n",
52827d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5295bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5305bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5315bc3cb74SMauro Carvalho Chehab }
5325bc3cb74SMauro Carvalho Chehab 
533e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
534e6bee368SHans Verkuil {
535e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
536e6bee368SHans Verkuil 
537e6bee368SHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, "
538e6bee368SHans Verkuil 		"step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, "
5390176077aSHans Verkuil 		"nr_of_dims=%u, dims=%u,%u,%u,%u\n",
540e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
541e6bee368SHans Verkuil 			p->minimum, p->maximum,
542e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
543e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5440176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
545e6bee368SHans Verkuil }
546e6bee368SHans Verkuil 
5475bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5485bc3cb74SMauro Carvalho Chehab {
5495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5505bc3cb74SMauro Carvalho Chehab 
5515bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5525bc3cb74SMauro Carvalho Chehab }
5535bc3cb74SMauro Carvalho Chehab 
5545bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5555bc3cb74SMauro Carvalho Chehab {
5565bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5575bc3cb74SMauro Carvalho Chehab 
5585bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5595bc3cb74SMauro Carvalho Chehab }
5605bc3cb74SMauro Carvalho Chehab 
5615bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5625bc3cb74SMauro Carvalho Chehab {
5635bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5645bc3cb74SMauro Carvalho Chehab 	int i;
5655bc3cb74SMauro Carvalho Chehab 
5665bc3cb74SMauro Carvalho Chehab 	pr_cont("class=0x%x, count=%d, error_idx=%d",
5675bc3cb74SMauro Carvalho Chehab 			p->ctrl_class, p->count, p->error_idx);
5685bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
569017ab36aSHans Verkuil 		if (!p->controls[i].size)
5705bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
5715bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
5725bc3cb74SMauro Carvalho Chehab 		else
5735bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
5745bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
5755bc3cb74SMauro Carvalho Chehab 	}
5765bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5775bc3cb74SMauro Carvalho Chehab }
5785bc3cb74SMauro Carvalho Chehab 
5795bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5805bc3cb74SMauro Carvalho Chehab {
5815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5825bc3cb74SMauro Carvalho Chehab 
5835bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, "
584a112fbafSHans Verkuil 		"defrect wxh=%dx%d, x,y=%d,%d, "
5855bc3cb74SMauro Carvalho Chehab 		"pixelaspect %d/%d\n",
5865bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5875bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5885bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5895bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5905bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5915bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5925bc3cb74SMauro Carvalho Chehab }
5935bc3cb74SMauro Carvalho Chehab 
5945bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5955bc3cb74SMauro Carvalho Chehab {
5965bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
5975bc3cb74SMauro Carvalho Chehab 
5985bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
5995bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6005bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6015bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6025bc3cb74SMauro Carvalho Chehab }
6035bc3cb74SMauro Carvalho Chehab 
6045bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6055bc3cb74SMauro Carvalho Chehab {
6065bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6075bc3cb74SMauro Carvalho Chehab 
6085bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6095bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6105bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6115bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6125bc3cb74SMauro Carvalho Chehab }
6135bc3cb74SMauro Carvalho Chehab 
6145bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6155bc3cb74SMauro Carvalho Chehab {
6165bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6175bc3cb74SMauro Carvalho Chehab 
6185bc3cb74SMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, "
6195bc3cb74SMauro Carvalho Chehab 		"COM_len=%d, jpeg_markers=0x%x\n",
6205bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6215bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6225bc3cb74SMauro Carvalho Chehab }
6235bc3cb74SMauro Carvalho Chehab 
6245bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6255bc3cb74SMauro Carvalho Chehab {
6265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6275bc3cb74SMauro Carvalho Chehab 
6285bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6295bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6305bc3cb74SMauro Carvalho Chehab }
6315bc3cb74SMauro Carvalho Chehab 
6325bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6335bc3cb74SMauro Carvalho Chehab {
6345bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6355bc3cb74SMauro Carvalho Chehab 
6365bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6375bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6385bc3cb74SMauro Carvalho Chehab }
6395bc3cb74SMauro Carvalho Chehab 
6405bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6415bc3cb74SMauro Carvalho Chehab {
6425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6435bc3cb74SMauro Carvalho Chehab 
6445bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6455bc3cb74SMauro Carvalho Chehab 
6465bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6475bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6485bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6495bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6505bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6515bc3cb74SMauro Carvalho Chehab }
6525bc3cb74SMauro Carvalho Chehab 
65396b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65479b0c640SHans Verkuil {
65596b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65679b0c640SHans Verkuil 
65779b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6583eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
65979b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66079b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66179b0c640SHans Verkuil 	else
66279b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66379b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66479b0c640SHans Verkuil }
66579b0c640SHans Verkuil 
6665bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6675bc3cb74SMauro Carvalho Chehab {
6685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6695bc3cb74SMauro Carvalho Chehab 
6705bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6713eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67227d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67327d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6745bc3cb74SMauro Carvalho Chehab 	else
6755bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6765bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6775bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6785bc3cb74SMauro Carvalho Chehab }
6795bc3cb74SMauro Carvalho Chehab 
6805bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6815bc3cb74SMauro Carvalho Chehab {
6825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6835bc3cb74SMauro Carvalho Chehab 
6845bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6855bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6865bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, interlaced=%u, "
6875bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu, "
6885bc3cb74SMauro Carvalho Chehab 			"width=%u, height=%u, polarities=0x%x, "
6895bc3cb74SMauro Carvalho Chehab 			"hfrontporch=%u, hsync=%u, "
6905bc3cb74SMauro Carvalho Chehab 			"hbackporch=%u, vfrontporch=%u, "
6915bc3cb74SMauro Carvalho Chehab 			"vsync=%u, vbackporch=%u, "
6925bc3cb74SMauro Carvalho Chehab 			"il_vfrontporch=%u, il_vsync=%u, "
6935bc3cb74SMauro Carvalho Chehab 			"il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
6945bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6955bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6965bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6975bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6985bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6995bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
7005bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7015bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7025bc3cb74SMauro Carvalho Chehab 		break;
7035bc3cb74SMauro Carvalho Chehab 	default:
7045bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7055bc3cb74SMauro Carvalho Chehab 		break;
7065bc3cb74SMauro Carvalho Chehab 	}
7075bc3cb74SMauro Carvalho Chehab }
7085bc3cb74SMauro Carvalho Chehab 
7095bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7105bc3cb74SMauro Carvalho Chehab {
7115bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7125bc3cb74SMauro Carvalho Chehab 
7135bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7145bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7155bc3cb74SMauro Carvalho Chehab }
7165bc3cb74SMauro Carvalho Chehab 
7175bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7185bc3cb74SMauro Carvalho Chehab {
7195bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7205bc3cb74SMauro Carvalho Chehab 
7215bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7225bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7235bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, "
7245bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7255bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7265bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7275bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7285bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7295bc3cb74SMauro Carvalho Chehab 		break;
7305bc3cb74SMauro Carvalho Chehab 	default:
7315bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7325bc3cb74SMauro Carvalho Chehab 		break;
7335bc3cb74SMauro Carvalho Chehab 	}
7345bc3cb74SMauro Carvalho Chehab }
7355bc3cb74SMauro Carvalho Chehab 
7365bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7375bc3cb74SMauro Carvalho Chehab {
7385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7395bc3cb74SMauro Carvalho Chehab 
7405bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7415bc3cb74SMauro Carvalho Chehab 			p->index,
7425bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7435bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7445bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7455bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7465bc3cb74SMauro Carvalho Chehab 			p->type);
7475bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7485bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
749560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7505bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7515bc3cb74SMauro Carvalho Chehab 		break;
7525bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
753560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7545bc3cb74SMauro Carvalho Chehab 				p->stepwise.min_width,  p->stepwise.min_height,
7555bc3cb74SMauro Carvalho Chehab 				p->stepwise.step_width, p->stepwise.step_height,
7565bc3cb74SMauro Carvalho Chehab 				p->stepwise.max_width,  p->stepwise.max_height);
7575bc3cb74SMauro Carvalho Chehab 		break;
7585bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7595bc3cb74SMauro Carvalho Chehab 		/* fall through */
7605bc3cb74SMauro Carvalho Chehab 	default:
7615bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7625bc3cb74SMauro Carvalho Chehab 		break;
7635bc3cb74SMauro Carvalho Chehab 	}
7645bc3cb74SMauro Carvalho Chehab }
7655bc3cb74SMauro Carvalho Chehab 
7665bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7675bc3cb74SMauro Carvalho Chehab {
7685bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7695bc3cb74SMauro Carvalho Chehab 
7705bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7715bc3cb74SMauro Carvalho Chehab 			p->index,
7725bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7735bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7745bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7755bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7765bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
7775bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7785bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
779560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7805bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7815bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7825bc3cb74SMauro Carvalho Chehab 		break;
7835bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
784560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7855bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7865bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7875bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7885bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7895bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7905bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7915bc3cb74SMauro Carvalho Chehab 		break;
7925bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7935bc3cb74SMauro Carvalho Chehab 		/* fall through */
7945bc3cb74SMauro Carvalho Chehab 	default:
7955bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7965bc3cb74SMauro Carvalho Chehab 		break;
7975bc3cb74SMauro Carvalho Chehab 	}
7985bc3cb74SMauro Carvalho Chehab }
7995bc3cb74SMauro Carvalho Chehab 
8005bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
8015bc3cb74SMauro Carvalho Chehab {
8025bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
8035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
8045bc3cb74SMauro Carvalho Chehab 
8055bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, "
8065bc3cb74SMauro Carvalho Chehab 		"timestamp=%lu.%9.9lu\n",
8075bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
8085bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
8095bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8105bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
8115bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8125bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8135bc3cb74SMauro Carvalho Chehab 		break;
8145bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8155bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8165bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8175bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8185bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8195bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8205bc3cb74SMauro Carvalho Chehab 		else
8215bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8225bc3cb74SMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, "
8235bc3cb74SMauro Carvalho Chehab 			"default_value=%d\n",
8245bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8255bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8265bc3cb74SMauro Carvalho Chehab 		break;
8275bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8285bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8295bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8305bc3cb74SMauro Carvalho Chehab 		break;
8315bc3cb74SMauro Carvalho Chehab 	}
8325bc3cb74SMauro Carvalho Chehab }
8335bc3cb74SMauro Carvalho Chehab 
8345bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8355bc3cb74SMauro Carvalho Chehab {
8365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8375bc3cb74SMauro Carvalho Chehab 
8385bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8395bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8405bc3cb74SMauro Carvalho Chehab }
8415bc3cb74SMauro Carvalho Chehab 
8425bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8435bc3cb74SMauro Carvalho Chehab {
8445bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8455bc3cb74SMauro Carvalho Chehab 	int i;
8465bc3cb74SMauro Carvalho Chehab 
8475bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8485bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8495bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8505bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8515bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8525bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8535bc3cb74SMauro Carvalho Chehab }
8545bc3cb74SMauro Carvalho Chehab 
8555bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8565bc3cb74SMauro Carvalho Chehab {
8575bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8585bc3cb74SMauro Carvalho Chehab 
8595bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, "
8605bc3cb74SMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8615bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8625bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8635bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8645bc3cb74SMauro Carvalho Chehab }
8655bc3cb74SMauro Carvalho Chehab 
866dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
867dd519bb3SHans Verkuil {
868dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
869dd519bb3SHans Verkuil 
870dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
871dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
872dd519bb3SHans Verkuil }
873dd519bb3SHans Verkuil 
8745bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8755bc3cb74SMauro Carvalho Chehab {
8765bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8775bc3cb74SMauro Carvalho Chehab }
8785bc3cb74SMauro Carvalho Chehab 
8795bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8805bc3cb74SMauro Carvalho Chehab {
8815bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8825bc3cb74SMauro Carvalho Chehab }
8835bc3cb74SMauro Carvalho Chehab 
8845bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8855bc3cb74SMauro Carvalho Chehab {
8865bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8875bc3cb74SMauro Carvalho Chehab }
8885bc3cb74SMauro Carvalho Chehab 
8895bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
8905bc3cb74SMauro Carvalho Chehab {
8915bc3cb74SMauro Carvalho Chehab 	__u32 i;
8925bc3cb74SMauro Carvalho Chehab 
8935bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
8945bc3cb74SMauro Carvalho Chehab 	c->reserved[0] = c->reserved[1] = 0;
8955bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8965bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8975bc3cb74SMauro Carvalho Chehab 
8985bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
8995bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
9005bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
9015bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
9025bc3cb74SMauro Carvalho Chehab 	 */
9035bc3cb74SMauro Carvalho Chehab 	if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
9045bc3cb74SMauro Carvalho Chehab 		return 0;
9059b239b22SHans Verkuil 	if (c->ctrl_class == 0)
9069b239b22SHans Verkuil 		return 1;
9075bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9085bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9095bc3cb74SMauro Carvalho Chehab 		if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
9105bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
9115bc3cb74SMauro Carvalho Chehab 			return 0;
9125bc3cb74SMauro Carvalho Chehab 		}
9135bc3cb74SMauro Carvalho Chehab 	}
9145bc3cb74SMauro Carvalho Chehab 	return 1;
9155bc3cb74SMauro Carvalho Chehab }
9165bc3cb74SMauro Carvalho Chehab 
9174b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9185bc3cb74SMauro Carvalho Chehab {
9194b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9204b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
9214b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
9224b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
923582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
9244b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9254b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9264b20259fSHans Verkuil 
9275bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9285bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9295bc3cb74SMauro Carvalho Chehab 
9305bc3cb74SMauro Carvalho Chehab 	switch (type) {
9315bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
9324b20259fSHans Verkuil 		if (is_vid && is_rx &&
9334b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9345bc3cb74SMauro Carvalho Chehab 			return 0;
9355bc3cb74SMauro Carvalho Chehab 		break;
9365bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9374b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9385bc3cb74SMauro Carvalho Chehab 			return 0;
9395bc3cb74SMauro Carvalho Chehab 		break;
9405bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9414b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9425bc3cb74SMauro Carvalho Chehab 			return 0;
9435bc3cb74SMauro Carvalho Chehab 		break;
9445bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9454b20259fSHans Verkuil 		if (is_vid && is_tx &&
9464b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9475bc3cb74SMauro Carvalho Chehab 			return 0;
9485bc3cb74SMauro Carvalho Chehab 		break;
9495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9504b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9515bc3cb74SMauro Carvalho Chehab 			return 0;
9525bc3cb74SMauro Carvalho Chehab 		break;
9535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9544b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9555bc3cb74SMauro Carvalho Chehab 			return 0;
9565bc3cb74SMauro Carvalho Chehab 		break;
9575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9584b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9595bc3cb74SMauro Carvalho Chehab 			return 0;
9605bc3cb74SMauro Carvalho Chehab 		break;
9615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9624b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9635bc3cb74SMauro Carvalho Chehab 			return 0;
9645bc3cb74SMauro Carvalho Chehab 		break;
9655bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9664b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9675bc3cb74SMauro Carvalho Chehab 			return 0;
9685bc3cb74SMauro Carvalho Chehab 		break;
9695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9704b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9715bc3cb74SMauro Carvalho Chehab 			return 0;
9725bc3cb74SMauro Carvalho Chehab 		break;
973582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
974582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
975582c52cbSAntti Palosaari 			return 0;
976582c52cbSAntti Palosaari 		break;
977633c98e5SHans Verkuil 	default:
9785bc3cb74SMauro Carvalho Chehab 		break;
9795bc3cb74SMauro Carvalho Chehab 	}
9805bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9815bc3cb74SMauro Carvalho Chehab }
9825bc3cb74SMauro Carvalho Chehab 
983d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
984d52e2381SLaurent Pinchart {
985d52e2381SLaurent Pinchart 	unsigned int offset;
986d52e2381SLaurent Pinchart 
987d52e2381SLaurent Pinchart 	/*
988d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
989d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
990d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
991d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
992d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
993d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
994d52e2381SLaurent Pinchart 	 * isn't used by applications.
995d52e2381SLaurent Pinchart 	 */
996d52e2381SLaurent Pinchart 
997d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
998d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
999d52e2381SLaurent Pinchart 		return;
1000d52e2381SLaurent Pinchart 
1001d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1002d52e2381SLaurent Pinchart 		return;
1003d52e2381SLaurent Pinchart 
1004d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1005d52e2381SLaurent Pinchart 
1006d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1007d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1008d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1009d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1010d52e2381SLaurent Pinchart }
1011d52e2381SLaurent Pinchart 
10125bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10135bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10145bc3cb74SMauro Carvalho Chehab {
10155bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
1016d52e2381SLaurent Pinchart 	int ret;
10175bc3cb74SMauro Carvalho Chehab 
10185bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
1019d52e2381SLaurent Pinchart 
1020d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1021d52e2381SLaurent Pinchart 
1022d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1023454a4e72SHans Verkuil 	/*
1024454a4e72SHans Verkuil 	 * Drivers MUST fill in device_caps, so check for this and
1025454a4e72SHans Verkuil 	 * warn if it was forgotten.
1026454a4e72SHans Verkuil 	 */
10276d7570c4SLaura Abbott 	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
10286d7570c4SLaura Abbott 		!cap->device_caps, "Bad caps for driver %s, %x %x",
10296d7570c4SLaura Abbott 		cap->driver, cap->capabilities, cap->device_caps);
1030796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1031d52e2381SLaurent Pinchart 
1032d52e2381SLaurent Pinchart 	return ret;
10335bc3cb74SMauro Carvalho Chehab }
10345bc3cb74SMauro Carvalho Chehab 
10355bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10375bc3cb74SMauro Carvalho Chehab {
10385bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10395bc3cb74SMauro Carvalho Chehab }
10405bc3cb74SMauro Carvalho Chehab 
10415bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10435bc3cb74SMauro Carvalho Chehab {
10445bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10455bc3cb74SMauro Carvalho Chehab }
10465bc3cb74SMauro Carvalho Chehab 
10475bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10485bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10495bc3cb74SMauro Carvalho Chehab {
10505bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10515bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10525bc3cb74SMauro Carvalho Chehab 
10535bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
105459b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
10555bc3cb74SMauro Carvalho Chehab 	return 0;
10565bc3cb74SMauro Carvalho Chehab }
10575bc3cb74SMauro Carvalho Chehab 
10585bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
10595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10605bc3cb74SMauro Carvalho Chehab {
10615bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10625bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
10635bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10645bc3cb74SMauro Carvalho Chehab 
10655bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
10662438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
10672438e78aSHans Verkuil 		return -ENOTTY;
10685bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
106959b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
10705bc3cb74SMauro Carvalho Chehab }
10715bc3cb74SMauro Carvalho Chehab 
10725bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
10735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10745bc3cb74SMauro Carvalho Chehab {
107573f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10765bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
10775bc3cb74SMauro Carvalho Chehab 
10785bc3cb74SMauro Carvalho Chehab 	/*
107902fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10805bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10815bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10825bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
10835bc3cb74SMauro Carvalho Chehab 	 */
108473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
10855bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
10865bc3cb74SMauro Carvalho Chehab 
10875bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
10885bc3cb74SMauro Carvalho Chehab }
10895bc3cb74SMauro Carvalho Chehab 
10905bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
10915bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10925bc3cb74SMauro Carvalho Chehab {
109373f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10945bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
10955bc3cb74SMauro Carvalho Chehab 
10965bc3cb74SMauro Carvalho Chehab 	/*
109702fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10985bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10995bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11005bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11015bc3cb74SMauro Carvalho Chehab 	 */
110273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11035bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11045bc3cb74SMauro Carvalho Chehab 
11055bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
11065bc3cb74SMauro Carvalho Chehab }
11075bc3cb74SMauro Carvalho Chehab 
1108ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1109ba300204SHans Verkuil {
1110ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1111ba300204SHans Verkuil 	const char *descr = NULL;
1112ba300204SHans Verkuil 	u32 flags = 0;
1113ba300204SHans Verkuil 
1114ba300204SHans Verkuil 	/*
1115ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1116ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1117ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1118ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1119ba300204SHans Verkuil 	 *
1120ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1121ba300204SHans Verkuil 	 */
1122ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1123ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1124ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1125ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1126ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1127ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
1128ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1129ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1130ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
1131ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1132ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1133ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1134ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1135ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1136ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1137ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1138ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1139ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1140ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1141ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1142ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1143ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1144ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
1145ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1146ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1147ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1148ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1149ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1150ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
11512e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1152ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
1153ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1154ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1155ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1156ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1157ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1158ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1159ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1160ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1161ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1162ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YVU 4:2:2"; break;
1163ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1164ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1165ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1166ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1167ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
1168ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1169ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1170ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1171ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1172ba300204SHans Verkuil 	case V4L2_PIX_FMT_HM12:		descr = "YUV 4:2:0 (16x16 Macroblocks)"; break;
1173ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1174ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1175ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1176ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1177ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1178ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1179ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1180ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1181ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1182ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1183ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1184ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1185ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1186ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1187ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1188ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1189ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1190ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1191ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1192ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1193ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1194ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1195ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1196ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1197ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1198ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1199ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1200ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1201ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1202ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1203ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1204ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1205ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1206ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1207ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1208ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1209ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1210ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1211ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1212ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break;
121399b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1214ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1215ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1216ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1217ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1218ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1219ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1220ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
122148fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
122248fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1223ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1224ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1225ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1226ba300204SHans Verkuil 
1227ba300204SHans Verkuil 	default:
1228ba300204SHans Verkuil 		/* Compressed formats */
1229ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1230ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1231ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1232ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1233ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1234ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1235ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1236ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1237ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1238ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
1239ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1240ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1241ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1242ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
1243ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1244ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1245ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1246ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1247ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1248ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1249ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1250ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1251ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1252ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1253ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1254ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1255ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1256ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1257ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1258ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1259ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1260ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1261ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1262ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1263ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1264ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1265ba300204SHans Verkuil 		default:
1266ba300204SHans Verkuil 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1267ba300204SHans Verkuil 			if (fmt->description[0])
1268ba300204SHans Verkuil 				return;
1269ba300204SHans Verkuil 			flags = 0;
1270ba300204SHans Verkuil 			snprintf(fmt->description, sz, "%c%c%c%c%s",
1271ba300204SHans Verkuil 					(char)(fmt->pixelformat & 0x7f),
1272ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 8) & 0x7f),
1273ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 16) & 0x7f),
1274ba300204SHans Verkuil 					(char)((fmt->pixelformat >> 24) & 0x7f),
1275ba300204SHans Verkuil 					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1276ba300204SHans Verkuil 			break;
1277ba300204SHans Verkuil 		}
1278ba300204SHans Verkuil 	}
1279ba300204SHans Verkuil 
1280ba300204SHans Verkuil 	if (descr)
1281ba300204SHans Verkuil 		WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
1282ba300204SHans Verkuil 	fmt->flags = flags;
1283ba300204SHans Verkuil }
1284ba300204SHans Verkuil 
12855bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
12865bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
12875bc3cb74SMauro Carvalho Chehab {
12885bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
12894b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1290ce71bbc9SHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1291ce71bbc9SHans Verkuil 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
12924b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
12934b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1294ba300204SHans Verkuil 	int ret = -EINVAL;
12955bc3cb74SMauro Carvalho Chehab 
12965bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
12975bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1298ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap))
12995bc3cb74SMauro Carvalho Chehab 			break;
1300ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1301ba300204SHans Verkuil 		break;
13025bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1303ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
13045bc3cb74SMauro Carvalho Chehab 			break;
1305ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
1306ba300204SHans Verkuil 		break;
13075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1308ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
13095bc3cb74SMauro Carvalho Chehab 			break;
1310ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1311ba300204SHans Verkuil 		break;
13125bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1313ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
13145bc3cb74SMauro Carvalho Chehab 			break;
1315ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1316ba300204SHans Verkuil 		break;
13175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1318ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
13195bc3cb74SMauro Carvalho Chehab 			break;
1320ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1321ba300204SHans Verkuil 		break;
1322582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1323ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
1324582c52cbSAntti Palosaari 			break;
1325ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1326ba300204SHans Verkuil 		break;
13275bc3cb74SMauro Carvalho Chehab 	}
1328ba300204SHans Verkuil 	if (ret == 0)
1329ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1330ba300204SHans Verkuil 	return ret;
13315bc3cb74SMauro Carvalho Chehab }
13325bc3cb74SMauro Carvalho Chehab 
13335bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
13345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13355bc3cb74SMauro Carvalho Chehab {
13365bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
13374b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
13384b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1339582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
13404b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
13414b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1342d52e2381SLaurent Pinchart 	int ret;
1343d52e2381SLaurent Pinchart 
1344e5ce558aSHans Verkuil 	/*
1345e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1346e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1347e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1348e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1349e5ce558aSHans Verkuil 	 */
1350e5ce558aSHans Verkuil 	switch (p->type) {
1351e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1352e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
13534d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1354e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
13554d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1356e5ce558aSHans Verkuil 
1357e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1358e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1359e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1360e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1361e5ce558aSHans Verkuil 		break;
1362e5ce558aSHans Verkuil 	}
1363e5ce558aSHans Verkuil 	default:
1364e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1365e5ce558aSHans Verkuil 		break;
1366e5ce558aSHans Verkuil 	}
1367e5ce558aSHans Verkuil 
13685bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
13704b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
13715bc3cb74SMauro Carvalho Chehab 			break;
137248f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1373d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
137448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1375d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1376d52e2381SLaurent Pinchart 		return ret;
13775bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
13784b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
13795bc3cb74SMauro Carvalho Chehab 			break;
13805bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
13815bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
13824b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
13835bc3cb74SMauro Carvalho Chehab 			break;
13845bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
13854b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
13864b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
13874b20259fSHans Verkuil 			break;
13884b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
13894b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
13904b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
13914b20259fSHans Verkuil 			break;
13924b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
13935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
13944b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
13955bc3cb74SMauro Carvalho Chehab 			break;
139648f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1397d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
139848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1399d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1400d52e2381SLaurent Pinchart 		return ret;
14015bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
14024b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
14035bc3cb74SMauro Carvalho Chehab 			break;
14045bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
14055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
14064b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
14075bc3cb74SMauro Carvalho Chehab 			break;
14085bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
14095bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
14104b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
14115bc3cb74SMauro Carvalho Chehab 			break;
14125bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
14135bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
14144b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
14155bc3cb74SMauro Carvalho Chehab 			break;
14165bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1417582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1418582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
1419582c52cbSAntti Palosaari 			break;
1420582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
14215bc3cb74SMauro Carvalho Chehab 	}
14225bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
14235bc3cb74SMauro Carvalho Chehab }
14245bc3cb74SMauro Carvalho Chehab 
14255bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
14265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14275bc3cb74SMauro Carvalho Chehab {
14285bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
14294b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
14304b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1431582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
14324b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
14334b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
143448f2650aSHans Verkuil 	int ret;
14355bc3cb74SMauro Carvalho Chehab 
1436d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1437d52e2381SLaurent Pinchart 
14385bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14395bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
14404b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
14415bc3cb74SMauro Carvalho Chehab 			break;
14425bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
144348f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
144448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
144548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
144648f2650aSHans Verkuil 		return ret;
14475bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
14484b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
14495bc3cb74SMauro Carvalho Chehab 			break;
14505bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
14515bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
14525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14534b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
14545bc3cb74SMauro Carvalho Chehab 			break;
14555bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
14565bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
14574b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
14584b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
14594b20259fSHans Verkuil 			break;
14604b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
14614b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
14624b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
14634b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
14644b20259fSHans Verkuil 			break;
14654b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
14664b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
14675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
14684b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
14695bc3cb74SMauro Carvalho Chehab 			break;
14705bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
147148f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
147248f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
147348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
147448f2650aSHans Verkuil 		return ret;
14755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
14764b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
14775bc3cb74SMauro Carvalho Chehab 			break;
14785bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
14795bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
14805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
14814b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
14825bc3cb74SMauro Carvalho Chehab 			break;
14835bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
14845bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
14855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
14864b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
14875bc3cb74SMauro Carvalho Chehab 			break;
14885bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
14895bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
14905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
14914b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
14925bc3cb74SMauro Carvalho Chehab 			break;
14935bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
14945bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1495582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1496582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
1497582c52cbSAntti Palosaari 			break;
1498582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1499582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
15005bc3cb74SMauro Carvalho Chehab 	}
15015bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15025bc3cb74SMauro Carvalho Chehab }
15035bc3cb74SMauro Carvalho Chehab 
15045bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
15055bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15065bc3cb74SMauro Carvalho Chehab {
15075bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
15084b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
15094b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1510582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
15114b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
15124b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
151348f2650aSHans Verkuil 	int ret;
15145bc3cb74SMauro Carvalho Chehab 
1515d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1516d52e2381SLaurent Pinchart 
15175bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
15194b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
15205bc3cb74SMauro Carvalho Chehab 			break;
15215bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
152248f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
152348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
152448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
152548f2650aSHans Verkuil 		return ret;
15265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15274b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
15285bc3cb74SMauro Carvalho Chehab 			break;
15295bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
15305bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
15315bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15324b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
15335bc3cb74SMauro Carvalho Chehab 			break;
15345bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15355bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
15364b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
15374b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
15384b20259fSHans Verkuil 			break;
15394b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15404b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
15414b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
15424b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
15434b20259fSHans Verkuil 			break;
15444b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15454b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
15465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15474b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
15485bc3cb74SMauro Carvalho Chehab 			break;
15495bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
155048f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
155148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
155248f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
155348f2650aSHans Verkuil 		return ret;
15545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15554b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
15565bc3cb74SMauro Carvalho Chehab 			break;
15575bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
15585bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
15595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15604b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
15615bc3cb74SMauro Carvalho Chehab 			break;
15625bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
15635bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
15645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15654b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
15665bc3cb74SMauro Carvalho Chehab 			break;
15675bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
15685bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
15695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15704b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
15715bc3cb74SMauro Carvalho Chehab 			break;
15725bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
15735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1574582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1575582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
1576582c52cbSAntti Palosaari 			break;
1577582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1578582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
15795bc3cb74SMauro Carvalho Chehab 	}
15805bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
15815bc3cb74SMauro Carvalho Chehab }
15825bc3cb74SMauro Carvalho Chehab 
15835bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
15845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15855bc3cb74SMauro Carvalho Chehab {
15865bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
15875bc3cb74SMauro Carvalho Chehab }
15885bc3cb74SMauro Carvalho Chehab 
15895bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
15905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15915bc3cb74SMauro Carvalho Chehab {
15925bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
15935bc3cb74SMauro Carvalho Chehab }
15945bc3cb74SMauro Carvalho Chehab 
15955bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
15965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15975bc3cb74SMauro Carvalho Chehab {
15985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
15995bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
16005bc3cb74SMauro Carvalho Chehab 	int err;
16015bc3cb74SMauro Carvalho Chehab 
16025bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16035bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16045bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
16055bc3cb74SMauro Carvalho Chehab 	if (!err)
16065bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16075bc3cb74SMauro Carvalho Chehab 	return err;
16085bc3cb74SMauro Carvalho Chehab }
16095bc3cb74SMauro Carvalho Chehab 
16105bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
16115bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16125bc3cb74SMauro Carvalho Chehab {
16135bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16145bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
16155bc3cb74SMauro Carvalho Chehab 
16165bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16175bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16185bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
16195bc3cb74SMauro Carvalho Chehab }
16205bc3cb74SMauro Carvalho Chehab 
16215bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
16225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16235bc3cb74SMauro Carvalho Chehab {
16245bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
16255bc3cb74SMauro Carvalho Chehab 	int err;
16265bc3cb74SMauro Carvalho Chehab 
16275bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
16285bc3cb74SMauro Carvalho Chehab 	if (!err)
16295bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
16305bc3cb74SMauro Carvalho Chehab 	return err;
16315bc3cb74SMauro Carvalho Chehab }
16325bc3cb74SMauro Carvalho Chehab 
16335bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
16345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16355bc3cb74SMauro Carvalho Chehab {
16365bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16375bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
16385bc3cb74SMauro Carvalho Chehab 
163984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
164084099a28SAntti Palosaari 		p->type = V4L2_TUNER_ADC;
164184099a28SAntti Palosaari 	else
16425bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16435bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
16445bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
16455bc3cb74SMauro Carvalho Chehab }
16465bc3cb74SMauro Carvalho Chehab 
16475bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
16485bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16495bc3cb74SMauro Carvalho Chehab {
16505bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1651b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
16525bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
16535bc3cb74SMauro Carvalho Chehab 
165484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
165584099a28SAntti Palosaari 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
165684099a28SAntti Palosaari 			return -EINVAL;
165784099a28SAntti Palosaari 	} else {
16585bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
16595bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
166084099a28SAntti Palosaari 		if (type != p->type)
16615bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
166284099a28SAntti Palosaari 	}
16635bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
16645bc3cb74SMauro Carvalho Chehab }
16655bc3cb74SMauro Carvalho Chehab 
16665bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
16675bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16685bc3cb74SMauro Carvalho Chehab {
16695bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16705bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
16715bc3cb74SMauro Carvalho Chehab 	v4l2_std_id id = vfd->tvnorms, curr_id = 0;
16725bc3cb74SMauro Carvalho Chehab 	unsigned int index = p->index, i, j = 0;
16735bc3cb74SMauro Carvalho Chehab 	const char *descr = "";
16745bc3cb74SMauro Carvalho Chehab 
1675a5338190SHans Verkuil 	/* Return -ENODATA if the tvnorms for the current input
1676a5338190SHans Verkuil 	   or output is 0, meaning that it doesn't support this API. */
1677a5338190SHans Verkuil 	if (id == 0)
1678a5338190SHans Verkuil 		return -ENODATA;
1679a5338190SHans Verkuil 
16805bc3cb74SMauro Carvalho Chehab 	/* Return norm array in a canonical way */
16815bc3cb74SMauro Carvalho Chehab 	for (i = 0; i <= index && id; i++) {
16825bc3cb74SMauro Carvalho Chehab 		/* last std value in the standards array is 0, so this
16835bc3cb74SMauro Carvalho Chehab 		   while always ends there since (id & 0) == 0. */
16845bc3cb74SMauro Carvalho Chehab 		while ((id & standards[j].std) != standards[j].std)
16855bc3cb74SMauro Carvalho Chehab 			j++;
16865bc3cb74SMauro Carvalho Chehab 		curr_id = standards[j].std;
16875bc3cb74SMauro Carvalho Chehab 		descr = standards[j].descr;
16885bc3cb74SMauro Carvalho Chehab 		j++;
16895bc3cb74SMauro Carvalho Chehab 		if (curr_id == 0)
16905bc3cb74SMauro Carvalho Chehab 			break;
16915bc3cb74SMauro Carvalho Chehab 		if (curr_id != V4L2_STD_PAL &&
16925bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_SECAM &&
16935bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_NTSC)
16945bc3cb74SMauro Carvalho Chehab 			id &= ~curr_id;
16955bc3cb74SMauro Carvalho Chehab 	}
16965bc3cb74SMauro Carvalho Chehab 	if (i <= index)
16975bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
16985bc3cb74SMauro Carvalho Chehab 
16995bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_construct(p, curr_id, descr);
17005bc3cb74SMauro Carvalho Chehab 	return 0;
17015bc3cb74SMauro Carvalho Chehab }
17025bc3cb74SMauro Carvalho Chehab 
17035bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
17045bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17055bc3cb74SMauro Carvalho Chehab {
17065bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1707314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
17085bc3cb74SMauro Carvalho Chehab 
1709314527acSHans Verkuil 	norm = id & vfd->tvnorms;
17105bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
17115bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17125bc3cb74SMauro Carvalho Chehab 
17135bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1714ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
17155bc3cb74SMauro Carvalho Chehab }
17165bc3cb74SMauro Carvalho Chehab 
17175bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
17185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17195bc3cb74SMauro Carvalho Chehab {
17205bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17215bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
17225bc3cb74SMauro Carvalho Chehab 
17235bc3cb74SMauro Carvalho Chehab 	/*
17241a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
17251a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
17261a2c6866SHans Verkuil 	 * any standards that do not apply removed.
17271a2c6866SHans Verkuil 	 *
17285bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
17295bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
17305bc3cb74SMauro Carvalho Chehab 	 */
17315bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
17325bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
17335bc3cb74SMauro Carvalho Chehab }
17345bc3cb74SMauro Carvalho Chehab 
17355bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
17365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17375bc3cb74SMauro Carvalho Chehab {
17385bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17395bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
17405bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
17415bc3cb74SMauro Carvalho Chehab 
174284099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
174384099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
174484099a28SAntti Palosaari 		return -EINVAL;
174584099a28SAntti Palosaari 
17465bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
17475bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
17485bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
17495bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
17505bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
17515bc3cb74SMauro Carvalho Chehab }
17525bc3cb74SMauro Carvalho Chehab 
1753737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1754737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1755737c097bSHans Verkuil {
1756737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1757737c097bSHans Verkuil }
1758737c097bSHans Verkuil 
17595bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
17605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17615bc3cb74SMauro Carvalho Chehab {
17625bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
17634b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
17645bc3cb74SMauro Carvalho Chehab 
17655bc3cb74SMauro Carvalho Chehab 	if (ret)
17665bc3cb74SMauro Carvalho Chehab 		return ret;
17675bc3cb74SMauro Carvalho Chehab 
17685bc3cb74SMauro Carvalho Chehab 	CLEAR_AFTER_FIELD(p, memory);
17695bc3cb74SMauro Carvalho Chehab 
17705bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
17715bc3cb74SMauro Carvalho Chehab }
17725bc3cb74SMauro Carvalho Chehab 
17735bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
17745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17755bc3cb74SMauro Carvalho Chehab {
17765bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
17774b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
17785bc3cb74SMauro Carvalho Chehab 
17795bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
17805bc3cb74SMauro Carvalho Chehab }
17815bc3cb74SMauro Carvalho Chehab 
17825bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
17835bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17845bc3cb74SMauro Carvalho Chehab {
17855bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
17864b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
17875bc3cb74SMauro Carvalho Chehab 
17885bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
17895bc3cb74SMauro Carvalho Chehab }
17905bc3cb74SMauro Carvalho Chehab 
17915bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
17925bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17935bc3cb74SMauro Carvalho Chehab {
17945bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
17954b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
17965bc3cb74SMauro Carvalho Chehab 
17975bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
17985bc3cb74SMauro Carvalho Chehab }
17995bc3cb74SMauro Carvalho Chehab 
18005bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
18015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18025bc3cb74SMauro Carvalho Chehab {
18035bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
18044b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
18055bc3cb74SMauro Carvalho Chehab 
1806d52e2381SLaurent Pinchart 	if (ret)
1807d52e2381SLaurent Pinchart 		return ret;
1808d52e2381SLaurent Pinchart 
18095d351251SHans Verkuil 	CLEAR_AFTER_FIELD(create, format);
18105d351251SHans Verkuil 
1811d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1812d52e2381SLaurent Pinchart 
1813d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1814d52e2381SLaurent Pinchart 
1815d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1816d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1817d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1818d52e2381SLaurent Pinchart 
1819d52e2381SLaurent Pinchart 	return ret;
18205bc3cb74SMauro Carvalho Chehab }
18215bc3cb74SMauro Carvalho Chehab 
18225bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
18235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18245bc3cb74SMauro Carvalho Chehab {
18255bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
18264b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
18275bc3cb74SMauro Carvalho Chehab 
18285bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
18295bc3cb74SMauro Carvalho Chehab }
18305bc3cb74SMauro Carvalho Chehab 
18315bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
18325bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18335bc3cb74SMauro Carvalho Chehab {
18345bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
18355bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
18364b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18375bc3cb74SMauro Carvalho Chehab 
18385bc3cb74SMauro Carvalho Chehab 	if (ret)
18395bc3cb74SMauro Carvalho Chehab 		return ret;
18405bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
18415bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
18425bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
18435bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
18445bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
18455bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
18465bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
18475bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
1848ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
18495bc3cb74SMauro Carvalho Chehab 	return ret;
18505bc3cb74SMauro Carvalho Chehab }
18515bc3cb74SMauro Carvalho Chehab 
18525bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
18535bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18545bc3cb74SMauro Carvalho Chehab {
18555bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
18564b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
18575bc3cb74SMauro Carvalho Chehab 
18585bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_s_parm(file, fh, p);
18595bc3cb74SMauro Carvalho Chehab }
18605bc3cb74SMauro Carvalho Chehab 
18615bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
18625bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18635bc3cb74SMauro Carvalho Chehab {
18645bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18655bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
18665bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
18675bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
18685bc3cb74SMauro Carvalho Chehab 
18695bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
18705bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
18715bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
18725bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
18735bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
18745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
18755bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
18765bc3cb74SMauro Carvalho Chehab }
18775bc3cb74SMauro Carvalho Chehab 
1878e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
1879e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
1880e6bee368SHans Verkuil {
1881e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1882e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
1883e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
1884e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
1885e6bee368SHans Verkuil 
1886e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
1887e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
1888e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
1889e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
1890e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
1891e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
1892e6bee368SHans Verkuil 	return -ENOTTY;
1893e6bee368SHans Verkuil }
1894e6bee368SHans Verkuil 
18955bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
18965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18975bc3cb74SMauro Carvalho Chehab {
18985bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18995bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
19005bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19015bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19025bc3cb74SMauro Carvalho Chehab 
19035bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19045bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
19055bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19065bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
19075bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
19085bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
19095bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19105bc3cb74SMauro Carvalho Chehab }
19115bc3cb74SMauro Carvalho Chehab 
19125bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
19135bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19145bc3cb74SMauro Carvalho Chehab {
19155bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19165bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
19175bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19185bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19195bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
19205bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
19215bc3cb74SMauro Carvalho Chehab 
19225bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19235bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
19245bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19255bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
19265bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
19275bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
19285bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
19295bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
19305bc3cb74SMauro Carvalho Chehab 
19315bc3cb74SMauro Carvalho Chehab 	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
19325bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
19335bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
19345bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
19355bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
19365bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
19375bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
19385bc3cb74SMauro Carvalho Chehab 
19395bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
19405bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
19415bc3cb74SMauro Carvalho Chehab 		return ret;
19425bc3cb74SMauro Carvalho Chehab 	}
19435bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
19445bc3cb74SMauro Carvalho Chehab }
19455bc3cb74SMauro Carvalho Chehab 
19465bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
19475bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19485bc3cb74SMauro Carvalho Chehab {
19495bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19505bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
19515bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19525bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19535bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
19545bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
19555bc3cb74SMauro Carvalho Chehab 
19565bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19575bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
19585bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19595bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
19605bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
19615bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
19625bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
19635bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
19645bc3cb74SMauro Carvalho Chehab 
19655bc3cb74SMauro Carvalho Chehab 	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
19665bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
19675bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
19685bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
19695bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
19705bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
19715bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
19725bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
19735bc3cb74SMauro Carvalho Chehab }
19745bc3cb74SMauro Carvalho Chehab 
19755bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
19765bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19775bc3cb74SMauro Carvalho Chehab {
19785bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19795bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
19805bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
19815bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
19825bc3cb74SMauro Carvalho Chehab 
19835bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
19845bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
19855bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
19865bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
19875bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
19885bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
19895bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
19905bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
19915bc3cb74SMauro Carvalho Chehab 					-EINVAL;
19925bc3cb74SMauro Carvalho Chehab }
19935bc3cb74SMauro Carvalho Chehab 
19945bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
19955bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19965bc3cb74SMauro Carvalho Chehab {
19975bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19985bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
19995bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20005bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20015bc3cb74SMauro Carvalho Chehab 
20025bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20035bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20045bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
20055bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20065bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
20075bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
20085bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20095bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
20105bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20115bc3cb74SMauro Carvalho Chehab }
20125bc3cb74SMauro Carvalho Chehab 
20135bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
20145bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20155bc3cb74SMauro Carvalho Chehab {
20165bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20175bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
20185bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
20195bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
20205bc3cb74SMauro Carvalho Chehab 
20215bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
20225bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
20235bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
20245bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
20255bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
20265bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
20275bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
20285bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
20295bc3cb74SMauro Carvalho Chehab 					-EINVAL;
20305bc3cb74SMauro Carvalho Chehab }
20315bc3cb74SMauro Carvalho Chehab 
20325bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
20335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20345bc3cb74SMauro Carvalho Chehab {
20355bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
20365bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
20375bc3cb74SMauro Carvalho Chehab 		.type = p->type,
20385bc3cb74SMauro Carvalho Chehab 	};
20395bc3cb74SMauro Carvalho Chehab 	int ret;
20405bc3cb74SMauro Carvalho Chehab 
20415bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_crop)
20425bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_crop(file, fh, p);
20435bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
20445bc3cb74SMauro Carvalho Chehab 
20455bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
20465bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
20475bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
20485bc3cb74SMauro Carvalho Chehab 	else
20495bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
20505bc3cb74SMauro Carvalho Chehab 
20515bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
20525bc3cb74SMauro Carvalho Chehab 
20535bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
20545bc3cb74SMauro Carvalho Chehab 	if (!ret)
20555bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
20565bc3cb74SMauro Carvalho Chehab 	return ret;
20575bc3cb74SMauro Carvalho Chehab }
20585bc3cb74SMauro Carvalho Chehab 
20595bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
20605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20615bc3cb74SMauro Carvalho Chehab {
20625bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
20635bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
20645bc3cb74SMauro Carvalho Chehab 		.type = p->type,
20655bc3cb74SMauro Carvalho Chehab 		.r = p->c,
20665bc3cb74SMauro Carvalho Chehab 	};
20675bc3cb74SMauro Carvalho Chehab 
20685bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_crop)
20695bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_crop(file, fh, p);
20705bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
20715bc3cb74SMauro Carvalho Chehab 
20725bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
20735bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
20745bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
20755bc3cb74SMauro Carvalho Chehab 	else
20765bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
20775bc3cb74SMauro Carvalho Chehab 
20785bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_selection(file, fh, &s);
20795bc3cb74SMauro Carvalho Chehab }
20805bc3cb74SMauro Carvalho Chehab 
20815bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
20825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20835bc3cb74SMauro Carvalho Chehab {
20845bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
20859409945cSHans Verkuil 
20869409945cSHans Verkuil 	if (ops->vidioc_g_selection) {
20875bc3cb74SMauro Carvalho Chehab 		struct v4l2_selection s = { .type = p->type };
20885bc3cb74SMauro Carvalho Chehab 		int ret;
20895bc3cb74SMauro Carvalho Chehab 
20905bc3cb74SMauro Carvalho Chehab 		/* obtaining bounds */
20915bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
20925bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
20935bc3cb74SMauro Carvalho Chehab 		else
20945bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_BOUNDS;
20955bc3cb74SMauro Carvalho Chehab 
20965bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
20975bc3cb74SMauro Carvalho Chehab 		if (ret)
20985bc3cb74SMauro Carvalho Chehab 			return ret;
20995bc3cb74SMauro Carvalho Chehab 		p->bounds = s.r;
21005bc3cb74SMauro Carvalho Chehab 
21015bc3cb74SMauro Carvalho Chehab 		/* obtaining defrect */
21025bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
21035bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
21045bc3cb74SMauro Carvalho Chehab 		else
21055bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_DEFAULT;
21065bc3cb74SMauro Carvalho Chehab 
21075bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
21085bc3cb74SMauro Carvalho Chehab 		if (ret)
21095bc3cb74SMauro Carvalho Chehab 			return ret;
21105bc3cb74SMauro Carvalho Chehab 		p->defrect = s.r;
21119409945cSHans Verkuil 	}
21125bc3cb74SMauro Carvalho Chehab 
21135bc3cb74SMauro Carvalho Chehab 	/* setting trivial pixelaspect */
21145bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.numerator = 1;
21155bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.denominator = 1;
21169409945cSHans Verkuil 
21179409945cSHans Verkuil 	if (ops->vidioc_cropcap)
21189409945cSHans Verkuil 		return ops->vidioc_cropcap(file, fh, p);
21199409945cSHans Verkuil 
21205bc3cb74SMauro Carvalho Chehab 	return 0;
21215bc3cb74SMauro Carvalho Chehab }
21225bc3cb74SMauro Carvalho Chehab 
21235bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
21245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21255bc3cb74SMauro Carvalho Chehab {
21265bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21275bc3cb74SMauro Carvalho Chehab 	int ret;
21285bc3cb74SMauro Carvalho Chehab 
21295bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
21305bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
21315bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
21325bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
21335bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
21345bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
21355bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
21365bc3cb74SMauro Carvalho Chehab 	return ret;
21375bc3cb74SMauro Carvalho Chehab }
21385bc3cb74SMauro Carvalho Chehab 
21395bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
21405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21415bc3cb74SMauro Carvalho Chehab {
21425bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
21435bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
214479b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
214579b0c640SHans Verkuil 	struct v4l2_subdev *sd;
214679b0c640SHans Verkuil 	int idx = 0;
21475bc3cb74SMauro Carvalho Chehab 
21485bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
21495bc3cb74SMauro Carvalho Chehab 		return -EPERM;
21503eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
215179b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
215279b0c640SHans Verkuil 			return -EINVAL;
21533eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
21543eef2510SHans Verkuil 			if (p->match.addr == idx++)
215579b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
215679b0c640SHans Verkuil 		return -EINVAL;
215779b0c640SHans Verkuil 	}
2158191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2159191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
21605bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
216179b0c640SHans Verkuil 	return -EINVAL;
21625bc3cb74SMauro Carvalho Chehab #else
21635bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21645bc3cb74SMauro Carvalho Chehab #endif
21655bc3cb74SMauro Carvalho Chehab }
21665bc3cb74SMauro Carvalho Chehab 
21675bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
21685bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21695bc3cb74SMauro Carvalho Chehab {
21705bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2171977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
217279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
217379b0c640SHans Verkuil 	struct v4l2_subdev *sd;
217479b0c640SHans Verkuil 	int idx = 0;
21755bc3cb74SMauro Carvalho Chehab 
21765bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
21775bc3cb74SMauro Carvalho Chehab 		return -EPERM;
21783eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
217979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
218079b0c640SHans Verkuil 			return -EINVAL;
21813eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
21823eef2510SHans Verkuil 			if (p->match.addr == idx++)
218379b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
218479b0c640SHans Verkuil 		return -EINVAL;
218579b0c640SHans Verkuil 	}
2186191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2187191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
21885bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
218979b0c640SHans Verkuil 	return -EINVAL;
21905bc3cb74SMauro Carvalho Chehab #else
21915bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21925bc3cb74SMauro Carvalho Chehab #endif
21935bc3cb74SMauro Carvalho Chehab }
21945bc3cb74SMauro Carvalho Chehab 
219596b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
219679b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
219779b0c640SHans Verkuil {
2198cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
219979b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
220096b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
220179b0c640SHans Verkuil 	struct v4l2_subdev *sd;
220279b0c640SHans Verkuil 	int idx = 0;
220379b0c640SHans Verkuil 
220479b0c640SHans Verkuil 	switch (p->match.type) {
220579b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
220679b0c640SHans Verkuil 		if (ops->vidioc_s_register)
220779b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
220879b0c640SHans Verkuil 		if (ops->vidioc_g_register)
220979b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
221079b0c640SHans Verkuil 		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
221196b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
221296b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
22130f0fe4b9SHans Verkuil 		if (p->match.addr)
22140f0fe4b9SHans Verkuil 			return -EINVAL;
221579b0c640SHans Verkuil 		return 0;
221679b0c640SHans Verkuil 
22173eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
221879b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
221979b0c640SHans Verkuil 			break;
222079b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
22213eef2510SHans Verkuil 			if (p->match.addr != idx++)
22223eef2510SHans Verkuil 				continue;
222379b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
222479b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
222579b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
222679b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
222779b0c640SHans Verkuil 			strlcpy(p->name, sd->name, sizeof(p->name));
222879b0c640SHans Verkuil 			return 0;
222979b0c640SHans Verkuil 		}
223079b0c640SHans Verkuil 		break;
223179b0c640SHans Verkuil 	}
223279b0c640SHans Verkuil 	return -EINVAL;
2233cd634f1bSHans Verkuil #else
2234cd634f1bSHans Verkuil 	return -ENOTTY;
2235cd634f1bSHans Verkuil #endif
223679b0c640SHans Verkuil }
223779b0c640SHans Verkuil 
22385bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
22395bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22405bc3cb74SMauro Carvalho Chehab {
22415bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
22425bc3cb74SMauro Carvalho Chehab }
22435bc3cb74SMauro Carvalho Chehab 
22445bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
22455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22465bc3cb74SMauro Carvalho Chehab {
22475bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
22485bc3cb74SMauro Carvalho Chehab }
22495bc3cb74SMauro Carvalho Chehab 
22505bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
22515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22525bc3cb74SMauro Carvalho Chehab {
22535bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
22545bc3cb74SMauro Carvalho Chehab }
22555bc3cb74SMauro Carvalho Chehab 
22565bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
22575bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22585bc3cb74SMauro Carvalho Chehab {
22595bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
22604b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
22614b20259fSHans Verkuil 
22624b20259fSHans Verkuil 	if (ret)
22634b20259fSHans Verkuil 		return ret;
22645bc3cb74SMauro Carvalho Chehab 
22655bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
22665bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
22675bc3cb74SMauro Carvalho Chehab 
22685bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
22695bc3cb74SMauro Carvalho Chehab }
22705bc3cb74SMauro Carvalho Chehab 
22715bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
22725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22735bc3cb74SMauro Carvalho Chehab {
22745bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22755bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
22765bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
22775bc3cb74SMauro Carvalho Chehab 	int err;
22785bc3cb74SMauro Carvalho Chehab 
227984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
228084099a28SAntti Palosaari 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
228184099a28SAntti Palosaari 			return -EINVAL;
228284099a28SAntti Palosaari 		type = p->type;
228384099a28SAntti Palosaari 	} else {
22845bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
22855bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
22865bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
22875bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
228884099a28SAntti Palosaari 	}
2289a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2290a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2291a7f404afSHans Verkuil 		if (err != -ENOTTY)
2292a7f404afSHans Verkuil 			return err;
2293a7f404afSHans Verkuil 	}
229473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
22955bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
22965bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
22975bc3cb74SMauro Carvalho Chehab 			.type = type,
22985bc3cb74SMauro Carvalho Chehab 		};
22995bc3cb74SMauro Carvalho Chehab 
230079e8c7beSMauro Carvalho Chehab 		if (p->index)
230179e8c7beSMauro Carvalho Chehab 			return -EINVAL;
23025bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
23035bc3cb74SMauro Carvalho Chehab 		if (err)
23045bc3cb74SMauro Carvalho Chehab 			return err;
23055bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
23065bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
23075bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
23085bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
23095bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
23105bc3cb74SMauro Carvalho Chehab 		return 0;
23115bc3cb74SMauro Carvalho Chehab 	}
231273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
23135bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
23145bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
23155bc3cb74SMauro Carvalho Chehab 		};
23165bc3cb74SMauro Carvalho Chehab 
23175bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
23185bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
231979e8c7beSMauro Carvalho Chehab 		if (p->index)
232079e8c7beSMauro Carvalho Chehab 			return -EINVAL;
23215bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
23225bc3cb74SMauro Carvalho Chehab 		if (err)
23235bc3cb74SMauro Carvalho Chehab 			return err;
23245bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
23255bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
23265bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
23275bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
23285bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
23295bc3cb74SMauro Carvalho Chehab 		return 0;
23305bc3cb74SMauro Carvalho Chehab 	}
23315bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
23325bc3cb74SMauro Carvalho Chehab }
23335bc3cb74SMauro Carvalho Chehab 
23345bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
23355bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
23365bc3cb74SMauro Carvalho Chehab 	u32 flags;
23375bc3cb74SMauro Carvalho Chehab 	const char * const name;
23385bc3cb74SMauro Carvalho Chehab 	union {
23395bc3cb74SMauro Carvalho Chehab 		u32 offset;
23405bc3cb74SMauro Carvalho Chehab 		int (*func)(const struct v4l2_ioctl_ops *ops,
23415bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *p);
23425bc3cb74SMauro Carvalho Chehab 	} u;
23435bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
23445bc3cb74SMauro Carvalho Chehab };
23455bc3cb74SMauro Carvalho Chehab 
23465bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
23475bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO	(1 << 0)
23485bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
23495bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL	(1 << 1)
23505bc3cb74SMauro Carvalho Chehab /* This is a standard ioctl, no need for special code */
23515bc3cb74SMauro Carvalho Chehab #define INFO_FL_STD	(1 << 2)
23525bc3cb74SMauro Carvalho Chehab /* This is ioctl has its own function */
23535bc3cb74SMauro Carvalho Chehab #define INFO_FL_FUNC	(1 << 3)
23545bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
23555bc3cb74SMauro Carvalho Chehab #define INFO_FL_QUEUE	(1 << 4)
23565bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
23575bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
23585bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
23595bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
23605bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
23615bc3cb74SMauro Carvalho Chehab 
23625bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags)			\
23635bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
23645bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
23655bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_STD,				\
23665bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
23675bc3cb74SMauro Carvalho Chehab 		.u.offset = offsetof(struct v4l2_ioctl_ops, _vidioc),	\
23685bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
23695bc3cb74SMauro Carvalho Chehab 	}
23705bc3cb74SMauro Carvalho Chehab 
23715bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags)			\
23725bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
23735bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
23745bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_FUNC,				\
23755bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
23765bc3cb74SMauro Carvalho Chehab 		.u.func = _func,					\
23775bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
23785bc3cb74SMauro Carvalho Chehab 	}
23795bc3cb74SMauro Carvalho Chehab 
23805bc3cb74SMauro Carvalho Chehab static struct v4l2_ioctl_info v4l2_ioctls[] = {
23815bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
23825bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
2383e5ce558aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
23845bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
23855bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
23865bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
23875bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
23885bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
2389737c097bSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
23905bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
2391b799d09aSTomasz Stanislawski 	IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
23925bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
23935bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
23945bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
23955bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
23965bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
2397ca371575SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
23985bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
23995bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
24005bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
24015bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
24025bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
24035bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
24045bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
24055bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
24065bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
24075bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
24085bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
24095bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
24105bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
2411f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0),
2412f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO),
24135bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
24145bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
24155bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
24165bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
24175bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
24185bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
24195bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
24205bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
24215bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
24225bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
24235bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
24245bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
2425865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
2426865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
24275bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
24285bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
24295bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
24305bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
24315bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
24325bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
24335bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
24345bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
24355bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)),
24365bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
24375bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
24385bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
24395bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
24405bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
24415bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
24425bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0),
24435bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENCODER_CMD, vidioc_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
24445bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
24455bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
24465bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
24475bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
24485bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
24495bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
24505bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
24515bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
24525bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
24535bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
24545bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
24555bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
24565bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
24575bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0),
24585bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
24595bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)),
24605bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
246196b03d2aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
2462e6bee368SHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)),
24635bc3cb74SMauro Carvalho Chehab };
24645bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
24655bc3cb74SMauro Carvalho Chehab 
24665bc3cb74SMauro Carvalho Chehab bool v4l2_is_known_ioctl(unsigned int cmd)
24675bc3cb74SMauro Carvalho Chehab {
24685bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
24695bc3cb74SMauro Carvalho Chehab 		return false;
24705bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
24715bc3cb74SMauro Carvalho Chehab }
24725bc3cb74SMauro Carvalho Chehab 
24735bc3cb74SMauro Carvalho Chehab struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
24745bc3cb74SMauro Carvalho Chehab {
24755bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
24765bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
24775bc3cb74SMauro Carvalho Chehab 	if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
24785bc3cb74SMauro Carvalho Chehab 		return NULL;
24795bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
24805bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
24815bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
24825bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
24835bc3cb74SMauro Carvalho Chehab }
24845bc3cb74SMauro Carvalho Chehab 
24855bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
24865bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
24875bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
24885bc3cb74SMauro Carvalho Chehab {
24895bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
24905bc3cb74SMauro Carvalho Chehab 
24915bc3cb74SMauro Carvalho Chehab 	if (prefix)
24925bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
24935bc3cb74SMauro Carvalho Chehab 
24945bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
24955bc3cb74SMauro Carvalho Chehab 	case 'd':
24965bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
24975bc3cb74SMauro Carvalho Chehab 		break;
24985bc3cb74SMauro Carvalho Chehab 	case 'V':
24995bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
25005bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
25015bc3cb74SMauro Carvalho Chehab 			break;
25025bc3cb74SMauro Carvalho Chehab 		}
25035bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
25045bc3cb74SMauro Carvalho Chehab 		return;
25055bc3cb74SMauro Carvalho Chehab 	default:
25065bc3cb74SMauro Carvalho Chehab 		type = "unknown";
25075bc3cb74SMauro Carvalho Chehab 		break;
25085bc3cb74SMauro Carvalho Chehab 	}
25095bc3cb74SMauro Carvalho Chehab 
25105bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
25115bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
25125bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
25135bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
25145bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
25155bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
25165bc3cb74SMauro Carvalho Chehab 	}
25175bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
25185bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
25195bc3cb74SMauro Carvalho Chehab }
25205bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
25215bc3cb74SMauro Carvalho Chehab 
25225bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
25235bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
25245bc3cb74SMauro Carvalho Chehab {
25255bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
25265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
25275bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
25285bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
25295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
25305bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
25315bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
253217028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
25335bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
25345bc3cb74SMauro Carvalho Chehab 
25355bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
25365bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
25375bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
25385bc3cb74SMauro Carvalho Chehab 		return ret;
25395bc3cb74SMauro Carvalho Chehab 	}
25405bc3cb74SMauro Carvalho Chehab 
2541b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
25425bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
25435bc3cb74SMauro Carvalho Chehab 
25445bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
25455bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
25465bc3cb74SMauro Carvalho Chehab 
25475bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
25485bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
25495bc3cb74SMauro Carvalho Chehab 			goto done;
25505bc3cb74SMauro Carvalho Chehab 
2551b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
25525bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
25535bc3cb74SMauro Carvalho Chehab 			if (ret)
25545bc3cb74SMauro Carvalho Chehab 				goto done;
25555bc3cb74SMauro Carvalho Chehab 		}
25565bc3cb74SMauro Carvalho Chehab 	} else {
25575bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
25585bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
25595bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
25605bc3cb74SMauro Carvalho Chehab 		info = &default_info;
25615bc3cb74SMauro Carvalho Chehab 	}
25625bc3cb74SMauro Carvalho Chehab 
25635bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
25645bc3cb74SMauro Carvalho Chehab 	if (info->flags & INFO_FL_STD) {
25655bc3cb74SMauro Carvalho Chehab 		typedef int (*vidioc_op)(struct file *file, void *fh, void *p);
25665bc3cb74SMauro Carvalho Chehab 		const void *p = vfd->ioctl_ops;
25675bc3cb74SMauro Carvalho Chehab 		const vidioc_op *vidioc = p + info->u.offset;
25685bc3cb74SMauro Carvalho Chehab 
25695bc3cb74SMauro Carvalho Chehab 		ret = (*vidioc)(file, fh, arg);
25705bc3cb74SMauro Carvalho Chehab 	} else if (info->flags & INFO_FL_FUNC) {
25715bc3cb74SMauro Carvalho Chehab 		ret = info->u.func(ops, file, fh, arg);
25725bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
25735bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
25745bc3cb74SMauro Carvalho Chehab 	} else {
25755bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2576b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
25775bc3cb74SMauro Carvalho Chehab 			cmd, arg);
25785bc3cb74SMauro Carvalho Chehab 	}
25795bc3cb74SMauro Carvalho Chehab 
25805bc3cb74SMauro Carvalho Chehab done:
258117028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
258217028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
258317028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
258417028cdbSHans Verkuil 			return ret;
258517028cdbSHans Verkuil 
25865bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
25875bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2588505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
258917028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
25905bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
25915bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
25925bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
25935bc3cb74SMauro Carvalho Chehab 		else {
25945bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
25955bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
25965bc3cb74SMauro Carvalho Chehab 		}
25975bc3cb74SMauro Carvalho Chehab 	}
25985bc3cb74SMauro Carvalho Chehab 
25995bc3cb74SMauro Carvalho Chehab 	return ret;
26005bc3cb74SMauro Carvalho Chehab }
26015bc3cb74SMauro Carvalho Chehab 
26025bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2603ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
26045bc3cb74SMauro Carvalho Chehab {
26055bc3cb74SMauro Carvalho Chehab 	int ret = 0;
26065bc3cb74SMauro Carvalho Chehab 
26075bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
260896b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
26095bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
26105bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
26115bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
26125bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
26135bc3cb74SMauro Carvalho Chehab 
26145bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
26155bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
26165bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
26175bc3cb74SMauro Carvalho Chehab 				break;
26185bc3cb74SMauro Carvalho Chehab 			}
26195bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2620ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
26215bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
26225bc3cb74SMauro Carvalho Chehab 			ret = 1;
26235bc3cb74SMauro Carvalho Chehab 		}
26245bc3cb74SMauro Carvalho Chehab 		break;
26255bc3cb74SMauro Carvalho Chehab 	}
26265bc3cb74SMauro Carvalho Chehab 
2627dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2628dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2629dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2630ed45ce2cSHans Verkuil 
2631ed45ce2cSHans Verkuil 		if (edid->blocks) {
26321b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
26331b8b10ccSHans Verkuil 				ret = -EINVAL;
26341b8b10ccSHans Verkuil 				break;
26351b8b10ccSHans Verkuil 			}
2636ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2637ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2638ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2639ed45ce2cSHans Verkuil 			ret = 1;
2640ed45ce2cSHans Verkuil 		}
2641ed45ce2cSHans Verkuil 		break;
2642ed45ce2cSHans Verkuil 	}
2643ed45ce2cSHans Verkuil 
26445bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
26455bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
26465bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
26475bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
26485bc3cb74SMauro Carvalho Chehab 
26495bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
26505bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
26515bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
26525bc3cb74SMauro Carvalho Chehab 				break;
26535bc3cb74SMauro Carvalho Chehab 			}
26545bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2655ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
26565bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
26575bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
26585bc3cb74SMauro Carvalho Chehab 			ret = 1;
26595bc3cb74SMauro Carvalho Chehab 		}
26605bc3cb74SMauro Carvalho Chehab 		break;
26615bc3cb74SMauro Carvalho Chehab 	}
26625bc3cb74SMauro Carvalho Chehab 	}
26635bc3cb74SMauro Carvalho Chehab 
26645bc3cb74SMauro Carvalho Chehab 	return ret;
26655bc3cb74SMauro Carvalho Chehab }
26665bc3cb74SMauro Carvalho Chehab 
26675bc3cb74SMauro Carvalho Chehab long
26685bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
26695bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
26705bc3cb74SMauro Carvalho Chehab {
26715bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
26725bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
26735bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
26745bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
26755bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
26765bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
26775bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
26785bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
26795bc3cb74SMauro Carvalho Chehab 
26805bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
26815bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
26825bc3cb74SMauro Carvalho Chehab 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
26835bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
26845bc3cb74SMauro Carvalho Chehab 		} else {
26855bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
26865bc3cb74SMauro Carvalho Chehab 			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
26875bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
26885bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
26895bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
26905bc3cb74SMauro Carvalho Chehab 		}
26915bc3cb74SMauro Carvalho Chehab 
26925bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
26935bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
26945bc3cb74SMauro Carvalho Chehab 			unsigned int n = _IOC_SIZE(cmd);
26955bc3cb74SMauro Carvalho Chehab 
26965bc3cb74SMauro Carvalho Chehab 			/*
26975bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
26985bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
26995bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
27005bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
27015bc3cb74SMauro Carvalho Chehab 			 * non-input field.
27025bc3cb74SMauro Carvalho Chehab 			 */
27035bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
27045bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
27055bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
27065bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
27075bc3cb74SMauro Carvalho Chehab 			}
27085bc3cb74SMauro Carvalho Chehab 
27095bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
27105bc3cb74SMauro Carvalho Chehab 				goto out;
27115bc3cb74SMauro Carvalho Chehab 
27125bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
27135bc3cb74SMauro Carvalho Chehab 			if (n < _IOC_SIZE(cmd))
27145bc3cb74SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
27155bc3cb74SMauro Carvalho Chehab 		} else {
27165bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
27175bc3cb74SMauro Carvalho Chehab 			memset(parg, 0, _IOC_SIZE(cmd));
27185bc3cb74SMauro Carvalho Chehab 		}
27195bc3cb74SMauro Carvalho Chehab 	}
27205bc3cb74SMauro Carvalho Chehab 
27215bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
27225bc3cb74SMauro Carvalho Chehab 	if (err < 0)
27235bc3cb74SMauro Carvalho Chehab 		goto out;
27245bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
27255bc3cb74SMauro Carvalho Chehab 
27265bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
27275bc3cb74SMauro Carvalho Chehab 		/*
27285bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
27295bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
27305bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
27315bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
27325bc3cb74SMauro Carvalho Chehab 		 */
27335bc3cb74SMauro Carvalho Chehab 		mbuf = kmalloc(array_size, GFP_KERNEL);
27345bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
27355bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
27365bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
27375bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
27385bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
27395bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
27405bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
27415bc3cb74SMauro Carvalho Chehab 	}
27425bc3cb74SMauro Carvalho Chehab 
27435bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
27445bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
27455bc3cb74SMauro Carvalho Chehab 	if (err == -ENOIOCTLCMD)
27465bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
2747aa32f4c0SHans Verkuil 	if (err == 0) {
2748aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
2749aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
2750aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
2751aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
2752aa32f4c0SHans Verkuil 	}
27535bc3cb74SMauro Carvalho Chehab 
27545bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
2755ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
27565bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
27575bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
27585bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
27595bc3cb74SMauro Carvalho Chehab 	}
27605bc3cb74SMauro Carvalho Chehab 	/* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
27615bc3cb74SMauro Carvalho Chehab 	   results that must be returned. */
27625bc3cb74SMauro Carvalho Chehab 	if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
27635bc3cb74SMauro Carvalho Chehab 		goto out;
27645bc3cb74SMauro Carvalho Chehab 
27655bc3cb74SMauro Carvalho Chehab out_array_args:
27665bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
27675bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
27685bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
27695bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
27705bc3cb74SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
27715bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
27725bc3cb74SMauro Carvalho Chehab 		break;
27735bc3cb74SMauro Carvalho Chehab 	}
27745bc3cb74SMauro Carvalho Chehab 
27755bc3cb74SMauro Carvalho Chehab out:
27765bc3cb74SMauro Carvalho Chehab 	kfree(mbuf);
27775bc3cb74SMauro Carvalho Chehab 	return err;
27785bc3cb74SMauro Carvalho Chehab }
27795bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_usercopy);
27805bc3cb74SMauro Carvalho Chehab 
27815bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
27825bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
27835bc3cb74SMauro Carvalho Chehab {
27845bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
27855bc3cb74SMauro Carvalho Chehab }
27865bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
2787