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 
19a418bb3fSLaurent Pinchart #include <linux/v4l2-subdev.h>
205bc3cb74SMauro Carvalho Chehab #include <linux/videodev2.h>
215bc3cb74SMauro Carvalho Chehab 
22f2d8b691SSakari Ailus #include <media/media-device.h> /* for media_set_bus_info() */
235bc3cb74SMauro Carvalho Chehab #include <media/v4l2-common.h>
245bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ioctl.h>
255bc3cb74SMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
265bc3cb74SMauro Carvalho Chehab #include <media/v4l2-fh.h>
275bc3cb74SMauro Carvalho Chehab #include <media/v4l2-event.h>
285bc3cb74SMauro Carvalho Chehab #include <media/v4l2-device.h>
29c139990eSJunghak Sung #include <media/videobuf2-v4l2.h>
3077fa4e07SShuah Khan #include <media/v4l2-mc.h>
31d862bc08SHans Verkuil #include <media/v4l2-mem2mem.h>
325bc3cb74SMauro Carvalho Chehab 
33aa32f4c0SHans Verkuil #include <trace/events/v4l2.h>
34aa32f4c0SHans Verkuil 
3573f35418SHans Verkuil #define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
3673f35418SHans Verkuil 
375bc3cb74SMauro Carvalho Chehab struct std_descr {
385bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
395bc3cb74SMauro Carvalho Chehab 	const char *descr;
405bc3cb74SMauro Carvalho Chehab };
415bc3cb74SMauro Carvalho Chehab 
425bc3cb74SMauro Carvalho Chehab static const struct std_descr standards[] = {
435bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC,	"NTSC"      },
445bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
455bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
465bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
475bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
485bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL,		"PAL"       },
495bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
505bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B,	"PAL-B"     },
515bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
525bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_G,	"PAL-G"     },
535bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_H,	"PAL-H"     },
545bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_I,	"PAL-I"     },
555bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
565bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D,	"PAL-D"     },
575bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
585bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_K,	"PAL-K"     },
595bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_M,	"PAL-M"     },
605bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_N,	"PAL-N"     },
615bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
625bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_PAL_60,	"PAL-60"    },
635bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM,	"SECAM"     },
645bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
655bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
665bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
675bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
685bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
695bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
705bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
715bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
725bc3cb74SMauro Carvalho Chehab 	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
735bc3cb74SMauro Carvalho Chehab 	{ 0,			"Unknown"   }
745bc3cb74SMauro Carvalho Chehab };
755bc3cb74SMauro Carvalho Chehab 
765bc3cb74SMauro Carvalho Chehab /* video4linux standard ID conversion to standard name
775bc3cb74SMauro Carvalho Chehab  */
v4l2_norm_to_name(v4l2_std_id id)785bc3cb74SMauro Carvalho Chehab const char *v4l2_norm_to_name(v4l2_std_id id)
795bc3cb74SMauro Carvalho Chehab {
805bc3cb74SMauro Carvalho Chehab 	u32 myid = id;
815bc3cb74SMauro Carvalho Chehab 	int i;
825bc3cb74SMauro Carvalho Chehab 
835bc3cb74SMauro Carvalho Chehab 	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
844faf7066SMauro Carvalho Chehab 	   64 bit comparisons. So, on that architecture, with some gcc
855bc3cb74SMauro Carvalho Chehab 	   variants, compilation fails. Currently, the max value is 30bit wide.
865bc3cb74SMauro Carvalho Chehab 	 */
875bc3cb74SMauro Carvalho Chehab 	BUG_ON(myid != id);
885bc3cb74SMauro Carvalho Chehab 
895bc3cb74SMauro Carvalho Chehab 	for (i = 0; standards[i].std; i++)
905bc3cb74SMauro Carvalho Chehab 		if (myid == standards[i].std)
915bc3cb74SMauro Carvalho Chehab 			break;
925bc3cb74SMauro Carvalho Chehab 	return standards[i].descr;
935bc3cb74SMauro Carvalho Chehab }
945bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_norm_to_name);
955bc3cb74SMauro Carvalho Chehab 
965bc3cb74SMauro Carvalho Chehab /* Returns frame period for the given standard */
v4l2_video_std_frame_period(int id,struct v4l2_fract * frameperiod)975bc3cb74SMauro Carvalho Chehab void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
985bc3cb74SMauro Carvalho Chehab {
995bc3cb74SMauro Carvalho Chehab 	if (id & V4L2_STD_525_60) {
1005bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1001;
1015bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 30000;
1025bc3cb74SMauro Carvalho Chehab 	} else {
1035bc3cb74SMauro Carvalho Chehab 		frameperiod->numerator = 1;
1045bc3cb74SMauro Carvalho Chehab 		frameperiod->denominator = 25;
1055bc3cb74SMauro Carvalho Chehab 	}
1065bc3cb74SMauro Carvalho Chehab }
1075bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_frame_period);
1085bc3cb74SMauro Carvalho Chehab 
1095bc3cb74SMauro Carvalho Chehab /* Fill in the fields of a v4l2_standard structure according to the
1105bc3cb74SMauro Carvalho Chehab    'id' and 'transmission' parameters.  Returns negative on error.  */
v4l2_video_std_construct(struct v4l2_standard * vs,int id,const char * name)1115bc3cb74SMauro Carvalho Chehab int v4l2_video_std_construct(struct v4l2_standard *vs,
1125bc3cb74SMauro Carvalho Chehab 			     int id, const char *name)
1135bc3cb74SMauro Carvalho Chehab {
1145bc3cb74SMauro Carvalho Chehab 	vs->id = id;
1155bc3cb74SMauro Carvalho Chehab 	v4l2_video_std_frame_period(id, &vs->frameperiod);
1165bc3cb74SMauro Carvalho Chehab 	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
117c0decac1SMauro Carvalho Chehab 	strscpy(vs->name, name, sizeof(vs->name));
1185bc3cb74SMauro Carvalho Chehab 	return 0;
1195bc3cb74SMauro Carvalho Chehab }
1205bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_video_std_construct);
1215bc3cb74SMauro Carvalho Chehab 
122aa2f8871SNiklas Söderlund /* Fill in the fields of a v4l2_standard structure according to the
123aa2f8871SNiklas Söderlund  * 'id' and 'vs->index' parameters. Returns negative on error. */
v4l_video_std_enumstd(struct v4l2_standard * vs,v4l2_std_id id)124aa2f8871SNiklas Söderlund int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id)
125aa2f8871SNiklas Söderlund {
126aa2f8871SNiklas Söderlund 	v4l2_std_id curr_id = 0;
127aa2f8871SNiklas Söderlund 	unsigned int index = vs->index, i, j = 0;
128aa2f8871SNiklas Söderlund 	const char *descr = "";
129aa2f8871SNiklas Söderlund 
130aa2f8871SNiklas Söderlund 	/* Return -ENODATA if the id for the current input
131aa2f8871SNiklas Söderlund 	   or output is 0, meaning that it doesn't support this API. */
132aa2f8871SNiklas Söderlund 	if (id == 0)
133aa2f8871SNiklas Söderlund 		return -ENODATA;
134aa2f8871SNiklas Söderlund 
135aa2f8871SNiklas Söderlund 	/* Return norm array in a canonical way */
136aa2f8871SNiklas Söderlund 	for (i = 0; i <= index && id; i++) {
137aa2f8871SNiklas Söderlund 		/* last std value in the standards array is 0, so this
138aa2f8871SNiklas Söderlund 		   while always ends there since (id & 0) == 0. */
139aa2f8871SNiklas Söderlund 		while ((id & standards[j].std) != standards[j].std)
140aa2f8871SNiklas Söderlund 			j++;
141aa2f8871SNiklas Söderlund 		curr_id = standards[j].std;
142aa2f8871SNiklas Söderlund 		descr = standards[j].descr;
143aa2f8871SNiklas Söderlund 		j++;
144aa2f8871SNiklas Söderlund 		if (curr_id == 0)
145aa2f8871SNiklas Söderlund 			break;
146aa2f8871SNiklas Söderlund 		if (curr_id != V4L2_STD_PAL &&
147aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_SECAM &&
148aa2f8871SNiklas Söderlund 				curr_id != V4L2_STD_NTSC)
149aa2f8871SNiklas Söderlund 			id &= ~curr_id;
150aa2f8871SNiklas Söderlund 	}
151aa2f8871SNiklas Söderlund 	if (i <= index)
152aa2f8871SNiklas Söderlund 		return -EINVAL;
153aa2f8871SNiklas Söderlund 
154aa2f8871SNiklas Söderlund 	v4l2_video_std_construct(vs, curr_id, descr);
155aa2f8871SNiklas Söderlund 	return 0;
156aa2f8871SNiklas Söderlund }
157aa2f8871SNiklas Söderlund 
1585bc3cb74SMauro Carvalho Chehab /* ----------------------------------------------------------------- */
1595bc3cb74SMauro Carvalho Chehab /* some arrays for pretty-printing debug messages of enum types      */
1605bc3cb74SMauro Carvalho Chehab 
1615bc3cb74SMauro Carvalho Chehab const char *v4l2_field_names[] = {
1625bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ANY]        = "any",
1635bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_NONE]       = "none",
1645bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_TOP]        = "top",
1655bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_BOTTOM]     = "bottom",
1665bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED] = "interlaced",
1675bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
1685bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
1695bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_ALTERNATE]  = "alternate",
1705bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
1715bc3cb74SMauro Carvalho Chehab 	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
1725bc3cb74SMauro Carvalho Chehab };
1735bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_field_names);
1745bc3cb74SMauro Carvalho Chehab 
1755bc3cb74SMauro Carvalho Chehab const char *v4l2_type_names[] = {
176839aa56dSHans Verkuil 	[0]				   = "0",
1775bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
1785bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
1795bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
1805bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
1815bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
1825bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
1835bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
1845bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
1855bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
1865bc3cb74SMauro Carvalho Chehab 	[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
1876f3073b8SAntti Palosaari 	[V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
1889effc72fSAntti Palosaari 	[V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
189fb9ffa6aSLaurent Pinchart 	[V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
19072148d1aSSakari Ailus 	[V4L2_BUF_TYPE_META_OUTPUT]	   = "meta-out",
1915bc3cb74SMauro Carvalho Chehab };
1925bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l2_type_names);
1935bc3cb74SMauro Carvalho Chehab 
1945bc3cb74SMauro Carvalho Chehab static const char *v4l2_memory_names[] = {
1955bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_MMAP]    = "mmap",
1965bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_USERPTR] = "userptr",
1975bc3cb74SMauro Carvalho Chehab 	[V4L2_MEMORY_OVERLAY] = "overlay",
198051c7788SSumit Semwal 	[V4L2_MEMORY_DMABUF] = "dmabuf",
1995bc3cb74SMauro Carvalho Chehab };
2005bc3cb74SMauro Carvalho Chehab 
201d9246240SHans Verkuil #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
2025bc3cb74SMauro Carvalho Chehab 
2035bc3cb74SMauro Carvalho Chehab /* ------------------------------------------------------------------ */
2045bc3cb74SMauro Carvalho Chehab /* debug help functions                                               */
2055bc3cb74SMauro Carvalho Chehab 
v4l_print_querycap(const void * arg,bool write_only)2065bc3cb74SMauro Carvalho Chehab static void v4l_print_querycap(const void *arg, bool write_only)
2075bc3cb74SMauro Carvalho Chehab {
2085bc3cb74SMauro Carvalho Chehab 	const struct v4l2_capability *p = arg;
2095bc3cb74SMauro Carvalho Chehab 
2108720427cSMauro Carvalho Chehab 	pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n",
21127d5a87cSHans Verkuil 		(int)sizeof(p->driver), p->driver,
21227d5a87cSHans Verkuil 		(int)sizeof(p->card), p->card,
21327d5a87cSHans Verkuil 		(int)sizeof(p->bus_info), p->bus_info,
2145bc3cb74SMauro Carvalho Chehab 		p->version, p->capabilities, p->device_caps);
2155bc3cb74SMauro Carvalho Chehab }
2165bc3cb74SMauro Carvalho Chehab 
v4l_print_enuminput(const void * arg,bool write_only)2175bc3cb74SMauro Carvalho Chehab static void v4l_print_enuminput(const void *arg, bool write_only)
2185bc3cb74SMauro Carvalho Chehab {
2195bc3cb74SMauro Carvalho Chehab 	const struct v4l2_input *p = arg;
2205bc3cb74SMauro Carvalho Chehab 
2218720427cSMauro 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",
22227d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
22327d5a87cSHans Verkuil 		p->tuner, (unsigned long long)p->std, p->status,
22427d5a87cSHans Verkuil 		p->capabilities);
2255bc3cb74SMauro Carvalho Chehab }
2265bc3cb74SMauro Carvalho Chehab 
v4l_print_enumoutput(const void * arg,bool write_only)2275bc3cb74SMauro Carvalho Chehab static void v4l_print_enumoutput(const void *arg, bool write_only)
2285bc3cb74SMauro Carvalho Chehab {
2295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_output *p = arg;
2305bc3cb74SMauro Carvalho Chehab 
2318720427cSMauro Carvalho Chehab 	pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
23227d5a87cSHans Verkuil 		p->index, (int)sizeof(p->name), p->name, p->type, p->audioset,
23327d5a87cSHans Verkuil 		p->modulator, (unsigned long long)p->std, p->capabilities);
2345bc3cb74SMauro Carvalho Chehab }
2355bc3cb74SMauro Carvalho Chehab 
v4l_print_audio(const void * arg,bool write_only)2365bc3cb74SMauro Carvalho Chehab static void v4l_print_audio(const void *arg, bool write_only)
2375bc3cb74SMauro Carvalho Chehab {
2385bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audio *p = arg;
2395bc3cb74SMauro Carvalho Chehab 
2405bc3cb74SMauro Carvalho Chehab 	if (write_only)
2415bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
2425bc3cb74SMauro Carvalho Chehab 	else
24327d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
24427d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
24527d5a87cSHans Verkuil 			p->capability, p->mode);
2465bc3cb74SMauro Carvalho Chehab }
2475bc3cb74SMauro Carvalho Chehab 
v4l_print_audioout(const void * arg,bool write_only)2485bc3cb74SMauro Carvalho Chehab static void v4l_print_audioout(const void *arg, bool write_only)
2495bc3cb74SMauro Carvalho Chehab {
2505bc3cb74SMauro Carvalho Chehab 	const struct v4l2_audioout *p = arg;
2515bc3cb74SMauro Carvalho Chehab 
2525bc3cb74SMauro Carvalho Chehab 	if (write_only)
2535bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u\n", p->index);
2545bc3cb74SMauro Carvalho Chehab 	else
25527d5a87cSHans Verkuil 		pr_cont("index=%u, name=%.*s, capability=0x%x, mode=0x%x\n",
25627d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name,
25727d5a87cSHans Verkuil 			p->capability, p->mode);
2585bc3cb74SMauro Carvalho Chehab }
2595bc3cb74SMauro Carvalho Chehab 
v4l_print_fmtdesc(const void * arg,bool write_only)2605bc3cb74SMauro Carvalho Chehab static void v4l_print_fmtdesc(const void *arg, bool write_only)
2615bc3cb74SMauro Carvalho Chehab {
2625bc3cb74SMauro Carvalho Chehab 	const struct v4l2_fmtdesc *p = arg;
2635bc3cb74SMauro Carvalho Chehab 
264e927e1e0SSakari Ailus 	pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%p4cc, mbus_code=0x%04x, description='%.*s'\n",
2655bc3cb74SMauro Carvalho Chehab 		p->index, prt_names(p->type, v4l2_type_names),
266e927e1e0SSakari Ailus 		p->flags, &p->pixelformat, p->mbus_code,
26727d5a87cSHans Verkuil 		(int)sizeof(p->description), p->description);
2685bc3cb74SMauro Carvalho Chehab }
2695bc3cb74SMauro Carvalho Chehab 
v4l_print_format(const void * arg,bool write_only)2705bc3cb74SMauro Carvalho Chehab static void v4l_print_format(const void *arg, bool write_only)
2715bc3cb74SMauro Carvalho Chehab {
2725bc3cb74SMauro Carvalho Chehab 	const struct v4l2_format *p = arg;
2735bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format *pix;
2745bc3cb74SMauro Carvalho Chehab 	const struct v4l2_pix_format_mplane *mp;
2755bc3cb74SMauro Carvalho Chehab 	const struct v4l2_vbi_format *vbi;
2765bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_format *sliced;
2775bc3cb74SMauro Carvalho Chehab 	const struct v4l2_window *win;
278fb9ffa6aSLaurent Pinchart 	const struct v4l2_meta_format *meta;
27924bb30c8SSakari Ailus 	u32 pixelformat;
2807fe9f01cSSakari Ailus 	u32 planes;
2815bc3cb74SMauro Carvalho Chehab 	unsigned i;
2825bc3cb74SMauro Carvalho Chehab 
2835bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
2845bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
2855bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2865bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2875bc3cb74SMauro Carvalho Chehab 		pix = &p->fmt.pix;
288e927e1e0SSakari 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",
289e927e1e0SSakari Ailus 			pix->width, pix->height, &pix->pixelformat,
2905bc3cb74SMauro Carvalho Chehab 			prt_names(pix->field, v4l2_field_names),
2915bc3cb74SMauro Carvalho Chehab 			pix->bytesperline, pix->sizeimage,
292736d96b5SHans Verkuil 			pix->colorspace, pix->flags, pix->ycbcr_enc,
29374fdcb2eSHans Verkuil 			pix->quantization, pix->xfer_func);
2945bc3cb74SMauro Carvalho Chehab 		break;
2955bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
2965bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2975bc3cb74SMauro Carvalho Chehab 		mp = &p->fmt.pix_mp;
29824bb30c8SSakari Ailus 		pixelformat = mp->pixelformat;
299e927e1e0SSakari 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",
30024bb30c8SSakari Ailus 			mp->width, mp->height, &pixelformat,
3015bc3cb74SMauro Carvalho Chehab 			prt_names(mp->field, v4l2_field_names),
302736d96b5SHans Verkuil 			mp->colorspace, mp->num_planes, mp->flags,
30374fdcb2eSHans Verkuil 			mp->ycbcr_enc, mp->quantization, mp->xfer_func);
3047fe9f01cSSakari Ailus 		planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
3057fe9f01cSSakari Ailus 		for (i = 0; i < planes; i++)
3065bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
3075bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].bytesperline,
3085bc3cb74SMauro Carvalho Chehab 					mp->plane_fmt[i].sizeimage);
3095bc3cb74SMauro Carvalho Chehab 		break;
3105bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3115bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
3125bc3cb74SMauro Carvalho Chehab 		win = &p->fmt.win;
31399ba0703SHans Verkuil 		pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, global_alpha=0x%02x\n",
314560dde24SHans Verkuil 			win->w.width, win->w.height, win->w.left, win->w.top,
3155bc3cb74SMauro Carvalho Chehab 			prt_names(win->field, v4l2_field_names),
31699ba0703SHans Verkuil 			win->chromakey, win->global_alpha);
3175bc3cb74SMauro Carvalho Chehab 		break;
3185bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
3195bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
3205bc3cb74SMauro Carvalho Chehab 		vbi = &p->fmt.vbi;
321e927e1e0SSakari Ailus 		pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%p4cc, start=%u,%u, count=%u,%u\n",
3225bc3cb74SMauro Carvalho Chehab 			vbi->sampling_rate, vbi->offset,
323e927e1e0SSakari Ailus 			vbi->samples_per_line, &vbi->sample_format,
3245bc3cb74SMauro Carvalho Chehab 			vbi->start[0], vbi->start[1],
3255bc3cb74SMauro Carvalho Chehab 			vbi->count[0], vbi->count[1]);
3265bc3cb74SMauro Carvalho Chehab 		break;
3275bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
3285bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
3295bc3cb74SMauro Carvalho Chehab 		sliced = &p->fmt.sliced;
3305bc3cb74SMauro Carvalho Chehab 		pr_cont(", service_set=0x%08x, io_size=%d\n",
3315bc3cb74SMauro Carvalho Chehab 				sliced->service_set, sliced->io_size);
3325bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < 24; i++)
3335bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
3345bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[0][i],
3355bc3cb74SMauro Carvalho Chehab 				sliced->service_lines[1][i]);
3365bc3cb74SMauro Carvalho Chehab 		break;
337582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
3389effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
33924bb30c8SSakari Ailus 		pixelformat = p->fmt.sdr.pixelformat;
34024bb30c8SSakari Ailus 		pr_cont(", pixelformat=%p4cc\n", &pixelformat);
341582c52cbSAntti Palosaari 		break;
342fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
34372148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
344fb9ffa6aSLaurent Pinchart 		meta = &p->fmt.meta;
34524bb30c8SSakari Ailus 		pixelformat = meta->dataformat;
346e927e1e0SSakari Ailus 		pr_cont(", dataformat=%p4cc, buffersize=%u\n",
34724bb30c8SSakari Ailus 			&pixelformat, meta->buffersize);
348fb9ffa6aSLaurent Pinchart 		break;
3495bc3cb74SMauro Carvalho Chehab 	}
3505bc3cb74SMauro Carvalho Chehab }
3515bc3cb74SMauro Carvalho Chehab 
v4l_print_framebuffer(const void * arg,bool write_only)3525bc3cb74SMauro Carvalho Chehab static void v4l_print_framebuffer(const void *arg, bool write_only)
3535bc3cb74SMauro Carvalho Chehab {
3545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_framebuffer *p = arg;
3555bc3cb74SMauro Carvalho Chehab 
356e927e1e0SSakari 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",
357e927e1e0SSakari Ailus 		p->capability, p->flags, p->base, p->fmt.width, p->fmt.height,
358e927e1e0SSakari Ailus 		&p->fmt.pixelformat, p->fmt.bytesperline, p->fmt.sizeimage,
3595bc3cb74SMauro Carvalho Chehab 		p->fmt.colorspace);
3605bc3cb74SMauro Carvalho Chehab }
3615bc3cb74SMauro Carvalho Chehab 
v4l_print_buftype(const void * arg,bool write_only)3625bc3cb74SMauro Carvalho Chehab static void v4l_print_buftype(const void *arg, bool write_only)
3635bc3cb74SMauro Carvalho Chehab {
3645bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
3655bc3cb74SMauro Carvalho Chehab }
3665bc3cb74SMauro Carvalho Chehab 
v4l_print_modulator(const void * arg,bool write_only)3675bc3cb74SMauro Carvalho Chehab static void v4l_print_modulator(const void *arg, bool write_only)
3685bc3cb74SMauro Carvalho Chehab {
3695bc3cb74SMauro Carvalho Chehab 	const struct v4l2_modulator *p = arg;
3705bc3cb74SMauro Carvalho Chehab 
3715bc3cb74SMauro Carvalho Chehab 	if (write_only)
372560dde24SHans Verkuil 		pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
3735bc3cb74SMauro Carvalho Chehab 	else
3748720427cSMauro Carvalho Chehab 		pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
37527d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->capability,
3765bc3cb74SMauro Carvalho Chehab 			p->rangelow, p->rangehigh, p->txsubchans);
3775bc3cb74SMauro Carvalho Chehab }
3785bc3cb74SMauro Carvalho Chehab 
v4l_print_tuner(const void * arg,bool write_only)3795bc3cb74SMauro Carvalho Chehab static void v4l_print_tuner(const void *arg, bool write_only)
3805bc3cb74SMauro Carvalho Chehab {
3815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_tuner *p = arg;
3825bc3cb74SMauro Carvalho Chehab 
3835bc3cb74SMauro Carvalho Chehab 	if (write_only)
3845bc3cb74SMauro Carvalho Chehab 		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
3855bc3cb74SMauro Carvalho Chehab 	else
3868720427cSMauro 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",
38727d5a87cSHans Verkuil 			p->index, (int)sizeof(p->name), p->name, p->type,
3885bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
3895bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->signal, p->afc,
3905bc3cb74SMauro Carvalho Chehab 			p->rxsubchans, p->audmode);
3915bc3cb74SMauro Carvalho Chehab }
3925bc3cb74SMauro Carvalho Chehab 
v4l_print_frequency(const void * arg,bool write_only)3935bc3cb74SMauro Carvalho Chehab static void v4l_print_frequency(const void *arg, bool write_only)
3945bc3cb74SMauro Carvalho Chehab {
3955bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency *p = arg;
3965bc3cb74SMauro Carvalho Chehab 
3975bc3cb74SMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, frequency=%u\n",
3985bc3cb74SMauro Carvalho Chehab 				p->tuner, p->type, p->frequency);
3995bc3cb74SMauro Carvalho Chehab }
4005bc3cb74SMauro Carvalho Chehab 
v4l_print_standard(const void * arg,bool write_only)4015bc3cb74SMauro Carvalho Chehab static void v4l_print_standard(const void *arg, bool write_only)
4025bc3cb74SMauro Carvalho Chehab {
4035bc3cb74SMauro Carvalho Chehab 	const struct v4l2_standard *p = arg;
4045bc3cb74SMauro Carvalho Chehab 
4058720427cSMauro Carvalho Chehab 	pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n",
4068720427cSMauro Carvalho Chehab 		p->index,
40727d5a87cSHans Verkuil 		(unsigned long long)p->id, (int)sizeof(p->name), p->name,
4085bc3cb74SMauro Carvalho Chehab 		p->frameperiod.numerator,
4095bc3cb74SMauro Carvalho Chehab 		p->frameperiod.denominator,
4105bc3cb74SMauro Carvalho Chehab 		p->framelines);
4115bc3cb74SMauro Carvalho Chehab }
4125bc3cb74SMauro Carvalho Chehab 
v4l_print_std(const void * arg,bool write_only)4135bc3cb74SMauro Carvalho Chehab static void v4l_print_std(const void *arg, bool write_only)
4145bc3cb74SMauro Carvalho Chehab {
4155bc3cb74SMauro Carvalho Chehab 	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
4165bc3cb74SMauro Carvalho Chehab }
4175bc3cb74SMauro Carvalho Chehab 
v4l_print_hw_freq_seek(const void * arg,bool write_only)4185bc3cb74SMauro Carvalho Chehab static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
4195bc3cb74SMauro Carvalho Chehab {
4205bc3cb74SMauro Carvalho Chehab 	const struct v4l2_hw_freq_seek *p = arg;
4215bc3cb74SMauro Carvalho Chehab 
4228720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n",
42379e8c7beSMauro Carvalho Chehab 		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
42479e8c7beSMauro Carvalho Chehab 		p->rangelow, p->rangehigh);
4255bc3cb74SMauro Carvalho Chehab }
4265bc3cb74SMauro Carvalho Chehab 
v4l_print_requestbuffers(const void * arg,bool write_only)4275bc3cb74SMauro Carvalho Chehab static void v4l_print_requestbuffers(const void *arg, bool write_only)
4285bc3cb74SMauro Carvalho Chehab {
4295bc3cb74SMauro Carvalho Chehab 	const struct v4l2_requestbuffers *p = arg;
4305bc3cb74SMauro Carvalho Chehab 
4315bc3cb74SMauro Carvalho Chehab 	pr_cont("count=%d, type=%s, memory=%s\n",
4325bc3cb74SMauro Carvalho Chehab 		p->count,
4335bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
4345bc3cb74SMauro Carvalho Chehab 		prt_names(p->memory, v4l2_memory_names));
4355bc3cb74SMauro Carvalho Chehab }
4365bc3cb74SMauro Carvalho Chehab 
v4l_print_buffer(const void * arg,bool write_only)4375bc3cb74SMauro Carvalho Chehab static void v4l_print_buffer(const void *arg, bool write_only)
4385bc3cb74SMauro Carvalho Chehab {
4395bc3cb74SMauro Carvalho Chehab 	const struct v4l2_buffer *p = arg;
4405bc3cb74SMauro Carvalho Chehab 	const struct v4l2_timecode *tc = &p->timecode;
4415bc3cb74SMauro Carvalho Chehab 	const struct v4l2_plane *plane;
4425bc3cb74SMauro Carvalho Chehab 	int i;
4435bc3cb74SMauro Carvalho Chehab 
44448e15418SHans Verkuil 	pr_cont("%02d:%02d:%02d.%06ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
445577c89b0SArnd Bergmann 			(int)p->timestamp.tv_sec / 3600,
446577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec / 60) % 60,
447577c89b0SArnd Bergmann 			((int)p->timestamp.tv_sec % 60),
4485bc3cb74SMauro Carvalho Chehab 			(long)p->timestamp.tv_usec,
4495bc3cb74SMauro Carvalho Chehab 			p->index,
45062fed26fSHans Verkuil 			prt_names(p->type, v4l2_type_names), p->request_fd,
4515bc3cb74SMauro Carvalho Chehab 			p->flags, prt_names(p->field, v4l2_field_names),
4525bc3cb74SMauro Carvalho Chehab 			p->sequence, prt_names(p->memory, v4l2_memory_names));
4535bc3cb74SMauro Carvalho Chehab 
4545bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
4555bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
4565bc3cb74SMauro Carvalho Chehab 		for (i = 0; i < p->length; ++i) {
4575bc3cb74SMauro Carvalho Chehab 			plane = &p->m.planes[i];
4585bc3cb74SMauro Carvalho Chehab 			printk(KERN_DEBUG
4598720427cSMauro Carvalho Chehab 				"plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n",
4605bc3cb74SMauro Carvalho Chehab 				i, plane->bytesused, plane->data_offset,
4615bc3cb74SMauro Carvalho Chehab 				plane->m.userptr, plane->length);
4625bc3cb74SMauro Carvalho Chehab 		}
4635bc3cb74SMauro Carvalho Chehab 	} else {
464560dde24SHans Verkuil 		pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
4655bc3cb74SMauro Carvalho Chehab 			p->bytesused, p->m.userptr, p->length);
4665bc3cb74SMauro Carvalho Chehab 	}
4675bc3cb74SMauro Carvalho Chehab 
4688720427cSMauro Carvalho Chehab 	printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n",
4695bc3cb74SMauro Carvalho Chehab 			tc->hours, tc->minutes, tc->seconds,
4705bc3cb74SMauro Carvalho Chehab 			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
4715bc3cb74SMauro Carvalho Chehab }
4725bc3cb74SMauro Carvalho Chehab 
v4l_print_exportbuffer(const void * arg,bool write_only)473b799d09aSTomasz Stanislawski static void v4l_print_exportbuffer(const void *arg, bool write_only)
474b799d09aSTomasz Stanislawski {
475b799d09aSTomasz Stanislawski 	const struct v4l2_exportbuffer *p = arg;
476b799d09aSTomasz Stanislawski 
477b799d09aSTomasz Stanislawski 	pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
478b799d09aSTomasz Stanislawski 		p->fd, prt_names(p->type, v4l2_type_names),
479b799d09aSTomasz Stanislawski 		p->index, p->plane, p->flags);
480b799d09aSTomasz Stanislawski }
481b799d09aSTomasz Stanislawski 
v4l_print_create_buffers(const void * arg,bool write_only)4825bc3cb74SMauro Carvalho Chehab static void v4l_print_create_buffers(const void *arg, bool write_only)
4835bc3cb74SMauro Carvalho Chehab {
4845bc3cb74SMauro Carvalho Chehab 	const struct v4l2_create_buffers *p = arg;
4855bc3cb74SMauro Carvalho Chehab 
486319c4bd4SHelen Koike 	pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, ",
487319c4bd4SHelen Koike 		p->index, p->count, prt_names(p->memory, v4l2_memory_names),
488319c4bd4SHelen Koike 		p->capabilities);
4895bc3cb74SMauro Carvalho Chehab 	v4l_print_format(&p->format, write_only);
4905bc3cb74SMauro Carvalho Chehab }
4915bc3cb74SMauro Carvalho Chehab 
v4l_print_streamparm(const void * arg,bool write_only)4925bc3cb74SMauro Carvalho Chehab static void v4l_print_streamparm(const void *arg, bool write_only)
4935bc3cb74SMauro Carvalho Chehab {
4945bc3cb74SMauro Carvalho Chehab 	const struct v4l2_streamparm *p = arg;
4955bc3cb74SMauro Carvalho Chehab 
4965bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
4975bc3cb74SMauro Carvalho Chehab 
4985bc3cb74SMauro Carvalho Chehab 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4995bc3cb74SMauro Carvalho Chehab 	    p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
5005bc3cb74SMauro Carvalho Chehab 		const struct v4l2_captureparm *c = &p->parm.capture;
5015bc3cb74SMauro Carvalho Chehab 
5028720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n",
5035bc3cb74SMauro Carvalho Chehab 			c->capability, c->capturemode,
5045bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5055bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->readbuffers);
5065bc3cb74SMauro Carvalho Chehab 	} else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
5075bc3cb74SMauro Carvalho Chehab 		   p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
5085bc3cb74SMauro Carvalho Chehab 		const struct v4l2_outputparm *c = &p->parm.output;
5095bc3cb74SMauro Carvalho Chehab 
5108720427cSMauro Carvalho Chehab 		pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n",
5115bc3cb74SMauro Carvalho Chehab 			c->capability, c->outputmode,
5125bc3cb74SMauro Carvalho Chehab 			c->timeperframe.numerator, c->timeperframe.denominator,
5135bc3cb74SMauro Carvalho Chehab 			c->extendedmode, c->writebuffers);
514560dde24SHans Verkuil 	} else {
515560dde24SHans Verkuil 		pr_cont("\n");
5165bc3cb74SMauro Carvalho Chehab 	}
5175bc3cb74SMauro Carvalho Chehab }
5185bc3cb74SMauro Carvalho Chehab 
v4l_print_queryctrl(const void * arg,bool write_only)5195bc3cb74SMauro Carvalho Chehab static void v4l_print_queryctrl(const void *arg, bool write_only)
5205bc3cb74SMauro Carvalho Chehab {
5215bc3cb74SMauro Carvalho Chehab 	const struct v4l2_queryctrl *p = arg;
5225bc3cb74SMauro Carvalho Chehab 
5238720427cSMauro Carvalho Chehab 	pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n",
52427d5a87cSHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
5255bc3cb74SMauro Carvalho Chehab 			p->minimum, p->maximum,
5265bc3cb74SMauro Carvalho Chehab 			p->step, p->default_value, p->flags);
5275bc3cb74SMauro Carvalho Chehab }
5285bc3cb74SMauro Carvalho Chehab 
v4l_print_query_ext_ctrl(const void * arg,bool write_only)529e6bee368SHans Verkuil static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
530e6bee368SHans Verkuil {
531e6bee368SHans Verkuil 	const struct v4l2_query_ext_ctrl *p = arg;
532e6bee368SHans Verkuil 
5338720427cSMauro 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",
534e6bee368SHans Verkuil 			p->id, p->type, (int)sizeof(p->name), p->name,
535e6bee368SHans Verkuil 			p->minimum, p->maximum,
536e6bee368SHans Verkuil 			p->step, p->default_value, p->flags,
537e6bee368SHans Verkuil 			p->elem_size, p->elems, p->nr_of_dims,
5380176077aSHans Verkuil 			p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
539e6bee368SHans Verkuil }
540e6bee368SHans Verkuil 
v4l_print_querymenu(const void * arg,bool write_only)5415bc3cb74SMauro Carvalho Chehab static void v4l_print_querymenu(const void *arg, bool write_only)
5425bc3cb74SMauro Carvalho Chehab {
5435bc3cb74SMauro Carvalho Chehab 	const struct v4l2_querymenu *p = arg;
5445bc3cb74SMauro Carvalho Chehab 
5455bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, index=%d\n", p->id, p->index);
5465bc3cb74SMauro Carvalho Chehab }
5475bc3cb74SMauro Carvalho Chehab 
v4l_print_control(const void * arg,bool write_only)5485bc3cb74SMauro Carvalho Chehab static void v4l_print_control(const void *arg, bool write_only)
5495bc3cb74SMauro Carvalho Chehab {
5505bc3cb74SMauro Carvalho Chehab 	const struct v4l2_control *p = arg;
551a69a7a33SEzequiel Garcia 	const char *name = v4l2_ctrl_get_name(p->id);
5525bc3cb74SMauro Carvalho Chehab 
553a69a7a33SEzequiel Garcia 	if (name)
554a69a7a33SEzequiel Garcia 		pr_cont("name=%s, ", name);
5555bc3cb74SMauro Carvalho Chehab 	pr_cont("id=0x%x, value=%d\n", p->id, p->value);
5565bc3cb74SMauro Carvalho Chehab }
5575bc3cb74SMauro Carvalho Chehab 
v4l_print_ext_controls(const void * arg,bool write_only)5585bc3cb74SMauro Carvalho Chehab static void v4l_print_ext_controls(const void *arg, bool write_only)
5595bc3cb74SMauro Carvalho Chehab {
5605bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ext_controls *p = arg;
5615bc3cb74SMauro Carvalho Chehab 	int i;
5625bc3cb74SMauro Carvalho Chehab 
563f23317adSAlexandre Courbot 	pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
564f23317adSAlexandre Courbot 			p->which, p->count, p->error_idx, p->request_fd);
5655bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < p->count; i++) {
566a69a7a33SEzequiel Garcia 		unsigned int id = p->controls[i].id;
567a69a7a33SEzequiel Garcia 		const char *name = v4l2_ctrl_get_name(id);
568a69a7a33SEzequiel Garcia 
569a69a7a33SEzequiel Garcia 		if (name)
570a69a7a33SEzequiel Garcia 			pr_cont(", name=%s", name);
571017ab36aSHans Verkuil 		if (!p->controls[i].size)
572a69a7a33SEzequiel Garcia 			pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
5735bc3cb74SMauro Carvalho Chehab 		else
574a69a7a33SEzequiel Garcia 			pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
5755bc3cb74SMauro Carvalho Chehab 	}
5765bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
5775bc3cb74SMauro Carvalho Chehab }
5785bc3cb74SMauro Carvalho Chehab 
v4l_print_cropcap(const void * arg,bool write_only)5795bc3cb74SMauro Carvalho Chehab static void v4l_print_cropcap(const void *arg, bool write_only)
5805bc3cb74SMauro Carvalho Chehab {
5815bc3cb74SMauro Carvalho Chehab 	const struct v4l2_cropcap *p = arg;
5825bc3cb74SMauro Carvalho Chehab 
5838720427cSMauro 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",
5845bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5855bc3cb74SMauro Carvalho Chehab 		p->bounds.width, p->bounds.height,
5865bc3cb74SMauro Carvalho Chehab 		p->bounds.left, p->bounds.top,
5875bc3cb74SMauro Carvalho Chehab 		p->defrect.width, p->defrect.height,
5885bc3cb74SMauro Carvalho Chehab 		p->defrect.left, p->defrect.top,
5895bc3cb74SMauro Carvalho Chehab 		p->pixelaspect.numerator, p->pixelaspect.denominator);
5905bc3cb74SMauro Carvalho Chehab }
5915bc3cb74SMauro Carvalho Chehab 
v4l_print_crop(const void * arg,bool write_only)5925bc3cb74SMauro Carvalho Chehab static void v4l_print_crop(const void *arg, bool write_only)
5935bc3cb74SMauro Carvalho Chehab {
5945bc3cb74SMauro Carvalho Chehab 	const struct v4l2_crop *p = arg;
5955bc3cb74SMauro Carvalho Chehab 
5965bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
5975bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
5985bc3cb74SMauro Carvalho Chehab 		p->c.width, p->c.height,
5995bc3cb74SMauro Carvalho Chehab 		p->c.left, p->c.top);
6005bc3cb74SMauro Carvalho Chehab }
6015bc3cb74SMauro Carvalho Chehab 
v4l_print_selection(const void * arg,bool write_only)6025bc3cb74SMauro Carvalho Chehab static void v4l_print_selection(const void *arg, bool write_only)
6035bc3cb74SMauro Carvalho Chehab {
6045bc3cb74SMauro Carvalho Chehab 	const struct v4l2_selection *p = arg;
6055bc3cb74SMauro Carvalho Chehab 
6065bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
6075bc3cb74SMauro Carvalho Chehab 		prt_names(p->type, v4l2_type_names),
6085bc3cb74SMauro Carvalho Chehab 		p->target, p->flags,
6095bc3cb74SMauro Carvalho Chehab 		p->r.width, p->r.height, p->r.left, p->r.top);
6105bc3cb74SMauro Carvalho Chehab }
6115bc3cb74SMauro Carvalho Chehab 
v4l_print_jpegcompression(const void * arg,bool write_only)6125bc3cb74SMauro Carvalho Chehab static void v4l_print_jpegcompression(const void *arg, bool write_only)
6135bc3cb74SMauro Carvalho Chehab {
6145bc3cb74SMauro Carvalho Chehab 	const struct v4l2_jpegcompression *p = arg;
6155bc3cb74SMauro Carvalho Chehab 
6168720427cSMauro Carvalho Chehab 	pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n",
6175bc3cb74SMauro Carvalho Chehab 		p->quality, p->APPn, p->APP_len,
6185bc3cb74SMauro Carvalho Chehab 		p->COM_len, p->jpeg_markers);
6195bc3cb74SMauro Carvalho Chehab }
6205bc3cb74SMauro Carvalho Chehab 
v4l_print_enc_idx(const void * arg,bool write_only)6215bc3cb74SMauro Carvalho Chehab static void v4l_print_enc_idx(const void *arg, bool write_only)
6225bc3cb74SMauro Carvalho Chehab {
6235bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enc_idx *p = arg;
6245bc3cb74SMauro Carvalho Chehab 
6255bc3cb74SMauro Carvalho Chehab 	pr_cont("entries=%d, entries_cap=%d\n",
6265bc3cb74SMauro Carvalho Chehab 			p->entries, p->entries_cap);
6275bc3cb74SMauro Carvalho Chehab }
6285bc3cb74SMauro Carvalho Chehab 
v4l_print_encoder_cmd(const void * arg,bool write_only)6295bc3cb74SMauro Carvalho Chehab static void v4l_print_encoder_cmd(const void *arg, bool write_only)
6305bc3cb74SMauro Carvalho Chehab {
6315bc3cb74SMauro Carvalho Chehab 	const struct v4l2_encoder_cmd *p = arg;
6325bc3cb74SMauro Carvalho Chehab 
6335bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n",
6345bc3cb74SMauro Carvalho Chehab 			p->cmd, p->flags);
6355bc3cb74SMauro Carvalho Chehab }
6365bc3cb74SMauro Carvalho Chehab 
v4l_print_decoder_cmd(const void * arg,bool write_only)6375bc3cb74SMauro Carvalho Chehab static void v4l_print_decoder_cmd(const void *arg, bool write_only)
6385bc3cb74SMauro Carvalho Chehab {
6395bc3cb74SMauro Carvalho Chehab 	const struct v4l2_decoder_cmd *p = arg;
6405bc3cb74SMauro Carvalho Chehab 
6415bc3cb74SMauro Carvalho Chehab 	pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
6425bc3cb74SMauro Carvalho Chehab 
6435bc3cb74SMauro Carvalho Chehab 	if (p->cmd == V4L2_DEC_CMD_START)
6445bc3cb74SMauro Carvalho Chehab 		pr_info("speed=%d, format=%u\n",
6455bc3cb74SMauro Carvalho Chehab 				p->start.speed, p->start.format);
6465bc3cb74SMauro Carvalho Chehab 	else if (p->cmd == V4L2_DEC_CMD_STOP)
6475bc3cb74SMauro Carvalho Chehab 		pr_info("pts=%llu\n", p->stop.pts);
6485bc3cb74SMauro Carvalho Chehab }
6495bc3cb74SMauro Carvalho Chehab 
v4l_print_dbg_chip_info(const void * arg,bool write_only)65096b03d2aSHans Verkuil static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
65179b0c640SHans Verkuil {
65296b03d2aSHans Verkuil 	const struct v4l2_dbg_chip_info *p = arg;
65379b0c640SHans Verkuil 
65479b0c640SHans Verkuil 	pr_cont("type=%u, ", p->match.type);
6553eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
65679b0c640SHans Verkuil 		pr_cont("name=%.*s, ",
65779b0c640SHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
65879b0c640SHans Verkuil 	else
65979b0c640SHans Verkuil 		pr_cont("addr=%u, ", p->match.addr);
66079b0c640SHans Verkuil 	pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
66179b0c640SHans Verkuil }
66279b0c640SHans Verkuil 
v4l_print_dbg_register(const void * arg,bool write_only)6635bc3cb74SMauro Carvalho Chehab static void v4l_print_dbg_register(const void *arg, bool write_only)
6645bc3cb74SMauro Carvalho Chehab {
6655bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dbg_register *p = arg;
6665bc3cb74SMauro Carvalho Chehab 
6675bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%u, ", p->match.type);
6683eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
66927d5a87cSHans Verkuil 		pr_cont("name=%.*s, ",
67027d5a87cSHans Verkuil 				(int)sizeof(p->match.name), p->match.name);
6715bc3cb74SMauro Carvalho Chehab 	else
6725bc3cb74SMauro Carvalho Chehab 		pr_cont("addr=%u, ", p->match.addr);
6735bc3cb74SMauro Carvalho Chehab 	pr_cont("reg=0x%llx, val=0x%llx\n",
6745bc3cb74SMauro Carvalho Chehab 			p->reg, p->val);
6755bc3cb74SMauro Carvalho Chehab }
6765bc3cb74SMauro Carvalho Chehab 
v4l_print_dv_timings(const void * arg,bool write_only)6775bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings(const void *arg, bool write_only)
6785bc3cb74SMauro Carvalho Chehab {
6795bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings *p = arg;
6805bc3cb74SMauro Carvalho Chehab 
6815bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
6825bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
6838720427cSMauro 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",
6845bc3cb74SMauro Carvalho Chehab 				p->bt.interlaced, p->bt.pixelclock,
6855bc3cb74SMauro Carvalho Chehab 				p->bt.width, p->bt.height,
6865bc3cb74SMauro Carvalho Chehab 				p->bt.polarities, p->bt.hfrontporch,
6875bc3cb74SMauro Carvalho Chehab 				p->bt.hsync, p->bt.hbackporch,
6885bc3cb74SMauro Carvalho Chehab 				p->bt.vfrontporch, p->bt.vsync,
6895bc3cb74SMauro Carvalho Chehab 				p->bt.vbackporch, p->bt.il_vfrontporch,
6905bc3cb74SMauro Carvalho Chehab 				p->bt.il_vsync, p->bt.il_vbackporch,
6915bc3cb74SMauro Carvalho Chehab 				p->bt.standards, p->bt.flags);
6925bc3cb74SMauro Carvalho Chehab 		break;
6935bc3cb74SMauro Carvalho Chehab 	default:
6945bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%d\n", p->type);
6955bc3cb74SMauro Carvalho Chehab 		break;
6965bc3cb74SMauro Carvalho Chehab 	}
6975bc3cb74SMauro Carvalho Chehab }
6985bc3cb74SMauro Carvalho Chehab 
v4l_print_enum_dv_timings(const void * arg,bool write_only)6995bc3cb74SMauro Carvalho Chehab static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
7005bc3cb74SMauro Carvalho Chehab {
7015bc3cb74SMauro Carvalho Chehab 	const struct v4l2_enum_dv_timings *p = arg;
7025bc3cb74SMauro Carvalho Chehab 
7035bc3cb74SMauro Carvalho Chehab 	pr_cont("index=%u, ", p->index);
7045bc3cb74SMauro Carvalho Chehab 	v4l_print_dv_timings(&p->timings, write_only);
7055bc3cb74SMauro Carvalho Chehab }
7065bc3cb74SMauro Carvalho Chehab 
v4l_print_dv_timings_cap(const void * arg,bool write_only)7075bc3cb74SMauro Carvalho Chehab static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
7085bc3cb74SMauro Carvalho Chehab {
7095bc3cb74SMauro Carvalho Chehab 	const struct v4l2_dv_timings_cap *p = arg;
7105bc3cb74SMauro Carvalho Chehab 
7115bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7125bc3cb74SMauro Carvalho Chehab 	case V4L2_DV_BT_656_1120:
7138720427cSMauro Carvalho Chehab 		pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
7145bc3cb74SMauro Carvalho Chehab 			p->bt.min_width, p->bt.max_width,
7155bc3cb74SMauro Carvalho Chehab 			p->bt.min_height, p->bt.max_height,
7165bc3cb74SMauro Carvalho Chehab 			p->bt.min_pixelclock, p->bt.max_pixelclock,
7175bc3cb74SMauro Carvalho Chehab 			p->bt.standards, p->bt.capabilities);
7185bc3cb74SMauro Carvalho Chehab 		break;
7195bc3cb74SMauro Carvalho Chehab 	default:
7205bc3cb74SMauro Carvalho Chehab 		pr_cont("type=%u\n", p->type);
7215bc3cb74SMauro Carvalho Chehab 		break;
7225bc3cb74SMauro Carvalho Chehab 	}
7235bc3cb74SMauro Carvalho Chehab }
7245bc3cb74SMauro Carvalho Chehab 
v4l_print_frmsizeenum(const void * arg,bool write_only)7255bc3cb74SMauro Carvalho Chehab static void v4l_print_frmsizeenum(const void *arg, bool write_only)
7265bc3cb74SMauro Carvalho Chehab {
7275bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmsizeenum *p = arg;
7285bc3cb74SMauro Carvalho Chehab 
729e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, type=%u",
730e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->type);
7315bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7325bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_DISCRETE:
733560dde24SHans Verkuil 		pr_cont(", wxh=%ux%u\n",
7345bc3cb74SMauro Carvalho Chehab 			p->discrete.width, p->discrete.height);
7355bc3cb74SMauro Carvalho Chehab 		break;
7365bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_STEPWISE:
737560dde24SHans Verkuil 		pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
7382489477eSRicardo Ribalda 				p->stepwise.min_width,
7392489477eSRicardo Ribalda 				p->stepwise.min_height,
7402489477eSRicardo Ribalda 				p->stepwise.max_width,
7412489477eSRicardo Ribalda 				p->stepwise.max_height,
7422489477eSRicardo Ribalda 				p->stepwise.step_width,
7432489477eSRicardo Ribalda 				p->stepwise.step_height);
7445bc3cb74SMauro Carvalho Chehab 		break;
7455bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMSIZE_TYPE_CONTINUOUS:
7465bc3cb74SMauro Carvalho Chehab 	default:
7475bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7485bc3cb74SMauro Carvalho Chehab 		break;
7495bc3cb74SMauro Carvalho Chehab 	}
7505bc3cb74SMauro Carvalho Chehab }
7515bc3cb74SMauro Carvalho Chehab 
v4l_print_frmivalenum(const void * arg,bool write_only)7525bc3cb74SMauro Carvalho Chehab static void v4l_print_frmivalenum(const void *arg, bool write_only)
7535bc3cb74SMauro Carvalho Chehab {
7545bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frmivalenum *p = arg;
7555bc3cb74SMauro Carvalho Chehab 
756e927e1e0SSakari Ailus 	pr_cont("index=%u, pixelformat=%p4cc, wxh=%ux%u, type=%u",
757e927e1e0SSakari Ailus 		p->index, &p->pixel_format, p->width, p->height, p->type);
7585bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7595bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_DISCRETE:
760560dde24SHans Verkuil 		pr_cont(", fps=%d/%d\n",
7615bc3cb74SMauro Carvalho Chehab 				p->discrete.numerator,
7625bc3cb74SMauro Carvalho Chehab 				p->discrete.denominator);
7635bc3cb74SMauro Carvalho Chehab 		break;
7645bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_STEPWISE:
765560dde24SHans Verkuil 		pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
7665bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.numerator,
7675bc3cb74SMauro Carvalho Chehab 				p->stepwise.min.denominator,
7685bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.numerator,
7695bc3cb74SMauro Carvalho Chehab 				p->stepwise.max.denominator,
7705bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.numerator,
7715bc3cb74SMauro Carvalho Chehab 				p->stepwise.step.denominator);
7725bc3cb74SMauro Carvalho Chehab 		break;
7735bc3cb74SMauro Carvalho Chehab 	case V4L2_FRMIVAL_TYPE_CONTINUOUS:
7745bc3cb74SMauro Carvalho Chehab 	default:
7755bc3cb74SMauro Carvalho Chehab 		pr_cont("\n");
7765bc3cb74SMauro Carvalho Chehab 		break;
7775bc3cb74SMauro Carvalho Chehab 	}
7785bc3cb74SMauro Carvalho Chehab }
7795bc3cb74SMauro Carvalho Chehab 
v4l_print_event(const void * arg,bool write_only)7805bc3cb74SMauro Carvalho Chehab static void v4l_print_event(const void *arg, bool write_only)
7815bc3cb74SMauro Carvalho Chehab {
7825bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event *p = arg;
7835bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_ctrl *c;
7845bc3cb74SMauro Carvalho Chehab 
7851a6c0b36SArnd Bergmann 	pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
7865bc3cb74SMauro Carvalho Chehab 			p->type, p->pending, p->sequence, p->id,
7875bc3cb74SMauro Carvalho Chehab 			p->timestamp.tv_sec, p->timestamp.tv_nsec);
7885bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
7895bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_VSYNC:
7905bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "field=%s\n",
7915bc3cb74SMauro Carvalho Chehab 			prt_names(p->u.vsync.field, v4l2_field_names));
7925bc3cb74SMauro Carvalho Chehab 		break;
7935bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_CTRL:
7945bc3cb74SMauro Carvalho Chehab 		c = &p->u.ctrl;
7955bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "changes=0x%x, type=%u, ",
7965bc3cb74SMauro Carvalho Chehab 			c->changes, c->type);
7975bc3cb74SMauro Carvalho Chehab 		if (c->type == V4L2_CTRL_TYPE_INTEGER64)
7985bc3cb74SMauro Carvalho Chehab 			pr_cont("value64=%lld, ", c->value64);
7995bc3cb74SMauro Carvalho Chehab 		else
8005bc3cb74SMauro Carvalho Chehab 			pr_cont("value=%d, ", c->value);
8018720427cSMauro Carvalho Chehab 		pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n",
8025bc3cb74SMauro Carvalho Chehab 			c->flags, c->minimum, c->maximum,
8035bc3cb74SMauro Carvalho Chehab 			c->step, c->default_value);
8045bc3cb74SMauro Carvalho Chehab 		break;
8055bc3cb74SMauro Carvalho Chehab 	case V4L2_EVENT_FRAME_SYNC:
8065bc3cb74SMauro Carvalho Chehab 		pr_cont("frame_sequence=%u\n",
8075bc3cb74SMauro Carvalho Chehab 			p->u.frame_sync.frame_sequence);
8085bc3cb74SMauro Carvalho Chehab 		break;
8095bc3cb74SMauro Carvalho Chehab 	}
8105bc3cb74SMauro Carvalho Chehab }
8115bc3cb74SMauro Carvalho Chehab 
v4l_print_event_subscription(const void * arg,bool write_only)8125bc3cb74SMauro Carvalho Chehab static void v4l_print_event_subscription(const void *arg, bool write_only)
8135bc3cb74SMauro Carvalho Chehab {
8145bc3cb74SMauro Carvalho Chehab 	const struct v4l2_event_subscription *p = arg;
8155bc3cb74SMauro Carvalho Chehab 
8165bc3cb74SMauro Carvalho Chehab 	pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
8175bc3cb74SMauro Carvalho Chehab 			p->type, p->id, p->flags);
8185bc3cb74SMauro Carvalho Chehab }
8195bc3cb74SMauro Carvalho Chehab 
v4l_print_sliced_vbi_cap(const void * arg,bool write_only)8205bc3cb74SMauro Carvalho Chehab static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
8215bc3cb74SMauro Carvalho Chehab {
8225bc3cb74SMauro Carvalho Chehab 	const struct v4l2_sliced_vbi_cap *p = arg;
8235bc3cb74SMauro Carvalho Chehab 	int i;
8245bc3cb74SMauro Carvalho Chehab 
8255bc3cb74SMauro Carvalho Chehab 	pr_cont("type=%s, service_set=0x%08x\n",
8265bc3cb74SMauro Carvalho Chehab 			prt_names(p->type, v4l2_type_names), p->service_set);
8275bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < 24; i++)
8285bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
8295bc3cb74SMauro Carvalho Chehab 				p->service_lines[0][i],
8305bc3cb74SMauro Carvalho Chehab 				p->service_lines[1][i]);
8315bc3cb74SMauro Carvalho Chehab }
8325bc3cb74SMauro Carvalho Chehab 
v4l_print_freq_band(const void * arg,bool write_only)8335bc3cb74SMauro Carvalho Chehab static void v4l_print_freq_band(const void *arg, bool write_only)
8345bc3cb74SMauro Carvalho Chehab {
8355bc3cb74SMauro Carvalho Chehab 	const struct v4l2_frequency_band *p = arg;
8365bc3cb74SMauro Carvalho Chehab 
8378720427cSMauro Carvalho Chehab 	pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n",
8385bc3cb74SMauro Carvalho Chehab 			p->tuner, p->type, p->index,
8395bc3cb74SMauro Carvalho Chehab 			p->capability, p->rangelow,
8405bc3cb74SMauro Carvalho Chehab 			p->rangehigh, p->modulation);
8415bc3cb74SMauro Carvalho Chehab }
8425bc3cb74SMauro Carvalho Chehab 
v4l_print_edid(const void * arg,bool write_only)843dd519bb3SHans Verkuil static void v4l_print_edid(const void *arg, bool write_only)
844dd519bb3SHans Verkuil {
845dd519bb3SHans Verkuil 	const struct v4l2_edid *p = arg;
846dd519bb3SHans Verkuil 
847dd519bb3SHans Verkuil 	pr_cont("pad=%u, start_block=%u, blocks=%u\n",
848dd519bb3SHans Verkuil 		p->pad, p->start_block, p->blocks);
849dd519bb3SHans Verkuil }
850dd519bb3SHans Verkuil 
v4l_print_u32(const void * arg,bool write_only)8515bc3cb74SMauro Carvalho Chehab static void v4l_print_u32(const void *arg, bool write_only)
8525bc3cb74SMauro Carvalho Chehab {
8535bc3cb74SMauro Carvalho Chehab 	pr_cont("value=%u\n", *(const u32 *)arg);
8545bc3cb74SMauro Carvalho Chehab }
8555bc3cb74SMauro Carvalho Chehab 
v4l_print_newline(const void * arg,bool write_only)8565bc3cb74SMauro Carvalho Chehab static void v4l_print_newline(const void *arg, bool write_only)
8575bc3cb74SMauro Carvalho Chehab {
8585bc3cb74SMauro Carvalho Chehab 	pr_cont("\n");
8595bc3cb74SMauro Carvalho Chehab }
8605bc3cb74SMauro Carvalho Chehab 
v4l_print_default(const void * arg,bool write_only)8615bc3cb74SMauro Carvalho Chehab static void v4l_print_default(const void *arg, bool write_only)
8625bc3cb74SMauro Carvalho Chehab {
8635bc3cb74SMauro Carvalho Chehab 	pr_cont("driver-specific ioctl\n");
8645bc3cb74SMauro Carvalho Chehab }
8655bc3cb74SMauro Carvalho Chehab 
check_ext_ctrls(struct v4l2_ext_controls * c,unsigned long ioctl)866861f92cbSRicardo Ribalda static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl)
8675bc3cb74SMauro Carvalho Chehab {
8685bc3cb74SMauro Carvalho Chehab 	__u32 i;
8695bc3cb74SMauro Carvalho Chehab 
8705bc3cb74SMauro Carvalho Chehab 	/* zero the reserved fields */
871f23317adSAlexandre Courbot 	c->reserved[0] = 0;
8725bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++)
8735bc3cb74SMauro Carvalho Chehab 		c->controls[i].reserved2[0] = 0;
8745bc3cb74SMauro Carvalho Chehab 
875861f92cbSRicardo Ribalda 	switch (c->which) {
876861f92cbSRicardo Ribalda 	case V4L2_CID_PRIVATE_BASE:
877861f92cbSRicardo Ribalda 		/*
878861f92cbSRicardo Ribalda 		 * V4L2_CID_PRIVATE_BASE cannot be used as control class
879861f92cbSRicardo Ribalda 		 * when using extended controls.
880861f92cbSRicardo Ribalda 		 * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
881861f92cbSRicardo Ribalda 		 * is it allowed for backwards compatibility.
8825bc3cb74SMauro Carvalho Chehab 		 */
883861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL)
884861f92cbSRicardo Ribalda 			return false;
885861f92cbSRicardo Ribalda 		break;
886861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_DEF_VAL:
887861f92cbSRicardo Ribalda 		/* Default value cannot be changed */
888861f92cbSRicardo Ribalda 		if (ioctl == VIDIOC_S_EXT_CTRLS ||
889861f92cbSRicardo Ribalda 		    ioctl == VIDIOC_TRY_EXT_CTRLS) {
890861f92cbSRicardo Ribalda 			c->error_idx = c->count;
891861f92cbSRicardo Ribalda 			return false;
892861f92cbSRicardo Ribalda 		}
893861f92cbSRicardo Ribalda 		return true;
894861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_CUR_VAL:
895861f92cbSRicardo Ribalda 		return true;
896861f92cbSRicardo Ribalda 	case V4L2_CTRL_WHICH_REQUEST_VAL:
897861f92cbSRicardo Ribalda 		c->error_idx = c->count;
898861f92cbSRicardo Ribalda 		return false;
899861f92cbSRicardo Ribalda 	}
900861f92cbSRicardo Ribalda 
9015bc3cb74SMauro Carvalho Chehab 	/* Check that all controls are from the same control class. */
9025bc3cb74SMauro Carvalho Chehab 	for (i = 0; i < c->count; i++) {
9030f8017beSRicardo Ribalda 		if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) {
904861f92cbSRicardo Ribalda 			c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i :
905861f92cbSRicardo Ribalda 								      c->count;
906861f92cbSRicardo Ribalda 			return false;
9075bc3cb74SMauro Carvalho Chehab 		}
9085bc3cb74SMauro Carvalho Chehab 	}
909861f92cbSRicardo Ribalda 	return true;
9105bc3cb74SMauro Carvalho Chehab }
9115bc3cb74SMauro Carvalho Chehab 
check_fmt(struct file * file,enum v4l2_buf_type type)9124b20259fSHans Verkuil static int check_fmt(struct file *file, enum v4l2_buf_type type)
9135bc3cb74SMauro Carvalho Chehab {
91496f49c1aSVandana BN 	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
91596f49c1aSVandana BN 			     V4L2_CAP_VIDEO_CAPTURE_MPLANE |
91696f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT |
91796f49c1aSVandana BN 			     V4L2_CAP_VIDEO_OUTPUT_MPLANE |
91896f49c1aSVandana BN 			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
91996f49c1aSVandana BN 	const u32 meta_caps = V4L2_CAP_META_CAPTURE |
92096f49c1aSVandana BN 			      V4L2_CAP_META_OUTPUT;
9214b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
9224b20259fSHans Verkuil 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
923238e4a5bSHans Verkuil 	bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
92496f49c1aSVandana BN 		      (vfd->device_caps & vid_caps);
9254b20259fSHans Verkuil 	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
926582c52cbSAntti Palosaari 	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
927b2fe22d0SNick Dyer 	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
928238e4a5bSHans Verkuil 	bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
92996f49c1aSVandana BN 		       (vfd->device_caps & meta_caps);
9304b20259fSHans Verkuil 	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
9314b20259fSHans Verkuil 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
9324b20259fSHans Verkuil 
9335bc3cb74SMauro Carvalho Chehab 	if (ops == NULL)
9345bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
9355bc3cb74SMauro Carvalho Chehab 
9365bc3cb74SMauro Carvalho Chehab 	switch (type) {
9375bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
938b2fe22d0SNick Dyer 		if ((is_vid || is_tch) && is_rx &&
9394b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
9405bc3cb74SMauro Carvalho Chehab 			return 0;
9415bc3cb74SMauro Carvalho Chehab 		break;
9425bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
943095c21d3SHans Verkuil 		if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
9445bc3cb74SMauro Carvalho Chehab 			return 0;
9455bc3cb74SMauro Carvalho Chehab 		break;
9465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
9474b20259fSHans Verkuil 		if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
9485bc3cb74SMauro Carvalho Chehab 			return 0;
9495bc3cb74SMauro Carvalho Chehab 		break;
9505bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
9514b20259fSHans Verkuil 		if (is_vid && is_tx &&
9524b20259fSHans Verkuil 		    (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
9535bc3cb74SMauro Carvalho Chehab 			return 0;
9545bc3cb74SMauro Carvalho Chehab 		break;
9555bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9564b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
9575bc3cb74SMauro Carvalho Chehab 			return 0;
9585bc3cb74SMauro Carvalho Chehab 		break;
9595bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9604b20259fSHans Verkuil 		if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
9615bc3cb74SMauro Carvalho Chehab 			return 0;
9625bc3cb74SMauro Carvalho Chehab 		break;
9635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_CAPTURE:
9644b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
9655bc3cb74SMauro Carvalho Chehab 			return 0;
9665bc3cb74SMauro Carvalho Chehab 		break;
9675bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
9684b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
9695bc3cb74SMauro Carvalho Chehab 			return 0;
9705bc3cb74SMauro Carvalho Chehab 		break;
9715bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9724b20259fSHans Verkuil 		if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
9735bc3cb74SMauro Carvalho Chehab 			return 0;
9745bc3cb74SMauro Carvalho Chehab 		break;
9755bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9764b20259fSHans Verkuil 		if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
9775bc3cb74SMauro Carvalho Chehab 			return 0;
9785bc3cb74SMauro Carvalho Chehab 		break;
979582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
980582c52cbSAntti Palosaari 		if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
981582c52cbSAntti Palosaari 			return 0;
982582c52cbSAntti Palosaari 		break;
9839effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
9849effc72fSAntti Palosaari 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
9859effc72fSAntti Palosaari 			return 0;
9869effc72fSAntti Palosaari 		break;
987fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
98896f49c1aSVandana BN 		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
989fb9ffa6aSLaurent Pinchart 			return 0;
990fb9ffa6aSLaurent Pinchart 		break;
99172148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
99296f49c1aSVandana BN 		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
99372148d1aSSakari Ailus 			return 0;
99472148d1aSSakari Ailus 		break;
995633c98e5SHans Verkuil 	default:
9965bc3cb74SMauro Carvalho Chehab 		break;
9975bc3cb74SMauro Carvalho Chehab 	}
9985bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
9995bc3cb74SMauro Carvalho Chehab }
10005bc3cb74SMauro Carvalho Chehab 
v4l_sanitize_colorspace(u32 pixelformat,u32 * colorspace,u32 * encoding,u32 * quantization,u32 * xfer_func)100148e93b0cSLaurent Pinchart static void v4l_sanitize_colorspace(u32 pixelformat, u32 *colorspace,
100248e93b0cSLaurent Pinchart 				    u32 *encoding, u32 *quantization,
100348e93b0cSLaurent Pinchart 				    u32 *xfer_func)
100448e93b0cSLaurent Pinchart {
100548e93b0cSLaurent Pinchart 	bool is_hsv = pixelformat == V4L2_PIX_FMT_HSV24 ||
100648e93b0cSLaurent Pinchart 		      pixelformat == V4L2_PIX_FMT_HSV32;
100748e93b0cSLaurent Pinchart 
100848e93b0cSLaurent Pinchart 	if (!v4l2_is_colorspace_valid(*colorspace)) {
100948e93b0cSLaurent Pinchart 		*colorspace = V4L2_COLORSPACE_DEFAULT;
101048e93b0cSLaurent Pinchart 		*encoding = V4L2_YCBCR_ENC_DEFAULT;
101148e93b0cSLaurent Pinchart 		*quantization = V4L2_QUANTIZATION_DEFAULT;
101248e93b0cSLaurent Pinchart 		*xfer_func = V4L2_XFER_FUNC_DEFAULT;
101348e93b0cSLaurent Pinchart 	}
101448e93b0cSLaurent Pinchart 
101548e93b0cSLaurent Pinchart 	if ((!is_hsv && !v4l2_is_ycbcr_enc_valid(*encoding)) ||
101648e93b0cSLaurent Pinchart 	    (is_hsv && !v4l2_is_hsv_enc_valid(*encoding)))
101748e93b0cSLaurent Pinchart 		*encoding = V4L2_YCBCR_ENC_DEFAULT;
101848e93b0cSLaurent Pinchart 
101948e93b0cSLaurent Pinchart 	if (!v4l2_is_quant_valid(*quantization))
102048e93b0cSLaurent Pinchart 		*quantization = V4L2_QUANTIZATION_DEFAULT;
102148e93b0cSLaurent Pinchart 
102248e93b0cSLaurent Pinchart 	if (!v4l2_is_xfer_func_valid(*xfer_func))
102348e93b0cSLaurent Pinchart 		*xfer_func = V4L2_XFER_FUNC_DEFAULT;
102448e93b0cSLaurent Pinchart }
102548e93b0cSLaurent Pinchart 
v4l_sanitize_format(struct v4l2_format * fmt)1026d52e2381SLaurent Pinchart static void v4l_sanitize_format(struct v4l2_format *fmt)
1027d52e2381SLaurent Pinchart {
1028d52e2381SLaurent Pinchart 	unsigned int offset;
1029d52e2381SLaurent Pinchart 
103014c8e80eSEzequiel Garcia 	/* Make sure num_planes is not bogus */
103114c8e80eSEzequiel Garcia 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
103214c8e80eSEzequiel Garcia 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
103314c8e80eSEzequiel Garcia 		fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes,
103414c8e80eSEzequiel Garcia 					       VIDEO_MAX_PLANES);
103514c8e80eSEzequiel Garcia 
1036d52e2381SLaurent Pinchart 	/*
1037d52e2381SLaurent Pinchart 	 * The v4l2_pix_format structure has been extended with fields that were
1038d52e2381SLaurent Pinchart 	 * not previously required to be set to zero by applications. The priv
1039fd3ed970SSlark Xiao 	 * field, when set to a magic value, indicates that the extended fields
1040d52e2381SLaurent Pinchart 	 * are valid. Otherwise they will contain undefined values. To simplify
1041d52e2381SLaurent Pinchart 	 * the API towards drivers zero the extended fields and set the priv
1042d52e2381SLaurent Pinchart 	 * field to the magic value when the extended pixel format structure
1043d52e2381SLaurent Pinchart 	 * isn't used by applications.
1044d52e2381SLaurent Pinchart 	 */
104548e93b0cSLaurent Pinchart 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
104648e93b0cSLaurent Pinchart 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
104748e93b0cSLaurent Pinchart 		if (fmt->fmt.pix.priv != V4L2_PIX_FMT_PRIV_MAGIC) {
1048d52e2381SLaurent Pinchart 			fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1049d52e2381SLaurent Pinchart 
1050d52e2381SLaurent Pinchart 			offset = offsetof(struct v4l2_pix_format, priv)
1051d52e2381SLaurent Pinchart 			       + sizeof(fmt->fmt.pix.priv);
1052d52e2381SLaurent Pinchart 			memset(((void *)&fmt->fmt.pix) + offset, 0,
1053d52e2381SLaurent Pinchart 			       sizeof(fmt->fmt.pix) - offset);
1054d52e2381SLaurent Pinchart 		}
105548e93b0cSLaurent Pinchart 	}
105648e93b0cSLaurent Pinchart 
105748e93b0cSLaurent Pinchart 	/* Replace invalid colorspace values with defaults. */
105848e93b0cSLaurent Pinchart 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
105948e93b0cSLaurent Pinchart 	    fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
106048e93b0cSLaurent Pinchart 		v4l_sanitize_colorspace(fmt->fmt.pix.pixelformat,
106148e93b0cSLaurent Pinchart 					&fmt->fmt.pix.colorspace,
106248e93b0cSLaurent Pinchart 					&fmt->fmt.pix.ycbcr_enc,
106348e93b0cSLaurent Pinchart 					&fmt->fmt.pix.quantization,
106448e93b0cSLaurent Pinchart 					&fmt->fmt.pix.xfer_func);
106548e93b0cSLaurent Pinchart 	} else if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
106648e93b0cSLaurent Pinchart 		   fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
106748e93b0cSLaurent Pinchart 		u32 ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
106848e93b0cSLaurent Pinchart 		u32 quantization = fmt->fmt.pix_mp.quantization;
106948e93b0cSLaurent Pinchart 		u32 xfer_func = fmt->fmt.pix_mp.xfer_func;
107048e93b0cSLaurent Pinchart 
107148e93b0cSLaurent Pinchart 		v4l_sanitize_colorspace(fmt->fmt.pix_mp.pixelformat,
107248e93b0cSLaurent Pinchart 					&fmt->fmt.pix_mp.colorspace, &ycbcr_enc,
107348e93b0cSLaurent Pinchart 					&quantization, &xfer_func);
107448e93b0cSLaurent Pinchart 
107548e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.ycbcr_enc = ycbcr_enc;
107648e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.quantization = quantization;
107748e93b0cSLaurent Pinchart 		fmt->fmt.pix_mp.xfer_func = xfer_func;
107848e93b0cSLaurent Pinchart 	}
107948e93b0cSLaurent Pinchart }
1080d52e2381SLaurent Pinchart 
v4l_querycap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)10815bc3cb74SMauro Carvalho Chehab static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
10825bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
10835bc3cb74SMauro Carvalho Chehab {
10845bc3cb74SMauro Carvalho Chehab 	struct v4l2_capability *cap = (struct v4l2_capability *)arg;
10857bbe7813SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1086d52e2381SLaurent Pinchart 	int ret;
10875bc3cb74SMauro Carvalho Chehab 
10885bc3cb74SMauro Carvalho Chehab 	cap->version = LINUX_VERSION_CODE;
10897bbe7813SHans Verkuil 	cap->device_caps = vfd->device_caps;
10907bbe7813SHans Verkuil 	cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
1091d52e2381SLaurent Pinchart 
1092f2d8b691SSakari Ailus 	media_set_bus_info(cap->bus_info, sizeof(cap->bus_info),
1093f2d8b691SSakari Ailus 			   vfd->dev_parent);
1094f2d8b691SSakari Ailus 
1095d52e2381SLaurent Pinchart 	ret = ops->vidioc_querycap(file, fh, cap);
1096d52e2381SLaurent Pinchart 
1097454a4e72SHans Verkuil 	/*
10983c135050SHans Verkuil 	 * Drivers must not change device_caps, so check for this and
10993c135050SHans Verkuil 	 * warn if this happened.
1100454a4e72SHans Verkuil 	 */
11013c135050SHans Verkuil 	WARN_ON(cap->device_caps != vfd->device_caps);
11023c135050SHans Verkuil 	/*
11033c135050SHans Verkuil 	 * Check that capabilities is a superset of
11043c135050SHans Verkuil 	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
11053c135050SHans Verkuil 	 */
11063c135050SHans Verkuil 	WARN_ON((cap->capabilities &
11073c135050SHans Verkuil 		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
11083c135050SHans Verkuil 		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
11093c135050SHans Verkuil 	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1110796a2bd2SHans Verkuil 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
1111d52e2381SLaurent Pinchart 
1112d52e2381SLaurent Pinchart 	return ret;
11135bc3cb74SMauro Carvalho Chehab }
11145bc3cb74SMauro Carvalho Chehab 
v4l_g_input(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1115f645e625SNiklas Söderlund static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
1116f645e625SNiklas Söderlund 		       struct file *file, void *fh, void *arg)
1117f645e625SNiklas Söderlund {
1118f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1119f645e625SNiklas Söderlund 
1120f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1121f645e625SNiklas Söderlund 		*(int *)arg = 0;
1122f645e625SNiklas Söderlund 		return 0;
1123f645e625SNiklas Söderlund 	}
1124f645e625SNiklas Söderlund 
1125f645e625SNiklas Söderlund 	return ops->vidioc_g_input(file, fh, arg);
1126f645e625SNiklas Söderlund }
1127f645e625SNiklas Söderlund 
v4l_g_output(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)1128f645e625SNiklas Söderlund static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
1129f645e625SNiklas Söderlund 			struct file *file, void *fh, void *arg)
1130f645e625SNiklas Söderlund {
1131f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1132f645e625SNiklas Söderlund 
1133f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1134f645e625SNiklas Söderlund 		*(int *)arg = 0;
1135f645e625SNiklas Söderlund 		return 0;
1136f645e625SNiklas Söderlund 	}
1137f645e625SNiklas Söderlund 
1138f645e625SNiklas Söderlund 	return ops->vidioc_g_output(file, fh, arg);
1139f645e625SNiklas Söderlund }
1140f645e625SNiklas Söderlund 
v4l_s_input(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)11415bc3cb74SMauro Carvalho Chehab static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
11425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11435bc3cb74SMauro Carvalho Chehab {
114477fa4e07SShuah Khan 	struct video_device *vfd = video_devdata(file);
114577fa4e07SShuah Khan 	int ret;
114677fa4e07SShuah Khan 
114777fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
114877fa4e07SShuah Khan 	if (ret)
114977fa4e07SShuah Khan 		return ret;
1150f645e625SNiklas Söderlund 
1151f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1152f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1153f645e625SNiklas Söderlund 
11545bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
11555bc3cb74SMauro Carvalho Chehab }
11565bc3cb74SMauro Carvalho Chehab 
v4l_s_output(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)11575bc3cb74SMauro Carvalho Chehab static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
11585bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11595bc3cb74SMauro Carvalho Chehab {
1160f645e625SNiklas Söderlund 	struct video_device *vfd = video_devdata(file);
1161f645e625SNiklas Söderlund 
1162f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC)
1163f645e625SNiklas Söderlund 		return  *(int *)arg ? -EINVAL : 0;
1164f645e625SNiklas Söderlund 
11655bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
11665bc3cb74SMauro Carvalho Chehab }
11675bc3cb74SMauro Carvalho Chehab 
v4l_g_priority(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)11685bc3cb74SMauro Carvalho Chehab static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
11695bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11705bc3cb74SMauro Carvalho Chehab {
11715bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11725bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11735bc3cb74SMauro Carvalho Chehab 
11745bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
117559b702eaSLaurent Pinchart 	*p = v4l2_prio_max(vfd->prio);
11765bc3cb74SMauro Carvalho Chehab 	return 0;
11775bc3cb74SMauro Carvalho Chehab }
11785bc3cb74SMauro Carvalho Chehab 
v4l_s_priority(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)11795bc3cb74SMauro Carvalho Chehab static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
11805bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11815bc3cb74SMauro Carvalho Chehab {
11825bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd;
11835bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh;
11845bc3cb74SMauro Carvalho Chehab 	u32 *p = arg;
11855bc3cb74SMauro Carvalho Chehab 
11865bc3cb74SMauro Carvalho Chehab 	vfd = video_devdata(file);
11872438e78aSHans Verkuil 	if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
11882438e78aSHans Verkuil 		return -ENOTTY;
11895bc3cb74SMauro Carvalho Chehab 	vfh = file->private_data;
119059b702eaSLaurent Pinchart 	return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
11915bc3cb74SMauro Carvalho Chehab }
11925bc3cb74SMauro Carvalho Chehab 
v4l_enuminput(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)11935bc3cb74SMauro Carvalho Chehab static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
11945bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
11955bc3cb74SMauro Carvalho Chehab {
119673f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
11975bc3cb74SMauro Carvalho Chehab 	struct v4l2_input *p = arg;
11985bc3cb74SMauro Carvalho Chehab 
11995bc3cb74SMauro Carvalho Chehab 	/*
120002fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
12015bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
12025bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
12035bc3cb74SMauro Carvalho Chehab 	 * for a specific input, it must override these flags.
12045bc3cb74SMauro Carvalho Chehab 	 */
120573f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
12065bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_IN_CAP_STD;
12075bc3cb74SMauro Carvalho Chehab 
1208f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1209f645e625SNiklas Söderlund 		if (p->index)
1210f645e625SNiklas Söderlund 			return -EINVAL;
1211f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1212f645e625SNiklas Söderlund 		p->type = V4L2_INPUT_TYPE_CAMERA;
1213f645e625SNiklas Söderlund 		return 0;
1214f645e625SNiklas Söderlund 	}
1215f645e625SNiklas Söderlund 
12165bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_input(file, fh, p);
12175bc3cb74SMauro Carvalho Chehab }
12185bc3cb74SMauro Carvalho Chehab 
v4l_enumoutput(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)12195bc3cb74SMauro Carvalho Chehab static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
12205bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
12215bc3cb74SMauro Carvalho Chehab {
122273f35418SHans Verkuil 	struct video_device *vfd = video_devdata(file);
12235bc3cb74SMauro Carvalho Chehab 	struct v4l2_output *p = arg;
12245bc3cb74SMauro Carvalho Chehab 
12255bc3cb74SMauro Carvalho Chehab 	/*
122602fa6282SHans Verkuil 	 * We set the flags for CAP_DV_TIMINGS &
12275bc3cb74SMauro Carvalho Chehab 	 * CAP_STD here based on ioctl handler provided by the
12285bc3cb74SMauro Carvalho Chehab 	 * driver. If the driver doesn't support these
12295bc3cb74SMauro Carvalho Chehab 	 * for a specific output, it must override these flags.
12305bc3cb74SMauro Carvalho Chehab 	 */
123173f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
12325bc3cb74SMauro Carvalho Chehab 		p->capabilities |= V4L2_OUT_CAP_STD;
12335bc3cb74SMauro Carvalho Chehab 
1234f645e625SNiklas Söderlund 	if (vfd->device_caps & V4L2_CAP_IO_MC) {
1235f645e625SNiklas Söderlund 		if (p->index)
1236f645e625SNiklas Söderlund 			return -EINVAL;
1237f645e625SNiklas Söderlund 		strscpy(p->name, vfd->name, sizeof(p->name));
1238f645e625SNiklas Söderlund 		p->type = V4L2_OUTPUT_TYPE_ANALOG;
1239f645e625SNiklas Söderlund 		return 0;
1240f645e625SNiklas Söderlund 	}
1241f645e625SNiklas Söderlund 
12425bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_enum_output(file, fh, p);
12435bc3cb74SMauro Carvalho Chehab }
12445bc3cb74SMauro Carvalho Chehab 
v4l_fill_fmtdesc(struct v4l2_fmtdesc * fmt)1245ba300204SHans Verkuil static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1246ba300204SHans Verkuil {
1247ba300204SHans Verkuil 	const unsigned sz = sizeof(fmt->description);
1248ba300204SHans Verkuil 	const char *descr = NULL;
1249ba300204SHans Verkuil 	u32 flags = 0;
1250ba300204SHans Verkuil 
1251ba300204SHans Verkuil 	/*
1252ba300204SHans Verkuil 	 * We depart from the normal coding style here since the descriptions
1253ba300204SHans Verkuil 	 * should be aligned so it is easy to see which descriptions will be
1254ba300204SHans Verkuil 	 * longer than 31 characters (the max length for a description).
1255ba300204SHans Verkuil 	 * And frankly, this is easier to read anyway.
1256ba300204SHans Verkuil 	 *
1257ba300204SHans Verkuil 	 * Note that gcc will use O(log N) comparisons to find the right case.
1258ba300204SHans Verkuil 	 */
1259ba300204SHans Verkuil 	switch (fmt->pixelformat) {
1260ba300204SHans Verkuil 	/* Max description length mask:	descr = "0123456789012345678901234567890" */
1261ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB332:	descr = "8-bit RGB 3-3-2"; break;
1262ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
1263ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
1264ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
12654747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
12664747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
12674747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
12684747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
12694747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
12704747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
1271ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
1272ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
1273ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
12744747bd0fSHans Verkuil 	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
12754747bd0fSHans Verkuil 	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
12764747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
12774747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
12784747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
12794747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
1280ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
1281ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
1282ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
1283ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB555X:	descr = "16-bit XRGB 1-5-5-5 BE"; break;
1284ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB565X:	descr = "16-bit RGB 5-6-5 BE"; break;
1285ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR666:	descr = "18-bit BGRX 6-6-6-14"; break;
1286ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR24:	descr = "24-bit BGR 8-8-8"; break;
1287ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB24:	descr = "24-bit RGB 8-8-8"; break;
1288ba300204SHans Verkuil 	case V4L2_PIX_FMT_BGR32:	descr = "32-bit BGRA/X 8-8-8-8"; break;
1289ba300204SHans Verkuil 	case V4L2_PIX_FMT_ABGR32:	descr = "32-bit BGRA 8-8-8-8"; break;
1290ba300204SHans Verkuil 	case V4L2_PIX_FMT_XBGR32:	descr = "32-bit BGRX 8-8-8-8"; break;
1291ba300204SHans Verkuil 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
1292ba300204SHans Verkuil 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
1293ba300204SHans Verkuil 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
12944747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
12954747bd0fSHans Verkuil 	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
12964747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
12974747bd0fSHans Verkuil 	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
12988d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_RGBX1010102:	descr = "32-bit RGBX 10-10-10-2"; break;
12998d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_RGBA1010102:	descr = "32-bit RGBA 10-10-10-2"; break;
13008d0e3fc6STomi Valkeinen 	case V4L2_PIX_FMT_ARGB2101010:	descr = "32-bit ARGB 2-10-10-10"; break;
1301da0b7a40SMing Qian 	case V4L2_PIX_FMT_BGR48_12:	descr = "12-bit Depth BGR"; break;
1302302b988cSMing Qian 	case V4L2_PIX_FMT_ABGR64_12:	descr = "12-bit Depth BGRA"; break;
1303ba300204SHans Verkuil 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
1304ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
1305ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
1306ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10:		descr = "10-bit Greyscale"; break;
1307ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y12:		descr = "12-bit Greyscale"; break;
1308a490ea68SMing Qian 	case V4L2_PIX_FMT_Y012:		descr = "12-bit Greyscale (bits 15-4)"; break;
1309ae9753a0SDaniel Glöckner 	case V4L2_PIX_FMT_Y14:		descr = "14-bit Greyscale"; break;
1310ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y16:		descr = "16-bit Greyscale"; break;
13112e5e435fSRicardo Ribalda 	case V4L2_PIX_FMT_Y16_BE:	descr = "16-bit Greyscale BE"; break;
1312ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y10BPACK:	descr = "10-bit Greyscale (Packed)"; break;
13136e15bec4STodor Tomov 	case V4L2_PIX_FMT_Y10P:		descr = "10-bit Greyscale (MIPI Packed)"; break;
1314b87f5e25SDaniel Scally 	case V4L2_PIX_FMT_IPU3_Y10:	descr = "10-bit greyscale (IPU3 Packed)"; break;
13155b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y8I:		descr = "Interleaved 8-bit Greyscale"; break;
13165b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Y12I:		descr = "Interleaved 12-bit Greyscale"; break;
13175b382290SLaurent Pinchart 	case V4L2_PIX_FMT_Z16:		descr = "16-bit Depth"; break;
13185df082e2SEvgeni Raikhel 	case V4L2_PIX_FMT_INZI:		descr = "Planar 10:16 Greyscale Depth"; break;
131992799ef7SSergey Dorodnicov 	case V4L2_PIX_FMT_CNF4:		descr = "4-bit Depth Confidence (Packed)"; break;
1320ba300204SHans Verkuil 	case V4L2_PIX_FMT_PAL8:		descr = "8-bit Palette"; break;
1321ba300204SHans Verkuil 	case V4L2_PIX_FMT_UV8:		descr = "8-bit Chrominance UV 4-4"; break;
1322ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU410:	descr = "Planar YVU 4:1:0"; break;
1323ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420:	descr = "Planar YVU 4:2:0"; break;
1324ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUYV:		descr = "YUYV 4:2:2"; break;
1325ba300204SHans Verkuil 	case V4L2_PIX_FMT_YYUV:		descr = "YYUV 4:2:2"; break;
1326ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVYU:		descr = "YVYU 4:2:2"; break;
1327ba300204SHans Verkuil 	case V4L2_PIX_FMT_UYVY:		descr = "UYVY 4:2:2"; break;
1328ba300204SHans Verkuil 	case V4L2_PIX_FMT_VYUY:		descr = "VYUY 4:2:2"; break;
1329fcbafafbSPhilipp Zabel 	case V4L2_PIX_FMT_YUV422P:	descr = "Planar YUV 4:2:2"; break;
1330ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV411P:	descr = "Planar YUV 4:1:1"; break;
1331ba300204SHans Verkuil 	case V4L2_PIX_FMT_Y41P:		descr = "YUV 4:1:1 (Packed)"; break;
1332ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV444:	descr = "16-bit A/XYUV 4-4-4-4"; break;
1333ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV555:	descr = "16-bit A/XYUV 1-5-5-5"; break;
1334ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV565:	descr = "16-bit YUV 5-6-5"; break;
13350376a51fSMirela Rabulea 	case V4L2_PIX_FMT_YUV24:	descr = "24-bit YUV 4:4:4 8-8-8"; break;
1336ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV32:	descr = "32-bit A/XYUV 8-8-8-8"; break;
1337a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_AYUV32:	descr = "32-bit AYUV 8-8-8-8"; break;
1338a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_XYUV32:	descr = "32-bit XYUV 8-8-8-8"; break;
1339a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYA32:	descr = "32-bit VUYA 8-8-8-8"; break;
1340a7fe4ca7SVivek Kasireddy 	case V4L2_PIX_FMT_VUYX32:	descr = "32-bit VUYX 8-8-8-8"; break;
134100f6842eSLaurent Pinchart 	case V4L2_PIX_FMT_YUVA32:	descr = "32-bit YUVA 8-8-8-8"; break;
134200f6842eSLaurent Pinchart 	case V4L2_PIX_FMT_YUVX32:	descr = "32-bit YUVX 8-8-8-8"; break;
1343ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV410:	descr = "Planar YUV 4:1:0"; break;
1344ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
1345ba300204SHans Verkuil 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
1346ba300204SHans Verkuil 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
134799c95496SMing Qian 	case V4L2_PIX_FMT_YUV48_12:	descr = "12-bit YUV 4:4:4 Packed"; break;
13486a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12:		descr = "Y/UV 4:2:0"; break;
13496a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV21:		descr = "Y/VU 4:2:0"; break;
13506a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV16:		descr = "Y/UV 4:2:2"; break;
13516a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV61:		descr = "Y/VU 4:2:2"; break;
13526a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV24:		descr = "Y/UV 4:4:4"; break;
13536a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV42:		descr = "Y/VU 4:4:4"; break;
13546a394d56SJernej Skrabec 	case V4L2_PIX_FMT_P010:		descr = "10-bit Y/UV 4:2:0"; break;
1355aa108040SMing Qian 	case V4L2_PIX_FMT_P012:		descr = "12-bit Y/UV 4:2:0"; break;
13566a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/UV 4:2:0 (4x4 Linear)"; break;
13576a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/UV 4:2:0 (16x16 Linear)"; break;
13586a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/UV 4:2:0 (32x32 Linear)"; break;
1359fc91af07SBenjamin Gaignard 	case V4L2_PIX_FMT_NV15_4L4:	descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break;
13606a394d56SJernej Skrabec 	case V4L2_PIX_FMT_P010_4L4:	descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break;
13616a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12M:	descr = "Y/UV 4:2:0 (N-C)"; break;
13626a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV21M:	descr = "Y/VU 4:2:0 (N-C)"; break;
13636a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV16M:	descr = "Y/UV 4:2:2 (N-C)"; break;
13646a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV61M:	descr = "Y/VU 4:2:2 (N-C)"; break;
13656a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
13666a394d56SJernej Skrabec 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
1367aa108040SMing Qian 	case V4L2_PIX_FMT_P012M:	descr = "12-bit Y/UV 4:2:0 (N-C)"; break;
1368ba300204SHans Verkuil 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
1369ba300204SHans Verkuil 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
1370d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
1371d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU422M:	descr = "Planar YVU 4:2:2 (N-C)"; break;
1372d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YUV444M:	descr = "Planar YUV 4:4:4 (N-C)"; break;
1373d65fae92SLaurent Pinchart 	case V4L2_PIX_FMT_YVU444M:	descr = "Planar YVU 4:4:4 (N-C)"; break;
1374ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR8:	descr = "8-bit Bayer BGBG/GRGR"; break;
1375ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG8:	descr = "8-bit Bayer GBGB/RGRG"; break;
1376ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG8:	descr = "8-bit Bayer GRGR/BGBG"; break;
1377ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB8:	descr = "8-bit Bayer RGRG/GBGB"; break;
1378ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10:	descr = "10-bit Bayer BGBG/GRGR"; break;
1379ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10:	descr = "10-bit Bayer GBGB/RGRG"; break;
1380ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10:	descr = "10-bit Bayer GRGR/BGBG"; break;
1381ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10:	descr = "10-bit Bayer RGRG/GBGB"; break;
1382ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10P:	descr = "10-bit Bayer BGBG/GRGR Packed"; break;
1383ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
1384ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
1385ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
1386e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
1387e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
1388e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
1389e8391b76SYong Zhi 	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
1390ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
1391ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
1392ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
1393ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10ALAW8:	descr = "8-bit Bayer RGRG/GBGB (A-law)"; break;
1394ba300204SHans Verkuil 	case V4L2_PIX_FMT_SBGGR10DPCM8:	descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break;
1395ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGBRG10DPCM8:	descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1396ba300204SHans Verkuil 	case V4L2_PIX_FMT_SGRBG10DPCM8:	descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1397ba300204SHans Verkuil 	case V4L2_PIX_FMT_SRGGB10DPCM8:	descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1398d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12:	descr = "12-bit Bayer BGBG/GRGR"; break;
1399d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12:	descr = "12-bit Bayer GBGB/RGRG"; break;
1400d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12:	descr = "12-bit Bayer GRGR/BGBG"; break;
1401d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12:	descr = "12-bit Bayer RGRG/GBGB"; break;
1402d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SBGGR12P:	descr = "12-bit Bayer BGBG/GRGR Packed"; break;
1403d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGBRG12P:	descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1404d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SGRBG12P:	descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1405d1b3437eSSakari Ailus 	case V4L2_PIX_FMT_SRGGB12P:	descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1406d12127edSSakari Ailus 	case V4L2_PIX_FMT_SBGGR14:	descr = "14-bit Bayer BGBG/GRGR"; break;
1407d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGBRG14:	descr = "14-bit Bayer GBGB/RGRG"; break;
1408d12127edSSakari Ailus 	case V4L2_PIX_FMT_SGRBG14:	descr = "14-bit Bayer GRGR/BGBG"; break;
1409d12127edSSakari Ailus 	case V4L2_PIX_FMT_SRGGB14:	descr = "14-bit Bayer RGRG/GBGB"; break;
141083b15832SSakari Ailus 	case V4L2_PIX_FMT_SBGGR14P:	descr = "14-bit Bayer BGBG/GRGR Packed"; break;
141183b15832SSakari Ailus 	case V4L2_PIX_FMT_SGBRG14P:	descr = "14-bit Bayer GBGB/RGRG Packed"; break;
141283b15832SSakari Ailus 	case V4L2_PIX_FMT_SGRBG14P:	descr = "14-bit Bayer GRGR/BGBG Packed"; break;
141383b15832SSakari Ailus 	case V4L2_PIX_FMT_SRGGB14P:	descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1414b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SBGGR16:	descr = "16-bit Bayer BGBG/GRGR"; break;
1415b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
1416b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
1417b9a4b13cSSakari Ailus 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
141899b74277SMauro Carvalho Chehab 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
1419ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
1420ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
1421ba300204SHans Verkuil 	case V4L2_PIX_FMT_SPCA508:	descr = "GSPCA SPCA508"; break;
1422ba300204SHans Verkuil 	case V4L2_PIX_FMT_STV0680:	descr = "GSPCA STV0680"; break;
1423ba300204SHans Verkuil 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
1424ba300204SHans Verkuil 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
1425ba300204SHans Verkuil 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
1426ffe5350cSAlexandre Courbot 	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
142766b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
142866b2ab27SRicardo Ribalda Delgado 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
142948fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
143048fc10aaSAntti Palosaari 	case V4L2_SDR_FMT_CU16LE:	descr = "Complex U16LE"; break;
1431ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS8:		descr = "Complex S8"; break;
1432ba300204SHans Verkuil 	case V4L2_SDR_FMT_CS14LE:	descr = "Complex S14LE"; break;
1433ba300204SHans Verkuil 	case V4L2_SDR_FMT_RU12LE:	descr = "Real U12LE"; break;
1434c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
1435c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
1436c28f2118SRamesh Shanmugasundaram 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
14374747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
14384747bd0fSHans Verkuil 	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
14394747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
14404747bd0fSHans Verkuil 	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
144114d66538SLaurent Pinchart 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
14425deb1c04SNiklas Söderlund 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
14434747bd0fSHans Verkuil 	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
14444747bd0fSHans Verkuil 	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
144578892b6bSVandana BN 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
1446df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
1447df22026aSShunqian Zheng 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
14485b8bb216SMing Qian 	case V4L2_PIX_FMT_NV12_8L128:	descr = "NV12 (8x128 Linear)"; break;
144972a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
14505b8bb216SMing Qian 	case V4L2_PIX_FMT_NV12_10BE_8L128:	descr = "10-bit NV12 (8x128 Linear, BE)"; break;
145172a74c8fSMing Qian 	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
14520dc1d7a7STomi Valkeinen 	case V4L2_PIX_FMT_Y210:		descr = "10-bit YUYV Packed"; break;
14530dc1d7a7STomi Valkeinen 	case V4L2_PIX_FMT_Y212:		descr = "12-bit YUYV Packed"; break;
14540dc1d7a7STomi Valkeinen 	case V4L2_PIX_FMT_Y216:		descr = "16-bit YUYV Packed"; break;
1455ba300204SHans Verkuil 
1456ba300204SHans Verkuil 	default:
1457ba300204SHans Verkuil 		/* Compressed formats */
1458ba300204SHans Verkuil 		flags = V4L2_FMT_FLAG_COMPRESSED;
1459ba300204SHans Verkuil 		switch (fmt->pixelformat) {
1460ba300204SHans Verkuil 		/* Max description length mask:	descr = "0123456789012345678901234567890" */
1461ba300204SHans Verkuil 		case V4L2_PIX_FMT_MJPEG:	descr = "Motion-JPEG"; break;
1462ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPEG:		descr = "JFIF JPEG"; break;
1463ba300204SHans Verkuil 		case V4L2_PIX_FMT_DV:		descr = "1394"; break;
1464ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG:		descr = "MPEG-1/2/4"; break;
1465ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
1466ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
1467ba300204SHans Verkuil 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
14687bb3c32aSEzequiel Garcia 		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
1469ba300204SHans Verkuil 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
1470ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
1471ba300204SHans Verkuil 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
1472c27bb30eSPaul Kocialkowski 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
14734747bd0fSHans Verkuil 		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
1474ba300204SHans Verkuil 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
1475ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
1476ba300204SHans Verkuil 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
1477ba300204SHans Verkuil 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
1478a57d6acaSPawel Osciak 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
1479fa14a564SWu-Cheng Li 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
1480b88dbe38SAndrzej Pietrasiewicz 		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
14811c791727SSmitha T Murthy 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
1482256fa392SPaul Kocialkowski 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
148362c3fce0SHans Verkuil 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
1484f05a51b9SHans Verkuil 		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */
1485ae77d139SMing Qian 		case V4L2_PIX_FMT_SPK:		descr = "Sorenson Spark"; break;
1486ec9aa62aSMing Qian 		case V4L2_PIX_FMT_RV30:		descr = "RealVideo 8"; break;
1487ec9aa62aSMing Qian 		case V4L2_PIX_FMT_RV40:		descr = "RealVideo 9 & 10"; break;
1488ba300204SHans Verkuil 		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break;
1489ba300204SHans Verkuil 		case V4L2_PIX_FMT_WNVA:		descr = "WNVA"; break;
1490ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C10X:	descr = "GSPCA SN9C10X"; break;
1491ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC1:		descr = "Raw Philips Webcam Type (Old)"; break;
1492ba300204SHans Verkuil 		case V4L2_PIX_FMT_PWC2:		descr = "Raw Philips Webcam Type (New)"; break;
1493ba300204SHans Verkuil 		case V4L2_PIX_FMT_ET61X251:	descr = "GSPCA ET61X251"; break;
1494ba300204SHans Verkuil 		case V4L2_PIX_FMT_SPCA561:	descr = "GSPCA SPCA561"; break;
1495ba300204SHans Verkuil 		case V4L2_PIX_FMT_PAC207:	descr = "GSPCA PAC207"; break;
1496ba300204SHans Verkuil 		case V4L2_PIX_FMT_MR97310A:	descr = "GSPCA MR97310A"; break;
1497ba300204SHans Verkuil 		case V4L2_PIX_FMT_JL2005BCD:	descr = "GSPCA JL2005BCD"; break;
1498ba300204SHans Verkuil 		case V4L2_PIX_FMT_SN9C2028:	descr = "GSPCA SN9C2028"; break;
1499ba300204SHans Verkuil 		case V4L2_PIX_FMT_SQ905C:	descr = "GSPCA SQ905C"; break;
1500ba300204SHans Verkuil 		case V4L2_PIX_FMT_PJPG:		descr = "GSPCA PJPG"; break;
1501ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV511:	descr = "GSPCA OV511"; break;
1502ba300204SHans Verkuil 		case V4L2_PIX_FMT_OV518:	descr = "GSPCA OV518"; break;
1503ba300204SHans Verkuil 		case V4L2_PIX_FMT_JPGL:		descr = "JPEG Lite"; break;
1504ba300204SHans Verkuil 		case V4L2_PIX_FMT_SE401:	descr = "GSPCA SE401"; break;
1505ba300204SHans Verkuil 		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
1506d4de6634STiffany Lin 		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
15072308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC08C:	descr = "QCOM Compressed 8-bit Format"; break;
15082308d5afSStanimir Varbanov 		case V4L2_PIX_FMT_QC10C:	descr = "QCOM Compressed 10-bit Format"; break;
15097a4b3770SJammy Huang 		case V4L2_PIX_FMT_AJPG:		descr = "Aspeed JPEG"; break;
15109de30f57SDaniel Almeida 		case V4L2_PIX_FMT_AV1_FRAME:	descr = "AV1 Frame"; break;
15116afcc2b0SMingjia Zhang 		case V4L2_PIX_FMT_MT2110T:	descr = "Mediatek 10bit Tile Mode"; break;
15121dff2bebSMingjia Zhang 		case V4L2_PIX_FMT_MT2110R:	descr = "Mediatek 10bit Raster Mode"; break;
1513b3acd097SMarvin Lin 		case V4L2_PIX_FMT_HEXTILE:	descr = "Hextile Compressed Format"; break;
1514ba300204SHans Verkuil 		default:
1515ba300204SHans Verkuil 			if (fmt->description[0])
1516ba300204SHans Verkuil 				return;
1517c2286cc0SSakari Ailus 			WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
1518ba300204SHans Verkuil 			flags = 0;
1519e927e1e0SSakari Ailus 			snprintf(fmt->description, sz, "%p4cc",
1520e927e1e0SSakari Ailus 				 &fmt->pixelformat);
1521ba300204SHans Verkuil 			break;
1522ba300204SHans Verkuil 		}
1523ba300204SHans Verkuil 	}
1524ba300204SHans Verkuil 
1525ba300204SHans Verkuil 	if (descr)
1526e7dd89ceSHans Petter Selasky 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
15277c490e25SHans Verkuil 	fmt->flags |= flags;
1528ba300204SHans Verkuil }
1529ba300204SHans Verkuil 
v4l_enum_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)15305bc3cb74SMauro Carvalho Chehab static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
15315bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
15325bc3cb74SMauro Carvalho Chehab {
15337e98b7b5SBoris Brezillon 	struct video_device *vdev = video_devdata(file);
15345bc3cb74SMauro Carvalho Chehab 	struct v4l2_fmtdesc *p = arg;
1535b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1536e5b6b07aSLaurent Pinchart 	u32 mbus_code;
1537f0d2b7a8SBoris Brezillon 	u32 cap_mask;
1538b2469c81SHans Verkuil 
1539b2469c81SHans Verkuil 	if (ret)
1540b2469c81SHans Verkuil 		return ret;
1541b2469c81SHans Verkuil 	ret = -EINVAL;
15425bc3cb74SMauro Carvalho Chehab 
1543e5b6b07aSLaurent Pinchart 	if (!(vdev->device_caps & V4L2_CAP_IO_MC))
1544e5b6b07aSLaurent Pinchart 		p->mbus_code = 0;
1545e5b6b07aSLaurent Pinchart 
1546e5b6b07aSLaurent Pinchart 	mbus_code = p->mbus_code;
15470625b6b8SXiu Jianfeng 	memset_after(p, 0, type);
1548e5b6b07aSLaurent Pinchart 	p->mbus_code = mbus_code;
1549e5b6b07aSLaurent Pinchart 
15505bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
15515bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
15527e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1553f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1554f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1555f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15567e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
15577e98b7b5SBoris Brezillon 			break;
15587e98b7b5SBoris Brezillon 
1559b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
15605bc3cb74SMauro Carvalho Chehab 			break;
1561ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
1562ba300204SHans Verkuil 		break;
15635bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1564b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
15655bc3cb74SMauro Carvalho Chehab 			break;
1566ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
1567ba300204SHans Verkuil 		break;
15685bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
15697e98b7b5SBoris Brezillon 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1570f0d2b7a8SBoris Brezillon 		cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
1571f0d2b7a8SBoris Brezillon 			   V4L2_CAP_VIDEO_M2M_MPLANE;
1572f0d2b7a8SBoris Brezillon 		if (!!(vdev->device_caps & cap_mask) !=
15737e98b7b5SBoris Brezillon 		    (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
15747e98b7b5SBoris Brezillon 			break;
15757e98b7b5SBoris Brezillon 
1576b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
15775bc3cb74SMauro Carvalho Chehab 			break;
1578ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
1579ba300204SHans Verkuil 		break;
1580582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1581b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
1582582c52cbSAntti Palosaari 			break;
1583ba300204SHans Verkuil 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
1584ba300204SHans Verkuil 		break;
15859effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1586b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
15879effc72fSAntti Palosaari 			break;
15889effc72fSAntti Palosaari 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
15899effc72fSAntti Palosaari 		break;
1590fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1591b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
1592fb9ffa6aSLaurent Pinchart 			break;
1593fb9ffa6aSLaurent Pinchart 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1594fb9ffa6aSLaurent Pinchart 		break;
159572148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
159672148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_enum_fmt_meta_out))
159772148d1aSSakari Ailus 			break;
159872148d1aSSakari Ailus 		ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
159972148d1aSSakari Ailus 		break;
16005bc3cb74SMauro Carvalho Chehab 	}
1601ba300204SHans Verkuil 	if (ret == 0)
1602ba300204SHans Verkuil 		v4l_fill_fmtdesc(p);
1603ba300204SHans Verkuil 	return ret;
16045bc3cb74SMauro Carvalho Chehab }
16055bc3cb74SMauro Carvalho Chehab 
v4l_pix_format_touch(struct v4l2_pix_format * p)1606545b618cSVandana BN static void v4l_pix_format_touch(struct v4l2_pix_format *p)
1607545b618cSVandana BN {
1608545b618cSVandana BN 	/*
1609545b618cSVandana BN 	 * The v4l2_pix_format structure contains fields that make no sense for
1610545b618cSVandana BN 	 * touch. Set them to default values in this case.
1611545b618cSVandana BN 	 */
1612545b618cSVandana BN 
1613545b618cSVandana BN 	p->field = V4L2_FIELD_NONE;
1614545b618cSVandana BN 	p->colorspace = V4L2_COLORSPACE_RAW;
1615545b618cSVandana BN 	p->flags = 0;
1616545b618cSVandana BN 	p->ycbcr_enc = 0;
1617545b618cSVandana BN 	p->quantization = 0;
1618545b618cSVandana BN 	p->xfer_func = 0;
1619545b618cSVandana BN }
1620545b618cSVandana BN 
v4l_g_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)16215bc3cb74SMauro Carvalho Chehab static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
16225bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16235bc3cb74SMauro Carvalho Chehab {
16245bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1625545b618cSVandana BN 	struct video_device *vfd = video_devdata(file);
1626b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
1627b2469c81SHans Verkuil 
1628b2469c81SHans Verkuil 	if (ret)
1629b2469c81SHans Verkuil 		return ret;
1630d52e2381SLaurent Pinchart 
1631e5ce558aSHans Verkuil 	memset(&p->fmt, 0, sizeof(p->fmt));
1632e5ce558aSHans Verkuil 
16335bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16345bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1635b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
16365bc3cb74SMauro Carvalho Chehab 			break;
163748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1638d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
163948f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1640d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1641545b618cSVandana BN 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1642545b618cSVandana BN 			v4l_pix_format_touch(&p->fmt.pix);
1643d52e2381SLaurent Pinchart 		return ret;
16445bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
16455bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
16465bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
16475bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
16484b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
16494b20259fSHans Verkuil 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
16504b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
16514b20259fSHans Verkuil 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
16525bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1653b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_g_fmt_vid_out))
16545bc3cb74SMauro Carvalho Chehab 			break;
165548f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1656d52e2381SLaurent Pinchart 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
165748f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
1658d52e2381SLaurent Pinchart 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1659d52e2381SLaurent Pinchart 		return ret;
16605bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
16615bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
16625bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16635bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
16645bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
16655bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
16665bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
16675bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
1668582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1669582c52cbSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
16709effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
16719effc72fSAntti Palosaari 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1672fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1673fb9ffa6aSLaurent Pinchart 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
167472148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
167572148d1aSSakari Ailus 		return ops->vidioc_g_fmt_meta_out(file, fh, arg);
16765bc3cb74SMauro Carvalho Chehab 	}
16775bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
16785bc3cb74SMauro Carvalho Chehab }
16795bc3cb74SMauro Carvalho Chehab 
v4l_s_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)16805bc3cb74SMauro Carvalho Chehab static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
16815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
16825bc3cb74SMauro Carvalho Chehab {
16835bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
16844b20259fSHans Verkuil 	struct video_device *vfd = video_devdata(file);
1685b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
16864e1e0eb0SEzequiel Garcia 	unsigned int i;
1687b2469c81SHans Verkuil 
1688b2469c81SHans Verkuil 	if (ret)
1689b2469c81SHans Verkuil 		return ret;
16905bc3cb74SMauro Carvalho Chehab 
169177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
169277fa4e07SShuah Khan 	if (ret)
169377fa4e07SShuah Khan 		return ret;
1694d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1695d52e2381SLaurent Pinchart 
16965bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
16975bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1698b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
16995bc3cb74SMauro Carvalho Chehab 			break;
17000625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
170148f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
170248f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
170348f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1704b2469c81SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1705b2fe22d0SNick Dyer 			v4l_pix_format_touch(&p->fmt.pix);
170648f2650aSHans Verkuil 		return ret;
17075bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1708b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
17095bc3cb74SMauro Carvalho Chehab 			break;
17100625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
17114e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
17120625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
17130625b6b8SXiu Jianfeng 				     0, bytesperline);
17145bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
17155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1716b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
17175bc3cb74SMauro Carvalho Chehab 			break;
17180625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
171999ba0703SHans Verkuil 		p->fmt.win.clips = NULL;
172099ba0703SHans Verkuil 		p->fmt.win.clipcount = 0;
172199ba0703SHans Verkuil 		p->fmt.win.bitmap = NULL;
17225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
17234b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1724b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
17254b20259fSHans Verkuil 			break;
17260625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
17274b20259fSHans Verkuil 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
17284b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1729b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
17304b20259fSHans Verkuil 			break;
17310625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
17324b20259fSHans Verkuil 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
17335bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1734b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out))
17355bc3cb74SMauro Carvalho Chehab 			break;
17360625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
173748f2650aSHans Verkuil 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
173848f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
173948f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
174048f2650aSHans Verkuil 		return ret;
17415bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1742b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
17435bc3cb74SMauro Carvalho Chehab 			break;
17440625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
17454e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
17460625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
17470625b6b8SXiu Jianfeng 				     0, bytesperline);
17485bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
17495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1750b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
17515bc3cb74SMauro Carvalho Chehab 			break;
17520625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
175399ba0703SHans Verkuil 		p->fmt.win.clips = NULL;
175499ba0703SHans Verkuil 		p->fmt.win.clipcount = 0;
175599ba0703SHans Verkuil 		p->fmt.win.bitmap = NULL;
17565bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
17575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1758b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
17595bc3cb74SMauro Carvalho Chehab 			break;
17600625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
17615bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
17625bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1763b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
17645bc3cb74SMauro Carvalho Chehab 			break;
17650625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
17665bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
1767582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1768b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
1769582c52cbSAntti Palosaari 			break;
17700625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
1771582c52cbSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
17729effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1773b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
17749effc72fSAntti Palosaari 			break;
17750625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
17769effc72fSAntti Palosaari 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1777fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1778b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
1779fb9ffa6aSLaurent Pinchart 			break;
17800625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
1781fb9ffa6aSLaurent Pinchart 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
178272148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
178372148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_s_fmt_meta_out))
178472148d1aSSakari Ailus 			break;
17850625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
178672148d1aSSakari Ailus 		return ops->vidioc_s_fmt_meta_out(file, fh, arg);
17875bc3cb74SMauro Carvalho Chehab 	}
17885bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
17895bc3cb74SMauro Carvalho Chehab }
17905bc3cb74SMauro Carvalho Chehab 
v4l_try_fmt(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)17915bc3cb74SMauro Carvalho Chehab static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
17925bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
17935bc3cb74SMauro Carvalho Chehab {
17945bc3cb74SMauro Carvalho Chehab 	struct v4l2_format *p = arg;
1795999a4312SHans Verkuil 	struct video_device *vfd = video_devdata(file);
1796b2469c81SHans Verkuil 	int ret = check_fmt(file, p->type);
17974e1e0eb0SEzequiel Garcia 	unsigned int i;
1798b2469c81SHans Verkuil 
1799b2469c81SHans Verkuil 	if (ret)
1800b2469c81SHans Verkuil 		return ret;
18015bc3cb74SMauro Carvalho Chehab 
1802d52e2381SLaurent Pinchart 	v4l_sanitize_format(p);
1803d52e2381SLaurent Pinchart 
18045bc3cb74SMauro Carvalho Chehab 	switch (p->type) {
18055bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1806b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
18075bc3cb74SMauro Carvalho Chehab 			break;
18080625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
180948f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
181048f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
181148f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1812999a4312SHans Verkuil 		if (vfd->vfl_type == VFL_TYPE_TOUCH)
1813999a4312SHans Verkuil 			v4l_pix_format_touch(&p->fmt.pix);
181448f2650aSHans Verkuil 		return ret;
18155bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1816b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
18175bc3cb74SMauro Carvalho Chehab 			break;
18180625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
18194e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
18200625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
18210625b6b8SXiu Jianfeng 				     0, bytesperline);
18225bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
18235bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1824b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
18255bc3cb74SMauro Carvalho Chehab 			break;
18260625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
182799ba0703SHans Verkuil 		p->fmt.win.clips = NULL;
182899ba0703SHans Verkuil 		p->fmt.win.clipcount = 0;
182999ba0703SHans Verkuil 		p->fmt.win.bitmap = NULL;
18305bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
18314b20259fSHans Verkuil 	case V4L2_BUF_TYPE_VBI_CAPTURE:
1832b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
18334b20259fSHans Verkuil 			break;
18340625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
18354b20259fSHans Verkuil 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
18364b20259fSHans Verkuil 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1837b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
18384b20259fSHans Verkuil 			break;
18390625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
18404b20259fSHans Verkuil 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
18415bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1842b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out))
18435bc3cb74SMauro Carvalho Chehab 			break;
18440625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix);
184548f2650aSHans Verkuil 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
184648f2650aSHans Verkuil 		/* just in case the driver zeroed it again */
184748f2650aSHans Verkuil 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
184848f2650aSHans Verkuil 		return ret;
18495bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1850b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
18515bc3cb74SMauro Carvalho Chehab 			break;
18520625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.pix_mp.xfer_func);
18534e1e0eb0SEzequiel Garcia 		for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
18540625b6b8SXiu Jianfeng 			memset_after(&p->fmt.pix_mp.plane_fmt[i],
18550625b6b8SXiu Jianfeng 				     0, bytesperline);
18565bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
18575bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1858b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
18595bc3cb74SMauro Carvalho Chehab 			break;
18600625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.win);
186199ba0703SHans Verkuil 		p->fmt.win.clips = NULL;
186299ba0703SHans Verkuil 		p->fmt.win.clipcount = 0;
186399ba0703SHans Verkuil 		p->fmt.win.bitmap = NULL;
18645bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
18655bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_VBI_OUTPUT:
1866b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
18675bc3cb74SMauro Carvalho Chehab 			break;
18680625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.vbi.flags);
18695bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
18705bc3cb74SMauro Carvalho Chehab 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1871b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
18725bc3cb74SMauro Carvalho Chehab 			break;
18730625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sliced.io_size);
18745bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
1875582c52cbSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_CAPTURE:
1876b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
1877582c52cbSAntti Palosaari 			break;
18780625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
1879582c52cbSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
18809effc72fSAntti Palosaari 	case V4L2_BUF_TYPE_SDR_OUTPUT:
1881b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
18829effc72fSAntti Palosaari 			break;
18830625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.sdr.buffersize);
18849effc72fSAntti Palosaari 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1885fb9ffa6aSLaurent Pinchart 	case V4L2_BUF_TYPE_META_CAPTURE:
1886b2469c81SHans Verkuil 		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
1887fb9ffa6aSLaurent Pinchart 			break;
18880625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
1889fb9ffa6aSLaurent Pinchart 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
189072148d1aSSakari Ailus 	case V4L2_BUF_TYPE_META_OUTPUT:
189172148d1aSSakari Ailus 		if (unlikely(!ops->vidioc_try_fmt_meta_out))
189272148d1aSSakari Ailus 			break;
18930625b6b8SXiu Jianfeng 		memset_after(p, 0, fmt.meta);
189472148d1aSSakari Ailus 		return ops->vidioc_try_fmt_meta_out(file, fh, arg);
18955bc3cb74SMauro Carvalho Chehab 	}
18965bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
18975bc3cb74SMauro Carvalho Chehab }
18985bc3cb74SMauro Carvalho Chehab 
v4l_streamon(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)18995bc3cb74SMauro Carvalho Chehab static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
19005bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19015bc3cb74SMauro Carvalho Chehab {
19025bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
19035bc3cb74SMauro Carvalho Chehab }
19045bc3cb74SMauro Carvalho Chehab 
v4l_streamoff(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19055bc3cb74SMauro Carvalho Chehab static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
19065bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19075bc3cb74SMauro Carvalho Chehab {
19085bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
19095bc3cb74SMauro Carvalho Chehab }
19105bc3cb74SMauro Carvalho Chehab 
v4l_g_tuner(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19115bc3cb74SMauro Carvalho Chehab static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
19125bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19135bc3cb74SMauro Carvalho Chehab {
19145bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19155bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
19165bc3cb74SMauro Carvalho Chehab 	int err;
19175bc3cb74SMauro Carvalho Chehab 
19185bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19195bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19205bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_tuner(file, fh, p);
19215bc3cb74SMauro Carvalho Chehab 	if (!err)
19225bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
19235bc3cb74SMauro Carvalho Chehab 	return err;
19245bc3cb74SMauro Carvalho Chehab }
19255bc3cb74SMauro Carvalho Chehab 
v4l_s_tuner(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19265bc3cb74SMauro Carvalho Chehab static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
19275bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19285bc3cb74SMauro Carvalho Chehab {
19295bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19305bc3cb74SMauro Carvalho Chehab 	struct v4l2_tuner *p = arg;
193177fa4e07SShuah Khan 	int ret;
19325bc3cb74SMauro Carvalho Chehab 
193377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
193477fa4e07SShuah Khan 	if (ret)
193577fa4e07SShuah Khan 		return ret;
19365bc3cb74SMauro Carvalho Chehab 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19375bc3cb74SMauro Carvalho Chehab 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19385bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_tuner(file, fh, p);
19395bc3cb74SMauro Carvalho Chehab }
19405bc3cb74SMauro Carvalho Chehab 
v4l_g_modulator(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19415bc3cb74SMauro Carvalho Chehab static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
19425bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19435bc3cb74SMauro Carvalho Chehab {
19444124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19455bc3cb74SMauro Carvalho Chehab 	struct v4l2_modulator *p = arg;
19465bc3cb74SMauro Carvalho Chehab 	int err;
19475bc3cb74SMauro Carvalho Chehab 
19484124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19494124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19504124a3c4SAntti Palosaari 
19515bc3cb74SMauro Carvalho Chehab 	err = ops->vidioc_g_modulator(file, fh, p);
19525bc3cb74SMauro Carvalho Chehab 	if (!err)
19535bc3cb74SMauro Carvalho Chehab 		p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
19545bc3cb74SMauro Carvalho Chehab 	return err;
19555bc3cb74SMauro Carvalho Chehab }
19565bc3cb74SMauro Carvalho Chehab 
v4l_s_modulator(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19574124a3c4SAntti Palosaari static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
19584124a3c4SAntti Palosaari 				struct file *file, void *fh, void *arg)
19594124a3c4SAntti Palosaari {
19604124a3c4SAntti Palosaari 	struct video_device *vfd = video_devdata(file);
19614124a3c4SAntti Palosaari 	struct v4l2_modulator *p = arg;
19624124a3c4SAntti Palosaari 
19634124a3c4SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_RADIO)
19644124a3c4SAntti Palosaari 		p->type = V4L2_TUNER_RADIO;
19654124a3c4SAntti Palosaari 
19664124a3c4SAntti Palosaari 	return ops->vidioc_s_modulator(file, fh, p);
19674124a3c4SAntti Palosaari }
19684124a3c4SAntti Palosaari 
v4l_g_frequency(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19695bc3cb74SMauro Carvalho Chehab static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
19705bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19715bc3cb74SMauro Carvalho Chehab {
19725bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
19735bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency *p = arg;
19745bc3cb74SMauro Carvalho Chehab 
197584099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
1976f3c3ececSAntti Palosaari 		p->type = V4L2_TUNER_SDR;
197784099a28SAntti Palosaari 	else
19785bc3cb74SMauro Carvalho Chehab 		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19795bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
19805bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_frequency(file, fh, p);
19815bc3cb74SMauro Carvalho Chehab }
19825bc3cb74SMauro Carvalho Chehab 
v4l_s_frequency(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)19835bc3cb74SMauro Carvalho Chehab static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
19845bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
19855bc3cb74SMauro Carvalho Chehab {
19865bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
1987b530a447SHans Verkuil 	const struct v4l2_frequency *p = arg;
19885bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
198977fa4e07SShuah Khan 	int ret;
19905bc3cb74SMauro Carvalho Chehab 
199177fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
199277fa4e07SShuah Khan 	if (ret)
199377fa4e07SShuah Khan 		return ret;
199484099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
1995f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
199684099a28SAntti Palosaari 			return -EINVAL;
199784099a28SAntti Palosaari 	} else {
19985bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
19995bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
200084099a28SAntti Palosaari 		if (type != p->type)
20015bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
200284099a28SAntti Palosaari 	}
20035bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_frequency(file, fh, p);
20045bc3cb74SMauro Carvalho Chehab }
20055bc3cb74SMauro Carvalho Chehab 
v4l_enumstd(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)20065bc3cb74SMauro Carvalho Chehab static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
20075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20085bc3cb74SMauro Carvalho Chehab {
20095bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20105bc3cb74SMauro Carvalho Chehab 	struct v4l2_standard *p = arg;
20115bc3cb74SMauro Carvalho Chehab 
2012aa2f8871SNiklas Söderlund 	return v4l_video_std_enumstd(p, vfd->tvnorms);
20135bc3cb74SMauro Carvalho Chehab }
20145bc3cb74SMauro Carvalho Chehab 
v4l_s_std(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)20155bc3cb74SMauro Carvalho Chehab static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
20165bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20175bc3cb74SMauro Carvalho Chehab {
20185bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2019314527acSHans Verkuil 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
202077fa4e07SShuah Khan 	int ret;
20215bc3cb74SMauro Carvalho Chehab 
202277fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
202377fa4e07SShuah Khan 	if (ret)
202477fa4e07SShuah Khan 		return ret;
2025314527acSHans Verkuil 	norm = id & vfd->tvnorms;
20265bc3cb74SMauro Carvalho Chehab 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
20275bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20285bc3cb74SMauro Carvalho Chehab 
20295bc3cb74SMauro Carvalho Chehab 	/* Calls the specific handler */
2030ca371575SHans Verkuil 	return ops->vidioc_s_std(file, fh, norm);
20315bc3cb74SMauro Carvalho Chehab }
20325bc3cb74SMauro Carvalho Chehab 
v4l_querystd(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)20335bc3cb74SMauro Carvalho Chehab static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
20345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20355bc3cb74SMauro Carvalho Chehab {
20365bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20375bc3cb74SMauro Carvalho Chehab 	v4l2_std_id *p = arg;
203877fa4e07SShuah Khan 	int ret;
20395bc3cb74SMauro Carvalho Chehab 
204077fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
204177fa4e07SShuah Khan 	if (ret)
204277fa4e07SShuah Khan 		return ret;
20435bc3cb74SMauro Carvalho Chehab 	/*
20441a2c6866SHans Verkuil 	 * If no signal is detected, then the driver should return
20451a2c6866SHans Verkuil 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
20461a2c6866SHans Verkuil 	 * any standards that do not apply removed.
20471a2c6866SHans Verkuil 	 *
20485bc3cb74SMauro Carvalho Chehab 	 * This means that tuners, audio and video decoders can join
20495bc3cb74SMauro Carvalho Chehab 	 * their efforts to improve the standards detection.
20505bc3cb74SMauro Carvalho Chehab 	 */
20515bc3cb74SMauro Carvalho Chehab 	*p = vfd->tvnorms;
20525bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_querystd(file, fh, arg);
20535bc3cb74SMauro Carvalho Chehab }
20545bc3cb74SMauro Carvalho Chehab 
v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)20555bc3cb74SMauro Carvalho Chehab static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
20565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20575bc3cb74SMauro Carvalho Chehab {
20585bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
20595bc3cb74SMauro Carvalho Chehab 	struct v4l2_hw_freq_seek *p = arg;
20605bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
206177fa4e07SShuah Khan 	int ret;
20625bc3cb74SMauro Carvalho Chehab 
206377fa4e07SShuah Khan 	ret = v4l_enable_media_source(vfd);
206477fa4e07SShuah Khan 	if (ret)
206577fa4e07SShuah Khan 		return ret;
206684099a28SAntti Palosaari 	/* s_hw_freq_seek is not supported for SDR for now */
206784099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR)
206884099a28SAntti Palosaari 		return -EINVAL;
206984099a28SAntti Palosaari 
20705bc3cb74SMauro Carvalho Chehab 	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
20715bc3cb74SMauro Carvalho Chehab 		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
20725bc3cb74SMauro Carvalho Chehab 	if (p->type != type)
20735bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
20745bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_s_hw_freq_seek(file, fh, p);
20755bc3cb74SMauro Carvalho Chehab }
20765bc3cb74SMauro Carvalho Chehab 
v4l_s_fbuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2077d04794daSHans Verkuil static int v4l_s_fbuf(const struct v4l2_ioctl_ops *ops,
2078d04794daSHans Verkuil 		      struct file *file, void *fh, void *arg)
2079d04794daSHans Verkuil {
2080d04794daSHans Verkuil 	struct v4l2_framebuffer *p = arg;
2081d04794daSHans Verkuil 
2082d04794daSHans Verkuil 	p->base = NULL;
2083d04794daSHans Verkuil 	return ops->vidioc_s_fbuf(file, fh, p);
2084d04794daSHans Verkuil }
2085d04794daSHans Verkuil 
v4l_overlay(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2086737c097bSHans Verkuil static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
2087737c097bSHans Verkuil 				struct file *file, void *fh, void *arg)
2088737c097bSHans Verkuil {
2089737c097bSHans Verkuil 	return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
2090737c097bSHans Verkuil }
2091737c097bSHans Verkuil 
v4l_reqbufs(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)20925bc3cb74SMauro Carvalho Chehab static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
20935bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
20945bc3cb74SMauro Carvalho Chehab {
20955bc3cb74SMauro Carvalho Chehab 	struct v4l2_requestbuffers *p = arg;
20964b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
20975bc3cb74SMauro Carvalho Chehab 
20985bc3cb74SMauro Carvalho Chehab 	if (ret)
20995bc3cb74SMauro Carvalho Chehab 		return ret;
2100129134e5SSergey Senozhatsky 
21010625b6b8SXiu Jianfeng 	memset_after(p, 0, flags);
2102129134e5SSergey Senozhatsky 
21035bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_reqbufs(file, fh, p);
21045bc3cb74SMauro Carvalho Chehab }
21055bc3cb74SMauro Carvalho Chehab 
v4l_querybuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21065bc3cb74SMauro Carvalho Chehab static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
21075bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21085bc3cb74SMauro Carvalho Chehab {
21095bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
21104b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21115bc3cb74SMauro Carvalho Chehab 
21125bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_querybuf(file, fh, p);
21135bc3cb74SMauro Carvalho Chehab }
21145bc3cb74SMauro Carvalho Chehab 
v4l_qbuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21155bc3cb74SMauro Carvalho Chehab static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
21165bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21175bc3cb74SMauro Carvalho Chehab {
21185bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
21194b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21205bc3cb74SMauro Carvalho Chehab 
21215bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_qbuf(file, fh, p);
21225bc3cb74SMauro Carvalho Chehab }
21235bc3cb74SMauro Carvalho Chehab 
v4l_dqbuf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21245bc3cb74SMauro Carvalho Chehab static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
21255bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21265bc3cb74SMauro Carvalho Chehab {
21275bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *p = arg;
21284b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21295bc3cb74SMauro Carvalho Chehab 
21305bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
21315bc3cb74SMauro Carvalho Chehab }
21325bc3cb74SMauro Carvalho Chehab 
v4l_create_bufs(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21335bc3cb74SMauro Carvalho Chehab static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
21345bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21355bc3cb74SMauro Carvalho Chehab {
21365bc3cb74SMauro Carvalho Chehab 	struct v4l2_create_buffers *create = arg;
21374b20259fSHans Verkuil 	int ret = check_fmt(file, create->format.type);
21385bc3cb74SMauro Carvalho Chehab 
2139d52e2381SLaurent Pinchart 	if (ret)
2140d52e2381SLaurent Pinchart 		return ret;
2141d52e2381SLaurent Pinchart 
21420625b6b8SXiu Jianfeng 	memset_after(create, 0, flags);
21435d351251SHans Verkuil 
2144d52e2381SLaurent Pinchart 	v4l_sanitize_format(&create->format);
2145d52e2381SLaurent Pinchart 
2146d52e2381SLaurent Pinchart 	ret = ops->vidioc_create_bufs(file, fh, create);
2147d52e2381SLaurent Pinchart 
2148d52e2381SLaurent Pinchart 	if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2149d52e2381SLaurent Pinchart 	    create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2150d52e2381SLaurent Pinchart 		create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
2151d52e2381SLaurent Pinchart 
2152d52e2381SLaurent Pinchart 	return ret;
21535bc3cb74SMauro Carvalho Chehab }
21545bc3cb74SMauro Carvalho Chehab 
v4l_prepare_buf(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21555bc3cb74SMauro Carvalho Chehab static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
21565bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21575bc3cb74SMauro Carvalho Chehab {
21585bc3cb74SMauro Carvalho Chehab 	struct v4l2_buffer *b = arg;
21594b20259fSHans Verkuil 	int ret = check_fmt(file, b->type);
21605bc3cb74SMauro Carvalho Chehab 
21615bc3cb74SMauro Carvalho Chehab 	return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
21625bc3cb74SMauro Carvalho Chehab }
21635bc3cb74SMauro Carvalho Chehab 
v4l_g_parm(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21645bc3cb74SMauro Carvalho Chehab static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
21655bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21665bc3cb74SMauro Carvalho Chehab {
2167cd9d9377SHans Verkuil 	struct video_device *vfd = video_devdata(file);
21685bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21695bc3cb74SMauro Carvalho Chehab 	v4l2_std_id std;
21704b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21715bc3cb74SMauro Carvalho Chehab 
21725bc3cb74SMauro Carvalho Chehab 	if (ret)
21735bc3cb74SMauro Carvalho Chehab 		return ret;
21745bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_parm)
21755bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_parm(file, fh, p);
21765bc3cb74SMauro Carvalho Chehab 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
21775bc3cb74SMauro Carvalho Chehab 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
21785bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2179cd9d9377SHans Verkuil 	if (vfd->device_caps & V4L2_CAP_READWRITE)
21805bc3cb74SMauro Carvalho Chehab 		p->parm.capture.readbuffers = 2;
21815bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_g_std(file, fh, &std);
21825bc3cb74SMauro Carvalho Chehab 	if (ret == 0)
2183ca371575SHans Verkuil 		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
21845bc3cb74SMauro Carvalho Chehab 	return ret;
21855bc3cb74SMauro Carvalho Chehab }
21865bc3cb74SMauro Carvalho Chehab 
v4l_s_parm(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)21875bc3cb74SMauro Carvalho Chehab static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
21885bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
21895bc3cb74SMauro Carvalho Chehab {
21905bc3cb74SMauro Carvalho Chehab 	struct v4l2_streamparm *p = arg;
21914b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
21925bc3cb74SMauro Carvalho Chehab 
21938a7c5594SHans Verkuil 	if (ret)
21948a7c5594SHans Verkuil 		return ret;
21958a7c5594SHans Verkuil 
21964f62e840SHans Verkuil 	/* Note: extendedmode is never used in drivers */
21978a7c5594SHans Verkuil 	if (V4L2_TYPE_IS_OUTPUT(p->type)) {
21988a7c5594SHans Verkuil 		memset(p->parm.output.reserved, 0,
21998a7c5594SHans Verkuil 		       sizeof(p->parm.output.reserved));
22008a7c5594SHans Verkuil 		p->parm.output.extendedmode = 0;
22018a7c5594SHans Verkuil 		p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY;
22028a7c5594SHans Verkuil 	} else {
22038a7c5594SHans Verkuil 		memset(p->parm.capture.reserved, 0,
22048a7c5594SHans Verkuil 		       sizeof(p->parm.capture.reserved));
22054f62e840SHans Verkuil 		p->parm.capture.extendedmode = 0;
22068a7c5594SHans Verkuil 		p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
22078a7c5594SHans Verkuil 	}
22088a7c5594SHans Verkuil 	return ops->vidioc_s_parm(file, fh, p);
22095bc3cb74SMauro Carvalho Chehab }
22105bc3cb74SMauro Carvalho Chehab 
v4l_queryctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)22115bc3cb74SMauro Carvalho Chehab static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
22125bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22135bc3cb74SMauro Carvalho Chehab {
22145bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22155bc3cb74SMauro Carvalho Chehab 	struct v4l2_queryctrl *p = arg;
22165bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22175bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22185bc3cb74SMauro Carvalho Chehab 
22195bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22205bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfh->ctrl_handler, p);
22215bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22225bc3cb74SMauro Carvalho Chehab 		return v4l2_queryctrl(vfd->ctrl_handler, p);
22235bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_queryctrl)
22245bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_queryctrl(file, fh, p);
22255bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22265bc3cb74SMauro Carvalho Chehab }
22275bc3cb74SMauro Carvalho Chehab 
v4l_query_ext_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2228e6bee368SHans Verkuil static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
2229e6bee368SHans Verkuil 				struct file *file, void *fh, void *arg)
2230e6bee368SHans Verkuil {
2231e6bee368SHans Verkuil 	struct video_device *vfd = video_devdata(file);
2232e6bee368SHans Verkuil 	struct v4l2_query_ext_ctrl *p = arg;
2233e6bee368SHans Verkuil 	struct v4l2_fh *vfh =
2234e6bee368SHans Verkuil 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
2235e6bee368SHans Verkuil 
2236e6bee368SHans Verkuil 	if (vfh && vfh->ctrl_handler)
2237e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
2238e6bee368SHans Verkuil 	if (vfd->ctrl_handler)
2239e6bee368SHans Verkuil 		return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
2240e6bee368SHans Verkuil 	if (ops->vidioc_query_ext_ctrl)
2241e6bee368SHans Verkuil 		return ops->vidioc_query_ext_ctrl(file, fh, p);
2242e6bee368SHans Verkuil 	return -ENOTTY;
2243e6bee368SHans Verkuil }
2244e6bee368SHans Verkuil 
v4l_querymenu(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)22455bc3cb74SMauro Carvalho Chehab static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
22465bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22475bc3cb74SMauro Carvalho Chehab {
22485bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22495bc3cb74SMauro Carvalho Chehab 	struct v4l2_querymenu *p = arg;
22505bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22515bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22525bc3cb74SMauro Carvalho Chehab 
22535bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22545bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfh->ctrl_handler, p);
22555bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22565bc3cb74SMauro Carvalho Chehab 		return v4l2_querymenu(vfd->ctrl_handler, p);
22575bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_querymenu)
22585bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_querymenu(file, fh, p);
22595bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
22605bc3cb74SMauro Carvalho Chehab }
22615bc3cb74SMauro Carvalho Chehab 
v4l_g_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)22625bc3cb74SMauro Carvalho Chehab static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
22635bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22645bc3cb74SMauro Carvalho Chehab {
22655bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
22665bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
22675bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
22685bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
22695bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
22705bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
22715bc3cb74SMauro Carvalho Chehab 
22725bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
22735bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfh->ctrl_handler, p);
22745bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
22755bc3cb74SMauro Carvalho Chehab 		return v4l2_g_ctrl(vfd->ctrl_handler, p);
22765bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ctrl)
22775bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_ctrl(file, fh, p);
22785bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
22795bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
22805bc3cb74SMauro Carvalho Chehab 
22810f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
22825bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
22835bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
22845bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
22855bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2286861f92cbSRicardo Ribalda 	if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
22875bc3cb74SMauro Carvalho Chehab 		int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
22885bc3cb74SMauro Carvalho Chehab 
22895bc3cb74SMauro Carvalho Chehab 		if (ret == 0)
22905bc3cb74SMauro Carvalho Chehab 			p->value = ctrl.value;
22915bc3cb74SMauro Carvalho Chehab 		return ret;
22925bc3cb74SMauro Carvalho Chehab 	}
22935bc3cb74SMauro Carvalho Chehab 	return -EINVAL;
22945bc3cb74SMauro Carvalho Chehab }
22955bc3cb74SMauro Carvalho Chehab 
v4l_s_ctrl(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)22965bc3cb74SMauro Carvalho Chehab static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
22975bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
22985bc3cb74SMauro Carvalho Chehab {
22995bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23005bc3cb74SMauro Carvalho Chehab 	struct v4l2_control *p = arg;
23015bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23025bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23035bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls ctrls;
23045bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_control ctrl;
2305c87ed935SRicardo Ribalda 	int ret;
23065bc3cb74SMauro Carvalho Chehab 
23075bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
23085bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
23095bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
23105bc3cb74SMauro Carvalho Chehab 		return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
23115bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ctrl)
23125bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_ctrl(file, fh, p);
23135bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
23145bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
23155bc3cb74SMauro Carvalho Chehab 
23160f8017beSRicardo Ribalda 	ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
23175bc3cb74SMauro Carvalho Chehab 	ctrls.count = 1;
23185bc3cb74SMauro Carvalho Chehab 	ctrls.controls = &ctrl;
23195bc3cb74SMauro Carvalho Chehab 	ctrl.id = p->id;
23205bc3cb74SMauro Carvalho Chehab 	ctrl.value = p->value;
2321c87ed935SRicardo Ribalda 	if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
23225bc3cb74SMauro Carvalho Chehab 		return -EINVAL;
2323c87ed935SRicardo Ribalda 	ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
2324c87ed935SRicardo Ribalda 	p->value = ctrl.value;
2325c87ed935SRicardo Ribalda 	return ret;
23265bc3cb74SMauro Carvalho Chehab }
23275bc3cb74SMauro Carvalho Chehab 
v4l_g_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)23285bc3cb74SMauro Carvalho Chehab static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23295bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23305bc3cb74SMauro Carvalho Chehab {
23315bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23325bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23335bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23345bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23355bc3cb74SMauro Carvalho Chehab 
23365bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23375bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2338173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
2339173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23405bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2341173f6eacSEzequiel Garcia 		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
2342173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23435bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_g_ext_ctrls == NULL)
23445bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2345861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
2346861f92cbSRicardo Ribalda 				ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
23475bc3cb74SMauro Carvalho Chehab }
23485bc3cb74SMauro Carvalho Chehab 
v4l_s_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)23495bc3cb74SMauro Carvalho Chehab static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23505bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23515bc3cb74SMauro Carvalho Chehab {
23525bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23535bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23545bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23555bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23565bc3cb74SMauro Carvalho Chehab 
23575bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23585bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2359173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
2360173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23615bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2362173f6eacSEzequiel Garcia 		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
2363173f6eacSEzequiel Garcia 					vfd, vfd->v4l2_dev->mdev, p);
23645bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_s_ext_ctrls == NULL)
23655bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2366861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
2367861f92cbSRicardo Ribalda 				ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
23685bc3cb74SMauro Carvalho Chehab }
23695bc3cb74SMauro Carvalho Chehab 
v4l_try_ext_ctrls(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)23705bc3cb74SMauro Carvalho Chehab static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
23715bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
23725bc3cb74SMauro Carvalho Chehab {
23735bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
23745bc3cb74SMauro Carvalho Chehab 	struct v4l2_ext_controls *p = arg;
23755bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh =
23765bc3cb74SMauro Carvalho Chehab 		test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
23775bc3cb74SMauro Carvalho Chehab 
23785bc3cb74SMauro Carvalho Chehab 	p->error_idx = p->count;
23795bc3cb74SMauro Carvalho Chehab 	if (vfh && vfh->ctrl_handler)
2380173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
2381173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23825bc3cb74SMauro Carvalho Chehab 	if (vfd->ctrl_handler)
2383173f6eacSEzequiel Garcia 		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
2384173f6eacSEzequiel Garcia 					  vfd, vfd->v4l2_dev->mdev, p);
23855bc3cb74SMauro Carvalho Chehab 	if (ops->vidioc_try_ext_ctrls == NULL)
23865bc3cb74SMauro Carvalho Chehab 		return -ENOTTY;
2387861f92cbSRicardo Ribalda 	return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
2388861f92cbSRicardo Ribalda 			ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
23895bc3cb74SMauro Carvalho Chehab }
23905bc3cb74SMauro Carvalho Chehab 
2391eaec420fSHans Verkuil /*
2392eaec420fSHans Verkuil  * The selection API specified originally that the _MPLANE buffer types
2393eaec420fSHans Verkuil  * shouldn't be used. The reasons for this are lost in the mists of time
2394eaec420fSHans Verkuil  * (or just really crappy memories). Regardless, this is really annoying
2395eaec420fSHans Verkuil  * for userspace. So to keep things simple we map _MPLANE buffer types
2396eaec420fSHans Verkuil  * to their 'regular' counterparts before calling the driver. And we
2397eaec420fSHans Verkuil  * restore it afterwards. This way applications can use either buffer
2398eaec420fSHans Verkuil  * type and drivers don't need to check for both.
2399eaec420fSHans Verkuil  */
v4l_g_selection(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2400eaec420fSHans Verkuil static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
2401eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2402eaec420fSHans Verkuil {
2403eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2404eaec420fSHans Verkuil 	u32 old_type = p->type;
2405eaec420fSHans Verkuil 	int ret;
2406eaec420fSHans Verkuil 
2407eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2408eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2409eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2410eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2411eaec420fSHans Verkuil 	ret = ops->vidioc_g_selection(file, fh, p);
2412eaec420fSHans Verkuil 	p->type = old_type;
2413eaec420fSHans Verkuil 	return ret;
2414eaec420fSHans Verkuil }
2415eaec420fSHans Verkuil 
v4l_s_selection(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)2416eaec420fSHans Verkuil static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
2417eaec420fSHans Verkuil 			   struct file *file, void *fh, void *arg)
2418eaec420fSHans Verkuil {
2419eaec420fSHans Verkuil 	struct v4l2_selection *p = arg;
2420eaec420fSHans Verkuil 	u32 old_type = p->type;
2421eaec420fSHans Verkuil 	int ret;
2422eaec420fSHans Verkuil 
2423eaec420fSHans Verkuil 	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2424eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2425eaec420fSHans Verkuil 	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2426eaec420fSHans Verkuil 		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2427eaec420fSHans Verkuil 	ret = ops->vidioc_s_selection(file, fh, p);
2428eaec420fSHans Verkuil 	p->type = old_type;
2429eaec420fSHans Verkuil 	return ret;
2430eaec420fSHans Verkuil }
2431eaec420fSHans Verkuil 
v4l_g_crop(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)24325bc3cb74SMauro Carvalho Chehab static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
24335bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24345bc3cb74SMauro Carvalho Chehab {
24358cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24365bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
24375bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
24385bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24395bc3cb74SMauro Carvalho Chehab 	};
24405bc3cb74SMauro Carvalho Chehab 	int ret;
24415bc3cb74SMauro Carvalho Chehab 
24425bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24435bc3cb74SMauro Carvalho Chehab 
24445bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24455bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24465b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24475bc3cb74SMauro Carvalho Chehab 	else
24485b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24495bc3cb74SMauro Carvalho Chehab 
24508cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24518cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24528cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24538cbd94bdSHans Verkuil 
2454eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
24555bc3cb74SMauro Carvalho Chehab 
24565bc3cb74SMauro Carvalho Chehab 	/* copying results to old structure on success */
24575bc3cb74SMauro Carvalho Chehab 	if (!ret)
24585bc3cb74SMauro Carvalho Chehab 		p->c = s.r;
24595bc3cb74SMauro Carvalho Chehab 	return ret;
24605bc3cb74SMauro Carvalho Chehab }
24615bc3cb74SMauro Carvalho Chehab 
v4l_s_crop(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)24625bc3cb74SMauro Carvalho Chehab static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
24635bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24645bc3cb74SMauro Carvalho Chehab {
24658cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24665bc3cb74SMauro Carvalho Chehab 	struct v4l2_crop *p = arg;
24675bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = {
24685bc3cb74SMauro Carvalho Chehab 		.type = p->type,
24695bc3cb74SMauro Carvalho Chehab 		.r = p->c,
24705bc3cb74SMauro Carvalho Chehab 	};
24715bc3cb74SMauro Carvalho Chehab 
24725bc3cb74SMauro Carvalho Chehab 	/* simulate capture crop using selection api */
24735bc3cb74SMauro Carvalho Chehab 
24745bc3cb74SMauro Carvalho Chehab 	/* crop means compose for output devices */
24755bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
24765b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_COMPOSE;
24775bc3cb74SMauro Carvalho Chehab 	else
24785b79da06SHans Verkuil 		s.target = V4L2_SEL_TGT_CROP;
24795bc3cb74SMauro Carvalho Chehab 
24808cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
24818cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
24828cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
24838cbd94bdSHans Verkuil 
2484eaec420fSHans Verkuil 	return v4l_s_selection(ops, file, fh, &s);
24855bc3cb74SMauro Carvalho Chehab }
24865bc3cb74SMauro Carvalho Chehab 
v4l_cropcap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)24875bc3cb74SMauro Carvalho Chehab static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
24885bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
24895bc3cb74SMauro Carvalho Chehab {
24908cbd94bdSHans Verkuil 	struct video_device *vfd = video_devdata(file);
24915bc3cb74SMauro Carvalho Chehab 	struct v4l2_cropcap *p = arg;
24925bc3cb74SMauro Carvalho Chehab 	struct v4l2_selection s = { .type = p->type };
249395dd7b7eSHans Verkuil 	int ret = 0;
249495dd7b7eSHans Verkuil 
249595dd7b7eSHans Verkuil 	/* setting trivial pixelaspect */
249695dd7b7eSHans Verkuil 	p->pixelaspect.numerator = 1;
249795dd7b7eSHans Verkuil 	p->pixelaspect.denominator = 1;
249895dd7b7eSHans Verkuil 
24995200ab6aSHans Verkuil 	if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
25005200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
25015200ab6aSHans Verkuil 	else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
25025200ab6aSHans Verkuil 		s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
25035200ab6aSHans Verkuil 
250495dd7b7eSHans Verkuil 	/*
250595dd7b7eSHans Verkuil 	 * The determine_valid_ioctls() call already should ensure
250695dd7b7eSHans Verkuil 	 * that this can never happen, but just in case...
250795dd7b7eSHans Verkuil 	 */
25085200ab6aSHans Verkuil 	if (WARN_ON(!ops->vidioc_g_selection))
250995dd7b7eSHans Verkuil 		return -ENOTTY;
251095dd7b7eSHans Verkuil 
25115200ab6aSHans Verkuil 	if (ops->vidioc_g_pixelaspect)
25125200ab6aSHans Verkuil 		ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
25135200ab6aSHans Verkuil 						&p->pixelaspect);
251495dd7b7eSHans Verkuil 
251595dd7b7eSHans Verkuil 	/*
251695dd7b7eSHans Verkuil 	 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
251795dd7b7eSHans Verkuil 	 * square pixel aspect ratio in that case.
251895dd7b7eSHans Verkuil 	 */
251995dd7b7eSHans Verkuil 	if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
252095dd7b7eSHans Verkuil 		return ret;
252195dd7b7eSHans Verkuil 
252295dd7b7eSHans Verkuil 	/* Use g_selection() to fill in the bounds and defrect rectangles */
25235bc3cb74SMauro Carvalho Chehab 
25245bc3cb74SMauro Carvalho Chehab 	/* obtaining bounds */
25255bc3cb74SMauro Carvalho Chehab 	if (V4L2_TYPE_IS_OUTPUT(p->type))
25265bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
25275bc3cb74SMauro Carvalho Chehab 	else
25285bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_BOUNDS;
25295bc3cb74SMauro Carvalho Chehab 
25308cbd94bdSHans Verkuil 	if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
25318cbd94bdSHans Verkuil 		s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
25328cbd94bdSHans Verkuil 			V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
25338cbd94bdSHans Verkuil 
2534eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
25355bc3cb74SMauro Carvalho Chehab 	if (ret)
25365bc3cb74SMauro Carvalho Chehab 		return ret;
25375bc3cb74SMauro Carvalho Chehab 	p->bounds = s.r;
25385bc3cb74SMauro Carvalho Chehab 
25395bc3cb74SMauro Carvalho Chehab 	/* obtaining defrect */
25408cbd94bdSHans Verkuil 	if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
25415bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
25425bc3cb74SMauro Carvalho Chehab 	else
25435bc3cb74SMauro Carvalho Chehab 		s.target = V4L2_SEL_TGT_CROP_DEFAULT;
25445bc3cb74SMauro Carvalho Chehab 
2545eaec420fSHans Verkuil 	ret = v4l_g_selection(ops, file, fh, &s);
25465bc3cb74SMauro Carvalho Chehab 	if (ret)
25475bc3cb74SMauro Carvalho Chehab 		return ret;
25485bc3cb74SMauro Carvalho Chehab 	p->defrect = s.r;
25499409945cSHans Verkuil 
25505bc3cb74SMauro Carvalho Chehab 	return 0;
25515bc3cb74SMauro Carvalho Chehab }
25525bc3cb74SMauro Carvalho Chehab 
v4l_log_status(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)25535bc3cb74SMauro Carvalho Chehab static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
25545bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25555bc3cb74SMauro Carvalho Chehab {
25565bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
25575bc3cb74SMauro Carvalho Chehab 	int ret;
25585bc3cb74SMauro Carvalho Chehab 
25595bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
25605bc3cb74SMauro Carvalho Chehab 		pr_info("%s: =================  START STATUS  =================\n",
25615bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25625bc3cb74SMauro Carvalho Chehab 	ret = ops->vidioc_log_status(file, fh);
25635bc3cb74SMauro Carvalho Chehab 	if (vfd->v4l2_dev)
25645bc3cb74SMauro Carvalho Chehab 		pr_info("%s: ==================  END STATUS  ==================\n",
25655bc3cb74SMauro Carvalho Chehab 			vfd->v4l2_dev->name);
25665bc3cb74SMauro Carvalho Chehab 	return ret;
25675bc3cb74SMauro Carvalho Chehab }
25685bc3cb74SMauro Carvalho Chehab 
v4l_dbg_g_register(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)25695bc3cb74SMauro Carvalho Chehab static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
25705bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25715bc3cb74SMauro Carvalho Chehab {
25725bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
25735bc3cb74SMauro Carvalho Chehab 	struct v4l2_dbg_register *p = arg;
257479b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
257579b0c640SHans Verkuil 	struct v4l2_subdev *sd;
257679b0c640SHans Verkuil 	int idx = 0;
25775bc3cb74SMauro Carvalho Chehab 
25785bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
25795bc3cb74SMauro Carvalho Chehab 		return -EPERM;
25803eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
258179b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
258279b0c640SHans Verkuil 			return -EINVAL;
25833eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
25843eef2510SHans Verkuil 			if (p->match.addr == idx++)
258579b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, g_register, p);
258679b0c640SHans Verkuil 		return -EINVAL;
258779b0c640SHans Verkuil 	}
2588191b79b0SHans Verkuil 	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2589191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
25905bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_g_register(file, fh, p);
259179b0c640SHans Verkuil 	return -EINVAL;
25925bc3cb74SMauro Carvalho Chehab #else
25935bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
25945bc3cb74SMauro Carvalho Chehab #endif
25955bc3cb74SMauro Carvalho Chehab }
25965bc3cb74SMauro Carvalho Chehab 
v4l_dbg_s_register(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)25975bc3cb74SMauro Carvalho Chehab static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
25985bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
25995bc3cb74SMauro Carvalho Chehab {
26005bc3cb74SMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
2601977ba3b1SHans Verkuil 	const struct v4l2_dbg_register *p = arg;
260279b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
260379b0c640SHans Verkuil 	struct v4l2_subdev *sd;
260479b0c640SHans Verkuil 	int idx = 0;
26055bc3cb74SMauro Carvalho Chehab 
26065bc3cb74SMauro Carvalho Chehab 	if (!capable(CAP_SYS_ADMIN))
26075bc3cb74SMauro Carvalho Chehab 		return -EPERM;
26083eef2510SHans Verkuil 	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV) {
260979b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
261079b0c640SHans Verkuil 			return -EINVAL;
26113eef2510SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
26123eef2510SHans Verkuil 			if (p->match.addr == idx++)
261379b0c640SHans Verkuil 				return v4l2_subdev_call(sd, core, s_register, p);
261479b0c640SHans Verkuil 		return -EINVAL;
261579b0c640SHans Verkuil 	}
2616191b79b0SHans Verkuil 	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
2617191b79b0SHans Verkuil 	    (ops->vidioc_g_chip_info || p->match.addr == 0))
26185bc3cb74SMauro Carvalho Chehab 		return ops->vidioc_s_register(file, fh, p);
261979b0c640SHans Verkuil 	return -EINVAL;
26205bc3cb74SMauro Carvalho Chehab #else
26215bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
26225bc3cb74SMauro Carvalho Chehab #endif
26235bc3cb74SMauro Carvalho Chehab }
26245bc3cb74SMauro Carvalho Chehab 
v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)262596b03d2aSHans Verkuil static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
262679b0c640SHans Verkuil 				struct file *file, void *fh, void *arg)
262779b0c640SHans Verkuil {
2628cd634f1bSHans Verkuil #ifdef CONFIG_VIDEO_ADV_DEBUG
262979b0c640SHans Verkuil 	struct video_device *vfd = video_devdata(file);
263096b03d2aSHans Verkuil 	struct v4l2_dbg_chip_info *p = arg;
263179b0c640SHans Verkuil 	struct v4l2_subdev *sd;
263279b0c640SHans Verkuil 	int idx = 0;
263379b0c640SHans Verkuil 
263479b0c640SHans Verkuil 	switch (p->match.type) {
263579b0c640SHans Verkuil 	case V4L2_CHIP_MATCH_BRIDGE:
263679b0c640SHans Verkuil 		if (ops->vidioc_s_register)
263779b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_WRITABLE;
263879b0c640SHans Verkuil 		if (ops->vidioc_g_register)
263979b0c640SHans Verkuil 			p->flags |= V4L2_CHIP_FL_READABLE;
2640c0decac1SMauro Carvalho Chehab 		strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
264196b03d2aSHans Verkuil 		if (ops->vidioc_g_chip_info)
264296b03d2aSHans Verkuil 			return ops->vidioc_g_chip_info(file, fh, arg);
26430f0fe4b9SHans Verkuil 		if (p->match.addr)
26440f0fe4b9SHans Verkuil 			return -EINVAL;
264579b0c640SHans Verkuil 		return 0;
264679b0c640SHans Verkuil 
26473eef2510SHans Verkuil 	case V4L2_CHIP_MATCH_SUBDEV:
264879b0c640SHans Verkuil 		if (vfd->v4l2_dev == NULL)
264979b0c640SHans Verkuil 			break;
265079b0c640SHans Verkuil 		v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
26513eef2510SHans Verkuil 			if (p->match.addr != idx++)
26523eef2510SHans Verkuil 				continue;
265379b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->s_register)
265479b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_WRITABLE;
265579b0c640SHans Verkuil 			if (sd->ops->core && sd->ops->core->g_register)
265679b0c640SHans Verkuil 				p->flags |= V4L2_CHIP_FL_READABLE;
2657c0decac1SMauro Carvalho Chehab 			strscpy(p->name, sd->name, sizeof(p->name));
265879b0c640SHans Verkuil 			return 0;
265979b0c640SHans Verkuil 		}
266079b0c640SHans Verkuil 		break;
266179b0c640SHans Verkuil 	}
266279b0c640SHans Verkuil 	return -EINVAL;
2663cd634f1bSHans Verkuil #else
2664cd634f1bSHans Verkuil 	return -ENOTTY;
2665cd634f1bSHans Verkuil #endif
266679b0c640SHans Verkuil }
266779b0c640SHans Verkuil 
v4l_dqevent(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)26685bc3cb74SMauro Carvalho Chehab static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
26695bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26705bc3cb74SMauro Carvalho Chehab {
26715bc3cb74SMauro Carvalho Chehab 	return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
26725bc3cb74SMauro Carvalho Chehab }
26735bc3cb74SMauro Carvalho Chehab 
v4l_subscribe_event(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)26745bc3cb74SMauro Carvalho Chehab static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
26755bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26765bc3cb74SMauro Carvalho Chehab {
26775bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_subscribe_event(fh, arg);
26785bc3cb74SMauro Carvalho Chehab }
26795bc3cb74SMauro Carvalho Chehab 
v4l_unsubscribe_event(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)26805bc3cb74SMauro Carvalho Chehab static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
26815bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26825bc3cb74SMauro Carvalho Chehab {
26835bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_unsubscribe_event(fh, arg);
26845bc3cb74SMauro Carvalho Chehab }
26855bc3cb74SMauro Carvalho Chehab 
v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)26865bc3cb74SMauro Carvalho Chehab static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
26875bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
26885bc3cb74SMauro Carvalho Chehab {
26895bc3cb74SMauro Carvalho Chehab 	struct v4l2_sliced_vbi_cap *p = arg;
26904b20259fSHans Verkuil 	int ret = check_fmt(file, p->type);
26914b20259fSHans Verkuil 
26924b20259fSHans Verkuil 	if (ret)
26934b20259fSHans Verkuil 		return ret;
26945bc3cb74SMauro Carvalho Chehab 
26955bc3cb74SMauro Carvalho Chehab 	/* Clear up to type, everything after type is zeroed already */
26965bc3cb74SMauro Carvalho Chehab 	memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
26975bc3cb74SMauro Carvalho Chehab 
26985bc3cb74SMauro Carvalho Chehab 	return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
26995bc3cb74SMauro Carvalho Chehab }
27005bc3cb74SMauro Carvalho Chehab 
v4l_enum_freq_bands(const struct v4l2_ioctl_ops * ops,struct file * file,void * fh,void * arg)27015bc3cb74SMauro Carvalho Chehab static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
27025bc3cb74SMauro Carvalho Chehab 				struct file *file, void *fh, void *arg)
27035bc3cb74SMauro Carvalho Chehab {
27045bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
27055bc3cb74SMauro Carvalho Chehab 	struct v4l2_frequency_band *p = arg;
27065bc3cb74SMauro Carvalho Chehab 	enum v4l2_tuner_type type;
27075bc3cb74SMauro Carvalho Chehab 	int err;
27085bc3cb74SMauro Carvalho Chehab 
270984099a28SAntti Palosaari 	if (vfd->vfl_type == VFL_TYPE_SDR) {
2710f3c3ececSAntti Palosaari 		if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
271184099a28SAntti Palosaari 			return -EINVAL;
271284099a28SAntti Palosaari 		type = p->type;
271384099a28SAntti Palosaari 	} else {
27145bc3cb74SMauro Carvalho Chehab 		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
27155bc3cb74SMauro Carvalho Chehab 				V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
27165bc3cb74SMauro Carvalho Chehab 		if (type != p->type)
27175bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
271884099a28SAntti Palosaari 	}
2719a7f404afSHans Verkuil 	if (ops->vidioc_enum_freq_bands) {
2720a7f404afSHans Verkuil 		err = ops->vidioc_enum_freq_bands(file, fh, p);
2721a7f404afSHans Verkuil 		if (err != -ENOTTY)
2722a7f404afSHans Verkuil 			return err;
2723a7f404afSHans Verkuil 	}
272473f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
27255bc3cb74SMauro Carvalho Chehab 		struct v4l2_tuner t = {
27265bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
27275bc3cb74SMauro Carvalho Chehab 			.type = type,
27285bc3cb74SMauro Carvalho Chehab 		};
27295bc3cb74SMauro Carvalho Chehab 
273079e8c7beSMauro Carvalho Chehab 		if (p->index)
273179e8c7beSMauro Carvalho Chehab 			return -EINVAL;
27325bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_tuner(file, fh, &t);
27335bc3cb74SMauro Carvalho Chehab 		if (err)
27345bc3cb74SMauro Carvalho Chehab 			return err;
27355bc3cb74SMauro Carvalho Chehab 		p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
27365bc3cb74SMauro Carvalho Chehab 		p->rangelow = t.rangelow;
27375bc3cb74SMauro Carvalho Chehab 		p->rangehigh = t.rangehigh;
27385bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
27395bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
27405bc3cb74SMauro Carvalho Chehab 		return 0;
27415bc3cb74SMauro Carvalho Chehab 	}
274273f35418SHans Verkuil 	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
27435bc3cb74SMauro Carvalho Chehab 		struct v4l2_modulator m = {
27445bc3cb74SMauro Carvalho Chehab 			.index = p->tuner,
27455bc3cb74SMauro Carvalho Chehab 		};
27465bc3cb74SMauro Carvalho Chehab 
27475bc3cb74SMauro Carvalho Chehab 		if (type != V4L2_TUNER_RADIO)
27485bc3cb74SMauro Carvalho Chehab 			return -EINVAL;
274979e8c7beSMauro Carvalho Chehab 		if (p->index)
275079e8c7beSMauro Carvalho Chehab 			return -EINVAL;
27515bc3cb74SMauro Carvalho Chehab 		err = ops->vidioc_g_modulator(file, fh, &m);
27525bc3cb74SMauro Carvalho Chehab 		if (err)
27535bc3cb74SMauro Carvalho Chehab 			return err;
27545bc3cb74SMauro Carvalho Chehab 		p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
27555bc3cb74SMauro Carvalho Chehab 		p->rangelow = m.rangelow;
27565bc3cb74SMauro Carvalho Chehab 		p->rangehigh = m.rangehigh;
27575bc3cb74SMauro Carvalho Chehab 		p->modulation = (type == V4L2_TUNER_RADIO) ?
27585bc3cb74SMauro Carvalho Chehab 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
27595bc3cb74SMauro Carvalho Chehab 		return 0;
27605bc3cb74SMauro Carvalho Chehab 	}
27615bc3cb74SMauro Carvalho Chehab 	return -ENOTTY;
27625bc3cb74SMauro Carvalho Chehab }
27635bc3cb74SMauro Carvalho Chehab 
27645bc3cb74SMauro Carvalho Chehab struct v4l2_ioctl_info {
27655bc3cb74SMauro Carvalho Chehab 	unsigned int ioctl;
27665bc3cb74SMauro Carvalho Chehab 	u32 flags;
27675bc3cb74SMauro Carvalho Chehab 	const char * const name;
27683ad3b7a2SSami Tolvanen 	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
27693ad3b7a2SSami Tolvanen 		    void *fh, void *p);
27705bc3cb74SMauro Carvalho Chehab 	void (*debug)(const void *arg, bool write_only);
27715bc3cb74SMauro Carvalho Chehab };
27725bc3cb74SMauro Carvalho Chehab 
27735bc3cb74SMauro Carvalho Chehab /* This control needs a priority check */
27745bc3cb74SMauro Carvalho Chehab #define INFO_FL_PRIO		(1 << 0)
27755bc3cb74SMauro Carvalho Chehab /* This control can be valid if the filehandle passes a control handler. */
27765bc3cb74SMauro Carvalho Chehab #define INFO_FL_CTRL		(1 << 1)
27775bc3cb74SMauro Carvalho Chehab /* Queuing ioctl */
27783ad3b7a2SSami Tolvanen #define INFO_FL_QUEUE		(1 << 2)
2779043f77edSHans Verkuil /* Always copy back result, even on error */
27803ad3b7a2SSami Tolvanen #define INFO_FL_ALWAYS_COPY	(1 << 3)
27815bc3cb74SMauro Carvalho Chehab /* Zero struct from after the field to the end */
27825bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR(v4l2_struct, field)			\
27835bc3cb74SMauro Carvalho Chehab 	((offsetof(struct v4l2_struct, field) +			\
2784c593642cSPankaj Bharadiya 	  sizeof_field(struct v4l2_struct, field)) << 16)
27855bc3cb74SMauro Carvalho Chehab #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
27865bc3cb74SMauro Carvalho Chehab 
27873ad3b7a2SSami Tolvanen #define DEFINE_V4L_STUB_FUNC(_vidioc)				\
27883ad3b7a2SSami Tolvanen 	static int v4l_stub_ ## _vidioc(			\
27893ad3b7a2SSami Tolvanen 			const struct v4l2_ioctl_ops *ops,	\
27903ad3b7a2SSami Tolvanen 			struct file *file, void *fh, void *p)	\
27913ad3b7a2SSami Tolvanen 	{							\
27923ad3b7a2SSami Tolvanen 		return ops->vidioc_ ## _vidioc(file, fh, p);	\
27933ad3b7a2SSami Tolvanen 	}
27943ad3b7a2SSami Tolvanen 
27953ad3b7a2SSami Tolvanen #define IOCTL_INFO(_ioctl, _func, _debug, _flags)		\
27965bc3cb74SMauro Carvalho Chehab 	[_IOC_NR(_ioctl)] = {					\
27975bc3cb74SMauro Carvalho Chehab 		.ioctl = _ioctl,				\
27983ad3b7a2SSami Tolvanen 		.flags = _flags,				\
27995bc3cb74SMauro Carvalho Chehab 		.name = #_ioctl,				\
28003ad3b7a2SSami Tolvanen 		.func = _func,					\
28015bc3cb74SMauro Carvalho Chehab 		.debug = _debug,				\
28025bc3cb74SMauro Carvalho Chehab 	}
28035bc3cb74SMauro Carvalho Chehab 
28043ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_fbuf)
28053ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(expbuf)
28063ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_std)
28073ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audio)
28083ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audio)
28093ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_edid)
28103ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_edid)
28113ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_audout)
28123ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_audout)
28133ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_jpegcomp)
28143ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_jpegcomp)
28153ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudio)
28163ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enumaudout)
28173ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_framesizes)
28183ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_frameintervals)
28193ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_enc_index)
28203ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(encoder_cmd)
28213ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_encoder_cmd)
28223ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(decoder_cmd)
28233ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(try_decoder_cmd)
28243ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(s_dv_timings)
28253ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(g_dv_timings)
28263ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(enum_dv_timings)
28273ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(query_dv_timings)
28283ad3b7a2SSami Tolvanen DEFINE_V4L_STUB_FUNC(dv_timings_cap)
28295bc3cb74SMauro Carvalho Chehab 
28307c91d0a4SEric Biggers static const struct v4l2_ioctl_info v4l2_ioctls[] = {
28313ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
2832e5b6b07aSLaurent Pinchart 	IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0),
28333ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
28343ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
28353ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
28363ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
28373ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FBUF, v4l_stub_g_fbuf, v4l_print_framebuffer, 0),
2838d04794daSHans Verkuil 	IOCTL_INFO(VIDIOC_S_FBUF, v4l_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
28393ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
28403ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
28413ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_EXPBUF, v4l_stub_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
28423ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
28433ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
28443ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
28453ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
28463ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
28473ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_STD, v4l_stub_g_std, v4l_print_std, 0),
28483ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
28493ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
28503ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
28513ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
28523ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
28533ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
28543ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
28553ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDIO, v4l_stub_g_audio, v4l_print_audio, 0),
28563ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
28573ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
28583ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
2859f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0),
28603ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
28613ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
28623ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY),
2863f645e625SNiklas Söderlund 	IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0),
28643ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
28653ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
28663ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
28673ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_AUDOUT, v4l_stub_s_audout, v4l_print_audioout, INFO_FL_PRIO),
28683ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
28693ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
28703ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
28713ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
28723ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
28733ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
28743ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
28753ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_SELECTION, v4l_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
28763ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_SELECTION, v4l_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
28773ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_JPEGCOMP, v4l_stub_g_jpegcomp, v4l_print_jpegcompression, 0),
28783ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_JPEGCOMP, v4l_stub_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
28793ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
28803ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
28813ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDIO, v4l_stub_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
28823ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUMAUDOUT, v4l_stub_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
28833ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
28843ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
28853ad3b7a2SSami 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)),
28863ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
2887f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
2888f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
2889f0da34f3SHans Verkuil 	IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL | INFO_FL_ALWAYS_COPY),
28903ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, v4l_stub_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
28913ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, v4l_stub_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
28923ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_ENC_INDEX, v4l_stub_g_enc_index, v4l_print_enc_idx, 0),
28933ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENCODER_CMD, v4l_stub_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28943ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, v4l_stub_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
28953ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DECODER_CMD, v4l_stub_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
28963ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, v4l_stub_try_decoder_cmd, v4l_print_decoder_cmd, 0),
28973ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
28983ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
28993ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
29003ad3b7a2SSami 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)),
29013ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_G_DV_TIMINGS, v4l_stub_g_dv_timings, v4l_print_dv_timings, 0),
29023ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
29033ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
29043ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
29053ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
29063ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
29073ad3b7a2SSami 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)),
29083ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, v4l_stub_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY),
29093ad3b7a2SSami 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)),
29103ad3b7a2SSami Tolvanen 	IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
29113ad3b7a2SSami 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)),
29123ad3b7a2SSami 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)),
29135bc3cb74SMauro Carvalho Chehab };
29145bc3cb74SMauro Carvalho Chehab #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
29155bc3cb74SMauro Carvalho Chehab 
v4l2_is_known_ioctl(unsigned int cmd)291673a11062SHans Verkuil static bool v4l2_is_known_ioctl(unsigned int cmd)
29175bc3cb74SMauro Carvalho Chehab {
29185bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
29195bc3cb74SMauro Carvalho Chehab 		return false;
29205bc3cb74SMauro Carvalho Chehab 	return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
29215bc3cb74SMauro Carvalho Chehab }
29225bc3cb74SMauro Carvalho Chehab 
v4l2_ioctl_get_lock(struct video_device * vdev,struct v4l2_fh * vfh,unsigned int cmd,void * arg)292373a11062SHans Verkuil static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
2924d862bc08SHans Verkuil 					 struct v4l2_fh *vfh, unsigned int cmd,
2925d862bc08SHans Verkuil 					 void *arg)
29265bc3cb74SMauro Carvalho Chehab {
29275bc3cb74SMauro Carvalho Chehab 	if (_IOC_NR(cmd) >= V4L2_IOCTLS)
29285bc3cb74SMauro Carvalho Chehab 		return vdev->lock;
2929d862bc08SHans Verkuil 	if (vfh && vfh->m2m_ctx &&
2930d862bc08SHans Verkuil 	    (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) {
2931542a522dSEzequiel Garcia 		if (vfh->m2m_ctx->q_lock)
2932542a522dSEzequiel Garcia 			return vfh->m2m_ctx->q_lock;
2933d862bc08SHans Verkuil 	}
29345bc3cb74SMauro Carvalho Chehab 	if (vdev->queue && vdev->queue->lock &&
29355bc3cb74SMauro Carvalho Chehab 			(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
29365bc3cb74SMauro Carvalho Chehab 		return vdev->queue->lock;
29375bc3cb74SMauro Carvalho Chehab 	return vdev->lock;
29385bc3cb74SMauro Carvalho Chehab }
29395bc3cb74SMauro Carvalho Chehab 
29405bc3cb74SMauro Carvalho Chehab /* Common ioctl debug function. This function can be used by
29415bc3cb74SMauro Carvalho Chehab    external ioctl messages as well as internal V4L ioctl */
v4l_printk_ioctl(const char * prefix,unsigned int cmd)29425bc3cb74SMauro Carvalho Chehab void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
29435bc3cb74SMauro Carvalho Chehab {
29445bc3cb74SMauro Carvalho Chehab 	const char *dir, *type;
29455bc3cb74SMauro Carvalho Chehab 
29465bc3cb74SMauro Carvalho Chehab 	if (prefix)
29475bc3cb74SMauro Carvalho Chehab 		printk(KERN_DEBUG "%s: ", prefix);
29485bc3cb74SMauro Carvalho Chehab 
29495bc3cb74SMauro Carvalho Chehab 	switch (_IOC_TYPE(cmd)) {
29505bc3cb74SMauro Carvalho Chehab 	case 'd':
29515bc3cb74SMauro Carvalho Chehab 		type = "v4l2_int";
29525bc3cb74SMauro Carvalho Chehab 		break;
29535bc3cb74SMauro Carvalho Chehab 	case 'V':
29545bc3cb74SMauro Carvalho Chehab 		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
29555bc3cb74SMauro Carvalho Chehab 			type = "v4l2";
29565bc3cb74SMauro Carvalho Chehab 			break;
29575bc3cb74SMauro Carvalho Chehab 		}
29585bc3cb74SMauro Carvalho Chehab 		pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
29595bc3cb74SMauro Carvalho Chehab 		return;
29605bc3cb74SMauro Carvalho Chehab 	default:
29615bc3cb74SMauro Carvalho Chehab 		type = "unknown";
29625bc3cb74SMauro Carvalho Chehab 		break;
29635bc3cb74SMauro Carvalho Chehab 	}
29645bc3cb74SMauro Carvalho Chehab 
29655bc3cb74SMauro Carvalho Chehab 	switch (_IOC_DIR(cmd)) {
29665bc3cb74SMauro Carvalho Chehab 	case _IOC_NONE:              dir = "--"; break;
29675bc3cb74SMauro Carvalho Chehab 	case _IOC_READ:              dir = "r-"; break;
29685bc3cb74SMauro Carvalho Chehab 	case _IOC_WRITE:             dir = "-w"; break;
29695bc3cb74SMauro Carvalho Chehab 	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
29705bc3cb74SMauro Carvalho Chehab 	default:                     dir = "*ERR*"; break;
29715bc3cb74SMauro Carvalho Chehab 	}
29725bc3cb74SMauro Carvalho Chehab 	pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
29735bc3cb74SMauro Carvalho Chehab 		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
29745bc3cb74SMauro Carvalho Chehab }
29755bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(v4l_printk_ioctl);
29765bc3cb74SMauro Carvalho Chehab 
__video_do_ioctl(struct file * file,unsigned int cmd,void * arg)29775bc3cb74SMauro Carvalho Chehab static long __video_do_ioctl(struct file *file,
29785bc3cb74SMauro Carvalho Chehab 		unsigned int cmd, void *arg)
29795bc3cb74SMauro Carvalho Chehab {
29805bc3cb74SMauro Carvalho Chehab 	struct video_device *vfd = video_devdata(file);
2981cc6eddcdSHans Verkuil 	struct mutex *req_queue_lock = NULL;
298273a11062SHans Verkuil 	struct mutex *lock; /* ioctl serialization mutex */
29835bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
29845bc3cb74SMauro Carvalho Chehab 	bool write_only = false;
29855bc3cb74SMauro Carvalho Chehab 	struct v4l2_ioctl_info default_info;
29865bc3cb74SMauro Carvalho Chehab 	const struct v4l2_ioctl_info *info;
29875bc3cb74SMauro Carvalho Chehab 	void *fh = file->private_data;
29885bc3cb74SMauro Carvalho Chehab 	struct v4l2_fh *vfh = NULL;
298917028cdbSHans Verkuil 	int dev_debug = vfd->dev_debug;
29905bc3cb74SMauro Carvalho Chehab 	long ret = -ENOTTY;
29915bc3cb74SMauro Carvalho Chehab 
29925bc3cb74SMauro Carvalho Chehab 	if (ops == NULL) {
29935bc3cb74SMauro Carvalho Chehab 		pr_warn("%s: has no ioctl_ops.\n",
29945bc3cb74SMauro Carvalho Chehab 				video_device_node_name(vfd));
29955bc3cb74SMauro Carvalho Chehab 		return ret;
29965bc3cb74SMauro Carvalho Chehab 	}
29975bc3cb74SMauro Carvalho Chehab 
2998b7284bb0SRamakrishnan Muthukrishnan 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
29995bc3cb74SMauro Carvalho Chehab 		vfh = file->private_data;
30005bc3cb74SMauro Carvalho Chehab 
3001cc6eddcdSHans Verkuil 	/*
3002cc6eddcdSHans Verkuil 	 * We need to serialize streamon/off with queueing new requests.
3003cc6eddcdSHans Verkuil 	 * These ioctls may trigger the cancellation of a streaming
3004cc6eddcdSHans Verkuil 	 * operation, and that should not be mixed with queueing a new
3005cc6eddcdSHans Verkuil 	 * request at the same time.
3006cc6eddcdSHans Verkuil 	 */
3007cc6eddcdSHans Verkuil 	if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
3008cc6eddcdSHans Verkuil 	    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
3009cc6eddcdSHans Verkuil 		req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
3010cc6eddcdSHans Verkuil 
3011cc6eddcdSHans Verkuil 		if (mutex_lock_interruptible(req_queue_lock))
3012cc6eddcdSHans Verkuil 			return -ERESTARTSYS;
3013cc6eddcdSHans Verkuil 	}
3014cc6eddcdSHans Verkuil 
3015d862bc08SHans Verkuil 	lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
301673a11062SHans Verkuil 
3017cc6eddcdSHans Verkuil 	if (lock && mutex_lock_interruptible(lock)) {
3018cc6eddcdSHans Verkuil 		if (req_queue_lock)
3019cc6eddcdSHans Verkuil 			mutex_unlock(req_queue_lock);
302073a11062SHans Verkuil 		return -ERESTARTSYS;
3021cc6eddcdSHans Verkuil 	}
302273a11062SHans Verkuil 
302373a11062SHans Verkuil 	if (!video_is_registered(vfd)) {
302473a11062SHans Verkuil 		ret = -ENODEV;
302573a11062SHans Verkuil 		goto unlock;
302673a11062SHans Verkuil 	}
302773a11062SHans Verkuil 
30285bc3cb74SMauro Carvalho Chehab 	if (v4l2_is_known_ioctl(cmd)) {
30295bc3cb74SMauro Carvalho Chehab 		info = &v4l2_ioctls[_IOC_NR(cmd)];
30305bc3cb74SMauro Carvalho Chehab 
30315bc3cb74SMauro Carvalho Chehab 		if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
30325bc3cb74SMauro Carvalho Chehab 		    !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
30335bc3cb74SMauro Carvalho Chehab 			goto done;
30345bc3cb74SMauro Carvalho Chehab 
3035b7284bb0SRamakrishnan Muthukrishnan 		if (vfh && (info->flags & INFO_FL_PRIO)) {
30365bc3cb74SMauro Carvalho Chehab 			ret = v4l2_prio_check(vfd->prio, vfh->prio);
30375bc3cb74SMauro Carvalho Chehab 			if (ret)
30385bc3cb74SMauro Carvalho Chehab 				goto done;
30395bc3cb74SMauro Carvalho Chehab 		}
30405bc3cb74SMauro Carvalho Chehab 	} else {
30415bc3cb74SMauro Carvalho Chehab 		default_info.ioctl = cmd;
30425bc3cb74SMauro Carvalho Chehab 		default_info.flags = 0;
30435bc3cb74SMauro Carvalho Chehab 		default_info.debug = v4l_print_default;
30445bc3cb74SMauro Carvalho Chehab 		info = &default_info;
30455bc3cb74SMauro Carvalho Chehab 	}
30465bc3cb74SMauro Carvalho Chehab 
30475bc3cb74SMauro Carvalho Chehab 	write_only = _IOC_DIR(cmd) == _IOC_WRITE;
30483ad3b7a2SSami Tolvanen 	if (info != &default_info) {
30493ad3b7a2SSami Tolvanen 		ret = info->func(ops, file, fh, arg);
30505bc3cb74SMauro Carvalho Chehab 	} else if (!ops->vidioc_default) {
30515bc3cb74SMauro Carvalho Chehab 		ret = -ENOTTY;
30525bc3cb74SMauro Carvalho Chehab 	} else {
30535bc3cb74SMauro Carvalho Chehab 		ret = ops->vidioc_default(file, fh,
3054b7284bb0SRamakrishnan Muthukrishnan 			vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
30555bc3cb74SMauro Carvalho Chehab 			cmd, arg);
30565bc3cb74SMauro Carvalho Chehab 	}
30575bc3cb74SMauro Carvalho Chehab 
30585bc3cb74SMauro Carvalho Chehab done:
305917028cdbSHans Verkuil 	if (dev_debug & (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG)) {
306017028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_STREAMING) &&
306117028cdbSHans Verkuil 		    (cmd == VIDIOC_QBUF || cmd == VIDIOC_DQBUF))
30625983d3bcSHans Verkuil 			goto unlock;
306317028cdbSHans Verkuil 
30645bc3cb74SMauro Carvalho Chehab 		v4l_printk_ioctl(video_device_node_name(vfd), cmd);
30655bc3cb74SMauro Carvalho Chehab 		if (ret < 0)
3066505d04bdSHans Verkuil 			pr_cont(": error %ld", ret);
306717028cdbSHans Verkuil 		if (!(dev_debug & V4L2_DEV_DEBUG_IOCTL_ARG))
30685bc3cb74SMauro Carvalho Chehab 			pr_cont("\n");
30695bc3cb74SMauro Carvalho Chehab 		else if (_IOC_DIR(cmd) == _IOC_NONE)
30705bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30715bc3cb74SMauro Carvalho Chehab 		else {
30725bc3cb74SMauro Carvalho Chehab 			pr_cont(": ");
30735bc3cb74SMauro Carvalho Chehab 			info->debug(arg, write_only);
30745bc3cb74SMauro Carvalho Chehab 		}
30755bc3cb74SMauro Carvalho Chehab 	}
30765bc3cb74SMauro Carvalho Chehab 
307773a11062SHans Verkuil unlock:
307873a11062SHans Verkuil 	if (lock)
307973a11062SHans Verkuil 		mutex_unlock(lock);
3080cc6eddcdSHans Verkuil 	if (req_queue_lock)
3081cc6eddcdSHans Verkuil 		mutex_unlock(req_queue_lock);
30825bc3cb74SMauro Carvalho Chehab 	return ret;
30835bc3cb74SMauro Carvalho Chehab }
30845bc3cb74SMauro Carvalho Chehab 
check_array_args(unsigned int cmd,void * parg,size_t * array_size,void __user ** user_ptr,void *** kernel_ptr)30855bc3cb74SMauro Carvalho Chehab static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
3086ba2d35c1SHans Verkuil 			    void __user **user_ptr, void ***kernel_ptr)
30875bc3cb74SMauro Carvalho Chehab {
30885bc3cb74SMauro Carvalho Chehab 	int ret = 0;
30895bc3cb74SMauro Carvalho Chehab 
30905bc3cb74SMauro Carvalho Chehab 	switch (cmd) {
309196b1a702SHans Verkuil 	case VIDIOC_PREPARE_BUF:
30925bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QUERYBUF:
30935bc3cb74SMauro Carvalho Chehab 	case VIDIOC_QBUF:
30945bc3cb74SMauro Carvalho Chehab 	case VIDIOC_DQBUF: {
30955bc3cb74SMauro Carvalho Chehab 		struct v4l2_buffer *buf = parg;
30965bc3cb74SMauro Carvalho Chehab 
30975bc3cb74SMauro Carvalho Chehab 		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
30985bc3cb74SMauro Carvalho Chehab 			if (buf->length > VIDEO_MAX_PLANES) {
30995bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
31005bc3cb74SMauro Carvalho Chehab 				break;
31015bc3cb74SMauro Carvalho Chehab 			}
31025bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)buf->m.planes;
3103ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&buf->m.planes;
31045bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_plane) * buf->length;
31055bc3cb74SMauro Carvalho Chehab 			ret = 1;
31065bc3cb74SMauro Carvalho Chehab 		}
31075bc3cb74SMauro Carvalho Chehab 		break;
31085bc3cb74SMauro Carvalho Chehab 	}
31095bc3cb74SMauro Carvalho Chehab 
3110dd519bb3SHans Verkuil 	case VIDIOC_G_EDID:
3111dd519bb3SHans Verkuil 	case VIDIOC_S_EDID: {
3112dd519bb3SHans Verkuil 		struct v4l2_edid *edid = parg;
3113ed45ce2cSHans Verkuil 
3114ed45ce2cSHans Verkuil 		if (edid->blocks) {
31151b8b10ccSHans Verkuil 			if (edid->blocks > 256) {
31161b8b10ccSHans Verkuil 				ret = -EINVAL;
31171b8b10ccSHans Verkuil 				break;
31181b8b10ccSHans Verkuil 			}
3119ed45ce2cSHans Verkuil 			*user_ptr = (void __user *)edid->edid;
3120ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&edid->edid;
3121ed45ce2cSHans Verkuil 			*array_size = edid->blocks * 128;
3122ed45ce2cSHans Verkuil 			ret = 1;
3123ed45ce2cSHans Verkuil 		}
3124ed45ce2cSHans Verkuil 		break;
3125ed45ce2cSHans Verkuil 	}
3126ed45ce2cSHans Verkuil 
31275bc3cb74SMauro Carvalho Chehab 	case VIDIOC_S_EXT_CTRLS:
31285bc3cb74SMauro Carvalho Chehab 	case VIDIOC_G_EXT_CTRLS:
31295bc3cb74SMauro Carvalho Chehab 	case VIDIOC_TRY_EXT_CTRLS: {
31305bc3cb74SMauro Carvalho Chehab 		struct v4l2_ext_controls *ctrls = parg;
31315bc3cb74SMauro Carvalho Chehab 
31325bc3cb74SMauro Carvalho Chehab 		if (ctrls->count != 0) {
31335bc3cb74SMauro Carvalho Chehab 			if (ctrls->count > V4L2_CID_MAX_CTRLS) {
31345bc3cb74SMauro Carvalho Chehab 				ret = -EINVAL;
31355bc3cb74SMauro Carvalho Chehab 				break;
31365bc3cb74SMauro Carvalho Chehab 			}
31375bc3cb74SMauro Carvalho Chehab 			*user_ptr = (void __user *)ctrls->controls;
3138ba2d35c1SHans Verkuil 			*kernel_ptr = (void **)&ctrls->controls;
31395bc3cb74SMauro Carvalho Chehab 			*array_size = sizeof(struct v4l2_ext_control)
31405bc3cb74SMauro Carvalho Chehab 				    * ctrls->count;
31415bc3cb74SMauro Carvalho Chehab 			ret = 1;
31425bc3cb74SMauro Carvalho Chehab 		}
31435bc3cb74SMauro Carvalho Chehab 		break;
31445bc3cb74SMauro Carvalho Chehab 	}
3145a418bb3fSLaurent Pinchart 
3146a418bb3fSLaurent Pinchart 	case VIDIOC_SUBDEV_G_ROUTING:
3147a418bb3fSLaurent Pinchart 	case VIDIOC_SUBDEV_S_ROUTING: {
3148a418bb3fSLaurent Pinchart 		struct v4l2_subdev_routing *routing = parg;
3149a418bb3fSLaurent Pinchart 
3150a418bb3fSLaurent Pinchart 		if (routing->num_routes > 256)
3151a418bb3fSLaurent Pinchart 			return -E2BIG;
3152a418bb3fSLaurent Pinchart 
3153a418bb3fSLaurent Pinchart 		*user_ptr = u64_to_user_ptr(routing->routes);
3154a418bb3fSLaurent Pinchart 		*kernel_ptr = (void **)&routing->routes;
3155a418bb3fSLaurent Pinchart 		*array_size = sizeof(struct v4l2_subdev_route)
3156a418bb3fSLaurent Pinchart 			    * routing->num_routes;
3157a418bb3fSLaurent Pinchart 		ret = 1;
3158a418bb3fSLaurent Pinchart 		break;
3159a418bb3fSLaurent Pinchart 	}
31605bc3cb74SMauro Carvalho Chehab 	}
31615bc3cb74SMauro Carvalho Chehab 
31625bc3cb74SMauro Carvalho Chehab 	return ret;
31635bc3cb74SMauro Carvalho Chehab }
31645bc3cb74SMauro Carvalho Chehab 
video_translate_cmd(unsigned int cmd)3165c8ef1a60SArnd Bergmann static unsigned int video_translate_cmd(unsigned int cmd)
3166c8ef1a60SArnd Bergmann {
3167c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
31681a6c0b36SArnd Bergmann 	switch (cmd) {
31691a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32:
31701a6c0b36SArnd Bergmann 		return VIDIOC_DQEVENT;
3171577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3172577c89b0SArnd Bergmann 		return VIDIOC_QUERYBUF;
3173577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3174577c89b0SArnd Bergmann 		return VIDIOC_QBUF;
3175577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3176577c89b0SArnd Bergmann 		return VIDIOC_DQBUF;
3177577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32:
3178577c89b0SArnd Bergmann 		return VIDIOC_PREPARE_BUF;
31791a6c0b36SArnd Bergmann 	}
3180c344f07aSArnd Bergmann #endif
31818dbcc3faSArnd Bergmann 	if (in_compat_syscall())
31828dbcc3faSArnd Bergmann 		return v4l2_compat_translate_cmd(cmd);
31831a6c0b36SArnd Bergmann 
3184c8ef1a60SArnd Bergmann 	return cmd;
3185c8ef1a60SArnd Bergmann }
3186c8ef1a60SArnd Bergmann 
video_get_user(void __user * arg,void * parg,unsigned int real_cmd,unsigned int cmd,bool * always_copy)31878dbcc3faSArnd Bergmann static int video_get_user(void __user *arg, void *parg,
31888dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd,
3189c8ef1a60SArnd Bergmann 			  bool *always_copy)
3190c8ef1a60SArnd Bergmann {
31918dbcc3faSArnd Bergmann 	unsigned int n = _IOC_SIZE(real_cmd);
31928dbcc3faSArnd Bergmann 	int err = 0;
3193c8ef1a60SArnd Bergmann 
3194c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
3195c8ef1a60SArnd Bergmann 		/* read-only ioctl */
3196c8ef1a60SArnd Bergmann 		memset(parg, 0, n);
3197c8ef1a60SArnd Bergmann 		return 0;
3198c8ef1a60SArnd Bergmann 	}
3199c8ef1a60SArnd Bergmann 
32008dbcc3faSArnd Bergmann 	/*
32018dbcc3faSArnd Bergmann 	 * In some cases, only a few fields are used as input,
32028dbcc3faSArnd Bergmann 	 * i.e. when the app sets "index" and then the driver
32038dbcc3faSArnd Bergmann 	 * fills in the rest of the structure for the thing
32048dbcc3faSArnd Bergmann 	 * with that index.  We only need to copy up the first
32058dbcc3faSArnd Bergmann 	 * non-input field.
32068dbcc3faSArnd Bergmann 	 */
32078dbcc3faSArnd Bergmann 	if (v4l2_is_known_ioctl(real_cmd)) {
32088dbcc3faSArnd Bergmann 		u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
32098dbcc3faSArnd Bergmann 
32108dbcc3faSArnd Bergmann 		if (flags & INFO_FL_CLEAR_MASK)
32118dbcc3faSArnd Bergmann 			n = (flags & INFO_FL_CLEAR_MASK) >> 16;
32128dbcc3faSArnd Bergmann 		*always_copy = flags & INFO_FL_ALWAYS_COPY;
32138dbcc3faSArnd Bergmann 	}
32148dbcc3faSArnd Bergmann 
32158dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32168dbcc3faSArnd Bergmann 		if (copy_from_user(parg, (void __user *)arg, n))
32178dbcc3faSArnd Bergmann 			err = -EFAULT;
32188dbcc3faSArnd Bergmann 	} else if (in_compat_syscall()) {
32197b53cca7SArnd Bergmann 		memset(parg, 0, n);
32208dbcc3faSArnd Bergmann 		err = v4l2_compat_get_user(arg, parg, cmd);
32218dbcc3faSArnd Bergmann 	} else {
32227b53cca7SArnd Bergmann 		memset(parg, 0, n);
3223c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3224c8ef1a60SArnd Bergmann 		switch (cmd) {
3225577c89b0SArnd Bergmann 		case VIDIOC_QUERYBUF_TIME32:
3226577c89b0SArnd Bergmann 		case VIDIOC_QBUF_TIME32:
3227577c89b0SArnd Bergmann 		case VIDIOC_DQBUF_TIME32:
3228577c89b0SArnd Bergmann 		case VIDIOC_PREPARE_BUF_TIME32: {
3229577c89b0SArnd Bergmann 			struct v4l2_buffer_time32 vb32;
3230577c89b0SArnd Bergmann 			struct v4l2_buffer *vb = parg;
3231577c89b0SArnd Bergmann 
3232577c89b0SArnd Bergmann 			if (copy_from_user(&vb32, arg, sizeof(vb32)))
3233577c89b0SArnd Bergmann 				return -EFAULT;
3234577c89b0SArnd Bergmann 
3235577c89b0SArnd Bergmann 			*vb = (struct v4l2_buffer) {
3236577c89b0SArnd Bergmann 				.index		= vb32.index,
3237577c89b0SArnd Bergmann 				.type		= vb32.type,
3238577c89b0SArnd Bergmann 				.bytesused	= vb32.bytesused,
3239577c89b0SArnd Bergmann 				.flags		= vb32.flags,
3240577c89b0SArnd Bergmann 				.field		= vb32.field,
3241577c89b0SArnd Bergmann 				.timestamp.tv_sec	= vb32.timestamp.tv_sec,
3242577c89b0SArnd Bergmann 				.timestamp.tv_usec	= vb32.timestamp.tv_usec,
3243577c89b0SArnd Bergmann 				.timecode	= vb32.timecode,
3244577c89b0SArnd Bergmann 				.sequence	= vb32.sequence,
3245577c89b0SArnd Bergmann 				.memory		= vb32.memory,
3246577c89b0SArnd Bergmann 				.m.userptr	= vb32.m.userptr,
3247577c89b0SArnd Bergmann 				.length		= vb32.length,
3248577c89b0SArnd Bergmann 				.request_fd	= vb32.request_fd,
3249577c89b0SArnd Bergmann 			};
3250577c89b0SArnd Bergmann 			break;
3251577c89b0SArnd Bergmann 		}
3252c8ef1a60SArnd Bergmann 		}
3253c344f07aSArnd Bergmann #endif
32548dbcc3faSArnd Bergmann 	}
3255c8ef1a60SArnd Bergmann 
3256c8ef1a60SArnd Bergmann 	/* zero out anything we don't copy from userspace */
32578dbcc3faSArnd Bergmann 	if (!err && n < _IOC_SIZE(real_cmd))
32588dbcc3faSArnd Bergmann 		memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
32598dbcc3faSArnd Bergmann 	return err;
3260c8ef1a60SArnd Bergmann }
3261c8ef1a60SArnd Bergmann 
video_put_user(void __user * arg,void * parg,unsigned int real_cmd,unsigned int cmd)32628dbcc3faSArnd Bergmann static int video_put_user(void __user *arg, void *parg,
32638dbcc3faSArnd Bergmann 			  unsigned int real_cmd, unsigned int cmd)
3264c8ef1a60SArnd Bergmann {
3265c8ef1a60SArnd Bergmann 	if (!(_IOC_DIR(cmd) & _IOC_READ))
3266c8ef1a60SArnd Bergmann 		return 0;
3267c8ef1a60SArnd Bergmann 
32688dbcc3faSArnd Bergmann 	if (cmd == real_cmd) {
32698dbcc3faSArnd Bergmann 		/*  Copy results into user buffer  */
32708dbcc3faSArnd Bergmann 		if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
32718dbcc3faSArnd Bergmann 			return -EFAULT;
32728dbcc3faSArnd Bergmann 		return 0;
32738dbcc3faSArnd Bergmann 	}
32748dbcc3faSArnd Bergmann 
32758dbcc3faSArnd Bergmann 	if (in_compat_syscall())
32768dbcc3faSArnd Bergmann 		return v4l2_compat_put_user(arg, parg, cmd);
32778dbcc3faSArnd Bergmann 
3278c344f07aSArnd Bergmann #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3279c8ef1a60SArnd Bergmann 	switch (cmd) {
32801a6c0b36SArnd Bergmann 	case VIDIOC_DQEVENT_TIME32: {
32811a6c0b36SArnd Bergmann 		struct v4l2_event *ev = parg;
32824ffb879eSPeilin Ye 		struct v4l2_event_time32 ev32;
32834ffb879eSPeilin Ye 
32844ffb879eSPeilin Ye 		memset(&ev32, 0, sizeof(ev32));
32854ffb879eSPeilin Ye 
32864ffb879eSPeilin Ye 		ev32.type	= ev->type;
32874ffb879eSPeilin Ye 		ev32.pending	= ev->pending;
32884ffb879eSPeilin Ye 		ev32.sequence	= ev->sequence;
32894ffb879eSPeilin Ye 		ev32.timestamp.tv_sec	= ev->timestamp.tv_sec;
32904ffb879eSPeilin Ye 		ev32.timestamp.tv_nsec	= ev->timestamp.tv_nsec;
32914ffb879eSPeilin Ye 		ev32.id		= ev->id;
32921a6c0b36SArnd Bergmann 
32931a6c0b36SArnd Bergmann 		memcpy(&ev32.u, &ev->u, sizeof(ev->u));
32941a6c0b36SArnd Bergmann 		memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));
32951a6c0b36SArnd Bergmann 
32961a6c0b36SArnd Bergmann 		if (copy_to_user(arg, &ev32, sizeof(ev32)))
32971a6c0b36SArnd Bergmann 			return -EFAULT;
32981a6c0b36SArnd Bergmann 		break;
32991a6c0b36SArnd Bergmann 	}
3300577c89b0SArnd Bergmann 	case VIDIOC_QUERYBUF_TIME32:
3301577c89b0SArnd Bergmann 	case VIDIOC_QBUF_TIME32:
3302577c89b0SArnd Bergmann 	case VIDIOC_DQBUF_TIME32:
3303577c89b0SArnd Bergmann 	case VIDIOC_PREPARE_BUF_TIME32: {
3304577c89b0SArnd Bergmann 		struct v4l2_buffer *vb = parg;
33054ffb879eSPeilin Ye 		struct v4l2_buffer_time32 vb32;
33064ffb879eSPeilin Ye 
33074ffb879eSPeilin Ye 		memset(&vb32, 0, sizeof(vb32));
33084ffb879eSPeilin Ye 
33094ffb879eSPeilin Ye 		vb32.index	= vb->index;
33104ffb879eSPeilin Ye 		vb32.type	= vb->type;
33114ffb879eSPeilin Ye 		vb32.bytesused	= vb->bytesused;
33124ffb879eSPeilin Ye 		vb32.flags	= vb->flags;
33134ffb879eSPeilin Ye 		vb32.field	= vb->field;
33144ffb879eSPeilin Ye 		vb32.timestamp.tv_sec	= vb->timestamp.tv_sec;
33154ffb879eSPeilin Ye 		vb32.timestamp.tv_usec	= vb->timestamp.tv_usec;
33164ffb879eSPeilin Ye 		vb32.timecode	= vb->timecode;
33174ffb879eSPeilin Ye 		vb32.sequence	= vb->sequence;
33184ffb879eSPeilin Ye 		vb32.memory	= vb->memory;
33194ffb879eSPeilin Ye 		vb32.m.userptr	= vb->m.userptr;
33204ffb879eSPeilin Ye 		vb32.length	= vb->length;
33214ffb879eSPeilin Ye 		vb32.request_fd	= vb->request_fd;
3322577c89b0SArnd Bergmann 
3323577c89b0SArnd Bergmann 		if (copy_to_user(arg, &vb32, sizeof(vb32)))
3324577c89b0SArnd Bergmann 			return -EFAULT;
3325577c89b0SArnd Bergmann 		break;
3326577c89b0SArnd Bergmann 	}
3327c8ef1a60SArnd Bergmann 	}
3328c344f07aSArnd Bergmann #endif
3329c8ef1a60SArnd Bergmann 
3330c8ef1a60SArnd Bergmann 	return 0;
3331c8ef1a60SArnd Bergmann }
3332c8ef1a60SArnd Bergmann 
33335bc3cb74SMauro Carvalho Chehab long
video_usercopy(struct file * file,unsigned int orig_cmd,unsigned long arg,v4l2_kioctl func)3334c8ef1a60SArnd Bergmann video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
33355bc3cb74SMauro Carvalho Chehab 	       v4l2_kioctl func)
33365bc3cb74SMauro Carvalho Chehab {
33375bc3cb74SMauro Carvalho Chehab 	char	sbuf[128];
3338fb18802aSSakari Ailus 	void    *mbuf = NULL, *array_buf = NULL;
33395bc3cb74SMauro Carvalho Chehab 	void	*parg = (void *)arg;
33405bc3cb74SMauro Carvalho Chehab 	long	err  = -EINVAL;
33415bc3cb74SMauro Carvalho Chehab 	bool	has_array_args;
3342043f77edSHans Verkuil 	bool	always_copy = false;
33435bc3cb74SMauro Carvalho Chehab 	size_t  array_size = 0;
33445bc3cb74SMauro Carvalho Chehab 	void __user *user_ptr = NULL;
33455bc3cb74SMauro Carvalho Chehab 	void	**kernel_ptr = NULL;
3346c8ef1a60SArnd Bergmann 	unsigned int cmd = video_translate_cmd(orig_cmd);
3347f8a695c4SMauro Carvalho Chehab 	const size_t ioc_size = _IOC_SIZE(cmd);
33485bc3cb74SMauro Carvalho Chehab 
33495bc3cb74SMauro Carvalho Chehab 	/*  Copy arguments into temp kernel buffer  */
33505bc3cb74SMauro Carvalho Chehab 	if (_IOC_DIR(cmd) != _IOC_NONE) {
3351f8a695c4SMauro Carvalho Chehab 		if (ioc_size <= sizeof(sbuf)) {
33525bc3cb74SMauro Carvalho Chehab 			parg = sbuf;
33535bc3cb74SMauro Carvalho Chehab 		} else {
33545bc3cb74SMauro Carvalho Chehab 			/* too big to allocate from stack */
335562a12551SSakari Ailus 			mbuf = kmalloc(ioc_size, GFP_KERNEL);
33565bc3cb74SMauro Carvalho Chehab 			if (NULL == mbuf)
33575bc3cb74SMauro Carvalho Chehab 				return -ENOMEM;
33585bc3cb74SMauro Carvalho Chehab 			parg = mbuf;
33595bc3cb74SMauro Carvalho Chehab 		}
33605bc3cb74SMauro Carvalho Chehab 
33618dbcc3faSArnd Bergmann 		err = video_get_user((void __user *)arg, parg, cmd,
33628dbcc3faSArnd Bergmann 				     orig_cmd, &always_copy);
3363c8ef1a60SArnd Bergmann 		if (err)
33645bc3cb74SMauro Carvalho Chehab 			goto out;
33651dc8b65cSArnd Bergmann 	}
33665bc3cb74SMauro Carvalho Chehab 
33675bc3cb74SMauro Carvalho Chehab 	err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
33685bc3cb74SMauro Carvalho Chehab 	if (err < 0)
33695bc3cb74SMauro Carvalho Chehab 		goto out;
33705bc3cb74SMauro Carvalho Chehab 	has_array_args = err;
33715bc3cb74SMauro Carvalho Chehab 
33725bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3373fb18802aSSakari Ailus 		array_buf = kvmalloc(array_size, GFP_KERNEL);
33745bc3cb74SMauro Carvalho Chehab 		err = -ENOMEM;
3375fb18802aSSakari Ailus 		if (array_buf == NULL)
3376f0da34f3SHans Verkuil 			goto out;
33778dbcc3faSArnd Bergmann 		if (in_compat_syscall())
3378fb18802aSSakari Ailus 			err = v4l2_compat_get_array_args(file, array_buf,
3379fb18802aSSakari Ailus 							 user_ptr, array_size,
3380fb18802aSSakari Ailus 							 orig_cmd, parg);
33818dbcc3faSArnd Bergmann 		else
3382fb18802aSSakari Ailus 			err = copy_from_user(array_buf, user_ptr, array_size) ?
33838dbcc3faSArnd Bergmann 								-EFAULT : 0;
33848dbcc3faSArnd Bergmann 		if (err)
3385f0da34f3SHans Verkuil 			goto out;
3386fb18802aSSakari Ailus 		*kernel_ptr = array_buf;
33875bc3cb74SMauro Carvalho Chehab 	}
33885bc3cb74SMauro Carvalho Chehab 
33895bc3cb74SMauro Carvalho Chehab 	/* Handles IOCTL */
33905bc3cb74SMauro Carvalho Chehab 	err = func(file, cmd, parg);
3391181a4a2dSHans Verkuil 	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
33925bc3cb74SMauro Carvalho Chehab 		err = -ENOTTY;
3393181a4a2dSHans Verkuil 		goto out;
3394181a4a2dSHans Verkuil 	}
3395181a4a2dSHans Verkuil 
3396aa32f4c0SHans Verkuil 	if (err == 0) {
3397aa32f4c0SHans Verkuil 		if (cmd == VIDIOC_DQBUF)
3398aa32f4c0SHans Verkuil 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
3399aa32f4c0SHans Verkuil 		else if (cmd == VIDIOC_QBUF)
3400aa32f4c0SHans Verkuil 			trace_v4l2_qbuf(video_devdata(file)->minor, parg);
3401aa32f4c0SHans Verkuil 	}
34025bc3cb74SMauro Carvalho Chehab 
3403f0da34f3SHans Verkuil 	/*
3404f0da34f3SHans Verkuil 	 * Some ioctls can return an error, but still have valid
3405f0da34f3SHans Verkuil 	 * results that must be returned.
3406a418bb3fSLaurent Pinchart 	 *
3407a418bb3fSLaurent Pinchart 	 * FIXME: subdev IOCTLS are partially handled here and partially in
3408a418bb3fSLaurent Pinchart 	 * v4l2-subdev.c and the 'always_copy' flag can only be set for IOCTLS
3409a418bb3fSLaurent Pinchart 	 * defined here as part of the 'v4l2_ioctls' array. As
3410a418bb3fSLaurent Pinchart 	 * VIDIOC_SUBDEV_G_ROUTING needs to return results to applications even
3411a418bb3fSLaurent Pinchart 	 * in case of failure, but it is not defined here as part of the
3412a418bb3fSLaurent Pinchart 	 * 'v4l2_ioctls' array, insert an ad-hoc check to address that.
3413f0da34f3SHans Verkuil 	 */
3414a418bb3fSLaurent Pinchart 	if (err < 0 && !always_copy && cmd != VIDIOC_SUBDEV_G_ROUTING)
3415f0da34f3SHans Verkuil 		goto out;
3416f0da34f3SHans Verkuil 
34175bc3cb74SMauro Carvalho Chehab 	if (has_array_args) {
3418ba2d35c1SHans Verkuil 		*kernel_ptr = (void __force *)user_ptr;
34198dbcc3faSArnd Bergmann 		if (in_compat_syscall()) {
34208dbcc3faSArnd Bergmann 			int put_err;
34218dbcc3faSArnd Bergmann 
3422fb18802aSSakari Ailus 			put_err = v4l2_compat_put_array_args(file, user_ptr,
3423fb18802aSSakari Ailus 							     array_buf,
3424fb18802aSSakari Ailus 							     array_size,
3425fb18802aSSakari Ailus 							     orig_cmd, parg);
34268dbcc3faSArnd Bergmann 			if (put_err)
34278dbcc3faSArnd Bergmann 				err = put_err;
3428fb18802aSSakari Ailus 		} else if (copy_to_user(user_ptr, array_buf, array_size)) {
34295bc3cb74SMauro Carvalho Chehab 			err = -EFAULT;
34308dbcc3faSArnd Bergmann 		}
34315bc3cb74SMauro Carvalho Chehab 	}
34325bc3cb74SMauro Carvalho Chehab 
34338dbcc3faSArnd Bergmann 	if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
34345bc3cb74SMauro Carvalho Chehab 		err = -EFAULT;
34355bc3cb74SMauro Carvalho Chehab out:
3436fb18802aSSakari Ailus 	kvfree(array_buf);
343762a12551SSakari Ailus 	kfree(mbuf);
34385bc3cb74SMauro Carvalho Chehab 	return err;
34395bc3cb74SMauro Carvalho Chehab }
34405bc3cb74SMauro Carvalho Chehab 
video_ioctl2(struct file * file,unsigned int cmd,unsigned long arg)34415bc3cb74SMauro Carvalho Chehab long video_ioctl2(struct file *file,
34425bc3cb74SMauro Carvalho Chehab 	       unsigned int cmd, unsigned long arg)
34435bc3cb74SMauro Carvalho Chehab {
34445bc3cb74SMauro Carvalho Chehab 	return video_usercopy(file, cmd, arg, __video_do_ioctl);
34455bc3cb74SMauro Carvalho Chehab }
34465bc3cb74SMauro Carvalho Chehab EXPORT_SYMBOL(video_ioctl2);
3447