12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25bc3cb74SMauro Carvalho Chehab /*
35bc3cb74SMauro Carvalho Chehab  * Video capture interface for Linux version 2
45bc3cb74SMauro Carvalho Chehab  *
55bc3cb74SMauro Carvalho Chehab  * A generic framework to process V4L2 ioctl commands.
65bc3cb74SMauro Carvalho Chehab  *
75bc3cb74SMauro Carvalho Chehab  * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
832590819SMauro Carvalho Chehab  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
95bc3cb74SMauro Carvalho Chehab  */
105bc3cb74SMauro Carvalho Chehab 
118dbcc3faSArnd Bergmann #include <linux/compat.h>
12758d90e1STomasz Figa #include <linux/mm.h>
135bc3cb74SMauro Carvalho Chehab #include <linux/module.h>
145bc3cb74SMauro Carvalho Chehab #include <linux/slab.h>
155bc3cb74SMauro Carvalho Chehab #include <linux/types.h>
165bc3cb74SMauro Carvalho Chehab #include <linux/kernel.h>
175bc3cb74SMauro Carvalho Chehab #include <linux/version.h>
185bc3cb74SMauro Carvalho Chehab 
195bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
205bc3cb74SMauro Carvalho Chehab 
215bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
225bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
27c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
2877fa4e07SShuah Khan #include <media/v4l2-mc.h>
29d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
305bc3cb74SMauro Carvalho Chehab 
31aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
32aa32f4c0SHans Verkuil 
335bc3cb74SMauro Carvalho Chehab /* Zero out the end of the struct pointed to by p.  Everything after, but
345bc3cb74SMauro Carvalho Chehab  * not including, the specified field is cleared. */
355bc3cb74SMauro Carvalho Chehab #define CLEAR_AFTER_FIELD(p, field) \
365bc3cb74SMauro Carvalho Chehab 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
375bc3cb74SMauro Carvalho Chehab 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
385bc3cb74SMauro Carvalho Chehab 
3973f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
4073f35418SHans Verkuil 
415bc3cb74SMauro Carvalho Chehab struct std_descr {
425bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
435bc3cb74SMauro Carvalho Chehab 	const char *descr;
445bc3cb74SMauro Carvalho Chehab };
455bc3cb74SMauro Carvalho Chehab 
465bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
475bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
735bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
745bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
755bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
765bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
775bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
785bc3cb74SMauro Carvalho Chehab };
795bc3cb74SMauro Carvalho Chehab 
805bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
815bc3cb74SMauro Carvalho Chehab  */
825bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
835bc3cb74SMauro Carvalho Chehab {
845bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
855bc3cb74SMauro Carvalho Chehab 	int i;
865bc3cb74SMauro Carvalho Chehab 
875bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
884faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
895bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
905bc3cb74SMauro Carvalho Chehab 	 */
915bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
925bc3cb74SMauro Carvalho Chehab 
935bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
945bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
955bc3cb74SMauro Carvalho Chehab 			break;
965bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
975bc3cb74SMauro Carvalho Chehab }
985bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
995bc3cb74SMauro Carvalho Chehab 
1005bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
1015bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
1025bc3cb74SMauro Carvalho Chehab {
1035bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1045bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1055bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1065bc3cb74SMauro Carvalho Chehab 	} else {
1075bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1085bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1095bc3cb74SMauro Carvalho Chehab 	}
1105bc3cb74SMauro Carvalho Chehab }
1115bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1125bc3cb74SMauro Carvalho Chehab 
1135bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1145bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
1155bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1165bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1175bc3cb74SMauro Carvalho Chehab {
1185bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1195bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1205bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
121c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1225bc3cb74SMauro Carvalho Chehab 	return 0;
1235bc3cb74SMauro Carvalho Chehab }
1245bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1255bc3cb74SMauro Carvalho Chehab 
126aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
127aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
128aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
129aa2f8871SNiklas Söderlund {
130aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
131aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
132aa2f8871SNiklas Söderlund 	const char *descr = "";
133aa2f8871SNiklas Söderlund 
134aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
135aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
136aa2f8871SNiklas Söderlund 	if (id == 0)
137aa2f8871SNiklas Söderlund 		return -ENODATA;
138aa2f8871SNiklas Söderlund 
139aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
140aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
141aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
142aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
143aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
144aa2f8871SNiklas Söderlund 			j++;
145aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
146aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
147aa2f8871SNiklas Söderlund 		j++;
148aa2f8871SNiklas Söderlund 		if (curr_id == 0)
149aa2f8871SNiklas Söderlund 			break;
150aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
151aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
152aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
153aa2f8871SNiklas Söderlund 			id &= ~curr_id;
154aa2f8871SNiklas Söderlund 	}
155aa2f8871SNiklas Söderlund 	if (i <= index)
156aa2f8871SNiklas Söderlund 		return -EINVAL;
157aa2f8871SNiklas Söderlund 
158aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
159aa2f8871SNiklas Söderlund 	return 0;
160aa2f8871SNiklas Söderlund }
161aa2f8871SNiklas Söderlund 
1625bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1635bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1645bc3cb74SMauro Carvalho Chehab 
1655bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1665bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1675bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1685bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1715bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1725bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1735bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1745bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1755bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1765bc3cb74SMauro Carvalho Chehab };
1775bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1785bc3cb74SMauro Carvalho Chehab 
1795bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
180839aa56dSHans Verkuil 	[0]				   = "0",
1815bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1825bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1835bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1865bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1875bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1885bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1895bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1905bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1916f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1929effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
193fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
19472148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1955bc3cb74SMauro Carvalho Chehab };
1965bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1975bc3cb74SMauro Carvalho Chehab 
1985bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1995bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
2005bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
2015bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
202051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
2035bc3cb74SMauro Carvalho Chehab };
2045bc3cb74SMauro Carvalho Chehab 
205d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2065bc3cb74SMauro Carvalho Chehab 
2075bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2085bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2095bc3cb74SMauro Carvalho Chehab 
2105bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2115bc3cb74SMauro Carvalho Chehab {
2125bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2135bc3cb74SMauro Carvalho Chehab 
2148720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21527d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21627d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21727d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2185bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2195bc3cb74SMauro Carvalho Chehab }
2205bc3cb74SMauro Carvalho Chehab 
2215bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2225bc3cb74SMauro Carvalho Chehab {
2235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2245bc3cb74SMauro Carvalho Chehab 
2258720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
22627d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22727d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
22827d5a87cSHans Verkuil 		p->capabilities);
2295bc3cb74SMauro Carvalho Chehab }
2305bc3cb74SMauro Carvalho Chehab 
2315bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2325bc3cb74SMauro Carvalho Chehab {
2335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2345bc3cb74SMauro Carvalho Chehab 
2358720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23627d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23727d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2385bc3cb74SMauro Carvalho Chehab }
2395bc3cb74SMauro Carvalho Chehab 
2405bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2415bc3cb74SMauro Carvalho Chehab {
2425bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2435bc3cb74SMauro Carvalho Chehab 
2445bc3cb74SMauro Carvalho Chehab 	if (write_only)
2455bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2465bc3cb74SMauro Carvalho Chehab 	else
24727d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
24827d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
24927d5a87cSHans Verkuil 			p->capability, p->mode);
2505bc3cb74SMauro Carvalho Chehab }
2515bc3cb74SMauro Carvalho Chehab 
2525bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2535bc3cb74SMauro Carvalho Chehab {
2545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2555bc3cb74SMauro Carvalho Chehab 
2565bc3cb74SMauro Carvalho Chehab 	if (write_only)
2575bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2585bc3cb74SMauro Carvalho Chehab 	else
25927d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
26027d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
26127d5a87cSHans Verkuil 			p->capability, p->mode);
2625bc3cb74SMauro Carvalho Chehab }
2635bc3cb74SMauro Carvalho Chehab 
2645bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2655bc3cb74SMauro Carvalho Chehab {
2665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2675bc3cb74SMauro Carvalho Chehab 
268e927e1e0SSakari Ailus 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n",
2695bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
270e927e1e0SSakari Ailus 		p->flags, &p->pixelformat, p->mbus_code,
27127d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2725bc3cb74SMauro Carvalho Chehab }
2735bc3cb74SMauro Carvalho Chehab 
2745bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2755bc3cb74SMauro Carvalho Chehab {
2765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2785bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2805bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
28287185c95SAntti Palosaari 	const struct v4l2_sdr_format *sdr;
283fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
2847fe9f01cSSakari Ailus 	u32 planes;
2855bc3cb74SMauro Carvalho Chehab 	unsigned i;
2865bc3cb74SMauro Carvalho Chehab 
2875bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2885bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2895bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2905bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2915bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
292e927e1e0SSakari Ailus 		pr_cont(", width=%u, height=%u, pixelformat=%p4cc, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
293e927e1e0SSakari Ailus 			pix->width, pix->height, &pix->pixelformat,
2945bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2955bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
296736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
29774fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2985bc3cb74SMauro Carvalho Chehab 		break;
2995bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3005bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3015bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
302e927e1e0SSakari Ailus 		pr_cont(", width=%u, height=%u, format=%p4cc, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n",
303e927e1e0SSakari Ailus 			mp->width, mp->height, &mp->pixelformat,
3045bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
305736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
30674fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3077fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3087fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3095bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3105bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3115bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3125bc3cb74SMauro Carvalho Chehab 		break;
3135bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3145bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3155bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
316560dde24SHans Verkuil 		/* Note: we can't print the clip list here since the clips
317560dde24SHans Verkuil 		 * pointer is a userspace pointer, not a kernelspace
318560dde24SHans Verkuil 		 * pointer. */
319560dde24SHans 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",
320560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3215bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
322560dde24SHans Verkuil 			win->chromakey, win->clipcount, win->clips,
323560dde24SHans Verkuil 			win->bitmap, win->global_alpha);
3245bc3cb74SMauro Carvalho Chehab 		break;
3255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3275bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
328e927e1e0SSakari Ailus 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n",
3295bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
330e927e1e0SSakari Ailus 			vbi->samples_per_line, &vbi->sample_format,
3315bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3325bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3335bc3cb74SMauro Carvalho Chehab 		break;
3345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3355bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3365bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3375bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3385bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3395bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3405bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3415bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3425bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3435bc3cb74SMauro Carvalho Chehab 		break;
344582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3459effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
346582c52cbSAntti Palosaari 		sdr = &p->fmt.sdr;
347e927e1e0SSakari Ailus 		pr_cont(", pixelformat=%p4cc\n", &sdr->pixelformat);
348582c52cbSAntti Palosaari 		break;
349fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
35072148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
351fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
352e927e1e0SSakari Ailus 		pr_cont(", dataformat=%p4cc, buffersize=%u\n",
353e927e1e0SSakari Ailus 			&meta->dataformat, meta->buffersize);
354fb9ffa6aSLaurent Pinchart 		break;
3555bc3cb74SMauro Carvalho Chehab 	}
3565bc3cb74SMauro Carvalho Chehab }
3575bc3cb74SMauro Carvalho Chehab 
3585bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3595bc3cb74SMauro Carvalho Chehab {
3605bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3615bc3cb74SMauro Carvalho Chehab 
362e927e1e0SSakari Ailus 	pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%p4cc, bytesperline=%u, sizeimage=%u, colorspace=%d\n",
363e927e1e0SSakari Ailus 		p->capability, p->flags, p->base, p->fmt.width, p->fmt.height,
364e927e1e0SSakari Ailus 		&p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage,
3655bc3cb74SMauro Carvalho Chehab 		p->fmt.colorspace);
3665bc3cb74SMauro Carvalho Chehab }
3675bc3cb74SMauro Carvalho Chehab 
3685bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3695bc3cb74SMauro Carvalho Chehab {
3705bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3715bc3cb74SMauro Carvalho Chehab }
3725bc3cb74SMauro Carvalho Chehab 
3735bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3745bc3cb74SMauro Carvalho Chehab {
3755bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3765bc3cb74SMauro Carvalho Chehab 
3775bc3cb74SMauro Carvalho Chehab 	if (write_only)
378560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3795bc3cb74SMauro Carvalho Chehab 	else
3808720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
38127d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3825bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3835bc3cb74SMauro Carvalho Chehab }
3845bc3cb74SMauro Carvalho Chehab 
3855bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3865bc3cb74SMauro Carvalho Chehab {
3875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3885bc3cb74SMauro Carvalho Chehab 
3895bc3cb74SMauro Carvalho Chehab 	if (write_only)
3905bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3915bc3cb74SMauro Carvalho Chehab 	else
3928720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, rangelow=%u, rangehigh=%u, signal=%u, afc=%d, rxsubchans=0x%x, audmode=%u\n",
39327d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3945bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3955bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3965bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3975bc3cb74SMauro Carvalho Chehab }
3985bc3cb74SMauro Carvalho Chehab 
3995bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
4005bc3cb74SMauro Carvalho Chehab {
4015bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
4025bc3cb74SMauro Carvalho Chehab 
4035bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
4045bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
4055bc3cb74SMauro Carvalho Chehab }
4065bc3cb74SMauro Carvalho Chehab 
4075bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4085bc3cb74SMauro Carvalho Chehab {
4095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4105bc3cb74SMauro Carvalho Chehab 
4118720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4128720427cSMauro Carvalho Chehab 		p->index,
41327d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4145bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4155bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4165bc3cb74SMauro Carvalho Chehab 		p->framelines);
4175bc3cb74SMauro Carvalho Chehab }
4185bc3cb74SMauro Carvalho Chehab 
4195bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4205bc3cb74SMauro Carvalho Chehab {
4215bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4225bc3cb74SMauro Carvalho Chehab }
4235bc3cb74SMauro Carvalho Chehab 
4245bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4255bc3cb74SMauro Carvalho Chehab {
4265bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4275bc3cb74SMauro Carvalho Chehab 
4288720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
42979e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
43079e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4315bc3cb74SMauro Carvalho Chehab }
4325bc3cb74SMauro Carvalho Chehab 
4335bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4345bc3cb74SMauro Carvalho Chehab {
4355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4365bc3cb74SMauro Carvalho Chehab 
4375bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4385bc3cb74SMauro Carvalho Chehab 		p->count,
4395bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4405bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4415bc3cb74SMauro Carvalho Chehab }
4425bc3cb74SMauro Carvalho Chehab 
4435bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4445bc3cb74SMauro Carvalho Chehab {
4455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4465bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4475bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4485bc3cb74SMauro Carvalho Chehab 	int i;
4495bc3cb74SMauro Carvalho Chehab 
45048e15418SHans Verkuil 	pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
451577c89b0SArnd Bergmann 			(int)p->timestamp.tv_sec / 3600,
452577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec / 60) % 60,
453577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec % 60),
4545bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4555bc3cb74SMauro Carvalho Chehab 			p->index,
45662fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4575bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4585bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4595bc3cb74SMauro Carvalho Chehab 
4605bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4615bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4625bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4635bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4645bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4658720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4665bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4675bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4685bc3cb74SMauro Carvalho Chehab 		}
4695bc3cb74SMauro Carvalho Chehab 	} else {
470560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4715bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4725bc3cb74SMauro Carvalho Chehab 	}
4735bc3cb74SMauro Carvalho Chehab 
4748720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4755bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4765bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4775bc3cb74SMauro Carvalho Chehab }
4785bc3cb74SMauro Carvalho Chehab 
479b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
480b799d09aSTomasz Stanislawski {
481b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
482b799d09aSTomasz Stanislawski 
483b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
484b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
485b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
486b799d09aSTomasz Stanislawski }
487b799d09aSTomasz Stanislawski 
4885bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4895bc3cb74SMauro Carvalho Chehab {
4905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4915bc3cb74SMauro Carvalho Chehab 
492319c4bd4SHelen Koike 	pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ",
493319c4bd4SHelen Koike 		p->index, p->count, prt_names(p->memory, v4l2_memory_names),
494319c4bd4SHelen Koike 		p->capabilities);
4955bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4965bc3cb74SMauro Carvalho Chehab }
4975bc3cb74SMauro Carvalho Chehab 
4985bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4995bc3cb74SMauro Carvalho Chehab {
5005bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
5015bc3cb74SMauro Carvalho Chehab 
5025bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
5035bc3cb74SMauro Carvalho Chehab 
5045bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
5055bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5065bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5075bc3cb74SMauro Carvalho Chehab 
5088720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5095bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5105bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5115bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5125bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5135bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5145bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5155bc3cb74SMauro Carvalho Chehab 
5168720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5175bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5185bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5195bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
520560dde24SHans Verkuil 	} else {
521560dde24SHans Verkuil 		pr_cont("\n");
5225bc3cb74SMauro Carvalho Chehab 	}
5235bc3cb74SMauro Carvalho Chehab }
5245bc3cb74SMauro Carvalho Chehab 
5255bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5265bc3cb74SMauro Carvalho Chehab {
5275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5285bc3cb74SMauro Carvalho Chehab 
5298720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
53027d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5315bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5325bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5335bc3cb74SMauro Carvalho Chehab }
5345bc3cb74SMauro Carvalho Chehab 
535e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
536e6bee368SHans Verkuil {
537e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
538e6bee368SHans Verkuil 
5398720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, nr_of_dims=%u, dims=%u,%u,%u,%u\n",
540e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
541e6bee368SHans Verkuil 			p->minimum, p->maximum,
542e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
543e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5440176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
545e6bee368SHans Verkuil }
546e6bee368SHans Verkuil 
5475bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5485bc3cb74SMauro Carvalho Chehab {
5495bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5505bc3cb74SMauro Carvalho Chehab 
5515bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5525bc3cb74SMauro Carvalho Chehab }
5535bc3cb74SMauro Carvalho Chehab 
5545bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5555bc3cb74SMauro Carvalho Chehab {
5565bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
557a69a7a33SEzequiel Garcia 	const char *name = v4l2_ctrl_get_name(p->id);
5585bc3cb74SMauro Carvalho Chehab 
559a69a7a33SEzequiel Garcia 	if (name)
560a69a7a33SEzequiel Garcia 		pr_cont("name=%s, ", name);
5615bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5625bc3cb74SMauro Carvalho Chehab }
5635bc3cb74SMauro Carvalho Chehab 
5645bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5655bc3cb74SMauro Carvalho Chehab {
5665bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5675bc3cb74SMauro Carvalho Chehab 	int i;
5685bc3cb74SMauro Carvalho Chehab 
569f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
570f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5715bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
572a69a7a33SEzequiel Garcia 		unsigned int id = p->controls[i].id;
573a69a7a33SEzequiel Garcia 		const char *name = v4l2_ctrl_get_name(id);
574a69a7a33SEzequiel Garcia 
575a69a7a33SEzequiel Garcia 		if (name)
576a69a7a33SEzequiel Garcia 			pr_cont(", name=%s", name);
577017ab36aSHans Verkuil 		if (!p->controls[i].size)
578a69a7a33SEzequiel Garcia 			pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
5795bc3cb74SMauro Carvalho Chehab 		else
580a69a7a33SEzequiel Garcia 			pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
5815bc3cb74SMauro Carvalho Chehab 	}
5825bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5835bc3cb74SMauro Carvalho Chehab }
5845bc3cb74SMauro Carvalho Chehab 
5855bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5865bc3cb74SMauro Carvalho Chehab {
5875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5885bc3cb74SMauro Carvalho Chehab 
5898720427cSMauro Carvalho Chehab 	pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n",
5905bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5915bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5925bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5935bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5945bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5955bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5965bc3cb74SMauro Carvalho Chehab }
5975bc3cb74SMauro Carvalho Chehab 
5985bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5995bc3cb74SMauro Carvalho Chehab {
6005bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
6015bc3cb74SMauro Carvalho Chehab 
6025bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
6035bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6045bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
6055bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6065bc3cb74SMauro Carvalho Chehab }
6075bc3cb74SMauro Carvalho Chehab 
6085bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6095bc3cb74SMauro Carvalho Chehab {
6105bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6115bc3cb74SMauro Carvalho Chehab 
6125bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6135bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6145bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6155bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6165bc3cb74SMauro Carvalho Chehab }
6175bc3cb74SMauro Carvalho Chehab 
6185bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6195bc3cb74SMauro Carvalho Chehab {
6205bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6215bc3cb74SMauro Carvalho Chehab 
6228720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6235bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6245bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6255bc3cb74SMauro Carvalho Chehab }
6265bc3cb74SMauro Carvalho Chehab 
6275bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6285bc3cb74SMauro Carvalho Chehab {
6295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6305bc3cb74SMauro Carvalho Chehab 
6315bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6325bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6335bc3cb74SMauro Carvalho Chehab }
6345bc3cb74SMauro Carvalho Chehab 
6355bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6365bc3cb74SMauro Carvalho Chehab {
6375bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6385bc3cb74SMauro Carvalho Chehab 
6395bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6405bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6415bc3cb74SMauro Carvalho Chehab }
6425bc3cb74SMauro Carvalho Chehab 
6435bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6445bc3cb74SMauro Carvalho Chehab {
6455bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6465bc3cb74SMauro Carvalho Chehab 
6475bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6485bc3cb74SMauro Carvalho Chehab 
6495bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6505bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6515bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6525bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6535bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6545bc3cb74SMauro Carvalho Chehab }
6555bc3cb74SMauro Carvalho Chehab 
65696b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65779b0c640SHans Verkuil {
65896b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65979b0c640SHans Verkuil 
66079b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6613eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
66279b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
66379b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
66479b0c640SHans Verkuil 	else
66579b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66679b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66779b0c640SHans Verkuil }
66879b0c640SHans Verkuil 
6695bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6705bc3cb74SMauro Carvalho Chehab {
6715bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6725bc3cb74SMauro Carvalho Chehab 
6735bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6743eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
67527d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67627d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6775bc3cb74SMauro Carvalho Chehab 	else
6785bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6795bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6805bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6815bc3cb74SMauro Carvalho Chehab }
6825bc3cb74SMauro Carvalho Chehab 
6835bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6845bc3cb74SMauro Carvalho Chehab {
6855bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6865bc3cb74SMauro Carvalho Chehab 
6875bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6885bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6898720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, interlaced=%u, pixelclock=%llu, width=%u, height=%u, polarities=0x%x, hfrontporch=%u, hsync=%u, hbackporch=%u, vfrontporch=%u, vsync=%u, vbackporch=%u, il_vfrontporch=%u, il_vsync=%u, il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
6905bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6915bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6925bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6935bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6945bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6955bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6965bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
6975bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
6985bc3cb74SMauro Carvalho Chehab 		break;
6995bc3cb74SMauro Carvalho Chehab 	default:
7005bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
7015bc3cb74SMauro Carvalho Chehab 		break;
7025bc3cb74SMauro Carvalho Chehab 	}
7035bc3cb74SMauro Carvalho Chehab }
7045bc3cb74SMauro Carvalho Chehab 
7055bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7065bc3cb74SMauro Carvalho Chehab {
7075bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7085bc3cb74SMauro Carvalho Chehab 
7095bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7105bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7115bc3cb74SMauro Carvalho Chehab }
7125bc3cb74SMauro Carvalho Chehab 
7135bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7145bc3cb74SMauro Carvalho Chehab {
7155bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7165bc3cb74SMauro Carvalho Chehab 
7175bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7185bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7198720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7205bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7215bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7225bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7235bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7245bc3cb74SMauro Carvalho Chehab 		break;
7255bc3cb74SMauro Carvalho Chehab 	default:
7265bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7275bc3cb74SMauro Carvalho Chehab 		break;
7285bc3cb74SMauro Carvalho Chehab 	}
7295bc3cb74SMauro Carvalho Chehab }
7305bc3cb74SMauro Carvalho Chehab 
7315bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7325bc3cb74SMauro Carvalho Chehab {
7335bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7345bc3cb74SMauro Carvalho Chehab 
735e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, type=%u",
736e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->type);
7375bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7385bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
739560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7405bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7415bc3cb74SMauro Carvalho Chehab 		break;
7425bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
743560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7442489477eSRicardo Ribalda 				p->stepwise.min_width,
7452489477eSRicardo Ribalda 				p->stepwise.min_height,
7462489477eSRicardo Ribalda 				p->stepwise.max_width,
7472489477eSRicardo Ribalda 				p->stepwise.max_height,
7482489477eSRicardo Ribalda 				p->stepwise.step_width,
7492489477eSRicardo Ribalda 				p->stepwise.step_height);
7505bc3cb74SMauro Carvalho Chehab 		break;
7515bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7525bc3cb74SMauro Carvalho Chehab 	default:
7535bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7545bc3cb74SMauro Carvalho Chehab 		break;
7555bc3cb74SMauro Carvalho Chehab 	}
7565bc3cb74SMauro Carvalho Chehab }
7575bc3cb74SMauro Carvalho Chehab 
7585bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7595bc3cb74SMauro Carvalho Chehab {
7605bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7615bc3cb74SMauro Carvalho Chehab 
762e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u",
763e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->width, p->height, p->type);
7645bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7655bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
766560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7675bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7685bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7695bc3cb74SMauro Carvalho Chehab 		break;
7705bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
771560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7725bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7735bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7745bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7755bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7765bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7775bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7785bc3cb74SMauro Carvalho Chehab 		break;
7795bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7805bc3cb74SMauro Carvalho Chehab 	default:
7815bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7825bc3cb74SMauro Carvalho Chehab 		break;
7835bc3cb74SMauro Carvalho Chehab 	}
7845bc3cb74SMauro Carvalho Chehab }
7855bc3cb74SMauro Carvalho Chehab 
7865bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7875bc3cb74SMauro Carvalho Chehab {
7885bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7895bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7905bc3cb74SMauro Carvalho Chehab 
7911a6c0b36SArnd Bergmann 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
7925bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7935bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7945bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7955bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7965bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
7975bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
7985bc3cb74SMauro Carvalho Chehab 		break;
7995bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
8005bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
8015bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
8025bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
8035bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
8045bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
8055bc3cb74SMauro Carvalho Chehab 		else
8065bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8078720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8085bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8095bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8105bc3cb74SMauro Carvalho Chehab 		break;
8115bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8125bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8135bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8145bc3cb74SMauro Carvalho Chehab 		break;
8155bc3cb74SMauro Carvalho Chehab 	}
8165bc3cb74SMauro Carvalho Chehab }
8175bc3cb74SMauro Carvalho Chehab 
8185bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8195bc3cb74SMauro Carvalho Chehab {
8205bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8215bc3cb74SMauro Carvalho Chehab 
8225bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8235bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8245bc3cb74SMauro Carvalho Chehab }
8255bc3cb74SMauro Carvalho Chehab 
8265bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8275bc3cb74SMauro Carvalho Chehab {
8285bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8295bc3cb74SMauro Carvalho Chehab 	int i;
8305bc3cb74SMauro Carvalho Chehab 
8315bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8325bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8335bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8345bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8355bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8365bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8375bc3cb74SMauro Carvalho Chehab }
8385bc3cb74SMauro Carvalho Chehab 
8395bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8405bc3cb74SMauro Carvalho Chehab {
8415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8425bc3cb74SMauro Carvalho Chehab 
8438720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8445bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8455bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8465bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8475bc3cb74SMauro Carvalho Chehab }
8485bc3cb74SMauro Carvalho Chehab 
849dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
850dd519bb3SHans Verkuil {
851dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
852dd519bb3SHans Verkuil 
853dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
854dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
855dd519bb3SHans Verkuil }
856dd519bb3SHans Verkuil 
8575bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8585bc3cb74SMauro Carvalho Chehab {
8595bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8605bc3cb74SMauro Carvalho Chehab }
8615bc3cb74SMauro Carvalho Chehab 
8625bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8635bc3cb74SMauro Carvalho Chehab {
8645bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8655bc3cb74SMauro Carvalho Chehab }
8665bc3cb74SMauro Carvalho Chehab 
8675bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8685bc3cb74SMauro Carvalho Chehab {
8695bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8705bc3cb74SMauro Carvalho Chehab }
8715bc3cb74SMauro Carvalho Chehab 
8725bc3cb74SMauro Carvalho Chehab static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
8735bc3cb74SMauro Carvalho Chehab {
8745bc3cb74SMauro Carvalho Chehab 	__u32 i;
8755bc3cb74SMauro Carvalho Chehab 
8765bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
877f23317adSAlexandre Courbot 	c->reserved[0] = 0;
8785bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8795bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8805bc3cb74SMauro Carvalho Chehab 
8815bc3cb74SMauro Carvalho Chehab 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
8825bc3cb74SMauro Carvalho Chehab 	   when using extended controls.
8835bc3cb74SMauro Carvalho Chehab 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
8845bc3cb74SMauro Carvalho Chehab 	   is it allowed for backwards compatibility.
8855bc3cb74SMauro Carvalho Chehab 	 */
8860f8017beSRicardo Ribalda 	if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE)
8875bc3cb74SMauro Carvalho Chehab 		return 0;
8880f8017beSRicardo Ribalda 	if (!c->which)
8899b239b22SHans Verkuil 		return 1;
8905bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
8915bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
8920f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
8935bc3cb74SMauro Carvalho Chehab 			c->error_idx = i;
8945bc3cb74SMauro Carvalho Chehab 			return 0;
8955bc3cb74SMauro Carvalho Chehab 		}
8965bc3cb74SMauro Carvalho Chehab 	}
8975bc3cb74SMauro Carvalho Chehab 	return 1;
8985bc3cb74SMauro Carvalho Chehab }
8995bc3cb74SMauro Carvalho Chehab 
9004b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9015bc3cb74SMauro Carvalho Chehab {
90296f49c1aSVandana BN 	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
90396f49c1aSVandana BN 			     V4L2_CAP_VIDEO_CAPTURE_MPLANE |
90496f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT |
90596f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT_MPLANE |
90696f49c1aSVandana BN 			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
90796f49c1aSVandana BN 	const u32 meta_caps = V4L2_CAP_META_CAPTURE |
90896f49c1aSVandana BN 			      V4L2_CAP_META_OUTPUT;
9094b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9104b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
911238e4a5bSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
91296f49c1aSVandana BN 		      (vfd->device_caps & vid_caps);
9134b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
914582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
915b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
916238e4a5bSHans Verkuil 	bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
91796f49c1aSVandana BN 		       (vfd->device_caps & meta_caps);
9184b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9194b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9204b20259fSHans Verkuil 
9215bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9225bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9235bc3cb74SMauro Carvalho Chehab 
9245bc3cb74SMauro Carvalho Chehab 	switch (type) {
9255bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
926b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9274b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9285bc3cb74SMauro Carvalho Chehab 			return 0;
9295bc3cb74SMauro Carvalho Chehab 		break;
9305bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
931095c21d3SHans Verkuil 		if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9325bc3cb74SMauro Carvalho Chehab 			return 0;
9335bc3cb74SMauro Carvalho Chehab 		break;
9345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9354b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9365bc3cb74SMauro Carvalho Chehab 			return 0;
9375bc3cb74SMauro Carvalho Chehab 		break;
9385bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9394b20259fSHans Verkuil 		if (is_vid && is_tx &&
9404b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9415bc3cb74SMauro Carvalho Chehab 			return 0;
9425bc3cb74SMauro Carvalho Chehab 		break;
9435bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9444b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9455bc3cb74SMauro Carvalho Chehab 			return 0;
9465bc3cb74SMauro Carvalho Chehab 		break;
9475bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9484b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9495bc3cb74SMauro Carvalho Chehab 			return 0;
9505bc3cb74SMauro Carvalho Chehab 		break;
9515bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9524b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9535bc3cb74SMauro Carvalho Chehab 			return 0;
9545bc3cb74SMauro Carvalho Chehab 		break;
9555bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9564b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9575bc3cb74SMauro Carvalho Chehab 			return 0;
9585bc3cb74SMauro Carvalho Chehab 		break;
9595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9604b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9615bc3cb74SMauro Carvalho Chehab 			return 0;
9625bc3cb74SMauro Carvalho Chehab 		break;
9635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9644b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9655bc3cb74SMauro Carvalho Chehab 			return 0;
9665bc3cb74SMauro Carvalho Chehab 		break;
967582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
968582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
969582c52cbSAntti Palosaari 			return 0;
970582c52cbSAntti Palosaari 		break;
9719effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9729effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9739effc72fSAntti Palosaari 			return 0;
9749effc72fSAntti Palosaari 		break;
975fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
97696f49c1aSVandana BN 		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
977fb9ffa6aSLaurent Pinchart 			return 0;
978fb9ffa6aSLaurent Pinchart 		break;
97972148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
98096f49c1aSVandana BN 		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
98172148d1aSSakari Ailus 			return 0;
98272148d1aSSakari Ailus 		break;
983633c98e5SHans Verkuil 	default:
9845bc3cb74SMauro Carvalho Chehab 		break;
9855bc3cb74SMauro Carvalho Chehab 	}
9865bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9875bc3cb74SMauro Carvalho Chehab }
9885bc3cb74SMauro Carvalho Chehab 
989d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
990d52e2381SLaurent Pinchart {
991d52e2381SLaurent Pinchart 	unsigned int offset;
992d52e2381SLaurent Pinchart 
99314c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
99414c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
99514c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
99614c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
99714c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
99814c8e80eSEzequiel Garcia 
999d52e2381SLaurent Pinchart 	/*
1000d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1001d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1002d52e2381SLaurent Pinchart 	 * field, when set to a magic value, indicates the the extended fields
1003d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1004d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1005d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1006d52e2381SLaurent Pinchart 	 * isn't used by applications.
1007d52e2381SLaurent Pinchart 	 */
1008d52e2381SLaurent Pinchart 
1009d52e2381SLaurent Pinchart 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1010d52e2381SLaurent Pinchart 	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1011d52e2381SLaurent Pinchart 		return;
1012d52e2381SLaurent Pinchart 
1013d52e2381SLaurent Pinchart 	if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
1014d52e2381SLaurent Pinchart 		return;
1015d52e2381SLaurent Pinchart 
1016d52e2381SLaurent Pinchart 	fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1017d52e2381SLaurent Pinchart 
1018d52e2381SLaurent Pinchart 	offset = offsetof(struct v4l2_pix_format, priv)
1019d52e2381SLaurent Pinchart 	       + sizeof(fmt->fmt.pix.priv);
1020d52e2381SLaurent Pinchart 	memset(((void *)&fmt->fmt.pix) + offset, 0,
1021d52e2381SLaurent Pinchart 	       sizeof(fmt->fmt.pix) - offset);
1022d52e2381SLaurent Pinchart }
1023d52e2381SLaurent Pinchart 
10245bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10255bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10265bc3cb74SMauro Carvalho Chehab {
10275bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10287bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1029d52e2381SLaurent Pinchart 	int ret;
10305bc3cb74SMauro Carvalho Chehab 
10315bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10327bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10337bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1034d52e2381SLaurent Pinchart 
1035d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1036d52e2381SLaurent Pinchart 
1037454a4e72SHans Verkuil 	/*
10383c135050SHans Verkuil 	 * Drivers must not change device_caps, so check for this and
10393c135050SHans Verkuil 	 * warn if this happened.
1040454a4e72SHans Verkuil 	 */
10413c135050SHans Verkuil 	WARN_ON(cap->device_caps != vfd->device_caps);
10423c135050SHans Verkuil 	/*
10433c135050SHans Verkuil 	 * Check that capabilities is a superset of
10443c135050SHans Verkuil 	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
10453c135050SHans Verkuil 	 */
10463c135050SHans Verkuil 	WARN_ON((cap->capabilities &
10473c135050SHans Verkuil 		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
10483c135050SHans Verkuil 		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
10493c135050SHans Verkuil 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1050796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1051d52e2381SLaurent Pinchart 
1052d52e2381SLaurent Pinchart 	return ret;
10535bc3cb74SMauro Carvalho Chehab }
10545bc3cb74SMauro Carvalho Chehab 
1055f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1056f645e625SNiklas Söderlund 		       struct file *file, void *fh, void *arg)
1057f645e625SNiklas Söderlund {
1058f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1059f645e625SNiklas Söderlund 
1060f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1061f645e625SNiklas Söderlund 		*(int *)arg = 0;
1062f645e625SNiklas Söderlund 		return 0;
1063f645e625SNiklas Söderlund 	}
1064f645e625SNiklas Söderlund 
1065f645e625SNiklas Söderlund 	return ops->vidioc_g_input(file, fh, arg);
1066f645e625SNiklas Söderlund }
1067f645e625SNiklas Söderlund 
1068f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1069f645e625SNiklas Söderlund 			struct file *file, void *fh, void *arg)
1070f645e625SNiklas Söderlund {
1071f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1072f645e625SNiklas Söderlund 
1073f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1074f645e625SNiklas Söderlund 		*(int *)arg = 0;
1075f645e625SNiklas Söderlund 		return 0;
1076f645e625SNiklas Söderlund 	}
1077f645e625SNiklas Söderlund 
1078f645e625SNiklas Söderlund 	return ops->vidioc_g_output(file, fh, arg);
1079f645e625SNiklas Söderlund }
1080f645e625SNiklas Söderlund 
10815bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
10825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10835bc3cb74SMauro Carvalho Chehab {
108477fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
108577fa4e07SShuah Khan 	int ret;
108677fa4e07SShuah Khan 
108777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
108877fa4e07SShuah Khan 	if (ret)
108977fa4e07SShuah Khan 		return ret;
1090f645e625SNiklas Söderlund 
1091f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1092f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1093f645e625SNiklas Söderlund 
10945bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10955bc3cb74SMauro Carvalho Chehab }
10965bc3cb74SMauro Carvalho Chehab 
10975bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10985bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10995bc3cb74SMauro Carvalho Chehab {
1100f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1101f645e625SNiklas Söderlund 
1102f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1103f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1104f645e625SNiklas Söderlund 
11055bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
11065bc3cb74SMauro Carvalho Chehab }
11075bc3cb74SMauro Carvalho Chehab 
11085bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
11095bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11105bc3cb74SMauro Carvalho Chehab {
11115bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11125bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11135bc3cb74SMauro Carvalho Chehab 
11145bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
111559b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11165bc3cb74SMauro Carvalho Chehab 	return 0;
11175bc3cb74SMauro Carvalho Chehab }
11185bc3cb74SMauro Carvalho Chehab 
11195bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11215bc3cb74SMauro Carvalho Chehab {
11225bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11235bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11245bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11255bc3cb74SMauro Carvalho Chehab 
11265bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11272438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11282438e78aSHans Verkuil 		return -ENOTTY;
11295bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
113059b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11315bc3cb74SMauro Carvalho Chehab }
11325bc3cb74SMauro Carvalho Chehab 
11335bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11355bc3cb74SMauro Carvalho Chehab {
113673f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11375bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11385bc3cb74SMauro Carvalho Chehab 
11395bc3cb74SMauro Carvalho Chehab 	/*
114002fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11415bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11425bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11435bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
11445bc3cb74SMauro Carvalho Chehab 	 */
114573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11465bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
11475bc3cb74SMauro Carvalho Chehab 
1148f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1149f645e625SNiklas Söderlund 		if (p->index)
1150f645e625SNiklas Söderlund 			return -EINVAL;
1151f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1152f645e625SNiklas Söderlund 		p->type = V4L2_INPUT_TYPE_CAMERA;
1153f645e625SNiklas Söderlund 		return 0;
1154f645e625SNiklas Söderlund 	}
1155f645e625SNiklas Söderlund 
11565bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
11575bc3cb74SMauro Carvalho Chehab }
11585bc3cb74SMauro Carvalho Chehab 
11595bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
11605bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11615bc3cb74SMauro Carvalho Chehab {
116273f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11635bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
11645bc3cb74SMauro Carvalho Chehab 
11655bc3cb74SMauro Carvalho Chehab 	/*
116602fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
11675bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
11685bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
11695bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
11705bc3cb74SMauro Carvalho Chehab 	 */
117173f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11725bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
11735bc3cb74SMauro Carvalho Chehab 
1174f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1175f645e625SNiklas Söderlund 		if (p->index)
1176f645e625SNiklas Söderlund 			return -EINVAL;
1177f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1178f645e625SNiklas Söderlund 		p->type = V4L2_OUTPUT_TYPE_ANALOG;
1179f645e625SNiklas Söderlund 		return 0;
1180f645e625SNiklas Söderlund 	}
1181f645e625SNiklas Söderlund 
11825bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
11835bc3cb74SMauro Carvalho Chehab }
11845bc3cb74SMauro Carvalho Chehab 
1185ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1186ba300204SHans Verkuil {
1187ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1188ba300204SHans Verkuil 	const char *descr = NULL;
1189ba300204SHans Verkuil 	u32 flags = 0;
1190ba300204SHans Verkuil 
1191ba300204SHans Verkuil 	/*
1192ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1193ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1194ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1195ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1196ba300204SHans Verkuil 	 *
1197ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1198ba300204SHans Verkuil 	 */
1199ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1200ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1201ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1202ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1203ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1204ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
12054747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
12064747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
12074747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
12084747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
12094747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
12104747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
1211ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1212ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1213ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
12144747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
12154747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
12164747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
12174747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
12184747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
12194747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
1220ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1221ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1222ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1223ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1224ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1225ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1226ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1227ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1228ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1229ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1230ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1231ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1232ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1233ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
12344747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
12354747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
12364747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
12374747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
1238ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1239ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1240ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1241ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1242ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1243ae9753a0SDaniel Glöckner 	case V4L2_PIX_FMT_Y14:		descr = "14-bit Greyscale"; break;
1244ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
12452e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1246ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
12476e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
12485b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
12495b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
12505b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
12515df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
125292799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1253ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1254ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1255ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1256ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1257ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1258ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1259ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1260ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1261ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1262fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1263ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1264ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1265ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1266ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1267ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
12680376a51fSMirela Rabulea 	case V4L2_PIX_FMT_YUV24:	descr = "24-bit YUV 4:4:4 8-8-8"; break;
1269ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1270a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1271a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1272a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1273a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
1274ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1275ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1276ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1277ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
1278ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
1279ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
1280ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
1281ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
1282ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
1283ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
1284683f71ebSEzequiel Garcia 	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
128578eee7b5SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
1286b84f60a3SEzequiel Garcia 	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
1287ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
1288ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
1289ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
1290ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
1291ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
1292ba300204SHans Verkuil 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
1293ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1294ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1295d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1296d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1297d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1298d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1299ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1300ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1301ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1302ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1303ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1304ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1305ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1306ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1307ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1308ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1309ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1310ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1311e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1312e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1313e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1314e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1315ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1316ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1317ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1318ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1319ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1320ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1321ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1322ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1323d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1324d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1325d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1326d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1327d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1328d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1329d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1330d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1331d12127edSSakari Ailus 	case V4L2_PIX_FMT_SBGGR14:	descr = "14-bit Bayer BGBG/GRGR"; break;
1332d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGBRG14:	descr = "14-bit Bayer GBGB/RGRG"; break;
1333d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGRBG14:	descr = "14-bit Bayer GRGR/BGBG"; break;
1334d12127edSSakari Ailus 	case V4L2_PIX_FMT_SRGGB14:	descr = "14-bit Bayer RGRG/GBGB"; break;
133583b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
133683b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
133783b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
133883b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1339b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1340b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1341b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1342b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
134399b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1344ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1345ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1346ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1347ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1348ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1349ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1350ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
1351*ffe5350cSAlexandre Courbot 	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
135266b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
135366b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
135448fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
135548fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1356ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1357ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1358ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1359c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1360c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1361c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
13624747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
13634747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
13644747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
13654747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
136614d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
13675deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
13684747bd0fSHans Verkuil 	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
13694747bd0fSHans Verkuil 	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
137078892b6bSVandana BN 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
1371df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
1372df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
1373ba300204SHans Verkuil 
1374ba300204SHans Verkuil 	default:
1375ba300204SHans Verkuil 		/* Compressed formats */
1376ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1377ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1378ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1379ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1380ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1381ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1382ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1383ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1384ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1385ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
13867bb3c32aSEzequiel Garcia 		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
1387ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1388ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1389ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1390c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
13914747bd0fSHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
1392ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1393ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1394ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1395ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1396a57d6acaSPawel Osciak 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
1397fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
13981c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
1399256fa392SPaul Kocialkowski 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
140062c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1401f05a51b9SHans Verkuil 		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */
1402ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1403ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1404ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1405ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1406ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1407ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1408ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1409ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1410ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1411ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1412ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1413ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1414ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1415ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1416ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1417ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1418ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1419ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1420d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
1421ba300204SHans Verkuil 		default:
1422ba300204SHans Verkuil 			if (fmt->description[0])
1423ba300204SHans Verkuil 				return;
1424c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1425ba300204SHans Verkuil 			flags = 0;
1426e927e1e0SSakari Ailus 			snprintf(fmt->description, sz, "%p4cc",
1427e927e1e0SSakari Ailus 				 &fmt->pixelformat);
1428ba300204SHans Verkuil 			break;
1429ba300204SHans Verkuil 		}
1430ba300204SHans Verkuil 	}
1431ba300204SHans Verkuil 
1432ba300204SHans Verkuil 	if (descr)
1433e7dd89ceSHans Petter Selasky 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
14347c490e25SHans Verkuil 	fmt->flags |= flags;
1435ba300204SHans Verkuil }
1436ba300204SHans Verkuil 
14375bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
14385bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
14395bc3cb74SMauro Carvalho Chehab {
14407e98b7b5SBoris Brezillon 	struct video_device *vdev = video_devdata(file);
14415bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1442b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1443e5b6b07aSLaurent Pinchart 	u32 mbus_code;
1444f0d2b7a8SBoris Brezillon 	u32 cap_mask;
1445b2469c81SHans Verkuil 
1446b2469c81SHans Verkuil 	if (ret)
1447b2469c81SHans Verkuil 		return ret;
1448b2469c81SHans Verkuil 	ret = -EINVAL;
14495bc3cb74SMauro Carvalho Chehab 
1450e5b6b07aSLaurent Pinchart 	if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1451e5b6b07aSLaurent Pinchart 		p->mbus_code = 0;
1452e5b6b07aSLaurent Pinchart 
1453e5b6b07aSLaurent Pinchart 	mbus_code = p->mbus_code;
1454e5b6b07aSLaurent Pinchart 	CLEAR_AFTER_FIELD(p, type);
1455e5b6b07aSLaurent Pinchart 	p->mbus_code = mbus_code;
1456e5b6b07aSLaurent Pinchart 
14575bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
14585bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
14597e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1460f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1461f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1462f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
14637e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
14647e98b7b5SBoris Brezillon 			break;
14657e98b7b5SBoris Brezillon 
1466b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
14675bc3cb74SMauro Carvalho Chehab 			break;
1468ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1469ba300204SHans Verkuil 		break;
14705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1471b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
14725bc3cb74SMauro Carvalho Chehab 			break;
1473ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1474ba300204SHans Verkuil 		break;
14755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
14767e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1477f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1478f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1479f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
14807e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
14817e98b7b5SBoris Brezillon 			break;
14827e98b7b5SBoris Brezillon 
1483b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
14845bc3cb74SMauro Carvalho Chehab 			break;
1485ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1486ba300204SHans Verkuil 		break;
1487582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1488b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1489582c52cbSAntti Palosaari 			break;
1490ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1491ba300204SHans Verkuil 		break;
14929effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1493b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
14949effc72fSAntti Palosaari 			break;
14959effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
14969effc72fSAntti Palosaari 		break;
1497fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1498b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1499fb9ffa6aSLaurent Pinchart 			break;
1500fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1501fb9ffa6aSLaurent Pinchart 		break;
150272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
150372148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
150472148d1aSSakari Ailus 			break;
150572148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
150672148d1aSSakari Ailus 		break;
15075bc3cb74SMauro Carvalho Chehab 	}
1508ba300204SHans Verkuil 	if (ret == 0)
1509ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1510ba300204SHans Verkuil 	return ret;
15115bc3cb74SMauro Carvalho Chehab }
15125bc3cb74SMauro Carvalho Chehab 
1513545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1514545b618cSVandana BN {
1515545b618cSVandana BN 	/*
1516545b618cSVandana BN 	 * The v4l2_pix_format structure contains fields that make no sense for
1517545b618cSVandana BN 	 * touch. Set them to default values in this case.
1518545b618cSVandana BN 	 */
1519545b618cSVandana BN 
1520545b618cSVandana BN 	p->field = V4L2_FIELD_NONE;
1521545b618cSVandana BN 	p->colorspace = V4L2_COLORSPACE_RAW;
1522545b618cSVandana BN 	p->flags = 0;
1523545b618cSVandana BN 	p->ycbcr_enc = 0;
1524545b618cSVandana BN 	p->quantization = 0;
1525545b618cSVandana BN 	p->xfer_func = 0;
1526545b618cSVandana BN }
1527545b618cSVandana BN 
15285bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
15295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15305bc3cb74SMauro Carvalho Chehab {
15315bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1532545b618cSVandana BN 	struct video_device *vfd = video_devdata(file);
1533b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1534b2469c81SHans Verkuil 
1535b2469c81SHans Verkuil 	if (ret)
1536b2469c81SHans Verkuil 		return ret;
1537d52e2381SLaurent Pinchart 
1538e5ce558aSHans Verkuil 	/*
1539e5ce558aSHans Verkuil 	 * fmt can't be cleared for these overlay types due to the 'clips'
1540e5ce558aSHans Verkuil 	 * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
1541e5ce558aSHans Verkuil 	 * Those are provided by the user. So handle these two overlay types
1542e5ce558aSHans Verkuil 	 * first, and then just do a simple memset for the other types.
1543e5ce558aSHans Verkuil 	 */
1544e5ce558aSHans Verkuil 	switch (p->type) {
1545e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1546e5ce558aSHans Verkuil 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
15473f65c6f6SArnd Bergmann 		struct v4l2_clip *clips = p->fmt.win.clips;
1548e5ce558aSHans Verkuil 		u32 clipcount = p->fmt.win.clipcount;
15494d1afa51SHans Verkuil 		void __user *bitmap = p->fmt.win.bitmap;
1550e5ce558aSHans Verkuil 
1551e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1552e5ce558aSHans Verkuil 		p->fmt.win.clips = clips;
1553e5ce558aSHans Verkuil 		p->fmt.win.clipcount = clipcount;
1554e5ce558aSHans Verkuil 		p->fmt.win.bitmap = bitmap;
1555e5ce558aSHans Verkuil 		break;
1556e5ce558aSHans Verkuil 	}
1557e5ce558aSHans Verkuil 	default:
1558e5ce558aSHans Verkuil 		memset(&p->fmt, 0, sizeof(p->fmt));
1559e5ce558aSHans Verkuil 		break;
1560e5ce558aSHans Verkuil 	}
1561e5ce558aSHans Verkuil 
15625bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1564b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
15655bc3cb74SMauro Carvalho Chehab 			break;
156648f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1567d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
156848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1569d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1570545b618cSVandana BN 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1571545b618cSVandana BN 			v4l_pix_format_touch(&p->fmt.pix);
1572d52e2381SLaurent Pinchart 		return ret;
15735bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
15755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15765bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
15774b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
15784b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
15794b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
15804b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
15815bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1582b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
15835bc3cb74SMauro Carvalho Chehab 			break;
158448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1585d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
158648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1587d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1588d52e2381SLaurent Pinchart 		return ret;
15895bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15905bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
15915bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
15925bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
15935bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
15945bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
15955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
15965bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1597582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1598582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
15999effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16009effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1601fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1602fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
160372148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
160472148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
16055bc3cb74SMauro Carvalho Chehab 	}
16065bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16075bc3cb74SMauro Carvalho Chehab }
16085bc3cb74SMauro Carvalho Chehab 
16095bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
16105bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16115bc3cb74SMauro Carvalho Chehab {
16125bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
16134b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1614b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16154e1e0eb0SEzequiel Garcia 	unsigned int i;
1616b2469c81SHans Verkuil 
1617b2469c81SHans Verkuil 	if (ret)
1618b2469c81SHans Verkuil 		return ret;
16195bc3cb74SMauro Carvalho Chehab 
162077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
162177fa4e07SShuah Khan 	if (ret)
162277fa4e07SShuah Khan 		return ret;
1623d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1624d52e2381SLaurent Pinchart 
16255bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16265bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1627b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
16285bc3cb74SMauro Carvalho Chehab 			break;
16295bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
163048f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
163148f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
163248f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1633b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1634b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
163548f2650aSHans Verkuil 		return ret;
16365bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1637b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
16385bc3cb74SMauro Carvalho Chehab 			break;
1639c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16404e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1641dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1642dd91642aSThierry Reding 					  bytesperline);
16435bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
16445bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1645b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
16465bc3cb74SMauro Carvalho Chehab 			break;
16475bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16485bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
16494b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1650b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
16514b20259fSHans Verkuil 			break;
1652ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
16534b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
16544b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1655b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
16564b20259fSHans Verkuil 			break;
1657ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
16584b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
16595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1660b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
16615bc3cb74SMauro Carvalho Chehab 			break;
16625bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
166348f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
166448f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
166548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
166648f2650aSHans Verkuil 		return ret;
16675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1668b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
16695bc3cb74SMauro Carvalho Chehab 			break;
1670c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
16714e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1672dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1673dd91642aSThierry Reding 					  bytesperline);
16745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
16755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1676b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
16775bc3cb74SMauro Carvalho Chehab 			break;
16785bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
16795bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
16805bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1681b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
16825bc3cb74SMauro Carvalho Chehab 			break;
1683ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
16845bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
16855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1686b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
16875bc3cb74SMauro Carvalho Chehab 			break;
1688ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
16895bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1690582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1691b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1692582c52cbSAntti Palosaari 			break;
1693ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1694582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
16959effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1696b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
16979effc72fSAntti Palosaari 			break;
1698ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
16999effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1700fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1701b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1702fb9ffa6aSLaurent Pinchart 			break;
1703fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1704fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
170572148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
170672148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
170772148d1aSSakari Ailus 			break;
170872148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
170972148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
17105bc3cb74SMauro Carvalho Chehab 	}
17115bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17125bc3cb74SMauro Carvalho Chehab }
17135bc3cb74SMauro Carvalho Chehab 
17145bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
17155bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17165bc3cb74SMauro Carvalho Chehab {
17175bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1718999a4312SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1719b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
17204e1e0eb0SEzequiel Garcia 	unsigned int i;
1721b2469c81SHans Verkuil 
1722b2469c81SHans Verkuil 	if (ret)
1723b2469c81SHans Verkuil 		return ret;
17245bc3cb74SMauro Carvalho Chehab 
1725d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1726d52e2381SLaurent Pinchart 
17275bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
17285bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1729b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
17305bc3cb74SMauro Carvalho Chehab 			break;
17315bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
173248f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
173348f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
173448f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1735999a4312SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1736999a4312SHans Verkuil 			v4l_pix_format_touch(&p->fmt.pix);
173748f2650aSHans Verkuil 		return ret;
17385bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1739b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
17405bc3cb74SMauro Carvalho Chehab 			break;
1741c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17424e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1743dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1744dd91642aSThierry Reding 					  bytesperline);
17455bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
17465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1747b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
17485bc3cb74SMauro Carvalho Chehab 			break;
17495bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17505bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
17514b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1752b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
17534b20259fSHans Verkuil 			break;
1754ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17554b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
17564b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1757b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
17584b20259fSHans Verkuil 			break;
1759ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17604b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
17615bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1762b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
17635bc3cb74SMauro Carvalho Chehab 			break;
17645bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.pix);
176548f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
176648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
176748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
176848f2650aSHans Verkuil 		return ret;
17695bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1770b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
17715bc3cb74SMauro Carvalho Chehab 			break;
1772c49148e8SLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
17734e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
1774dd91642aSThierry Reding 			CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
1775dd91642aSThierry Reding 					  bytesperline);
17765bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
17775bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1778b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
17795bc3cb74SMauro Carvalho Chehab 			break;
17805bc3cb74SMauro Carvalho Chehab 		CLEAR_AFTER_FIELD(p, fmt.win);
17815bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
17825bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1783b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
17845bc3cb74SMauro Carvalho Chehab 			break;
1785ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
17865bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
17875bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1788b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
17895bc3cb74SMauro Carvalho Chehab 			break;
1790ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
17915bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1792582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1793b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1794582c52cbSAntti Palosaari 			break;
1795ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
1796582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
17979effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1798b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
17999effc72fSAntti Palosaari 			break;
1800ee8951e5SHans Verkuil 		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
18019effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1802fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1803b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1804fb9ffa6aSLaurent Pinchart 			break;
1805fb9ffa6aSLaurent Pinchart 		CLEAR_AFTER_FIELD(p, fmt.meta);
1806fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
180772148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
180872148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
180972148d1aSSakari Ailus 			break;
181072148d1aSSakari Ailus 		CLEAR_AFTER_FIELD(p, fmt.meta);
181172148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
18125bc3cb74SMauro Carvalho Chehab 	}
18135bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
18145bc3cb74SMauro Carvalho Chehab }
18155bc3cb74SMauro Carvalho Chehab 
18165bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
18175bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18185bc3cb74SMauro Carvalho Chehab {
18195bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
18205bc3cb74SMauro Carvalho Chehab }
18215bc3cb74SMauro Carvalho Chehab 
18225bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
18235bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18245bc3cb74SMauro Carvalho Chehab {
18255bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
18265bc3cb74SMauro Carvalho Chehab }
18275bc3cb74SMauro Carvalho Chehab 
18285bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
18295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18305bc3cb74SMauro Carvalho Chehab {
18315bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18325bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
18335bc3cb74SMauro Carvalho Chehab 	int err;
18345bc3cb74SMauro Carvalho Chehab 
18355bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18365bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18375bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
18385bc3cb74SMauro Carvalho Chehab 	if (!err)
18395bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
18405bc3cb74SMauro Carvalho Chehab 	return err;
18415bc3cb74SMauro Carvalho Chehab }
18425bc3cb74SMauro Carvalho Chehab 
18435bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
18445bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18455bc3cb74SMauro Carvalho Chehab {
18465bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18475bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
184877fa4e07SShuah Khan 	int ret;
18495bc3cb74SMauro Carvalho Chehab 
185077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
185177fa4e07SShuah Khan 	if (ret)
185277fa4e07SShuah Khan 		return ret;
18535bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18545bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18555bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
18565bc3cb74SMauro Carvalho Chehab }
18575bc3cb74SMauro Carvalho Chehab 
18585bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
18595bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18605bc3cb74SMauro Carvalho Chehab {
18614124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
18625bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
18635bc3cb74SMauro Carvalho Chehab 	int err;
18645bc3cb74SMauro Carvalho Chehab 
18654124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
18664124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
18674124a3c4SAntti Palosaari 
18685bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
18695bc3cb74SMauro Carvalho Chehab 	if (!err)
18705bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
18715bc3cb74SMauro Carvalho Chehab 	return err;
18725bc3cb74SMauro Carvalho Chehab }
18735bc3cb74SMauro Carvalho Chehab 
18744124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
18754124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
18764124a3c4SAntti Palosaari {
18774124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
18784124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
18794124a3c4SAntti Palosaari 
18804124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
18814124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
18824124a3c4SAntti Palosaari 
18834124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
18844124a3c4SAntti Palosaari }
18854124a3c4SAntti Palosaari 
18865bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
18875bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
18885bc3cb74SMauro Carvalho Chehab {
18895bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
18905bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
18915bc3cb74SMauro Carvalho Chehab 
189284099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1893f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
189484099a28SAntti Palosaari 	else
18955bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
18965bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
18975bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
18985bc3cb74SMauro Carvalho Chehab }
18995bc3cb74SMauro Carvalho Chehab 
19005bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
19015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19025bc3cb74SMauro Carvalho Chehab {
19035bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1904b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
19055bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
190677fa4e07SShuah Khan 	int ret;
19075bc3cb74SMauro Carvalho Chehab 
190877fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
190977fa4e07SShuah Khan 	if (ret)
191077fa4e07SShuah Khan 		return ret;
191184099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1912f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
191384099a28SAntti Palosaari 			return -EINVAL;
191484099a28SAntti Palosaari 	} else {
19155bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19165bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
191784099a28SAntti Palosaari 		if (type != p->type)
19185bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
191984099a28SAntti Palosaari 	}
19205bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
19215bc3cb74SMauro Carvalho Chehab }
19225bc3cb74SMauro Carvalho Chehab 
19235bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
19245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19255bc3cb74SMauro Carvalho Chehab {
19265bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19275bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
19285bc3cb74SMauro Carvalho Chehab 
1929aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
19305bc3cb74SMauro Carvalho Chehab }
19315bc3cb74SMauro Carvalho Chehab 
19325bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
19335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19345bc3cb74SMauro Carvalho Chehab {
19355bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1936314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
193777fa4e07SShuah Khan 	int ret;
19385bc3cb74SMauro Carvalho Chehab 
193977fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
194077fa4e07SShuah Khan 	if (ret)
194177fa4e07SShuah Khan 		return ret;
1942314527acSHans Verkuil 	norm = id & vfd->tvnorms;
19435bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
19445bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19455bc3cb74SMauro Carvalho Chehab 
19465bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
1947ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
19485bc3cb74SMauro Carvalho Chehab }
19495bc3cb74SMauro Carvalho Chehab 
19505bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
19515bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19525bc3cb74SMauro Carvalho Chehab {
19535bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19545bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
195577fa4e07SShuah Khan 	int ret;
19565bc3cb74SMauro Carvalho Chehab 
195777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
195877fa4e07SShuah Khan 	if (ret)
195977fa4e07SShuah Khan 		return ret;
19605bc3cb74SMauro Carvalho Chehab 	/*
19611a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
19621a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
19631a2c6866SHans Verkuil 	 * any standards that do not apply removed.
19641a2c6866SHans Verkuil 	 *
19655bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
19665bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
19675bc3cb74SMauro Carvalho Chehab 	 */
19685bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
19695bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
19705bc3cb74SMauro Carvalho Chehab }
19715bc3cb74SMauro Carvalho Chehab 
19725bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
19735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19745bc3cb74SMauro Carvalho Chehab {
19755bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19765bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
19775bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
197877fa4e07SShuah Khan 	int ret;
19795bc3cb74SMauro Carvalho Chehab 
198077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
198177fa4e07SShuah Khan 	if (ret)
198277fa4e07SShuah Khan 		return ret;
198384099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
198484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
198584099a28SAntti Palosaari 		return -EINVAL;
198684099a28SAntti Palosaari 
19875bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19885bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19895bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
19905bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
19915bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
19925bc3cb74SMauro Carvalho Chehab }
19935bc3cb74SMauro Carvalho Chehab 
1994737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
1995737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
1996737c097bSHans Verkuil {
1997737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
1998737c097bSHans Verkuil }
1999737c097bSHans Verkuil 
20005bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
20015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20025bc3cb74SMauro Carvalho Chehab {
20035bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
20044b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20055bc3cb74SMauro Carvalho Chehab 
20065bc3cb74SMauro Carvalho Chehab 	if (ret)
20075bc3cb74SMauro Carvalho Chehab 		return ret;
2008129134e5SSergey Senozhatsky 
2009129134e5SSergey Senozhatsky 	CLEAR_AFTER_FIELD(p, capabilities);
2010129134e5SSergey Senozhatsky 
20115bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
20125bc3cb74SMauro Carvalho Chehab }
20135bc3cb74SMauro Carvalho Chehab 
20145bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
20155bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20165bc3cb74SMauro Carvalho Chehab {
20175bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20184b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20195bc3cb74SMauro Carvalho Chehab 
20205bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
20215bc3cb74SMauro Carvalho Chehab }
20225bc3cb74SMauro Carvalho Chehab 
20235bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
20245bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20255bc3cb74SMauro Carvalho Chehab {
20265bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20274b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20285bc3cb74SMauro Carvalho Chehab 
20295bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
20305bc3cb74SMauro Carvalho Chehab }
20315bc3cb74SMauro Carvalho Chehab 
20325bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
20335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20345bc3cb74SMauro Carvalho Chehab {
20355bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
20364b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20375bc3cb74SMauro Carvalho Chehab 
20385bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
20395bc3cb74SMauro Carvalho Chehab }
20405bc3cb74SMauro Carvalho Chehab 
20415bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
20425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20435bc3cb74SMauro Carvalho Chehab {
20445bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
20454b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
20465bc3cb74SMauro Carvalho Chehab 
2047d52e2381SLaurent Pinchart 	if (ret)
2048d52e2381SLaurent Pinchart 		return ret;
2049d52e2381SLaurent Pinchart 
2050129134e5SSergey Senozhatsky 	CLEAR_AFTER_FIELD(create, capabilities);
20515d351251SHans Verkuil 
2052d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
2053d52e2381SLaurent Pinchart 
2054d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
2055d52e2381SLaurent Pinchart 
2056d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2057d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2058d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2059d52e2381SLaurent Pinchart 
2060d52e2381SLaurent Pinchart 	return ret;
20615bc3cb74SMauro Carvalho Chehab }
20625bc3cb74SMauro Carvalho Chehab 
20635bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
20645bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20655bc3cb74SMauro Carvalho Chehab {
20665bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
20674b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
20685bc3cb74SMauro Carvalho Chehab 
20695bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
20705bc3cb74SMauro Carvalho Chehab }
20715bc3cb74SMauro Carvalho Chehab 
20725bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
20735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20745bc3cb74SMauro Carvalho Chehab {
20755bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
20765bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
20774b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20785bc3cb74SMauro Carvalho Chehab 
20795bc3cb74SMauro Carvalho Chehab 	if (ret)
20805bc3cb74SMauro Carvalho Chehab 		return ret;
20815bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
20825bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
20835bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
20845bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
20855bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20865bc3cb74SMauro Carvalho Chehab 	p->parm.capture.readbuffers = 2;
20875bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
20885bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2089ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
20905bc3cb74SMauro Carvalho Chehab 	return ret;
20915bc3cb74SMauro Carvalho Chehab }
20925bc3cb74SMauro Carvalho Chehab 
20935bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
20945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20955bc3cb74SMauro Carvalho Chehab {
20965bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
20974b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20985bc3cb74SMauro Carvalho Chehab 
20998a7c5594SHans Verkuil 	if (ret)
21008a7c5594SHans Verkuil 		return ret;
21018a7c5594SHans Verkuil 
21024f62e840SHans Verkuil 	/* Note: extendedmode is never used in drivers */
21038a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
21048a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
21058a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
21068a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
21078a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
21088a7c5594SHans Verkuil 	} else {
21098a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
21108a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
21114f62e840SHans Verkuil 		p->parm.capture.extendedmode = 0;
21128a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
21138a7c5594SHans Verkuil 	}
21148a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
21155bc3cb74SMauro Carvalho Chehab }
21165bc3cb74SMauro Carvalho Chehab 
21175bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
21185bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21195bc3cb74SMauro Carvalho Chehab {
21205bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21215bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
21225bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21235bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21245bc3cb74SMauro Carvalho Chehab 
21255bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21265bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
21275bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21285bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
21295bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
21305bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
21315bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21325bc3cb74SMauro Carvalho Chehab }
21335bc3cb74SMauro Carvalho Chehab 
2134e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2135e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2136e6bee368SHans Verkuil {
2137e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2138e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2139e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2140e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2141e6bee368SHans Verkuil 
2142e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2143e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2144e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2145e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2146e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2147e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2148e6bee368SHans Verkuil 	return -ENOTTY;
2149e6bee368SHans Verkuil }
2150e6bee368SHans Verkuil 
21515bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
21525bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21535bc3cb74SMauro Carvalho Chehab {
21545bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21555bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
21565bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21575bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21585bc3cb74SMauro Carvalho Chehab 
21595bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21605bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
21615bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21625bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
21635bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
21645bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
21655bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
21665bc3cb74SMauro Carvalho Chehab }
21675bc3cb74SMauro Carvalho Chehab 
21685bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
21695bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21705bc3cb74SMauro Carvalho Chehab {
21715bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
21725bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
21735bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
21745bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21755bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
21765bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
21775bc3cb74SMauro Carvalho Chehab 
21785bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
21795bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
21805bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
21815bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
21825bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
21835bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
21845bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
21855bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
21865bc3cb74SMauro Carvalho Chehab 
21870f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
21885bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
21895bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
21905bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
21915bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
21925bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1)) {
21935bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
21945bc3cb74SMauro Carvalho Chehab 
21955bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
21965bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
21975bc3cb74SMauro Carvalho Chehab 		return ret;
21985bc3cb74SMauro Carvalho Chehab 	}
21995bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22005bc3cb74SMauro Carvalho Chehab }
22015bc3cb74SMauro Carvalho Chehab 
22025bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
22035bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22045bc3cb74SMauro Carvalho Chehab {
22055bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22065bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22075bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22085bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22095bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22105bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
22115bc3cb74SMauro Carvalho Chehab 
22125bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22135bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
22145bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22155bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
22165bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
22175bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
22185bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
22195bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22205bc3cb74SMauro Carvalho Chehab 
22210f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22225bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22235bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22245bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22255bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
22265bc3cb74SMauro Carvalho Chehab 	if (check_ext_ctrls(&ctrls, 1))
22275bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
22285bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22295bc3cb74SMauro Carvalho Chehab }
22305bc3cb74SMauro Carvalho Chehab 
22315bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22325bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22335bc3cb74SMauro Carvalho Chehab {
22345bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22355bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22365bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22375bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22385bc3cb74SMauro Carvalho Chehab 
22395bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22405bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2241173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2242173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22435bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2244173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2245173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22465bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22475bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22485bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
22495bc3cb74SMauro Carvalho Chehab 					-EINVAL;
22505bc3cb74SMauro Carvalho Chehab }
22515bc3cb74SMauro Carvalho Chehab 
22525bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22535bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22545bc3cb74SMauro Carvalho Chehab {
22555bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22565bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22575bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22585bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22595bc3cb74SMauro Carvalho Chehab 
22605bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22615bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2262173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2263173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22645bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2265173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2266173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
22675bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
22685bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22695bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
22705bc3cb74SMauro Carvalho Chehab 					-EINVAL;
22715bc3cb74SMauro Carvalho Chehab }
22725bc3cb74SMauro Carvalho Chehab 
22735bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
22745bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22755bc3cb74SMauro Carvalho Chehab {
22765bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22775bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
22785bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22795bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22805bc3cb74SMauro Carvalho Chehab 
22815bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
22825bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2283173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2284173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
22855bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2286173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2287173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
22885bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
22895bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22905bc3cb74SMauro Carvalho Chehab 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
22915bc3cb74SMauro Carvalho Chehab 					-EINVAL;
22925bc3cb74SMauro Carvalho Chehab }
22935bc3cb74SMauro Carvalho Chehab 
2294eaec420fSHans Verkuil /*
2295eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2296eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2297eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2298eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2299eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2300eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2301eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2302eaec420fSHans Verkuil  */
2303eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2304eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2305eaec420fSHans Verkuil {
2306eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2307eaec420fSHans Verkuil 	u32 old_type = p->type;
2308eaec420fSHans Verkuil 	int ret;
2309eaec420fSHans Verkuil 
2310eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2311eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2312eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2313eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2314eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2315eaec420fSHans Verkuil 	p->type = old_type;
2316eaec420fSHans Verkuil 	return ret;
2317eaec420fSHans Verkuil }
2318eaec420fSHans Verkuil 
2319eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2320eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2321eaec420fSHans Verkuil {
2322eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2323eaec420fSHans Verkuil 	u32 old_type = p->type;
2324eaec420fSHans Verkuil 	int ret;
2325eaec420fSHans Verkuil 
2326eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2327eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2328eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2329eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2330eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2331eaec420fSHans Verkuil 	p->type = old_type;
2332eaec420fSHans Verkuil 	return ret;
2333eaec420fSHans Verkuil }
2334eaec420fSHans Verkuil 
23355bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
23365bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23375bc3cb74SMauro Carvalho Chehab {
23388cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23395bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
23405bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
23415bc3cb74SMauro Carvalho Chehab 		.type = p->type,
23425bc3cb74SMauro Carvalho Chehab 	};
23435bc3cb74SMauro Carvalho Chehab 	int ret;
23445bc3cb74SMauro Carvalho Chehab 
23455bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
23465bc3cb74SMauro Carvalho Chehab 
23475bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
23485bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
23495b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
23505bc3cb74SMauro Carvalho Chehab 	else
23515b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
23525bc3cb74SMauro Carvalho Chehab 
23538cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23548cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
23558cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
23568cbd94bdSHans Verkuil 
2357eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
23585bc3cb74SMauro Carvalho Chehab 
23595bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
23605bc3cb74SMauro Carvalho Chehab 	if (!ret)
23615bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
23625bc3cb74SMauro Carvalho Chehab 	return ret;
23635bc3cb74SMauro Carvalho Chehab }
23645bc3cb74SMauro Carvalho Chehab 
23655bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
23665bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23675bc3cb74SMauro Carvalho Chehab {
23688cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23695bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
23705bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
23715bc3cb74SMauro Carvalho Chehab 		.type = p->type,
23725bc3cb74SMauro Carvalho Chehab 		.r = p->c,
23735bc3cb74SMauro Carvalho Chehab 	};
23745bc3cb74SMauro Carvalho Chehab 
23755bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
23765bc3cb74SMauro Carvalho Chehab 
23775bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
23785bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
23795b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
23805bc3cb74SMauro Carvalho Chehab 	else
23815b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
23825bc3cb74SMauro Carvalho Chehab 
23838cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
23848cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
23858cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
23868cbd94bdSHans Verkuil 
2387eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
23885bc3cb74SMauro Carvalho Chehab }
23895bc3cb74SMauro Carvalho Chehab 
23905bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
23915bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23925bc3cb74SMauro Carvalho Chehab {
23938cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
23945bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
23955bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
239695dd7b7eSHans Verkuil 	int ret = 0;
239795dd7b7eSHans Verkuil 
239895dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
239995dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
240095dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
240195dd7b7eSHans Verkuil 
24025200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
24035200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
24045200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
24055200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
24065200ab6aSHans Verkuil 
240795dd7b7eSHans Verkuil 	/*
240895dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
240995dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
241095dd7b7eSHans Verkuil 	 */
24115200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
241295dd7b7eSHans Verkuil 		return -ENOTTY;
241395dd7b7eSHans Verkuil 
24145200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
24155200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
24165200ab6aSHans Verkuil 						&p->pixelaspect);
241795dd7b7eSHans Verkuil 
241895dd7b7eSHans Verkuil 	/*
241995dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
242095dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
242195dd7b7eSHans Verkuil 	 */
242295dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
242395dd7b7eSHans Verkuil 		return ret;
242495dd7b7eSHans Verkuil 
242595dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
24265bc3cb74SMauro Carvalho Chehab 
24275bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
24285bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24295bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
24305bc3cb74SMauro Carvalho Chehab 	else
24315bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
24325bc3cb74SMauro Carvalho Chehab 
24338cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24348cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
24358cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
24368cbd94bdSHans Verkuil 
2437eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24385bc3cb74SMauro Carvalho Chehab 	if (ret)
24395bc3cb74SMauro Carvalho Chehab 		return ret;
24405bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
24415bc3cb74SMauro Carvalho Chehab 
24425bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
24438cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
24445bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
24455bc3cb74SMauro Carvalho Chehab 	else
24465bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
24475bc3cb74SMauro Carvalho Chehab 
2448eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24495bc3cb74SMauro Carvalho Chehab 	if (ret)
24505bc3cb74SMauro Carvalho Chehab 		return ret;
24515bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
24529409945cSHans Verkuil 
24535bc3cb74SMauro Carvalho Chehab 	return 0;
24545bc3cb74SMauro Carvalho Chehab }
24555bc3cb74SMauro Carvalho Chehab 
24565bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
24575bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24585bc3cb74SMauro Carvalho Chehab {
24595bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
24605bc3cb74SMauro Carvalho Chehab 	int ret;
24615bc3cb74SMauro Carvalho Chehab 
24625bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
24635bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
24645bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
24655bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
24665bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
24675bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
24685bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
24695bc3cb74SMauro Carvalho Chehab 	return ret;
24705bc3cb74SMauro Carvalho Chehab }
24715bc3cb74SMauro Carvalho Chehab 
24725bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
24735bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24745bc3cb74SMauro Carvalho Chehab {
24755bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
24765bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
247779b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
247879b0c640SHans Verkuil 	struct v4l2_subdev *sd;
247979b0c640SHans Verkuil 	int idx = 0;
24805bc3cb74SMauro Carvalho Chehab 
24815bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
24825bc3cb74SMauro Carvalho Chehab 		return -EPERM;
24833eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
248479b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
248579b0c640SHans Verkuil 			return -EINVAL;
24863eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
24873eef2510SHans Verkuil 			if (p->match.addr == idx++)
248879b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
248979b0c640SHans Verkuil 		return -EINVAL;
249079b0c640SHans Verkuil 	}
2491191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2492191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
24935bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
249479b0c640SHans Verkuil 	return -EINVAL;
24955bc3cb74SMauro Carvalho Chehab #else
24965bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
24975bc3cb74SMauro Carvalho Chehab #endif
24985bc3cb74SMauro Carvalho Chehab }
24995bc3cb74SMauro Carvalho Chehab 
25005bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
25015bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25025bc3cb74SMauro Carvalho Chehab {
25035bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2504977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
250579b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
250679b0c640SHans Verkuil 	struct v4l2_subdev *sd;
250779b0c640SHans Verkuil 	int idx = 0;
25085bc3cb74SMauro Carvalho Chehab 
25095bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25105bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25113eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
251279b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
251379b0c640SHans Verkuil 			return -EINVAL;
25143eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25153eef2510SHans Verkuil 			if (p->match.addr == idx++)
251679b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
251779b0c640SHans Verkuil 		return -EINVAL;
251879b0c640SHans Verkuil 	}
2519191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2520191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25215bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
252279b0c640SHans Verkuil 	return -EINVAL;
25235bc3cb74SMauro Carvalho Chehab #else
25245bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25255bc3cb74SMauro Carvalho Chehab #endif
25265bc3cb74SMauro Carvalho Chehab }
25275bc3cb74SMauro Carvalho Chehab 
252896b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
252979b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
253079b0c640SHans Verkuil {
2531cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
253279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
253396b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
253479b0c640SHans Verkuil 	struct v4l2_subdev *sd;
253579b0c640SHans Verkuil 	int idx = 0;
253679b0c640SHans Verkuil 
253779b0c640SHans Verkuil 	switch (p->match.type) {
253879b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
253979b0c640SHans Verkuil 		if (ops->vidioc_s_register)
254079b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
254179b0c640SHans Verkuil 		if (ops->vidioc_g_register)
254279b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2543c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
254496b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
254596b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
25460f0fe4b9SHans Verkuil 		if (p->match.addr)
25470f0fe4b9SHans Verkuil 			return -EINVAL;
254879b0c640SHans Verkuil 		return 0;
254979b0c640SHans Verkuil 
25503eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
255179b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
255279b0c640SHans Verkuil 			break;
255379b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
25543eef2510SHans Verkuil 			if (p->match.addr != idx++)
25553eef2510SHans Verkuil 				continue;
255679b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
255779b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
255879b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
255979b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2560c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
256179b0c640SHans Verkuil 			return 0;
256279b0c640SHans Verkuil 		}
256379b0c640SHans Verkuil 		break;
256479b0c640SHans Verkuil 	}
256579b0c640SHans Verkuil 	return -EINVAL;
2566cd634f1bSHans Verkuil #else
2567cd634f1bSHans Verkuil 	return -ENOTTY;
2568cd634f1bSHans Verkuil #endif
256979b0c640SHans Verkuil }
257079b0c640SHans Verkuil 
25715bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
25725bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25735bc3cb74SMauro Carvalho Chehab {
25745bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
25755bc3cb74SMauro Carvalho Chehab }
25765bc3cb74SMauro Carvalho Chehab 
25775bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
25785bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25795bc3cb74SMauro Carvalho Chehab {
25805bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
25815bc3cb74SMauro Carvalho Chehab }
25825bc3cb74SMauro Carvalho Chehab 
25835bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
25845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25855bc3cb74SMauro Carvalho Chehab {
25865bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
25875bc3cb74SMauro Carvalho Chehab }
25885bc3cb74SMauro Carvalho Chehab 
25895bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
25905bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25915bc3cb74SMauro Carvalho Chehab {
25925bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
25934b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
25944b20259fSHans Verkuil 
25954b20259fSHans Verkuil 	if (ret)
25964b20259fSHans Verkuil 		return ret;
25975bc3cb74SMauro Carvalho Chehab 
25985bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
25995bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
26005bc3cb74SMauro Carvalho Chehab 
26015bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
26025bc3cb74SMauro Carvalho Chehab }
26035bc3cb74SMauro Carvalho Chehab 
26045bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
26055bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26065bc3cb74SMauro Carvalho Chehab {
26075bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
26085bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
26095bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
26105bc3cb74SMauro Carvalho Chehab 	int err;
26115bc3cb74SMauro Carvalho Chehab 
261284099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2613f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
261484099a28SAntti Palosaari 			return -EINVAL;
261584099a28SAntti Palosaari 		type = p->type;
261684099a28SAntti Palosaari 	} else {
26175bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
26185bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
26195bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
26205bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
262184099a28SAntti Palosaari 	}
2622a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2623a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2624a7f404afSHans Verkuil 		if (err != -ENOTTY)
2625a7f404afSHans Verkuil 			return err;
2626a7f404afSHans Verkuil 	}
262773f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
26285bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
26295bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26305bc3cb74SMauro Carvalho Chehab 			.type = type,
26315bc3cb74SMauro Carvalho Chehab 		};
26325bc3cb74SMauro Carvalho Chehab 
263379e8c7beSMauro Carvalho Chehab 		if (p->index)
263479e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26355bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
26365bc3cb74SMauro Carvalho Chehab 		if (err)
26375bc3cb74SMauro Carvalho Chehab 			return err;
26385bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26395bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
26405bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
26415bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26425bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26435bc3cb74SMauro Carvalho Chehab 		return 0;
26445bc3cb74SMauro Carvalho Chehab 	}
264573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
26465bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
26475bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
26485bc3cb74SMauro Carvalho Chehab 		};
26495bc3cb74SMauro Carvalho Chehab 
26505bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
26515bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
265279e8c7beSMauro Carvalho Chehab 		if (p->index)
265379e8c7beSMauro Carvalho Chehab 			return -EINVAL;
26545bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
26555bc3cb74SMauro Carvalho Chehab 		if (err)
26565bc3cb74SMauro Carvalho Chehab 			return err;
26575bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
26585bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
26595bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
26605bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
26615bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
26625bc3cb74SMauro Carvalho Chehab 		return 0;
26635bc3cb74SMauro Carvalho Chehab 	}
26645bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
26655bc3cb74SMauro Carvalho Chehab }
26665bc3cb74SMauro Carvalho Chehab 
26675bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
26685bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
26695bc3cb74SMauro Carvalho Chehab 	u32 flags;
26705bc3cb74SMauro Carvalho Chehab 	const char * const name;
26713ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
26723ad3b7a2SSami Tolvanen 		    void *fh, void *p);
26735bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
26745bc3cb74SMauro Carvalho Chehab };
26755bc3cb74SMauro Carvalho Chehab 
26765bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
26775bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
26785bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
26795bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
26805bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
26813ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2682043f77edSHans Verkuil /* Always copy back result, even on error */
26833ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
26845bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
26855bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
26865bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
2687c593642cSPankaj Bharadiya 	  sizeof_field(struct v4l2_struct, field)) << 16)
26885bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
26895bc3cb74SMauro Carvalho Chehab 
26903ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
26913ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
26923ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
26933ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
26943ad3b7a2SSami Tolvanen 	{							\
26953ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
26963ad3b7a2SSami Tolvanen 	}
26973ad3b7a2SSami Tolvanen 
26983ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
26995bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
27005bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
27013ad3b7a2SSami Tolvanen 		.flags = _flags,				\
27025bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
27033ad3b7a2SSami Tolvanen 		.func = _func,					\
27045bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
27055bc3cb74SMauro Carvalho Chehab 	}
27065bc3cb74SMauro Carvalho Chehab 
27073ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
27083ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_fbuf)
27093ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
27103ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
27113ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
27123ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
27133ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
27143ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
27153ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
27163ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
27173ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
27183ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
27193ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
27203ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
27213ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
27223ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
27233ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
27243ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
27253ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
27263ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
27273ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
27283ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
27293ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
27303ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
27313ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
27323ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
27335bc3cb74SMauro Carvalho Chehab 
27347c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
27353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2736e5b6b07aSLaurent Pinchart 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
27373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
27383ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
27393ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
27403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
27413ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
27423ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_stub_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
27433ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
27443ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
27453ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
27463ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
27473ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27483ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
27493ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
27503ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
27513ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
27523ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
27533ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
27543ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
27553ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
27563ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
27573ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
27583ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
27593ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
27603ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
27613ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
27623ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2763f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
27643ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
27653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
27663ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2767f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
27683ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
27693ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
27703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
27713ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
27723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
27733ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
27743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
27753ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
27763ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
27773ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
27783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
27793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
27803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
27813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
27823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
27833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
27843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
27853ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
27863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
27873ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
27883ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
27893ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)),
27903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
27913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
27923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
27933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
27943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
27953ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
27963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
27973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
27983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
27993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
28003ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
28013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
28023ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
28033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
28043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_DV_TIMINGS, v4l_stub_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_dv_timings, bt.flags)),
28053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
28063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
28073ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
28083ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
28093ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
28113ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, v4l_stub_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)),
28123ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
28133ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, v4l_stub_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, pad)),
28143ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
28153ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
28163ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)),
28175bc3cb74SMauro Carvalho Chehab };
28185bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
28195bc3cb74SMauro Carvalho Chehab 
282073a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
28215bc3cb74SMauro Carvalho Chehab {
28225bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28235bc3cb74SMauro Carvalho Chehab 		return false;
28245bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
28255bc3cb74SMauro Carvalho Chehab }
28265bc3cb74SMauro Carvalho Chehab 
282773a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2828d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2829d862bc08SHans Verkuil 					 void *arg)
28305bc3cb74SMauro Carvalho Chehab {
28315bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
28325bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2833d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2834d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2835542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2836542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2837d862bc08SHans Verkuil 	}
28385bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
28395bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
28405bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
28415bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
28425bc3cb74SMauro Carvalho Chehab }
28435bc3cb74SMauro Carvalho Chehab 
28445bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
28455bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
28465bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
28475bc3cb74SMauro Carvalho Chehab {
28485bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
28495bc3cb74SMauro Carvalho Chehab 
28505bc3cb74SMauro Carvalho Chehab 	if (prefix)
28515bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
28525bc3cb74SMauro Carvalho Chehab 
28535bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
28545bc3cb74SMauro Carvalho Chehab 	case 'd':
28555bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
28565bc3cb74SMauro Carvalho Chehab 		break;
28575bc3cb74SMauro Carvalho Chehab 	case 'V':
28585bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
28595bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
28605bc3cb74SMauro Carvalho Chehab 			break;
28615bc3cb74SMauro Carvalho Chehab 		}
28625bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
28635bc3cb74SMauro Carvalho Chehab 		return;
28645bc3cb74SMauro Carvalho Chehab 	default:
28655bc3cb74SMauro Carvalho Chehab 		type = "unknown";
28665bc3cb74SMauro Carvalho Chehab 		break;
28675bc3cb74SMauro Carvalho Chehab 	}
28685bc3cb74SMauro Carvalho Chehab 
28695bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
28705bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
28715bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
28725bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
28735bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
28745bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
28755bc3cb74SMauro Carvalho Chehab 	}
28765bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
28775bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
28785bc3cb74SMauro Carvalho Chehab }
28795bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
28805bc3cb74SMauro Carvalho Chehab 
28815bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
28825bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
28835bc3cb74SMauro Carvalho Chehab {
28845bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2885cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
288673a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
28875bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
28885bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
28895bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
28905bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
28915bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
28925bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
289317028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
28945bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
28955bc3cb74SMauro Carvalho Chehab 
28965bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
28975bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
28985bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
28995bc3cb74SMauro Carvalho Chehab 		return ret;
29005bc3cb74SMauro Carvalho Chehab 	}
29015bc3cb74SMauro Carvalho Chehab 
2902b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
29035bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
29045bc3cb74SMauro Carvalho Chehab 
2905cc6eddcdSHans Verkuil 	/*
2906cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
2907cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
2908cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
2909cc6eddcdSHans Verkuil 	 * request at the same time.
2910cc6eddcdSHans Verkuil 	 */
2911cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
2912cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
2913cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
2914cc6eddcdSHans Verkuil 
2915cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
2916cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
2917cc6eddcdSHans Verkuil 	}
2918cc6eddcdSHans Verkuil 
2919d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
292073a11062SHans Verkuil 
2921cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
2922cc6eddcdSHans Verkuil 		if (req_queue_lock)
2923cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
292473a11062SHans Verkuil 		return -ERESTARTSYS;
2925cc6eddcdSHans Verkuil 	}
292673a11062SHans Verkuil 
292773a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
292873a11062SHans Verkuil 		ret = -ENODEV;
292973a11062SHans Verkuil 		goto unlock;
293073a11062SHans Verkuil 	}
293173a11062SHans Verkuil 
29325bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
29335bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
29345bc3cb74SMauro Carvalho Chehab 
29355bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
29365bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
29375bc3cb74SMauro Carvalho Chehab 			goto done;
29385bc3cb74SMauro Carvalho Chehab 
2939b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
29405bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
29415bc3cb74SMauro Carvalho Chehab 			if (ret)
29425bc3cb74SMauro Carvalho Chehab 				goto done;
29435bc3cb74SMauro Carvalho Chehab 		}
29445bc3cb74SMauro Carvalho Chehab 	} else {
29455bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
29465bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
29475bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
29485bc3cb74SMauro Carvalho Chehab 		info = &default_info;
29495bc3cb74SMauro Carvalho Chehab 	}
29505bc3cb74SMauro Carvalho Chehab 
29515bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
29523ad3b7a2SSami Tolvanen 	if (info != &default_info) {
29533ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
29545bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
29555bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
29565bc3cb74SMauro Carvalho Chehab 	} else {
29575bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
2958b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
29595bc3cb74SMauro Carvalho Chehab 			cmd, arg);
29605bc3cb74SMauro Carvalho Chehab 	}
29615bc3cb74SMauro Carvalho Chehab 
29625bc3cb74SMauro Carvalho Chehab done:
296317028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
296417028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
296517028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
29665983d3bcSHans Verkuil 			goto unlock;
296717028cdbSHans Verkuil 
29685bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
29695bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
2970505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
297117028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
29725bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
29735bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
29745bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
29755bc3cb74SMauro Carvalho Chehab 		else {
29765bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
29775bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
29785bc3cb74SMauro Carvalho Chehab 		}
29795bc3cb74SMauro Carvalho Chehab 	}
29805bc3cb74SMauro Carvalho Chehab 
298173a11062SHans Verkuil unlock:
298273a11062SHans Verkuil 	if (lock)
298373a11062SHans Verkuil 		mutex_unlock(lock);
2984cc6eddcdSHans Verkuil 	if (req_queue_lock)
2985cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
29865bc3cb74SMauro Carvalho Chehab 	return ret;
29875bc3cb74SMauro Carvalho Chehab }
29885bc3cb74SMauro Carvalho Chehab 
29895bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2990ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
29915bc3cb74SMauro Carvalho Chehab {
29925bc3cb74SMauro Carvalho Chehab 	int ret = 0;
29935bc3cb74SMauro Carvalho Chehab 
29945bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
299596b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
29965bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
29975bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
29985bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
29995bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
30005bc3cb74SMauro Carvalho Chehab 
30015bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
30025bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
30035bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30045bc3cb74SMauro Carvalho Chehab 				break;
30055bc3cb74SMauro Carvalho Chehab 			}
30065bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
3007ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
30085bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
30095bc3cb74SMauro Carvalho Chehab 			ret = 1;
30105bc3cb74SMauro Carvalho Chehab 		}
30115bc3cb74SMauro Carvalho Chehab 		break;
30125bc3cb74SMauro Carvalho Chehab 	}
30135bc3cb74SMauro Carvalho Chehab 
3014dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
3015dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
3016dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
3017ed45ce2cSHans Verkuil 
3018ed45ce2cSHans Verkuil 		if (edid->blocks) {
30191b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
30201b8b10ccSHans Verkuil 				ret = -EINVAL;
30211b8b10ccSHans Verkuil 				break;
30221b8b10ccSHans Verkuil 			}
3023ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
3024ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
3025ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
3026ed45ce2cSHans Verkuil 			ret = 1;
3027ed45ce2cSHans Verkuil 		}
3028ed45ce2cSHans Verkuil 		break;
3029ed45ce2cSHans Verkuil 	}
3030ed45ce2cSHans Verkuil 
30315bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
30325bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
30335bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
30345bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
30355bc3cb74SMauro Carvalho Chehab 
30365bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
30375bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
30385bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
30395bc3cb74SMauro Carvalho Chehab 				break;
30405bc3cb74SMauro Carvalho Chehab 			}
30415bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
3042ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
30435bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
30445bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
30455bc3cb74SMauro Carvalho Chehab 			ret = 1;
30465bc3cb74SMauro Carvalho Chehab 		}
30475bc3cb74SMauro Carvalho Chehab 		break;
30485bc3cb74SMauro Carvalho Chehab 	}
30493f65c6f6SArnd Bergmann 	case VIDIOC_G_FMT:
30503f65c6f6SArnd Bergmann 	case VIDIOC_S_FMT:
30513f65c6f6SArnd Bergmann 	case VIDIOC_TRY_FMT: {
30523f65c6f6SArnd Bergmann 		struct v4l2_format *fmt = parg;
30533f65c6f6SArnd Bergmann 
30543f65c6f6SArnd Bergmann 		if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
30553f65c6f6SArnd Bergmann 		    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
30563f65c6f6SArnd Bergmann 			break;
30573f65c6f6SArnd Bergmann 		if (fmt->fmt.win.clipcount > 2048)
30583f65c6f6SArnd Bergmann 			return -EINVAL;
30593f65c6f6SArnd Bergmann 		if (!fmt->fmt.win.clipcount)
30603f65c6f6SArnd Bergmann 			break;
30613f65c6f6SArnd Bergmann 
30623f65c6f6SArnd Bergmann 		*user_ptr = (void __user *)fmt->fmt.win.clips;
30633f65c6f6SArnd Bergmann 		*kernel_ptr = (void **)&fmt->fmt.win.clips;
30643f65c6f6SArnd Bergmann 		*array_size = sizeof(struct v4l2_clip)
30653f65c6f6SArnd Bergmann 				* fmt->fmt.win.clipcount;
30663f65c6f6SArnd Bergmann 
30673f65c6f6SArnd Bergmann 		ret = 1;
30683f65c6f6SArnd Bergmann 		break;
30693f65c6f6SArnd Bergmann 	}
30705bc3cb74SMauro Carvalho Chehab 	}
30715bc3cb74SMauro Carvalho Chehab 
30725bc3cb74SMauro Carvalho Chehab 	return ret;
30735bc3cb74SMauro Carvalho Chehab }
30745bc3cb74SMauro Carvalho Chehab 
3075c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd)
3076c8ef1a60SArnd Bergmann {
3077c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
30781a6c0b36SArnd Bergmann 	switch (cmd) {
30791a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32:
30801a6c0b36SArnd Bergmann 		return VIDIOC_DQEVENT;
3081577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3082577c89b0SArnd Bergmann 		return VIDIOC_QUERYBUF;
3083577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3084577c89b0SArnd Bergmann 		return VIDIOC_QBUF;
3085577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3086577c89b0SArnd Bergmann 		return VIDIOC_DQBUF;
3087577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32:
3088577c89b0SArnd Bergmann 		return VIDIOC_PREPARE_BUF;
30891a6c0b36SArnd Bergmann 	}
3090c344f07aSArnd Bergmann #endif
30918dbcc3faSArnd Bergmann 	if (in_compat_syscall())
30928dbcc3faSArnd Bergmann 		return v4l2_compat_translate_cmd(cmd);
30931a6c0b36SArnd Bergmann 
3094c8ef1a60SArnd Bergmann 	return cmd;
3095c8ef1a60SArnd Bergmann }
3096c8ef1a60SArnd Bergmann 
30978dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg,
30988dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd,
3099c8ef1a60SArnd Bergmann 			  bool *always_copy)
3100c8ef1a60SArnd Bergmann {
31018dbcc3faSArnd Bergmann 	unsigned int n = _IOC_SIZE(real_cmd);
31028dbcc3faSArnd Bergmann 	int err = 0;
3103c8ef1a60SArnd Bergmann 
3104c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3105c8ef1a60SArnd Bergmann 		/* read-only ioctl */
3106c8ef1a60SArnd Bergmann 		memset(parg, 0, n);
3107c8ef1a60SArnd Bergmann 		return 0;
3108c8ef1a60SArnd Bergmann 	}
3109c8ef1a60SArnd Bergmann 
31108dbcc3faSArnd Bergmann 	/*
31118dbcc3faSArnd Bergmann 	 * In some cases, only a few fields are used as input,
31128dbcc3faSArnd Bergmann 	 * i.e. when the app sets "index" and then the driver
31138dbcc3faSArnd Bergmann 	 * fills in the rest of the structure for the thing
31148dbcc3faSArnd Bergmann 	 * with that index.  We only need to copy up the first
31158dbcc3faSArnd Bergmann 	 * non-input field.
31168dbcc3faSArnd Bergmann 	 */
31178dbcc3faSArnd Bergmann 	if (v4l2_is_known_ioctl(real_cmd)) {
31188dbcc3faSArnd Bergmann 		u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
31198dbcc3faSArnd Bergmann 
31208dbcc3faSArnd Bergmann 		if (flags & INFO_FL_CLEAR_MASK)
31218dbcc3faSArnd Bergmann 			n = (flags & INFO_FL_CLEAR_MASK) >> 16;
31228dbcc3faSArnd Bergmann 		*always_copy = flags & INFO_FL_ALWAYS_COPY;
31238dbcc3faSArnd Bergmann 	}
31248dbcc3faSArnd Bergmann 
31258dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
31268dbcc3faSArnd Bergmann 		if (copy_from_user(parg, (void __user *)arg, n))
31278dbcc3faSArnd Bergmann 			err = -EFAULT;
31288dbcc3faSArnd Bergmann 	} else if (in_compat_syscall()) {
31297b53cca7SArnd Bergmann 		memset(parg, 0, n);
31308dbcc3faSArnd Bergmann 		err = v4l2_compat_get_user(arg, parg, cmd);
31318dbcc3faSArnd Bergmann 	} else {
31327b53cca7SArnd Bergmann 		memset(parg, 0, n);
3133c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3134c8ef1a60SArnd Bergmann 		switch (cmd) {
3135577c89b0SArnd Bergmann 		case VIDIOC_QUERYBUF_TIME32:
3136577c89b0SArnd Bergmann 		case VIDIOC_QBUF_TIME32:
3137577c89b0SArnd Bergmann 		case VIDIOC_DQBUF_TIME32:
3138577c89b0SArnd Bergmann 		case VIDIOC_PREPARE_BUF_TIME32: {
3139577c89b0SArnd Bergmann 			struct v4l2_buffer_time32 vb32;
3140577c89b0SArnd Bergmann 			struct v4l2_buffer *vb = parg;
3141577c89b0SArnd Bergmann 
3142577c89b0SArnd Bergmann 			if (copy_from_user(&vb32, arg, sizeof(vb32)))
3143577c89b0SArnd Bergmann 				return -EFAULT;
3144577c89b0SArnd Bergmann 
3145577c89b0SArnd Bergmann 			*vb = (struct v4l2_buffer) {
3146577c89b0SArnd Bergmann 				.index		= vb32.index,
3147577c89b0SArnd Bergmann 				.type		= vb32.type,
3148577c89b0SArnd Bergmann 				.bytesused	= vb32.bytesused,
3149577c89b0SArnd Bergmann 				.flags		= vb32.flags,
3150577c89b0SArnd Bergmann 				.field		= vb32.field,
3151577c89b0SArnd Bergmann 				.timestamp.tv_sec	= vb32.timestamp.tv_sec,
3152577c89b0SArnd Bergmann 				.timestamp.tv_usec	= vb32.timestamp.tv_usec,
3153577c89b0SArnd Bergmann 				.timecode	= vb32.timecode,
3154577c89b0SArnd Bergmann 				.sequence	= vb32.sequence,
3155577c89b0SArnd Bergmann 				.memory		= vb32.memory,
3156577c89b0SArnd Bergmann 				.m.userptr	= vb32.m.userptr,
3157577c89b0SArnd Bergmann 				.length		= vb32.length,
3158577c89b0SArnd Bergmann 				.request_fd	= vb32.request_fd,
3159577c89b0SArnd Bergmann 			};
3160577c89b0SArnd Bergmann 			break;
3161577c89b0SArnd Bergmann 		}
3162c8ef1a60SArnd Bergmann 		}
3163c344f07aSArnd Bergmann #endif
31648dbcc3faSArnd Bergmann 	}
3165c8ef1a60SArnd Bergmann 
3166c8ef1a60SArnd Bergmann 	/* zero out anything we don't copy from userspace */
31678dbcc3faSArnd Bergmann 	if (!err && n < _IOC_SIZE(real_cmd))
31688dbcc3faSArnd Bergmann 		memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
31698dbcc3faSArnd Bergmann 	return err;
3170c8ef1a60SArnd Bergmann }
3171c8ef1a60SArnd Bergmann 
31728dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg,
31738dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd)
3174c8ef1a60SArnd Bergmann {
3175c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_READ))
3176c8ef1a60SArnd Bergmann 		return 0;
3177c8ef1a60SArnd Bergmann 
31788dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
31798dbcc3faSArnd Bergmann 		/*  Copy results into user buffer  */
31808dbcc3faSArnd Bergmann 		if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
31818dbcc3faSArnd Bergmann 			return -EFAULT;
31828dbcc3faSArnd Bergmann 		return 0;
31838dbcc3faSArnd Bergmann 	}
31848dbcc3faSArnd Bergmann 
31858dbcc3faSArnd Bergmann 	if (in_compat_syscall())
31868dbcc3faSArnd Bergmann 		return v4l2_compat_put_user(arg, parg, cmd);
31878dbcc3faSArnd Bergmann 
3188c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3189c8ef1a60SArnd Bergmann 	switch (cmd) {
31901a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32: {
31911a6c0b36SArnd Bergmann 		struct v4l2_event *ev = parg;
31924ffb879eSPeilin Ye 		struct v4l2_event_time32 ev32;
31934ffb879eSPeilin Ye 
31944ffb879eSPeilin Ye 		memset(&ev32, 0, sizeof(ev32));
31954ffb879eSPeilin Ye 
31964ffb879eSPeilin Ye 		ev32.type	= ev->type;
31974ffb879eSPeilin Ye 		ev32.pending	= ev->pending;
31984ffb879eSPeilin Ye 		ev32.sequence	= ev->sequence;
31994ffb879eSPeilin Ye 		ev32.timestamp.tv_sec	= ev->timestamp.tv_sec;
32004ffb879eSPeilin Ye 		ev32.timestamp.tv_nsec	= ev->timestamp.tv_nsec;
32014ffb879eSPeilin Ye 		ev32.id		= ev->id;
32021a6c0b36SArnd Bergmann 
32031a6c0b36SArnd Bergmann 		memcpy(&ev32.u, &ev->u, sizeof(ev->u));
32041a6c0b36SArnd Bergmann 		memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
32051a6c0b36SArnd Bergmann 
32061a6c0b36SArnd Bergmann 		if (copy_to_user(arg, &ev32, sizeof(ev32)))
32071a6c0b36SArnd Bergmann 			return -EFAULT;
32081a6c0b36SArnd Bergmann 		break;
32091a6c0b36SArnd Bergmann 	}
3210577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3211577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3212577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3213577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32: {
3214577c89b0SArnd Bergmann 		struct v4l2_buffer *vb = parg;
32154ffb879eSPeilin Ye 		struct v4l2_buffer_time32 vb32;
32164ffb879eSPeilin Ye 
32174ffb879eSPeilin Ye 		memset(&vb32, 0, sizeof(vb32));
32184ffb879eSPeilin Ye 
32194ffb879eSPeilin Ye 		vb32.index	= vb->index;
32204ffb879eSPeilin Ye 		vb32.type	= vb->type;
32214ffb879eSPeilin Ye 		vb32.bytesused	= vb->bytesused;
32224ffb879eSPeilin Ye 		vb32.flags	= vb->flags;
32234ffb879eSPeilin Ye 		vb32.field	= vb->field;
32244ffb879eSPeilin Ye 		vb32.timestamp.tv_sec	= vb->timestamp.tv_sec;
32254ffb879eSPeilin Ye 		vb32.timestamp.tv_usec	= vb->timestamp.tv_usec;
32264ffb879eSPeilin Ye 		vb32.timecode	= vb->timecode;
32274ffb879eSPeilin Ye 		vb32.sequence	= vb->sequence;
32284ffb879eSPeilin Ye 		vb32.memory	= vb->memory;
32294ffb879eSPeilin Ye 		vb32.m.userptr	= vb->m.userptr;
32304ffb879eSPeilin Ye 		vb32.length	= vb->length;
32314ffb879eSPeilin Ye 		vb32.request_fd	= vb->request_fd;
3232577c89b0SArnd Bergmann 
3233577c89b0SArnd Bergmann 		if (copy_to_user(arg, &vb32, sizeof(vb32)))
3234577c89b0SArnd Bergmann 			return -EFAULT;
3235577c89b0SArnd Bergmann 		break;
3236577c89b0SArnd Bergmann 	}
3237c8ef1a60SArnd Bergmann 	}
3238c344f07aSArnd Bergmann #endif
3239c8ef1a60SArnd Bergmann 
3240c8ef1a60SArnd Bergmann 	return 0;
3241c8ef1a60SArnd Bergmann }
3242c8ef1a60SArnd Bergmann 
32435bc3cb74SMauro Carvalho Chehab long
3244c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
32455bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
32465bc3cb74SMauro Carvalho Chehab {
32475bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
3248fb18802aSSakari Ailus 	void    *mbuf = NULL, *array_buf = NULL;
32495bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
32505bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
32515bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
3252043f77edSHans Verkuil 	bool	always_copy = false;
32535bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
32545bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
32555bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
3256c8ef1a60SArnd Bergmann 	unsigned int cmd = video_translate_cmd(orig_cmd);
3257f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
32585bc3cb74SMauro Carvalho Chehab 
32595bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
32605bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
3261f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
32625bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
32635bc3cb74SMauro Carvalho Chehab 		} else {
32645bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
326562a12551SSakari Ailus 			mbuf = kmalloc(ioc_size, GFP_KERNEL);
32665bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
32675bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
32685bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
32695bc3cb74SMauro Carvalho Chehab 		}
32705bc3cb74SMauro Carvalho Chehab 
32718dbcc3faSArnd Bergmann 		err = video_get_user((void __user *)arg, parg, cmd,
32728dbcc3faSArnd Bergmann 				     orig_cmd, &always_copy);
3273c8ef1a60SArnd Bergmann 		if (err)
32745bc3cb74SMauro Carvalho Chehab 			goto out;
32751dc8b65cSArnd Bergmann 	}
32765bc3cb74SMauro Carvalho Chehab 
32775bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
32785bc3cb74SMauro Carvalho Chehab 	if (err < 0)
32795bc3cb74SMauro Carvalho Chehab 		goto out;
32805bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
32815bc3cb74SMauro Carvalho Chehab 
32825bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3283fb18802aSSakari Ailus 		array_buf = kvmalloc(array_size, GFP_KERNEL);
32845bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
3285fb18802aSSakari Ailus 		if (array_buf == NULL)
32865bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
32875bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
32888dbcc3faSArnd Bergmann 		if (in_compat_syscall())
3289fb18802aSSakari Ailus 			err = v4l2_compat_get_array_args(file, array_buf,
3290fb18802aSSakari Ailus 							 user_ptr, array_size,
3291fb18802aSSakari Ailus 							 orig_cmd, parg);
32928dbcc3faSArnd Bergmann 		else
3293fb18802aSSakari Ailus 			err = copy_from_user(array_buf, user_ptr, array_size) ?
32948dbcc3faSArnd Bergmann 								-EFAULT : 0;
32958dbcc3faSArnd Bergmann 		if (err)
32965bc3cb74SMauro Carvalho Chehab 			goto out_array_args;
3297fb18802aSSakari Ailus 		*kernel_ptr = array_buf;
32985bc3cb74SMauro Carvalho Chehab 	}
32995bc3cb74SMauro Carvalho Chehab 
33005bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
33015bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3302181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
33035bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3304181a4a2dSHans Verkuil 		goto out;
3305181a4a2dSHans Verkuil 	}
3306181a4a2dSHans Verkuil 
3307aa32f4c0SHans Verkuil 	if (err == 0) {
3308aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3309aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3310aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3311aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3312aa32f4c0SHans Verkuil 	}
33135bc3cb74SMauro Carvalho Chehab 
33145bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3315ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
33168dbcc3faSArnd Bergmann 		if (in_compat_syscall()) {
33178dbcc3faSArnd Bergmann 			int put_err;
33188dbcc3faSArnd Bergmann 
3319fb18802aSSakari Ailus 			put_err = v4l2_compat_put_array_args(file, user_ptr,
3320fb18802aSSakari Ailus 							     array_buf,
3321fb18802aSSakari Ailus 							     array_size,
3322fb18802aSSakari Ailus 							     orig_cmd, parg);
33238dbcc3faSArnd Bergmann 			if (put_err)
33248dbcc3faSArnd Bergmann 				err = put_err;
3325fb18802aSSakari Ailus 		} else if (copy_to_user(user_ptr, array_buf, array_size)) {
33265bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
33278dbcc3faSArnd Bergmann 		}
33285bc3cb74SMauro Carvalho Chehab 		goto out_array_args;
33295bc3cb74SMauro Carvalho Chehab 	}
3330043f77edSHans Verkuil 	/*
3331043f77edSHans Verkuil 	 * Some ioctls can return an error, but still have valid
3332043f77edSHans Verkuil 	 * results that must be returned.
3333043f77edSHans Verkuil 	 */
3334043f77edSHans Verkuil 	if (err < 0 && !always_copy)
33355bc3cb74SMauro Carvalho Chehab 		goto out;
33365bc3cb74SMauro Carvalho Chehab 
33375bc3cb74SMauro Carvalho Chehab out_array_args:
33388dbcc3faSArnd Bergmann 	if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
33395bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
33405bc3cb74SMauro Carvalho Chehab out:
3341fb18802aSSakari Ailus 	kvfree(array_buf);
334262a12551SSakari Ailus 	kfree(mbuf);
33435bc3cb74SMauro Carvalho Chehab 	return err;
33445bc3cb74SMauro Carvalho Chehab }
33455bc3cb74SMauro Carvalho Chehab 
33465bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
33475bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
33485bc3cb74SMauro Carvalho Chehab {
33495bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
33505bc3cb74SMauro Carvalho Chehab }
33515bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3352