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>
295bc3cb74SMauro Carvalho Chehab #include <media/videobuf2-core.h>
305bc3cb74SMauro Carvalho Chehab 
31aa32f4c0SHans Verkuil #define CREATE_TRACE_POINTS
32aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
33aa32f4c0SHans Verkuil 
345bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
355bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
365bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
375bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
385bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
395bc3cb74SMauro Carvalho Chehab 
4073f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4173f35418SHans Verkuil 
425bc3cb74SMauro Carvalho Chehab struct std_descr {
435bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
445bc3cb74SMauro Carvalho Chehab 	const char *descr;
455bc3cb74SMauro Carvalho Chehab };
465bc3cb74SMauro Carvalho Chehab 
475bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC, 	"NTSC"      },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL, 	"PAL"       },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B, 	"PAL-B"     },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G, 	"PAL-G"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H, 	"PAL-H"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I, 	"PAL-I"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D, 	"PAL-D"     },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K, 	"PAL-K"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M, 	"PAL-M"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N, 	"PAL-N"     },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60, 	"PAL-60"    },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM, 	"SECAM"     },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
775bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
785bc3cb74SMauro Carvalho Chehab 	{ 0, 			"Unknown"   }
795bc3cb74SMauro Carvalho Chehab };
805bc3cb74SMauro Carvalho Chehab 
815bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
825bc3cb74SMauro Carvalho Chehab  */
835bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
845bc3cb74SMauro Carvalho Chehab {
855bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
865bc3cb74SMauro Carvalho Chehab 	int i;
875bc3cb74SMauro Carvalho Chehab 
885bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
895bc3cb74SMauro Carvalho Chehab 	   64 bit comparations. So, on that architecture, with some gcc
905bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
915bc3cb74SMauro Carvalho Chehab 	 */
925bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
935bc3cb74SMauro Carvalho Chehab 
945bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
955bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
965bc3cb74SMauro Carvalho Chehab 			break;
975bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
985bc3cb74SMauro Carvalho Chehab }
995bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
1005bc3cb74SMauro Carvalho Chehab 
1015bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1025bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1035bc3cb74SMauro Carvalho Chehab {
1045bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1065bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1075bc3cb74SMauro Carvalho Chehab 	} else {
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1095bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1105bc3cb74SMauro Carvalho Chehab 	}
1115bc3cb74SMauro Carvalho Chehab }
1125bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1135bc3cb74SMauro Carvalho Chehab 
1145bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1155bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1165bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1175bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1185bc3cb74SMauro Carvalho Chehab {
1195bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1205bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1215bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
1225bc3cb74SMauro Carvalho Chehab 	strlcpy(vs->name, name, sizeof(vs->name));
1235bc3cb74SMauro Carvalho Chehab 	return 0;
1245bc3cb74SMauro Carvalho Chehab }
1255bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1265bc3cb74SMauro Carvalho Chehab 
1275bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1285bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1295bc3cb74SMauro Carvalho Chehab 
1305bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1315bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1325bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1335bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1345bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1355bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1365bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1375bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1385bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1395bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1405bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1415bc3cb74SMauro Carvalho Chehab };
1425bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1435bc3cb74SMauro Carvalho Chehab 
1445bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
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, "
260736d96b5SHans Verkuil 			"flags %x, ycbcr_enc=%u, quantization=%u\n",
2615bc3cb74SMauro Carvalho Chehab 			pix->width, pix->height,
2625bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat & 0xff),
2635bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >>  8) & 0xff,
2645bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 16) & 0xff,
2655bc3cb74SMauro Carvalho Chehab 			(pix->pixelformat >> 24) & 0xff,
2665bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2675bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
268736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
269736d96b5SHans Verkuil 			pix->quantization);
2705bc3cb74SMauro Carvalho Chehab 		break;
2715bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2725bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2735bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
2745bc3cb74SMauro Carvalho Chehab 		pr_cont(", width=%u, height=%u, "
2755bc3cb74SMauro Carvalho Chehab 			"format=%c%c%c%c, field=%s, "
276736d96b5SHans Verkuil 			"colorspace=%d, num_planes=%u, flags=%x, "
277736d96b5SHans Verkuil 			"ycbcr_enc=%u, quantization=%u\n",
2785bc3cb74SMauro Carvalho Chehab 			mp->width, mp->height,
2795bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat & 0xff),
2805bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >>  8) & 0xff,
2815bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 16) & 0xff,
2825bc3cb74SMauro Carvalho Chehab 			(mp->pixelformat >> 24) & 0xff,
2835bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
284736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
285736d96b5SHans Verkuil 			mp->ycbcr_enc, mp->quantization);
2865bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < mp->num_planes; i++)
2875bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
2885bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
2895bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
2905bc3cb74SMauro Carvalho Chehab 		break;
2915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2925bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
2935bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
294560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
295560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
296560dde24SHans Verkuil 		 * pointer. */
297560dde24SHans 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",
298560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
2995bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
300560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
301560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3025bc3cb74SMauro Carvalho Chehab 		break;
3035bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3045bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3055bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
3065bc3cb74SMauro Carvalho Chehab 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, "
3075bc3cb74SMauro Carvalho Chehab 			"sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
3085bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
3095bc3cb74SMauro Carvalho Chehab 			vbi->samples_per_line,
3105bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format & 0xff),
3115bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >>  8) & 0xff,
3125bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 16) & 0xff,
3135bc3cb74SMauro Carvalho Chehab 			(vbi->sample_format >> 24) & 0xff,
3145bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3155bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3165bc3cb74SMauro Carvalho Chehab 		break;
3175bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3195bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3205bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3215bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3225bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3235bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3245bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3255bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3265bc3cb74SMauro Carvalho Chehab 		break;
327582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
328582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
329582c52cbSAntti Palosaari 		pr_cont(", pixelformat=%c%c%c%c\n",
330582c52cbSAntti Palosaari 			(sdr->pixelformat >>  0) & 0xff,
331582c52cbSAntti Palosaari 			(sdr->pixelformat >>  8) & 0xff,
332582c52cbSAntti Palosaari 			(sdr->pixelformat >> 16) & 0xff,
333582c52cbSAntti Palosaari 			(sdr->pixelformat >> 24) & 0xff);
334582c52cbSAntti Palosaari 		break;
3355bc3cb74SMauro Carvalho Chehab 	}
3365bc3cb74SMauro Carvalho Chehab }
3375bc3cb74SMauro Carvalho Chehab 
3385bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3395bc3cb74SMauro Carvalho Chehab {
3405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3415bc3cb74SMauro Carvalho Chehab 
3425bc3cb74SMauro Carvalho Chehab 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, "
3435bc3cb74SMauro Carvalho Chehab 		"height=%u, pixelformat=%c%c%c%c, "
344560dde24SHans Verkuil 		"bytesperline=%u, sizeimage=%u, colorspace=%d\n",
3455bc3cb74SMauro Carvalho Chehab 			p->capability, p->flags, p->base,
3465bc3cb74SMauro Carvalho Chehab 			p->fmt.width, p->fmt.height,
3475bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat & 0xff),
3485bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >>  8) & 0xff,
3495bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 16) & 0xff,
3505bc3cb74SMauro Carvalho Chehab 			(p->fmt.pixelformat >> 24) & 0xff,
3515bc3cb74SMauro Carvalho Chehab 			p->fmt.bytesperline, p->fmt.sizeimage,
3525bc3cb74SMauro Carvalho Chehab 			p->fmt.colorspace);
3535bc3cb74SMauro Carvalho Chehab }
3545bc3cb74SMauro Carvalho Chehab 
3555bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3565bc3cb74SMauro Carvalho Chehab {
3575bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3585bc3cb74SMauro Carvalho Chehab }
3595bc3cb74SMauro Carvalho Chehab 
3605bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3615bc3cb74SMauro Carvalho Chehab {
3625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3635bc3cb74SMauro Carvalho Chehab 
3645bc3cb74SMauro Carvalho Chehab 	if (write_only)
365560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3665bc3cb74SMauro Carvalho Chehab 	else
36727d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, "
3685bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
36927d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3705bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3715bc3cb74SMauro Carvalho Chehab }
3725bc3cb74SMauro Carvalho Chehab 
3735bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3745bc3cb74SMauro Carvalho Chehab {
3755bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3765bc3cb74SMauro Carvalho Chehab 
3775bc3cb74SMauro Carvalho Chehab 	if (write_only)
3785bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3795bc3cb74SMauro Carvalho Chehab 	else
38027d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, "
3815bc3cb74SMauro Carvalho Chehab 			"rangelow=%u, rangehigh=%u, signal=%u, afc=%d, "
3825bc3cb74SMauro Carvalho Chehab 			"rxsubchans=0x%x, audmode=%u\n",
38327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3845bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3855bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3865bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3875bc3cb74SMauro Carvalho Chehab }
3885bc3cb74SMauro Carvalho Chehab 
3895bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3905bc3cb74SMauro Carvalho Chehab {
3915bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3925bc3cb74SMauro Carvalho Chehab 
3935bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
3945bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
3955bc3cb74SMauro Carvalho Chehab }
3965bc3cb74SMauro Carvalho Chehab 
3975bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
3985bc3cb74SMauro Carvalho Chehab {
3995bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4005bc3cb74SMauro Carvalho Chehab 
40127d5a87cSHans Verkuil 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, "
4025bc3cb74SMauro Carvalho Chehab 		"framelines=%u\n", p->index,
40327d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4045bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4055bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4065bc3cb74SMauro Carvalho Chehab 		p->framelines);
4075bc3cb74SMauro Carvalho Chehab }
4085bc3cb74SMauro Carvalho Chehab 
4095bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4105bc3cb74SMauro Carvalho Chehab {
4115bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4125bc3cb74SMauro Carvalho Chehab }
4135bc3cb74SMauro Carvalho Chehab 
4145bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4155bc3cb74SMauro Carvalho Chehab {
4165bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4175bc3cb74SMauro Carvalho Chehab 
41879e8c7beSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
41979e8c7beSMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u\n",
42079e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
42179e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4225bc3cb74SMauro Carvalho Chehab }
4235bc3cb74SMauro Carvalho Chehab 
4245bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4255bc3cb74SMauro Carvalho Chehab {
4265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4275bc3cb74SMauro Carvalho Chehab 
4285bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4295bc3cb74SMauro Carvalho Chehab 		p->count,
4305bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4315bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4325bc3cb74SMauro Carvalho Chehab }
4335bc3cb74SMauro Carvalho Chehab 
4345bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4355bc3cb74SMauro Carvalho Chehab {
4365bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4395bc3cb74SMauro Carvalho Chehab 	int i;
4405bc3cb74SMauro Carvalho Chehab 
4415bc3cb74SMauro Carvalho Chehab 	pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, "
4425bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, field=%s, sequence=%d, memory=%s",
4435bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec / 3600,
4445bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec / 60) % 60,
4455bc3cb74SMauro Carvalho Chehab 			(int)(p->timestamp.tv_sec % 60),
4465bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4475bc3cb74SMauro Carvalho Chehab 			p->index,
4485bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names),
4495bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4505bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4515bc3cb74SMauro Carvalho Chehab 
4525bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4535bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4545bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4555bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4565bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
457560dde24SHans Verkuil 				"plane %d: bytesused=%d, data_offset=0x%08x, "
4585bc3cb74SMauro Carvalho Chehab 				"offset/userptr=0x%lx, length=%d\n",
4595bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4605bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4615bc3cb74SMauro Carvalho Chehab 		}
4625bc3cb74SMauro Carvalho Chehab 	} else {
463560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4645bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4655bc3cb74SMauro Carvalho Chehab 	}
4665bc3cb74SMauro Carvalho Chehab 
4675bc3cb74SMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, "
4685bc3cb74SMauro Carvalho Chehab 		"flags=0x%08x, frames=%d, userbits=0x%08x\n",
4695bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4705bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4715bc3cb74SMauro Carvalho Chehab }
4725bc3cb74SMauro Carvalho Chehab 
473b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
474b799d09aSTomasz Stanislawski {
475b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
476b799d09aSTomasz Stanislawski 
477b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
478b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
479b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
480b799d09aSTomasz Stanislawski }
481b799d09aSTomasz Stanislawski 
4825bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4835bc3cb74SMauro Carvalho Chehab {
4845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4855bc3cb74SMauro Carvalho Chehab 
4865bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%d, count=%d, memory=%s, ",
4875bc3cb74SMauro Carvalho Chehab 			p->index, p->count,
4885bc3cb74SMauro Carvalho Chehab 			prt_names(p->memory, v4l2_memory_names));
4895bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4905bc3cb74SMauro Carvalho Chehab }
4915bc3cb74SMauro Carvalho Chehab 
4925bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4935bc3cb74SMauro Carvalho Chehab {
4945bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4955bc3cb74SMauro Carvalho Chehab 
4965bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
4975bc3cb74SMauro Carvalho Chehab 
4985bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4995bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5005bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5015bc3cb74SMauro Carvalho Chehab 
5025bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, "
5035bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, readbuffers=%d\n",
5045bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5055bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5065bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5075bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5085bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5095bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5105bc3cb74SMauro Carvalho Chehab 
5115bc3cb74SMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, "
5125bc3cb74SMauro Carvalho Chehab 			"extendedmode=%d, writebuffers=%d\n",
5135bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5145bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5155bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
516560dde24SHans Verkuil 	} else {
517560dde24SHans Verkuil 		pr_cont("\n");
5185bc3cb74SMauro Carvalho Chehab 	}
5195bc3cb74SMauro Carvalho Chehab }
5205bc3cb74SMauro Carvalho Chehab 
5215bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5225bc3cb74SMauro Carvalho Chehab {
5235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5245bc3cb74SMauro Carvalho Chehab 
52527d5a87cSHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, "
5265bc3cb74SMauro Carvalho Chehab 		"step=%d, default=%d, flags=0x%08x\n",
52727d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5285bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5295bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5305bc3cb74SMauro Carvalho Chehab }
5315bc3cb74SMauro Carvalho Chehab 
532e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
533e6bee368SHans Verkuil {
534e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
535e6bee368SHans Verkuil 
536e6bee368SHans Verkuil 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, "
537e6bee368SHans Verkuil 		"step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, "
5380176077aSHans Verkuil 		"nr_of_dims=%u, dims=%u,%u,%u,%u\n",
539e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
540e6bee368SHans Verkuil 			p->minimum, p->maximum,
541e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
542e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5430176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
544e6bee368SHans Verkuil }
545e6bee368SHans Verkuil 
5465bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5475bc3cb74SMauro Carvalho Chehab {
5485bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5495bc3cb74SMauro Carvalho Chehab 
5505bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5515bc3cb74SMauro Carvalho Chehab }
5525bc3cb74SMauro Carvalho Chehab 
5535bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5545bc3cb74SMauro Carvalho Chehab {
5555bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
5565bc3cb74SMauro Carvalho Chehab 
5575bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5585bc3cb74SMauro Carvalho Chehab }
5595bc3cb74SMauro Carvalho Chehab 
5605bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5615bc3cb74SMauro Carvalho Chehab {
5625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5635bc3cb74SMauro Carvalho Chehab 	int i;
5645bc3cb74SMauro Carvalho Chehab 
5655bc3cb74SMauro Carvalho Chehab 	pr_cont("class=0x%x, count=%d, error_idx=%d",
5665bc3cb74SMauro Carvalho Chehab 			p->ctrl_class, p->count, p->error_idx);
5675bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
568017ab36aSHans Verkuil 		if (!p->controls[i].size)
5695bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/val=0x%x/0x%x",
5705bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].value);
5715bc3cb74SMauro Carvalho Chehab 		else
5725bc3cb74SMauro Carvalho Chehab 			pr_cont(", id/size=0x%x/%u",
5735bc3cb74SMauro Carvalho Chehab 				p->controls[i].id, p->controls[i].size);
5745bc3cb74SMauro Carvalho Chehab 	}
5755bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5765bc3cb74SMauro Carvalho Chehab }
5775bc3cb74SMauro Carvalho Chehab 
5785bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5795bc3cb74SMauro Carvalho Chehab {
5805bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5815bc3cb74SMauro Carvalho Chehab 
5825bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, "
583a112fbafSHans Verkuil 		"defrect wxh=%dx%d, x,y=%d,%d, "
5845bc3cb74SMauro Carvalho Chehab 		"pixelaspect %d/%d\n",
5855bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5865bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5875bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5885bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5895bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5905bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5915bc3cb74SMauro Carvalho Chehab }
5925bc3cb74SMauro Carvalho Chehab 
5935bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5945bc3cb74SMauro Carvalho Chehab {
5955bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
5965bc3cb74SMauro Carvalho Chehab 
5975bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
5985bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5995bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6005bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6015bc3cb74SMauro Carvalho Chehab }
6025bc3cb74SMauro Carvalho Chehab 
6035bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6045bc3cb74SMauro Carvalho Chehab {
6055bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6065bc3cb74SMauro Carvalho Chehab 
6075bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6085bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6095bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6105bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6115bc3cb74SMauro Carvalho Chehab }
6125bc3cb74SMauro Carvalho Chehab 
6135bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6145bc3cb74SMauro Carvalho Chehab {
6155bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6165bc3cb74SMauro Carvalho Chehab 
6175bc3cb74SMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, "
6185bc3cb74SMauro Carvalho Chehab 		"COM_len=%d, jpeg_markers=0x%x\n",
6195bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6205bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6215bc3cb74SMauro Carvalho Chehab }
6225bc3cb74SMauro Carvalho Chehab 
6235bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6245bc3cb74SMauro Carvalho Chehab {
6255bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6265bc3cb74SMauro Carvalho Chehab 
6275bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6285bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6295bc3cb74SMauro Carvalho Chehab }
6305bc3cb74SMauro Carvalho Chehab 
6315bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6325bc3cb74SMauro Carvalho Chehab {
6335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6345bc3cb74SMauro Carvalho Chehab 
6355bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6365bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6375bc3cb74SMauro Carvalho Chehab }
6385bc3cb74SMauro Carvalho Chehab 
6395bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6405bc3cb74SMauro Carvalho Chehab {
6415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6425bc3cb74SMauro Carvalho Chehab 
6435bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6445bc3cb74SMauro Carvalho Chehab 
6455bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6465bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6475bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6485bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6495bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6505bc3cb74SMauro Carvalho Chehab }
6515bc3cb74SMauro Carvalho Chehab 
65296b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65379b0c640SHans Verkuil {
65496b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65579b0c640SHans Verkuil 
65679b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6573eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
65879b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
65979b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66079b0c640SHans Verkuil 	else
66179b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66279b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66379b0c640SHans Verkuil }
66479b0c640SHans Verkuil 
6655bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6665bc3cb74SMauro Carvalho Chehab {
6675bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6685bc3cb74SMauro Carvalho Chehab 
6695bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6703eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67127d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67227d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6735bc3cb74SMauro Carvalho Chehab 	else
6745bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6755bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6765bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6775bc3cb74SMauro Carvalho Chehab }
6785bc3cb74SMauro Carvalho Chehab 
6795bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6805bc3cb74SMauro Carvalho Chehab {
6815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6825bc3cb74SMauro Carvalho Chehab 
6835bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6845bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6855bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, interlaced=%u, "
6865bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu, "
6875bc3cb74SMauro Carvalho Chehab 			"width=%u, height=%u, polarities=0x%x, "
6885bc3cb74SMauro Carvalho Chehab 			"hfrontporch=%u, hsync=%u, "
6895bc3cb74SMauro Carvalho Chehab 			"hbackporch=%u, vfrontporch=%u, "
6905bc3cb74SMauro Carvalho Chehab 			"vsync=%u, vbackporch=%u, "
6915bc3cb74SMauro Carvalho Chehab 			"il_vfrontporch=%u, il_vsync=%u, "
6925bc3cb74SMauro Carvalho Chehab 			"il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
6935bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6945bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6955bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6965bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6975bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6985bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6995bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
7005bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
7015bc3cb74SMauro Carvalho Chehab 		break;
7025bc3cb74SMauro Carvalho Chehab 	default:
7035bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7045bc3cb74SMauro Carvalho Chehab 		break;
7055bc3cb74SMauro Carvalho Chehab 	}
7065bc3cb74SMauro Carvalho Chehab }
7075bc3cb74SMauro Carvalho Chehab 
7085bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7095bc3cb74SMauro Carvalho Chehab {
7105bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7115bc3cb74SMauro Carvalho Chehab 
7125bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7135bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7145bc3cb74SMauro Carvalho Chehab }
7155bc3cb74SMauro Carvalho Chehab 
7165bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7175bc3cb74SMauro Carvalho Chehab {
7185bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7195bc3cb74SMauro Carvalho Chehab 
7205bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7215bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7225bc3cb74SMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, "
7235bc3cb74SMauro Carvalho Chehab 			"pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7245bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7255bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7265bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7275bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7285bc3cb74SMauro Carvalho Chehab 		break;
7295bc3cb74SMauro Carvalho Chehab 	default:
7305bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7315bc3cb74SMauro Carvalho Chehab 		break;
7325bc3cb74SMauro Carvalho Chehab 	}
7335bc3cb74SMauro Carvalho Chehab }
7345bc3cb74SMauro Carvalho Chehab 
7355bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7365bc3cb74SMauro Carvalho Chehab {
7375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7385bc3cb74SMauro Carvalho Chehab 
7395bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
7405bc3cb74SMauro Carvalho Chehab 			p->index,
7415bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7425bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7435bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7445bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7455bc3cb74SMauro Carvalho Chehab 			p->type);
7465bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7475bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
748560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7495bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7505bc3cb74SMauro Carvalho Chehab 		break;
7515bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
752560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7535bc3cb74SMauro Carvalho Chehab 				p->stepwise.min_width,  p->stepwise.min_height,
7545bc3cb74SMauro Carvalho Chehab 				p->stepwise.step_width, p->stepwise.step_height,
7555bc3cb74SMauro Carvalho Chehab 				p->stepwise.max_width,  p->stepwise.max_height);
7565bc3cb74SMauro Carvalho Chehab 		break;
7575bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7585bc3cb74SMauro Carvalho Chehab 		/* fall through */
7595bc3cb74SMauro Carvalho Chehab 	default:
7605bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7615bc3cb74SMauro Carvalho Chehab 		break;
7625bc3cb74SMauro Carvalho Chehab 	}
7635bc3cb74SMauro Carvalho Chehab }
7645bc3cb74SMauro Carvalho Chehab 
7655bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7665bc3cb74SMauro Carvalho Chehab {
7675bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7685bc3cb74SMauro Carvalho Chehab 
7695bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
7705bc3cb74SMauro Carvalho Chehab 			p->index,
7715bc3cb74SMauro Carvalho Chehab 			(p->pixel_format & 0xff),
7725bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >>  8) & 0xff,
7735bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 16) & 0xff,
7745bc3cb74SMauro Carvalho Chehab 			(p->pixel_format >> 24) & 0xff,
7755bc3cb74SMauro Carvalho Chehab 			p->width, p->height, p->type);
7765bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7775bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
778560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7795bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7805bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7815bc3cb74SMauro Carvalho Chehab 		break;
7825bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
783560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7845bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7855bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7865bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7875bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7885bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7895bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7905bc3cb74SMauro Carvalho Chehab 		break;
7915bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7925bc3cb74SMauro Carvalho Chehab 		/* fall through */
7935bc3cb74SMauro Carvalho Chehab 	default:
7945bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7955bc3cb74SMauro Carvalho Chehab 		break;
7965bc3cb74SMauro Carvalho Chehab 	}
7975bc3cb74SMauro Carvalho Chehab }
7985bc3cb74SMauro Carvalho Chehab 
7995bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
8005bc3cb74SMauro Carvalho Chehab {
8015bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
8025bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
8035bc3cb74SMauro Carvalho Chehab 
8045bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, "
8055bc3cb74SMauro Carvalho Chehab 		"timestamp=%lu.%9.9lu\n",
8065bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
8075bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
8085bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
8095bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
8105bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
8115bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
8125bc3cb74SMauro Carvalho Chehab 		break;
8135bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8145bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8155bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8165bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8175bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8185bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8195bc3cb74SMauro Carvalho Chehab 		else
8205bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8215bc3cb74SMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, "
8225bc3cb74SMauro Carvalho Chehab 			"default_value=%d\n",
8235bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8245bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8255bc3cb74SMauro Carvalho Chehab 		break;
8265bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8275bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8285bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8295bc3cb74SMauro Carvalho Chehab 		break;
8305bc3cb74SMauro Carvalho Chehab 	}
8315bc3cb74SMauro Carvalho Chehab }
8325bc3cb74SMauro Carvalho Chehab 
8335bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8345bc3cb74SMauro Carvalho Chehab {
8355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8365bc3cb74SMauro Carvalho Chehab 
8375bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8385bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8395bc3cb74SMauro Carvalho Chehab }
8405bc3cb74SMauro Carvalho Chehab 
8415bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8425bc3cb74SMauro Carvalho Chehab {
8435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8445bc3cb74SMauro Carvalho Chehab 	int i;
8455bc3cb74SMauro Carvalho Chehab 
8465bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8475bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8485bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8495bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8505bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8515bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8525bc3cb74SMauro Carvalho Chehab }
8535bc3cb74SMauro Carvalho Chehab 
8545bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8555bc3cb74SMauro Carvalho Chehab {
8565bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8575bc3cb74SMauro Carvalho Chehab 
8585bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, "
8595bc3cb74SMauro Carvalho Chehab 		"rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8605bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8615bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8625bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8635bc3cb74SMauro Carvalho Chehab }
8645bc3cb74SMauro Carvalho Chehab 
865dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
866dd519bb3SHans Verkuil {
867dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
868dd519bb3SHans Verkuil 
869dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
870dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
871dd519bb3SHans Verkuil }
872dd519bb3SHans Verkuil 
8735bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8745bc3cb74SMauro Carvalho Chehab {
8755bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8765bc3cb74SMauro Carvalho Chehab }
8775bc3cb74SMauro Carvalho Chehab 
8785bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8795bc3cb74SMauro Carvalho Chehab {
8805bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8815bc3cb74SMauro Carvalho Chehab }
8825bc3cb74SMauro Carvalho Chehab 
8835bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8845bc3cb74SMauro Carvalho Chehab {
8855bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8865bc3cb74SMauro Carvalho Chehab }
8875bc3cb74SMauro Carvalho Chehab 
8885bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
8895bc3cb74SMauro Carvalho Chehab {
8905bc3cb74SMauro Carvalho Chehab 	__u32 i;
8915bc3cb74SMauro Carvalho Chehab 
8925bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
8935bc3cb74SMauro Carvalho Chehab 	c->reserved[0] = c->reserved[1] = 0;
8945bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8955bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8965bc3cb74SMauro Carvalho Chehab 
8975bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
8985bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
8995bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
9005bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
9015bc3cb74SMauro Carvalho Chehab 	 */
9025bc3cb74SMauro Carvalho Chehab 	if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
9035bc3cb74SMauro Carvalho Chehab 		return 0;
9045bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9055bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9065bc3cb74SMauro Carvalho Chehab 		if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
9075bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
9085bc3cb74SMauro Carvalho Chehab 			return 0;
9095bc3cb74SMauro Carvalho Chehab 		}
9105bc3cb74SMauro Carvalho Chehab 	}
9115bc3cb74SMauro Carvalho Chehab 	return 1;
9125bc3cb74SMauro Carvalho Chehab }
9135bc3cb74SMauro Carvalho Chehab 
9144b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9155bc3cb74SMauro Carvalho Chehab {
9164b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9174b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
9184b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
9194b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
920582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
9214b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9224b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9234b20259fSHans Verkuil 
9245bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9255bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9265bc3cb74SMauro Carvalho Chehab 
9275bc3cb74SMauro Carvalho Chehab 	switch (type) {
9285bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
9294b20259fSHans Verkuil 		if (is_vid && is_rx &&
9304b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9315bc3cb74SMauro Carvalho Chehab 			return 0;
9325bc3cb74SMauro Carvalho Chehab 		break;
9335bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9344b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9355bc3cb74SMauro Carvalho Chehab 			return 0;
9365bc3cb74SMauro Carvalho Chehab 		break;
9375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9384b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9395bc3cb74SMauro Carvalho Chehab 			return 0;
9405bc3cb74SMauro Carvalho Chehab 		break;
9415bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9424b20259fSHans Verkuil 		if (is_vid && is_tx &&
9434b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9445bc3cb74SMauro Carvalho Chehab 			return 0;
9455bc3cb74SMauro Carvalho Chehab 		break;
9465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9474b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9485bc3cb74SMauro Carvalho Chehab 			return 0;
9495bc3cb74SMauro Carvalho Chehab 		break;
9505bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9514b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9525bc3cb74SMauro Carvalho Chehab 			return 0;
9535bc3cb74SMauro Carvalho Chehab 		break;
9545bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9554b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9565bc3cb74SMauro Carvalho Chehab 			return 0;
9575bc3cb74SMauro Carvalho Chehab 		break;
9585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9594b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9605bc3cb74SMauro Carvalho Chehab 			return 0;
9615bc3cb74SMauro Carvalho Chehab 		break;
9625bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9634b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9645bc3cb74SMauro Carvalho Chehab 			return 0;
9655bc3cb74SMauro Carvalho Chehab 		break;
9665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9674b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9685bc3cb74SMauro Carvalho Chehab 			return 0;
9695bc3cb74SMauro Carvalho Chehab 		break;
970582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
971582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
972582c52cbSAntti Palosaari 			return 0;
973582c52cbSAntti Palosaari 		break;
974633c98e5SHans Verkuil 	default:
9755bc3cb74SMauro Carvalho Chehab 		break;
9765bc3cb74SMauro Carvalho Chehab 	}
9775bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9785bc3cb74SMauro Carvalho Chehab }
9795bc3cb74SMauro Carvalho Chehab 
980d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
981d52e2381SLaurent Pinchart {
982d52e2381SLaurent Pinchart 	unsigned int offset;
983d52e2381SLaurent Pinchart 
984d52e2381SLaurent Pinchart 	/*
985d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
986d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
987d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
988d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
989d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
990d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
991d52e2381SLaurent Pinchart 	 * isn't used by applications.
992d52e2381SLaurent Pinchart 	 */
993d52e2381SLaurent Pinchart 
994d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
995d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
996d52e2381SLaurent Pinchart 		return;
997d52e2381SLaurent Pinchart 
998d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
999d52e2381SLaurent Pinchart 		return;
1000d52e2381SLaurent Pinchart 
1001d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1002d52e2381SLaurent Pinchart 
1003d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1004d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1005d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1006d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1007d52e2381SLaurent Pinchart }
1008d52e2381SLaurent Pinchart 
10095bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10115bc3cb74SMauro Carvalho Chehab {
10125bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
1013d52e2381SLaurent Pinchart 	int ret;
10145bc3cb74SMauro Carvalho Chehab 
10155bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
1016d52e2381SLaurent Pinchart 
1017d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1018d52e2381SLaurent Pinchart 
1019d52e2381SLaurent Pinchart 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1020796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1021d52e2381SLaurent Pinchart 
1022d52e2381SLaurent Pinchart 	return ret;
10235bc3cb74SMauro Carvalho Chehab }
10245bc3cb74SMauro Carvalho Chehab 
10255bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10265bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10275bc3cb74SMauro Carvalho Chehab {
10285bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10295bc3cb74SMauro Carvalho Chehab }
10305bc3cb74SMauro Carvalho Chehab 
10315bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10325bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10335bc3cb74SMauro Carvalho Chehab {
10345bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10355bc3cb74SMauro Carvalho Chehab }
10365bc3cb74SMauro Carvalho Chehab 
10375bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
10385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10395bc3cb74SMauro Carvalho Chehab {
10405bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10415bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10425bc3cb74SMauro Carvalho Chehab 
10435bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_priority)
10445bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_priority(file, fh, arg);
10455bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
104659b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
10475bc3cb74SMauro Carvalho Chehab 	return 0;
10485bc3cb74SMauro Carvalho Chehab }
10495bc3cb74SMauro Carvalho Chehab 
10505bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
10515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10525bc3cb74SMauro Carvalho Chehab {
10535bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
10545bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
10555bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
10565bc3cb74SMauro Carvalho Chehab 
10575bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_priority)
10585bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_priority(file, fh, *p);
10595bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
10605bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
106159b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
10625bc3cb74SMauro Carvalho Chehab }
10635bc3cb74SMauro Carvalho Chehab 
10645bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
10655bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10665bc3cb74SMauro Carvalho Chehab {
106773f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10685bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
10695bc3cb74SMauro Carvalho Chehab 
10705bc3cb74SMauro Carvalho Chehab 	/*
107102fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10725bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10735bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10745bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
10755bc3cb74SMauro Carvalho Chehab 	 */
107673f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
10775bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
10785bc3cb74SMauro Carvalho Chehab 
10795bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
10805bc3cb74SMauro Carvalho Chehab }
10815bc3cb74SMauro Carvalho Chehab 
10825bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
10835bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10845bc3cb74SMauro Carvalho Chehab {
108573f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
10865bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
10875bc3cb74SMauro Carvalho Chehab 
10885bc3cb74SMauro Carvalho Chehab 	/*
108902fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
10905bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
10915bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
10925bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
10935bc3cb74SMauro Carvalho Chehab 	 */
109473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
10955bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
10965bc3cb74SMauro Carvalho Chehab 
10975bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
10985bc3cb74SMauro Carvalho Chehab }
10995bc3cb74SMauro Carvalho Chehab 
11005bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
11015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11025bc3cb74SMauro Carvalho Chehab {
11035bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
11044b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1105ce71bbc9SHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1106ce71bbc9SHans Verkuil 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
11074b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
11084b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
11095bc3cb74SMauro Carvalho Chehab 
11105bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
11115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1112ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap))
11135bc3cb74SMauro Carvalho Chehab 			break;
11145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
11155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1116ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
11175bc3cb74SMauro Carvalho Chehab 			break;
11185bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
11195bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1120ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
11215bc3cb74SMauro Carvalho Chehab 			break;
11225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
11235bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1124ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
11255bc3cb74SMauro Carvalho Chehab 			break;
11265bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_enum_fmt_vid_out(file, fh, arg);
11275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1128ce71bbc9SHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
11295bc3cb74SMauro Carvalho Chehab 			break;
11305bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
1131582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1132ce71bbc9SHans Verkuil 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
1133582c52cbSAntti Palosaari 			break;
1134582c52cbSAntti Palosaari 		return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
11355bc3cb74SMauro Carvalho Chehab 	}
11365bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
11375bc3cb74SMauro Carvalho Chehab }
11385bc3cb74SMauro Carvalho Chehab 
11395bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
11405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11415bc3cb74SMauro Carvalho Chehab {
11425bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
11434b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
11444b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1145582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
11464b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
11474b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1148d52e2381SLaurent Pinchart 	int ret;
1149d52e2381SLaurent Pinchart 
1150e5ce558aSHans Verkuil 	/*
1151e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1152e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1153e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1154e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1155e5ce558aSHans Verkuil 	 */
1156e5ce558aSHans Verkuil 	switch (p->type) {
1157e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1158e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
11594d1afa51SHans Verkuil 		struct v4l2_clip __user *clips = p->fmt.win.clips;
1160e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
11614d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1162e5ce558aSHans Verkuil 
1163e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1164e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1165e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1166e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1167e5ce558aSHans Verkuil 		break;
1168e5ce558aSHans Verkuil 	}
1169e5ce558aSHans Verkuil 	default:
1170e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1171e5ce558aSHans Verkuil 		break;
1172e5ce558aSHans Verkuil 	}
1173e5ce558aSHans Verkuil 
11745bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
11755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
11764b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
11775bc3cb74SMauro Carvalho Chehab 			break;
117848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1179d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
118048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1181d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1182d52e2381SLaurent Pinchart 		return ret;
11835bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11844b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
11855bc3cb74SMauro Carvalho Chehab 			break;
11865bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
11875bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
11884b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
11895bc3cb74SMauro Carvalho Chehab 			break;
11905bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
11914b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
11924b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
11934b20259fSHans Verkuil 			break;
11944b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
11954b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11964b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
11974b20259fSHans Verkuil 			break;
11984b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
11995bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
12004b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
12015bc3cb74SMauro Carvalho Chehab 			break;
120248f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1203d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
120448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1205d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1206d52e2381SLaurent Pinchart 		return ret;
12075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
12084b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
12095bc3cb74SMauro Carvalho Chehab 			break;
12105bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
12115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
12124b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
12135bc3cb74SMauro Carvalho Chehab 			break;
12145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
12155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
12164b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
12175bc3cb74SMauro Carvalho Chehab 			break;
12185bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
12195bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
12204b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
12215bc3cb74SMauro Carvalho Chehab 			break;
12225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1223582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1224582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
1225582c52cbSAntti Palosaari 			break;
1226582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
12275bc3cb74SMauro Carvalho Chehab 	}
12285bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
12295bc3cb74SMauro Carvalho Chehab }
12305bc3cb74SMauro Carvalho Chehab 
12315bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
12325bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
12335bc3cb74SMauro Carvalho Chehab {
12345bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
12354b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
12364b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1237582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
12384b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
12394b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
124048f2650aSHans Verkuil 	int ret;
12415bc3cb74SMauro Carvalho Chehab 
1242d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1243d52e2381SLaurent Pinchart 
12445bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
12455bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
12464b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
12475bc3cb74SMauro Carvalho Chehab 			break;
12485bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
124948f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
125048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
125148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
125248f2650aSHans Verkuil 		return ret;
12535bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
12544b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
12555bc3cb74SMauro Carvalho Chehab 			break;
12565bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
12575bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
12585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
12594b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
12605bc3cb74SMauro Carvalho Chehab 			break;
12615bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
12625bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
12634b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
12644b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
12654b20259fSHans Verkuil 			break;
12664b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
12674b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
12684b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
12694b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
12704b20259fSHans Verkuil 			break;
12714b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
12724b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
12735bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
12744b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
12755bc3cb74SMauro Carvalho Chehab 			break;
12765bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
127748f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
127848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
127948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
128048f2650aSHans Verkuil 		return ret;
12815bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
12824b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
12835bc3cb74SMauro Carvalho Chehab 			break;
12845bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
12855bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
12865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
12874b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
12885bc3cb74SMauro Carvalho Chehab 			break;
12895bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
12905bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
12915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
12924b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
12935bc3cb74SMauro Carvalho Chehab 			break;
12945bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
12955bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
12965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
12974b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
12985bc3cb74SMauro Carvalho Chehab 			break;
12995bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
13005bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1301582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1302582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
1303582c52cbSAntti Palosaari 			break;
1304582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1305582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
13065bc3cb74SMauro Carvalho Chehab 	}
13075bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
13085bc3cb74SMauro Carvalho Chehab }
13095bc3cb74SMauro Carvalho Chehab 
13105bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
13115bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13125bc3cb74SMauro Carvalho Chehab {
13135bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
13144b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
13154b20259fSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
1316582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
13174b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
13184b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
131948f2650aSHans Verkuil 	int ret;
13205bc3cb74SMauro Carvalho Chehab 
1321d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1322d52e2381SLaurent Pinchart 
13235bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
13245bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
13254b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
13265bc3cb74SMauro Carvalho Chehab 			break;
13275bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
132848f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
132948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
133048f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
133148f2650aSHans Verkuil 		return ret;
13325bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
13334b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
13345bc3cb74SMauro Carvalho Chehab 			break;
13355bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
13365bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
13375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
13384b20259fSHans Verkuil 		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
13395bc3cb74SMauro Carvalho Chehab 			break;
13405bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
13415bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
13424b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
13434b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
13444b20259fSHans Verkuil 			break;
13454b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi);
13464b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
13474b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
13484b20259fSHans Verkuil 		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
13494b20259fSHans Verkuil 			break;
13504b20259fSHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced);
13514b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
13525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
13534b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
13545bc3cb74SMauro Carvalho Chehab 			break;
13555bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
135648f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
135748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
135848f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
135948f2650aSHans Verkuil 		return ret;
13605bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
13614b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
13625bc3cb74SMauro Carvalho Chehab 			break;
13635bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix_mp);
13645bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
13655bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
13664b20259fSHans Verkuil 		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
13675bc3cb74SMauro Carvalho Chehab 			break;
13685bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
13695bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
13705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
13714b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
13725bc3cb74SMauro Carvalho Chehab 			break;
13735bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.vbi);
13745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
13755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
13764b20259fSHans Verkuil 		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
13775bc3cb74SMauro Carvalho Chehab 			break;
13785bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.sliced);
13795bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1380582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1381582c52cbSAntti Palosaari 		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
1382582c52cbSAntti Palosaari 			break;
1383582c52cbSAntti Palosaari 		CLEAR_AFTER_FIELD(p, fmt.sdr);
1384582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
13855bc3cb74SMauro Carvalho Chehab 	}
13865bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
13875bc3cb74SMauro Carvalho Chehab }
13885bc3cb74SMauro Carvalho Chehab 
13895bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
13905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13915bc3cb74SMauro Carvalho Chehab {
13925bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
13935bc3cb74SMauro Carvalho Chehab }
13945bc3cb74SMauro Carvalho Chehab 
13955bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
13965bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
13975bc3cb74SMauro Carvalho Chehab {
13985bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
13995bc3cb74SMauro Carvalho Chehab }
14005bc3cb74SMauro Carvalho Chehab 
14015bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
14025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14035bc3cb74SMauro Carvalho Chehab {
14045bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
14055bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
14065bc3cb74SMauro Carvalho Chehab 	int err;
14075bc3cb74SMauro Carvalho Chehab 
14085bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
14095bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
14105bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
14115bc3cb74SMauro Carvalho Chehab 	if (!err)
14125bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
14135bc3cb74SMauro Carvalho Chehab 	return err;
14145bc3cb74SMauro Carvalho Chehab }
14155bc3cb74SMauro Carvalho Chehab 
14165bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
14175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14185bc3cb74SMauro Carvalho Chehab {
14195bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
14205bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
14215bc3cb74SMauro Carvalho Chehab 
14225bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
14235bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
14245bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
14255bc3cb74SMauro Carvalho Chehab }
14265bc3cb74SMauro Carvalho Chehab 
14275bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
14285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14295bc3cb74SMauro Carvalho Chehab {
14305bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
14315bc3cb74SMauro Carvalho Chehab 	int err;
14325bc3cb74SMauro Carvalho Chehab 
14335bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
14345bc3cb74SMauro Carvalho Chehab 	if (!err)
14355bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
14365bc3cb74SMauro Carvalho Chehab 	return err;
14375bc3cb74SMauro Carvalho Chehab }
14385bc3cb74SMauro Carvalho Chehab 
14395bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
14405bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14415bc3cb74SMauro Carvalho Chehab {
14425bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
14435bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
14445bc3cb74SMauro Carvalho Chehab 
144584099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
144684099a28SAntti Palosaari 		p->type = V4L2_TUNER_ADC;
144784099a28SAntti Palosaari 	else
14485bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
14495bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
14505bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
14515bc3cb74SMauro Carvalho Chehab }
14525bc3cb74SMauro Carvalho Chehab 
14535bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
14545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14555bc3cb74SMauro Carvalho Chehab {
14565bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1457b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
14585bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
14595bc3cb74SMauro Carvalho Chehab 
146084099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
146184099a28SAntti Palosaari 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
146284099a28SAntti Palosaari 			return -EINVAL;
146384099a28SAntti Palosaari 	} else {
14645bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
14655bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
146684099a28SAntti Palosaari 		if (type != p->type)
14675bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
146884099a28SAntti Palosaari 	}
14695bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
14705bc3cb74SMauro Carvalho Chehab }
14715bc3cb74SMauro Carvalho Chehab 
14725bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
14735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14745bc3cb74SMauro Carvalho Chehab {
14755bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
14765bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
14775bc3cb74SMauro Carvalho Chehab 	v4l2_std_id id = vfd->tvnorms, curr_id = 0;
14785bc3cb74SMauro Carvalho Chehab 	unsigned int index = p->index, i, j = 0;
14795bc3cb74SMauro Carvalho Chehab 	const char *descr = "";
14805bc3cb74SMauro Carvalho Chehab 
1481a5338190SHans Verkuil 	/* Return -ENODATA if the tvnorms for the current input
1482a5338190SHans Verkuil 	   or output is 0, meaning that it doesn't support this API. */
1483a5338190SHans Verkuil 	if (id == 0)
1484a5338190SHans Verkuil 		return -ENODATA;
1485a5338190SHans Verkuil 
14865bc3cb74SMauro Carvalho Chehab 	/* Return norm array in a canonical way */
14875bc3cb74SMauro Carvalho Chehab 	for (i = 0; i <= index && id; i++) {
14885bc3cb74SMauro Carvalho Chehab 		/* last std value in the standards array is 0, so this
14895bc3cb74SMauro Carvalho Chehab 		   while always ends there since (id & 0) == 0. */
14905bc3cb74SMauro Carvalho Chehab 		while ((id & standards[j].std) != standards[j].std)
14915bc3cb74SMauro Carvalho Chehab 			j++;
14925bc3cb74SMauro Carvalho Chehab 		curr_id = standards[j].std;
14935bc3cb74SMauro Carvalho Chehab 		descr = standards[j].descr;
14945bc3cb74SMauro Carvalho Chehab 		j++;
14955bc3cb74SMauro Carvalho Chehab 		if (curr_id == 0)
14965bc3cb74SMauro Carvalho Chehab 			break;
14975bc3cb74SMauro Carvalho Chehab 		if (curr_id != V4L2_STD_PAL &&
14985bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_SECAM &&
14995bc3cb74SMauro Carvalho Chehab 				curr_id != V4L2_STD_NTSC)
15005bc3cb74SMauro Carvalho Chehab 			id &= ~curr_id;
15015bc3cb74SMauro Carvalho Chehab 	}
15025bc3cb74SMauro Carvalho Chehab 	if (i <= index)
15035bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
15045bc3cb74SMauro Carvalho Chehab 
15055bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_construct(p, curr_id, descr);
15065bc3cb74SMauro Carvalho Chehab 	return 0;
15075bc3cb74SMauro Carvalho Chehab }
15085bc3cb74SMauro Carvalho Chehab 
15095bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
15105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15115bc3cb74SMauro Carvalho Chehab {
15125bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1513314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
15145bc3cb74SMauro Carvalho Chehab 
1515314527acSHans Verkuil 	norm = id & vfd->tvnorms;
15165bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
15175bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
15185bc3cb74SMauro Carvalho Chehab 
15195bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1520ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
15215bc3cb74SMauro Carvalho Chehab }
15225bc3cb74SMauro Carvalho Chehab 
15235bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
15245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15255bc3cb74SMauro Carvalho Chehab {
15265bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
15275bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
15285bc3cb74SMauro Carvalho Chehab 
15295bc3cb74SMauro Carvalho Chehab 	/*
15301a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
15311a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
15321a2c6866SHans Verkuil 	 * any standards that do not apply removed.
15331a2c6866SHans Verkuil 	 *
15345bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
15355bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
15365bc3cb74SMauro Carvalho Chehab 	 */
15375bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
15385bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
15395bc3cb74SMauro Carvalho Chehab }
15405bc3cb74SMauro Carvalho Chehab 
15415bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
15425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15435bc3cb74SMauro Carvalho Chehab {
15445bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
15455bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
15465bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
15475bc3cb74SMauro Carvalho Chehab 
154884099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
154984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
155084099a28SAntti Palosaari 		return -EINVAL;
155184099a28SAntti Palosaari 
15525bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
15535bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
15545bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
15555bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
15565bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
15575bc3cb74SMauro Carvalho Chehab }
15585bc3cb74SMauro Carvalho Chehab 
1559737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1560737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1561737c097bSHans Verkuil {
1562737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1563737c097bSHans Verkuil }
1564737c097bSHans Verkuil 
15655bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
15665bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15675bc3cb74SMauro Carvalho Chehab {
15685bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
15694b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
15705bc3cb74SMauro Carvalho Chehab 
15715bc3cb74SMauro Carvalho Chehab 	if (ret)
15725bc3cb74SMauro Carvalho Chehab 		return ret;
15735bc3cb74SMauro Carvalho Chehab 
15745bc3cb74SMauro Carvalho Chehab 	CLEAR_AFTER_FIELD(p, memory);
15755bc3cb74SMauro Carvalho Chehab 
15765bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
15775bc3cb74SMauro Carvalho Chehab }
15785bc3cb74SMauro Carvalho Chehab 
15795bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
15805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15815bc3cb74SMauro Carvalho Chehab {
15825bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
15834b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
15845bc3cb74SMauro Carvalho Chehab 
15855bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
15865bc3cb74SMauro Carvalho Chehab }
15875bc3cb74SMauro Carvalho Chehab 
15885bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
15895bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15905bc3cb74SMauro Carvalho Chehab {
15915bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
15924b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
15935bc3cb74SMauro Carvalho Chehab 
15945bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
15955bc3cb74SMauro Carvalho Chehab }
15965bc3cb74SMauro Carvalho Chehab 
15975bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
15985bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15995bc3cb74SMauro Carvalho Chehab {
16005bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
16014b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
16025bc3cb74SMauro Carvalho Chehab 
16035bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
16045bc3cb74SMauro Carvalho Chehab }
16055bc3cb74SMauro Carvalho Chehab 
16065bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
16075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16085bc3cb74SMauro Carvalho Chehab {
16095bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
16104b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
16115bc3cb74SMauro Carvalho Chehab 
1612d52e2381SLaurent Pinchart 	if (ret)
1613d52e2381SLaurent Pinchart 		return ret;
1614d52e2381SLaurent Pinchart 
1615d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
1616d52e2381SLaurent Pinchart 
1617d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
1618d52e2381SLaurent Pinchart 
1619d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1620d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1621d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1622d52e2381SLaurent Pinchart 
1623d52e2381SLaurent Pinchart 	return ret;
16245bc3cb74SMauro Carvalho Chehab }
16255bc3cb74SMauro Carvalho Chehab 
16265bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
16275bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16285bc3cb74SMauro Carvalho Chehab {
16295bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
16304b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
16315bc3cb74SMauro Carvalho Chehab 
16325bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
16335bc3cb74SMauro Carvalho Chehab }
16345bc3cb74SMauro Carvalho Chehab 
16355bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
16365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16375bc3cb74SMauro Carvalho Chehab {
16385bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
16395bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
16404b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
16415bc3cb74SMauro Carvalho Chehab 
16425bc3cb74SMauro Carvalho Chehab 	if (ret)
16435bc3cb74SMauro Carvalho Chehab 		return ret;
16445bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
16455bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
16465bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
16475bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
16485bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
16495bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
16505bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
16515bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
1652ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
16535bc3cb74SMauro Carvalho Chehab 	return ret;
16545bc3cb74SMauro Carvalho Chehab }
16555bc3cb74SMauro Carvalho Chehab 
16565bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
16575bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16585bc3cb74SMauro Carvalho Chehab {
16595bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
16604b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
16615bc3cb74SMauro Carvalho Chehab 
16625bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_s_parm(file, fh, p);
16635bc3cb74SMauro Carvalho Chehab }
16645bc3cb74SMauro Carvalho Chehab 
16655bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
16665bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16675bc3cb74SMauro Carvalho Chehab {
16685bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
16695bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
16705bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
16715bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
16725bc3cb74SMauro Carvalho Chehab 
16735bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
16745bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
16755bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
16765bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
16775bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
16785bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
16795bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
16805bc3cb74SMauro Carvalho Chehab }
16815bc3cb74SMauro Carvalho Chehab 
1682e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
1683e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
1684e6bee368SHans Verkuil {
1685e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1686e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
1687e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
1688e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
1689e6bee368SHans Verkuil 
1690e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
1691e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
1692e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
1693e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
1694e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
1695e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
1696e6bee368SHans Verkuil 	return -ENOTTY;
1697e6bee368SHans Verkuil }
1698e6bee368SHans Verkuil 
16995bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
17005bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17015bc3cb74SMauro Carvalho Chehab {
17025bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17035bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
17045bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
17055bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
17065bc3cb74SMauro Carvalho Chehab 
17075bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
17085bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
17095bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
17105bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
17115bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
17125bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
17135bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
17145bc3cb74SMauro Carvalho Chehab }
17155bc3cb74SMauro Carvalho Chehab 
17165bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
17175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17185bc3cb74SMauro Carvalho Chehab {
17195bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17205bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
17215bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
17225bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
17235bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
17245bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
17255bc3cb74SMauro Carvalho Chehab 
17265bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
17275bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
17285bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
17295bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
17305bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
17315bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
17325bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
17335bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
17345bc3cb74SMauro Carvalho Chehab 
17355bc3cb74SMauro Carvalho Chehab 	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
17365bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
17375bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
17385bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
17395bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
17405bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
17415bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
17425bc3cb74SMauro Carvalho Chehab 
17435bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
17445bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
17455bc3cb74SMauro Carvalho Chehab 		return ret;
17465bc3cb74SMauro Carvalho Chehab 	}
17475bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17485bc3cb74SMauro Carvalho Chehab }
17495bc3cb74SMauro Carvalho Chehab 
17505bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
17515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17525bc3cb74SMauro Carvalho Chehab {
17535bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17545bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
17555bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
17565bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
17575bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
17585bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
17595bc3cb74SMauro Carvalho Chehab 
17605bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
17615bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
17625bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
17635bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
17645bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
17655bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
17665bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
17675bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
17685bc3cb74SMauro Carvalho Chehab 
17695bc3cb74SMauro Carvalho Chehab 	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
17705bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
17715bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
17725bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
17735bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
17745bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
17755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
17765bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17775bc3cb74SMauro Carvalho Chehab }
17785bc3cb74SMauro Carvalho Chehab 
17795bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
17805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17815bc3cb74SMauro Carvalho Chehab {
17825bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
17835bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
17845bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
17855bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
17865bc3cb74SMauro Carvalho Chehab 
17875bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
17885bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
17895bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
17905bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
17915bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
17925bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
17935bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
17945bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
17955bc3cb74SMauro Carvalho Chehab 					-EINVAL;
17965bc3cb74SMauro Carvalho Chehab }
17975bc3cb74SMauro Carvalho Chehab 
17985bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
17995bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18005bc3cb74SMauro Carvalho Chehab {
18015bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18025bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
18035bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
18045bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
18055bc3cb74SMauro Carvalho Chehab 
18065bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
18075bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
18085bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
18095bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
18105bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
18115bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
18125bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
18135bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
18145bc3cb74SMauro Carvalho Chehab 					-EINVAL;
18155bc3cb74SMauro Carvalho Chehab }
18165bc3cb74SMauro Carvalho Chehab 
18175bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
18185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18195bc3cb74SMauro Carvalho Chehab {
18205bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18215bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
18225bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
18235bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
18245bc3cb74SMauro Carvalho Chehab 
18255bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
18265bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
18275bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
18285bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
18295bc3cb74SMauro Carvalho Chehab 		return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
18305bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
18315bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
18325bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
18335bc3cb74SMauro Carvalho Chehab 					-EINVAL;
18345bc3cb74SMauro Carvalho Chehab }
18355bc3cb74SMauro Carvalho Chehab 
18365bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
18375bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18385bc3cb74SMauro Carvalho Chehab {
18395bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
18405bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
18415bc3cb74SMauro Carvalho Chehab 		.type = p->type,
18425bc3cb74SMauro Carvalho Chehab 	};
18435bc3cb74SMauro Carvalho Chehab 	int ret;
18445bc3cb74SMauro Carvalho Chehab 
18455bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_crop)
18465bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_crop(file, fh, p);
18475bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
18485bc3cb74SMauro Carvalho Chehab 
18495bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
18505bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
18515bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
18525bc3cb74SMauro Carvalho Chehab 	else
18535bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
18545bc3cb74SMauro Carvalho Chehab 
18555bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_selection(file, fh, &s);
18565bc3cb74SMauro Carvalho Chehab 
18575bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
18585bc3cb74SMauro Carvalho Chehab 	if (!ret)
18595bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
18605bc3cb74SMauro Carvalho Chehab 	return ret;
18615bc3cb74SMauro Carvalho Chehab }
18625bc3cb74SMauro Carvalho Chehab 
18635bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
18645bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18655bc3cb74SMauro Carvalho Chehab {
18665bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
18675bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
18685bc3cb74SMauro Carvalho Chehab 		.type = p->type,
18695bc3cb74SMauro Carvalho Chehab 		.r = p->c,
18705bc3cb74SMauro Carvalho Chehab 	};
18715bc3cb74SMauro Carvalho Chehab 
18725bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_crop)
18735bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_crop(file, fh, p);
18745bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
18755bc3cb74SMauro Carvalho Chehab 
18765bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
18775bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
18785bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
18795bc3cb74SMauro Carvalho Chehab 	else
18805bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_ACTIVE;
18815bc3cb74SMauro Carvalho Chehab 
18825bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_selection(file, fh, &s);
18835bc3cb74SMauro Carvalho Chehab }
18845bc3cb74SMauro Carvalho Chehab 
18855bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
18865bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18875bc3cb74SMauro Carvalho Chehab {
18885bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
18899409945cSHans Verkuil 
18909409945cSHans Verkuil 	if (ops->vidioc_g_selection) {
18915bc3cb74SMauro Carvalho Chehab 		struct v4l2_selection s = { .type = p->type };
18925bc3cb74SMauro Carvalho Chehab 		int ret;
18935bc3cb74SMauro Carvalho Chehab 
18945bc3cb74SMauro Carvalho Chehab 		/* obtaining bounds */
18955bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
18965bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
18975bc3cb74SMauro Carvalho Chehab 		else
18985bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_BOUNDS;
18995bc3cb74SMauro Carvalho Chehab 
19005bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
19015bc3cb74SMauro Carvalho Chehab 		if (ret)
19025bc3cb74SMauro Carvalho Chehab 			return ret;
19035bc3cb74SMauro Carvalho Chehab 		p->bounds = s.r;
19045bc3cb74SMauro Carvalho Chehab 
19055bc3cb74SMauro Carvalho Chehab 		/* obtaining defrect */
19065bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_OUTPUT(p->type))
19075bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
19085bc3cb74SMauro Carvalho Chehab 		else
19095bc3cb74SMauro Carvalho Chehab 			s.target = V4L2_SEL_TGT_CROP_DEFAULT;
19105bc3cb74SMauro Carvalho Chehab 
19115bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_g_selection(file, fh, &s);
19125bc3cb74SMauro Carvalho Chehab 		if (ret)
19135bc3cb74SMauro Carvalho Chehab 			return ret;
19145bc3cb74SMauro Carvalho Chehab 		p->defrect = s.r;
19159409945cSHans Verkuil 	}
19165bc3cb74SMauro Carvalho Chehab 
19175bc3cb74SMauro Carvalho Chehab 	/* setting trivial pixelaspect */
19185bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.numerator = 1;
19195bc3cb74SMauro Carvalho Chehab 	p->pixelaspect.denominator = 1;
19209409945cSHans Verkuil 
19219409945cSHans Verkuil 	if (ops->vidioc_cropcap)
19229409945cSHans Verkuil 		return ops->vidioc_cropcap(file, fh, p);
19239409945cSHans Verkuil 
19245bc3cb74SMauro Carvalho Chehab 	return 0;
19255bc3cb74SMauro Carvalho Chehab }
19265bc3cb74SMauro Carvalho Chehab 
19275bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
19285bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19295bc3cb74SMauro Carvalho Chehab {
19305bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19315bc3cb74SMauro Carvalho Chehab 	int ret;
19325bc3cb74SMauro Carvalho Chehab 
19335bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
19345bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
19355bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
19365bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
19375bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
19385bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
19395bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
19405bc3cb74SMauro Carvalho Chehab 	return ret;
19415bc3cb74SMauro Carvalho Chehab }
19425bc3cb74SMauro Carvalho Chehab 
19435bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
19445bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19455bc3cb74SMauro Carvalho Chehab {
19465bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
19475bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
194879b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
194979b0c640SHans Verkuil 	struct v4l2_subdev *sd;
195079b0c640SHans Verkuil 	int idx = 0;
19515bc3cb74SMauro Carvalho Chehab 
19525bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
19535bc3cb74SMauro Carvalho Chehab 		return -EPERM;
19543eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
195579b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
195679b0c640SHans Verkuil 			return -EINVAL;
19573eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
19583eef2510SHans Verkuil 			if (p->match.addr == idx++)
195979b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
196079b0c640SHans Verkuil 		return -EINVAL;
196179b0c640SHans Verkuil 	}
1962191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
1963191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
19645bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
196579b0c640SHans Verkuil 	return -EINVAL;
19665bc3cb74SMauro Carvalho Chehab #else
19675bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19685bc3cb74SMauro Carvalho Chehab #endif
19695bc3cb74SMauro Carvalho Chehab }
19705bc3cb74SMauro Carvalho Chehab 
19715bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
19725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19735bc3cb74SMauro Carvalho Chehab {
19745bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
1975977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
197679b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
197779b0c640SHans Verkuil 	struct v4l2_subdev *sd;
197879b0c640SHans Verkuil 	int idx = 0;
19795bc3cb74SMauro Carvalho Chehab 
19805bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
19815bc3cb74SMauro Carvalho Chehab 		return -EPERM;
19823eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
198379b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
198479b0c640SHans Verkuil 			return -EINVAL;
19853eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
19863eef2510SHans Verkuil 			if (p->match.addr == idx++)
198779b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
198879b0c640SHans Verkuil 		return -EINVAL;
198979b0c640SHans Verkuil 	}
1990191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
1991191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
19925bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
199379b0c640SHans Verkuil 	return -EINVAL;
19945bc3cb74SMauro Carvalho Chehab #else
19955bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
19965bc3cb74SMauro Carvalho Chehab #endif
19975bc3cb74SMauro Carvalho Chehab }
19985bc3cb74SMauro Carvalho Chehab 
199996b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
200079b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
200179b0c640SHans Verkuil {
2002cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
200379b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
200496b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
200579b0c640SHans Verkuil 	struct v4l2_subdev *sd;
200679b0c640SHans Verkuil 	int idx = 0;
200779b0c640SHans Verkuil 
200879b0c640SHans Verkuil 	switch (p->match.type) {
200979b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
201079b0c640SHans Verkuil 		if (ops->vidioc_s_register)
201179b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
201279b0c640SHans Verkuil 		if (ops->vidioc_g_register)
201379b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
201479b0c640SHans Verkuil 		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
201596b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
201696b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
20170f0fe4b9SHans Verkuil 		if (p->match.addr)
20180f0fe4b9SHans Verkuil 			return -EINVAL;
201979b0c640SHans Verkuil 		return 0;
202079b0c640SHans Verkuil 
20213eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
202279b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
202379b0c640SHans Verkuil 			break;
202479b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
20253eef2510SHans Verkuil 			if (p->match.addr != idx++)
20263eef2510SHans Verkuil 				continue;
202779b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
202879b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
202979b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
203079b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
203179b0c640SHans Verkuil 			strlcpy(p->name, sd->name, sizeof(p->name));
203279b0c640SHans Verkuil 			return 0;
203379b0c640SHans Verkuil 		}
203479b0c640SHans Verkuil 		break;
203579b0c640SHans Verkuil 	}
203679b0c640SHans Verkuil 	return -EINVAL;
2037cd634f1bSHans Verkuil #else
2038cd634f1bSHans Verkuil 	return -ENOTTY;
2039cd634f1bSHans Verkuil #endif
204079b0c640SHans Verkuil }
204179b0c640SHans Verkuil 
20425bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
20435bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20445bc3cb74SMauro Carvalho Chehab {
20455bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
20465bc3cb74SMauro Carvalho Chehab }
20475bc3cb74SMauro Carvalho Chehab 
20485bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
20495bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20505bc3cb74SMauro Carvalho Chehab {
20515bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
20525bc3cb74SMauro Carvalho Chehab }
20535bc3cb74SMauro Carvalho Chehab 
20545bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
20555bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20565bc3cb74SMauro Carvalho Chehab {
20575bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
20585bc3cb74SMauro Carvalho Chehab }
20595bc3cb74SMauro Carvalho Chehab 
20605bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
20615bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20625bc3cb74SMauro Carvalho Chehab {
20635bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
20644b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20654b20259fSHans Verkuil 
20664b20259fSHans Verkuil 	if (ret)
20674b20259fSHans Verkuil 		return ret;
20685bc3cb74SMauro Carvalho Chehab 
20695bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
20705bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
20715bc3cb74SMauro Carvalho Chehab 
20725bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
20735bc3cb74SMauro Carvalho Chehab }
20745bc3cb74SMauro Carvalho Chehab 
20755bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
20765bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20775bc3cb74SMauro Carvalho Chehab {
20785bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20795bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
20805bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
20815bc3cb74SMauro Carvalho Chehab 	int err;
20825bc3cb74SMauro Carvalho Chehab 
208384099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
208484099a28SAntti Palosaari 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
208584099a28SAntti Palosaari 			return -EINVAL;
208684099a28SAntti Palosaari 		type = p->type;
208784099a28SAntti Palosaari 	} else {
20885bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
20895bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
20905bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
20915bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
209284099a28SAntti Palosaari 	}
2093a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2094a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2095a7f404afSHans Verkuil 		if (err != -ENOTTY)
2096a7f404afSHans Verkuil 			return err;
2097a7f404afSHans Verkuil 	}
209873f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
20995bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
21005bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
21015bc3cb74SMauro Carvalho Chehab 			.type = type,
21025bc3cb74SMauro Carvalho Chehab 		};
21035bc3cb74SMauro Carvalho Chehab 
210479e8c7beSMauro Carvalho Chehab 		if (p->index)
210579e8c7beSMauro Carvalho Chehab 			return -EINVAL;
21065bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
21075bc3cb74SMauro Carvalho Chehab 		if (err)
21085bc3cb74SMauro Carvalho Chehab 			return err;
21095bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
21105bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
21115bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
21125bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
21135bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
21145bc3cb74SMauro Carvalho Chehab 		return 0;
21155bc3cb74SMauro Carvalho Chehab 	}
211673f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
21175bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
21185bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
21195bc3cb74SMauro Carvalho Chehab 		};
21205bc3cb74SMauro Carvalho Chehab 
21215bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
21225bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
212379e8c7beSMauro Carvalho Chehab 		if (p->index)
212479e8c7beSMauro Carvalho Chehab 			return -EINVAL;
21255bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
21265bc3cb74SMauro Carvalho Chehab 		if (err)
21275bc3cb74SMauro Carvalho Chehab 			return err;
21285bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
21295bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
21305bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
21315bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
21325bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
21335bc3cb74SMauro Carvalho Chehab 		return 0;
21345bc3cb74SMauro Carvalho Chehab 	}
21355bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21365bc3cb74SMauro Carvalho Chehab }
21375bc3cb74SMauro Carvalho Chehab 
21385bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
21395bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
21405bc3cb74SMauro Carvalho Chehab 	u32 flags;
21415bc3cb74SMauro Carvalho Chehab 	const char * const name;
21425bc3cb74SMauro Carvalho Chehab 	union {
21435bc3cb74SMauro Carvalho Chehab 		u32 offset;
21445bc3cb74SMauro Carvalho Chehab 		int (*func)(const struct v4l2_ioctl_ops *ops,
21455bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *p);
21465bc3cb74SMauro Carvalho Chehab 	} u;
21475bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
21485bc3cb74SMauro Carvalho Chehab };
21495bc3cb74SMauro Carvalho Chehab 
21505bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
21515bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO	(1 << 0)
21525bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
21535bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL	(1 << 1)
21545bc3cb74SMauro Carvalho Chehab /* This is a standard ioctl, no need for special code */
21555bc3cb74SMauro Carvalho Chehab #define INFO_FL_STD	(1 << 2)
21565bc3cb74SMauro Carvalho Chehab /* This is ioctl has its own function */
21575bc3cb74SMauro Carvalho Chehab #define INFO_FL_FUNC	(1 << 3)
21585bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
21595bc3cb74SMauro Carvalho Chehab #define INFO_FL_QUEUE	(1 << 4)
21605bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
21615bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
21625bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
21635bc3cb74SMauro Carvalho Chehab 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
21645bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
21655bc3cb74SMauro Carvalho Chehab 
21665bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags)			\
21675bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
21685bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
21695bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_STD,				\
21705bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
21715bc3cb74SMauro Carvalho Chehab 		.u.offset = offsetof(struct v4l2_ioctl_ops, _vidioc),	\
21725bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
21735bc3cb74SMauro Carvalho Chehab 	}
21745bc3cb74SMauro Carvalho Chehab 
21755bc3cb74SMauro Carvalho Chehab #define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags)			\
21765bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {						\
21775bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,					\
21785bc3cb74SMauro Carvalho Chehab 		.flags = _flags | INFO_FL_FUNC,				\
21795bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,					\
21805bc3cb74SMauro Carvalho Chehab 		.u.func = _func,					\
21815bc3cb74SMauro Carvalho Chehab 		.debug = _debug,					\
21825bc3cb74SMauro Carvalho Chehab 	}
21835bc3cb74SMauro Carvalho Chehab 
21845bc3cb74SMauro Carvalho Chehab static struct v4l2_ioctl_info v4l2_ioctls[] = {
21855bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
21865bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
2187e5ce558aSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
21885bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
21895bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
21905bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
21915bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
21925bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
2193737c097bSHans Verkuil 	IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
21945bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
2195b799d09aSTomasz Stanislawski 	IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
21965bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
21975bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
21985bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
21995bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
22005bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
2201ca371575SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
22025bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
22035bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
22045bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
22055bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
22065bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
22075bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
22085bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
22095bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
22105bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
22115bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
22125bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
22135bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
22145bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
2215f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0),
2216f9402a94SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO),
22175bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
22185bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
22195bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
22205bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
22215bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
22225bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
22235bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
22245bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
22255bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
22265bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
22275bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
22285bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
2229865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
2230865c4642SHans Verkuil 	IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
22315bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
22325bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
22335bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
22345bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
22355bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
22365bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
22375bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
22385bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
22395bc3cb74SMauro 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)),
22405bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
22415bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
22425bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
22435bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
22445bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
22455bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
22465bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0),
22475bc3cb74SMauro 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)),
22485bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
22495bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
22505bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
22515bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
22525bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
22535bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
22545bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
22555bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
22565bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
22575bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
22585bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
22595bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
22605bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
22615bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0),
22625bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
22635bc3cb74SMauro 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)),
22645bc3cb74SMauro Carvalho Chehab 	IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
226596b03d2aSHans 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)),
2266e6bee368SHans 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)),
22675bc3cb74SMauro Carvalho Chehab };
22685bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
22695bc3cb74SMauro Carvalho Chehab 
22705bc3cb74SMauro Carvalho Chehab bool v4l2_is_known_ioctl(unsigned int cmd)
22715bc3cb74SMauro Carvalho Chehab {
22725bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
22735bc3cb74SMauro Carvalho Chehab 		return false;
22745bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
22755bc3cb74SMauro Carvalho Chehab }
22765bc3cb74SMauro Carvalho Chehab 
22775bc3cb74SMauro Carvalho Chehab struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
22785bc3cb74SMauro Carvalho Chehab {
22795bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
22805bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
22815bc3cb74SMauro Carvalho Chehab 	if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
22825bc3cb74SMauro Carvalho Chehab 		return NULL;
22835bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
22845bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
22855bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
22865bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
22875bc3cb74SMauro Carvalho Chehab }
22885bc3cb74SMauro Carvalho Chehab 
22895bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
22905bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
22915bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
22925bc3cb74SMauro Carvalho Chehab {
22935bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
22945bc3cb74SMauro Carvalho Chehab 
22955bc3cb74SMauro Carvalho Chehab 	if (prefix)
22965bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
22975bc3cb74SMauro Carvalho Chehab 
22985bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
22995bc3cb74SMauro Carvalho Chehab 	case 'd':
23005bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
23015bc3cb74SMauro Carvalho Chehab 		break;
23025bc3cb74SMauro Carvalho Chehab 	case 'V':
23035bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
23045bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
23055bc3cb74SMauro Carvalho Chehab 			break;
23065bc3cb74SMauro Carvalho Chehab 		}
23075bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
23085bc3cb74SMauro Carvalho Chehab 		return;
23095bc3cb74SMauro Carvalho Chehab 	default:
23105bc3cb74SMauro Carvalho Chehab 		type = "unknown";
23115bc3cb74SMauro Carvalho Chehab 		break;
23125bc3cb74SMauro Carvalho Chehab 	}
23135bc3cb74SMauro Carvalho Chehab 
23145bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
23155bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
23165bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
23175bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
23185bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
23195bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
23205bc3cb74SMauro Carvalho Chehab 	}
23215bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
23225bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
23235bc3cb74SMauro Carvalho Chehab }
23245bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
23255bc3cb74SMauro Carvalho Chehab 
23265bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
23275bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
23285bc3cb74SMauro Carvalho Chehab {
23295bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23305bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
23315bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
23325bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
23335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
23345bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
23355bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
23365bc3cb74SMauro Carvalho Chehab 	int debug = vfd->debug;
23375bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
23385bc3cb74SMauro Carvalho Chehab 
23395bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
23405bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
23415bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
23425bc3cb74SMauro Carvalho Chehab 		return ret;
23435bc3cb74SMauro Carvalho Chehab 	}
23445bc3cb74SMauro Carvalho Chehab 
2345b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
23465bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
23475bc3cb74SMauro Carvalho Chehab 
23485bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
23495bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
23505bc3cb74SMauro Carvalho Chehab 
23515bc3cb74SMauro Carvalho Chehab 	        if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
23525bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
23535bc3cb74SMauro Carvalho Chehab 			goto done;
23545bc3cb74SMauro Carvalho Chehab 
2355b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
23565bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
23575bc3cb74SMauro Carvalho Chehab 			if (ret)
23585bc3cb74SMauro Carvalho Chehab 				goto done;
23595bc3cb74SMauro Carvalho Chehab 		}
23605bc3cb74SMauro Carvalho Chehab 	} else {
23615bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
23625bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
23635bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
23645bc3cb74SMauro Carvalho Chehab 		info = &default_info;
23655bc3cb74SMauro Carvalho Chehab 	}
23665bc3cb74SMauro Carvalho Chehab 
23675bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
23685bc3cb74SMauro Carvalho Chehab 	if (info->flags & INFO_FL_STD) {
23695bc3cb74SMauro Carvalho Chehab 		typedef int (*vidioc_op)(struct file *file, void *fh, void *p);
23705bc3cb74SMauro Carvalho Chehab 		const void *p = vfd->ioctl_ops;
23715bc3cb74SMauro Carvalho Chehab 		const vidioc_op *vidioc = p + info->u.offset;
23725bc3cb74SMauro Carvalho Chehab 
23735bc3cb74SMauro Carvalho Chehab 		ret = (*vidioc)(file, fh, arg);
23745bc3cb74SMauro Carvalho Chehab 	} else if (info->flags & INFO_FL_FUNC) {
23755bc3cb74SMauro Carvalho Chehab 		ret = info->u.func(ops, file, fh, arg);
23765bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
23775bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
23785bc3cb74SMauro Carvalho Chehab 	} else {
23795bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2380b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
23815bc3cb74SMauro Carvalho Chehab 			cmd, arg);
23825bc3cb74SMauro Carvalho Chehab 	}
23835bc3cb74SMauro Carvalho Chehab 
23845bc3cb74SMauro Carvalho Chehab done:
23855bc3cb74SMauro Carvalho Chehab 	if (debug) {
23865bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
23875bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2388505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
2389505d04bdSHans Verkuil 		if (debug == V4L2_DEBUG_IOCTL)
23905bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
23915bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
23925bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
23935bc3cb74SMauro Carvalho Chehab 		else {
23945bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
23955bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
23965bc3cb74SMauro Carvalho Chehab 		}
23975bc3cb74SMauro Carvalho Chehab 	}
23985bc3cb74SMauro Carvalho Chehab 
23995bc3cb74SMauro Carvalho Chehab 	return ret;
24005bc3cb74SMauro Carvalho Chehab }
24015bc3cb74SMauro Carvalho Chehab 
24025bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2403ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
24045bc3cb74SMauro Carvalho Chehab {
24055bc3cb74SMauro Carvalho Chehab 	int ret = 0;
24065bc3cb74SMauro Carvalho Chehab 
24075bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
240896b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
24095bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
24105bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
24115bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
24125bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
24135bc3cb74SMauro Carvalho Chehab 
24145bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
24155bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
24165bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
24175bc3cb74SMauro Carvalho Chehab 				break;
24185bc3cb74SMauro Carvalho Chehab 			}
24195bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
2420ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
24215bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
24225bc3cb74SMauro Carvalho Chehab 			ret = 1;
24235bc3cb74SMauro Carvalho Chehab 		}
24245bc3cb74SMauro Carvalho Chehab 		break;
24255bc3cb74SMauro Carvalho Chehab 	}
24265bc3cb74SMauro Carvalho Chehab 
2427dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
2428dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
2429dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
2430ed45ce2cSHans Verkuil 
2431ed45ce2cSHans Verkuil 		if (edid->blocks) {
24321b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
24331b8b10ccSHans Verkuil 				ret = -EINVAL;
24341b8b10ccSHans Verkuil 				break;
24351b8b10ccSHans Verkuil 			}
2436ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
2437ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
2438ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
2439ed45ce2cSHans Verkuil 			ret = 1;
2440ed45ce2cSHans Verkuil 		}
2441ed45ce2cSHans Verkuil 		break;
2442ed45ce2cSHans Verkuil 	}
2443ed45ce2cSHans Verkuil 
24445bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
24455bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
24465bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
24475bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
24485bc3cb74SMauro Carvalho Chehab 
24495bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
24505bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
24515bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
24525bc3cb74SMauro Carvalho Chehab 				break;
24535bc3cb74SMauro Carvalho Chehab 			}
24545bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
2455ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
24565bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
24575bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
24585bc3cb74SMauro Carvalho Chehab 			ret = 1;
24595bc3cb74SMauro Carvalho Chehab 		}
24605bc3cb74SMauro Carvalho Chehab 		break;
24615bc3cb74SMauro Carvalho Chehab 	}
24625bc3cb74SMauro Carvalho Chehab 	}
24635bc3cb74SMauro Carvalho Chehab 
24645bc3cb74SMauro Carvalho Chehab 	return ret;
24655bc3cb74SMauro Carvalho Chehab }
24665bc3cb74SMauro Carvalho Chehab 
24675bc3cb74SMauro Carvalho Chehab long
24685bc3cb74SMauro Carvalho Chehab video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
24695bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
24705bc3cb74SMauro Carvalho Chehab {
24715bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
24725bc3cb74SMauro Carvalho Chehab 	void    *mbuf = NULL;
24735bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
24745bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
24755bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
24765bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
24775bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
24785bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
24795bc3cb74SMauro Carvalho Chehab 
24805bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
24815bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
24825bc3cb74SMauro Carvalho Chehab 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
24835bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
24845bc3cb74SMauro Carvalho Chehab 		} else {
24855bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
24865bc3cb74SMauro Carvalho Chehab 			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
24875bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
24885bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
24895bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
24905bc3cb74SMauro Carvalho Chehab 		}
24915bc3cb74SMauro Carvalho Chehab 
24925bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
24935bc3cb74SMauro Carvalho Chehab 		if (_IOC_DIR(cmd) & _IOC_WRITE) {
24945bc3cb74SMauro Carvalho Chehab 			unsigned int n = _IOC_SIZE(cmd);
24955bc3cb74SMauro Carvalho Chehab 
24965bc3cb74SMauro Carvalho Chehab 			/*
24975bc3cb74SMauro Carvalho Chehab 			 * In some cases, only a few fields are used as input,
24985bc3cb74SMauro Carvalho Chehab 			 * i.e. when the app sets "index" and then the driver
24995bc3cb74SMauro Carvalho Chehab 			 * fills in the rest of the structure for the thing
25005bc3cb74SMauro Carvalho Chehab 			 * with that index.  We only need to copy up the first
25015bc3cb74SMauro Carvalho Chehab 			 * non-input field.
25025bc3cb74SMauro Carvalho Chehab 			 */
25035bc3cb74SMauro Carvalho Chehab 			if (v4l2_is_known_ioctl(cmd)) {
25045bc3cb74SMauro Carvalho Chehab 				u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
25055bc3cb74SMauro Carvalho Chehab 				if (flags & INFO_FL_CLEAR_MASK)
25065bc3cb74SMauro Carvalho Chehab 					n = (flags & INFO_FL_CLEAR_MASK) >> 16;
25075bc3cb74SMauro Carvalho Chehab 			}
25085bc3cb74SMauro Carvalho Chehab 
25095bc3cb74SMauro Carvalho Chehab 			if (copy_from_user(parg, (void __user *)arg, n))
25105bc3cb74SMauro Carvalho Chehab 				goto out;
25115bc3cb74SMauro Carvalho Chehab 
25125bc3cb74SMauro Carvalho Chehab 			/* zero out anything we don't copy from userspace */
25135bc3cb74SMauro Carvalho Chehab 			if (n < _IOC_SIZE(cmd))
25145bc3cb74SMauro Carvalho Chehab 				memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
25155bc3cb74SMauro Carvalho Chehab 		} else {
25165bc3cb74SMauro Carvalho Chehab 			/* read-only ioctl */
25175bc3cb74SMauro Carvalho Chehab 			memset(parg, 0, _IOC_SIZE(cmd));
25185bc3cb74SMauro Carvalho Chehab 		}
25195bc3cb74SMauro Carvalho Chehab 	}
25205bc3cb74SMauro Carvalho Chehab 
25215bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
25225bc3cb74SMauro Carvalho Chehab 	if (err < 0)
25235bc3cb74SMauro Carvalho Chehab 		goto out;
25245bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
25255bc3cb74SMauro Carvalho Chehab 
25265bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
25275bc3cb74SMauro Carvalho Chehab 		/*
25285bc3cb74SMauro Carvalho Chehab 		 * When adding new types of array args, make sure that the
25295bc3cb74SMauro Carvalho Chehab 		 * parent argument to ioctl (which contains the pointer to the
25305bc3cb74SMauro Carvalho Chehab 		 * array) fits into sbuf (so that mbuf will still remain
25315bc3cb74SMauro Carvalho Chehab 		 * unused up to here).
25325bc3cb74SMauro Carvalho Chehab 		 */
25335bc3cb74SMauro Carvalho Chehab 		mbuf = kmalloc(array_size, GFP_KERNEL);
25345bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
25355bc3cb74SMauro Carvalho Chehab 		if (NULL == mbuf)
25365bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
25375bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
25385bc3cb74SMauro Carvalho Chehab 		if (copy_from_user(mbuf, user_ptr, array_size))
25395bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
25405bc3cb74SMauro Carvalho Chehab 		*kernel_ptr = mbuf;
25415bc3cb74SMauro Carvalho Chehab 	}
25425bc3cb74SMauro Carvalho Chehab 
25435bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
25445bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
25455bc3cb74SMauro Carvalho Chehab 	if (err == -ENOIOCTLCMD)
25465bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
2547aa32f4c0SHans Verkuil 	if (err == 0) {
2548aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
2549aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
2550aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
2551aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
2552aa32f4c0SHans Verkuil 	}
25535bc3cb74SMauro Carvalho Chehab 
25545bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
2555ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
25565bc3cb74SMauro Carvalho Chehab 		if (copy_to_user(user_ptr, mbuf, array_size))
25575bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
25585bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
25595bc3cb74SMauro Carvalho Chehab 	}
25605bc3cb74SMauro Carvalho Chehab 	/* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
25615bc3cb74SMauro Carvalho Chehab 	   results that must be returned. */
25625bc3cb74SMauro Carvalho Chehab 	if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
25635bc3cb74SMauro Carvalho Chehab 		goto out;
25645bc3cb74SMauro Carvalho Chehab 
25655bc3cb74SMauro Carvalho Chehab out_array_args:
25665bc3cb74SMauro Carvalho Chehab 	/*  Copy results into user buffer  */
25675bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
25685bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:
25695bc3cb74SMauro Carvalho Chehab 	case (_IOC_WRITE | _IOC_READ):
25705bc3cb74SMauro Carvalho Chehab 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
25715bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
25725bc3cb74SMauro Carvalho Chehab 		break;
25735bc3cb74SMauro Carvalho Chehab 	}
25745bc3cb74SMauro Carvalho Chehab 
25755bc3cb74SMauro Carvalho Chehab out:
25765bc3cb74SMauro Carvalho Chehab 	kfree(mbuf);
25775bc3cb74SMauro Carvalho Chehab 	return err;
25785bc3cb74SMauro Carvalho Chehab }
25795bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_usercopy);
25805bc3cb74SMauro Carvalho Chehab 
25815bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
25825bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
25835bc3cb74SMauro Carvalho Chehab {
25845bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
25855bc3cb74SMauro Carvalho Chehab }
25865bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
2587